added several commands
This commit is contained in:
+2
-1
@@ -12,7 +12,8 @@
|
|||||||
(target clean
|
(target clean
|
||||||
(for-each (λ (f) (displayln f) (rm-f f)) (list-files "." #px"([.]bak|~)$" #:recursive #t))
|
(for-each (λ (f) (displayln f) (rm-f f)) (list-files "." #px"([.]bak|~)$" #:recursive #t))
|
||||||
(for-each (λ (d) (displayln d) (rm-rf d)) (list-dirs "." #px"(compiled|doc)$" #:recursive #t))
|
(for-each (λ (d) (displayln d) (rm-rf d)) (list-dirs "." #px"(compiled|doc)$" #:recursive #t))
|
||||||
(for-each (λ (f) (displayln f) (rm-f f)) (list-files "scribblings" #px"[.](css|js|html)$"))
|
(when (directory-exists? "scribblings")
|
||||||
|
(for-each (λ (f) (displayln f) (rm-f f)) (list-files "scribblings" #px"[.](css|js|html)$")))
|
||||||
)
|
)
|
||||||
|
|
||||||
(target package
|
(target package
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ A small command-line-like Git module for Racket, implemented directly on top of
|
|||||||
(git 'diff)
|
(git 'diff)
|
||||||
(git 'diff '--cached)
|
(git 'diff '--cached)
|
||||||
(git 'add "main.rkt" "info.rkt")
|
(git 'add "main.rkt" "info.rkt")
|
||||||
|
(git 'restore '--staged "scratch.rkt")
|
||||||
|
(git 'reset 'HEAD "--" "main.rkt")
|
||||||
|
(git 'grep '-i '-n "todo")
|
||||||
(git 'commit "Implement raco support")
|
(git 'commit "Implement raco support")
|
||||||
(git 'tag "v0.2")
|
(git 'tag "v0.2")
|
||||||
(git 'branch-current)
|
(git 'branch-current)
|
||||||
@@ -90,8 +93,8 @@ operations use them automatically:
|
|||||||
|
|
||||||
## Supported Git operations
|
## Supported Git operations
|
||||||
|
|
||||||
Version 0.2 supports repository discovery, init, clone, status, add, config,
|
Version 0.2 supports repository discovery, init, clone, status, diff, add, restore, reset, grep, config,
|
||||||
commit, branch, branch-current, switch, checkout, lightweight tags, log, remotes, fetch,
|
commit, branch, branch-current, switch, checkout, merge, lightweight tags, log, remotes, fetch,
|
||||||
fast-forward-only pull, push, tag push, network transfer progress, and HTTPS username/token credentials.
|
fast-forward-only pull, push, tag push, network transfer progress, and HTTPS username/token credentials.
|
||||||
|
|
||||||
SSH credentials, merge/rebase pull, annotated tags, and submodules are not yet
|
SSH credentials, merge/rebase pull, annotated tags, and submodules are not yet
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
(define collection "git")
|
(define collection "git")
|
||||||
(define pkg-desc "Command-line-like Git operations for Racket, implemented with libgit2")
|
(define pkg-desc "Command-line-like Git operations for Racket, implemented with libgit2")
|
||||||
(define version "0.2.11")
|
(define version "0.2.12")
|
||||||
(define pkg-authors '("Hans Dijkema"))
|
(define pkg-authors '("Hans Dijkema"))
|
||||||
(define license 'MIT)
|
(define license 'MIT)
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
setup/getinfo
|
setup/getinfo
|
||||||
racket/async-channel
|
racket/async-channel
|
||||||
racket/list
|
racket/list
|
||||||
|
racket/file
|
||||||
racket/match
|
racket/match
|
||||||
racket/path
|
racket/path
|
||||||
racket/string
|
racket/string
|
||||||
@@ -24,6 +25,8 @@
|
|||||||
git-clean?
|
git-clean?
|
||||||
git-diff
|
git-diff
|
||||||
git-add
|
git-add
|
||||||
|
git-restore
|
||||||
|
git-reset
|
||||||
git-config
|
git-config
|
||||||
git-config-get
|
git-config-get
|
||||||
git-config-set
|
git-config-set
|
||||||
@@ -42,6 +45,8 @@
|
|||||||
git-tag
|
git-tag
|
||||||
git-tag-delete
|
git-tag-delete
|
||||||
(struct-out git-log-entry)
|
(struct-out git-log-entry)
|
||||||
|
(struct-out git-grep-entry)
|
||||||
|
git-grep
|
||||||
git-log
|
git-log
|
||||||
git-log-lines
|
git-log-lines
|
||||||
git-remotes
|
git-remotes
|
||||||
@@ -59,10 +64,13 @@
|
|||||||
git-credentials-set!
|
git-credentials-set!
|
||||||
git-credentials-ref
|
git-credentials-ref
|
||||||
git-credentials-configured?
|
git-credentials-configured?
|
||||||
git-credentials-remove!)
|
git-credentials-remove!
|
||||||
|
git-prompt
|
||||||
|
)
|
||||||
|
|
||||||
(struct git-status-entry (path code flags) #:transparent)
|
(struct git-status-entry (path code flags) #:transparent)
|
||||||
(struct git-log-entry (id summary time) #:transparent)
|
(struct git-log-entry (id summary time) #:transparent)
|
||||||
|
(struct git-grep-entry (path line-number line) #:transparent)
|
||||||
|
|
||||||
(define-runtime-path git-command-directory ".")
|
(define-runtime-path git-command-directory ".")
|
||||||
|
|
||||||
@@ -135,6 +143,16 @@
|
|||||||
[(3) "sending"]
|
[(3) "sending"]
|
||||||
[else #f]))
|
[else #f]))
|
||||||
|
|
||||||
|
(define (git-prompt . msg)
|
||||||
|
(let ((m (if (null? msg)
|
||||||
|
(begin
|
||||||
|
(display "Give (commit) message: ")
|
||||||
|
(flush-output)
|
||||||
|
(let ((line (read-line)))
|
||||||
|
line))
|
||||||
|
(car msg))))
|
||||||
|
m))
|
||||||
|
|
||||||
(define (make-progress-reporter label quiet #:bytes? [bytes? #t] #:phase? [phase? #f])
|
(define (make-progress-reporter label quiet #:bytes? [bytes? #t] #:phase? [phase? #f])
|
||||||
(define last-phase -1)
|
(define last-phase -1)
|
||||||
(define last-percent -10)
|
(define last-percent -10)
|
||||||
@@ -448,7 +466,7 @@
|
|||||||
(define (git-path-string path)
|
(define (git-path-string path)
|
||||||
(regexp-replace* #rx"\\\\" (path->string path) "/"))
|
(regexp-replace* #rx"\\\\" (path->string path) "/"))
|
||||||
|
|
||||||
(define (relative-pathspec workdir path)
|
(define (relative-pathspec workdir path [who 'git-add])
|
||||||
(define p0 (if (path? path) path (string->path path)))
|
(define p0 (if (path? path) path (string->path path)))
|
||||||
;; A relative path supplied by the caller is relative to the caller's
|
;; A relative path supplied by the caller is relative to the caller's
|
||||||
;; current directory, not automatically to the repository root.
|
;; current directory, not automatically to the repository root.
|
||||||
@@ -457,7 +475,7 @@
|
|||||||
(define s (git-path-string rel))
|
(define s (git-path-string rel))
|
||||||
(when (or (string=? s "..")
|
(when (or (string=? s "..")
|
||||||
(string-prefix? s "../"))
|
(string-prefix? s "../"))
|
||||||
(error 'git-add "path is outside the repository: ~a" path))
|
(error who "path is outside the repository: ~a" path))
|
||||||
s)
|
s)
|
||||||
|
|
||||||
(define (index-accept _path _matched-pathspec _payload)
|
(define (index-accept _path _matched-pathspec _payload)
|
||||||
@@ -478,6 +496,145 @@
|
|||||||
(git_index_write index)
|
(git_index_write index)
|
||||||
(void))
|
(void))
|
||||||
|
|
||||||
|
|
||||||
|
(define (revision-string revision)
|
||||||
|
(cond
|
||||||
|
[(symbol? revision) (symbol->string revision)]
|
||||||
|
[(string? revision) revision]
|
||||||
|
[else
|
||||||
|
(raise-argument-error 'git "(or/c symbol? string?)" revision)]))
|
||||||
|
|
||||||
|
(define (resolve-reset-target repo revision [allow-unborn-head? #f])
|
||||||
|
(define revision-name (revision-string revision))
|
||||||
|
(cond
|
||||||
|
[(and allow-unborn-head?
|
||||||
|
(string=? revision-name "HEAD")
|
||||||
|
(not (head-commit repo)))
|
||||||
|
#f]
|
||||||
|
[else
|
||||||
|
(with-handlers ([exn:fail?
|
||||||
|
(lambda (_)
|
||||||
|
(error 'git-reset "cannot resolve revision: ~a" revision-name))])
|
||||||
|
(git_revparse_single repo (format "~a^{commit}" revision-name)))]))
|
||||||
|
|
||||||
|
(define (make-pathspecs repo paths who)
|
||||||
|
(define workdir (string->path (git_repository_workdir repo)))
|
||||||
|
(make-git_strarray
|
||||||
|
(for/list ([path (in-list paths)])
|
||||||
|
(relative-pathspec workdir path who))))
|
||||||
|
|
||||||
|
(define (make-path-checkout-options repo paths)
|
||||||
|
(define options (make-safe-checkout-options))
|
||||||
|
;; `git restore` is explicitly destructive for the selected worktree paths.
|
||||||
|
;; Do not let checkout update the index when restoring only the worktree.
|
||||||
|
(set-git_checkout_opts-checkout_strategy!
|
||||||
|
options
|
||||||
|
'(GIT_CHECKOUT_FORCE GIT_CHECKOUT_DONT_UPDATE_INDEX))
|
||||||
|
(set-git_checkout_opts-paths! options (make-pathspecs repo paths 'git-restore))
|
||||||
|
options)
|
||||||
|
|
||||||
|
(define (split-at-double-dash args)
|
||||||
|
(let loop ([before null] [rest args])
|
||||||
|
(cond
|
||||||
|
[(null? rest) (values (reverse before) #f)]
|
||||||
|
[(equal? (car rest) "--") (values (reverse before) (cdr rest))]
|
||||||
|
[(eq? (car rest) '--) (values (reverse before) (cdr rest))]
|
||||||
|
[else (loop (cons (car rest) before) (cdr rest))])))
|
||||||
|
|
||||||
|
(define (git-reset . args)
|
||||||
|
(define repo (open-repository))
|
||||||
|
(define-values (before paths) (split-at-double-dash args))
|
||||||
|
(cond
|
||||||
|
[paths
|
||||||
|
(when (null? paths)
|
||||||
|
(error 'git-reset "expected at least one path after --"))
|
||||||
|
(define revision
|
||||||
|
(match before
|
||||||
|
['() 'HEAD]
|
||||||
|
[(list rev) rev]
|
||||||
|
[_ (error 'git-reset "invalid path reset arguments: ~e" args)]))
|
||||||
|
(define target (resolve-reset-target repo revision #t))
|
||||||
|
(git_reset_default repo target (make-pathspecs repo paths 'git-reset))
|
||||||
|
(void)]
|
||||||
|
[else
|
||||||
|
(define-values (mode revision)
|
||||||
|
(match args
|
||||||
|
['() (values 'GIT_RESET_MIXED 'HEAD)]
|
||||||
|
[(list '--soft) (values 'GIT_RESET_SOFT 'HEAD)]
|
||||||
|
[(list '--mixed) (values 'GIT_RESET_MIXED 'HEAD)]
|
||||||
|
[(list '--hard) (values 'GIT_RESET_HARD 'HEAD)]
|
||||||
|
[(list '--soft rev) (values 'GIT_RESET_SOFT rev)]
|
||||||
|
[(list '--mixed rev) (values 'GIT_RESET_MIXED rev)]
|
||||||
|
[(list '--hard rev) (values 'GIT_RESET_HARD rev)]
|
||||||
|
[(list rev) (values 'GIT_RESET_MIXED rev)]
|
||||||
|
[_ (error 'git-reset "invalid arguments: ~e" args)]))
|
||||||
|
(define target (resolve-reset-target repo revision))
|
||||||
|
(git_reset repo target mode (make-safe-checkout-options))
|
||||||
|
(void)]))
|
||||||
|
|
||||||
|
(define (parse-restore-arguments args)
|
||||||
|
(let loop ([rest args]
|
||||||
|
[staged? #f]
|
||||||
|
[worktree? #f]
|
||||||
|
[worktree-explicit? #f]
|
||||||
|
[source #f]
|
||||||
|
[paths null])
|
||||||
|
(cond
|
||||||
|
[(null? rest)
|
||||||
|
(define actual-worktree?
|
||||||
|
(if worktree-explicit? worktree? (not staged?)))
|
||||||
|
(values staged? actual-worktree? source (reverse paths))]
|
||||||
|
[(eq? (car rest) '--staged)
|
||||||
|
(loop (cdr rest) #t worktree? worktree-explicit? source paths)]
|
||||||
|
[(eq? (car rest) '--worktree)
|
||||||
|
(loop (cdr rest) staged? #t #t source paths)]
|
||||||
|
[(eq? (car rest) '--source)
|
||||||
|
(unless (pair? (cdr rest))
|
||||||
|
(error 'git-restore "--source requires a revision"))
|
||||||
|
(loop (cddr rest) staged? worktree? worktree-explicit?
|
||||||
|
(cadr rest) paths)]
|
||||||
|
[(or (eq? (car rest) '--) (equal? (car rest) "--"))
|
||||||
|
(values staged?
|
||||||
|
(if worktree-explicit? worktree? (not staged?))
|
||||||
|
source
|
||||||
|
(append (reverse paths) (cdr rest)))]
|
||||||
|
[(and (symbol? (car rest))
|
||||||
|
(string-prefix? (symbol->string (car rest)) "-"))
|
||||||
|
(error 'git-restore "unsupported option: ~a" (car rest))]
|
||||||
|
[else
|
||||||
|
(loop (cdr rest) staged? worktree? worktree-explicit?
|
||||||
|
source (cons (car rest) paths))])))
|
||||||
|
|
||||||
|
(define (git-restore . args)
|
||||||
|
(define-values (staged? worktree? source paths)
|
||||||
|
(parse-restore-arguments args))
|
||||||
|
(when (null? paths)
|
||||||
|
(error 'git-restore "expected at least one path"))
|
||||||
|
(unless (or staged? worktree?)
|
||||||
|
(error 'git-restore "nothing to restore"))
|
||||||
|
(define repo (open-repository))
|
||||||
|
(define source-revision (or source 'HEAD))
|
||||||
|
(when staged?
|
||||||
|
;; With an unborn HEAD, a staged restore removes matching new entries from
|
||||||
|
;; the index, which is exactly the useful `git restore --staged` behavior.
|
||||||
|
(define target (resolve-reset-target repo source-revision #t))
|
||||||
|
(git_reset_default repo target (make-pathspecs repo paths 'git-restore)))
|
||||||
|
(when worktree?
|
||||||
|
(define options (make-path-checkout-options repo paths))
|
||||||
|
(cond
|
||||||
|
[(or staged? (not source))
|
||||||
|
;; After a staged restore, or with no explicit source, the index is the
|
||||||
|
;; source for the worktree restore.
|
||||||
|
(git_checkout_index repo (git_repository_index repo) options)]
|
||||||
|
[else
|
||||||
|
(define object
|
||||||
|
(with-handlers ([exn:fail?
|
||||||
|
(lambda (_)
|
||||||
|
(error 'git-restore "cannot resolve source: ~a" source))])
|
||||||
|
(git_revparse_single repo (revision-string source))))
|
||||||
|
(git_checkout_tree repo object options)]))
|
||||||
|
(void))
|
||||||
|
|
||||||
(define (git-config-get key)
|
(define (git-config-get key)
|
||||||
(define repo (open-repository))
|
(define repo (open-repository))
|
||||||
(define config (git_repository_config repo))
|
(define config (git_repository_config repo))
|
||||||
@@ -712,6 +869,105 @@
|
|||||||
(git_tag_delete (open-repository) name)
|
(git_tag_delete (open-repository) name)
|
||||||
(void))
|
(void))
|
||||||
|
|
||||||
|
|
||||||
|
(define (grep-flag? x flag)
|
||||||
|
(and (symbol? x) (eq? x flag)))
|
||||||
|
|
||||||
|
(define (parse-grep-arguments args)
|
||||||
|
(let loop ([rest args] [ignore-case? #f] [invert? #f]
|
||||||
|
[show-line-numbers? #f] [files-only? #f] [count? #f])
|
||||||
|
(cond
|
||||||
|
[(null? rest)
|
||||||
|
(error 'git-grep "expected a pattern")]
|
||||||
|
[(grep-flag? (car rest) '-i)
|
||||||
|
(loop (cdr rest) #t invert? show-line-numbers? files-only? count?)]
|
||||||
|
[(grep-flag? (car rest) '-v)
|
||||||
|
(loop (cdr rest) ignore-case? #t show-line-numbers? files-only? count?)]
|
||||||
|
[(grep-flag? (car rest) '-n)
|
||||||
|
(loop (cdr rest) ignore-case? invert? #t files-only? count?)]
|
||||||
|
[(grep-flag? (car rest) '-l)
|
||||||
|
(loop (cdr rest) ignore-case? invert? show-line-numbers? #t count?)]
|
||||||
|
[(grep-flag? (car rest) '-c)
|
||||||
|
(loop (cdr rest) ignore-case? invert? show-line-numbers? files-only? #t)]
|
||||||
|
[(and (symbol? (car rest))
|
||||||
|
(string-prefix? (symbol->string (car rest)) "-"))
|
||||||
|
(error 'git-grep "unsupported option: ~a" (car rest))]
|
||||||
|
[else
|
||||||
|
(define pattern (car rest))
|
||||||
|
(define tail (cdr rest))
|
||||||
|
(when (> (length tail) 1)
|
||||||
|
(error 'git-grep "expected at most one revision after the pattern"))
|
||||||
|
(values ignore-case? invert? show-line-numbers? files-only? count?
|
||||||
|
pattern (and (pair? tail) (car tail)))])))
|
||||||
|
|
||||||
|
(define (grep-regexp pattern ignore-case?)
|
||||||
|
(define source
|
||||||
|
(cond
|
||||||
|
[(regexp? pattern) (object-name pattern)]
|
||||||
|
[(byte-regexp? pattern)
|
||||||
|
(bytes->string/utf-8 (object-name pattern))]
|
||||||
|
[(string? pattern) pattern]
|
||||||
|
[else (raise-argument-error 'git-grep "(or/c string? regexp?)" pattern)]))
|
||||||
|
(pregexp (if ignore-case? (format "(?i:~a)" source) source)))
|
||||||
|
|
||||||
|
(define (binary-bytes? bs)
|
||||||
|
(for/or ([b (in-bytes bs)]) (zero? b)))
|
||||||
|
|
||||||
|
(define (grep-bytes path bs rx invert?)
|
||||||
|
(cond
|
||||||
|
[(binary-bytes? bs) null]
|
||||||
|
[else
|
||||||
|
(define text (bytes->string/utf-8 bs #\uFFFD))
|
||||||
|
(for/list ([line (in-list (string-split text "\n" #:trim? #f))]
|
||||||
|
[number (in-naturals 1)]
|
||||||
|
#:when (if invert?
|
||||||
|
(not (regexp-match? rx line))
|
||||||
|
(regexp-match? rx line)))
|
||||||
|
(git-grep-entry path number line))]))
|
||||||
|
|
||||||
|
(define (working-tree-grep repo rx invert?)
|
||||||
|
(define index (git_repository_index repo))
|
||||||
|
(define workdir (git_repository_workdir repo))
|
||||||
|
(append*
|
||||||
|
(for/list ([i (in-range (git_index_entrycount index))])
|
||||||
|
(define entry (git_index_get_byindex index i))
|
||||||
|
(define path (git_index_entry-path entry))
|
||||||
|
(define full (build-path workdir path))
|
||||||
|
(if (file-exists? full)
|
||||||
|
(grep-bytes path (file->bytes full) rx invert?)
|
||||||
|
null))))
|
||||||
|
|
||||||
|
(define (revision-grep repo revision rx invert?)
|
||||||
|
(define object
|
||||||
|
(with-handlers ([exn:fail?
|
||||||
|
(lambda (_)
|
||||||
|
(error 'git-grep "cannot resolve revision: ~a" revision))])
|
||||||
|
(git_revparse_single repo (format "~a^{tree}" revision))))
|
||||||
|
(define tree (git_tree_lookup repo (git_object_id object)))
|
||||||
|
(define results null)
|
||||||
|
(git_tree_walk
|
||||||
|
tree 'GIT_TREEWALK_PRE
|
||||||
|
(lambda (root entry _payload)
|
||||||
|
(when (eq? (git_tree_entry_type entry) 'GIT_OBJECT_BLOB)
|
||||||
|
(define path (string-append root (git_tree_entry_name entry)))
|
||||||
|
(define blob (git_blob_lookup repo (git_tree_entry_id entry)))
|
||||||
|
(set! results
|
||||||
|
(append (grep-bytes path (git_blob_rawcontent blob) rx invert?)
|
||||||
|
results)))
|
||||||
|
0)
|
||||||
|
#"")
|
||||||
|
(reverse results))
|
||||||
|
|
||||||
|
(define (git-grep . args)
|
||||||
|
(define-values (ignore-case? invert? _show-line-numbers? _files-only? _count?
|
||||||
|
pattern revision)
|
||||||
|
(parse-grep-arguments args))
|
||||||
|
(define rx (grep-regexp pattern ignore-case?))
|
||||||
|
(define repo (open-repository))
|
||||||
|
(if revision
|
||||||
|
(revision-grep repo revision rx invert?)
|
||||||
|
(working-tree-grep repo rx invert?)))
|
||||||
|
|
||||||
(define (git-log [max-count 20])
|
(define (git-log [max-count 20])
|
||||||
(unless (exact-nonnegative-integer? max-count)
|
(unless (exact-nonnegative-integer? max-count)
|
||||||
(raise-argument-error 'git-log "exact-nonnegative-integer?" max-count))
|
(raise-argument-error 'git-log "exact-nonnegative-integer?" max-count))
|
||||||
@@ -919,6 +1175,8 @@
|
|||||||
(if (and (= (length args) 1) (eq? (car args) '-A))
|
(if (and (= (length args) 1) (eq? (car args) '-A))
|
||||||
(apply git-add (map git-status-entry-path (git 'status)))
|
(apply git-add (map git-status-entry-path (git 'status)))
|
||||||
(apply git-add args))]
|
(apply git-add args))]
|
||||||
|
[(restore) (apply git-restore args)]
|
||||||
|
[(reset) (apply git-reset args)]
|
||||||
[(config) (apply git-config args)]
|
[(config) (apply git-config args)]
|
||||||
[(commit) (apply git-commit args)]
|
[(commit) (apply git-commit args)]
|
||||||
[(branch-current)
|
[(branch-current)
|
||||||
@@ -940,6 +1198,7 @@
|
|||||||
(match args
|
(match args
|
||||||
[(list '-d name) (git-tag-delete name)]
|
[(list '-d name) (git-tag-delete name)]
|
||||||
[_ (apply git-tag args)])]
|
[_ (apply git-tag args)])]
|
||||||
|
[(grep) (apply git-grep args)]
|
||||||
[(log) (apply git-log args)]
|
[(log) (apply git-log args)]
|
||||||
[(remote)
|
[(remote)
|
||||||
(match args
|
(match args
|
||||||
@@ -1007,8 +1266,35 @@
|
|||||||
[(void? result) (void)]
|
[(void? result) (void)]
|
||||||
[else (displayln result out)]))
|
[else (displayln result out)]))
|
||||||
|
|
||||||
|
(define (display-grep-result args result [out (current-output-port)])
|
||||||
|
(define files-only? (member '-l args))
|
||||||
|
(define count? (member '-c args))
|
||||||
|
(define line-numbers? (member '-n args))
|
||||||
|
(cond
|
||||||
|
[files-only?
|
||||||
|
(for ([path (in-list (remove-duplicates (map git-grep-entry-path result)))])
|
||||||
|
(displayln path out))]
|
||||||
|
[count?
|
||||||
|
(define counts (make-hash))
|
||||||
|
(for ([entry (in-list result)])
|
||||||
|
(hash-update! counts (git-grep-entry-path entry) add1 0))
|
||||||
|
(for ([path (in-list (sort (hash-keys counts) string<?))])
|
||||||
|
(fprintf out "~a:~a\n" path (hash-ref counts path)))]
|
||||||
|
[else
|
||||||
|
(for ([entry (in-list result)])
|
||||||
|
(if line-numbers?
|
||||||
|
(fprintf out "~a:~a:~a\n"
|
||||||
|
(git-grep-entry-path entry)
|
||||||
|
(git-grep-entry-line-number entry)
|
||||||
|
(git-grep-entry-line entry))
|
||||||
|
(fprintf out "~a:~a\n"
|
||||||
|
(git-grep-entry-path entry)
|
||||||
|
(git-grep-entry-line entry))))]))
|
||||||
|
|
||||||
(define (dgit command #:quiet [quiet #f] . args)
|
(define (dgit command #:quiet [quiet #f] . args)
|
||||||
(define result
|
(define result
|
||||||
(keyword-apply git '(#:quiet) (list quiet) (cons command args)))
|
(keyword-apply git '(#:quiet) (list quiet) (cons command args)))
|
||||||
(display-git-result command result)
|
(if (eq? command 'grep)
|
||||||
|
(display-grep-result args result)
|
||||||
|
(display-git-result command result))
|
||||||
result)
|
result)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+42
-1
@@ -18,6 +18,9 @@ The short form is intended for build scripts and interactive use:
|
|||||||
(git 'diff)
|
(git 'diff)
|
||||||
(git 'diff '--cached)
|
(git 'diff '--cached)
|
||||||
(git 'add "main.rkt" "info.rkt")
|
(git 'add "main.rkt" "info.rkt")
|
||||||
|
(git 'restore '--staged "scratch.rkt")
|
||||||
|
(git 'reset 'HEAD "--" "main.rkt")
|
||||||
|
(git 'grep '-i '-n "todo")
|
||||||
(git 'commit "Implement raco support")
|
(git 'commit "Implement raco support")
|
||||||
(git 'tag "v0.1")
|
(git 'tag "v0.1")
|
||||||
(git 'checkout "main")
|
(git 'checkout "main")
|
||||||
@@ -40,7 +43,7 @@ Calls @racket[git], displays its result in a compact human-readable form, and re
|
|||||||
@defproc[(git-version) string?]{Returns the package version from @tt{info.rkt}. The command form is @racket[(git 'version)]. The version is not duplicated in @tt{main.rkt}; @tt{info.rkt} is the single source of truth.}
|
@defproc[(git-version) string?]{Returns the package version from @tt{info.rkt}. The command form is @racket[(git 'version)]. The version is not duplicated in @tt{main.rkt}; @tt{info.rkt} is the single source of truth.}
|
||||||
|
|
||||||
@racketblock[
|
@racketblock[
|
||||||
(git 'version) ; => "0.2.11"
|
(git 'version) ; => "0.2.12"
|
||||||
]
|
]
|
||||||
|
|
||||||
@section{Repository}
|
@section{Repository}
|
||||||
@@ -75,6 +78,39 @@ Calls @racket[git], displays its result in a compact human-readable form, and re
|
|||||||
(git 'commit "Update all changed files")
|
(git 'commit "Update all changed files")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@defproc[(git-restore [argument any/c] ...) void?]{Restores paths using Git-like command arguments. With only paths, the worktree is restored from the index, as in @tt{git restore path}. With @racket['--staged], matching index entries are restored from HEAD while the worktree is left untouched. @racket['--worktree] can be combined with @racket['--staged], and @racket['--source] selects another revision.}
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(git 'restore "main.rkt")
|
||||||
|
(git 'restore '--staged "scrbl/racket-makefile.bak")
|
||||||
|
(git 'restore '--source "HEAD~1" "main.rkt")
|
||||||
|
]
|
||||||
|
|
||||||
|
@defproc[(git-reset [argument any/c] ...) void?]{Resets HEAD, the index, or selected paths using Git-like command arguments. With @racket['--soft], @racket['--mixed], or @racket['--hard], the corresponding whole-repository reset is performed. Path resets use the familiar @tt{--} separator.}
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(git 'reset 'HEAD "--" "main.rkt")
|
||||||
|
(git 'reset '--mixed 'HEAD)
|
||||||
|
(git 'reset '--hard 'HEAD)
|
||||||
|
]
|
||||||
|
|
||||||
|
@section{Grep}
|
||||||
|
|
||||||
|
@defstruct*[git-grep-entry ([path string?] [line-number exact-positive-integer?] [line string?])]{Describes one line selected by @racket[git-grep]. Results are always structured this way, regardless of display-oriented flags such as @racket['-n], @racket['-l], or @racket['-c].}
|
||||||
|
|
||||||
|
@defproc[(git-grep [argument any/c] ...) (listof git-grep-entry?)]{Searches tracked files in the current worktree, or in an optional revision supplied after the pattern. String patterns are regular expressions. @racket['-i] makes matching case-insensitive and @racket['-v] inverts the match. The flags @racket['-n], @racket['-l], and @racket['-c] do not change the structured result; they control how @racket[dgit] displays it. Binary files are skipped.}
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(git 'grep "TODO")
|
||||||
|
(git 'grep '-i "todo")
|
||||||
|
(git 'grep '-v "generated")
|
||||||
|
(git 'grep "old-name" 'HEAD~1)
|
||||||
|
|
||||||
|
(dgit 'grep '-n "TODO") ; path:line-number:text
|
||||||
|
(dgit 'grep '-l "TODO") ; matching file names only
|
||||||
|
(dgit 'grep '-c "TODO") ; number of matching lines per file
|
||||||
|
]
|
||||||
|
|
||||||
@section{Configuration and commits}
|
@section{Configuration and commits}
|
||||||
|
|
||||||
@defproc*[([(git-config [key string?]) string?]
|
@defproc*[([(git-config [key string?]) string?]
|
||||||
@@ -84,6 +120,9 @@ Calls @racket[git], displays its result in a compact human-readable form, and re
|
|||||||
|
|
||||||
@defproc[(git-commit [message string?]) string?]{Creates a commit from the index and returns its full OID. The author and committer are read from the repository configuration.}
|
@defproc[(git-commit [message string?]) string?]{Creates a commit from the index and returns its full OID. The author and committer are read from the repository configuration.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(git-prompt [message string? #f]) string?]{Returns @racket[message] when supplied. Without an argument, displays @tt{Give (commit) message: }, reads one line from the current input port, and returns it. This is convenient in interactive make targets before staging and committing changes.}
|
||||||
|
|
||||||
@section{Branches, checkout, and tags}
|
@section{Branches, checkout, and tags}
|
||||||
|
|
||||||
@defproc[(git-current-branch) (or/c string? #f)]{Returns the current local branch name, or @racket[#f] for detached HEAD. The command form is @racket[(git 'branch-current)].}
|
@defproc[(git-current-branch) (or/c string? #f)]{Returns the current local branch name, or @racket[#f] for detached HEAD. The command form is @racket[(git 'branch-current)].}
|
||||||
@@ -162,6 +201,8 @@ The following command-like forms are supported directly:
|
|||||||
(git 'status)
|
(git 'status)
|
||||||
(git 'add "file.rkt")
|
(git 'add "file.rkt")
|
||||||
(git 'add '-A)
|
(git 'add '-A)
|
||||||
|
(git 'restore '--staged "file.rkt")
|
||||||
|
(git 'reset 'HEAD "--" "file.rkt")
|
||||||
(git 'config "user.name" "Name")
|
(git 'config "user.name" "Name")
|
||||||
(git 'commit "message")
|
(git 'commit "message")
|
||||||
(git 'branch-current)
|
(git 'branch-current)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,326 +0,0 @@
|
|||||||
/* See the beginning of "manual.css". */
|
|
||||||
|
|
||||||
/* Monospace: */
|
|
||||||
|
|
||||||
.RktIn, .RktRdr, .RktPn, .RktMeta,
|
|
||||||
.RktMod, .RktKw, .RktVar, .RktSym,
|
|
||||||
.RktRes, .RktOut, .RktCmt, .RktVal,
|
|
||||||
.RktBlk, .RktErr {
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
white-space: inherit;
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this selctor grabs the first linked Racket symbol
|
|
||||||
in a definition box (i.e., the symbol being defined) */
|
|
||||||
a.RktValDef, a.RktStxDef, a.RktSymDef,
|
|
||||||
span.RktValDef, span.RktStxDef, span.RktSymDef
|
|
||||||
{
|
|
||||||
font-size: 1.1rem;
|
|
||||||
color: black;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.inheritedlbl {
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RBackgroundLabelInner {
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Inherited methods, left margin */
|
|
||||||
|
|
||||||
.inherited {
|
|
||||||
width: 95%;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
text-align: left;
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inherited td {
|
|
||||||
font-size: 82%;
|
|
||||||
padding-left: 0.5rem;
|
|
||||||
line-height: 1.3;
|
|
||||||
text-indent: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inheritedlbl {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Racket text styles */
|
|
||||||
|
|
||||||
.RktIn {
|
|
||||||
color: #cc6633;
|
|
||||||
background-color: #eee;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktInBG {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.refcolumn .RktInBG {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktRdr {
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktPn {
|
|
||||||
color: #843c24;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktMeta {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktMod {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktOpt {
|
|
||||||
color: black;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktKw {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktErr {
|
|
||||||
color: red;
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktVar {
|
|
||||||
position: relative;
|
|
||||||
left: -1px; font-style: italic;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SVInsetFlow .RktVar {
|
|
||||||
font-weight: 400;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.RktSym {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.RktValLink, .RktStxLink, .RktModLink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #07A;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for syntax links within headings */
|
|
||||||
h1 a.RktStxLink, h2 a.RktStxLink, h3 a.RktStxLink, h4 a.RktStxLink, h5 a.RktStxLink,
|
|
||||||
h1 a.RktValLink, h2 a.RktValLink, h3 a.RktValLink, h4 a.RktValLink, h5 a.RktValLink,
|
|
||||||
h1 .RktSym, h2 .RktSym, h3 .RktSym, h4 .RktSym, h5 .RktSym,
|
|
||||||
h1 .RktMod, h2 .RktMod, h3 .RktMod, h4 .RktMod, h5 .RktMod,
|
|
||||||
h1 .RktVal, h2 .RktVal, h3 .RktVal, h4 .RktVal, h5 .RktVal,
|
|
||||||
h1 .RktPn, h2 .RktPn, h3 .RktPn, h4 .RktPn, h5 .RktPn {
|
|
||||||
color: #333;
|
|
||||||
font-size: 1.50rem;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toptoclink .RktStxLink, .toclink .RktStxLink,
|
|
||||||
.toptoclink .RktValLink, .toclink .RktValLink,
|
|
||||||
.toptoclink .RktModLink, .toclink .RktModLink {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset .RktValLink, .tocset .RktStxLink, .tocset .RktModLink, .tocset .RktSym {
|
|
||||||
color: black;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset td a.tocviewselflink .RktValLink,
|
|
||||||
.tocset td a.tocviewselflink .RktStxLink,
|
|
||||||
.tocset td a.tocviewselflink .RktMod,
|
|
||||||
.tocset td a.tocviewselflink .RktSym {
|
|
||||||
font-weight: lighter;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.RktRes {
|
|
||||||
color: #0000af;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktOut {
|
|
||||||
color: #960096;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktCmt {
|
|
||||||
color: #c2741f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktVal {
|
|
||||||
color: #228b22;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Some inline styles */
|
|
||||||
|
|
||||||
.together { /* for definitions grouped together in one box */
|
|
||||||
width: 100%;
|
|
||||||
border-top: 2px solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody > tr:first-child > td > .together {
|
|
||||||
border-top: 0px; /* erase border on first instance of together */
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktBlk {
|
|
||||||
white-space: pre;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlighted {
|
|
||||||
font-size: 1rem;
|
|
||||||
background-color: #fee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.defmodule {
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
padding: 0.25rem 0.75rem 0.25rem 0.5rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
background-color: #ebf0f4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.defmodule a {
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.defmodule td span.hspace:first-child {
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.defmodule .RpackageSpec .Smaller,
|
|
||||||
.defmodule .RpackageSpec .stt {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make parens ordinary color in defmodule */
|
|
||||||
.defmodule .RktPn {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.specgrammar {
|
|
||||||
float: none;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.RBibliography td {
|
|
||||||
vertical-align: text-top;
|
|
||||||
padding-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftindent {
|
|
||||||
margin-left: 2rem;
|
|
||||||
margin-right: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.insetpara {
|
|
||||||
margin-left: 1em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SCodeFlow .Rfilebox {
|
|
||||||
margin-left: -1em; /* see 17.2 of guide, module languages */
|
|
||||||
}
|
|
||||||
|
|
||||||
.Rfiletitle {
|
|
||||||
text-align: right;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SCodeFlow .Rfiletitle {
|
|
||||||
border-top: 1px dotted gray;
|
|
||||||
border-right: 1px dotted gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.Rfilename {
|
|
||||||
border-top: 0;
|
|
||||||
border-right: 0;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
padding-right: 0.5em;
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Rfilecontent {
|
|
||||||
margin: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RpackageSpec {
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* For background labels */
|
|
||||||
|
|
||||||
.RBackgroundLabel {
|
|
||||||
float: right;
|
|
||||||
width: 0px;
|
|
||||||
height: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RBackgroundLabelInner {
|
|
||||||
position: relative;
|
|
||||||
width: 25em;
|
|
||||||
left: -25.5em;
|
|
||||||
top: 0.20rem; /* sensitive to monospaced font choice */
|
|
||||||
text-align: right;
|
|
||||||
z-index: 0;
|
|
||||||
font-weight: 300;
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.RpackageSpec .Smaller {
|
|
||||||
font-weight: 300;
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RForeground {
|
|
||||||
position: relative;
|
|
||||||
left: 0px;
|
|
||||||
top: 0px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* For section source modules & tags */
|
|
||||||
|
|
||||||
.RPartExplain {
|
|
||||||
background: #eee;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
margin-top: 0.2rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
/* For the Racket manual style */
|
|
||||||
|
|
||||||
AddOnLoad(function() {
|
|
||||||
/* Look for header elements that have x-source-module and x-part tag.
|
|
||||||
For those elements, add a hidden element that explains how to
|
|
||||||
link to the section, and set the element's onclick() to display
|
|
||||||
the explanation. */
|
|
||||||
var tag_names = ["h1", "h2", "h3", "h4", "h5"];
|
|
||||||
for (var j = 0; j < tag_names.length; j++) {
|
|
||||||
elems = document.getElementsByTagName(tag_names[j]);
|
|
||||||
for (var i = 0; i < elems.length; i++) {
|
|
||||||
var elem = elems.item(i);
|
|
||||||
AddPartTitleOnClick(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// for copies that start in Racket code, strip out extra newlines
|
|
||||||
AddOnLoad(function() {
|
|
||||||
const codeBlocks = document.getElementsByClassName("SCodeFlow");
|
|
||||||
for (var i = 0; i < codeBlocks.length; i++) {
|
|
||||||
var codeBlock = codeBlocks[i];
|
|
||||||
console.log("add");
|
|
||||||
codeBlock.addEventListener('copy', function(e) {
|
|
||||||
var selection = window.getSelection();
|
|
||||||
var text = selection.toString();
|
|
||||||
var codeText = text.replace(/\n\n/g, '\n');
|
|
||||||
if (text != codeText) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.clipboardData.setData('text/plain', codeText);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// cache of source urls
|
|
||||||
var cache = {};
|
|
||||||
|
|
||||||
function ParseSource(source, mod_path, single_collection) {
|
|
||||||
|
|
||||||
var source_url = new URL(source);
|
|
||||||
|
|
||||||
if (source_url.protocol == "github:") {
|
|
||||||
// browser URL parser only works with http(s) URLs
|
|
||||||
source_url = new URL("https" + source.substring(6));
|
|
||||||
var host = source_url.host;
|
|
||||||
var url_path = source_url.pathname.substring(1).split("/");
|
|
||||||
if (!(url_path.length >= 2)) return null;
|
|
||||||
var user = url_path.shift();
|
|
||||||
var repo = url_path.shift();
|
|
||||||
var branch = url_path.shift();
|
|
||||||
var source_path = url_path.join("/");
|
|
||||||
}
|
|
||||||
else if (("https:" == source_url.protocol) || ("git:" == source_url.protocol)) {
|
|
||||||
// browser URL parser only works with http(s) URLs
|
|
||||||
if ("git:" == source_url.protocol)
|
|
||||||
source_url = new URL("https" + source.substring(3));
|
|
||||||
|
|
||||||
var host = source_url.host;
|
|
||||||
var source_path = source_url.searchParams.get("path");
|
|
||||||
var branch = (source_url.hash || "#master").substring(1);
|
|
||||||
var url_path = source_url.pathname.substring(1).split("/");
|
|
||||||
if (url_path.length < 2) throw [source_url.pathname, url_path];
|
|
||||||
var user = url_path.shift();
|
|
||||||
var repo = url_path.shift();
|
|
||||||
var mtch = repo.match(/(.*)\.git$/);
|
|
||||||
if (mtch) repo = mtch[1];
|
|
||||||
|
|
||||||
}
|
|
||||||
else return null;
|
|
||||||
|
|
||||||
var mod_path_re = /^\(lib "(.+)"\)$/;
|
|
||||||
|
|
||||||
var mod_path_elems = mod_path && mod_path.match(mod_path_re)[1].split("/");
|
|
||||||
|
|
||||||
if (!user || !repo || !mod_path_elems)
|
|
||||||
return null;
|
|
||||||
if (single_collection)
|
|
||||||
mod_path_elems.shift();
|
|
||||||
|
|
||||||
var file_path = mod_path_elems.join("/");
|
|
||||||
|
|
||||||
|
|
||||||
if (source_path) {
|
|
||||||
file_path = source_path + "/" + file_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { user: user,
|
|
||||||
repo: repo,
|
|
||||||
file_path: file_path,
|
|
||||||
branch: branch,
|
|
||||||
host: host };
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddSourceElement(pkg_url, info) {
|
|
||||||
info.appendChild(document.createTextNode("Document source "));
|
|
||||||
var url_line = document.createElement("div");
|
|
||||||
var a = document.createElement("a");
|
|
||||||
a.href = pkg_url;
|
|
||||||
a.style.whiteSpace = "nowrap";
|
|
||||||
a.appendChild(document.createTextNode(pkg_url));
|
|
||||||
addSpan(url_line, "\xA0", "RktRdr");
|
|
||||||
url_line.appendChild(a);
|
|
||||||
info.appendChild(url_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
var prefixes = { "github.com": "tree",
|
|
||||||
"gitlab.com": "-/blob" };
|
|
||||||
|
|
||||||
|
|
||||||
function AddSourceUrl(source, mod_path, collection, info) {
|
|
||||||
// multi is encoded as an array, empty as false
|
|
||||||
single_collection = (typeof collection === "string");
|
|
||||||
|
|
||||||
var parsed = source && mod_path && ParseSource(source, mod_path, single_collection);
|
|
||||||
|
|
||||||
if (!parsed) return;
|
|
||||||
|
|
||||||
prefix = prefixes.hasOwnProperty(parsed.host) && prefixes[parsed.host];
|
|
||||||
if (!prefix) return;
|
|
||||||
|
|
||||||
var correct_url = "https://" + [parsed.host, parsed.user, parsed.repo, prefix, parsed.branch, parsed.file_path].join("/");
|
|
||||||
|
|
||||||
if (info) AddSourceElement(correct_url, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addSpan(dest, str, cn) {
|
|
||||||
var s = document.createElement("span");
|
|
||||||
s.className = cn;
|
|
||||||
s.style.whiteSpace = "nowrap";
|
|
||||||
s.appendChild(document.createTextNode(str));
|
|
||||||
dest.appendChild(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// test cases
|
|
||||||
if (false) {
|
|
||||||
console.log(ParseSource("git://gitlab.com/benn/foo?path=xxx",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
false))
|
|
||||||
console.log(ParseSource("github://github.com/carl-eastlund/mischief/master",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
false))
|
|
||||||
console.log(ParseSource("github://github.com/carl-eastlund/mischief/stable/dir",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
false))
|
|
||||||
|
|
||||||
console.log(ParseSource("git://github.com/racket/racket/?path=pkgs/racket-doc",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
false));
|
|
||||||
|
|
||||||
console.log(ParseSource("git://github.com/rmculpepper/asn1.git?path=asn1-doc",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
true));
|
|
||||||
console.log(ParseSource("git://github.com/rmculpepper/asn1",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
true));
|
|
||||||
console.log(ParseSource("git://github.com/rmculpepper/asn1",
|
|
||||||
'(lib "asn1/scribblings/asn1.scrbl")',
|
|
||||||
false));
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddPartTitleOnClick(elem) {
|
|
||||||
var mod_path = elem.getAttribute("x-source-module");
|
|
||||||
var tag = elem.getAttribute("x-part-tag");
|
|
||||||
var source_pkg = elem.getAttribute("x-source-pkg");
|
|
||||||
|
|
||||||
// create here to share
|
|
||||||
var info = document.createElement("div");
|
|
||||||
|
|
||||||
|
|
||||||
// tag is not needed, but this way we can add the element in only one place
|
|
||||||
// avoid failing on browser that don't have `fetch`
|
|
||||||
if (mod_path && source_pkg && tag && window.fetch) {
|
|
||||||
|
|
||||||
var cached = cache[mod_path]
|
|
||||||
if (cached) {
|
|
||||||
AddSourceElement(cached[0], mod_path, cached[1], info);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fetch("https://pkgs.racket-lang.org/pkg/" + source_pkg + ".json")
|
|
||||||
.then(function (response) { return response.json(); })
|
|
||||||
.then(function (data) {
|
|
||||||
var vers = data["versions"] || {};
|
|
||||||
var def = vers["default"] || {};
|
|
||||||
var source = def["source"] || undefined;
|
|
||||||
var collection = data["collection"];
|
|
||||||
if (source) {
|
|
||||||
cache[mod_path] = [source, collection];
|
|
||||||
AddSourceUrl(source, mod_path, collection, info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mod_path && tag) {
|
|
||||||
// Might not be present:
|
|
||||||
var prefixes = elem.getAttribute("x-part-prefixes");
|
|
||||||
|
|
||||||
info.className = "RPartExplain";
|
|
||||||
|
|
||||||
/* The "top" tag refers to a whole document: */
|
|
||||||
var is_top = (tag == "\"top\"");
|
|
||||||
info.appendChild(document.createTextNode("Link to this "
|
|
||||||
+ (is_top ? "document" : "section")
|
|
||||||
+ " with "));
|
|
||||||
|
|
||||||
/* Break `secref` into two lines if the module path and tag
|
|
||||||
are long enough: */
|
|
||||||
var is_long = (is_top ? false : ((mod_path.length
|
|
||||||
+ tag.length
|
|
||||||
+ (prefixes ? (16 + prefixes.length) : 0))
|
|
||||||
> 60));
|
|
||||||
|
|
||||||
var line1 = document.createElement("div");
|
|
||||||
var line1x = ((is_long && prefixes) ? document.createElement("div") : line1);
|
|
||||||
var line2 = (is_long ? document.createElement("div") : line1);
|
|
||||||
|
|
||||||
/* Construct a `secref` call with suitable syntax coloring: */
|
|
||||||
addSpan(line1, "\xA0@", "RktRdr");
|
|
||||||
addSpan(line1, (is_top ? "other-doc" : "secref"), "RktSym");
|
|
||||||
addSpan(line1, "[", "RktPn");
|
|
||||||
if (!is_top)
|
|
||||||
addSpan(line1, tag, "RktVal");
|
|
||||||
if (is_long) {
|
|
||||||
/* indent additional lines: */
|
|
||||||
if (prefixes)
|
|
||||||
addSpan(line1x, "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0", "RktPn");
|
|
||||||
addSpan(line2, "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0", "RktPn");
|
|
||||||
}
|
|
||||||
if (prefixes) {
|
|
||||||
addSpan(line1x, " #:tag-prefixes ", "RktPn");
|
|
||||||
addSpan(line1x, "'", "RktVal");
|
|
||||||
addSpan(line1x, prefixes, "RktVal");
|
|
||||||
}
|
|
||||||
if (!is_top)
|
|
||||||
addSpan(line2, " #:doc ", "RktPn");
|
|
||||||
addSpan(line2, "'", "RktVal");
|
|
||||||
addSpan(line2, mod_path, "RktVal");
|
|
||||||
addSpan(line2, "]", "RktPn");
|
|
||||||
|
|
||||||
info.appendChild(line1);
|
|
||||||
if (is_long)
|
|
||||||
info.appendChild(line1x);
|
|
||||||
if (is_long)
|
|
||||||
info.appendChild(line2);
|
|
||||||
|
|
||||||
info.style.display = "none";
|
|
||||||
|
|
||||||
/* Add the new element afterthe header: */
|
|
||||||
var n = elem.nextSibling;
|
|
||||||
if (n)
|
|
||||||
elem.parentNode.insertBefore(info, n);
|
|
||||||
else
|
|
||||||
elem.parentNode.appendChild(info);
|
|
||||||
|
|
||||||
/* Clicking the information button shows the explanation element: */
|
|
||||||
const heading = elem.querySelector('.heading-source');
|
|
||||||
if (heading) {
|
|
||||||
heading.onclick = function () {
|
|
||||||
if (info.style.display === "none")
|
|
||||||
info.style.display = "block";
|
|
||||||
else
|
|
||||||
info.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,815 +0,0 @@
|
|||||||
|
|
||||||
/* See the beginning of "scribble.css".
|
|
||||||
This file is used by the `scribble/manual` language, along with
|
|
||||||
"manual-racket.css". */
|
|
||||||
|
|
||||||
@import url("manual-fonts.css");
|
|
||||||
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all {html {font-size: 15px;}}
|
|
||||||
@media all and (max-width:940px){html {font-size: 14px;}}
|
|
||||||
@media all and (max-width:850px){html {font-size: 13px;}}
|
|
||||||
@media all and (max-width:830px){html {font-size: 12px;}}
|
|
||||||
@media all and (max-width:740px){html {font-size: 11px;}}
|
|
||||||
|
|
||||||
/* CSS seems backward: List all the classes for which we want a
|
|
||||||
particular font, so that the font can be changed in one place. (It
|
|
||||||
would be nicer to reference a font definition from all the places
|
|
||||||
that we want it.)
|
|
||||||
|
|
||||||
As you read the rest of the file, remember to double-check here to
|
|
||||||
see if any font is set. */
|
|
||||||
|
|
||||||
/* Monospace: */
|
|
||||||
.maincolumn, .refpara, .refelem, .tocset, .stt, .hspace, .refparaleft, .refelemleft {
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
white-space: inherit;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable heading-source */
|
|
||||||
.button-group > .heading-source {
|
|
||||||
visibility: inherit;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
color: gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* embolden the "Racket Guide" and "Racket Reference" links on the TOC */
|
|
||||||
/* there isn't an obvious tag in the markup that designates the top TOC page, which is called "start.scrbl" */
|
|
||||||
/* nor a tag that designates these two links as special */
|
|
||||||
/* so we'll use this slightly tortured sibling selector that hooks onto the h1 tag */
|
|
||||||
h1[x-source-module='(lib "scribblings/main/start.scrbl")'] ~ table a[href="guide/index.html"],
|
|
||||||
h1[x-source-module='(lib "scribblings/main/start.scrbl")'] ~ table a[href="reference/index.html"] {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
h1 .stt {
|
|
||||||
font-size: 2.3rem;
|
|
||||||
/* prevent automatic bolding from h1 */
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toptoclink .stt {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
.toclink .stt {
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RpackageSpec .stt {
|
|
||||||
font-weight: 300;
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 .stt, h3 .stt, h4 .stt, h5 .stt {
|
|
||||||
color: #333;
|
|
||||||
font-size: 1.65rem;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Serif: */
|
|
||||||
.main, .refcontent, .tocview, .tocsub, .sroman, i {
|
|
||||||
font-family: 'Charter-Racket', serif;
|
|
||||||
font-size: 1.18rem;
|
|
||||||
/* Don't use font-feature-settings with Charter,
|
|
||||||
it fouls up loading for reasons mysterious */
|
|
||||||
/* font-feature-settings: 'tnum' 1, 'liga' 0; */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Sans-serif: */
|
|
||||||
.version, .versionNoNav, .ssansserif, .navfamily, .famlink {
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* used mostly for DrRacket menu commands */
|
|
||||||
.ssansserif {
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset .ssansserif {
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
|
|
||||||
p, .SIntrapara {
|
|
||||||
display: block;
|
|
||||||
margin: 0 0 1em 0;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.compact {
|
|
||||||
padding: 0 0 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
list-style-position: outside;
|
|
||||||
margin-left: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6, h7, h8 {
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
color: #333;
|
|
||||||
margin-top: inherit;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
line-height: 1.25;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
h2, h3, h4, h5, h6, h7, h8 {
|
|
||||||
border-top: 1px solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
h1 { /* per-page main title */
|
|
||||||
font-family: 'Cooper-Hewitt';
|
|
||||||
margin-top: 4rem;
|
|
||||||
font-size: 2.3rem;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 1.2;
|
|
||||||
width: 90%;
|
|
||||||
/* a little nudge to make text visually lower than 4rem rule in left margin */
|
|
||||||
position: relative;
|
|
||||||
top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2, h3, h4, h5, h6, h7, h8 {
|
|
||||||
margin-top: 2em;
|
|
||||||
padding-top: 0.1em;
|
|
||||||
margin-bottom: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Main */
|
|
||||||
|
|
||||||
body {
|
|
||||||
color: black;
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.maincolumn {
|
|
||||||
width: auto;
|
|
||||||
margin-top: 4rem;
|
|
||||||
margin-left: 17rem;
|
|
||||||
margin-right: 2rem;
|
|
||||||
margin-bottom: 10rem; /* to avoid fixed bottom nav bar */
|
|
||||||
max-width: 700px;
|
|
||||||
min-width: 370px; /* below this size, code samples don't fit */
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
a, .toclink, .toptoclink, .tocviewlink, .tocviewselflink, .tocviewtoggle, .plainlink,
|
|
||||||
.techinside, .techoutside:hover, .techinside:hover {
|
|
||||||
color: #07A;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Navigation */
|
|
||||||
|
|
||||||
.navsettop, .navsetbottom {
|
|
||||||
left: 0;
|
|
||||||
width: 15rem;
|
|
||||||
height: 6rem;
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
border-bottom: 0px solid hsl(216, 15%, 70%);
|
|
||||||
background-color: inherit;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navsettop {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 2;
|
|
||||||
background: #a7b0be;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navsettop a, .navsetbottom a {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navsettop a:hover, .navsetbottom a:hover {
|
|
||||||
background: hsl(216, 78%, 95%);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navleft, .navright {
|
|
||||||
position: static;
|
|
||||||
float: none;
|
|
||||||
margin: 0;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.navleft a {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navright a {
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navleft a, .navright a, .navright span {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.5rem;
|
|
||||||
min-width: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.navright {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.navsetbottom {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nonavigation {
|
|
||||||
color: #889;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchform {
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
height: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nosearchform {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
height: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchbox {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
width: 12rem;
|
|
||||||
margin: 1rem;
|
|
||||||
padding: 0.25rem 0.4rem ;
|
|
||||||
vertical-align: middle;
|
|
||||||
background-color: white;
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#search_box {
|
|
||||||
font-family: 'Fira-Mono', monospace;
|
|
||||||
font-size: 1rem;
|
|
||||||
padding: 0.25rem 0.3rem ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Default to local view. Global will specialize */
|
|
||||||
.plt_global_only { display: none; }
|
|
||||||
.plt_local_only { display: block; }
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Version */
|
|
||||||
|
|
||||||
.versionbox {
|
|
||||||
position: absolute;
|
|
||||||
float: none;
|
|
||||||
top: 0.25rem;
|
|
||||||
left: 17rem;
|
|
||||||
z-index: 11000;
|
|
||||||
height: 2em;
|
|
||||||
font-size: 70%;
|
|
||||||
font-weight: lighter;
|
|
||||||
width: inherit;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.version, .versionNoNav {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
.version:before, .versionNoNav:before {
|
|
||||||
content: "v";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Language Family */
|
|
||||||
|
|
||||||
.navfamily {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
left: 100%;
|
|
||||||
width: 13em;
|
|
||||||
margin-top: -4.75em;
|
|
||||||
margin-right: -15em;
|
|
||||||
font-size: 70%;
|
|
||||||
font-weight: lighter;
|
|
||||||
height: auto;
|
|
||||||
padding-top: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Margin notes */
|
|
||||||
|
|
||||||
/* cancel scribble.css styles: */
|
|
||||||
.refpara, .refelem {
|
|
||||||
position: static;
|
|
||||||
float: none;
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcolumn {
|
|
||||||
position: static;
|
|
||||||
display: block;
|
|
||||||
width: auto;
|
|
||||||
font-size: inherit;
|
|
||||||
margin: 2rem;
|
|
||||||
margin-left: 2rem;
|
|
||||||
padding: 0.5em;
|
|
||||||
padding-left: 0.75em;
|
|
||||||
padding-right: 1em;
|
|
||||||
background: hsl(60, 29%, 94%);
|
|
||||||
border: 1px solid #ccb;
|
|
||||||
border-left: 0.4rem solid #ccb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* slightly different handling for margin-note* on narrow screens */
|
|
||||||
@media all and (max-width:1340px) {
|
|
||||||
span.refcolumn {
|
|
||||||
float: right;
|
|
||||||
width: 50%;
|
|
||||||
margin-left: 1rem;
|
|
||||||
margin-bottom: 0.8rem;
|
|
||||||
margin-top: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navfamily {
|
|
||||||
position: static;
|
|
||||||
margin: -4.75em 0em 0em 0em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcontent, .refcontent p {
|
|
||||||
line-height: 1.5;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcontent p + p {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcontent a {
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refpara, .refparaleft {
|
|
||||||
top: -1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media all and (max-width:600px) {
|
|
||||||
.refcolumn {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media all and (min-width:1340px) {
|
|
||||||
.refcolumn {
|
|
||||||
margin: 0 -22.5rem 1rem 0;
|
|
||||||
float: right;
|
|
||||||
clear: right;
|
|
||||||
width: 18rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcontent {
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.6;
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.refparaleft, .refelemleft {
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
right: 2em;
|
|
||||||
height: 0em;
|
|
||||||
width: 13em;
|
|
||||||
margin: 0em 0em 0em 0em;
|
|
||||||
display: contents;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcolumnleft {
|
|
||||||
background-color: hsl(60, 29%, 94%);
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
width: 13em;
|
|
||||||
font-size: 85%;
|
|
||||||
border: 0.5em solid hsl(60, 29%, 94%);
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Table of contents, left margin */
|
|
||||||
|
|
||||||
.tocset {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 2;
|
|
||||||
overflow-y: scroll;
|
|
||||||
float: none;
|
|
||||||
left: 0;
|
|
||||||
top: 0rem;
|
|
||||||
bottom: 0;
|
|
||||||
width: 14rem;
|
|
||||||
padding: 0rem 0.5rem 0.5rem 0.5rem;
|
|
||||||
background-color: hsl(216, 15%, 70%);
|
|
||||||
border-top: 6rem solid hsl(216, 15%, 70%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset td {
|
|
||||||
vertical-align: text-top;
|
|
||||||
padding-bottom: 0.4rem;
|
|
||||||
padding-left: 0.2rem;
|
|
||||||
line-height: 1.1;
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset td a {
|
|
||||||
color: black;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.tocview {
|
|
||||||
text-align: left;
|
|
||||||
background-color: inherit;
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.tocview td, .tocsub td {
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.tocview table, .tocsub table {
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset td a.tocviewselflink {
|
|
||||||
font-weight: lighter;
|
|
||||||
font-size: 110%; /* monospaced styles below don't need to enlarge */
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewselflink {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsub {
|
|
||||||
text-align: left;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewlist, .tocsublist {
|
|
||||||
margin-left: 0.2em;
|
|
||||||
margin-right: 0.2em;
|
|
||||||
padding-top: 0.2em;
|
|
||||||
padding-bottom: 0.2em;
|
|
||||||
}
|
|
||||||
.tocviewlist table {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewlisttopspace {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewsublist, .tocviewsublistonly, .tocviewsublisttop, .tocviewsublistbottom {
|
|
||||||
margin-left: 0.4em;
|
|
||||||
border-left: 1px solid #99a;
|
|
||||||
padding-left: 0.8em;
|
|
||||||
}
|
|
||||||
.tocviewsublist {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
.tocviewsublist table,
|
|
||||||
.tocviewsublistonly table,
|
|
||||||
.tocviewsublisttop table,
|
|
||||||
.tocviewsublistbottom table,
|
|
||||||
table.tocsublist {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewsublist td,
|
|
||||||
.tocviewsublistbottom td,
|
|
||||||
.tocviewsublisttop td,
|
|
||||||
.tocsub td,
|
|
||||||
.tocviewsublistonly td {
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* shrink the monospaced text (`stt`) within nav */
|
|
||||||
.tocviewsublist td .stt,
|
|
||||||
.tocviewsublistbottom td .stt,
|
|
||||||
.tocviewsublisttop td .stt,
|
|
||||||
.tocsub td .stt,
|
|
||||||
.tocviewsublistonly td .stt {
|
|
||||||
font-size: 95%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.tocviewtoggle {
|
|
||||||
font-size: 75%; /* looks better, and avoids bounce when toggling sub-sections due to font alignments */
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsublist td {
|
|
||||||
padding-left: 0.5rem;
|
|
||||||
padding-top: 0.25rem;
|
|
||||||
text-indent: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsublinknumber {
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsublink {
|
|
||||||
font-size: 82%;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsubseclink {
|
|
||||||
font-size: 100%;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsubnonseclink {
|
|
||||||
font-size: 82%;
|
|
||||||
text-decoration: none;
|
|
||||||
margin-left: 1rem;
|
|
||||||
padding-left: 0;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the label "on this page" */
|
|
||||||
.tocsubtitle {
|
|
||||||
display: block;
|
|
||||||
font-size: 62%;
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
font-weight: bolder;
|
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
margin: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toptoclink {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 110%;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toclink {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Some inline styles */
|
|
||||||
|
|
||||||
.indexlink {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
margin-left: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
margin-left: 2em;
|
|
||||||
margin-right: 2em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SCodeFlow {
|
|
||||||
border-left: 1px dotted black;
|
|
||||||
padding-left: 1em;
|
|
||||||
padding-right: 1em;
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
margin-left: 0em;
|
|
||||||
margin-right: 2em;
|
|
||||||
white-space: nowrap;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SCodeFlow img {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put a little air between lines of code sample */
|
|
||||||
/* Fira Mono appears taller than Source Code Pro */
|
|
||||||
.SCodeFlow td {
|
|
||||||
padding-bottom: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boxed {
|
|
||||||
margin: 0;
|
|
||||||
margin-top: 2em;
|
|
||||||
padding: 0.25em;
|
|
||||||
padding-top: 0.3em;
|
|
||||||
padding-bottom: 0.4em;
|
|
||||||
background: #f3f3f3;
|
|
||||||
box-sizing:border-box;
|
|
||||||
border-top: 1px solid #99b;
|
|
||||||
background: hsl(216, 78%, 95%);
|
|
||||||
background: -moz-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%);
|
|
||||||
background: -webkit-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%);
|
|
||||||
background: -o-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%);
|
|
||||||
background: -ms-linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%);
|
|
||||||
background: linear-gradient(to bottom left, hsl(0, 0%, 99%) 0%, hsl(216, 62%, 95%) 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote > blockquote.SVInsetFlow {
|
|
||||||
/* resolves issue in e.g. /reference/notation.html */
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftindent .SVInsetFlow { /* see e.g. section 4.5 of Racket Guide */
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SVInsetFlow a, .SCodeFlow a {
|
|
||||||
color: #07A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SubFlow {
|
|
||||||
display: block;
|
|
||||||
margin: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boxed {
|
|
||||||
width: 100%;
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.techoutside { text-decoration: none; }
|
|
||||||
|
|
||||||
.SAuthorListBox {
|
|
||||||
position: static;
|
|
||||||
float: none;
|
|
||||||
font-family: 'Fira', sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 110%;
|
|
||||||
margin-top: 1rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
width: 30rem;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.author > a { /* email links within author block */
|
|
||||||
font-weight: inherit;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SAuthorList {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
.SAuthorList:before {
|
|
||||||
content: "by ";
|
|
||||||
}
|
|
||||||
.author {
|
|
||||||
display: inline;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* phone + tablet styles */
|
|
||||||
|
|
||||||
@media all and (max-width:720px){
|
|
||||||
|
|
||||||
|
|
||||||
@media all and (max-width:720px){
|
|
||||||
|
|
||||||
@media all {html {font-size: 15px;}}
|
|
||||||
@media all and (max-width:700px){html {font-size: 14px;}}
|
|
||||||
@media all and (max-width:630px){html {font-size: 13px;}}
|
|
||||||
@media all and (max-width:610px){html {font-size: 12px;}}
|
|
||||||
@media all and (max-width:550px){html {font-size: 11px;}}
|
|
||||||
@media all and (max-width:520px){html {font-size: 10px;}}
|
|
||||||
|
|
||||||
.navsettop, .navsetbottom {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 4rem;
|
|
||||||
border: 0;
|
|
||||||
background-color: hsl(216, 15%, 70%);
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsetoverlay .navsettop {
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navleft {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchform {
|
|
||||||
display: inline;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchbox {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navleft .tocsettoggle {
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navright {
|
|
||||||
margin-right: 1.3rem;
|
|
||||||
border: 0px solid red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navsetbottom {
|
|
||||||
display: block;
|
|
||||||
margin-top: 8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocset {
|
|
||||||
display: none;
|
|
||||||
border-top-width: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsetoverlay .tocset {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.versionbox {
|
|
||||||
top: 4.5rem;
|
|
||||||
left: 1rem; /* same distance as main-column */
|
|
||||||
z-index: 1;
|
|
||||||
height: 2em;
|
|
||||||
font-size: 70%;
|
|
||||||
font-weight: lighter;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navfamily {
|
|
||||||
position: static;
|
|
||||||
margin: -3.25em 0em 0em 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.maincolumn {
|
|
||||||
margin-left: 1em;
|
|
||||||
margin-top: 7rem;
|
|
||||||
margin-bottom: 0rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* print styles : hide the navigation elements */
|
|
||||||
@media print {
|
|
||||||
.tocset,
|
|
||||||
.navsettop,
|
|
||||||
.navsetbottom { display: none; }
|
|
||||||
.maincolumn {
|
|
||||||
width: auto;
|
|
||||||
margin-right: 13em;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
|
|
||||||
/* See the beginning of "scribble.css". */
|
|
||||||
|
|
||||||
/* Monospace: */
|
|
||||||
.RktIn, .RktRdr, .RktPn, .RktMeta,
|
|
||||||
.RktMod, .RktKw, .RktVar, .RktSym,
|
|
||||||
.RktRes, .RktOut, .RktCmt, .RktVal,
|
|
||||||
.RktBlk {
|
|
||||||
font-family: monospace;
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Serif: */
|
|
||||||
.inheritedlbl {
|
|
||||||
font-family: serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sans-serif: */
|
|
||||||
.RBackgroundLabelInner {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Inherited methods, left margin */
|
|
||||||
|
|
||||||
.inherited {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
text-align: left;
|
|
||||||
background-color: #ECF5F5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inherited td {
|
|
||||||
font-size: 82%;
|
|
||||||
padding-left: 1em;
|
|
||||||
text-indent: -0.8em;
|
|
||||||
padding-right: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inheritedlbl {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Racket text styles */
|
|
||||||
|
|
||||||
.RktIn {
|
|
||||||
color: #cc6633;
|
|
||||||
background-color: #eeeeee;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktInBG {
|
|
||||||
background-color: #eeeeee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktRdr {
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktPn {
|
|
||||||
color: #843c24;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktMeta {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktMod {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktOpt {
|
|
||||||
color: black;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktKw {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktErr {
|
|
||||||
color: red;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktVar {
|
|
||||||
color: #262680;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktSym {
|
|
||||||
color: #262680;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktSymDef { /* used with RktSym at def site */
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktValLink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktValDef { /* used with RktValLink at def site */
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktModLink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktStxLink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktStxDef { /* used with RktStxLink at def site */
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktRes {
|
|
||||||
color: #0000af;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktOut {
|
|
||||||
color: #960096;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktCmt {
|
|
||||||
color: #c2741f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktVal {
|
|
||||||
color: #228b22;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Some inline styles */
|
|
||||||
|
|
||||||
.together {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prototype, .argcontract, .RBoxed {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prototype td {
|
|
||||||
vertical-align: text-top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktBlk {
|
|
||||||
white-space: inherit;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktBlk tr {
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RktBlk td {
|
|
||||||
vertical-align: baseline;
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.argcontract td {
|
|
||||||
vertical-align: text-top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlighted {
|
|
||||||
background-color: #ddddff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.defmodule {
|
|
||||||
width: 100%;
|
|
||||||
background-color: #F5F5DC;
|
|
||||||
}
|
|
||||||
|
|
||||||
.specgrammar {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RBibliography td {
|
|
||||||
vertical-align: text-top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftindent {
|
|
||||||
margin-left: 1em;
|
|
||||||
margin-right: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.insetpara {
|
|
||||||
margin-left: 1em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Rfilebox {
|
|
||||||
}
|
|
||||||
|
|
||||||
.Rfiletitle {
|
|
||||||
text-align: right;
|
|
||||||
margin: 0em 0em 0em 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Rfilename {
|
|
||||||
border-top: 1px solid #6C8585;
|
|
||||||
border-right: 1px solid #6C8585;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
padding-right: 0.5em;
|
|
||||||
background-color: #ECF5F5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Rfilecontent {
|
|
||||||
margin: 0em 0em 0em 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RpackageSpec {
|
|
||||||
padding-right: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* For background labels */
|
|
||||||
|
|
||||||
.RBackgroundLabel {
|
|
||||||
float: right;
|
|
||||||
width: 0px;
|
|
||||||
height: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RBackgroundLabelInner {
|
|
||||||
position: relative;
|
|
||||||
width: 25em;
|
|
||||||
left: -25.5em;
|
|
||||||
top: 0px;
|
|
||||||
text-align: right;
|
|
||||||
color: white;
|
|
||||||
z-index: 0;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.RForeground {
|
|
||||||
position: relative;
|
|
||||||
left: 0px;
|
|
||||||
top: 0px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* History */
|
|
||||||
|
|
||||||
.SHistory {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
@@ -1,263 +0,0 @@
|
|||||||
// Common functionality for PLT documentation pages
|
|
||||||
|
|
||||||
// Page Parameters ------------------------------------------------------------
|
|
||||||
|
|
||||||
var plt_root_as_query = false;
|
|
||||||
|
|
||||||
function GetURL() {
|
|
||||||
return new URL(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetPageArgs() {
|
|
||||||
return GetURL().searchParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetPageQueryString() {
|
|
||||||
return GetPageArgs().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetPageArg(key, def) {
|
|
||||||
return GetPageArgs().get(key) || def;
|
|
||||||
}
|
|
||||||
|
|
||||||
function MergePageArgsIntoLink(a) {
|
|
||||||
if ((GetPageArgs().size === 0 || !a.dataset.pltdoc) && !plt_root_as_query) return;
|
|
||||||
a.href = MergePageArgsIntoUrl(a.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MergePageArgsIntoUrl(href) {
|
|
||||||
const url = new URL(href, window.location.href);
|
|
||||||
MergePageArgsIntoUrlObject(url);
|
|
||||||
return url.href;
|
|
||||||
}
|
|
||||||
|
|
||||||
function MergePageArgsIntoUrlObject(url) {
|
|
||||||
for (const [key, val] of GetPageArgs()) {
|
|
||||||
if (key[0] == "q") continue; // use "q" to mean "don't propagate automatcially"
|
|
||||||
if (url.searchParams.has(key)) continue;
|
|
||||||
url.searchParams.append(key, val)
|
|
||||||
}
|
|
||||||
if (plt_root_as_query && !url.searchParams.has("PLT_Root")) {
|
|
||||||
url.searchParams.append("PLT_Root", plt_root_as_query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cookies --------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Actually, try localStorage (a la HTML 5), first.
|
|
||||||
|
|
||||||
function GetCookie(key, def) {
|
|
||||||
try {
|
|
||||||
var v = localStorage[key];
|
|
||||||
if (!v) v = def;
|
|
||||||
return v;
|
|
||||||
} catch (e) {
|
|
||||||
var i, cookiestrs;
|
|
||||||
try {
|
|
||||||
if (document.cookie.length <= 0) return def;
|
|
||||||
cookiestrs = document.cookie.split(/; */);
|
|
||||||
} catch (e) { return def; }
|
|
||||||
for (i = 0; i < cookiestrs.length; i++) {
|
|
||||||
var cur = cookiestrs[i];
|
|
||||||
var eql = cur.indexOf('=');
|
|
||||||
if (eql >= 0 && cur.substring(0,eql) == key)
|
|
||||||
return unescape(cur.substring(eql+1));
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetCookie(key, val) {
|
|
||||||
try {
|
|
||||||
localStorage[key] = val;
|
|
||||||
} catch(e) {
|
|
||||||
var d = new Date();
|
|
||||||
d.setTime(d.getTime()+(365*24*60*60*1000));
|
|
||||||
try {
|
|
||||||
document.cookie =
|
|
||||||
key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/";
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// note that this always stores a directory name, ending with a "/"
|
|
||||||
function SetPLTRoot(ver, relative) {
|
|
||||||
var root = location.protocol + "//" + location.host
|
|
||||||
+ NormalizePath(location.pathname.replace(/[^\/]*$/, relative));
|
|
||||||
if (location.protocol == "file:") {
|
|
||||||
// local storage or cookies are not going to work in modern browsers,
|
|
||||||
// so add a query parameter to all URLs
|
|
||||||
plt_root_as_query=root
|
|
||||||
} else {
|
|
||||||
SetCookie("PLT_Root."+ver, root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// adding index.html works because of the above
|
|
||||||
function GotoPLTRoot(ver, root_relative, here_to_root_relative) {
|
|
||||||
// the relative path is optional, default goes to the toplevel start page
|
|
||||||
if (!root_relative) root_relative = "index.html";
|
|
||||||
if (here_to_root_relative == undefined) here_to_root_relative = "../"
|
|
||||||
var famroot = false;
|
|
||||||
if (root_relative == "index.html") {
|
|
||||||
famroot = (GetPageArg("fam", false) ? GetPageArg("famroot", false) : false)
|
|
||||||
if (famroot) {
|
|
||||||
root_relative = famroot + "/index.html";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var u = GetRootPath(ver);
|
|
||||||
if (u == null) {
|
|
||||||
if (famroot) {
|
|
||||||
location = MergePageArgsIntoUrl(here_to_root_relative + famroot + "/index.html");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// no cookie and no famroot => follow href, instead
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
location = MergePageArgsIntoUrl(u + root_relative);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetRootPath(ver) {
|
|
||||||
var u = GetCookie("PLT_Root."+ver, null);
|
|
||||||
if (u != null)
|
|
||||||
return u;
|
|
||||||
|
|
||||||
// via query argument? (especially for `file://` URLs)
|
|
||||||
u = GetPageArg("PLT_Root", null)
|
|
||||||
if (u != null)
|
|
||||||
return u;
|
|
||||||
|
|
||||||
// use root specified by local-redirect wrapper, if present
|
|
||||||
if (typeof user_doc_root != "undefined")
|
|
||||||
return user_doc_root;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utilities ------------------------------------------------------------------
|
|
||||||
|
|
||||||
var normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/];
|
|
||||||
function NormalizePath(path) {
|
|
||||||
var tmp, i;
|
|
||||||
for (i = 0; i < normalize_rxs.length; i++)
|
|
||||||
while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp;
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// `noscript' is problematic in some browsers (always renders as a
|
|
||||||
// block), use this hack instead (does not always work!)
|
|
||||||
// document.write("<style>mynoscript { display:none; }</style>");
|
|
||||||
|
|
||||||
// Interactions ---------------------------------------------------------------
|
|
||||||
|
|
||||||
function DoSearchKey(event, field, ver, top_path) {
|
|
||||||
var val = field.value;
|
|
||||||
if (event && event.key === 'Enter') {
|
|
||||||
var u = GetRootPath(ver);
|
|
||||||
if (u == null) u = top_path; // default: go to the top path
|
|
||||||
u += "search/index.html?q=" + encodeURIComponent(val);
|
|
||||||
u = MergePageArgsIntoUrl(u);
|
|
||||||
location = u;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function TocviewToggle(glyph, id) {
|
|
||||||
var s = document.getElementById(id).style;
|
|
||||||
var expand = s.display == "none";
|
|
||||||
s.display = expand ? "block" : "none";
|
|
||||||
glyph.innerHTML = expand ? "▼" : "►";
|
|
||||||
}
|
|
||||||
|
|
||||||
function TocsetToggle() {
|
|
||||||
document.body.classList.toggle("tocsetoverlay");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page Init ------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Note: could make a function that inspects and uses window.onload to chain to
|
|
||||||
// a previous one, but this file needs to be required first anyway, since it
|
|
||||||
// contains utilities for all other files.
|
|
||||||
var on_load_funcs = [];
|
|
||||||
function AddOnLoad(fun) { on_load_funcs.push(fun); }
|
|
||||||
window.onload = function() {
|
|
||||||
for (var i=0; i<on_load_funcs.length; i++) on_load_funcs[i]();
|
|
||||||
};
|
|
||||||
|
|
||||||
AddOnLoad(function(){
|
|
||||||
var links = document.getElementsByTagName("a");
|
|
||||||
for (var i=0; i<links.length; i++) MergePageArgsIntoLink(links[i]);
|
|
||||||
var label = GetPageArg("ctxtname",false);
|
|
||||||
if (!label) return;
|
|
||||||
var indicator = document.getElementById("contextindicator");
|
|
||||||
if (!indicator) return;
|
|
||||||
indicator.innerHTML = label;
|
|
||||||
indicator.style.display = "block";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Pressing "S" or "s" focuses on the "...search manuals..." text field
|
|
||||||
AddOnLoad(function(){
|
|
||||||
window.addEventListener("keyup", function(e) {
|
|
||||||
if ((e.key === 's' || e.key === 'S') && e.target === document.body) {
|
|
||||||
var searchBox = document.getElementById('searchbox');
|
|
||||||
if (searchBox) {
|
|
||||||
searchBox.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddOnLoad(function(){
|
|
||||||
var es = document.getElementsByClassName("family-navigation");
|
|
||||||
if (es.length > 0) {
|
|
||||||
var fams = es[0].dataset.familynav.split(/,/);
|
|
||||||
var fam = GetPageArg("famroot", false) && GetPageArg("fam", false);
|
|
||||||
if (!fam) fam = "Racket";
|
|
||||||
if (fams.indexOf(fam) == -1) {
|
|
||||||
for (var i=0; i < es.length; i++) {
|
|
||||||
es[i].style.display = "inline-block";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AddOnLoad(function(){
|
|
||||||
var es = document.getElementsByClassName("navfamily");
|
|
||||||
for (var i=0; i < es.length; i++) {
|
|
||||||
var e = es[i];
|
|
||||||
if (e.dataset.fam != undefined) {
|
|
||||||
var fams = e.dataset.fam.split(/,/);
|
|
||||||
var fam = GetPageArg("fam", false);
|
|
||||||
if (!fam) fam = "Racket";
|
|
||||||
var link = document.createElement('a');
|
|
||||||
var root = GetRootPath(e.dataset.version)
|
|
||||||
var family_url;
|
|
||||||
if (root == null) {
|
|
||||||
family_url = new URL(e.dataset.famPath + "family/index.html", window.location.href);
|
|
||||||
} else {
|
|
||||||
family_url = new URL(root + "family/index.html", window.location.href);
|
|
||||||
}
|
|
||||||
family_url.searchParams.append("qfrom", window.location.href)
|
|
||||||
MergePageArgsIntoUrlObject(family_url);
|
|
||||||
if (fams.indexOf(fam) == -1) {
|
|
||||||
var nav_as = document.createElement('div');
|
|
||||||
link.textContent = "navigating as " + fam;
|
|
||||||
link.href = family_url
|
|
||||||
nav_as.appendChild(link)
|
|
||||||
e.appendChild(nav_as)
|
|
||||||
} else {
|
|
||||||
var link = document.createElement('a');
|
|
||||||
var span = e.children[0]
|
|
||||||
link.textContent = span.textContent;
|
|
||||||
link.href = family_url
|
|
||||||
span.textContent = ''; // Clear span
|
|
||||||
e.removeChild(span);
|
|
||||||
link.appendChild(span);
|
|
||||||
e.appendChild(link);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,587 +0,0 @@
|
|||||||
|
|
||||||
/* This file is used by default by all Scribble documents.
|
|
||||||
See also "manual.css", which is added by default by the
|
|
||||||
`scribble/manual` language. */
|
|
||||||
|
|
||||||
/* CSS seems backward: List all the classes for which we want a
|
|
||||||
particular font, so that the font can be changed in one place. (It
|
|
||||||
would be nicer to reference a font definition from all the places
|
|
||||||
that we want it.)
|
|
||||||
|
|
||||||
As you read the rest of the file, remember to double-check here to
|
|
||||||
see if any font is set. */
|
|
||||||
|
|
||||||
/* Monospace: */
|
|
||||||
.maincolumn, .refpara, .refelem, .tocset, .stt, .hspace, .refparaleft, .refelemleft, .reffootnote {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Serif: */
|
|
||||||
.main, .refcontent, .tocview, .tocsub, .sroman, i {
|
|
||||||
font-family: serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sans-serif: */
|
|
||||||
.version, .versionNoNav, .ssansserif, .navfamily {
|
|
||||||
font-family: sans-serif;
|
|
||||||
}
|
|
||||||
.ssansserif {
|
|
||||||
font-size: 80%;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emphasis: alternate italics and normal as we nest */
|
|
||||||
.emph {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.emph .emph {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
.emph .emph .emph {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.emph .emph .emph .emph {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
.emph .emph .emph .emph .emph {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.emph .emph .emph .emph .emph .emph {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
|
|
||||||
p, .SIntrapara {
|
|
||||||
display: block;
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 { /* per-page main title */
|
|
||||||
font-size: 1.5em;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2, h3, h4, h5, h6, h7, h8 {
|
|
||||||
margin-top: 1.75em;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 1.17em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.00em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 0.83em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SSubSubSubSection {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 0.83em; /* should match h5; from HTML 4 reference */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Needed for browsers like Opera, and eventually for HTML 4 conformance.
|
|
||||||
This means that multiple paragraphs in a table element do not have a space
|
|
||||||
between them. */
|
|
||||||
table p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Main */
|
|
||||||
|
|
||||||
body {
|
|
||||||
color: black;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
table td {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.maincolumn {
|
|
||||||
width: 43em;
|
|
||||||
margin-right: -40em;
|
|
||||||
margin-left: 15em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Navigation */
|
|
||||||
|
|
||||||
.navsettop, .navsetbottom {
|
|
||||||
background-color: #f0f0e0;
|
|
||||||
padding: 0.25em 0 0.25em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navsettop {
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
border-bottom: 2px solid #e0e0c0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navsetbottom {
|
|
||||||
margin-top: 2em;
|
|
||||||
border-top: 2px solid #e0e0c0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navleft {
|
|
||||||
margin-left: 1ex;
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.navright {
|
|
||||||
margin-right: 1ex;
|
|
||||||
position: relative;
|
|
||||||
float: right;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.nonavigation {
|
|
||||||
color: #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navleft .tocsettoggle {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchform {
|
|
||||||
display: inline;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nosearchform {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchbox {
|
|
||||||
width: 16em;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
background-color: #eee;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchbox::placeholder {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#contextindicator {
|
|
||||||
position: fixed;
|
|
||||||
background-color: #c6f;
|
|
||||||
color: #000;
|
|
||||||
font-family: monospace;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 2px 10px;
|
|
||||||
display: none;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Version */
|
|
||||||
|
|
||||||
.versionbox {
|
|
||||||
position: relative;
|
|
||||||
float: right;
|
|
||||||
left: 2em;
|
|
||||||
height: 0em;
|
|
||||||
width: 13em;
|
|
||||||
margin: 0em -13em 0em 0em;
|
|
||||||
}
|
|
||||||
.version {
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
.versionNoNav {
|
|
||||||
font-size: xx-small; /* avoid overlap with author */
|
|
||||||
}
|
|
||||||
|
|
||||||
.version:before, .versionNoNav:before {
|
|
||||||
content: "Version ";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Language Family */
|
|
||||||
|
|
||||||
.navfamily {
|
|
||||||
float: right;
|
|
||||||
white-space: nowrap;
|
|
||||||
left: 2em;
|
|
||||||
height: 0em;
|
|
||||||
width: 10.5em;
|
|
||||||
margin: 1.5em -13em 0em 0em;
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
|
|
||||||
.docfamily:after {
|
|
||||||
content: " language family";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Margin notes */
|
|
||||||
|
|
||||||
.refpara, .refelem, .reffootnote {
|
|
||||||
position: relative;
|
|
||||||
float: right;
|
|
||||||
left: 2em;
|
|
||||||
height: 0em;
|
|
||||||
width: 13em;
|
|
||||||
margin: 0em -13em 0em 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refpara, .refparaleft, .reffootnote {
|
|
||||||
top: -1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcolumn {
|
|
||||||
background-color: #F5F5DC;
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
width: 13em;
|
|
||||||
font-size: 85%;
|
|
||||||
border: 0.5em solid #F5F5DC;
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
white-space: normal; /* in case margin note is inside code sample */
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcontent {
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcontent p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refparaleft, .refelemleft {
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
right: 2em;
|
|
||||||
height: 0em;
|
|
||||||
width: 13em;
|
|
||||||
margin: 0em 0em 0em -13em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refcolumnleft {
|
|
||||||
background-color: #F5F5DC;
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
width: 13em;
|
|
||||||
font-size: 85%;
|
|
||||||
border: 0.5em solid #F5F5DC;
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* narrow display => inline right-hand margin notes */
|
|
||||||
@media screen and (max-width: 55em) {
|
|
||||||
.refpara, .refelem, .reffootnote {
|
|
||||||
all: unset !important;
|
|
||||||
display: block !important;
|
|
||||||
margin: 1em 0 !important;
|
|
||||||
padding: 0.75em !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Table of contents, inline */
|
|
||||||
|
|
||||||
.toclink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
font-size: 85%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toptoclink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Table of contents, left margin */
|
|
||||||
|
|
||||||
.tocset {
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
width: 12.5em;
|
|
||||||
margin-right: 2em;
|
|
||||||
}
|
|
||||||
.tocset td {
|
|
||||||
vertical-align: text-top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocview {
|
|
||||||
text-align: left;
|
|
||||||
background-color: #f0f0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsub {
|
|
||||||
text-align: left;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
background-color: #f0f0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewlist, .tocsublist {
|
|
||||||
margin-left: 0.2em;
|
|
||||||
margin-right: 0.2em;
|
|
||||||
padding-top: 0.2em;
|
|
||||||
padding-bottom: 0.2em;
|
|
||||||
}
|
|
||||||
.tocviewlist table {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewlisttopspace {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewsublist, .tocviewsublistonly, .tocviewsublisttop, .tocviewsublistbottom {
|
|
||||||
margin-left: 0.4em;
|
|
||||||
border-left: 1px solid #bbf;
|
|
||||||
padding-left: 0.8em;
|
|
||||||
}
|
|
||||||
.tocviewsublist {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
.tocviewsublist table,
|
|
||||||
.tocviewsublistonly table,
|
|
||||||
.tocviewsublisttop table,
|
|
||||||
.tocviewsublistbottom table {
|
|
||||||
font-size: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewtitle * {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewlink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewselflink {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocviewtoggle {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
font-size: 75%; /* looks better, and avoids bounce when toggling sub-sections due to font alignments */
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsublist td {
|
|
||||||
padding-left: 1em;
|
|
||||||
text-indent: -1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsublinknumber {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsublink {
|
|
||||||
font-size: 82%;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsubseclink {
|
|
||||||
font-size: 82%;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsubnonseclink {
|
|
||||||
font-size: 82%;
|
|
||||||
text-decoration: none;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tocsubtitle {
|
|
||||||
font-size: 82%;
|
|
||||||
font-style: italic;
|
|
||||||
margin: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
/* Some inline styles */
|
|
||||||
|
|
||||||
.indexlink {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nobreak {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre { margin-left: 2em; }
|
|
||||||
blockquote { margin-left: 2em; }
|
|
||||||
|
|
||||||
ol { list-style-type: decimal; }
|
|
||||||
ol ol { list-style-type: lower-alpha; }
|
|
||||||
ol ol ol { list-style-type: lower-roman; }
|
|
||||||
ol ol ol ol { list-style-type: upper-alpha; }
|
|
||||||
|
|
||||||
.SCodeFlow {
|
|
||||||
display: block;
|
|
||||||
margin-left: 1em;
|
|
||||||
margin-bottom: 0em;
|
|
||||||
margin-right: 1em;
|
|
||||||
margin-top: 0em;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SVInsetFlow {
|
|
||||||
display: block;
|
|
||||||
margin-left: 0em;
|
|
||||||
margin-bottom: 0em;
|
|
||||||
margin-right: 0em;
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SubFlow {
|
|
||||||
display: block;
|
|
||||||
margin: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boxed {
|
|
||||||
width: 100%;
|
|
||||||
background-color: #E8E8FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hspace {
|
|
||||||
}
|
|
||||||
|
|
||||||
.slant {
|
|
||||||
font-style: oblique;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badlink {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plainlink {
|
|
||||||
text-decoration: none;
|
|
||||||
color: blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.techoutside { text-decoration: underline; color: #b0b0b0; }
|
|
||||||
.techoutside:hover { text-decoration: underline; color: blue; }
|
|
||||||
|
|
||||||
/* .techinside:hover doesn't work with FF, .techinside:hover>
|
|
||||||
.techinside doesn't work with IE, so use both (and IE doesn't
|
|
||||||
work with inherit in the second one, so use blue directly) */
|
|
||||||
.techinside { color: black; }
|
|
||||||
.techinside:hover { color: blue; }
|
|
||||||
.techoutside:hover>.techinside { color: inherit; }
|
|
||||||
|
|
||||||
.SCentered {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.imageleft {
|
|
||||||
float: left;
|
|
||||||
margin-right: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Smaller {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Larger {
|
|
||||||
font-size: 122%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A hack, inserted to break some Scheme ids: */
|
|
||||||
.mywbr {
|
|
||||||
display: inline-block;
|
|
||||||
height: 0;
|
|
||||||
width: 0;
|
|
||||||
font-size: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.compact li p {
|
|
||||||
margin: 0em;
|
|
||||||
padding: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.noborder img {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SVerbatim {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.SAuthorListBox {
|
|
||||||
position: relative;
|
|
||||||
float: right;
|
|
||||||
left: 2em;
|
|
||||||
top: -2.25em;
|
|
||||||
height: 0em;
|
|
||||||
width: 13em;
|
|
||||||
margin: 0em -13em 0em 0em;
|
|
||||||
}
|
|
||||||
.SAuthorList {
|
|
||||||
font-size: 82%;
|
|
||||||
}
|
|
||||||
.SAuthorList:before {
|
|
||||||
content: "by ";
|
|
||||||
}
|
|
||||||
.author {
|
|
||||||
display: inline;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* print styles : hide the navigation elements */
|
|
||||||
@media print {
|
|
||||||
.tocset,
|
|
||||||
.navsettop,
|
|
||||||
.navsetbottom { display: none; }
|
|
||||||
.maincolumn {
|
|
||||||
width: auto;
|
|
||||||
margin-right: 13em;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Begin headings */
|
|
||||||
|
|
||||||
/* Hide the button group by default, but show them on hovering the heading title */
|
|
||||||
.button-group {
|
|
||||||
padding-left: 0.3em;
|
|
||||||
visibility: hidden;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.heading:hover > .button-group {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group > a {
|
|
||||||
margin: 0 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group > a, .button-group > a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading-anchor {
|
|
||||||
font-size: 60%;
|
|
||||||
/* A trick to color an emoji from https://stackoverflow.com/questions/32413731/color-for-unicode-emoji */
|
|
||||||
color: transparent;
|
|
||||||
text-shadow: 0 0 0 gray;
|
|
||||||
vertical-align: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading-source {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
@@ -56,10 +56,65 @@
|
|||||||
(check-equal? (git 'diff) "")
|
(check-equal? (git 'diff) "")
|
||||||
(check-equal? (git 'diff '--cached) "")
|
(check-equal? (git 'diff '--cached) "")
|
||||||
|
|
||||||
|
;; Grep always returns structured entries. -n, -l, and -c affect only
|
||||||
|
;; dgit presentation; -i and -v affect matching.
|
||||||
|
(define grep-hello (git 'grep "hello"))
|
||||||
|
(check-equal? grep-hello
|
||||||
|
(list (git-grep-entry "sub/hello.txt" 1 "hello")))
|
||||||
|
(check-equal? (git 'grep '-n "hello") grep-hello)
|
||||||
|
(check-equal? (git 'grep '-l "hello") grep-hello)
|
||||||
|
(check-equal? (git 'grep '-c "hello") grep-hello)
|
||||||
|
(check-equal? (git 'grep '-i "HELLO") grep-hello)
|
||||||
|
(check-false
|
||||||
|
(for/or ([entry (in-list (git 'grep '-v "hello"))])
|
||||||
|
(and (string=? (git-grep-entry-path entry) "sub/hello.txt")
|
||||||
|
(string=? (git-grep-entry-line entry) "hello"))))
|
||||||
|
|
||||||
|
(define grep-output (open-output-string))
|
||||||
|
(parameterize ([current-output-port grep-output])
|
||||||
|
(dgit 'grep '-n "hello"))
|
||||||
|
(check-equal? (get-output-string grep-output)
|
||||||
|
"sub/hello.txt:1:hello\n")
|
||||||
|
(define grep-files-output (open-output-string))
|
||||||
|
(parameterize ([current-output-port grep-files-output])
|
||||||
|
(dgit 'grep '-l "hello"))
|
||||||
|
(check-equal? (get-output-string grep-files-output)
|
||||||
|
"sub/hello.txt\n")
|
||||||
|
(define grep-count-output (open-output-string))
|
||||||
|
(parameterize ([current-output-port grep-count-output])
|
||||||
|
(dgit 'grep '-c "hello"))
|
||||||
|
(check-equal? (get-output-string grep-count-output)
|
||||||
|
"sub/hello.txt:1\n")
|
||||||
|
|
||||||
|
;; `restore --staged` removes a path from the index without deleting the
|
||||||
|
;; worktree file. Once the path is ignored, it disappears from status.
|
||||||
|
(call-with-output-file "staged.txt"
|
||||||
|
#:exists 'truncate/replace
|
||||||
|
(lambda (out) (displayln "staged" out)))
|
||||||
|
(git 'add "staged.txt")
|
||||||
|
(call-with-output-file ".gitignore"
|
||||||
|
#:exists 'append
|
||||||
|
(lambda (out) (displayln "staged.txt" out)))
|
||||||
|
(check-not-false
|
||||||
|
(member "A staged.txt" (git-status-lines)))
|
||||||
|
(git 'restore '--staged "staged.txt")
|
||||||
|
(check-false
|
||||||
|
(member "?? staged.txt" (git-status-lines)))
|
||||||
|
(check-true (file-exists? "staged.txt"))
|
||||||
|
;; Restore the tracked .gitignore from the index and remove the now
|
||||||
|
;; untracked test file, returning to a clean repository.
|
||||||
|
(git 'restore ".gitignore")
|
||||||
|
(delete-file "staged.txt")
|
||||||
|
(check-true (git-clean?))
|
||||||
|
|
||||||
(call-with-output-file (build-path "sub" "hello.txt")
|
(call-with-output-file (build-path "sub" "hello.txt")
|
||||||
#:exists 'truncate/replace
|
#:exists 'truncate/replace
|
||||||
(lambda (out) (displayln "changed" out)))
|
(lambda (out) (displayln "changed" out)))
|
||||||
(define worktree-diff (git 'diff))
|
(define worktree-diff (git 'diff))
|
||||||
|
(check-equal? (git 'grep "hello" 'HEAD)
|
||||||
|
(list (git-grep-entry "sub/hello.txt" 1 "hello")))
|
||||||
|
(check-equal? (git 'grep "changed")
|
||||||
|
(list (git-grep-entry "sub/hello.txt" 1 "changed")))
|
||||||
(check-true (regexp-match? #rx"-hello" worktree-diff))
|
(check-true (regexp-match? #rx"-hello" worktree-diff))
|
||||||
(check-true (regexp-match? #rx"[+]changed" worktree-diff))
|
(check-true (regexp-match? #rx"[+]changed" worktree-diff))
|
||||||
(check-equal? (git 'diff '--cached) "")
|
(check-equal? (git 'diff '--cached) "")
|
||||||
@@ -74,6 +129,14 @@
|
|||||||
(define cached-diff (git 'diff '--cached))
|
(define cached-diff (git 'diff '--cached))
|
||||||
(check-true (regexp-match? #rx"-hello" cached-diff))
|
(check-true (regexp-match? #rx"-hello" cached-diff))
|
||||||
(check-true (regexp-match? #rx"[+]changed" cached-diff))
|
(check-true (regexp-match? #rx"[+]changed" cached-diff))
|
||||||
|
|
||||||
|
;; Path reset restores the index from HEAD but keeps the worktree edit.
|
||||||
|
(git 'reset 'HEAD "--" "sub/hello.txt")
|
||||||
|
(check-equal? (git 'diff '--cached) "")
|
||||||
|
(check-true (regexp-match? #rx"[+]changed" (git 'diff)))
|
||||||
|
(check-not-false
|
||||||
|
(member " M sub/hello.txt" (git-status-lines)))
|
||||||
|
(git 'add "sub/hello.txt")
|
||||||
(git 'commit "prepare branches")
|
(git 'commit "prepare branches")
|
||||||
|
|
||||||
(git 'checkout '-b "work")
|
(git 'checkout '-b "work")
|
||||||
|
|||||||
Reference in New Issue
Block a user