diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl index c7fc5d0e..96d8f34d 100644 --- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl +++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl @@ -1354,6 +1354,16 @@ whether the resulting information originated from an external source (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?]) void?]{ diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/renderer.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/renderer.scrbl index 3822b290..2d610f1a 100644 --- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/renderer.scrbl +++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/renderer.scrbl @@ -320,10 +320,16 @@ Specializes a @racket[render<%>] class for generating HTML output. @defmethod[(set-external-tag-path [url string?]) void?]{ -Configures the renderer to redirect links to external via -@racket[url], adding a @racket[tag] query element to the end of the +Configures the renderer to redirect links to external documents via +@racket[url], adding a @tt{tag} query element to the end of the 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?]{ diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/xref.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/xref.scrbl index 3b0f99cc..06a55d18 100644 --- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/xref.scrbl +++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/xref.scrbl @@ -25,7 +25,8 @@ by @racket[load-xref], @racket[#f] otherwise.} (lambda (_tag) #f)] [#:render% using-render% (implementation?/c 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?]{ 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 @racket[_info]s. Finally, each @racket[_info] can be either serialized information, a @racket[#f] to be ignored, or a value produced by -@racket[make-data+root] from which @racket[_data] part is used as -serialized information and the @racket[_root] part overrides -@racket[root-path] for deserialization. +@racket[make-data+root] or @racket[make-data+root+doc-id], from which +@racket[_data] part is used as serialized information, the +@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 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 @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 -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?] @@ -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 source procedure for @racket[load-xref] to specify a path used for 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"]} diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/base-render.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/base-render.rkt index 00f15c0a..2f339b73 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/base-render.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/base-render.rkt @@ -353,13 +353,13 @@ (when 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)] [in-ht (collect-info-ext-ht ci)]) (when root-path (set-mobile-root-path! (car root+ht) root-path)) (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) (hash-map (collect-info-ht ci) (lambda (k v) k))) diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/base.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/base.rkt index 639f8a6e..61fbb4e6 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/base.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/base.rkt @@ -729,7 +729,8 @@ (collect-info-ext-ht ci)))) (lambda (k v) (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 . 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-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-get-keys ((or/c part? false/c) resolve-info? (info-key? . -> . any/c) . -> . any/c)]) diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt index b779cb40..d3ebebd3 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt @@ -508,6 +508,19 @@ (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 has-sub-parts? (pair? (part-parts d))) @@ -1239,15 +1252,15 @@ [(and (link-element? e) (not (current-no-links))) (parameterize ([current-no-links #t]) (define indirect-link? (link-element-indirect? e)) - (let-values ([(dest ext?) + (let-values ([(dest ext-id) (if (and indirect-link? external-tag-path) (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) - `((a [(href + `((a ([href ,(cond - [(and ext? external-root-url + [(and ext-id external-root-url (let ([rel (find-relative-path (find-doc-dir) (relative->path (dest-path dest)))]) @@ -1270,7 +1283,7 @@ (and (not (dest-page? dest)) (anchor-name (dest-anchor dest)))])))] [(or indirect-link? - (and ext? external-tag-path)) + (and ext-id external-tag-path)) ;; Redirected to search: (url->string* (let ([u (string->url (or external-tag-path @@ -1279,16 +1292,20 @@ url u [query - (cons (cons 'tag (tag->query-string (link-element-tag e))) - (url-query u))])))] + (if (string? ext-id) + (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 ;; Normal link: - (dest->url dest)])) + (dest->url dest)])] ,@(attribs (if (or indirect-link? - (and ext? external-tag-path)) - '((class "Sq")) + (and ext-id external-tag-path)) + '([class "Sq"]) null)) - [data-pltdoc "x"]] + [data-pltdoc "x"]) ,@(if (empty-content? (element-content e)) (render-content (strip-aux (dest-title dest)) part ri) (render-content (element-content e) part ri)))) diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/xref.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/xref.rkt index 75c1dfe9..b0ae6fa8 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/xref.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/xref.rkt @@ -1,6 +1,7 @@ #lang scheme/base (require scribble/struct + (only-in scribble/core known-doc? known-doc-v) scribble/base-render scribble/search (prefix-in html: scribble/html-render) @@ -17,7 +18,9 @@ xref-transfer-info (struct-out entry) make-data+root - data+root?) + data+root? + make-data+root+doc-id + data+root+doc-id?) (define-struct entry (words ; list of strings: main term, sub-term, etc. @@ -26,6 +29,7 @@ desc)) ; further info that depends on the kind of index entry (define-struct data+root (data root)) +(define-struct (data+root+doc-id data+root) (doc-id)) ;; Private: (define-struct xrefs (renderer ri)) @@ -40,7 +44,8 @@ (define (load-xref sources #:demand-source [demand-source (lambda (key) #f)] #: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)])] [fp (send renderer traverse null null)] [load-source (lambda (src ci) @@ -51,7 +56,11 @@ (when v (define data (if (data+root? v) (data+root-data v) v)) (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 (lambda (key ci) (define src (demand-source key)) @@ -73,7 +82,10 @@ #:when (and (pair? k) (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 ;; resulting html @@ -151,8 +163,11 @@ (collect-info-ext-ht (resolve-info-ci (xrefs-ri xrefs))) `(index-entry ,tag) #f)]) - (cond [v (make-entry (car v) (cadr v) (cadr tag) (caddr v))] - [(and (pair? tag) (eq? 'form (car tag))) - ;; Try again with 'def: - (xref-tag->index-entry xrefs (cons 'def (cdr tag)))] - [else #f]))) + (let ([v (if (known-doc? v) + (known-doc-v v) + v)]) + (cond [v (make-entry (car v) (cadr v) (cadr tag) (caddr v))] + [(and (pair? tag) (eq? 'form (car tag))) + ;; Try again with 'def: + (xref-tag->index-entry xrefs (cons 'def (cdr tag)))] + [else #f]))))