From b76831a2cf0cd85c6cbf8fea61e746d9f142280e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 3 May 2014 07:30:23 -0600 Subject: [PATCH] scribble/manual: clicking on a section title shows linking information Thanks to Matthew Butterick for help and advice. original commit: b8cc111e92e1c704a0f3462102c86dc24f8f5615 --- .../scribblings/scribble/base.scrbl | 6 +- .../scribblings/scribble/core.scrbl | 21 +++++ pkgs/scribble-pkgs/scribble-lib/info.rkt | 2 +- .../scribble-lib/scribble/html-properties.rkt | 2 + .../scribble-lib/scribble/html-render.rkt | 24 +++++- .../scribble-lib/scribble/manual-racket.css | 13 ++- .../scribble-lib/scribble/manual-racket.js | 82 +++++++++++++++++++ .../scribble/private/manual-defaults.rkt | 4 +- 8 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.js diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl index 05345bb7..94f2ba5f 100644 --- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl +++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl @@ -598,7 +598,11 @@ document style. By default, only the section number is shown in the reference, but the @racketmodname[scribble/manual] style shows the title after the section number. Customize the output (see @secref["config"]) by redefining the @ltx{BookRef}, @|etc|, macros (see -@secref["builtin-latex"]).} +@secref["builtin-latex"]). + +In Racket documentation that is rendered to HTML, clicking on a +section title normally shows the @racket[secref] call that is needed +to link to the section.} @defproc[(Secref [tag string?] diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl index 4890066a..89acf33c 100644 --- a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl +++ b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/core.scrbl @@ -479,6 +479,12 @@ The recognized @tech{style properties} are as follows: how objects that subscribe to the @racketmodname[file/convertible] protocol are rendered.} + @item{@racket[document-source] structure --- For HTML, provides a + module path for the part's source. Clicking on an HTML section + title generated for the part or its sub-parts may show the + module path plus a section-tag string, so that the user can + create a reference to the section.} + ] The @racket[to-collect] field contains @techlink{content} that is @@ -1557,6 +1563,21 @@ Used as a @tech{style property} to associate an @tt{id} attribute with an HTML tag.} +@defstruct[document-source ([module-path module-path?])]{ + +Used as a @tech{style property} to associate a module path with a +part. Clicking on a section title within the part may show +@racket[module-path] with the part's tag string, so that authors of +other documents can link to the section. + +More specifically, the section title is given the HTML attributes +@tt{x-source-module} and @tt{x-part-tag}. The +@racketmodname[scribble/manual] style recognizes those tags to make +clicking a title show cross-reference information. + +@history[#:added "1.2"]} + + @defstruct[html-defaults ([prefix (or/c bytes? path-string? (cons/c 'collects (listof bytes?)))] [style (or/c bytes? path-string? diff --git a/pkgs/scribble-pkgs/scribble-lib/info.rkt b/pkgs/scribble-pkgs/scribble-lib/info.rkt index fc1bec26..14418af7 100644 --- a/pkgs/scribble-pkgs/scribble-lib/info.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/info.rkt @@ -22,4 +22,4 @@ (define pkg-authors '(mflatt eli)) -(define version "1.1") +(define version "1.2") diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/html-properties.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/html-properties.rkt index 65d3b415..6ba51790 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/html-properties.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/html-properties.rkt @@ -6,6 +6,8 @@ (provide-structs [body-id ([value string?])] + [document-source ([module-path module-path?])] + [hover-property ([text string?])] [script-property ([type string?] [script (or/c path-string? (listof string?))])] diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt index b2a2a79f..5ffe2ebd 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt @@ -770,13 +770,19 @@ d ri))))))))) ps))))))) - (define/public (extract-part-body-id d ri) + (define/private (extract-inherited d ri pred extract) (or (ormap (lambda (v) - (and (body-id? v) - (body-id-value v))) + (and (pred v) + (extract v))) (style-properties (part-style d))) (let ([p (part-parent d ri)]) - (and p (extract-part-body-id p ri))))) + (and p (extract-inherited p ri pred extract))))) + + (define/public (extract-part-body-id d ri) + (extract-inherited d ri body-id? body-id-value)) + + (define/public (extract-part-source d ri) + (extract-inherited d ri document-source? document-source-module-path)) (define/public (part-nesting-depth d ri) 0) @@ -1079,6 +1085,16 @@ [(1) 'h3] [(2) 'h4] [else 'h5]) + ,(let ([src (extract-part-source d ri)] + [taglet (for/or ([t (in-list (part-tags d))]) + (and (pair? t) + (eq? 'part (car t)) + (= 2 (length t)) + (cadr t)))]) + (if (and src taglet) + `([x-source-module ,(format "~s" src)] + [x-part-tag ,(format "~s" taglet)]) + '())) ,@(format-number number '((tt nbsp))) ,@(map (lambda (t) `(a ([name ,(format "~a" (anchor-name diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.css b/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.css index bd830967..18c93607 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.css +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.css @@ -305,4 +305,15 @@ tbody > tr:first-child > td > .together { left: 0px; top: 0px; z-index: 1; -} \ No newline at end of file +} + +/* ---------------------------------------- */ +/* For section source modules & tags */ + +.RPartExplain { + background: #eee; + font-size: 0.9rem; + margin-top: 0.2rem; + padding: 0.2rem; + text-align: left; +} diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.js b/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.js new file mode 100644 index 00000000..9691015e --- /dev/null +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/manual-racket.js @@ -0,0 +1,82 @@ +/* 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); + } + } +}) + +function AddPartTitleOnClick(elem) { + var mod_path = elem.getAttribute("x-source-module"); + var tag = elem.getAttribute("x-part-tag"); + if (mod_path && tag) { + var info = document.createElement("div"); + 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 > 60)); + + var line1 = document.createElement("div"); + var line2 = (is_long ? document.createElement("div") : line1); + + function add(dest, str, cn) { + var s = document.createElement("span"); + s.className = cn; + s.style.whiteSpace = "nowrap"; + s.appendChild(document.createTextNode(str)); + dest.appendChild(s); + } + /* Construct a `secref` call with suitable syntax coloring: */ + add(line1, "\xA0@", "RktRdr"); + add(line1, (is_top ? "other-doc" : "secref"), "RktSym"); + add(line1, "[", "RktPn"); + if (!is_top) + add(line1, tag, "RktVal"); + if (is_long) { + /* indent second line: */ + add(line2, "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0", "RktPn"); + } + if (!is_top) + add(line2, " #:doc ", "RktPn"); + add(line2, "'", "RktVal"); + add(line2, mod_path, "RktVal"); + add(line2, "]", "RktPn"); + + info.appendChild(line1); + 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 header shows the explanation element: */ + elem.onclick = function () { + if (info.style.display == "none") + info.style.display = "block"; + else + info.style.display = "none"; + } + } +} diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/private/manual-defaults.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/private/manual-defaults.rkt index 6750ac14..809d18dd 100644 --- a/pkgs/scribble-pkgs/scribble-lib/scribble/private/manual-defaults.rkt +++ b/pkgs/scribble-pkgs/scribble-lib/scribble/private/manual-defaults.rkt @@ -18,7 +18,9 @@ (scribble-file "manual-fonts.css"))) #:properties (list (css-style-addition - (scribble-file "manual-racket.css"))) + (scribble-file "manual-racket.css")) + (js-style-addition + (scribble-file "manual-racket.js"))) #t)) (define-on-demand manual-doc-style