scribble: #:doc-id argument to load-xref
and associated plumbing
Keep track of the target document name (i.e., the name of the directory that will contain the target document) for a cross reference, when known. This identification enables a simpler dynamic resolution of a hyperlink in almost all cases, istead of requiring a search for an arbitrary corss-reference key. Indirect links still need a mapping of cross-reference keys to document locations, but the mapping can be pruned to just section and module-name keys. This change cuts a generated "local-redirect.js" for the main distribution to 1/8 of its size.
This commit is contained in:
parent
6182541889
commit
a956918adb
|
@ -6,6 +6,7 @@
|
||||||
setup/main-collects
|
setup/main-collects
|
||||||
setup/path-to-relative
|
setup/path-to-relative
|
||||||
setup/dirs
|
setup/dirs
|
||||||
|
(only-in scribble/manual secref)
|
||||||
(only-in scribble/base-render render%)
|
(only-in scribble/base-render render%)
|
||||||
(only-in scribble/html-render render-mixin)
|
(only-in scribble/html-render render-mixin)
|
||||||
(only-in scribble/xref load-xref make-data+root)))
|
(only-in scribble/xref load-xref make-data+root)))
|
||||||
|
@ -176,10 +177,15 @@ are not available, the query link is left unmodified to go through a
|
||||||
server.
|
server.
|
||||||
|
|
||||||
The @filepath{local-redirect.js} and @filepath{local-user-redirect.js}
|
The @filepath{local-redirect.js} and @filepath{local-user-redirect.js}
|
||||||
files embed a copy of the cross-reference database, where the copy is
|
files map documentation-directory names to specific paths. Most query
|
||||||
specialized and compacted. These JavaScript files are generated as
|
references contain a documentation-directory name and a relative path
|
||||||
part of the special @filepath{local-redirect} document that is
|
within the directory, in which case the mapping from directory names
|
||||||
implemented by the @pkgname{racket-index} package.
|
to paths is sufficient. Indirect links, such as those created by
|
||||||
|
@racket[(seclink #:indirect? #t ...)], embed a cross-reference key, and
|
||||||
|
so @filepath{local-redirect.js} and @filepath{local-user-redirect.js}
|
||||||
|
must also embed a part of the cross-reference database. The JavaScript
|
||||||
|
files are generated as part of the special @filepath{local-redirect}
|
||||||
|
document that is implemented by the @pkgname{racket-index} package.
|
||||||
|
|
||||||
The indirection through @filepath{local-redirect.js} and
|
The indirection through @filepath{local-redirect.js} and
|
||||||
@filepath{local-user-redirect.js} reduces the problem of relative
|
@filepath{local-user-redirect.js} reduces the problem of relative
|
||||||
|
@ -187,7 +193,7 @@ links to the problem of referencing those two files. They are
|
||||||
referenced as absolute paths in a user-specific document build. To
|
referenced as absolute paths in a user-specific document build. To
|
||||||
create a @tech{built package} or @tech{binary package} that includes
|
create a @tech{built package} or @tech{binary package} that includes
|
||||||
documentation, each @filepath{.html} file must be modified to remove
|
documentation, each @filepath{.html} file must be modified to remove
|
||||||
the absolute path, and then each @filepath{.html} file must be
|
the absolute paths, and then each @filepath{.html} file must be
|
||||||
modified again on installation to put the target installation's paths
|
modified again on installation to put the target installation's paths
|
||||||
in path.
|
in path.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#lang scheme/base
|
#lang racket/base
|
||||||
|
|
||||||
(provide (all-defined-out))
|
(provide (all-defined-out))
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
racket/serialize
|
racket/serialize
|
||||||
racket/class
|
racket/class
|
||||||
racket/match
|
racket/match
|
||||||
|
racket/set
|
||||||
setup/dirs
|
setup/dirs
|
||||||
net/url
|
net/url
|
||||||
scribble/html-properties
|
scribble/html-properties
|
||||||
|
setup/xref
|
||||||
"index-scope.rkt")
|
"index-scope.rkt")
|
||||||
|
|
||||||
(provide make-local-redirect)
|
(provide make-local-redirect)
|
||||||
|
@ -13,17 +15,17 @@
|
||||||
(define (rewrite-code user?)
|
(define (rewrite-code user?)
|
||||||
(define prefix (if user? "user_" ""))
|
(define prefix (if user? "user_" ""))
|
||||||
@string-append|{
|
@string-append|{
|
||||||
function |@|prefix|bsearch(str, start, end) {
|
function |@|prefix|bsearch(str, a, start, end) {
|
||||||
if (start >= end)
|
if (start >= end)
|
||||||
return false;
|
return false;
|
||||||
else {
|
else {
|
||||||
var mid = Math.floor((start + end) / 2);
|
var mid = Math.floor((start + end) / 2);
|
||||||
if (|@|prefix|link_targets[mid][0] == str)
|
if (a[mid][0] == str)
|
||||||
return mid;
|
return mid;
|
||||||
else if (|@|prefix|link_targets[mid][0] < str)
|
else if (a[mid][0] < str)
|
||||||
return |@|prefix|bsearch(str, mid+1, end);
|
return |@|prefix|bsearch(str, a, mid+1, end);
|
||||||
else
|
else
|
||||||
return |@|prefix|bsearch(str, start, mid);
|
return |@|prefix|bsearch(str, a, start, mid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +35,26 @@
|
||||||
var elements = document.getElementsByClassName("Sq");
|
var elements = document.getElementsByClassName("Sq");
|
||||||
for (var i = 0; i < elements.length; i++) {
|
for (var i = 0; i < elements.length; i++) {
|
||||||
var elem = elements[i];
|
var elem = elements[i];
|
||||||
var n = elem.href.match(/tag=[^&]*/);
|
var doc = elem.href.match(/doc=[^&]*/);
|
||||||
if (n) {
|
var rel = elem.href.match(/rel=[^&]*/);
|
||||||
var pos = |@|prefix|bsearch(decodeURIComponent(n[0].substring(4)),
|
var tag = elem.href.match(/tag=[^&]*/);
|
||||||
|
if (doc && rel) {
|
||||||
|
var pos = |@|prefix|bsearch(decodeURIComponent(doc[0].substring(4)),
|
||||||
|
|@|prefix|link_dirs,
|
||||||
|
0,
|
||||||
|
|@|prefix|link_dirs.length);
|
||||||
|
if (pos) {
|
||||||
|
var p = |@|prefix|link_dirs[pos][1];
|
||||||
|
if (|@|prefix|link_target_prefix) {
|
||||||
|
p = |@|prefix|link_target_prefix + p;
|
||||||
|
}
|
||||||
|
elem.href = p + "/" + decodeURIComponent(rel[0].substring(4));
|
||||||
|
tag = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tag) {
|
||||||
|
var pos = |@|prefix|bsearch(decodeURIComponent(tag[0].substring(4)),
|
||||||
|
|@|prefix|link_targets,
|
||||||
0,
|
0,
|
||||||
|@|prefix|link_targets.length);
|
|@|prefix|link_targets.length);
|
||||||
if (pos) {
|
if (pos) {
|
||||||
|
@ -43,7 +62,6 @@
|
||||||
if (|@|prefix|link_target_prefix) {
|
if (|@|prefix|link_target_prefix) {
|
||||||
p = |@|prefix|link_target_prefix + p;
|
p = |@|prefix|link_target_prefix + p;
|
||||||
}
|
}
|
||||||
elem.href = p;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,11 +100,18 @@
|
||||||
#f
|
#f
|
||||||
null
|
null
|
||||||
(lambda (renderer p ri)
|
(lambda (renderer p ri)
|
||||||
|
(define doc-dirs (get-rendered-doc-directories (not user?) user?))
|
||||||
(define keys (if (and main-at-user? (not user?))
|
(define keys (if (and main-at-user? (not user?))
|
||||||
;; If there's no installation-scope "doc", then
|
;; If there's no installation-scope "doc", then
|
||||||
;; the "main" redirection table is useless.
|
;; the "main" redirection table is useless.
|
||||||
null
|
null
|
||||||
(resolve-get-keys #f ri (lambda (v) #t))))
|
(resolve-get-keys #f ri
|
||||||
|
(lambda (v)
|
||||||
|
;; Support key-based indirect only on sections
|
||||||
|
;; and module names:
|
||||||
|
(define t (car v))
|
||||||
|
(or (eq? t 'part)
|
||||||
|
(eq? t 'mod-path))))))
|
||||||
(define (target? v) (and (vector? v) (= 5 (vector-length v))))
|
(define (target? v) (and (vector? v) (= 5 (vector-length v))))
|
||||||
(define dest-dir (send renderer get-dest-directory #t))
|
(define dest-dir (send renderer get-dest-directory #t))
|
||||||
(define (make-dest user?)
|
(define (make-dest user?)
|
||||||
|
@ -124,13 +149,26 @@
|
||||||
(path->directory-path
|
(path->directory-path
|
||||||
(build-path (find-doc-dir) "local-redirect")))))
|
(build-path (find-doc-dir) "local-redirect")))))
|
||||||
(newline o))
|
(newline o))
|
||||||
|
(fprintf o "var ~alink_dirs = [" (if user? "user_" ""))
|
||||||
|
(define (extract-name e)
|
||||||
|
(let-values ([(base name dir?) (split-path e)])
|
||||||
|
(path->string name)))
|
||||||
|
(for ([e (in-list (sort doc-dirs string<? #:key extract-name))]
|
||||||
|
[i (in-naturals)])
|
||||||
|
(define name (extract-name e))
|
||||||
|
(fprintf o (if (zero? i) "\n" ",\n"))
|
||||||
|
(fprintf o " [~s, ~s]" name (if user?
|
||||||
|
(url->string (path->url e))
|
||||||
|
(format "../~a" name))))
|
||||||
|
(fprintf o "];\n\n")
|
||||||
(fprintf o "var ~alink_targets = [" (if user? "user_" ""))
|
(fprintf o "var ~alink_targets = [" (if user? "user_" ""))
|
||||||
(for ([e (in-list db)]
|
(for ([e (in-list db)]
|
||||||
[i (in-naturals)])
|
[i (in-naturals)])
|
||||||
(fprintf o (if (zero? i) "\n" ",\n"))
|
(fprintf o (if (zero? i) "\n" ",\n"))
|
||||||
(fprintf o " [~s, ~s]" (car e) (cadr e)))
|
(fprintf o " [~s, ~s]" (car e) (cadr e)))
|
||||||
(fprintf o "];\n\n")
|
(fprintf o "];\n\n")
|
||||||
(fprintf o (rewrite-code user?))))
|
(fprintf o (rewrite-code user?))
|
||||||
|
(newline o)))
|
||||||
(unless (file-exists? alt-dest)
|
(unless (file-exists? alt-dest)
|
||||||
;; make empty alternate file; in `user?` mode, this
|
;; make empty alternate file; in `user?` mode, this
|
||||||
;; file will get used only when "racket-index" is not
|
;; file will get used only when "racket-index" is not
|
||||||
|
|
|
@ -10,11 +10,16 @@
|
||||||
setup/doc-db)
|
setup/doc-db)
|
||||||
|
|
||||||
(provide load-collections-xref
|
(provide load-collections-xref
|
||||||
make-collections-xref)
|
make-collections-xref
|
||||||
|
get-rendered-doc-directories)
|
||||||
|
|
||||||
(define cached-xref #f)
|
(define cached-xref #f)
|
||||||
|
|
||||||
(define (get-dests tag no-user? no-main?)
|
(define (get-rendered-doc-directories no-user? no-main?)
|
||||||
|
(append (get-dests 'scribblings no-user? no-main? #f)
|
||||||
|
(get-dests 'rendered-scribblings no-user? no-main? #f)))
|
||||||
|
|
||||||
|
(define (get-dests tag no-user? no-main? sxrefs?)
|
||||||
(define main-dirs
|
(define main-dirs
|
||||||
(for/hash ([k (in-list (find-relevant-directories (list tag) 'no-user))])
|
(for/hash ([k (in-list (find-relevant-directories (list tag) 'no-user))])
|
||||||
(values k #t)))
|
(values k #t)))
|
||||||
|
@ -42,10 +47,12 @@
|
||||||
(if no-user? 'never 'false-if-missing)
|
(if no-user? 'never 'false-if-missing)
|
||||||
#:main? (not no-main?))])
|
#:main? (not no-main?))])
|
||||||
(if d
|
(if d
|
||||||
(for*/list ([i (in-range (add1 out-count))]
|
(if sxrefs?
|
||||||
[p (in-value (build-path d (format "out~a.sxref" i)))]
|
(for*/list ([i (in-range (add1 out-count))]
|
||||||
#:when (file-exists? p))
|
[p (in-value (build-path d (format "out~a.sxref" i)))]
|
||||||
p)
|
#:when (file-exists? p))
|
||||||
|
p)
|
||||||
|
(list d))
|
||||||
null))
|
null))
|
||||||
null)))))
|
null)))))
|
||||||
|
|
||||||
|
@ -62,11 +69,19 @@
|
||||||
(exn-message exn)
|
(exn-message exn)
|
||||||
(format "~e" exn))))
|
(format "~e" exn))))
|
||||||
#f)])
|
#f)])
|
||||||
(make-data+root
|
(make-data+root+doc-id
|
||||||
;; data to deserialize:
|
;; data to deserialize:
|
||||||
(cadr (call-with-input-file* dest fasl->s-exp))
|
(cadr (call-with-input-file* dest fasl->s-exp))
|
||||||
;; provide a root for deserialization:
|
;; provide a root for deserialization:
|
||||||
(path-only dest))))))
|
(path-only dest)
|
||||||
|
;; Use the destination directory's name as an identifier,
|
||||||
|
;; which allows a faster and more compact indirection
|
||||||
|
;; for installation-scaoped documentation:
|
||||||
|
(let-values ([(base name dir?) (split-path dest)])
|
||||||
|
(and (path? base)
|
||||||
|
(let-values ([(base name dir?) (split-path base)])
|
||||||
|
(and (path? name)
|
||||||
|
(path->string name))))))))))
|
||||||
|
|
||||||
(define (make-key->source db-path no-user? no-main? quiet-fail? register-shutdown!)
|
(define (make-key->source db-path no-user? no-main? quiet-fail? register-shutdown!)
|
||||||
(define main-db (and (not no-main?)
|
(define main-db (and (not no-main?)
|
||||||
|
@ -132,8 +147,8 @@
|
||||||
|
|
||||||
(define (get-reader-thunks no-user? no-main? quiet-fail? done-ht)
|
(define (get-reader-thunks no-user? no-main? quiet-fail? done-ht)
|
||||||
(map (dest->source done-ht quiet-fail?)
|
(map (dest->source done-ht quiet-fail?)
|
||||||
(filter values (append (get-dests 'scribblings no-user? no-main?)
|
(filter values (append (get-dests 'scribblings no-user? no-main? #t)
|
||||||
(get-dests 'rendered-scribblings no-user? no-main?)))))
|
(get-dests 'rendered-scribblings no-user? no-main? #t)))))
|
||||||
|
|
||||||
(define (load-collections-xref [report-loading void])
|
(define (load-collections-xref [report-loading void])
|
||||||
(or cached-xref
|
(or cached-xref
|
||||||
|
|
|
@ -1354,6 +1354,16 @@ whether the resulting information originated from an external source
|
||||||
(i.e., a different document).}
|
(i.e., a different document).}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(resolve-get/ext-id [p (or/c part? #f)] [ri resolve-info?] [key info-key?])
|
||||||
|
(values any/c (or/c boolean? string?))]{
|
||||||
|
|
||||||
|
Like @racket[render-get/ext?], but the second result can be a string
|
||||||
|
to indicate the source document's identification as established via
|
||||||
|
@racket[load-xref] and a @racket[#:doc-id] argument.
|
||||||
|
|
||||||
|
@history[#:added "1.1"]}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(resolve-search [dep-key any/c] [p (or/c part? #f)] [ri resolve-info?] [key info-key?])
|
@defproc[(resolve-search [dep-key any/c] [p (or/c part? #f)] [ri resolve-info?] [key info-key?])
|
||||||
void?]{
|
void?]{
|
||||||
|
|
||||||
|
|
|
@ -320,10 +320,16 @@ Specializes a @racket[render<%>] class for generating HTML output.
|
||||||
|
|
||||||
@defmethod[(set-external-tag-path [url string?]) void?]{
|
@defmethod[(set-external-tag-path [url string?]) void?]{
|
||||||
|
|
||||||
Configures the renderer to redirect links to external via
|
Configures the renderer to redirect links to external documents via
|
||||||
@racket[url], adding a @racket[tag] query element to the end of the
|
@racket[url], adding a @tt{tag} query element to the end of the
|
||||||
URL that contains the Base64-encoded, @racket[print]ed, serialized
|
URL that contains the Base64-encoded, @racket[print]ed, serialized
|
||||||
original tag (in the sense of @racket[link-element]) for the link.}
|
original tag (in the sense of @racket[link-element]) for the link.
|
||||||
|
|
||||||
|
If the link is based on a cross-reference entry that has a
|
||||||
|
document-identifying string (see @racket[load-xref] and its
|
||||||
|
@racket[#:doc-id] argument), the document identifier is added as a
|
||||||
|
@tt{doc} query element, and a path to the target within the
|
||||||
|
document is added as a @tt{rel} query element.}
|
||||||
|
|
||||||
@defmethod[(set-external-root-url [url string?]) void?]{
|
@defmethod[(set-external-root-url [url string?]) void?]{
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ by @racket[load-xref], @racket[#f] otherwise.}
|
||||||
(lambda (_tag) #f)]
|
(lambda (_tag) #f)]
|
||||||
[#:render% using-render% (implementation?/c render<%>)
|
[#:render% using-render% (implementation?/c render<%>)
|
||||||
(render-mixin render%)]
|
(render-mixin render%)]
|
||||||
[#:root root-path (or/c path-string? false/c) #f])
|
[#:root root-path (or/c path-string? false/c) #f]
|
||||||
|
[#:doc-id doc-id-str (or/c path-string? false/c) #f])
|
||||||
xref?]{
|
xref?]{
|
||||||
|
|
||||||
Creates a cross-reference record given a list of functions,
|
Creates a cross-reference record given a list of functions,
|
||||||
|
@ -38,9 +39,11 @@ serialize-info]. The result of @racket[_source] can optionally be
|
||||||
another function, which is in turn responsible for returning a list of
|
another function, which is in turn responsible for returning a list of
|
||||||
@racket[_info]s. Finally, each @racket[_info] can be either serialized
|
@racket[_info]s. Finally, each @racket[_info] can be either serialized
|
||||||
information, a @racket[#f] to be ignored, or a value produced by
|
information, a @racket[#f] to be ignored, or a value produced by
|
||||||
@racket[make-data+root] from which @racket[_data] part is used as
|
@racket[make-data+root] or @racket[make-data+root+doc-id], from which
|
||||||
serialized information and the @racket[_root] part overrides
|
@racket[_data] part is used as serialized information, the
|
||||||
@racket[root-path] for deserialization.
|
@racket[_root] part overrides @racket[root-path] for deserialization,
|
||||||
|
and the @racket[_doc-id] part (if any) overrides
|
||||||
|
@racket[doc-id-string] to identify the source document.
|
||||||
|
|
||||||
The @racket[demand-source] function can effectively add a new source
|
The @racket[demand-source] function can effectively add a new source
|
||||||
to @racket[sources] in response to a search for information on the
|
to @racket[sources] in response to a search for information on the
|
||||||
|
@ -60,8 +63,16 @@ but a @racket[make-data+root] result for any @racket[_info] supplies
|
||||||
an alternate path for deserialization of the @racket[_info]'s
|
an alternate path for deserialization of the @racket[_info]'s
|
||||||
@racket[_data].
|
@racket[_data].
|
||||||
|
|
||||||
|
If @racket[doc-id-str] is not @racket[#f], it identifies each
|
||||||
|
cross-reference entry as originating from @racket[doc-id-str]. This
|
||||||
|
identification is used when a rendering link to the cross-reference
|
||||||
|
entry as an external query; see the @racket[set-external-tag-path]
|
||||||
|
method of @racket[render-mixin].
|
||||||
|
|
||||||
Use @racket[load-collections-xref] from @racketmodname[setup/xref] to
|
Use @racket[load-collections-xref] from @racketmodname[setup/xref] to
|
||||||
get all cross-reference information for installed documentation.}
|
get all cross-reference information for installed documentation.
|
||||||
|
|
||||||
|
@history[#:changed "1.1" @elem{Added the @racket[#:doc-id] argument.}]}
|
||||||
|
|
||||||
|
|
||||||
@defproc[(xref-binding->definition-tag [xref xref?]
|
@defproc[(xref-binding->definition-tag [xref xref?]
|
||||||
|
@ -213,3 +224,13 @@ the destination for the index link into the main document.}
|
||||||
A value constructed by @racket[make-data+root] can be returned by a
|
A value constructed by @racket[make-data+root] can be returned by a
|
||||||
source procedure for @racket[load-xref] to specify a path used for
|
source procedure for @racket[load-xref] to specify a path used for
|
||||||
deserialization.}
|
deserialization.}
|
||||||
|
|
||||||
|
@deftogether[(
|
||||||
|
@defproc[(data+root+doc-id? [v any/c]) boolean?]
|
||||||
|
@defproc[(make-data+root+doc-id [data any/c] [root (or/c #f path-string?)] [doc-id string?]) data+root+doc-id?]
|
||||||
|
)]{
|
||||||
|
|
||||||
|
Extends @racket[make-data+root+doc-id] to support an
|
||||||
|
document-identifying string (see @racket[load-xref]).
|
||||||
|
|
||||||
|
@history[#:added "1.1"]}
|
||||||
|
|
|
@ -353,13 +353,13 @@
|
||||||
(when rp
|
(when rp
|
||||||
(set-mobile-root-path! root rp))))))
|
(set-mobile-root-path! root rp))))))
|
||||||
|
|
||||||
(define/public (deserialize-info v ci #:root [root-path #f])
|
(define/public (deserialize-info v ci #:root [root-path #f] #:doc-id [doc-id #f])
|
||||||
(let ([root+ht (deserialize v)]
|
(let ([root+ht (deserialize v)]
|
||||||
[in-ht (collect-info-ext-ht ci)])
|
[in-ht (collect-info-ext-ht ci)])
|
||||||
(when root-path
|
(when root-path
|
||||||
(set-mobile-root-path! (car root+ht) root-path))
|
(set-mobile-root-path! (car root+ht) root-path))
|
||||||
(for ([(k v) (cdr root+ht)])
|
(for ([(k v) (cdr root+ht)])
|
||||||
(hash-set! in-ht k v))))
|
(hash-set! in-ht k (if doc-id (known-doc v doc-id) v)))))
|
||||||
|
|
||||||
(define/public (get-defined ci)
|
(define/public (get-defined ci)
|
||||||
(hash-map (collect-info-ht ci) (lambda (k v) k)))
|
(hash-map (collect-info-ht ci) (lambda (k v) k)))
|
||||||
|
|
|
@ -729,7 +729,8 @@
|
||||||
(collect-info-ext-ht ci))))
|
(collect-info-ext-ht ci))))
|
||||||
(lambda (k v)
|
(lambda (k v)
|
||||||
(when (and (pair? k) (eq? 'index-entry (car k)))
|
(when (and (pair? k) (eq? 'index-entry (car k)))
|
||||||
(set! l (cons (cons (cadr k) v) l)))))
|
(let ([v (if (known-doc? v) (known-doc-v v) v)])
|
||||||
|
(set! l (cons (cons (cadr k) v) l))))))
|
||||||
(sort l entry<?))
|
(sort l entry<?))
|
||||||
|
|
||||||
(define (index-block)
|
(define (index-block)
|
||||||
|
|
|
@ -37,31 +37,37 @@
|
||||||
(define ci (resolve-info-ci ri))
|
(define ci (resolve-info-ci ri))
|
||||||
(define (try-ext)
|
(define (try-ext)
|
||||||
(hash-ref (collect-info-ext-ht ci) key #f))
|
(hash-ref (collect-info-ext-ht ci) key #f))
|
||||||
(values
|
(define v
|
||||||
(or (try-ext)
|
(or (try-ext)
|
||||||
(and ((collect-info-ext-demand ci) key ci)
|
(and ((collect-info-ext-demand ci) key ci)
|
||||||
(try-ext)))
|
(try-ext))))
|
||||||
#t)]))))
|
(if (known-doc? v)
|
||||||
|
(values (known-doc-v v) (known-doc-id v))
|
||||||
|
(values v #t))]))))
|
||||||
|
|
||||||
(define (resolve-get/ext? part ri key)
|
(define (resolve-get/ext? part ri key)
|
||||||
(resolve-get/ext?* part ri key #f))
|
(define-values (v ext-id) (resolve-get/ext-id* part ri key #f))
|
||||||
|
(values v (and ext-id #t)))
|
||||||
|
|
||||||
(define (resolve-get/ext?* part ri key search-key)
|
(define (resolve-get/ext-id part ri key)
|
||||||
(let-values ([(v ext?) (resolve-get/where part ri key)])
|
(resolve-get/ext-id* part ri key #f))
|
||||||
(when ext?
|
|
||||||
|
(define (resolve-get/ext-id* part ri key search-key)
|
||||||
|
(let-values ([(v ext-id) (resolve-get/where part ri key)])
|
||||||
|
(when ext-id
|
||||||
(hash-set! (resolve-info-undef ri) (tag-key key ri)
|
(hash-set! (resolve-info-undef ri) (tag-key key ri)
|
||||||
(if v 'found search-key)))
|
(if v 'found search-key)))
|
||||||
(values v ext?)))
|
(values v ext-id)))
|
||||||
|
|
||||||
(define (resolve-get part ri key)
|
(define (resolve-get part ri key)
|
||||||
(resolve-get* part ri key #f))
|
(resolve-get* part ri key #f))
|
||||||
|
|
||||||
(define (resolve-get* part ri key search-key)
|
(define (resolve-get* part ri key search-key)
|
||||||
(let-values ([(v ext?) (resolve-get/ext?* part ri key search-key)])
|
(let-values ([(v ext-id) (resolve-get/ext-id* part ri key search-key)])
|
||||||
v))
|
v))
|
||||||
|
|
||||||
(define (resolve-get/tentative part ri key)
|
(define (resolve-get/tentative part ri key)
|
||||||
(let-values ([(v ext?) (resolve-get/where part ri key)])
|
(let-values ([(v ext-id) (resolve-get/where part ri key)])
|
||||||
v))
|
v))
|
||||||
|
|
||||||
(define (resolve-search search-key part ri key)
|
(define (resolve-search search-key part ri key)
|
||||||
|
@ -215,7 +221,10 @@
|
||||||
|
|
||||||
[collected-info ([number (listof (or/c false/c exact-nonnegative-integer? string?))]
|
[collected-info ([number (listof (or/c false/c exact-nonnegative-integer? string?))]
|
||||||
[parent (or/c false/c part?)]
|
[parent (or/c false/c part?)]
|
||||||
[info any/c])])
|
[info any/c])]
|
||||||
|
|
||||||
|
[known-doc ([v any/c]
|
||||||
|
[id string?])])
|
||||||
|
|
||||||
(provide plain)
|
(provide plain)
|
||||||
(define plain (make-style #f null))
|
(define plain (make-style #f null))
|
||||||
|
@ -715,5 +724,6 @@
|
||||||
[resolve-get ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
[resolve-get ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
||||||
[resolve-get/tentative ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
[resolve-get/tentative ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
||||||
[resolve-get/ext? ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
[resolve-get/ext? ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
||||||
|
[resolve-get/ext-id ((or/c part? false/c) resolve-info? info-key? . -> . any)]
|
||||||
[resolve-search (any/c (or/c part? false/c) resolve-info? info-key? . -> . any)]
|
[resolve-search (any/c (or/c part? false/c) resolve-info? info-key? . -> . any)]
|
||||||
[resolve-get-keys ((or/c part? false/c) resolve-info? (info-key? . -> . any/c) . -> . any/c)])
|
[resolve-get-keys ((or/c part? false/c) resolve-info? (info-key? . -> . any/c) . -> . any/c)])
|
||||||
|
|
|
@ -508,6 +508,19 @@
|
||||||
(anchor-name (dest-anchor dest))))))
|
(anchor-name (dest-anchor dest))))))
|
||||||
"???"))
|
"???"))
|
||||||
|
|
||||||
|
(define/private (dest->url-in-doc dest)
|
||||||
|
(and dest
|
||||||
|
(not (dest-redirect dest))
|
||||||
|
(format "~a~a~a"
|
||||||
|
(let-values ([(base name dir?) (split-path
|
||||||
|
(relative->path (dest-path dest)))])
|
||||||
|
name)
|
||||||
|
(if (dest-page? dest) "" "#")
|
||||||
|
(if (dest-page? dest)
|
||||||
|
""
|
||||||
|
(uri-unreserved-encode
|
||||||
|
(anchor-name (dest-anchor dest)))))))
|
||||||
|
|
||||||
(define/public (render-toc-view d ri)
|
(define/public (render-toc-view d ri)
|
||||||
(define has-sub-parts?
|
(define has-sub-parts?
|
||||||
(pair? (part-parts d)))
|
(pair? (part-parts d)))
|
||||||
|
@ -1239,15 +1252,15 @@
|
||||||
[(and (link-element? e) (not (current-no-links)))
|
[(and (link-element? e) (not (current-no-links)))
|
||||||
(parameterize ([current-no-links #t])
|
(parameterize ([current-no-links #t])
|
||||||
(define indirect-link? (link-element-indirect? e))
|
(define indirect-link? (link-element-indirect? e))
|
||||||
(let-values ([(dest ext?)
|
(let-values ([(dest ext-id)
|
||||||
(if (and indirect-link?
|
(if (and indirect-link?
|
||||||
external-tag-path)
|
external-tag-path)
|
||||||
(values #f #f)
|
(values #f #f)
|
||||||
(resolve-get/ext? part ri (link-element-tag e)))])
|
(resolve-get/ext-id part ri (link-element-tag e)))])
|
||||||
(if (or indirect-link? dest)
|
(if (or indirect-link? dest)
|
||||||
`((a [(href
|
`((a ([href
|
||||||
,(cond
|
,(cond
|
||||||
[(and ext? external-root-url
|
[(and ext-id external-root-url
|
||||||
(let ([rel (find-relative-path
|
(let ([rel (find-relative-path
|
||||||
(find-doc-dir)
|
(find-doc-dir)
|
||||||
(relative->path (dest-path dest)))])
|
(relative->path (dest-path dest)))])
|
||||||
|
@ -1270,7 +1283,7 @@
|
||||||
(and (not (dest-page? dest))
|
(and (not (dest-page? dest))
|
||||||
(anchor-name (dest-anchor dest)))])))]
|
(anchor-name (dest-anchor dest)))])))]
|
||||||
[(or indirect-link?
|
[(or indirect-link?
|
||||||
(and ext? external-tag-path))
|
(and ext-id external-tag-path))
|
||||||
;; Redirected to search:
|
;; Redirected to search:
|
||||||
(url->string*
|
(url->string*
|
||||||
(let ([u (string->url (or external-tag-path
|
(let ([u (string->url (or external-tag-path
|
||||||
|
@ -1279,16 +1292,20 @@
|
||||||
url
|
url
|
||||||
u
|
u
|
||||||
[query
|
[query
|
||||||
(cons (cons 'tag (tag->query-string (link-element-tag e)))
|
(if (string? ext-id)
|
||||||
(url-query u))])))]
|
(list* (cons 'doc ext-id)
|
||||||
|
(cons 'rel (or (dest->url-in-doc dest) "???"))
|
||||||
|
(url-query u))
|
||||||
|
(cons (cons 'tag (tag->query-string (link-element-tag e)))
|
||||||
|
(url-query u)))])))]
|
||||||
[else
|
[else
|
||||||
;; Normal link:
|
;; Normal link:
|
||||||
(dest->url dest)]))
|
(dest->url dest)])]
|
||||||
,@(attribs (if (or indirect-link?
|
,@(attribs (if (or indirect-link?
|
||||||
(and ext? external-tag-path))
|
(and ext-id external-tag-path))
|
||||||
'((class "Sq"))
|
'([class "Sq"])
|
||||||
null))
|
null))
|
||||||
[data-pltdoc "x"]]
|
[data-pltdoc "x"])
|
||||||
,@(if (empty-content? (element-content e))
|
,@(if (empty-content? (element-content e))
|
||||||
(render-content (strip-aux (dest-title dest)) part ri)
|
(render-content (strip-aux (dest-title dest)) part ri)
|
||||||
(render-content (element-content e) part ri))))
|
(render-content (element-content e) part ri))))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#lang scheme/base
|
#lang scheme/base
|
||||||
|
|
||||||
(require scribble/struct
|
(require scribble/struct
|
||||||
|
(only-in scribble/core known-doc? known-doc-v)
|
||||||
scribble/base-render
|
scribble/base-render
|
||||||
scribble/search
|
scribble/search
|
||||||
(prefix-in html: scribble/html-render)
|
(prefix-in html: scribble/html-render)
|
||||||
|
@ -17,7 +18,9 @@
|
||||||
xref-transfer-info
|
xref-transfer-info
|
||||||
(struct-out entry)
|
(struct-out entry)
|
||||||
make-data+root
|
make-data+root
|
||||||
data+root?)
|
data+root?
|
||||||
|
make-data+root+doc-id
|
||||||
|
data+root+doc-id?)
|
||||||
|
|
||||||
(define-struct entry
|
(define-struct entry
|
||||||
(words ; list of strings: main term, sub-term, etc.
|
(words ; list of strings: main term, sub-term, etc.
|
||||||
|
@ -26,6 +29,7 @@
|
||||||
desc)) ; further info that depends on the kind of index entry
|
desc)) ; further info that depends on the kind of index entry
|
||||||
|
|
||||||
(define-struct data+root (data root))
|
(define-struct data+root (data root))
|
||||||
|
(define-struct (data+root+doc-id data+root) (doc-id))
|
||||||
|
|
||||||
;; Private:
|
;; Private:
|
||||||
(define-struct xrefs (renderer ri))
|
(define-struct xrefs (renderer ri))
|
||||||
|
@ -40,7 +44,8 @@
|
||||||
(define (load-xref sources
|
(define (load-xref sources
|
||||||
#:demand-source [demand-source (lambda (key) #f)]
|
#:demand-source [demand-source (lambda (key) #f)]
|
||||||
#:render% [render% (html:render-mixin render%)]
|
#:render% [render% (html:render-mixin render%)]
|
||||||
#:root [root-path #f])
|
#:root [root-path #f]
|
||||||
|
#:doc-id [doc-id-str #f])
|
||||||
(let* ([renderer (new render% [dest-dir (find-system-path 'temp-dir)])]
|
(let* ([renderer (new render% [dest-dir (find-system-path 'temp-dir)])]
|
||||||
[fp (send renderer traverse null null)]
|
[fp (send renderer traverse null null)]
|
||||||
[load-source (lambda (src ci)
|
[load-source (lambda (src ci)
|
||||||
|
@ -51,7 +56,11 @@
|
||||||
(when v
|
(when v
|
||||||
(define data (if (data+root? v) (data+root-data v) v))
|
(define data (if (data+root? v) (data+root-data v) v))
|
||||||
(define root (if (data+root? v) (data+root-root v) root-path))
|
(define root (if (data+root? v) (data+root-root v) root-path))
|
||||||
(send renderer deserialize-info data ci #:root root))))))]
|
(define doc-id (or (and (data+root+doc-id? v) (data+root+doc-id-doc-id v))
|
||||||
|
doc-id-str))
|
||||||
|
(send renderer deserialize-info data ci
|
||||||
|
#:root root
|
||||||
|
#:doc-id doc-id))))))]
|
||||||
[ci (send renderer collect null null fp
|
[ci (send renderer collect null null fp
|
||||||
(lambda (key ci)
|
(lambda (key ci)
|
||||||
(define src (demand-source key))
|
(define src (demand-source key))
|
||||||
|
@ -73,7 +82,10 @@
|
||||||
#:when
|
#:when
|
||||||
(and (pair? k)
|
(and (pair? k)
|
||||||
(eq? (car k) 'index-entry)))
|
(eq? (car k) 'index-entry)))
|
||||||
(make-entry (car v) (cadr v) (cadr k) (caddr v))))
|
(let ([v (if (known-doc? v)
|
||||||
|
(known-doc-v v)
|
||||||
|
v)])
|
||||||
|
(make-entry (car v) (cadr v) (cadr k) (caddr v)))))
|
||||||
|
|
||||||
;; dest-file can be #f, which will make it return a string holding the
|
;; dest-file can be #f, which will make it return a string holding the
|
||||||
;; resulting html
|
;; resulting html
|
||||||
|
@ -151,8 +163,11 @@
|
||||||
(collect-info-ext-ht (resolve-info-ci (xrefs-ri xrefs)))
|
(collect-info-ext-ht (resolve-info-ci (xrefs-ri xrefs)))
|
||||||
`(index-entry ,tag)
|
`(index-entry ,tag)
|
||||||
#f)])
|
#f)])
|
||||||
(cond [v (make-entry (car v) (cadr v) (cadr tag) (caddr v))]
|
(let ([v (if (known-doc? v)
|
||||||
[(and (pair? tag) (eq? 'form (car tag)))
|
(known-doc-v v)
|
||||||
;; Try again with 'def:
|
v)])
|
||||||
(xref-tag->index-entry xrefs (cons 'def (cdr tag)))]
|
(cond [v (make-entry (car v) (cadr v) (cadr tag) (caddr v))]
|
||||||
[else #f])))
|
[(and (pair? tag) (eq? 'form (car tag)))
|
||||||
|
;; Try again with 'def:
|
||||||
|
(xref-tag->index-entry xrefs (cons 'def (cdr tag)))]
|
||||||
|
[else #f]))))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user