From 345c17e85c78771b1dd237c99c58571eb9f5fe7d Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 25 Jul 2009 20:25:33 +0000 Subject: [PATCH] major Scribble revision (v4.2.1.2) svn: r15569 --- .../scribblings/DMdA-beginner.scrbl | 2 +- collects/framework/main.ss | 12 +- collects/scribble/base-render.ss | 327 +++-- collects/scribble/base.ss | 740 ++++++++++ collects/scribble/base/lang.ss | 4 + collects/scribble/base/lang/reader.ss | 10 + collects/scribble/basic.ss | 443 +----- collects/scribble/core.ss | 532 +++++++ collects/scribble/decode-struct.ss | 3 +- collects/scribble/decode.ss | 103 +- collects/scribble/doc/reader.ss | 2 +- collects/scribble/doclang.ss | 18 +- collects/scribble/eval.ss | 14 +- collects/scribble/html-render.ss | 796 +++++------ collects/scribble/html-variants.ss | 16 + collects/scribble/latex-render.ss | 537 ++++---- collects/scribble/latex-variants.ss | 9 + collects/scribble/manual-prefix.tex | 12 + collects/scribble/manual-struct.ss | 3 +- collects/scribble/manual-style.tex | 11 + collects/scribble/manual.ss | 4 +- collects/scribble/manual/lang.ss | 21 +- collects/scribble/manual/lang/reader.ss | 2 +- collects/scribble/private/defaults.ss | 28 + collects/scribble/private/manual-bind.ss | 13 +- collects/scribble/private/manual-class.ss | 5 +- collects/scribble/private/manual-form.ss | 1 - collects/scribble/private/manual-method.ss | 4 +- collects/scribble/private/manual-proc.ss | 7 +- collects/scribble/private/manual-scheme.ss | 6 +- collects/scribble/private/manual-style.ss | 130 +- collects/scribble/private/manual-utils.ss | 13 +- collects/scribble/private/manual-vars.ss | 3 +- collects/scribble/private/provide-structs.ss | 37 + collects/scribble/private/render-utils.ss | 55 + collects/scribble/run.ss | 4 +- collects/scribble/scheme.css | 166 +++ collects/scribble/scheme.ss | 112 +- collects/scribble/scheme.tex | 52 + collects/scribble/scribble-prefix.tex | 10 - collects/scribble/scribble-style.css | 0 collects/scribble/scribble-style.tex | 0 collects/scribble/scribble.css | 204 +-- collects/scribble/scribble.tex | 125 +- collects/scribble/sigplan.ss | 109 ++ collects/scribble/sigplan/lang.ss | 41 + collects/scribble/sigplan/lang/reader.ss | 10 + collects/scribble/sigplan/sigplan.css | 8 + collects/scribble/sigplan/sigplan.tex | 18 + collects/scribble/sigplan/sigplanconf.cls | 1222 +++++++++++++++++ collects/scribble/sigplan/style.tex | 20 + collects/scribble/struct.ss | 837 +++++------ collects/scribble/text-render.ss | 29 +- .../drscheme/interface-essentials.scrbl | 3 +- collects/scribblings/guide/guide.scrbl | 5 +- collects/scribblings/guide/paths.scrbl | 8 +- collects/scribblings/guide/regexp.scrbl | 3 +- collects/scribblings/guide/unit.scrbl | 22 +- collects/scribblings/inside/utils.ss | 3 +- .../scribblings/main/private/make-search.ss | 19 +- collects/scribblings/main/private/search.js | 2 +- collects/scribblings/main/private/utils.ss | 37 +- collects/scribblings/quick/images/exprs.dat | 204 +-- collects/scribblings/quick/images/img0.pdf | Bin 2520 -> 2520 bytes collects/scribblings/quick/images/img1.pdf | Bin 2474 -> 2474 bytes collects/scribblings/quick/images/img10.pdf | 14 +- collects/scribblings/quick/images/img11.pdf | Bin 2507 -> 2507 bytes collects/scribblings/quick/images/img12.pdf | Bin 3655 -> 3655 bytes collects/scribblings/quick/images/img13.pdf | Bin 2851 -> 2851 bytes collects/scribblings/quick/images/img14.pdf | 14 +- collects/scribblings/quick/images/img15.pdf | Bin 2843 -> 2843 bytes collects/scribblings/quick/images/img16.pdf | 14 +- collects/scribblings/quick/images/img17.pdf | Bin 2520 -> 2520 bytes collects/scribblings/quick/images/img18.pdf | Bin 2474 -> 2474 bytes collects/scribblings/quick/images/img19.pdf | Bin 2473 -> 2473 bytes collects/scribblings/quick/images/img2.pdf | 14 +- collects/scribblings/quick/images/img20.pdf | Bin 2482 -> 2482 bytes collects/scribblings/quick/images/img21.pdf | Bin 2475 -> 2475 bytes collects/scribblings/quick/images/img22.pdf | Bin 2476 -> 2476 bytes collects/scribblings/quick/images/img23.pdf | Bin 2475 -> 2475 bytes collects/scribblings/quick/images/img24.pdf | Bin 2497 -> 2497 bytes collects/scribblings/quick/images/img25.pdf | 14 +- collects/scribblings/quick/images/img26.pdf | 14 +- collects/scribblings/quick/images/img27.pdf | Bin 4535 -> 4535 bytes collects/scribblings/quick/images/img28.pdf | Bin 4599 -> 4599 bytes collects/scribblings/quick/images/img29.pdf | Bin 12588 -> 12588 bytes collects/scribblings/quick/images/img3.pdf | Bin 2474 -> 2474 bytes collects/scribblings/quick/images/img4.pdf | 14 +- collects/scribblings/quick/images/img5.pdf | Bin 2578 -> 2578 bytes collects/scribblings/quick/images/img6.pdf | Bin 2474 -> 2474 bytes collects/scribblings/quick/images/img7.pdf | Bin 2623 -> 2623 bytes collects/scribblings/quick/images/img8.pdf | Bin 2502 -> 2502 bytes collects/scribblings/quick/images/img9.pdf | Bin 2852 -> 2852 bytes collects/scribblings/quick/keep.ss | 2 +- .../scribblings/reference/cont-marks.scrbl | 3 +- .../scribblings/reference/eval-model.scrbl | 5 +- collects/scribblings/reference/extras.css | 12 + collects/scribblings/reference/extras.tex | 4 + collects/scribblings/reference/help.scrbl | 15 +- collects/scribblings/reference/match-parse.ss | 12 +- .../scribblings/reference/procedures.scrbl | 2 +- .../scribblings/reference/reader-example.ss | 2 +- .../scribblings/reference/reference.scrbl | 14 +- collects/scribblings/reference/rx.ss | 37 +- collects/scribblings/scribble/base.scrbl | 494 +++++++ collects/scribblings/scribble/basic.scrbl | 270 +--- collects/scribblings/scribble/compat.scrbl | 6 + collects/scribblings/scribble/config.scrbl | 192 ++- collects/scribblings/scribble/core.scrbl | 1153 ++++++++++++++++ collects/scribblings/scribble/decode.scrbl | 45 +- collects/scribblings/scribble/doclang.scrbl | 5 +- collects/scribblings/scribble/generic.scrbl | 7 + .../scribble/getting-started.scrbl | 13 + .../scribblings/scribble/how-to-paper.scrbl | 622 +++++++++ collects/scribblings/scribble/how-to.scrbl | 209 +-- collects/scribblings/scribble/internals.scrbl | 16 + collects/scribblings/scribble/layers.scrbl | 45 +- collects/scribblings/scribble/lp.scrbl | 22 +- collects/scribblings/scribble/manual.scrbl | 164 +-- collects/scribblings/scribble/other.scrbl | 26 + collects/scribblings/scribble/plt.scrbl | 13 + .../scribblings/scribble/preprocessor.scrbl | 9 +- collects/scribblings/scribble/reader.scrbl | 2 +- collects/scribblings/scribble/scheme.scrbl | 28 +- collects/scribblings/scribble/scribble.scrbl | 38 +- collects/scribblings/scribble/shaded.css | 5 + collects/scribblings/scribble/shaded.tex | 5 + collects/scribblings/scribble/struct.scrbl | 1064 +++----------- collects/scribblings/scribble/utils.ss | 39 +- collects/scriblib/autobib.css | 6 +- collects/scriblib/autobib.ss | 122 +- collects/scriblib/autobib.tex | 4 +- collects/scriblib/figure.ss | 49 +- collects/scriblib/figure.tex | 2 +- collects/scriblib/gui-eval.ss | 17 +- collects/setup/scribble.ss | 46 +- collects/sgl/scribblings/gl.scrbl | 2 +- .../2htdp/scribblings/universe.scrbl | 2 +- src/mzscheme/src/schvers.h | 4 +- 139 files changed, 8095 insertions(+), 4053 deletions(-) create mode 100644 collects/scribble/base.ss create mode 100644 collects/scribble/base/lang.ss create mode 100644 collects/scribble/base/lang/reader.ss create mode 100644 collects/scribble/core.ss create mode 100644 collects/scribble/html-variants.ss create mode 100644 collects/scribble/latex-variants.ss create mode 100644 collects/scribble/manual-prefix.tex create mode 100644 collects/scribble/manual-style.tex create mode 100644 collects/scribble/private/defaults.ss create mode 100644 collects/scribble/private/provide-structs.ss create mode 100644 collects/scribble/private/render-utils.ss create mode 100644 collects/scribble/scheme.css create mode 100644 collects/scribble/scheme.tex create mode 100644 collects/scribble/scribble-style.css create mode 100644 collects/scribble/scribble-style.tex create mode 100644 collects/scribble/sigplan.ss create mode 100644 collects/scribble/sigplan/lang.ss create mode 100644 collects/scribble/sigplan/lang/reader.ss create mode 100644 collects/scribble/sigplan/sigplan.css create mode 100644 collects/scribble/sigplan/sigplan.tex create mode 100644 collects/scribble/sigplan/sigplanconf.cls create mode 100644 collects/scribble/sigplan/style.tex create mode 100644 collects/scribblings/reference/extras.css create mode 100644 collects/scribblings/reference/extras.tex create mode 100644 collects/scribblings/scribble/base.scrbl create mode 100644 collects/scribblings/scribble/compat.scrbl create mode 100644 collects/scribblings/scribble/core.scrbl create mode 100644 collects/scribblings/scribble/generic.scrbl create mode 100644 collects/scribblings/scribble/getting-started.scrbl create mode 100644 collects/scribblings/scribble/how-to-paper.scrbl create mode 100644 collects/scribblings/scribble/internals.scrbl create mode 100644 collects/scribblings/scribble/other.scrbl create mode 100644 collects/scribblings/scribble/plt.scrbl create mode 100644 collects/scribblings/scribble/shaded.css create mode 100644 collects/scribblings/scribble/shaded.tex diff --git a/collects/deinprogramm/scribblings/DMdA-beginner.scrbl b/collects/deinprogramm/scribblings/DMdA-beginner.scrbl index 1d73816596..ba44bb0194 100644 --- a/collects/deinprogramm/scribblings/DMdA-beginner.scrbl +++ b/collects/deinprogramm/scribblings/DMdA-beginner.scrbl @@ -200,7 +200,7 @@ sie bindet den Namen @scheme[id] an den Vertrag @scheme[contract]. Die zweite Form führt einen @deftech{parametrischen Vertrag} (wie @scheme[list]) ein, der über die Parameter @scheme[p1] -... abstrahiert. Der parametrische Vertrag kann dann als @schemeidfont['(id +... abstrahiert. Der parametrische Vertrag kann dann als @scheme['(id a1 ...)] verwendet werden, wobei in @scheme[contract] für die Parameter @scheme[p1] ... die @scheme[a1] ... eingesetzt werden. } diff --git a/collects/framework/main.ss b/collects/framework/main.ss index 3ef7215773..aa0a4b6874 100644 --- a/collects/framework/main.ss +++ b/collects/framework/main.ss @@ -854,7 +854,7 @@ () @{This returns the reset unlocked @scheme[bitmap]. - The bitmap may not respond @scheme[#t] to the @link bitmap ok? + The bitmap may not respond @scheme[#t] to the @method[bitmap% ok?] method.}) (proc-doc/names @@ -870,10 +870,10 @@ icon:get-left/right-cursor (-> (is-a?/c cursor%)) () - @{This function returns a @link cursor object that indicates + @{This function returns a @scheme[cursor%] object that indicates left/right sizing is possible, for use with columns inside a window. - The cursor may not respond @scheme[#t] to the @link cursor ok? + The cursor may not respond @scheme[#t] to the @method[cursor% ok?] method.}) (proc-doc/names @@ -893,7 +893,7 @@ @{This returns a bitmap to be displayed in an @scheme[frame:info<%>] frame when garbage collection is taking place. - The bitmap may not respond @scheme[#t] to the @link bitmap ok? + The bitmap may not respond @scheme[#t] to the @method[bitmap% ok?] method.}) (proc-doc/names @@ -1233,7 +1233,7 @@ keymap:setup-search ((is-a?/c keymap%) . -> . void?) (keymap) - @{This extends a @link keymap with the bindings for searching.}) + @{This extends a @scheme[keymap%] with the bindings for searching.}) (proc-doc/names keymap:set-chained-keymaps @@ -1344,7 +1344,7 @@ scheme:get-wordbreak-map (-> (is-a?/c editor-wordbreak-map%)) () - @{This method returns a @link editor-wordbreak-map that is suitable + @{This method returns a @scheme[editor-wordbreak-map%] that is suitable for Scheme.}) (proc-doc/names diff --git a/collects/scribble/base-render.ss b/collects/scribble/base-render.ss index a47126df5b..0cebeeb1d9 100644 --- a/collects/scribble/base-render.ss +++ b/collects/scribble/base-render.ss @@ -1,6 +1,7 @@ #lang scheme/base -(require "struct.ss" +(require "core.ss" + "private/render-utils.ss" mzlib/class mzlib/serialize scheme/file @@ -51,36 +52,109 @@ ;; ---------------------------------------- - (define/public (extract-part-style-files d ri tag stop-at-part?) - (let loop ([p d][up? #t][only-up? #f]) - (let ([s (part-style p)]) - (apply - append - (if up? - (let ([p (collected-info-parent (part-collected-info p ri))]) - (if p - (loop p #t #t) - null)) - null) - (if (list? s) - (filter - values - (map (lambda (s) - (and (list? s) - (= 2 (length s)) - (eq? (car s) tag) - (path-string? (cadr s)) - (cadr s))) - s)) - null) - (if only-up? - null - (map (lambda (p) - (if (stop-at-part? p) - null - (loop p #f #f))) - (part-parts p))))))) - + (define/public (extract-part-style-files d ri tag stop-at-part? pred extract) + (let ([ht (make-hash)]) + (let loop ([p d][up? #t][only-up? #f]) + (let ([s (part-style p)]) + (when up? + (let ([p (collected-info-parent (part-collected-info p ri))]) + (if p + (loop p #t #t) + null))) + (extract-style-style-files (part-style p) ht pred extract) + (unless only-up? + (extract-content-style-files (part-to-collect p) d ri ht pred extract) + (extract-content-style-files (part-title-content p) d ri ht pred extract) + (extract-flow-style-files (part-blocks p) d ri ht pred extract)) + (unless only-up? + (for-each (lambda (p) + (unless (stop-at-part? p) + (loop p #f #f))) + (part-parts p))))) + (for/list ([k (in-hash-keys ht)]) (main-collects-relative->path k)))) + + (define/private (extract-style-style-files s ht pred extract) + (for ([v (in-list (style-variants s))]) + (when (pred v) + (hash-set! ht (extract v) #t)))) + + (define/private (extract-flow-style-files blocks d ri ht pred extract) + (for ([b (in-list blocks)]) + (extract-block-style-files b d ri ht pred extract))) + + (define/private (extract-block-style-files p d ri ht pred extract) + (cond + [(table? p) + (extract-style-style-files (table-style p) ht pred extract) + (for-each (lambda (blocks) + (for-each (lambda (block) + (unless (eq? block 'cont) + (extract-block-style-files block d ri ht pred extract))) + blocks)) + (table-blockss p))] + [(itemization? p) + (extract-style-style-files (itemization-style p) ht pred extract) + (for-each (lambda (blocks) + (extract-flow-style-files blocks d ri ht pred extract)) + (itemization-blockss p))] + [(nested-flow? p) + (extract-style-style-files (nested-flow-style p) ht pred extract) + (extract-flow-style-files (nested-flow-blocks p) d ri ht pred extract)] + [(compound-paragraph? p) + (extract-style-style-files (compound-paragraph-style p) ht pred extract) + (extract-flow-style-files (compound-paragraph-blocks p) d ri ht pred extract)] + [(delayed-block? p) + (let ([v ((delayed-block-resolve p) this d ri)]) + (extract-block-style-files v d ri ht pred extract))] + [else + (extract-style-style-files (paragraph-style p) ht pred extract) + (extract-content-style-files (paragraph-content p) d ri ht pred extract)])) + + (define/private (extract-content-style-files e d ri ht pred extract) + (cond + [(element? e) + (when (style? (element-style e)) + (extract-style-style-files (element-style e) ht pred extract)) + (extract-content-style-files (element-content e) d ri ht pred extract)] + [(multiarg-element? e) + (when (style? (multiarg-element-style e)) + (extract-style-style-files (multiarg-element-style e) ht pred extract)) + (extract-content-style-files (multiarg-element-contents e) d ri ht pred extract)] + [(list? e) + (for ([e (in-list e)]) + (extract-content-style-files e d ri ht pred extract))] + [(delayed-element? e) + (extract-content-style-files (delayed-element-content e ri) d ri ht pred extract)] + [(part-relative-element? e) + (extract-content-style-files (part-relative-element-content e ri) d ri ht pred extract)])) + + (define/public (extract-version d) + (or (ormap (lambda (v) + (and (document-version? v) + (document-version-text v))) + (style-variants (part-style d))) + "")) + + (define/private (extract-pre-paras d sym) + (let loop ([l (part-blocks d)]) + (cond + [(null? l) null] + [else (let ([v (car l)]) + (cond + [(and (paragraph? v) + (eq? sym (style-name (paragraph-style v)))) + (cons v (loop (cdr l)))] + [(compound-paragraph? v) + (append (loop (compound-paragraph-blocks v)) + (loop (cdr l)))] + [else (loop (cdr l))]))]))) + + (define/public (extract-authors d) + (extract-pre-paras d 'author)) + + (define/public (extract-pretitle d) + (extract-pre-paras d 'pretitle)) + ;; ---------------------------------------- (define root (make-mobile-root root-path)) @@ -196,20 +270,18 @@ (collect-content (part-title-content d) p-ci)) (collect-part-tags d p-ci number) (collect-content (part-to-collect d) p-ci) - (collect-flow (part-flow d) p-ci) + (collect-flow (part-blocks d) p-ci) (let loop ([parts (part-parts d)] [pos 1]) (unless (null? parts) (let ([s (car parts)]) (collect-part s d p-ci - (cons (if (or (unnumbered-part? s) - (part-style? s 'unnumbered)) + (cons (if (part-style? s 'unnumbered) #f pos) number)) (loop (cdr parts) - (if (or (unnumbered-part? s) - (part-style? s 'unnumbered)) + (if (part-style? s 'unnumbered) pos (add1 pos))))))) (let ([prefix (part-tag-prefix d)]) @@ -241,41 +313,38 @@ number (add-current-tag-prefix t)))))) - (define/public (collect-content c ci) - (for ([i (in-list c)]) (collect-element i ci))) - (define/public (collect-paragraph p ci) (collect-content (paragraph-content p) ci)) (define/public (collect-flow p ci) - (for ([p (in-list (flow-paragraphs p))]) + (for ([p (in-list p)]) (collect-block p ci))) (define/public (collect-block p ci) (cond [(table? p) (collect-table p ci)] [(itemization? p) (collect-itemization p ci)] - [(blockquote? p) (collect-blockquote p ci)] + [(nested-flow? p) (collect-nested-flow p ci)] [(compound-paragraph? p) (collect-compound-paragraph p ci)] [(delayed-block? p) (void)] [else (collect-paragraph p ci)])) (define/public (collect-table i ci) - (for ([d (in-list (apply append (table-flowss i)))]) - (when (flow? d) (collect-flow d ci)))) + (for ([d (in-list (apply append (table-blockss i)))]) + (unless (eq? d 'cont) (collect-block d ci)))) (define/public (collect-itemization i ci) - (for ([d (in-list (itemization-flows i))]) + (for ([d (in-list (itemization-blockss i))]) (collect-flow d ci))) - (define/public (collect-blockquote i ci) - (for ([d (in-list (blockquote-paragraphs i))]) + (define/public (collect-nested-flow i ci) + (for ([d (in-list (nested-flow-blocks i))]) (collect-block d ci))) (define/public (collect-compound-paragraph i ci) (for ([d (in-list (compound-paragraph-blocks i))]) (collect-block d ci))) - (define/public (collect-element i ci) + (define/public (collect-content i ci) (if (part-relative-element? i) (let ([content (or (hash-ref (collect-info-relatives ci) i #f) (let ([v ((part-relative-element-collect i) ci)]) @@ -286,7 +355,11 @@ (when (index-element? i) (collect-index-element i ci)) (when (collect-element? i) ((collect-element-collect i) ci)) (when (element? i) - (for ([e (element-content i)]) (collect-element e ci)))))) + (collect-content (element-content i) ci)) + (when (multiarg-element? i) + (collect-content (multiarg-element-contents i) ci)) + (when (list? i) + (for ([e (in-list i)]) (collect-content e ci)))))) (define/public (collect-target-element i ci) (let ([t (generate-tag (target-element-tag i) ci)]) @@ -315,26 +388,22 @@ (extend-prefix d (fresh-tag-resolve-context? d ri))]) (when (part-title-content d) (resolve-content (part-title-content d) d ri)) - (resolve-flow (part-flow d) d ri) + (resolve-flow (part-blocks d) d ri) (for ([p (part-parts d)]) (resolve-part p ri)))) - (define/public (resolve-content c d ri) - (for ([i (in-list c)]) - (resolve-element i d ri))) - (define/public (resolve-paragraph p d ri) (resolve-content (paragraph-content p) d ri)) - (define/public (resolve-flow p d ri) - (for ([p (flow-paragraphs p)]) + (define/public (resolve-flow f d ri) + (for ([p (in-list f)]) (resolve-block p d ri))) (define/public (resolve-block p d ri) (cond [(table? p) (resolve-table p d ri)] [(itemization? p) (resolve-itemization p d ri)] - [(blockquote? p) (resolve-blockquote p d ri)] + [(nested-flow? p) (resolve-nested-flow p d ri)] [(compound-paragraph? p) (resolve-compound-paragraph p d ri)] [(delayed-block? p) (let ([v ((delayed-block-resolve p) this d ri)]) @@ -343,22 +412,22 @@ [else (resolve-paragraph p d ri)])) (define/public (resolve-table i d ri) - (for ([f (in-list (apply append (table-flowss i)))]) - (when (flow? f) (resolve-flow f d ri)))) + (for ([f (in-list (apply append (table-blockss i)))]) + (unless (eq? f 'cont) (resolve-block f d ri)))) (define/public (resolve-itemization i d ri) - (for ([f (in-list (itemization-flows i))]) + (for ([f (in-list (itemization-blockss i))]) (resolve-flow f d ri))) - - (define/public (resolve-blockquote i d ri) - (for ([f (in-list (blockquote-paragraphs i))]) + + (define/public (resolve-nested-flow i d ri) + (for ([f (in-list (nested-flow-blocks i))]) (resolve-block f d ri))) (define/public (resolve-compound-paragraph i d ri) (for ([f (in-list (compound-paragraph-blocks i))]) (resolve-block f d ri))) - (define/public (resolve-element i d ri) + (define/public (resolve-content i d ri) (cond [(part-relative-element? i) (resolve-content (part-relative-element-content i ri) d ri)] @@ -368,6 +437,9 @@ (hash-set! (resolve-info-delays ri) i v) v)) d ri)] + [(list? i) + (for ([i (in-list i)]) + (resolve-content i d ri))] [(element? i) (cond [(index-element? i) @@ -377,19 +449,30 @@ (hash-set! (resolve-info-delays ri) e v))))] [(link-element? i) (resolve-get d ri (link-element-tag i))]) - (for ([e (element-content i)]) - (resolve-element e d ri))])) + (resolve-content (element-content i) d ri)] + [(multiarg-element? i) + (resolve-content (multiarg-element-contents i) d ri)])) ;; ---------------------------------------- ;; render methods - (define/public (install-extra-files) - (for ([fn extra-files]) (install-file fn))) + (define/public (auto-extra-files? v) #f) + (define/public (auto-extra-files-paths v) null) + + (define/public (install-extra-files ds) + (for ([fn extra-files]) (install-file fn)) + (unless prefix-file + (for ([d (in-list ds)]) + (let ([extras (ormap (lambda (v) (and (auto-extra-files? v) v)) + (style-variants (part-style d)))]) + (when extras + (for ([fn (in-list (auto-extra-files-paths extras))]) + (install-file (main-collects-relative->path fn)))))))) (define/public (render ds fns ri) ;; maybe this should happen even if fns is empty or all #f? ;; or maybe it should happen for each file rendered (when d is not #f)? - (unless (andmap not ds) (install-extra-files)) + (unless (andmap not ds) (install-extra-files ds)) (map (lambda (d fn) (define (one) (render-one d ri fn)) (when (report-output?) (printf " [Output to ~a]\n" fn)) @@ -415,13 +498,10 @@ (list (when (part-title-content d) (render-content (part-title-content d) d ri)) - (render-flow (part-flow d) d ri #f) + (render-flow (part-blocks d) d ri #f) (map (lambda (s) (render-part s ri)) (part-parts d)))) - (define/public (render-content c part ri) - (apply append (map (lambda (i) (render-element i part ri)) c))) - (define/public (render-paragraph p part ri) (render-content (paragraph-content p) part ri)) @@ -436,49 +516,51 @@ (loop (cdr l) #f))])))) (define/public (render-flow p part ri starting-item?) - (if (null? (flow-paragraphs p)) + (if (null? p) null (append - (render-block (car (flow-paragraphs p)) + (render-block (car p) part ri starting-item?) (apply append (map (lambda (p) (render-block p part ri #f)) - (cdr (flow-paragraphs p))))))) + (cdr p)))))) (define/public (render-intrapara-block p part ri first? last? starting-item?) (render-block p part ri starting-item?)) - (define/public (render-block p part ri inline?) + (define/public (render-block p part ri starting-item?) (cond - [(table? p) (if (auxiliary-table? p) - (render-auxiliary-table p part ri) - (render-table p part ri inline?))] - [(itemization? p) (render-itemization p part ri)] - [(blockquote? p) (render-blockquote p part ri)] - [(compound-paragraph? p) (render-compound-paragraph p part ri inline?)] - [(delayed-block? p) - (render-block (delayed-block-blocks p ri) part ri inline?)] - [else (render-paragraph p part ri)])) + [(table? p) (if (memq 'aux (style-variants (table-style p))) + (render-auxiliary-table p part ri) + (render-table p part ri starting-item?))] + [(itemization? p) (render-itemization p part ri)] + [(nested-flow? p) (render-nested-flow p part ri)] + [(compound-paragraph? p) (render-compound-paragraph p part ri starting-item?)] + [(delayed-block? p) + (render-block (delayed-block-blocks p ri) part ri starting-item?)] + [else (render-paragraph p part ri)])) (define/public (render-auxiliary-table i part ri) null) - (define/public (render-table i part ri inline?) - (map (lambda (d) (if (flow? i) (render-flow d part ri #f) null)) - (apply append (table-flowss i)))) + (define/public (render-table i part ri starting-item?) + (map (lambda (d) (if (eq? i 'cont) null (render-block d part ri #f))) + (apply append (table-blockss i)))) (define/public (render-itemization i part ri) (map (lambda (d) (render-flow d part ri #t)) - (itemization-flows i))) + (itemization-blockss i))) - (define/public (render-blockquote i part ri) + (define/public (render-nested-flow i part ri) (map (lambda (d) (render-block d part ri #f)) - (blockquote-paragraphs i))) + (nested-flow-blocks i))) - (define/public (render-element i part ri) + (define/public (render-content i part ri) (cond [(string? i) (render-other i part ri)] ; short-cut for common case + [(list? i) + (apply append (for/list ([i (in-list i)]) (render-content i part ri)))] [(and (link-element? i) (null? (element-content i))) (let ([v (resolve-get part ri (link-element-tag i))]) @@ -489,6 +571,8 @@ (when (render-element? i) ((render-element-render i) this part ri)) (render-content (element-content i) part ri)] + [(multiarg-element? i) + (render-content (multiarg-element-contents i) part ri)] [(delayed-element? i) (render-content (delayed-element-content i ri) part ri)] [(part-relative-element? i) @@ -568,15 +652,15 @@ ;; ---------------------------------------- (define/private (do-table-of-contents part ri delta quiet depth) - (make-table #f (generate-toc part - ri - (+ delta - (length (collected-info-number - (part-collected-info part ri)))) - #t - quiet - depth - null))) + (make-table plain (generate-toc part + ri + (+ delta + (length (collected-info-number + (part-collected-info part ri)))) + #t + quiet + depth + null))) (define/public (table-of-contents part ri) (do-table-of-contents part ri -1 not +inf.0)) @@ -605,31 +689,30 @@ (if skip? subs (let ([l (cons - (list (make-flow + (list (make-paragraph + plain (list - (make-paragraph - (list - (make-element - 'hspace - (list (make-string (* 2 (- (length number) - base-len)) - #\space))) - (make-link-element - (if (= 1 (length number)) "toptoclink" "toclink") - (append - (format-number - number - (list (make-element 'hspace '(" ")))) - (or (part-title-content part) '("???"))) - (for/fold ([t (car (part-tags part))]) - ([prefix (in-list prefixes)]) - (convert-key prefix t)))))))) + (make-element + 'hspace + (list (make-string (* 2 (- (length number) + base-len)) + #\space))) + (make-link-element + (if (= 1 (length number)) "toptoclink" "toclink") + (append + (format-number + number + (list (make-element 'hspace '(" ")))) + (or (part-title-content part) '("???"))) + (for/fold ([t (car (part-tags part))]) + ([prefix (in-list prefixes)]) + (convert-key prefix t)))))) subs)]) (if (and (= 1 (length number)) (or (not (car number)) ((car number) . > . 1))) - (cons (list (make-flow - (list (make-paragraph - (list (make-element 'hspace (list ""))))))) + (cons (list (make-paragraph + plain + (list (make-element 'hspace (list ""))))) l) l))))) diff --git a/collects/scribble/base.ss b/collects/scribble/base.ss new file mode 100644 index 0000000000..c9f71fbc6b --- /dev/null +++ b/collects/scribble/base.ss @@ -0,0 +1,740 @@ +#lang scheme/base + +(require "decode.ss" + "core.ss" + "manual-struct.ss" + "decode-struct.ss" + "html-variants.ss" + scheme/list + scheme/class + scheme/contract + setup/main-collects + syntax/modresolve + (for-syntax scheme/base)) + +;; ---------------------------------------- + +(define-syntax-rule (title-like-contract) + (->* () + (#:tag (or/c #f string? (listof string?)) + #:tag-prefix (or/c #f string? module-path?) + #:style (or/c style? string? symbol? (listof symbol?) #f)) + #:rest (listof pre-content?) + part-start?)) + +(provide/contract + [title (->* () + (#:tag (or/c #f string? (listof string?)) + #:tag-prefix (or/c #f string? module-path?) + #:style (or/c style? string? symbol? (listof symbol?) #f) + #:version (or/c string? #f)) + #:rest (listof pre-content?) + title-decl?)] + [section (title-like-contract)] + [subsection (title-like-contract)] + [subsubsection (title-like-contract)] + [subsubsub*section (->* () + (#:tag (or/c #f string? (listof string?))) + #:rest (listof pre-content?) + block?)]) +(provide include-section) + +(define (gen-tag content) + (regexp-replace* "[^-a-zA-Z0-9_=]" (content->string content) "_")) + +(define (prefix->string p) + (and p (if (string? p) p (module-path-prefix->string p)))) + +(define (convert-tag tag content) + (if (list? tag) + (append-map (lambda (t) (convert-tag t content)) tag) + `((part ,(or tag (gen-tag content)))))) + +(define (convert-part-style who s) + (cond + [(style? s) s] + [(not s) plain] + [(string? s) (make-style s null)] + [(symbol? s) (make-style #f (list s))] + [(and (list? s) (andmap symbol? s)) (make-style #f s)] + [else (raise-type-error who "style, string, symbol, list of symbols, or #f" s)])) + +(define (title #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style plain] + #:version [version #f] . str) + (let ([content (decode-content str)]) + (make-title-decl (prefix->string prefix) + (convert-tag tag content) + version + (convert-part-style 'title style) + content))) + +(define (section #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style plain] + . str) + (let ([content (decode-content str)]) + (make-part-start 0 (prefix->string prefix) + (convert-tag tag content) + (convert-part-style 'section style) + content))) + +(define (subsection #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style plain] + . str) + (let ([content (decode-content str)]) + (make-part-start 1 + (prefix->string prefix) + (convert-tag tag content) + (convert-part-style 'subsection style) + content))) + +(define (subsubsection #:tag [tag #f] #:tag-prefix [prefix #f] + #:style [style plain] . str) + (let ([content (decode-content str)]) + (make-part-start 2 + (prefix->string prefix) + (convert-tag tag content) + (convert-part-style 'subsubsection style) + content))) + +(define (subsubsub*section #:tag [tag #f] . str) + (let ([content (decode-content str)]) + (make-paragraph plain + (list + (make-element 'bold + (if tag + (make-target-element #f content `(part ,tag)) + content)))))) + +(define-syntax (include-section stx) + (syntax-case stx () + [(_ mod) + (with-syntax ([mod (syntax-local-introduce #'mod)]) + (unless (module-path? (syntax->datum #'mod)) + (raise-syntax-error #f + "not a module path" + stx + #'mod)) + #'(begin + (require (only-in mod doc)) + doc))])) + +;; ---------------------------------------- + +(provide/contract + [author (->* (content?) () #:rest (listof content?) block?)] + [author+email (-> content? string? element?)]) + +(define (author . auths) + (make-paragraph + (make-style 'author null) + (let ([nl (make-element 'newline '("\n"))]) + (case (length auths) + [(1) auths] + [(2) (list (car auths) nl "and " (cadr auths))] + [else (let ([r (reverse auths)]) + (append (add-between (reverse (cdr r)) + (make-element #f (list "," nl))) + (list "," nl "and " (car r))))])))) + +(define (author+email name email) + (make-element #f + (list + name + " <" + (regexp-replace* #rx"[.]" + (regexp-replace* #rx"@" email " at ") + " dot ") + ">"))) + +;; ---------------------------------------- + +(provide intern-taglet + module-path-index->taglet + module-path-prefix->string + doc-prefix) + +(require syntax/modcollapse + ;; Needed to normalize planet version numbers: + (only-in planet/resolver get-planet-module-path/pkg) + (only-in planet/private/data pkg-maj pkg-min)) + +(define interned (make-weak-hash)) + +(define (intern-taglet v) + (let ([v (if (list? v) + (map intern-taglet v) + v)]) + (if (or (string? v) + (bytes? v) + (list? v)) + (let ([b (hash-ref interned v #f)]) + (if b + (or (weak-box-value b) + ;; just in case the value is GCed before we extract it: + (intern-taglet v)) + (begin + (hash-set! interned v (make-weak-box v)) + v))) + v))) + +(define (do-module-path-index->taglet mod) + ;; Derive the name from the module path: + (let ([p (collapse-module-path-index + mod + (lambda () (build-path (current-directory) "dummy")))]) + (if (path? p) + ;; If we got a path back anyway, then it's best to use the resolved + ;; name; if the current directory has changed since we + ;; the path-index was resolved, then p might not be right. Also, + ;; the resolved path might be a symbol instead of a path. + (let ([rp (resolved-module-path-name + (module-path-index-resolve mod))]) + (if (path? rp) + (intern-taglet + (path->main-collects-relative rp)) + rp)) + (let ([p (if (and (pair? p) + (eq? (car p) 'planet)) + ;; Normalize planet verion number based on current + ;; linking: + (let-values ([(path pkg) + (get-planet-module-path/pkg p #f #f)]) + (list* 'planet + (cadr p) + (list (car (caddr p)) + (cadr (caddr p)) + (pkg-maj pkg) + (pkg-min pkg)) + (cdddr p))) + ;; Otherwise the path is fully normalized: + p)]) + (intern-taglet p))))) + +(define collapsed (make-weak-hasheq)) +(define (module-path-index->taglet mod) + (or (hash-ref collapsed mod #f) + (let ([v (do-module-path-index->taglet mod)]) + (hash-set! collapsed mod v) + v))) + +(define (module-path-prefix->string p) + (format "~a" (module-path-index->taglet (module-path-index-join p #f)))) + +(define doc-prefix + (case-lambda + [(doc s) + (if doc + (list (module-path-prefix->string doc) s) + s)] + [(doc prefix s) + (doc-prefix doc (if prefix + (append prefix (list s)) + s))])) + +;; ---------------------------------------- + +(define (item? x) (an-item? x)) + +(provide/contract + [itemlist (->* () + (#:style (or/c style? string? symbol? #f)) + #:rest (listof item?) + itemization?)] + [item (->* () + () + #:rest (listof pre-flow?) + item?)]) +(provide item?) + +(define (itemlist #:style [style plain] . items) + (let ([flows (map an-item-flow items)]) + (make-itemization (convert-block-style style) flows))) + +(define-struct an-item (flow)) + +(define (item . str) + (make-an-item (decode-flow str))) + +;; ---------------------------------------- + +(define elem-like-contract + (->* () () #:rest (listof pre-content?) element?)) + +(provide/contract + [hspace (-> exact-nonnegative-integer? element?)] + [elem (->* () + (#:style element-style?) + #:rest (listof pre-content?) + element?)] + [italic elem-like-contract] + [bold elem-like-contract] + [smaller elem-like-contract] + [larger elem-like-contract] + [emph elem-like-contract] + [tt elem-like-contract] + [subscript elem-like-contract] + [superscript elem-like-contract] + + [literal (->* (string?) () #:rest (listof string?) element?)] + + [image (->* ((or/c path-string? (cons/c 'collects (listof bytes?)))) + (#:scale real? + #:suffixes (listof #rx"^[.]")) + #:rest (listof content?) + image-element?)]) + +(define hspace-cache (make-vector 100 #f)) + +(define (hspace n) + (if (n . < . (vector-length hspace-cache)) + (or (vector-ref hspace-cache n) + (let ([h (make-element 'hspace (list (make-string n #\space)))]) + (vector-set! hspace-cache n h) + h)) + (make-element 'hspace (list (make-string n #\space))))) + +(define (elem #:style [style plain] . str) + (make-element style (decode-content str))) + +(define (italic . str) + (make-element 'italic (decode-content str))) + +(define (bold . str) + (make-element 'bold (decode-content str))) + +(define (smaller . str) + (make-element 'smaller (decode-content str))) + +(define (larger . str) + (make-element 'larger (decode-content str))) + +(define (emph . str) + (make-element 'italic (decode-content str))) + +(define (tt . str) + (let* ([l (decode-content str)] + [l (let ([m (and (pair? l) + (string? (car l)) + (regexp-match-positions #rx"^ +" (car l)))]) + (if m + (list* (hspace (- (cdar m) (caar m))) + (substring (car l) (cdar m)) + (cdr l)) + l))]) + (if (andmap string? l) + (make-element 'tt l) + (make-element #f (map (lambda (s) + (if (or (string? s) (symbol? s)) + (make-element 'tt (list s)) + s)) + l))))) + +(define (span-class classname . str) + (make-element classname (decode-content str))) + +(define (subscript . str) + (make-element 'subscript (decode-content str))) + +(define (superscript . str) + (make-element 'superscript (decode-content str))) + +(define (literal s . strs) + (let ([s (apply string-append s strs)]) + (make-element #f s))) + +(define (image #:scale [scale 1.0] + filename-relative-to-source + #:suffixes [suffixes null] + . alt) + (make-image-element #f + (decode-content alt) + filename-relative-to-source + suffixes + scale)) + +;; ---------------------------------------- + +(provide/contract + [para (->* () + (#:style (or/c style? string? symbol? #f )) + #:rest (listof pre-content?) + paragraph?)] + [nested (->* () + (#:style (or/c style? string? symbol? #f )) + #:rest (listof pre-flow?) + nested-flow?)] + [compound (->* () + (#:style (or/c style? string? symbol? #f )) + #:rest (listof pre-flow?) + compound-paragraph?)] + [tabular (->* ((listof (listof (or/c 'cont block? content?)))) + (#:style (or/c style? string? symbol? #f )) + table?)]) + +(define (convert-block-style style) + (cond + [(style? style) style] + [(or (string? style) (symbol? style)) (make-style style null)] + [else plain])) + +(define (nested #:style [style #f] . c) + (make-nested-flow (convert-block-style style) + (decode-flow c))) + +(define (para #:style [style #f] . c) + (make-paragraph (convert-block-style style) + (decode-content c))) + +(define (compound #:style [style #f] . c) + (make-compound-paragraph (convert-block-style style) + (decode-flow c))) + +(define (tabular #:style [style #f] cells) + (define (nth-str pos) + (case (modulo pos 10) + [(1) "st"] + [(2) "nd"] + [(3) "rd"] + [else "th"])) + (unless (null? cells) + (let ([n (length (car cells))]) + (for ([row (in-list (cdr cells))] + [pos (in-naturals 2)]) + (unless (= n (length row)) + (raise-mismatch-error + 'tabular + (format "bad length (~a does not match first row's length ~a) for ~a~a row: " + (length row) + n + pos + (nth-str pos)) + row))))) + (for ([row (in-list cells)] + [pos (in-naturals 1)]) + (when (and (pair? row) (eq? (car row) 'cont)) + (raise-mismatch-error + 'tabular + (format "~a~a row starts with 'cont: " pos (nth-str pos)) + row))) + (make-table (convert-block-style style) + (map (lambda (row) + (map (lambda (cell) + (cond + [(eq? cell 'cont) cell] + [(block? cell) cell] + [else (make-paragraph plain cell)])) + row)) + cells))) + +;; ---------------------------------------- + +(provide/contract + [elemtag (->* ((or/c tag? string?)) + () + #:rest (listof pre-content?) + element?)] + [elemref (->* ((or/c tag? string?)) + (#:underline? any/c) + #:rest (listof pre-content?) + element?)] + [secref (->* (string?) + (#:doc module-path? + #:tag-prefixes (or/c #f (listof string)) + #:underline? any/c) + element?)] + [Secref (->* (string?) + (#:doc module-path? + #:tag-prefixes (or/c #f (listof string)) + #:underline? any/c) + element?)] + [seclink (->* (string?) + (#:doc module-path? + #:tag-prefixes (or/c #f (listof string)) + #:underline? any/c) + #:rest (listof pre-content?) + element?)] + [other-doc (->* (module-path?) + (#:underline? any/c) + element?)]) + +(define (elemtag t . body) + (make-target-element #f (decode-content body) `(elem ,t))) +(define (elemref #:underline? [u? #t] t . body) + (make-link-element (if u? #f "plainlink") (decode-content body) `(elem ,t))) + +(define (secref s #:underline? [u? #t] #:doc [doc #f] #:tag-prefixes [prefix #f]) + (make-link-element (if u? #f "plainlink") null `(part ,(doc-prefix doc prefix s)))) +(define (Secref s #:underline? [u? #t] #:doc [doc #f] #:tag-prefixes [prefix #f]) + (let ([le (secref s #:underline? u? #:doc doc #:tag-prefixes prefix)]) + (make-link-element + (make-style (element-style le) '(uppercase)) + (element-content le) + (link-element-tag le)))) + +(define (seclink tag #:underline? [u? #t] #:doc [doc #f] #:tag-prefixes [prefix #f] . s) + (make-link-element (if u? #f "plainlink") (decode-content s) + `(part ,(doc-prefix doc prefix tag)))) + +(define (other-doc #:underline? [u? #t] doc) + (secref #:doc doc #:underline? u? "top")) + +;; ---------------------------------------- + +(provide/contract + [hyperlink (->* ((or/c string? path?)) + (#:underline? any/c + #:style element-style?) + #:rest (listof pre-content?) + element?)] + [url (-> string? element?)] + [margin-note (->* () () #:rest (listof pre-flow?) block?)] + [centered (->* () () #:rest (listof pre-flow?) block?)] + [verbatim (->* (string?) (#:indent exact-nonnegative-integer?) #:rest (listof string?) block?)]) + +(define (centered . s) + (make-nested-flow (make-style "SCentered" null) (decode-flow s))) + +(define (hyperlink url + #:underline? [underline? #t] + #:style [style (if underline? #f "plainlink")] + . str) + (make-element (make-style (if (style? style) + (style-name style) + style) + (cons (make-target-url url) + (if (style? style) + (style-variants style) + null))) + (decode-content str))) + +(define (url str) + (hyperlink str (make-element 'url str))) + +(define (margin-note . c) + (make-nested-flow + (make-style "refpara" '(command)) + (list + (make-nested-flow + (make-style "refcolumn" null) + (list + (make-nested-flow + (make-style "refcontent" null) + (decode-flow c))))))) + +(define (verbatim #:indent [i 0] s . more) + (define indent + (if (zero? i) + values + (let ([hs (hspace i)]) (lambda (x) (cons hs x))))) + (define strs (regexp-split #rx"\n" (apply string-append s more))) + (define (str->elts str) + (let ([spaces (regexp-match-positions #rx"(?:^| ) +" str)]) + (if spaces + (list* (substring str 0 (caar spaces)) + (hspace (- (cdar spaces) (caar spaces))) + (str->elts (substring str (cdar spaces)))) + (list (make-element 'tt (list str)))))) + (define (make-nonempty l) + (if (let loop ([l l]) + (cond + [(null? l) #t] + [(equal? "" l) #t] + [(list? l) (andmap loop l)] + [(element? l) (loop (element-content l))] + [(multiarg-element? l) (loop (multiarg-element-contents l))] + [else #f])) + (list l (hspace 1)) + l)) + (define (make-line str) + (let* ([line (indent (str->elts str))] + [line (list (make-element 'tt line))]) + (list (make-paragraph omitable-style (make-nonempty line))))) + (make-table plain (map make-line strs))) + +(define omitable-style (make-style 'omitable null)) + +;; ---------------------------------------- + +(provide section-index index index* as-index index-section + get-index-entries index-block) + +(define (section-index . elems) + (make-part-index-decl (map content->string elems) elems)) + +(define (record-index word-seq element-seq tag content) + (make-index-element #f + (list (make-target-element #f content `(idx ,tag))) + `(idx ,tag) + word-seq + element-seq + #f)) + +(define (index* word-seq content-seq . s) + (let ([key (make-generated-tag)]) + (record-index (map clean-up-index-string word-seq) + content-seq key (decode-content s)))) + +(define (index word-seq . s) + (let ([word-seq (if (string? word-seq) (list word-seq) word-seq)]) + (apply index* word-seq word-seq s))) + +(define (as-index . s) + (let ([key (make-generated-tag)] + [content (decode-content s)]) + (record-index + (list (clean-up-index-string (content->string content))) + (if (= 1 (length content)) content (list (make-element #f content))) + key + content))) + +(define (index-section #:title [title "Index"] #:tag [tag #f]) + (make-part #f + `((part ,(or tag "doc-index"))) + (list title) + (make-style 'index '(unnumbered)) + null + (list (index-block)) + null)) + +;; returns an ordered list of (list tag (text ...) (element ...) index-desc) +(define (get-index-entries sec ri) + (define (compare-lists xs ys ] + [(] + [else (loop (cdr ys) (cdr xs))]))) + ;; string-ci] + [else (case t1 ; equal to t2 + [(part) '=] ; will just compare tags + [(mod) '=] ; the text fields are the names of the modules + [(libs) (compare-lists (cdr d1) (cdr d2) lib] ; dosn't matter, will run again + [(#f) '=])]))) + (define (entry) #f] + [else (case (compare-desc e1 e2) + [(<) #t] [(>) #f] + [else (case (compare-lists text1 text2 string) #f] + [else + ;; (error 'get-index-entries + ;; ;; when this happens, revise this code so + ;; ;; ordering will always be deterministic + ;; "internal error -- unordered entries: ~e ~e" + ;; e1 e2) + ;; Instead, just compare the tags + (stringlist "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) + (define (rows . rows) + (make-table (make-style 'index null) + (map (lambda (row) + (list (make-paragraph plain row))) + rows))) + (define contents + (lambda (renderer sec ri) + (define l (get-index-entries sec ri)) + (define manual-newlines? (send renderer index-manual-newlines?)) + (define alpha-starts (make-hasheq)) + (define alpha-row + (let loop ([i l] [alpha alpha]) + (define (add-letter let l) + (list* (make-element "nonavigation" (list (string let))) " " l)) + (cond [(null? alpha) null] + [(null? i) (add-letter (car alpha) (loop i (cdr alpha)))] + [else + (let* ([strs (cadr (car i))] + [letter (if (or (null? strs) (string=? "" (car strs))) + #f + (char-upcase (string-ref (car strs) 0)))]) + (cond [(not letter) (loop (cdr i) alpha)] + [(char-ci>? letter (car alpha)) + (add-letter (car alpha) (loop i (cdr alpha)))] + [(char-ci=? letter (car alpha)) + (hash-set! alpha-starts (car i) letter) + (list* (make-element + (make-style #f (list (make-target-url (format "#alpha:~a" letter)))) + (list (string (car alpha)))) + " " + (loop (cdr i) (cdr alpha)))] + [else (loop (cdr i) alpha)]))]))) + (define body + (let ([br (if manual-newlines? (make-element 'newline '("\n")) "")]) + (map (lambda (i) + (let ([e (make-link-element + "indexlink" + `(,@(add-between (caddr i) ", ") ,br) + (car i))]) + (cond [(hash-ref alpha-starts i #f) + => (lambda (let) + (make-element + (make-style #f (list + (make-url-anchor + (format "alpha:~a" (char-upcase let))))) + (list e)))] + [else e]))) + l))) + (if manual-newlines? + (rows alpha-row '(nbsp) body) + (apply rows alpha-row '(nbsp) (map list body))))) + (make-delayed-block contents)) + +;; ---------------------------------------- + +(provide table-of-contents + local-table-of-contents) + +(define (table-of-contents) + (make-delayed-block + (lambda (renderer part ri) + (send renderer table-of-contents part ri)))) + +(define (local-table-of-contents #:style [style plain]) + (make-delayed-block + (lambda (renderer part ri) + (send renderer local-table-of-contents part ri style)))) diff --git a/collects/scribble/base/lang.ss b/collects/scribble/base/lang.ss new file mode 100644 index 0000000000..173f2c1e57 --- /dev/null +++ b/collects/scribble/base/lang.ss @@ -0,0 +1,4 @@ +#lang scheme +(require scribble/doclang scribble/base) +(provide (all-from-out scribble/doclang + scribble/base)) diff --git a/collects/scribble/base/lang/reader.ss b/collects/scribble/base/lang/reader.ss new file mode 100644 index 0000000000..5839ac06e8 --- /dev/null +++ b/collects/scribble/base/lang/reader.ss @@ -0,0 +1,10 @@ +#lang s-exp syntax/module-reader + +scribble/base/lang + +#:read scribble:read-inside +#:read-syntax scribble:read-syntax-inside +#:whole-body-readers? #t +#:wrapper1 (lambda (t) (list* 'doc 'values '() (t))) + +(require (prefix-in scribble: "../../reader.ss")) diff --git a/collects/scribble/basic.ss b/collects/scribble/basic.ss index 80aed345a0..2bc2252c87 100644 --- a/collects/scribble/basic.ss +++ b/collects/scribble/basic.ss @@ -1,443 +1,46 @@ - #lang scheme/base -(require "decode.ss" - "struct.ss" - "config.ss" - "manual-struct.ss" - "decode-struct.ss" - scheme/list - scheme/class - setup/main-collects - syntax/modresolve - (for-syntax scheme/base)) +(require "base.ss" + "core.ss" + "decode.ss") (provide title section subsection subsubsection subsubsub*section - include-section) + include-section -(define (gen-tag content) - (regexp-replace* "[^-a-zA-Z0-9_=]" (content->string content) "_")) + author + author+email -(define (prefix->string p) - (and p (if (string? p) p (module-path-prefix->string p)))) - -(define (convert-tag tag content) - (if (list? tag) - (append-map (lambda (t) (convert-tag t content)) tag) - `((part ,(or tag (gen-tag content)))))) - -(define (title #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style #f] - #:version [version #f] . str) - (let ([content (decode-content str)]) - (make-title-decl (prefix->string prefix) - (convert-tag tag content) - version - style - content))) - -(define (section #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style #f] - . str) - (let ([content (decode-content str)]) - (make-part-start 0 (prefix->string prefix) - (convert-tag tag content) - style - content))) - -(define (subsection #:tag [tag #f] #:tag-prefix [prefix #f] #:style [style #f] - . str) - (let ([content (decode-content str)]) - (make-part-start 1 - (prefix->string prefix) - (convert-tag tag content) - style - content))) - -(define (subsubsection #:tag [tag #f] #:tag-prefix [prefix #f] - #:style [style #f] . str) - (let ([content (decode-content str)]) - (make-part-start 2 - (prefix->string prefix) - (convert-tag tag content) - style - content))) - -(define (subsubsub*section #:tag [tag #f] . str) - (let ([content (decode-content str)]) - (make-paragraph (list (make-element 'bold content))))) - -(define-syntax (include-section stx) - (syntax-case stx () - [(_ mod) - (with-syntax ([mod (syntax-local-introduce #'mod)]) - #'(begin - (require (only-in mod doc)) - doc))])) - -;; ---------------------------------------- - -(provide author - author+email) -(define (author . auths) - (make-styled-paragraph - (let ([nl (make-element 'newline '("\n"))]) - (case (length auths) - [(1) auths] - [(2) (list (car auths) nl "and " (cadr auths))] - [else (let ([r (reverse auths)]) - (append (add-between (reverse (cdr r)) - (make-element #f (list "," nl))) - (list "," nl "and " (car r))))])) - "author")) -(define (author+email name email) - (make-element #f - (list - name - " <" - (regexp-replace* #rx"[.]" - (regexp-replace* #rx"@" email " at ") - " dot ") - ">"))) - -;; ---------------------------------------- - -(provide intern-taglet + intern-taglet module-path-index->taglet - module-path-prefix->string) + module-path-prefix->string + + itemize item item? -(define interned (make-weak-hash)) - -(define (intern-taglet v) - (let ([v (if (list? v) - (map intern-taglet v) - v)]) - (if (or (string? v) - (bytes? v) - (list? v)) - (let ([b (hash-ref interned v #f)]) - (if b - (or (weak-box-value b) - ;; just in case the value is GCed before we extract it: - (intern-taglet v)) - (begin - (hash-set! interned v (make-weak-box v)) - v))) - v))) - -(define (do-module-path-index->taglet mod) - ;; Derive the name from the module path: - (let ([p (collapse-module-path-index - mod - (lambda () (build-path (current-directory) "dummy")))]) - (if (path? p) - ;; If we got a path back anyway, then it's best to use the resolved - ;; name; if the current directory has changed since we - ;; the path-index was resolved, then p might not be right. Also, - ;; the resolved path might be a symbol instead of a path. - (let ([rp (resolved-module-path-name - (module-path-index-resolve mod))]) - (if (path? rp) - (intern-taglet - (path->main-collects-relative rp)) - rp)) - (let ([p (if (and (pair? p) - (eq? (car p) 'planet)) - ;; Normalize planet verion number based on current - ;; linking: - (let-values ([(path pkg) - (get-planet-module-path/pkg p #f #f)]) - (list* 'planet - (cadr p) - (list (car (caddr p)) - (cadr (caddr p)) - (pkg-maj pkg) - (pkg-min pkg)) - (cdddr p))) - ;; Otherwise the path is fully normalized: - p)]) - (intern-taglet p))))) - -(define collapsed (make-weak-hasheq)) -(define (module-path-index->taglet mod) - (or (hash-ref collapsed mod #f) - (let ([v (do-module-path-index->taglet mod)]) - (hash-set! collapsed mod v) - v))) - -(define (module-path-prefix->string p) - (format "~a" (module-path-index->taglet (module-path-index-join p #f)))) - -;; ---------------------------------------- - -(require syntax/modcollapse - ;; Needed to normalize planet version numbers: - (only-in planet/resolver get-planet-module-path/pkg) - (only-in planet/private/data pkg-maj pkg-min)) - -(provide itemize item item?) - -(define (itemize #:style [style #f] . items) - (let ([items (filter (lambda (v) (not (whitespace? v))) items)]) - (for ([v items]) - (unless (an-item? v) - (error 'itemize "expected an item, found something else: ~e" v))) - (let ([flows (map an-item-flow items)]) - (if style - (make-styled-itemization flows style) - (make-itemization flows))))) - -(define-struct an-item (flow)) -(define (item? x) (an-item? x)) - -(define (item . str) - (make-an-item (decode-flow str))) - -;; ---------------------------------------- - -(provide hspace + hspace elem aux-elem italic bold smaller - tt span-class - subscript superscript) + tt + subscript superscript -(define hspace-cache (make-vector 100 #f)) + section-index index index* as-index index-section + get-index-entries index-block -(define (hspace n) - (if (n . < . (vector-length hspace-cache)) - (or (vector-ref hspace-cache n) - (let ([h (make-element 'hspace (list (make-string n #\space)))]) - (vector-set! hspace-cache n h) - h)) - (make-element 'hspace (list (make-string n #\space))))) + table-of-contents + local-table-of-contents -(define (elem #:style [style #f] . str) - (make-element style (decode-content str))) - -(define (aux-elem . s) - (make-aux-element #f (decode-content s))) - -(define (italic . str) - (make-element 'italic (decode-content str))) - -(define (bold . str) - (make-element 'bold (decode-content str))) - -(define (smaller . str) - (make-element "smaller" (decode-content str))) - -(define (tt . str) - (let* ([l (decode-content str)] - [l (let ([m (and (pair? l) - (string? (car l)) - (regexp-match-positions #rx"^ +" (car l)))]) - (if m - (list* (hspace (- (cdar m) (caar m))) - (substring (car l) (cdar m)) - (cdr l)) - l))]) - (if (andmap string? l) - (make-element 'tt l) - (make-element #f (map (lambda (s) - (if (or (string? s) (symbol? s)) - (make-element 'tt (list s)) - s)) - l))))) + span-class) (define (span-class classname . str) (make-element classname (decode-content str))) -(define (subscript . str) - (make-element 'subscript (decode-content str))) +(define (aux-elem . s) + (make-element (make-style #f (list 'aux)) (decode-content s))) -(define (superscript . str) - (make-element 'superscript (decode-content str))) +(define (itemize #:style [style #f] . items) + (let ([items (filter (lambda (v) (not (whitespace? v))) items)]) + (apply itemlist #:style style items))) -;; ---------------------------------------- - -(provide section-index index index* as-index index-section - get-index-entries index-block) - -(define (section-index . elems) - (make-part-index-decl (map element->string elems) elems)) - -(define (record-index word-seq element-seq tag content) - (make-index-element #f - (list (make-target-element #f content `(idx ,tag))) - `(idx ,tag) - word-seq - element-seq - #f)) - -(define (index* word-seq content-seq . s) - (let ([key (make-generated-tag)]) - (record-index (map clean-up-index-string word-seq) - content-seq key (decode-content s)))) - -(define (index word-seq . s) - (let ([word-seq (if (string? word-seq) (list word-seq) word-seq)]) - (apply index* word-seq word-seq s))) - -(define (as-index . s) - (let ([key (make-generated-tag)] - [content (decode-content s)]) - (record-index - (list (clean-up-index-string (content->string content))) - (if (= 1 (length content)) content (list (make-element #f content))) - key - content))) - -(define (index-section #:title [title "Index"] #:tag [tag #f]) - (make-unnumbered-part #f - `((part ,(or tag "doc-index"))) - (list title) - 'index - null - (make-flow (list (index-block))) - null)) - -;; returns an ordered list of (list tag (text ...) (element ...) index-desc) -(define (get-index-entries sec ri) - (define (compare-lists xs ys ] - [(] - [else (loop (cdr ys) (cdr xs))]))) - ;; string-ci] - [else (case t1 ; equal to t2 - [(part) '=] ; will just compare tags - [(mod) '=] ; the text fields are the names of the modules - [(libs) (compare-lists (cdr d1) (cdr d2) lib] ; dosn't matter, will run again - [(#f) '=])]))) - (define (entry) #f] - [else (case (compare-desc e1 e2) - [(<) #t] [(>) #f] - [else (case (compare-lists text1 text2 string) #f] - [else - ;; (error 'get-index-entries - ;; ;; when this happens, revise this code so - ;; ;; ordering will always be deterministic - ;; "internal error -- unordered entries: ~e ~e" - ;; e1 e2) - ;; Instead, just compare the tags - (stringlist "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) - (define (rows . rows) - (make-table 'index (map (lambda (row) - (list (make-flow (list (make-paragraph row))))) - rows))) - (define contents - (lambda (renderer sec ri) - (define l (get-index-entries sec ri)) - (define manual-newlines? (send renderer index-manual-newlines?)) - (define alpha-starts (make-hasheq)) - (define alpha-row - (let loop ([i l] [alpha alpha]) - (define (add-letter let l) - (list* (make-element "nonavigation" (list (string let))) " " l)) - (cond [(null? alpha) null] - [(null? i) (add-letter (car alpha) (loop i (cdr alpha)))] - [else - (let* ([strs (cadr (car i))] - [letter (if (or (null? strs) (string=? "" (car strs))) - #f - (char-upcase (string-ref (car strs) 0)))]) - (cond [(not letter) (loop (cdr i) alpha)] - [(char-ci>? letter (car alpha)) - (add-letter (car alpha) (loop i (cdr alpha)))] - [(char-ci=? letter (car alpha)) - (hash-set! alpha-starts (car i) letter) - (list* (make-element - (make-target-url (format "#alpha:~a" letter) - #f) - (list (string (car alpha)))) - " " - (loop (cdr i) (cdr alpha)))] - [else (loop (cdr i) alpha)]))]))) - (define body - (let ([br (if manual-newlines? (make-element 'newline '("\n")) "")]) - (map (lambda (i) - (let ([e (make-link-element - "indexlink" - `(,@(add-between (caddr i) ", ") ,br) - (car i))]) - (cond [(hash-ref alpha-starts i #f) - => (lambda (let) - (make-element - (make-url-anchor - (format "alpha:~a" (char-upcase let))) - (list e)))] - [else e]))) - l))) - (if manual-newlines? - (rows alpha-row '(nbsp) body) - (apply rows alpha-row '(nbsp) (map list body))))) - (make-delayed-block contents)) - -;; ---------------------------------------- - -(provide table-of-contents - local-table-of-contents) - -(define (table-of-contents) - (make-delayed-block - (lambda (renderer part ri) - (send renderer table-of-contents part ri)))) - -(define (local-table-of-contents #:style [style #f]) - (make-delayed-block - (lambda (renderer part ri) - (send renderer local-table-of-contents part ri style)))) diff --git a/collects/scribble/core.ss b/collects/scribble/core.ss new file mode 100644 index 0000000000..eb1caa8e0f --- /dev/null +++ b/collects/scribble/core.ss @@ -0,0 +1,532 @@ +#lang scheme/base +(require "private/provide-structs.ss" + scheme/serialize + scheme/contract) + +;; ---------------------------------------- + +(define-struct collect-info (ht ext-ht parts tags gen-prefix relatives parents)) +(define-struct resolve-info (ci delays undef searches)) + +(define (part-collected-info part ri) + (hash-ref (collect-info-parts (resolve-info-ci ri)) + part)) + +(define (collect-put! ci key val) + (let ([ht (collect-info-ht ci)]) + (let ([old-val (hash-ref ht key #f)]) + (when old-val + (fprintf (current-error-port) + "WARNING: collected information for key multiple times: ~e; values: ~e ~e\n" + key old-val val)) + (hash-set! ht key val)))) + +(define (resolve-get/where part ri key) + (let ([key (tag-key key ri)]) + (let ([v (hash-ref (if part + (collected-info-info (part-collected-info part ri)) + (collect-info-ht (resolve-info-ci ri))) + key + #f)]) + (cond + [v (values v #f)] + [part (resolve-get/where + (collected-info-parent (part-collected-info part ri)) + ri key)] + [else + (values (hash-ref (collect-info-ext-ht (resolve-info-ci ri)) key #f) + #t)])))) + +(define (resolve-get/ext? part ri key) + (let-values ([(v ext?) (resolve-get/where part ri key)]) + (when ext? + (hash-set! (resolve-info-undef ri) (tag-key key ri) #t)) + (values v ext?))) + +(define (resolve-get part ri key) + (let-values ([(v ext?) (resolve-get/ext? part ri key)]) + v)) + +(define (resolve-get/tentative part ri key) + (let-values ([(v ext?) (resolve-get/where part ri key)]) + v)) + +(define (resolve-search search-key part ri key) + (let ([s-ht (hash-ref (resolve-info-searches ri) + search-key + (lambda () + (let ([s-ht (make-hash)]) + (hash-set! (resolve-info-searches ri) + search-key s-ht) + s-ht)))]) + (hash-set! s-ht key #t)) + (resolve-get part ri key)) + +(define (resolve-get-keys part ri key-pred) + (let ([l null]) + (hash-for-each + (collected-info-info (part-collected-info part ri)) + (lambda (k v) (when (key-pred k) (set! l (cons k l))))) + l)) + +(provide (struct-out collect-info) + (struct-out resolve-info)) + +;; ---------------------------------------- + +(provide tag?) +(define (tag? s) + (and (pair? s) + (symbol? (car s)) + (pair? (cdr s)) + (or (string? (cadr s)) + (generated-tag? (cadr s)) + (and (pair? (cadr s)) + (list? (cadr s)))) + (null? (cddr s)))) + +(provide block?) +(define (block? p) + (or (paragraph? p) + (table? p) + (itemization? p) + (nested-flow? p) + (compound-paragraph? p) + (delayed-block? p))) + +(define content-symbols + #hasheq([nbsp . #t] + [mdash . #t] + [ndash . #t] + [ldquo . #t] + [rdquo . #t] + [rsquo . #t] + [prime . #t] + [rarr . #t] + [larr . #t] + [alpha . #t] + [infin . #t] + [lang . #t] + [rang . #t])) + +(provide content?) +(define (content? v) + (or (string? v) + (element? v) + (and (list? v) (andmap content? v)) + (delayed-element? v) + (part-relative-element? v) + (multiarg-element? v) + (hash-ref content-symbols v #f))) + +(provide element-style?) +(define (element-style? s) + (or (style? s) (not s) (string? s) (symbol? s))) + +(define (string-without-newline? s) + (and (string? s) + (not (regexp-match? #rx"\n" s)))) + +(provide-structs + [part ([tag-prefix (or/c false/c string?)] + [tags (listof tag?)] + [title-content (or/c false/c content?)] + [style style?] + [to-collect list?] + [blocks (listof block?)] + [parts (listof part?)])] + [paragraph ([style style?] + [content content?])] + [table ([style style?] + [blockss (listof (listof (or/c block? (one-of/c 'cont))))])] + [delayed-block ([resolve (any/c part? resolve-info? . -> . block?)])] + [itemization ([style style?] + [blockss (listof (listof block?))])] + [nested-flow ([style style?] + [blocks (listof block?)])] + [compound-paragraph ([style style?] + [blocks (listof block?)])] + + [element ([style element-style?] + [content content?])] + [(toc-element element) ([toc-content content?])] + [(target-element element) ([tag tag?])] + [(toc-target-element target-element) ()] + [(page-target-element target-element) ()] + [(redirect-target-element target-element) ([alt-path path-string?] + [alt-anchor string?])] + [(link-element element) ([tag tag?])] + [(index-element element) ([tag tag?] + [plain-seq (and/c pair? (listof string-without-newline?))] + [entry-seq (listof content?)] + [desc any/c])] + [(image-element element) ([path (or/c path-string? + (cons/c (one-of/c 'collects) + (listof bytes?)))] + [suffixes (listof #rx"^[.]")] + [scale real?])] + [multiarg-element ([style element-style?] + [contents (listof content?)])] + + [style ([name (or/c string? symbol? #f)] + [variants list?])] + ;; variants: + [document-version ([text (or/c string? false/c)])] + [target-url ([addr path-string?])] + [color-variant ([color (or/c string? (list/c byte? byte? byte?))])] + [background-color-variant ([color (or/c string? (list/c byte? byte? byte?))])] + + [table-columns ([styles (listof style?)])] + [table-cells ([styless (listof (listof style?))])] + + [collected-info ([number (listof (or/c false/c integer?))] + [parent (or/c false/c part?)] + [info any/c])]) + +(provide plain) +(define plain (make-style #f null)) + +;; ---------------------------------------- + +;; Delayed element has special serialization support: +(define-struct delayed-element (resolve sizer plain) + #:property + prop:serializable + (make-serialize-info + (lambda (d) + (let ([ri (current-serialize-resolve-info)]) + (unless ri + (error 'serialize-delayed-element + "current-serialize-resolve-info not set")) + (with-handlers ([exn:fail:contract? + (lambda (exn) + (error 'serialize-delayed-element + "serialization failed (wrong resolve info? delayed element never rendered?); ~a" + (exn-message exn)))]) + (vector + (let ([l (delayed-element-content d ri)]) + l))))) + #'deserialize-delayed-element + #f + (or (current-load-relative-directory) (current-directory)))) + +(provide/contract + (struct delayed-element ([resolve (any/c part? resolve-info? . -> . list?)] + [sizer (-> any)] + [plain (-> any)]))) + +(provide deserialize-delayed-element) +(define deserialize-delayed-element + (make-deserialize-info values values)) + +(provide delayed-element-content) +(define (delayed-element-content e ri) + (hash-ref (resolve-info-delays ri) e)) + +(provide delayed-block-blocks) +(define (delayed-block-blocks p ri) + (hash-ref (resolve-info-delays ri) p)) + +(provide current-serialize-resolve-info) +(define current-serialize-resolve-info (make-parameter #f)) + +;; ---------------------------------------- + +;; part-relative element has special serialization support: +(define-struct part-relative-element (collect sizer plain) + #:property + prop:serializable + (make-serialize-info + (lambda (d) + (let ([ri (current-serialize-resolve-info)]) + (unless ri + (error 'serialize-part-relative-element + "current-serialize-resolve-info not set")) + (with-handlers ([exn:fail:contract? + (lambda (exn) + (error 'serialize-part-relative-element + "serialization failed (wrong resolve info? part-relative element never rendered?); ~a" + (exn-message exn)))]) + (vector + (part-relative-element-content d ri))))) + #'deserialize-part-relative-element + #f + (or (current-load-relative-directory) (current-directory)))) + +(provide/contract + (struct part-relative-element ([collect (collect-info? . -> . list?)] + [sizer (-> any)] + [plain (-> any)]))) + +(provide deserialize-part-relative-element) +(define deserialize-part-relative-element + (make-deserialize-info values values)) + +(provide part-relative-element-content) +(define (part-relative-element-content e ci/ri) + (hash-ref (collect-info-relatives + (if (resolve-info? ci/ri) (resolve-info-ci ci/ri) ci/ri)) + e)) + +(provide collect-info-parents) + +;; ---------------------------------------- + +;; Delayed index entry also has special serialization support. +;; It uses the same delay -> value table as delayed-element +(define-struct delayed-index-desc (resolve) + #:mutable + #:property + prop:serializable + (make-serialize-info + (lambda (d) + (let ([ri (current-serialize-resolve-info)]) + (unless ri + (error 'serialize-delayed-index-desc + "current-serialize-resolve-info not set")) + (with-handlers ([exn:fail:contract? + (lambda (exn) + (error 'serialize-index-desc + "serialization failed (wrong resolve info?); ~a" + (exn-message exn)))]) + (vector + (delayed-element-content d ri))))) + #'deserialize-delayed-index-desc + #f + (or (current-load-relative-directory) (current-directory)))) + +(provide/contract + (struct delayed-index-desc ([resolve (any/c part? resolve-info? . -> . any)]))) + +(provide deserialize-delayed-index-desc) +(define deserialize-delayed-index-desc + (make-deserialize-info values values)) + +;; ---------------------------------------- + +(define-struct (collect-element element) (collect) + #:mutable + #:property + prop:serializable + (make-serialize-info + (lambda (d) + (vector (make-element + (element-style d) + (element-content d)))) + #'deserialize-collect-element + #f + (or (current-load-relative-directory) (current-directory)))) + +(provide deserialize-collect-element) +(define deserialize-collect-element + (make-deserialize-info values values)) + +(provide/contract + [struct collect-element ([style element-style?] + [content content?] + [collect (collect-info? . -> . any)])]) + +;; ---------------------------------------- + +(define-struct (render-element element) (render) + #:property + prop:serializable + (make-serialize-info + (lambda (d) + (vector (make-element + (element-style d) + (element-content d)))) + #'deserialize-render-element + #f + (or (current-load-relative-directory) (current-directory)))) + +(provide deserialize-render-element) +(define deserialize-render-element + (make-deserialize-info values values)) + +(provide/contract + [struct render-element ([style element-style?] + [content content?] + [render (any/c part? resolve-info? . -> . any)])]) + +;; ---------------------------------------- + +(define-struct generated-tag () + #:property + prop:serializable + (make-serialize-info + (lambda (g) + (let ([ri (current-serialize-resolve-info)]) + (unless ri + (error 'serialize-generated-tag + "current-serialize-resolve-info not set")) + (let ([t (hash-ref (collect-info-tags (resolve-info-ci ri)) g #f)]) + (if t + (vector t) + (error 'serialize-generated-tag + "serialization failed (wrong resolve info?)"))))) + #'deserialize-generated-tag + #f + (or (current-load-relative-directory) (current-directory)))) + +(provide (struct-out generated-tag)) + +(provide deserialize-generated-tag) +(define deserialize-generated-tag + (make-deserialize-info values values)) + +(provide generate-tag tag-key + current-tag-prefixes + add-current-tag-prefix) + +(define (generate-tag tg ci) + (if (generated-tag? (cadr tg)) + (let ([t (cadr tg)]) + (list (car tg) + (let ([tags (collect-info-tags ci)]) + (or (hash-ref tags t #f) + (let ([key (list* 'gentag + (hash-count tags) + (collect-info-gen-prefix ci))]) + (hash-set! tags t key) + key))))) + tg)) + +(define (tag-key tg ri) + (if (generated-tag? (cadr tg)) + (list (car tg) + (hash-ref (collect-info-tags (resolve-info-ci ri)) (cadr tg))) + tg)) + +(define current-tag-prefixes (make-parameter null)) +(define (add-current-tag-prefix t) + (let ([l (current-tag-prefixes)]) + (if (null? l) + t + (cons (car t) (append l (cdr t)))))) + +;; ---------------------------------------- + +(provide content->string + strip-aux) + +(define content->string + (case-lambda + [(c) + (cond + [(element? c) (content->string (element-content c))] + [(multiarg-element? c) (content->string (multiarg-element-contents c))] + [(list? c) (apply string-append (map content->string c))] + [(part-relative-element? c) (content->string ((part-relative-element-plain c)))] + [(delayed-element? c) (content->string ((delayed-element-plain c)))] + [(string? c) c] + [else (case c + [(mdash) "---"] + [(ndash) "--"] + [(ldquo rdquo) "\""] + [(rsquo) "'"] + [(rarr) "->"] + [(lang) "<"] + [(rang) ">"] + [else (format "~s" c)])])] + [(c renderer sec ri) + (cond + [(and (link-element? c) + (null? (element-content c))) + (let ([dest (resolve-get sec ri (link-element-tag c))]) + ;; FIXME: this is specific to renderer + (if dest + (content->string (strip-aux + (if (pair? dest) (cadr dest) (vector-ref dest 1))) + renderer sec ri) + "???"))] + [(element? c) (content->string (element-content c) renderer sec ri)] + [(multiarg-element? c) (content->string (multiarg-element-contents c) renderer sec ri)] + [(list? c) (apply string-append + (map(lambda (e) (content->string e renderer sec ri)) + c))] + [(delayed-element? c) + (content->string (delayed-element-content c ri) renderer sec ri)] + [(part-relative-element? c) + (content->string (part-relative-element-content c ri) renderer sec ri)] + [else (content->string c)])])) + +(define (aux-element? e) + (and (element? e) + (let ([s (element-style e)]) + (and (style? e) + (memq 'aux (style-variants s)))))) + +(define (strip-aux content) + (cond + [(null? content) null] + [(aux-element? content) null] + [(list? content) (map strip-aux content)] + [else content])) + +;; ---------------------------------------- + +(provide block-width + content-width) + +(define (content-width s) + (cond + [(string? s) (string-length s)] + [(list? s) (for/fold ([v 0]) ([s (in-list s)]) (+ v (content-width s)))] + [(element? s) (content-width (element-content s))] + [(multiarg-element? s) (content-width (multiarg-element-contents s))] + [(delayed-element? s) (content-width ((delayed-element-sizer s)))] + [(part-relative-element? s) (content-width ((part-relative-element-sizer s)))] + [else 1])) + +(define (paragraph-width s) + (content-width (paragraph-content s))) + +(define (flow-width f) + (apply max 0 (map block-width f))) + +(define (block-width p) + (cond + [(paragraph? p) (paragraph-width p)] + [(table? p) (table-width p)] + [(itemization? p) (itemization-width p)] + [(nested-flow? p) (nested-flow-width p)] + [(compound-paragraph? p) (compound-paragraph-width p)] + [(delayed-block? p) 1] + [(eq? p 'cont) 0])) + +(define (table-width p) + (let ([blocks (table-blockss p)]) + (if (null? blocks) + 0 + (let loop ([blocks blocks]) + (if (null? (car blocks)) + 0 + (+ (apply max 0 (map block-width (map car blocks))) + (loop (map cdr blocks)))))))) + +(define (itemization-width p) + (apply max 0 (map flow-width (itemization-blockss p)))) + +(define (nested-flow-width p) + (+ 4 (apply max 0 (map block-width (nested-flow-blocks p))))) + +(define (compound-paragraph-width p) + (apply max 0 (map block-width (compound-paragraph-blocks p)))) + +;; ---------------------------------------- + +(define (info-key? l) + (and (pair? l) + (symbol? (car l)) + (pair? (cdr l)))) + +(provide info-key?) +(provide/contract + [part-collected-info (part? resolve-info? . -> . collected-info?)] + [collect-put! (collect-info? info-key? any/c . -> . 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/ext? ((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/collects/scribble/decode-struct.ss b/collects/scribble/decode-struct.ss index 48ef06f38f..a9335e8c29 100644 --- a/collects/scribble/decode-struct.ss +++ b/collects/scribble/decode-struct.ss @@ -1,6 +1,7 @@ #lang scheme/base -(require "struct.ss") +(require "core.ss" + "private/provide-structs.ss") (provide-structs [part-index-desc ()]) diff --git a/collects/scribble/decode.ss b/collects/scribble/decode.ss index 50c9810471..567abd3177 100644 --- a/collects/scribble/decode.ss +++ b/collects/scribble/decode.ss @@ -1,5 +1,6 @@ #lang scheme/base -(require "struct.ss" +(require "core.ss" + "private/provide-structs.ss" "decode-struct.ss" scheme/contract scheme/class @@ -14,19 +15,36 @@ (rename-out [decode-content decode-elements]) decode-string whitespace? - clean-up-index-string) + clean-up-index-string + pre-content? + pre-flow?) + +(define (pre-content? i) + (or (string? i) + (and (content? i) + (not (list? i))) + (and (splice? i) + (andmap pre-content? (splice-run i))))) + +(define (pre-flow? i) + (or (string? i) + (and (content? i) + (not (list? i))) + (block? i) + (and (splice? i) + (andmap pre-flow? (splice-run i))))) (provide-structs [title-decl ([tag-prefix (or/c false/c string?)] [tags (listof tag?)] [version (or/c string? false/c)] - [style any/c] - [content list?])] + [style style?] + [content content?])] [part-start ([depth integer?] [tag-prefix (or/c false/c string?)] [tags (listof tag?)] - [style any/c] - [title list?])] + [style style?] + [title content?])] [splice ([run list?])] [part-index-decl ([plain-seq (listof string?)] [entry-seq list?])] @@ -67,11 +85,6 @@ null (list (decode-compound-paragraph (reverse (skip-whitespace accum)))))) -(define (part-version p) - (if (versioned-part? p) - (versioned-part-version p) - #f)) - (define (decode-flow* l keys colls tag-prefix tags vers style title part-depth) (let loop ([l l] [next? #f] [keys keys] [colls colls] [accum null] [title title] [tag-prefix tag-prefix] [tags tags] [vers vers] @@ -82,11 +95,15 @@ [tags (if (null? tags) (list `(part ,(make-generated-tag))) tags)]) - (make-versioned-part + (make-part tag-prefix (append tags k-tags) title - style + (if vers + (make-style (style-name style) + (cons (make-document-version vers) + (style-variants style))) + style) (let ([l (append (map (lambda (k tag) (make-index-element #f null tag @@ -95,8 +112,8 @@ #f)) keys k-tags) colls)]) - (if (and title (not (or (eq? 'hidden style) - (and (list? style) (memq 'hidden style))))) + (if (and title + (not (memq 'hidden (style-variants style)))) (cons (make-index-element #f null (car tags) (list (clean-up-index-string @@ -106,9 +123,8 @@ (make-part-index-desc)) l) l)) - (make-flow (decode-accum-para accum)) - null - vers))] + (decode-accum-para accum) + null))] [(title-decl? (car l)) (cond [(not part-depth) (error 'decode "misplaced title: ~e" (car l))] [title (error 'decode "found extra title: ~v" (car l))] @@ -124,29 +140,26 @@ (let ([para (decode-accum-para accum)] [part (decode-flow* (cdr l) keys colls tag-prefix tags vers style title part-depth)]) - (make-versioned-part + (make-part (part-tag-prefix part) (part-tags part) (part-title-content part) (part-style part) (part-to-collect part) - (make-flow (append para (list (car l)) - (flow-paragraphs (part-flow part)))) - (part-parts part) - (part-version part)))] + (append para (list (car l)) (part-flow part)) + (part-parts part)))] [(part? (car l)) (let ([para (decode-accum-para accum)] [part (decode-flow* (cdr l) keys colls tag-prefix tags vers style title part-depth)]) - (make-versioned-part + (make-part (part-tag-prefix part) (part-tags part) (part-title-content part) (part-style part) (part-to-collect part) - (make-flow (append para (flow-paragraphs (part-flow part)))) - (cons (car l) (part-parts part)) - (part-version part)))] + (append para (part-blocks part)) + (cons (car l) (part-parts part))))] [(and (part-start? (car l)) (or (not part-depth) ((part-start-depth (car l)) . <= . part-depth))) @@ -166,14 +179,13 @@ (add1 part-depth))] [part (decode-flow* l keys colls tag-prefix tags vers style title part-depth)]) - (make-versioned-part (part-tag-prefix part) - (part-tags part) - (part-title-content part) - (part-style part) - (part-to-collect part) - (make-flow para) - (cons s (part-parts part)) - (part-version part))) + (make-part (part-tag-prefix part) + (part-tags part) + (part-title-content part) + (part-style part) + (part-to-collect part) + para + (cons s (part-parts part)))) (if (splice? (car l)) (loop (append (splice-run (car l)) (cdr l)) s-accum) (loop (cdr l) (cons (car l) s-accum))))))] @@ -205,29 +217,28 @@ (if m (let ([part (loop m #t keys colls null title tag-prefix tags vers style)]) - (make-versioned-part + (make-part (part-tag-prefix part) (part-tags part) (part-title-content part) (part-style part) (part-to-collect part) - (make-flow (append (decode-accum-para accum) - (flow-paragraphs (part-flow part)))) - (part-parts part) - (part-version part))) + (append (decode-accum-para accum) + (part-blocks part)) + (part-parts part))) (loop (cdr l) #f keys colls (cons (car l) accum) title tag-prefix tags vers style))))] [else (loop (cdr l) #f keys colls (cons (car l) accum) title tag-prefix tags vers style)]))) (define (decode-part l tags title depth) - (decode-flow* l null null #f tags #f #f title depth)) + (decode-flow* l null null #f tags #f plain title depth)) (define (decode-styled-part l tag-prefix tags style title depth) (decode-flow* l null null tag-prefix tags #f style title depth)) (define (decode-flow l) - (part-flow (decode-flow* l null null #f null #f #f #f #f))) + (part-blocks (decode-flow* l null null #f null #f plain #f #f))) (define (match-newline-whitespace l) (cond [(null? l) #f] @@ -246,7 +257,7 @@ (decode-part l null #f 0)) (define (decode-paragraph l) - (make-paragraph (decode-content l))) + (make-paragraph plain (decode-content l))) (define (decode-content l) (append-map (lambda (s) (if (string? s) (decode-string s) (list s))) @@ -256,7 +267,7 @@ (define (finish-accum para-accum) (if (null? para-accum) null - (list (make-paragraph (skip-whitespace (apply append (reverse para-accum))))))) + (list (make-paragraph plain (skip-whitespace (apply append (reverse para-accum))))))) (let ([r (let loop ([l (skip-whitespace l)] [para-accum null]) (cond @@ -274,7 +285,7 @@ (cons (list (car l)) para-accum))]))]))]) (cond [(null? r) - (make-paragraph null)] + (make-paragraph plain null)] [(null? (cdr r)) (car r)] - [(make-compound-paragraph #f r)]))) + [(make-compound-paragraph plain r)]))) diff --git a/collects/scribble/doc/reader.ss b/collects/scribble/doc/reader.ss index ddc616132e..81513e36c8 100644 --- a/collects/scribble/doc/reader.ss +++ b/collects/scribble/doc/reader.ss @@ -5,6 +5,6 @@ scribble/doclang #:read scribble:read-inside #:read-syntax scribble:read-syntax-inside #:whole-body-readers? #t -#:wrapper1 (lambda (t) (list* 'doc '() (t))) +#:wrapper1 (lambda (t) (list* 'doc 'values '() (t))) (require (prefix-in scribble: "../reader.ss")) diff --git a/collects/scribble/doclang.ss b/collects/scribble/doclang.ss index f84c1b4cfe..b42e95e738 100644 --- a/collects/scribble/doclang.ss +++ b/collects/scribble/doclang.ss @@ -12,17 +12,17 @@ (define-syntax (*module-begin stx) (syntax-case stx () - [(_ id exprs . body) + [(_ id post-process exprs . body) #'(#%module-begin - (doc-begin id exprs . body))])) + (doc-begin id post-process exprs . body))])) (define-syntax (doc-begin stx) (syntax-case stx () - [(_ m-id (expr ...)) + [(_ m-id post-process (expr ...)) #`(begin - (define m-id (decode (list . #,(reverse (syntax->list #'(expr ...)))))) + (define m-id (post-process (decode (list . #,(reverse (syntax->list #'(expr ...))))))) (provide m-id))] - [(_ m-id exprs . body) + [(_ m-id post-process exprs . body) ;; `body' probably starts with lots of string constants; it's ;; slow to trampoline on every string, so do them in a batch ;; here: @@ -34,7 +34,7 @@ (loop #'rest (cons #'s accum))] [() (with-syntax ([(accum ...) accum]) - #`(doc-begin m-id (accum ... . exprs)))] + #`(doc-begin m-id post-process (accum ... . exprs)))] [(body1 . body) (with-syntax ([exprs (append accum #'exprs)]) (let ([expanded (local-expand @@ -46,7 +46,7 @@ #%require))))]) (syntax-case expanded (begin) [(begin body1 ...) - #`(doc-begin m-id exprs body1 ... . body)] + #`(doc-begin m-id post-process exprs body1 ... . body)] [(id . rest) (and (identifier? #'id) (ormap (lambda (kw) (free-identifier=? #'id kw)) @@ -57,6 +57,6 @@ define-values-for-syntax #%require #%provide)))) - #`(begin #,expanded (doc-begin m-id exprs . body))] + #`(begin #,expanded (doc-begin m-id post-process exprs . body))] [_else - #`(doc-begin m-id (#,expanded . exprs) . body)])))]))])) + #`(doc-begin m-id post-process (#,expanded . exprs) . body)])))]))])) diff --git a/collects/scribble/eval.ss b/collects/scribble/eval.ss index dccb93217b..945de315c3 100644 --- a/collects/scribble/eval.ss +++ b/collects/scribble/eval.ss @@ -90,13 +90,13 @@ (if (flow? p) p (make-flow (list p)))))) - (format-output (cadar val-list+outputs) "schemestdout") - (format-output (caddar val-list+outputs) "schemeerror") + (format-output (cadar val-list+outputs) output-color) + (format-output (caddar val-list+outputs) error-color) (if (string? (caar val-list+outputs)) ;; Error result case: (map (lambda (s) - (car (format-output s "schemeerror"))) + (car (format-output s error-color))) (let sloop ([s (caar val-list+outputs)]) (if ((string-length s) . > . maxlen) ;; break the error message into multiple lines: @@ -117,8 +117,8 @@ (list (make-flow (list (make-paragraph (list (hspace 2) - (span-class "schemeresult" - (to-element/no-color v)))))))) + (elem #:style result-color + (to-element/no-color v)))))))) val-list)))) (loop (cdr expr-paras) (cdr val-list+outputs) @@ -313,8 +313,8 @@ (define (show-val v) - (span-class "schemeresult" - (to-element/no-color v))) + (elem #:style result-color + (to-element/no-color v))) (define (do-interaction-eval-show ev e) (parameterize ([current-command-line-arguments #()]) diff --git a/collects/scribble/html-render.ss b/collects/scribble/html-render.ss index 905af622d8..a6a7beb9ed 100644 --- a/collects/scribble/html-render.ss +++ b/collects/scribble/html-render.ss @@ -1,6 +1,8 @@ #lang scheme/base -(require "struct.ss" +(require "core.ss" + "private/render-utils.ss" + "html-variants.ss" scheme/class scheme/path scheme/file @@ -17,18 +19,18 @@ (prefix-in xml: xml/xml) (for-syntax scheme/base) "search.ss" - "basic.ss") + (except-in "base.ss" url)) (provide render-mixin render-multi-mixin) -(define literal +(define as-literal (let ([loc (xml:make-location 0 0 0)]) (lambda strings (xml:make-cdata loc loc (string-append* strings))))) (define (ref-style path) `(link ([rel "stylesheet"] [type "text/css"] [href ,path] [title "default"]))) (define (inlined-style . body) `(style ([type "text/css"]) - ,(apply literal + ,(apply as-literal `("\n" ,@(map (lambda (x) (if (string? x) x (format "~a" x))) body) "\n")))) @@ -36,12 +38,13 @@ `(script ([type "text/javascript"] [src ,path]))) (define (inlined-script . body) `(script ([type "text/javascript"]) - ,(apply literal + ,(apply as-literal `("\n" ,@(map (lambda (x) (if (string? x) x (format "~a" x))) body) "\n")))) (define-runtime-path scribble-css "scribble.css") +(define-runtime-path scribble-style-css "scribble-style.css") (define-runtime-path scribble-prefix-html "scribble-prefix.html") (define-runtime-path scribble-js "scribble-common.js") ;; utilities for render-one-part @@ -57,7 +60,9 @@ (lambda (default-file make-inline make-ref) (let ([c #f]) (lambda (file path) - (cond [(not (eq? 'inline path)) + (cond [(bytes? file) + (make-inline (bytes->string/utf-8 file))] + [(not (eq? 'inline path)) (make-ref (or path (let-values ([(base name dir?) (split-path file)]) (path->string name))))] @@ -69,6 +74,12 @@ (values (file-getter scribble-css inlined-style ref-style) (file-getter scribble-js inlined-script ref-script)))) +(define (lookup-path path mapping) + (ormap (lambda (p) + (and (equal? (car p) path) + (cdr p))) + mapping)) + (define current-subdirectory (make-parameter #f)) (define current-output-file (make-parameter #f)) (define current-top-part (make-parameter #f)) @@ -104,99 +115,36 @@ (define-serializable-struct literal-anchor (string)) -(define (style->attribs raw-style) - (if (with-attributes? raw-style) - (map (lambda (p) (list (car p) (cdr p))) - (with-attributes-assoc raw-style)) - null)) +(define (color->string c) + (if (string? c) + c + (string-append* + "#" + (map (lambda (v) + (let ([s (number->string v 16)]) + (if (< v 16) (string-append "0" s) s))) + c)))) -(define (pdf-to-png p) - (if (equal? (filename-extension p) #"pdf") - (path-replace-suffix p #".png") - p)) - -#; ; no need for these index-local searches -#reader scribble/reader (begin ; easier to format - -(define search-script - @inlined-script{ - var search_nodes = null; - var last_search_terms = null; - function node_to_text(node) { - if (node.nodeType == 3) return node.nodeValue; - var r = ""; - var children = node.childNodes; - for (var i=0@";" i 0) { - var paramstrs = location.search.substring(1).split(/[@";"&]/); - for (var i in paramstrs) { - var param = paramstrs[i].split(/=/); - if (param.length == 2 && param[0] == "q") { - search_box.value = unescape(param[1]).replace(/\+/g," "); - break; - } - } - } - if (search_box.value != "") do_search(search_box.value); - search_box.focus(); - search_box.select(); - } - window.onload = initialize_search; - function do_search(terms) { - terms = terms.toLowerCase(); - if (terms == last_search_terms) return; - last_search_terms = terms; - terms = terms.split(/ +/); - var none = true; - for (var i=0@";" iattribs style) + (let ([a (apply + append + (map (lambda (v) + (cond + [(attributes? v) + (map (lambda (v) (list (car v) (cdr v))) (attributes-assoc v))] + [(color-variant? v) + `((style ,(format "color: ~a" (color->string (color-variant-color v)))))] + [(background-color-variant? v) + `((style ,(format "background-color: ~a" (color->string (background-color-variant-color v)))))] + [(hover-variant? v) + `((title ,(hover-variant-text v)))] + [else null])) + (style-variants style)))]) + (let ([name (style-name style)]) + (if (string? name) + (cons `[class ,name] + a) + a)))) (define (make-search-box top-path) ; appears on every page (let ([sa string-append] @@ -226,18 +174,20 @@ (define (render-mixin %) (class % - (inherit render-content - render-block + (inherit render-block render-part collect-part install-file get-dest-directory format-number quiet-table-of-contents - extract-part-style-files) + extract-part-style-files + extract-version + extract-authors + extract-pretitle) (inherit-field prefix-file style-file style-extra-files) - (init-field [css-path #f] + (init-field [alt-paths null] ;; up-path is either a link "up", or #t which uses ;; goes to start page (using cookies to get to the ;; user start page) @@ -251,6 +201,9 @@ (define/override (index-manual-newlines?) #t) + (define/override (auto-extra-files? v) (html-defaults? v)) + (define/override (auto-extra-files-paths v) (html-defaults-extra-files v)) + ;; ---------------------------------------- (inherit path->root-relative @@ -321,7 +274,10 @@ (build-path base (redirect-target-element-alt-path i))) p))) - #f + (let ([tag (target-element-tag i)]) + (if (and (pair? tag) (eq? 'part (car tag))) + (element-content i) + #f)) (page-target-element? i) (if (redirect-target-element? i) (make-literal-anchor @@ -475,11 +431,12 @@ (loop (delayed-block-blocks t ri))))) (filter (lambda (e) (let loop ([e e]) - (or (and (auxiliary-table? e) - (pair? (table-flowss e))) + (or (and (table? e) + (memq 'aux (style-variants (table-style e))) + (pair? (table-blockss e))) (and (delayed-block? e) (loop (delayed-block-blocks e ri)))))) - (flow-paragraphs (part-flow d)))))))) + (part-blocks d))))))) (define/public (get-onthispage-label) null) @@ -498,37 +455,33 @@ #f (nearly-top? d ri top)))]) (define (flow-targets flow) - (append-map block-targets (flow-paragraphs flow))) + (append-map block-targets flow)) (define (block-targets e) (cond [(table? e) (table-targets e)] [(paragraph? e) (para-targets e)] [(itemization? e) - (append-map flow-targets (itemization-flows e))] - [(blockquote? e) - (append-map block-targets (blockquote-paragraphs e))] + (append-map flow-targets (itemization-blockss e))] + [(nested-flow? e) + (append-map block-targets (nested-flow-blocks e))] [(compound-paragraph? e) (append-map block-targets (compound-paragraph-blocks e))] [(delayed-block? e) null])) (define (para-targets para) - (let loop ([c (paragraph-content para)]) - (define a (and (pair? c) (car c))) + (let loop ([a (paragraph-content para)]) (cond - [(null? c) null] - [(toc-target-element? a) (cons a (loop (cdr c)))] - [(toc-element? a) (cons a (loop (cdr c)))] - [(element? a) - (append (loop (element-content a)) (loop (cdr c)))] - [(delayed-element? a) - (loop (append (delayed-element-content a ri) (cdr c)))] - [(part-relative-element? a) - (loop (append (part-relative-element-content a ri) (cdr c)))] - [else (loop (cdr c))]))) + [(list? a) (append-map loop a)] + [(toc-target-element? a) (list a)] + [(toc-element? a) (list a)] + [(element? a) (loop (element-content a))] + [(delayed-element? a) (loop (delayed-element-content a ri))] + [(part-relative-element? a) (loop (part-relative-element-content a ri))] + [else null]))) (define (table-targets table) (append-map - (lambda (flows) - (append-map (lambda (f) (if (eq? f 'cont) null (flow-targets f))) - flows)) - (table-flowss table))) + (lambda (blocks) + (append-map (lambda (f) (if (eq? f 'cont) null (block-targets f))) + blocks)) + (table-blockss table))) (define ps ((if (nearly-top? d) values cdr) (let flatten ([d d]) @@ -536,7 +489,7 @@ ;; don't include the section if it's in the TOC (if (nearly-top? d) null (list d)) ;; get internal targets: - (append-map block-targets (flow-paragraphs (part-flow d))) + (append-map block-targets (part-blocks d)) (map (lambda (p) (if (part-whole-page? p ri) null (flatten p))) (part-parts d)))))) (define any-parts? (ormap part? ps)) @@ -577,45 +530,56 @@ ,@(render-content (if (part? p) (or (part-title-content p) - '("???")) + "???") (element-content p)) d ri)))))))) ps)))))))) - (define/public (extract-version d) - (if (and (versioned-part? d) - (versioned-part-version d)) - (versioned-part-version d) - (current-version))) - (define/public (extract-part-body-id d ri) - (or - (and (list? (part-style d)) - (ormap (lambda (s) - (and (list? s) - (= 2 (length s)) - (eq? (car s) 'body-id) - (string? (cadr s)) - (cadr s))) - (part-style d))) - (let ([p (part-parent d ri)]) - (and p (extract-part-body-id p ri))))) - + (or (ormap (lambda (v) + (and (body-id? v) + (body-id-value v))) + (style-variants (part-style d))) + (let ([p (part-parent d ri)]) + (and p (extract-part-body-id p ri))))) + (define/public (render-one-part d ri fn number) (parameterize ([current-output-file fn]) - (let* ([prefix-file (or prefix-file scribble-prefix-html)] - [style-file (or style-file scribble-css)] + (let* ([defaults (ormap (lambda (v) (and (html-defaults? v) v)) + (style-variants (part-style d)))] + [prefix-file (or prefix-file + (and defaults + (let ([v (html-defaults-prefix-path defaults)]) + (if (bytes? v) + v + (main-collects-relative->path v)))) + scribble-prefix-html)] + [style-file (or style-file + (and defaults + (let ([v (html-defaults-style-path defaults)]) + (if (bytes? v) + v + (main-collects-relative->path v)))) + scribble-style-css)] [script-file (or script-file scribble-js)] [title (cond [(part-title-content d) => (lambda (c) `(title ,@(format-number number '(nbsp)) ,(content->string c this d ri)))] [else `(title)])]) - (unless css-path (install-file style-file)) - (unless script-path (install-file script-file)) - (call-with-input-file* prefix-file - (lambda (in) - (copy-port in (current-output-port)))) + (unless (bytes? style-file) + (unless (lookup-path style-file alt-paths) + (install-file style-file))) + (unless (lookup-path scribble-css alt-paths) + (install-file scribble-css)) + (unless (lookup-path script-file alt-paths) + (install-file script-file)) + (if (bytes? prefix-file) + (display prefix-file) + (call-with-input-file* + prefix-file + (lambda (in) + (copy-port in (current-output-port))))) (parameterize ([xml:empty-tag-shorthand xml:html-empty-tags]) (xml:write-xml/content (xml:xexpr->xml @@ -624,17 +588,23 @@ (meta ([http-equiv "content-type"] [content "text-html; charset=utf-8"])) ,title - ,(scribble-css-contents style-file css-path) + ,(scribble-css-contents scribble-css (lookup-path scribble-css alt-paths)) ,@(map (lambda (style-file) - (install-file style-file) - (scribble-css-contents style-file #f)) - (append style-extra-files - (extract-part-style-files + (if (bytes? style-file) + (scribble-css-contents style-file #f) + (let ([p (lookup-path style-file alt-paths)]) + (unless p (install-file style-file)) + (scribble-css-contents style-file p)))) + (append (extract-part-style-files d ri 'css - (lambda (p) (part-whole-page? p ri))))) - ,(scribble-js-contents script-file script-path)) + (lambda (p) (part-whole-page? p ri)) + css-addition? + css-addition-path) + (list style-file) + style-extra-files)) + ,(scribble-js-contents script-file (lookup-path script-file alt-paths))) (body ((id ,(or (extract-part-body-id d ri) "scribble-plt-scheme-org"))) ,@(render-toc-view d ri) @@ -662,13 +632,13 @@ (values prev (and (pair? (cdr l)) (cadr l))) (loop (cdr l) (car l)))))) - (define top-content '("top")) - (define contents-content '("contents")) - (define index-content '("index")) + (define top-content "top") + (define contents-content "contents") + (define index-content "index") (define prev-content '(larr " prev")) - (define up-content '("up")) + (define up-content "up") (define next-content '("next " rarr)) - (define sep-element (make-element #f '(nbsp nbsp))) + (define sep-element '(nbsp nbsp)) (define/public (derive-filename d) "bad.html") @@ -700,7 +670,7 @@ (let ([subs (part-parts d)]) (and (pair? subs) (let ([d (last subs)]) - (and (part-style? d 'index) + (and (eq? (style-name (part-style d)) 'index) d)))))))) (define (render . content) (render-content (filter values content) d ri)) @@ -726,10 +696,13 @@ (string-append "\"" (content->string (part-title-content tfrom)) "\"") title)) - (make-target-url url - (make-with-attributes #f - `([title . ,(if title* (string-append label " to " title*) label)] - ,@more)))) + (make-style + #f + (list + (make-target-url url) + (make-attributes + `([title . ,(if title* (string-append label " to " title*) label)] + ,@more))))) (define top-link (titled-url "up" "../index.html" @@ -800,14 +773,20 @@ ;; show version: `((div ([class "versionbox"]) ,@(render-content - (list (make-element "version" + (list (make-element (if (include-navigation?) + "version" + "versionNoNav") (list "Version: " v))) d ri)))))) (define/override (render-part-content d ri) (let ([number (collected-info-number (part-collected-info d ri))]) - `(,@(cond + `(,@(let ([pres (extract-pretitle d)]) + (append-map (lambda (pre) + (do-render-paragraph pre d ri #f #t)) + pres)) + ,@(cond [(and (not (part-title-content d)) (null? number)) null] [(part-style? d 'hidden) (map (lambda (t) @@ -829,7 +808,20 @@ ,@(if (part-title-content d) (render-content (part-title-content d) d ri) null)))]) - ,@(render-flow* (part-flow d) d ri #f #f) + ,@(let ([auths (extract-authors d)]) + (if (null? auths) + null + `((div ([class "SAuthorListBox"]) + (span ([class "SAuthorList"]) + ,@(apply + append + (for/list ([auth (in-list auths)] + [pos (in-naturals)]) + (let ([v (do-render-paragraph auth d ri #f #t)]) + (if (zero? pos) + v + (cons '(span ([class "SAuthorSep"]) (br)) v)))))))))) + ,@(render-flow* (part-blocks d) d ri #f #f) ,@(let loop ([pos 1] [secs (part-parts d)]) (if (null? secs) @@ -840,7 +832,7 @@ (define/private (render-flow* p part ri starting-item? special-last?) ;; Wrap each table with

, except for a trailing table ;; when `special-last?' is #t - (let loop ([f (flow-paragraphs p)] [starting-item? starting-item?]) + (let loop ([f p] [starting-item? starting-item?]) (cond [(null? f) null] [(and (table? (car f)) @@ -853,57 +845,100 @@ (define/override (render-flow p part ri starting-item?) (render-flow* p part ri starting-item? #t)) - (define/private (do-render-paragraph p part ri flatten-unstyled?) - ;; HACK: for the search, we need to be able to render a `div' - ;; with an `id' attribute, `p' will probably work fine instead - ;; of `div' since it's a block element. Do this for now. + (define/private (do-render-paragraph p part ri flatten-unstyled? show-pre?) (let* ([contents (super render-paragraph p part ri)] - [raw-style (and (styled-paragraph? p) - (flatten-style (styled-paragraph-style p)))] - [style (if (with-attributes? raw-style) - (with-attributes-style raw-style) - raw-style)]) - (if (and flatten-unstyled? - (not style)) - contents - `((,(if (eq? style 'div) 'div 'p) - ,(append - (if (string? style) - `([class ,style]) - `()) - (style->attribs raw-style)) - ,@contents))))) + [style (paragraph-style p)] + [attrs (style->attribs style)]) + (if (and (not show-pre?) + (or (eq? (style-name style) 'author) + (eq? (style-name style) 'pretitle))) + null + (if (and flatten-unstyled? + (not (style-name style)) + (null? attrs)) + contents + `((,(if (memq 'div (style-variants style)) 'div 'p) + [,@attrs + ,@(case (style-name style) + [(author) '([class "author"])] + [(pretitle) '([class "SPretitle"])] + [else null])] + ,@contents)))))) (define/override (render-paragraph p part ri) - (do-render-paragraph p part ri #f)) + (do-render-paragraph p part ri #f #f)) (define/override (render-intrapara-block p part ri first? last? starting-item?) `((div ([class "SIntrapara"]) ,@(cond - [(paragraph? p) (do-render-paragraph p part ri #t)] + [(paragraph? p) (do-render-paragraph p part ri #t #f)] [else (render-block p part ri starting-item?)])))) - (define/override (render-element e part ri) + (define/private (content-style e) (cond - [(string? e) (super render-element e part ri)] ; short-cut for common case - [(hover-element? e) - `((span ([title ,(hover-element-text e)]) - ,@(render-plain-element e part ri)))] - [(script-element? e) - (let* ([t `[type ,(script-element-type e)]] - [s (script-element-script e)] - [s (if (list? s) - `(script (,t) ,(apply literal `("\n" ,@s "\n"))) - `(script (,t [src ,s])))]) - (list s - ;; mynoscript hack doesn't always work (see the - ;; (commented) hack in scribble-common.js) - `(noscript ,@(render-plain-element e part ri))))] + [(element? e) (element-style e)] + [(multiarg-element? e) (multiarg-element-style e)] + [else #f])) + + (define/private (content-attribs e) + (let ([s (content-style e)]) + (if (style? s) + (element-style->attribs (style-name s) s) + (element-style->attribs s #f)))) + + (define/override (render-content e part ri) + (define (attribs) (content-attribs e)) + (cond + [(string? e) (super render-content e part ri)] ; short-cut for common case + [(list? e) (super render-content e part ri)] ; also a short-cut + [(image-element? e) + (let* ([src (main-collects-relative->path (image-element-path e))] + [suffixes (image-element-suffixes e)] + [scale (image-element-scale e)] + [to-num + (lambda (s) + (number->string + (inexact->exact + (floor (* scale (integer-bytes->integer s #f #t))))))] + [src (select-suffix src suffixes '(".png" ".gif"))] + [sz (if (= 1.0 scale) + null + ;; Try to extract file size: + (call-with-input-file* + src + (lambda (in) + (if (regexp-try-match #px#"^\211PNG.{12}" in) + `([width ,(to-num (read-bytes 4 in))] + [height ,(to-num (read-bytes 4 in))]) + null))))]) + `((img ([src ,(let ([p (install-file src)]) + (if (path? p) + (url->string (path->url (path->complete-path p))) + p))] + [alt ,(content->string (element-content e))] + ,@sz + ,@(attribs)))))] + [(and (or (element? e) (multiarg-element? e)) + (ormap (lambda (v) (and (script-variant? v) v)) + (let ([s (if (element? e) + (element-style e) + (multiarg-element-style e))]) + (if (style? s) (style-variants s) null)))) + => + (lambda (v) + (let* ([t `[type ,(script-variant-type v)]] + [s (script-variant-script v)] + [s (if (list? s) + `(script (,t ,@(attribs)) ,(apply as-literal `("\n" ,@s "\n"))) + `(script (,t ,@(attribs) [src ,s])))]) + (list s + `(noscript ,@(render-plain-content e part ri)))))] [(target-element? e) `((a ([name ,(format "~a" (anchor-name (add-current-tag-prefix (tag-key (target-element-tag e) - ri))))])) - ,@(render-plain-element e part ri))] + ri))))] + ,@(attribs))) + ,@(render-content (element-content e) part ri))] [(and (link-element? e) (not (current-no-links))) (parameterize ([current-no-links #t]) (let-values ([(dest ext?) @@ -947,169 +982,139 @@ [else ;; Normal link: (dest->url dest)])) - ,@(if (string? (element-style e)) - `([class ,(element-style e)]) - null)] - ,@(if (null? (element-content e)) - (render-content (strip-aux (dest-title dest)) part ri) - (render-content (element-content e) part ri)))) + ,@(attribs)] + ,@(if (empty-content? (element-content e)) + (render-content (strip-aux (dest-title dest)) part ri) + (render-content (element-content e) part ri)))) (begin (when #f (fprintf (current-error-port) "Undefined link: ~s~n" (tag-key (link-element-tag e) ri))) `((font ([class "badlink"]) - ,@(if (null? (element-content e)) + ,@(if (empty-content? (element-content e)) `(,(format "~s" (tag-key (link-element-tag e) ri))) - (render-plain-element e part ri))))))))] + (render-plain-content e part ri))))))))] [else (when (render-element? e) ((render-element-render e) this part ri)) - (render-plain-element e part ri)])) + (render-plain-content e part ri)])) - (define/private (render-plain-element e part ri) - (let* ([raw-style (flatten-style (and (element? e) (element-style e)))] - [style (if (with-attributes? raw-style) - (with-attributes-style raw-style) - raw-style)]) - (define (attribs) (style->attribs raw-style)) - (define (render* [x 'span]) - ;; x can be a tag name, or a list of attributes, or a tag followed by - ;; a list of attributes (internal use: no error checking!) - (let-values ([(tag attribs) - (cond [(symbol? x) (values x (attribs))] - [(symbol? (car x)) - (unless (null? (cddr x)) (error "boom")) - (values (car x) (append (cadr x) (attribs)))] - [else (values 'span (append x (attribs)))])] - [(content) (super render-element e part ri)]) - (if (and (eq? 'span tag) (null? attribs)) + (define/private (render-plain-content e part ri) + (define (attribs) (content-attribs e)) + (let* ([variants (let ([s (content-style e)]) + (if (style? s) + (style-variants s) + null))] + [name (let ([s (content-style e)]) + (if (style? s) + (style-name s) + s))] + [link? (and (ormap target-url? variants) + (not (current-no-links)))] + [anchor? (ormap url-anchor? variants)] + [attribs + (append + (if (null? variants) + null + (append-map (lambda (v) + (cond + [(target-url? v) + (if (current-no-links) + null + `([href ,(let ([addr (target-url-addr v)]) + (if (path? addr) + (from-root addr (get-dest-directory)) + addr))]))] + [else null])) + variants)) + (attribs))] + [newline? (eq? name 'newline)]) + (let-values ([(content) (cond + [link? + (parameterize ([current-no-links #t]) + (super render-content e part ri))] + [newline? null] + [(eq? 'hspace name) + (let ([str (content->string e)]) + (map (lambda (c) 'nbsp) (string->list str)))] + [else + (super render-content e part ri)])]) + (if (and (null? attribs) + (not link?) + (not anchor?) + (not newline?)) content - `((,tag ,attribs ,@content))))) - (cond - [(symbol? style) - (case style - [(italic) (render* 'i)] - [(bold) (render* 'b)] - [(tt) (render* '([class "stt"]))] - [(url) (render* '([class "url"]))] - [(no-break) (render* '([class "nobreak"]))] - [(sf) `((b ,@(render* '(font ([size "-1"] [face "Helvetica"])))))] - [(subscript) (render* 'sub)] - [(superscript) (render* 'sup)] - [(hspace) - `((span ([class "hspace"] . ,(attribs)) - ,@(let ([str (content->string (element-content e))]) - (map (lambda (c) 'nbsp) (string->list str)))))] - [(newline) `((br ,(attribs)))] - [else (error 'html-render "unrecognized style symbol: ~e" style)])] - [(string? style) (render* `([class ,style]))] - [(and (pair? style) (memq (car style) '(color bg-color))) - (unless (and (list? style) - (case (length style) - [(4) (andmap byte? (cdr style))] - [(2) (member (cadr style) - '("white" "black" "red" "green" "blue" - "cyan" "magenta" "yellow"))] - [else #f])) - (error 'render-font "bad color style: ~e" style)) - (render* `(font - ([style - ,(format "~acolor: ~a" - (if (eq? (car style) 'bg-color) "background-" "") - (if (= 2 (length style)) - (cadr style) - (string-append* - "#" - (map (lambda (v) - (let ([s (number->string v 16)]) - (if (< v 16) (string-append "0" s) s))) - (cdr style)))))])))] - [(target-url? style) - (if (current-no-links) - (render*) - (parameterize ([current-no-links #t]) - (render* `(a ([href ,(let ([addr (target-url-addr style)]) - (if (path? addr) - (from-root addr (get-dest-directory)) - addr))] - ;; The target-url chains to another style, - ;; flatten-style above takes care of it though. - ,@(let ([style (target-url-style style)]) - (if (string? style) - `([class ,style]) - null)))))))] - [(url-anchor? style) - (render* `(a ([name ,(url-anchor-name style)])))] - [(image-file? style) - (let* ([src (main-collects-relative->path (image-file-path style))] - [scale (image-file-scale style)] - [to-num - (lambda (s) - (number->string - (inexact->exact - (floor (* scale (integer-bytes->integer s #f #t))))))] - [sz (if (= 1.0 scale) - null - ;; Try to extract file size: - (call-with-input-file* - src - (lambda (in) - (if (regexp-try-match #px#"^\211PNG.{12}" in) - `([width ,(to-num (read-bytes 4 in))] - [height ,(to-num (read-bytes 4 in))]) - null))))]) - `((img ([src ,(let ([p (install-file (pdf-to-png src))]) - (if (path? p) - (url->string (path->url (path->complete-path p))) - p))] - ,@(attribs) - ,@sz))))] - [else (render*)]))) + `(,@(if anchor? + (append-map (lambda (v) + (if (url-anchor? v) + `((a ([name ,(url-anchor-name v)]))) + null)) + variants) + null) + (,(cond + [link? 'a] + [newline? 'br] + [else 'span]) + ,attribs + ,@content)))))) + + (define/private (element-style->attribs name style) + (append + (cond + [(symbol? name) + (case name + [(italic) '([style "font-style: italic"])] + [(bold) '([style "font-weight: bold"])] + [(tt) '([class "stt"])] + [(url) '([class "url"])] + [(no-break) '([class "nobreak"])] + [(sf) '([style "font-family: sans-serif; font-size: 80%; font-weight: bold"])] + [(superscript) '([style "vertical-align: super; font-size: 80%"])] + [(subscript) '([style "vertical-align: sub; font-size: 80%"])] + [(smaller) '([class "Smaller"])] + [(larger) '([class "Larger"])] + [(hspace) '([class "hspace"])] + [(newline) '()] + [else (error 'html-render "unrecognized style symbol: ~e" name)])] + [(string? name) (if style null `([class ,name]))] + [else null]) + (if style + (style->attribs style) + null))) (define/override (render-table t part ri starting-item?) - (define raw-style (flatten-style (table-style t))) - (define t-style (if (with-attributes? raw-style) - (with-attributes-style raw-style) - raw-style)) - (define t-style-get (if (and (pair? t-style) (list? t-style)) - (lambda (k) (assoc k t-style)) - (lambda (k) #f))) - (define (make-row flows style) - `(tr (,@(if (string? style) `([class ,style]) null)) - ,@(let loop ([ds flows] - [as (cdr (or (and (list? style) (assq 'alignment style)) - (t-style-get 'alignment) - (cons #f (map (lambda (x) #f) flows))))] - [vas (cdr (or (and (list? style) (assq 'valignment style)) - (t-style-get 'valignment) - (cons #f (map (lambda (x) #f) flows))))] - [sts (cdr (or (and (list? style) (assq 'style style)) - (cons #f (map (lambda (x) #f) flows))))] - [first? #t]) - (cond - [(null? ds) null] - [(eq? (car ds) 'cont) - (loop (cdr ds) (cdr as) (cdr vas) (cdr sts) first?)] - [else - (let ([d (car ds)] [a (car as)] [va (car vas)] [st (car sts)]) - (cons - `(td (,@(case a - [(#f) null] - [(right) '([align "right"])] - [(center) '([align "center"])] - [(left) '([align "left"])]) - ,@(case va - [(#f) null] - [(top) '((valign "top"))] - [(baseline) '((valign "baseline"))] - [(center) '((valign "center"))] - [(bottom) '((valign "bottom"))]) - ,@(if (string? st) - `([class ,st]) - null) - ,@(if (and (pair? (cdr ds)) - (eq? 'cont (cadr ds))) + (define (make-row flows column-styles) + `(tr + ,@(let loop ([ds flows] + [column-styles column-styles] + [first? #t]) + (cond + [(null? ds) null] + [(eq? (car ds) 'cont) + (loop (cdr ds) (cdr column-styles) first?)] + [else + (let ([d (car ds)] [column-style (car column-styles)]) + (cons + `(td (,@(cond + [(not column-style) null] + [(memq 'right (style-variants column-style)) '([align "right"])] + [(memq 'left (style-variants column-style)) '([align "left"])] + [(memq 'center (style-variants column-style)) '([align "center"])] + [else null]) + ,@(cond + [(not column-style) null] + [(memq 'top (style-variants column-style)) '([valign "top"])] + [(memq 'baseline (style-variants column-style)) '([valign "baseline"])] + [(memq 'vcenter (style-variants column-style)) '([valign "center"])] + [(memq 'bottom (style-variants column-style)) '([valign "bottom"])] + [else null]) + ,@(if (and column-style + (string? (style-name column-style))) + `([class ,(style-name column-style)]) + null) + ,@(if (and (pair? (cdr ds)) + (eq? 'cont (cadr ds))) `([colspan ,(number->string (let loop ([n 2] [ds (cddr ds)]) @@ -1118,61 +1123,53 @@ (loop (+ n 1) (cdr ds))] [else n])))]) null)) - ,@(if (and (= 1 (length (flow-paragraphs d))) - (omitable-paragraph? (car (flow-paragraphs d)))) - (render-content (paragraph-content (car (flow-paragraphs d))) part ri) - (render-flow d part ri #f))) - (loop (cdr ds) (cdr as) (cdr vas) (cdr sts) #f)))])))) + ,@(if (and (paragraph? d) + (memq 'omitable (style-variants (paragraph-style d)))) + (render-content (paragraph-content d) part ri) + (render-block d part ri #f))) + (loop (cdr ds) (cdr column-styles) #f)))])))) `((table ([cellspacing "0"] ,@(if starting-item? '([style "display: inline-table; vertical-align: text-top;"]) null) - ,@(case t-style + ,@(case (style-name (table-style t)) [(boxed) '([class "boxed"])] [(centered) '([align "center"])] - [(at-right) '([align "right"])] - [(at-left) '([align "left"])] [else '()]) - ,@(let ([a (t-style-get 'style)]) - (if (and a (string? (cadr a))) `([class ,(cadr a)]) null)) - ,@(if (string? t-style) `([class ,t-style]) null) - ,@(style->attribs raw-style)) - ,@(if (null? (table-flowss t)) + ,@(style->attribs (table-style t))) + ,@(if (null? (table-blockss t)) `((tr (td))) (map make-row - (table-flowss t) - (cdr (or (t-style-get 'row-styles) - (cons #f (map (lambda (x) #f) (table-flowss t)))))))))) + (table-blockss t) + (extract-table-cell-styles t)))))) - (define/override (render-blockquote t part ri) - `((blockquote ,(if (string? (blockquote-style t)) - `([class ,(regexp-replace #rx"^[\\]" (blockquote-style t) "")]) - `()) - ,@(append-map (lambda (i) (render-block i part ri #f)) - (blockquote-paragraphs t))))) + (define/override (render-nested-flow t part ri) + `((blockquote [,@(style->attribs (nested-flow-style t)) + ,@(if (and (not (string? (style-name (nested-flow-style t)))) + (not (eq? 'inset (style-name (nested-flow-style t))))) + `([class "SubFlow"]) + null)] + ,@(append-map (lambda (i) (render-block i part ri #f)) + (nested-flow-blocks t))))) (define/override (render-compound-paragraph t part ri starting-item?) - `((p ,(if (string? (compound-paragraph-style t)) - `([class ,(regexp-replace #rx"^[\\]" (compound-paragraph-style t) "")]) - `()) + `((p ,(style->attribs (compound-paragraph-style t)) ,@(super render-compound-paragraph t part ri starting-item?)))) (define/override (render-itemization t part ri) - (let ([style-str (and (styled-itemization? t) - (string? (styled-itemization-style t)) - (styled-itemization-style t))]) - `((,(if (and (styled-itemization? t) - (eq? (styled-itemization-style t) 'ordered)) + (let ([style-str (or (and (string? (style-name (itemization-style t))) + (style-name (itemization-style t))) + (and (eq? 'compact (itemization-style t)) + "compact"))]) + `((,(if (eq? 'ordered (style-name (itemization-style t))) 'ol 'ul) - ,(if style-str - `([class ,style-str]) - `()) + ,(style->attribs (itemization-style t)) ,@(map (lambda (flow) `(li ,(if style-str `([class ,(string-append style-str "Item")]) `()) ,@(render-flow flow part ri #t))) - (itemization-flows t)))))) + (itemization-blockss t)))))) (define/override (render-other i part ri) (cond @@ -1200,8 +1197,11 @@ [(lang) '(8249)] [(rang) '(8250)] [else (list i)])] - [else (list (format "~s" i))])) - + [else + (error "bad") + (log-error (format "Unreocgnized element in content: ~e" i)) + (list (format "~s" i))])) + (define/private (ascii-ize s) (let ([m (regexp-match-positions #rx"[^\u01-\u7E]" s)]) (if m @@ -1297,7 +1297,7 @@ (parameterize ([current-subdirectory (file-name-from-path fn)] [current-top-part d]) ;; install files for each directory - (install-extra-files) + (install-extra-files ds) (let ([fn (build-path fn "index.html")]) (with-output-to-file fn #:exists 'truncate/replace (lambda () (render-one d ri fn)))))) diff --git a/collects/scribble/html-variants.ss b/collects/scribble/html-variants.ss new file mode 100644 index 0000000000..405b4fdbb3 --- /dev/null +++ b/collects/scribble/html-variants.ss @@ -0,0 +1,16 @@ +#lang scheme/base +(require "private/provide-structs.ss" + scheme/contract) + +(provide-structs + [body-id ([value string?])] + [hover-variant ([text string?])] + [script-variant ([type string?] + [script (or/c path-string? (listof string?))])] + [css-addition ([path (or/c path-string? (cons/c 'collects (listof bytes?)))])] + [html-defaults ([prefix-path (or/c bytes? path-string? (cons/c 'collects (listof bytes?)))] + [style-path (or/c bytes? path-string? (cons/c 'collects (listof bytes?)))] + [extra-files (listof (or/c path-string? (cons/c 'collects (listof bytes?))))])] + + [url-anchor ([name string?])] + [attributes ([assoc (listof (cons/c symbol? string?))])]) diff --git a/collects/scribble/latex-render.ss b/collects/scribble/latex-render.ss index 4783130b66..8382ebac18 100644 --- a/collects/scribble/latex-render.ss +++ b/collects/scribble/latex-render.ss @@ -1,6 +1,8 @@ #lang scheme/base -(require "struct.ss" +(require "core.ss" + "latex-variants.ss" + "private/render-utils.ss" scheme/class scheme/runtime-path scheme/port @@ -20,11 +22,15 @@ (define-runtime-path scribble-prefix-tex "scribble-prefix.tex") (define-runtime-path scribble-tex "scribble.tex") +(define-runtime-path scribble-style-tex "scribble-style.tex") -(define (gif-to-png p) - (if (equal? (filename-extension p) #"gif") - (path-replace-suffix p #".png") - p)) +(define (color->string c) + (if (string? c) + c + (format "~a,~a,~a" + (/ (car c) 255.0) + (/ (cadr c) 255.0) + (/ (caddr c) 255.0)))) (define (render-mixin %) (class % @@ -33,48 +39,76 @@ (define/override (get-suffix) #".tex") (inherit render-block - render-content render-part install-file format-number - extract-part-style-files) + extract-part-style-files + extract-version + extract-authors + extract-pretitle) + + (define/override (auto-extra-files? v) (latex-defaults? v)) + (define/override (auto-extra-files-paths v) (latex-defaults-extra-files v)) (define/override (render-one d ri fn) - (let ([style-file (or style-file scribble-tex)] - [prefix-file (or prefix-file scribble-prefix-tex)]) + (let* ([defaults (ormap (lambda (v) (and (latex-defaults? v) v)) + (style-variants (part-style d)))] + [prefix-file (or prefix-file + (and defaults + (let ([v (latex-defaults-prefix defaults)]) + (cond + [(bytes? v) v] + [else (main-collects-relative->path v)]))) + scribble-prefix-tex)] + [style-file (or style-file + (and defaults + (let ([v (latex-defaults-style defaults)]) + (cond + [(bytes? v) v] + [else (main-collects-relative->path v)]))) + scribble-style-tex)]) (for-each (lambda (style-file) - (with-input-from-file style-file - (lambda () - (copy-port (current-input-port) (current-output-port))))) - (list* prefix-file style-file - (append style-extra-files - (extract-part-style-files + (if (bytes? style-file) + (display style-file) + (with-input-from-file style-file + (lambda () + (copy-port (current-input-port) (current-output-port)))))) + (list* prefix-file + scribble-tex + (append (extract-part-style-files d ri 'tex - (lambda (p) #f))))) + (lambda (p) #f) + tex-addition? + tex-addition-path) + (list style-file) + style-extra-files))) (printf "\\begin{document}\n\\preDoc\n") (when (part-title-content d) - (let ([m (ormap (lambda (v) - (and (styled-paragraph? v) - (equal? "author" (styled-paragraph-style v)) - v)) - (flow-paragraphs (part-flow d)))]) - (when m - (do-render-paragraph m d ri #t))) - (let ([vers (or (and (versioned-part? d) (versioned-part-version d)) - (version))]) - (printf "\\titleAnd~aVersion{" (if (equal? vers "") "Empty" "")) + (let ([vers (extract-version d)] + [pres (extract-pretitle d)] + [auths (extract-authors d)]) + (for ([pre (in-list pres)]) + (do-render-paragraph pre d ri #t)) + (printf "\\titleAnd~aVersionAnd~aAuthors{" + (if (equal? vers "") "Empty" "") + (if (null? auths) "Empty" "")) (render-content (part-title-content d) d ri) - (printf "}{~a}\n" vers))) + (printf "}{~a}{" vers) + (for/fold ([first? #t]) ([auth (in-list auths)]) + (unless first? (printf "\\SAuthorSep{}")) + (do-render-paragraph auth d ri #t) + #f) + (printf "}\n"))) (render-part d ri) (printf "\n\n\\postDoc\n\\end{document}\n"))) (define/override (render-part-content d ri) (let ([number (collected-info-number (part-collected-info d ri))]) (when (and (part-title-content d) (pair? number)) - (when (part-style? d 'index) + (when (eq? (style-name (part-style d)) 'index) (printf "\\twocolumn\n\\parskip=0pt\n\\addcontentsline{toc}{section}{Index}\n")) (let ([no-number? (and (pair? number) (or (not (car number)) @@ -96,38 +130,32 @@ (printf "{") (render-content (part-title-content d) d ri) (printf "}") - (when (part-style? d 'index) (printf "\n\n"))) + (when (eq? (style-name (part-style d)) 'index) (printf "\n\n"))) (for ([t (part-tags d)]) (printf "\\label{t:~a}\n\n" (t-encode (add-current-tag-prefix (tag-key t ri))))) - (render-flow (part-flow d) d ri #f) + (render-flow (part-blocks d) d ri #f) (for ([sec (part-parts d)]) (render-part sec ri)) - (when (part-style? d 'index) (printf "\\onecolumn\n\n")) + (when (eq? (style-name (part-style d)) 'index) (printf "\\onecolumn\n\n")) null)) (define/override (render-paragraph p part ri) (do-render-paragraph p part ri #f)) - (define/private (do-render-paragraph p part ri author?) - (let ([style (and (styled-paragraph? p) - (let ([s (flatten-style - (styled-paragraph-style p))]) - (if (with-attributes? s) - (let ([base (with-attributes-style s)]) - (if (eq? base 'div) - (let ([a (assq 'class (with-attributes-assoc s))]) - (if a - (cdr a) - base)) - base)) - s)))]) - (unless (and (not author?) - (equal? style "author")) - (when (string? style) - (printf "\\~a{" style)) - (if (toc-paragraph? p) - (printf "\\newpage \\tableofcontents \\newpage") - (super render-paragraph p part ri)) - (when (string? style) (printf "}")))) + (define/private (do-render-paragraph p part ri show-pre?) + (let* ([sn (style-name (paragraph-style p))] + [style (if (eq? sn 'author) + "SAuthor" + sn)]) + (unless (and (not show-pre?) + (or (eq? sn 'author) + (eq? sn 'pretitle))) + (let ([use-style? (string? style)]) + (when use-style? + (printf "\\~a{" style)) + (if (toc-paragraph? p) + (printf "\\newpage \\tableofcontents \\newpage") + (super render-paragraph p part ri)) + (when use-style? (printf "}"))))) null) (define/override (render-intrapara-block p part ri first? last? starting-item?) @@ -136,91 +164,131 @@ (begin0 (super render-intrapara-block p part ri first? last? starting-item?))) - (define/override (render-element e part ri) + (define/override (render-content e part ri) (when (render-element? e) ((render-element-render e) this part ri)) (let ([part-label? (and (link-element? e) (pair? (link-element-tag e)) (eq? 'part (car (link-element-tag e))) - (null? (element-content e)))]) + (empty-content? (element-content e)))]) (parameterize ([done-link-page-numbers (or (done-link-page-numbers) (link-element? e))]) (when (target-element? e) (printf "\\label{t:~a}" (t-encode (add-current-tag-prefix (tag-key (target-element-tag e) ri))))) (when part-label? - (printf "\\SecRef{") - (render-content - (let ([dest (resolve-get part ri (link-element-tag e))]) + (let ([dest (resolve-get part ri (link-element-tag e))]) + (printf "\\~aRef~a{" + (case (and dest (length (cadr dest))) + [(0) "Book"] + [(1) "Chap"] + [else "Sec"]) + (if (let ([s (element-style e)]) + (and (style? s) (memq 'uppercase (style-variants s)))) + "UC" + "")) + (render-content (if dest - (if (list? (cadr dest)) - (format-number (cadr dest) null) - (begin (fprintf (current-error-port) - "Internal tag error: ~s -> ~s\n" - (link-element-tag e) - dest) - '("!!!"))) - (list "???"))) - part ri) - (printf "}{")) - (let ([style (and (element? e) - (let ([s (flatten-style (element-style e))]) - (if (with-attributes? s) - (with-attributes-style s) - s)))] - [wrap (lambda (e s tt?) - (printf "\\~a{" s) - (parameterize ([rendering-tt (or tt? (rendering-tt))]) - (super render-element e part ri)) - (printf "}"))]) - (cond - [(symbol? style) - (case style - [(italic) (wrap e "textit" #f)] - [(bold) (wrap e "textbf" #f)] - [(tt) (wrap e "Scribtexttt" #t)] - [(url) (wrap e "nolinkurl" 'exact)] - [(no-break) (super render-element e part ri)] - [(sf) (wrap e "textsf" #f)] - [(subscript) (wrap e "textsub" #f)] - [(superscript) (wrap e "textsuper" #f)] - [(hspace) - (let ([s (content->string (element-content e))]) - (case (string-length s) - [(0) (void)] - [else - (printf "\\mbox{\\hphantom{\\Scribtexttt{~a}}}" - (regexp-replace* #rx"." s "x"))]))] - [(newline) (printf "\\\\")] - [else (error 'latex-render - "unrecognzied style symbol: ~s" style)])] - [(target-url? style) - (wrap e (format "href{~a}" (target-url-addr style)) #f)] - [(string? style) - (wrap e style (regexp-match? #px"^scheme(?!error)" style))] - [(and (pair? style) (memq (car style) '(bg-color color))) - (wrap e (format - "~a{~a}" - (format (if (eq? (car style) 'bg-color) - "in~acolorbox" "intext~acolor") - (if (= (length style) 2) "" "rgb")) - (if (= (length style) 2) - (cadr style) - (format "~a,~a,~a" - (/ (cadr style) 255.0) - (/ (caddr style) 255.0) - (/ (cadddr style) 255.0)))) - #f)] - [(image-file? style) - (if (disable-images) - (void) - (let ([fn (install-file - (gif-to-png - (main-collects-relative->path - (image-file-path style))))]) - (printf "\\includegraphics[scale=~a]{~a}" - (image-file-scale style) fn)))] - [else (super render-element e part ri)]))) + (if (list? (cadr dest)) + (format-number (cadr dest) null) + (begin (fprintf (current-error-port) + "Internal tag error: ~s -> ~s\n" + (link-element-tag e) + dest) + '("!!!"))) + (list "???")) + part ri) + (printf "}{"))) + (let* ([es (cond + [(element? e) (element-style e)] + [(multiarg-element? e) (multiarg-element-style e)] + [else #f])] + [style-name (if (style? es) + (style-name es) + es)] + [style (and (style? es) es)] + [core-render (lambda (e tt?) + (if (and (image-element? e) + (not (disable-images))) + (let ([fn (install-file + (select-suffix + (main-collects-relative->path + (image-element-path e)) + (image-element-suffixes e) + '(".pdf" ".ps" ".png")))]) + (printf "\\includegraphics[scale=~a]{~a}" + (image-element-scale e) fn)) + (parameterize ([rendering-tt (or tt? (rendering-tt))]) + (super render-content e part ri))))] + [wrap (lambda (e s tt?) + (printf "\\~a{" s) + (core-render e tt?) + (printf "}"))]) + (define (finish tt?) + (cond + [(symbol? style-name) + (case style-name + [(italic) (wrap e "textit" tt?)] + [(bold) (wrap e "textbf" tt?)] + [(tt) (wrap e "Scribtexttt" #t)] + [(url) (wrap e "nolinkurl" 'exact)] + [(no-break) (core-render e tt?)] + [(sf) (wrap e "textsf" #f)] + [(subscript) (wrap e "textsub" #f)] + [(superscript) (wrap e "textsuper" #f)] + [(smaller) (wrap e "Smaller" #f)] + [(larger) (wrap e "Larger" #f)] + [(hspace) + (let ([s (content->string e)]) + (case (string-length s) + [(0) (void)] + [else + (printf "\\mbox{\\hphantom{\\Scribtexttt{~a}}}" + (regexp-replace* #rx"." s "x"))]))] + [(newline) (printf "\\\\")] + [else (error 'latex-render + "unrecognzied style symbol: ~s" style)])] + [(string? style-name) + (let* ([v (if style (style-variants style) null)] + [tt? (cond + [(memq 'tt-chars v) #t] + [(memq 'exact-chars v) 'exact] + [else tt?])]) + (cond + [(multiarg-element? e) + (printf "\\~a" style-name) + (if (null? (multiarg-element-contents e)) + (printf "{}") + (for ([i (in-list (multiarg-element-contents e))]) + (printf "{") + (render-content i part ri) + (printf "}")))] + [else + (wrap e style-name tt?)]))] + [else + (core-render e tt?)])) + (let loop ([l (if style (style-variants style) null)] [tt? #f]) + (if (null? l) + (finish tt?) + (let ([v (car l)]) + (cond + [(target-url? v) + (printf "\\href{~a}{" (target-url-addr v)) + (loop (cdr l) #t) + (printf "}")] + [(color-variant? v) + (printf "\\intext~acolor{~a}{" + (if (string? (color-variant-color v)) "" "rgb") + (color->string (color-variant-color v))) + (loop (cdr l) tt?) + (printf "}")] + [(background-color-variant? v) + (printf "\\in~acolorbox{~a}{" + (if (string? (background-color-variant-color v)) "" "rgb") + (color->string (background-color-variant-color v))) + (loop (cdr l) tt?) + (printf "}")] + [else (loop (cdr l) tt?)])))))) (when part-label? (printf "}")) (when (and (link-element? e) @@ -244,60 +312,70 @@ (string->list (format "~s" s))))) (define/override (render-flow p part ri starting-item?) - (if (null? (flow-paragraphs p)) + (if (null? p) null (begin - (render-block (car (flow-paragraphs p)) part ri starting-item?) - (for ([b (in-list (cdr (flow-paragraphs p)))]) + (render-block (car p) part ri starting-item?) + (for ([b (in-list (cdr p))]) (printf "\n\n") (render-block b part ri #f)) null))) (define/override (render-table t part ri starting-item?) - (let* ([boxed? (eq? 'boxed (table-style t))] - [index? (eq? 'index (table-style t))] + (render-table* t part ri starting-item? "[t]")) + + (define/private (render-table* t part ri starting-item? alignment) + (let* ([s-name (style-name (table-style t))] + [boxed? (eq? 'boxed s-name)] + [index? (eq? 'index s-name)] [tableform (cond [index? "list"] [(not (current-table-mode)) "bigtabular"] [else "tabular"])] [opt (cond [(equal? tableform "bigtabular") ""] - [(equal? tableform "tabular") "[t]"] + [(equal? tableform "tabular") alignment] [else ""])] - [flowss (if index? (cddr (table-flowss t)) (table-flowss t))] - [row-styles (cdr (or (and (list? (table-style t)) - (assoc 'row-styles (table-style t))) - (cons #f (map (lambda (x) #f) flowss))))] - [twidth (if (null? (table-flowss t)) + [blockss (if index? (cddr (table-blockss t)) (table-blockss t))] + [cell-styless (extract-table-cell-styles t)] + [twidth (if (null? (table-blockss t)) 1 - (length (car (table-flowss t))))] + (length (car (table-blockss t))))] [single-column? (and (= 1 twidth) - (or (not (table-style t)) - (string? (table-style t))) + (or (not s-name) (string? s-name)) + (not (ormap (lambda (cell-styles) + (ormap (lambda (s) + (or (string? (style-name s)) + (let ([l (style-variants s)]) + (or (memq 'right l) + (memq 'center l))))) + cell-styles)) + cell-styless)) (not (current-table-mode)))] [inline? (and (not single-column?) (not boxed?) (not index?) - (ormap (lambda (rs) (equal? rs "inferencetop")) row-styles) + (ormap (lambda (rs) + (ormap (lambda (cs) (style-name cs)) rs)) + cell-styless) (= 1 twidth) (let ([m (current-table-mode)]) (and m (equal? "bigtabular" (car m)) - (= 1 (length (car (table-flowss (cadr m))))))))] + (= 1 (length (car (table-blockss (cadr m))))))))] [boxline "{\\setlength{\\unitlength}{\\linewidth}\\begin{picture}(1,0)\\put(0,0){\\line(1,0){1}}\\end{picture}}"]) (if single-column? (begin - (when (string? (table-style t)) - (printf "\\begin{~a}" (table-style t))) - (do-render-blockquote - (make-blockquote "SingleColumn" - (apply append (map flow-paragraphs (map car (table-flowss t))))) + (when (string? s-name) + (printf "\\begin{~a}" s-name)) + (do-render-nested-flow + (make-nested-flow (make-style "SingleColumn" null) (map car (table-blockss t))) part ri #t) - (when (string? (table-style t)) - (printf "\\end{~a}" (table-style t)))) - (unless (or (null? flowss) (null? (car flowss))) + (when (string? s-name) + (printf "\\end{~a}" s-name))) + (unless (or (null? blockss) (null? (car blockss))) (parameterize ([current-table-mode (if inline? (current-table-mode) (list tableform t))] [show-link-page-numbers @@ -311,8 +389,8 @@ (if (and starting-item? (equal? tableform "bigtabular")) "\\bigtableinlinecorrect" "") - (if (string? (table-style t)) - (format "\\begin{~a}" (table-style t)) + (if (string? s-name) + (format "\\begin{~a}" s-name) "") tableform opt @@ -320,36 +398,27 @@ "\\bigtableleftpad" "") (string-append* - (map (lambda (i align) + (map (lambda (i cell-style) (format "~a@{}" - (case align - [(center) "c"] - [(right) "r"] - [else "l"]))) - (car flowss) - (cdr (or (and (list? (table-style t)) - (assoc 'alignment - (or (table-style t) null))) - (cons #f (map (lambda (x) #f) - (car flowss))))))) + (cond + [(memq 'center (style-variants cell-style)) "c"] + [(memq 'right (style-variants cell-style)) "r"] + [else "l"]))) + (car blockss) + (car cell-styless))) (if boxed? (if (equal? tableform "bigtabular") (format "~a \\SEndFirstHead\n" boxline) (format "\\multicolumn{~a}{@{}l@{}}{~a} \\\\\n" - (length (car flowss)) + (length (car blockss)) boxline)) ""))]) - (let loop ([flowss flowss] - [row-styles row-styles]) - (let ([flows (car flowss)] - [row-style (car row-styles)]) + (let loop ([blockss blockss] + [cell-styless cell-styless]) + (let ([flows (car blockss)] + [cell-styles (car cell-styless)]) (let loop ([flows flows] - [col-v-styles (or (and (list? row-style) - (let ([p (assoc 'valignment row-style)]) - (and p (cdr p)))) - (let ([p (and (list? (table-style t)) - (assoc 'valignment (table-style t)))]) - (and p (cdr p))))]) + [cell-styles cell-styles]) (unless (null? flows) (when index? (printf "\n\\item ")) (unless (eq? 'cont (car flows)) @@ -359,110 +428,103 @@ (loop (cdr flows) (add1 n))] [else n]))]) (unless (= cnt 1) (printf "\\multicolumn{~a}{l}{" cnt)) - (render-table-flow (car flows) part ri twidth (and col-v-styles - (car col-v-styles))) + (render-table-cell (car flows) part ri twidth (car cell-styles)) (unless (= cnt 1) (printf "}")) (unless (null? (list-tail flows cnt)) (printf " &\n")))) (unless (null? (cdr flows)) (loop (cdr flows) - (and col-v-styles (cdr col-v-styles)))))) - (unless (or index? (null? (cdr flowss))) - (printf " \\\\\n") - (when (equal? row-style "inferencetop") (printf "\\hline\n"))) - (unless (null? (cdr flowss)) - (loop (cdr flowss) (cdr row-styles))))) + (cdr cell-styles))))) + (unless (or index? (null? (cdr blockss))) + (printf " \\\\\n")) + (unless (null? (cdr blockss)) + (loop (cdr blockss) (cdr cell-styless))))) (unless inline? (printf "\\end{~a}~a" tableform - (if (string? (table-style t)) - (format "\\end{~a}" (table-style t)) + (if (string? s-name) + (format "\\end{~a}" s-name) ""))))))) null) - (define/private (render-table-flow p part ri twidth vstyle) - ;; Emit a \\ between blocks in single-column mode, - ;; used a nested table otherwise for multiple elements. - (let ([in-table? (or (and (not (= twidth 1)) - ((length (flow-paragraphs p)) . > . 1)) - (eq? vstyle 'top))]) - (when in-table? - (printf "\\begin{tabular}~a{@{}l@{}}\n" - (cond - [(eq? vstyle 'top) "[t]"] - [(eq? vstyle 'center) "[c]"] - [else ""]))) - (let loop ([ps (flow-paragraphs p)]) - (cond - [(null? ps) (void)] - [else - (let ([minipage? (or (not (or (paragraph? (car ps)) - (table? (car ps)))) - (eq? vstyle 'center))]) + (define/private (render-table-cell p part ri twidth vstyle) + (let ([top? (memq 'top (style-variants vstyle))] + [center? (memq 'vcenter (style-variants vstyle))]) + (when (style-name vstyle) + (printf "\\~a{" (style-name vstyle))) + (let ([minipage? (and (not (table? p)) + (or (not (paragraph? p)) + top? + center?))]) (when minipage? (printf "\\begin{minipage}~a{~a\\linewidth}\n" (cond - [(eq? vstyle 'top) "[t]"] - [(eq? vstyle 'center) "[c]"] + [top? "[t]"] + [center? "[c]"] [else ""]) (/ 1.0 twidth))) - (render-block (car ps) part ri #f) + (if (table? p) + (render-table* p part ri #f (cond + [center? "[c]"] + [else "[t]"])) + (render-block p part ri #f)) (when minipage? - (printf " \\end{minipage}\n")) - (unless (null? (cdr ps)) - (printf " \\\\\n") - (when in-table? - (printf " ~ \\\\\n")) - (loop (cdr ps))))])) - (when in-table? - (printf "\n\\end{tabular}")) + (printf " \\end{minipage}\n"))) + (when (style-name vstyle) + (printf "}")) null)) (define/override (render-itemization t part ri) - (let* ([style-str (and (styled-itemization? t) - (string? (styled-itemization-style t)) - (styled-itemization-style t))] - [mode (or style-str - (if (and (styled-itemization? t) - (eq? (styled-itemization-style t) 'ordered)) + (let* ([style-str (let ([s (style-name (itemization-style t))]) + (if (eq? s 'compact) + "compact" + s))] + [mode (or (and (string? style-str) + style-str) + (if (eq? 'ordered style-str) "enumerate" "itemize"))]) (printf "\\begin{~a}\\atItemizeStart" mode) - (for ([flow (itemization-flows t)]) - (printf "\n\n\\~a" (if style-str + (for ([flow (in-list (itemization-blockss t))]) + (printf "\n\n\\~a" (if (string? style-str) (format "~aItem{" style-str) "item ")) (render-flow flow part ri #t) - (when style-str + (when (string? style-str) (printf "}"))) (printf "\\end{~a}" mode) null)) - (define/private (do-render-blockquote t part ri single-column?) - (let ([kind (or (blockquote-style t) "quote")]) - (if (regexp-match #rx"^[\\]" kind) - (printf "~a{" kind) + (define/private (do-render-nested-flow t part ri single-column?) + (let ([kind (or (let ([s (style-name (nested-flow-style t))]) + (or (and (string? s) s) + (and (eq? s 'inset) "quote"))) + "Subflow")] + [command? (memq 'command (style-variants (nested-flow-style t)))]) + (if command? + (printf "\\~a{" kind) (printf "\\begin{~a}" kind)) (parameterize ([current-table-mode (if (or single-column? (not (current-table-mode))) (current-table-mode) - (list "blockquote" t))]) - (render-flow (make-flow (blockquote-paragraphs t)) part ri #f)) - (if (regexp-match #rx"^[\\]" kind) + (list "nested-flow" t))]) + (render-flow (nested-flow-blocks t) part ri #f)) + (if command? (printf "}") (printf "\\end{~a}" kind)) null)) - (define/override (render-blockquote t part ri) - (do-render-blockquote t part ri #f)) + (define/override (render-nested-flow t part ri) + (do-render-nested-flow t part ri #f)) (define/override (render-compound-paragraph t part ri starting-item?) - (let ([kind (compound-paragraph-style t)]) + (let ([kind (style-name (compound-paragraph-style t))] + [command? (memq 'command (style-variants (compound-paragraph-style t)))]) (when kind - (if (regexp-match #rx"^[\\]" kind) - (printf "~a{" kind) + (if command? + (printf "\\~a{" kind) (printf "\\begin{~a}" kind))) (super render-compound-paragraph t part ri starting-item?) (when kind - (if (regexp-match #rx"^[\\]" kind) + (if command? (printf "}") (printf "\\end{~a}" kind))) null)) @@ -480,6 +542,7 @@ [(rsquo) "'"] [(prime) "$'$"] [(rarr) "$\\rightarrow$"] + [(larr) "$\\leftarrow$"] [(alpha) "$\\alpha$"] [(infin) "$\\infty$"] [(lang) "$\\langle$"] @@ -674,10 +737,10 @@ (define/override (table-of-contents sec ri) ;; FIXME: isn't local to the section - (make-toc-paragraph null)) + (make-toc-paragraph plain null)) (define/override (local-table-of-contents part ri style) - (make-paragraph null)) + (make-paragraph plain null)) ;; ---------------------------------------- diff --git a/collects/scribble/latex-variants.ss b/collects/scribble/latex-variants.ss new file mode 100644 index 0000000000..f500bd7cd6 --- /dev/null +++ b/collects/scribble/latex-variants.ss @@ -0,0 +1,9 @@ +#lang scheme/base +(require "private/provide-structs.ss" + scheme/contract) + +(provide-structs + [tex-addition ([path (or/c path-string? (cons/c 'collects (listof bytes?)))])] + [latex-defaults ([prefix (or/c bytes? path-string? (cons/c 'collects (listof bytes?)))] + [style (or/c bytes? path-string? (cons/c 'collects (listof bytes?)))] + [extra-files (listof (or/c path-string? (cons/c 'collects (listof bytes?))))])]) diff --git a/collects/scribble/manual-prefix.tex b/collects/scribble/manual-prefix.tex new file mode 100644 index 0000000000..ddad26f489 --- /dev/null +++ b/collects/scribble/manual-prefix.tex @@ -0,0 +1,12 @@ +% This is the prefix for PLT Scheme manuals +\documentclass{article} + +\parskip=10pt +\parindent=0pt +\partopsep=0pt + +% Adjust margins to match HTML width for +% fixed-width font +\advance \oddsidemargin by -0.15in +\advance \evensidemargin by -0.15in +\advance \textwidth by 0.3in diff --git a/collects/scribble/manual-struct.ss b/collects/scribble/manual-struct.ss index 0c93f116bc..030bd883a3 100644 --- a/collects/scribble/manual-struct.ss +++ b/collects/scribble/manual-struct.ss @@ -1,6 +1,7 @@ #lang scheme/base -(require "struct.ss" +(require "core.ss" + "private/provide-structs.ss" scheme/contract) (provide-structs diff --git a/collects/scribble/manual-style.tex b/collects/scribble/manual-style.tex new file mode 100644 index 0000000000..50a42aa1ef --- /dev/null +++ b/collects/scribble/manual-style.tex @@ -0,0 +1,11 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Re-definitions for the PLT Scheme manual style + +\renewcommand{\sectionNewpage}{\newpage} + +\renewcommand{\preDoc}{\sloppy} + +\renewcommand{\ChapRef}[2]{\SecRef{#1}{#2}} +\renewcommand{\SecRef}[2]{\S#1 ``#2''} +\renewcommand{\ChapRefUC}[2]{\SecRefUC{#1}{#2}} +\renewcommand{\SecRefUC}[2]{\SecRef{#1}{#2}} diff --git a/collects/scribble/manual.ss b/collects/scribble/manual.ss index c902936141..960b4cd89a 100644 --- a/collects/scribble/manual.ss +++ b/collects/scribble/manual.ss @@ -1,5 +1,5 @@ #lang scheme/base -(require "basic.ss" +(require "base.ss" "private/manual-style.ss" "private/manual-scheme.ss" "private/manual-mod.ss" @@ -15,7 +15,7 @@ (provide unsyntax make-binding-redirect-elements defidentifier - (all-from-out "basic.ss" + (all-from-out "base.ss" "private/manual-style.ss" "private/manual-scheme.ss" "private/manual-mod.ss" diff --git a/collects/scribble/manual/lang.ss b/collects/scribble/manual/lang.ss index f3aa8bcbf4..bebfab3a82 100644 --- a/collects/scribble/manual/lang.ss +++ b/collects/scribble/manual/lang.ss @@ -1,4 +1,17 @@ -#lang scheme -(require scribble/doclang scribble/manual) -(provide (all-from-out scribble/doclang - scribble/manual)) +#lang scheme/base +(require scribble/doclang + scribble/manual + "../private/defaults.ss") +(provide (except-out (all-from-out scribble/doclang) #%module-begin) + (all-from-out scribble/manual) + (rename-out [module-begin #%module-begin])) + +(define-syntax-rule (module-begin id . body) + (#%module-begin id post-process () . body)) + +(define (post-process doc) + (add-defaults doc + (scribble-file "manual-prefix.tex") + (scribble-file "manual-style.tex") + null + #t)) diff --git a/collects/scribble/manual/lang/reader.ss b/collects/scribble/manual/lang/reader.ss index 45fc938087..b573019e95 100644 --- a/collects/scribble/manual/lang/reader.ss +++ b/collects/scribble/manual/lang/reader.ss @@ -5,6 +5,6 @@ scribble/manual/lang #:read scribble:read-inside #:read-syntax scribble:read-syntax-inside #:whole-body-readers? #t -#:wrapper1 (lambda (t) (list* 'doc '() (t))) +#:wrapper1 (lambda (t) (cons 'doc (t))) (require (prefix-in scribble: "../../reader.ss")) diff --git a/collects/scribble/private/defaults.ss b/collects/scribble/private/defaults.ss new file mode 100644 index 0000000000..9a1016862e --- /dev/null +++ b/collects/scribble/private/defaults.ss @@ -0,0 +1,28 @@ +#lang scheme/base +(require scribble/core + scribble/latex-variants + setup/main-collects) + +(provide scribble-file + add-defaults) + +(define (add-variant variants pred new) + (if (ormap pred variants) + variants + (cons new variants))) + +(define (scribble-file s) + (path->main-collects-relative (build-path (collection-path "scribble") s))) + +(define (add-defaults doc pfx styl extras version?) + (struct-copy part doc [style (make-style (style-name (part-style doc)) + ((if version? add-variant (lambda (x y z) x)) + (add-variant + (style-variants (part-style doc)) + latex-defaults? + (make-latex-defaults + pfx + styl + extras)) + document-version? + (make-document-version (version))))])) diff --git a/collects/scribble/private/manual-bind.ss b/collects/scribble/private/manual-bind.ss index b136277545..8b06fc9801 100644 --- a/collects/scribble/private/manual-bind.ss +++ b/collects/scribble/private/manual-bind.ss @@ -3,7 +3,6 @@ "../struct.ss" "../scheme.ss" "../search.ss" - "../config.ss" "../basic.ss" "../manual-struct.ss" "manual-ex.ss" @@ -52,10 +51,10 @@ [sd (and stag (resolve-get/tentative sec ri stag))]) (list (make-element - "schemesymbol" + symbol-color (list - (cond [sd (make-link-element "schemesyntaxlink" (list s) stag)] - [vtag (make-link-element "schemevaluelink" (list s) vtag)] + (cond [sd (make-link-element syntax-link-color (list s) stag)] + [vtag (make-link-element value-link-color (list s) vtag)] [else s])))))) (lambda () s) (lambda () s)))) @@ -232,12 +231,12 @@ (list (symbol->string id)) (list (make-element - "schemesymbol" + symbol-color (list (make-element (if form? - "schemesyntaxlink" - "schemevaluelink") + syntax-link-color + value-link-color) (list (symbol->string id)))))) ((if form? make-form-index-desc diff --git a/collects/scribble/private/manual-class.ss b/collects/scribble/private/manual-class.ss index bdef2649ab..8607349fe7 100644 --- a/collects/scribble/private/manual-class.ss +++ b/collects/scribble/private/manual-class.ss @@ -3,7 +3,6 @@ "../struct.ss" "../scheme.ss" "../search.ss" - "../config.ss" "../basic.ss" "../manual-struct.ss" "qsloc.ss" @@ -134,9 +133,9 @@ `(cls/intf ,(cadr tag)) (make-cls/intf (make-element - "schemesymbol" + symbol-color (list (make-link-element - "schemevaluelink" + value-link-color (list (symbol->string (syntax-e (decl-name decl)))) tag))) (map id-info (decl-app-mixins decl)) diff --git a/collects/scribble/private/manual-form.ss b/collects/scribble/private/manual-form.ss index 7f032455b0..b14506a532 100644 --- a/collects/scribble/private/manual-form.ss +++ b/collects/scribble/private/manual-form.ss @@ -3,7 +3,6 @@ "../struct.ss" "../scheme.ss" "../search.ss" - "../config.ss" "../basic.ss" "../manual-struct.ss" "qsloc.ss" diff --git a/collects/scribble/private/manual-method.ss b/collects/scribble/private/manual-method.ss index 0017a8340a..0b8400e582 100644 --- a/collects/scribble/private/manual-method.ss +++ b/collects/scribble/private/manual-method.ss @@ -34,8 +34,8 @@ (lambda (c mk) (mk id/tag))) content (lambda (tag) - (make-element "schemesymbol" - (list (make-link-element "schemevaluelink" content + (make-element symbol-color + (list (make-link-element value-link-color content (method-tag tag sym)))))))) (define (method-tag vtag sym) diff --git a/collects/scribble/private/manual-proc.ss b/collects/scribble/private/manual-proc.ss index 22130a06c4..81e40f1675 100644 --- a/collects/scribble/private/manual-proc.ss +++ b/collects/scribble/private/manual-proc.ss @@ -3,7 +3,6 @@ "../struct.ss" "../scheme.ss" "../search.ss" - "../config.ss" "../basic.ss" "../manual-struct.ss" "qsloc.ss" @@ -27,9 +26,9 @@ *defthing) (define dots0 - (make-element "schememeta" (list "..."))) + (make-element meta-color (list "..."))) (define dots1 - (make-element "schememeta" (list "...+"))) + (make-element meta-color (list "...+"))) (define (make-openers n) (schemeparenfont @@ -772,7 +771,7 @@ (list content) tag (list name) - (list (schemeidfont (make-element "schemevaluelink" + (list (schemeidfont (make-element value-link-color (list name)))) (with-exporting-libraries (lambda (libs) diff --git a/collects/scribble/private/manual-scheme.ss b/collects/scribble/private/manual-scheme.ss index cce0ac3756..b6e574aa20 100644 --- a/collects/scribble/private/manual-scheme.ss +++ b/collects/scribble/private/manual-scheme.ss @@ -57,9 +57,9 @@ (syntax/loc stx (schememod #:file #f lang rest ...))])) (define (to-element/result s) - (make-element "schemeresult" (list (to-element/no-color s)))) + (make-element result-color (list (to-element/no-color s)))) (define (to-element/id s) - (make-element "schemesymbol" (list (to-element/no-color s)))) + (make-element symbol-color (list (to-element/no-color s)))) (define-syntax (keep-s-expr stx) (syntax-case stx () @@ -106,7 +106,7 @@ (define (as-modname-link s e) (if (symbol? s) - (make-link-element "schememodlink" + (make-link-element module-link-color (list e) `(mod-path ,(symbol->string s))) e)) diff --git a/collects/scribble/private/manual-style.ss b/collects/scribble/private/manual-style.ss index 54cfa6c44f..f688bf5614 100644 --- a/collects/scribble/private/manual-style.ss +++ b/collects/scribble/private/manual-style.ss @@ -1,30 +1,34 @@ #lang scheme/base (require "../decode.ss" "../struct.ss" - "../basic.ss" + "../base.ss" + (only-in "../basic.ss" aux-elem itemize) + "../scheme.ss" + (only-in "../core.ss" make-style plain) "manual-utils.ss" scheme/list scheme/string) (provide PLaneT etc - litchar verbatim - image image/plain onscreen menuitem defterm emph + litchar + image (rename-out [image image/plain]) onscreen menuitem defterm schemefont schemevalfont schemeresultfont schemeidfont schemevarfont schemeparenfont schemekeywordfont schememetafont schememodfont - schemeerror + schemeerror schemeoutput filepath exec envvar Flag DFlag PFlag DPFlag indexed-file indexed-envvar - link procedure + (rename-out [hyperlink link]) + (rename-out [other-doc other-manual]) + (rename-out [centered centerline]) + itemize + procedure idefterm t inset-flow pidefterm hash-lang - centerline - commandline - elemtag elemref - secref seclink other-manual - margin-note + commandline void-const undefined-const + aux-elem math) (define PLaneT (make-element "planetName" '("PLaneT"))) @@ -37,51 +41,20 @@ (let ([s (string-append* (map (lambda (s) (regexp-replace* "\n" s " ")) strs))]) (if (regexp-match? #rx"^ *$" s) - (make-element "schemeinputbg" (list (hspace (string-length s)))) + (make-element input-background-color (list (hspace (string-length s)))) (let ([^spaces (car (regexp-match-positions #rx"^ *" s))] [$spaces (car (regexp-match-positions #rx" *$" s))]) (make-element - "schemeinputbg" + input-background-color (list (hspace (cdr ^spaces)) - (make-element "schemeinput" + (make-element input-color (list (substring s (cdr ^spaces) (car $spaces)))) (hspace (- (cdr $spaces) (car $spaces))))))))) -(define (verbatim #:indent [i 0] s . more) - (define indent - (if (zero? i) - values - (let ([hs (hspace i)]) (lambda (x) (cons hs x))))) - (define strs (regexp-split #rx"\n" (string-append* s more))) - (define (str->elts str) - (let ([spaces (regexp-match-positions #rx"(?:^| ) +" str)]) - (if spaces - (list* (substring str 0 (caar spaces)) - (hspace (- (cdar spaces) (caar spaces))) - (str->elts (substring str (cdar spaces)))) - (list (make-element 'tt (list str)))))) - (define (make-line str) - (let* ([line (indent (str->elts str))] - [line (list (make-element 'tt line))]) - (list (make-flow (list (make-omitable-paragraph line)))))) - (make-table #f (map make-line strs))) - -;; String String *-> Element -;; an in-lined image, relative to the current directory -(define (image #:scale [scale 1.0] filename-relative-to-source . alt) - (make-element (make-image-file filename-relative-to-source scale) - (decode-content alt))) - -(define (image/plain filename-relative-to-source . alt) - (make-element (make-image-file filename-relative-to-source 1.0) - (decode-content alt))) - (define (onscreen . str) (make-element 'sf (decode-content str))) (define (menuitem menu item) (make-element 'sf (list menu "|" item))) -(define (emph . str) - (make-element 'italic (decode-content str))) (define (defterm . str) (make-element 'italic (decode-content str))) (define (idefterm . str) @@ -90,21 +63,21 @@ (define (schemefont . str) (apply tt str)) (define (schemevalfont . str) - (make-element "schemevalue" (decode-content str))) + (make-element value-color (decode-content str))) (define (schemeresultfont . str) - (make-element "schemeresult" (decode-content str))) + (make-element result-color (decode-content str))) (define (schemeidfont . str) - (make-element "schemesymbol" (decode-content str))) + (make-element symbol-color (decode-content str))) (define (schemevarfont . str) - (make-element "schemevariable" (decode-content str))) + (make-element variable-color (decode-content str))) (define (schemeparenfont . str) - (make-element "schemeparen" (decode-content str))) + (make-element paren-color (decode-content str))) (define (schememetafont . str) - (make-element "schememeta" (decode-content str))) + (make-element meta-color (decode-content str))) (define (schememodfont . str) - (make-element "schememod" (decode-content str))) + (make-element module-color (decode-content str))) (define (schemekeywordfont . str) - (make-element "schemekeyword" (decode-content str))) + (make-element keyword-color (decode-content str))) (define (filepath . str) (make-element 'tt (append (list "\"") (decode-content str) (list "\"")))) (define (indexed-file . str) @@ -141,17 +114,12 @@ [s (element->string f)]) (index* (list s) (list f) f))) (define (procedure . str) - (make-element "schemeresult" `("#"))) - -(define (link url - #:underline? [underline? #t] - #:style [style (if underline? #f "plainlink")] - . str) - (make-element (make-target-url url style) - (decode-content str))) + (make-element result-color `("#"))) +(define (schemeoutput . str) + (make-element output-color (decode-content str))) (define (schemeerror . str) - (make-element "schemeerror" (decode-content str))) + (make-element error-color (decode-content str))) (define (t . str) (decode-paragraph str)) @@ -159,11 +127,6 @@ (define (inset-flow . c) (make-blockquote "insetpara" (flow-paragraphs (decode-flow c)))) - - -(define (centerline . s) - (make-blockquote "SCentered" (flow-paragraphs (decode-flow s)))) - (define (commandline . s) (make-paragraph (cons (hspace 2) (map (lambda (s) (if (string? s) @@ -171,20 +134,6 @@ s)) s)))) -(define (elemtag t . body) - (make-target-element #f (decode-content body) `(elem ,t))) -(define (elemref #:underline? [u? #t] t . body) - (make-link-element (if u? #f "plainlink") (decode-content body) `(elem ,t))) - -(define (secref s #:underline? [u? #t] #:doc [doc #f] #:tag-prefixes [prefix #f]) - (make-link-element (if u? #f "plainlink") null `(part ,(doc-prefix doc prefix s)))) -(define (seclink tag #:underline? [u? #t] #:doc [doc #f] #:tag-prefixes [prefix #f] . s) - (make-link-element (if u? #f "plainlink") (decode-content s) - `(part ,(doc-prefix doc prefix tag)))) - -(define (other-manual #:underline? [u? #t] doc) - (secref #:doc doc #:underline? u? "top")) - (define (pidefterm . s) (let ([c (apply defterm s)]) (index (string-append (content->string (element-content c)) "s") @@ -192,26 +141,21 @@ (define (hash-lang) (make-link-element - "schememodlink" + module-link-color (list (schememodfont "#lang")) `(part ,(doc-prefix '(lib "scribblings/guide/guide.scrbl") "hash-lang")))) -(define (margin-note . c) - (make-blockquote - "\\refpara" - (list - (make-blockquote - "refcolumn" - (list - (make-blockquote - "refcontent" - (flow-paragraphs (decode-flow c)))))))) - (define void-const (schemeresultfont "#")) (define undefined-const (schemeresultfont "#")) +(define (link url + #:underline? [underline? #t] + #:style [style (if underline? #f "plainlink")] + . str) + (apply hyperlink url #:style (if style (make-style style null) plain) str)) + (define (math . s) (let ([c (decode-content s)]) (make-element @@ -243,4 +187,4 @@ (list (make-element 'italic (list i)))])] [(eq? i 'rsquo) (list 'prime)] [else (list i)]))) - c)))) + c)))) \ No newline at end of file diff --git a/collects/scribble/private/manual-utils.ss b/collects/scribble/private/manual-utils.ss index a8e9a75961..3f3d40614c 100644 --- a/collects/scribble/private/manual-utils.ss +++ b/collects/scribble/private/manual-utils.ss @@ -1,7 +1,7 @@ #lang scheme/base (require "../struct.ss" "../decode.ss" - "../basic.ss" + "../base.ss" scheme/list) (provide spacer doc-prefix @@ -12,17 +12,6 @@ (define spacer (hspace 1)) -(define doc-prefix - (case-lambda - [(doc s) - (if doc - (list (module-path-prefix->string doc) s) - s)] - [(doc prefix s) - (doc-prefix doc (if prefix - (append prefix (list s)) - s))])) - (define (to-flow e) (make-flow (list (make-omitable-paragraph (list e))))) (define flow-spacer (to-flow spacer)) diff --git a/collects/scribble/private/manual-vars.ss b/collects/scribble/private/manual-vars.ss index 9d82498085..08f14edac9 100644 --- a/collects/scribble/private/manual-vars.ss +++ b/collects/scribble/private/manual-vars.ss @@ -2,6 +2,7 @@ (require "../decode.ss" "../scheme.ss" "../struct.ss" + (only-in "../core.ss" style-name) (for-syntax scheme/base syntax/kerncase syntax/boundmap) @@ -108,7 +109,7 @@ (unless (and (box-splice? box) (= 1 (length (splice-run box))) (table? (car (splice-run box))) - (eq? 'boxed (table-style (car (splice-run box))))) + (eq? 'boxed (style-name (table-style (car (splice-run box)))))) (error 'deftogether "element is not a boxing splice containing a single table: ~e" box)) diff --git a/collects/scribble/private/provide-structs.ss b/collects/scribble/private/provide-structs.ss new file mode 100644 index 0000000000..18162c2e8f --- /dev/null +++ b/collects/scribble/private/provide-structs.ss @@ -0,0 +1,37 @@ +#lang scheme/base +(require scheme/serialize + scheme/contract + (for-syntax scheme/base)) + +(provide provide-structs) + +(define-syntax (provide-structs stx) + (syntax-case stx () + [(_ (id ([field ct] ...)) ...) + #`(begin + (define-serializable-struct id (field ...)) ... + (provide/contract + #,@(let ([ids (syntax->list #'(id ...))] + [fields+cts (syntax->list #'(([field ct] ...) ...))]) + (define (get-fields super-id) + (ormap (lambda (id fields+cts) + (if (identifier? id) + (and (free-identifier=? id super-id) + fields+cts) + (syntax-case id () + [(my-id next-id) + (free-identifier=? #'my-id super-id) + #`[#,@(get-fields #'next-id) + #,@fields+cts]] + [_else #f]))) + ids fields+cts)) + (map (lambda (id fields+cts) + (if (identifier? id) + #`[struct #,id #,fields+cts] + (syntax-case id () + [(id super) + #`[struct id (#,@(get-fields #'super) + #,@fields+cts)]]))) + ids + fields+cts))))])) + diff --git a/collects/scribble/private/render-utils.ss b/collects/scribble/private/render-utils.ss new file mode 100644 index 0000000000..3e08cd9a4d --- /dev/null +++ b/collects/scribble/private/render-utils.ss @@ -0,0 +1,55 @@ +#lang scheme/base +(require "../core.ss") + +(provide part-style? + select-suffix + extract-table-cell-styles + empty-content?) + +(define (part-style? p s) + (memq s (style-variants (part-style p)))) + +(define (select-suffix path suggested-suffixes accepted-suffixes) + (or (ormap (lambda (suggested) + (and (member suggested accepted-suffixes) + (let ([p (bytes->path + (bytes-append (path->bytes (if (string? path) + (string->path path) + path)) + (string->bytes/utf-8 suggested)))]) + (and (file-exists? p) + p)))) + suggested-suffixes) + path)) + +(define (extract-table-cell-styles t) + (let ([vars (style-variants (table-style t))]) + (or (let ([l (ormap (lambda (v) + (and (table-cells? v) + (table-cells-styless v))) + vars)]) + (and l + (unless (= (length l) (length (table-blockss t))) + (error 'table + "table-cells variant list's length does not match row count: ~e vs. ~e" + l (length (table-blockss t)))) + (for-each (lambda (l row) + (unless (= (length l) (length row)) + (error 'table + "table-cells variant list contains a row whose length does not match the content: ~e vs. ~e" + l (length row)))) + l (table-blockss t)) + l)) + (let ([cols (ormap (lambda (v) (and (table-columns? v) v)) vars)]) + (and cols + (let ([cols (table-columns-styles cols)]) + (map (lambda (row) + (unless (= (length cols) (length row)) + (error 'table + "table-columns variant list's length does not match a row length: ~e vs. ~e" + cols (length row))) + cols) + (table-blockss t))))) + (map (lambda (row) (map (lambda (c) plain) row)) (table-blockss t))))) + +(define (empty-content? c) (null? c)) diff --git a/collects/scribble/run.ss b/collects/scribble/run.ss index fbe66bba03..e6dc70780e 100644 --- a/collects/scribble/run.ss +++ b/collects/scribble/run.ss @@ -1,6 +1,6 @@ #lang scheme/base -(require "struct.ss" +(require "core.ss" "base-render.ss" "xref.ss" scheme/cmdline @@ -64,7 +64,7 @@ #:multi [("++extra") file "add given file" (current-extra-files (cons file (current-extra-files)))] - [("++style") file "add given .css/.tex file" + [("++style") file "add given .css/.tex file after others" (current-style-extra-files (cons file (current-style-extra-files)))] [("++info-in") file "load format-specific link information from " (current-info-input-files diff --git a/collects/scribble/scheme.css b/collects/scribble/scheme.css new file mode 100644 index 0000000000..333029e5bb --- /dev/null +++ b/collects/scribble/scheme.css @@ -0,0 +1,166 @@ + +/* See the beginning of "scribble.css". */ + +/* Monospace: */ +.ScmIn, .ScmRdr, .ScmPn, .ScmMeta, +.ScmMod, .ScmKw, .ScmVar, .ScmSym, +.ScmRes, .ScmOut, .ScmCmt, .ScmVal { + font-family: monospace; +} + +/* Serif: */ +.inheritedlbl { + font-family: 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; +} + +/* ---------------------------------------- */ +/* Scheme text styles */ + +.ScmIn { + color: #cc6633; + background-color: #eeeeee; +} + +.ScmInBG { + background-color: #eeeeee; +} + +.ScmRdr { +} + +.ScmPn { + color: #843c24; +} + +.ScmMeta { + color: #262680; +} + +.ScmMod { + color: black; +} + +.ScmOpt { + color: black; +} + +.ScmKw { + color: black; + font-weight: bold; +} + +.ScmErr { + color: red; + font-style: italic; +} + +.ScmVar { + color: #262680; + font-style: italic; +} + +.ScmSym { + color: #262680; +} + +.ScmValLink { + text-decoration: none; + color: blue; +} + +.ScmModLink { + text-decoration: none; + color: blue; +} + +.ScmStxLink { + text-decoration: none; + color: black; + font-weight: bold; +} + +.ScmRes { + color: #0000af; +} + +.ScmOut { + color: #960096; +} + +.ScmCmt { + color: #c2741f; +} + +.ScmVal { + color: #228b22; +} + +/* ---------------------------------------- */ +/* Some inline styles */ + +.together { + width: 100%; +} + +.prototype td { + vertical-align: text-top; +} +.longprototype td { + vertical-align: bottom; +} + +.ScmBlk td { + vertical-align: baseline; +} + +.argcontract td { + vertical-align: text-top; +} + +.highlighted { + background-color: #ddddff; +} + +.defmodule { + width: 100%; + background-color: #F5F5DC; +} + +.specgrammar { + float: right; +} + +.SBibliography td { + vertical-align: text-top; +} + +.leftindent { + margin-left: 1em; + margin-right: 0em; +} + +.insetpara { + margin-left: 1em; + margin-right: 1em; +} diff --git a/collects/scribble/scheme.ss b/collects/scribble/scheme.ss index dff809d40f..c1fae37133 100644 --- a/collects/scribble/scheme.ss +++ b/collects/scribble/scheme.ss @@ -1,7 +1,9 @@ (module scheme scheme/base - (require "struct.ss" + (require "core.ss" "basic.ss" "search.ss" + "html-variants.ss" + "latex-variants.ss" mzlib/class mzlib/for setup/main-collects @@ -20,6 +22,28 @@ current-variable-list current-meta-list + input-color + output-color + input-background-color + no-color + reader-color + result-color + keyword-color + comment-color + paren-color + meta-color + value-color + symbol-color + variable-color + opt-color + error-color + syntax-link-color + value-link-color + module-color + module-link-color + block-color + highlighted-color + (struct-out var-id) (struct-out shaped-parens) (struct-out just-context) @@ -29,16 +53,38 @@ make-element-id-transformer element-id-transformer?)) - (define no-color "schemeplain") - (define reader-color "schemereader") - (define keyword-color "schemekeyword") - (define comment-color "schemecomment") - (define paren-color "schemeparen") - (define meta-color "schememeta") - (define value-color "schemevalue") - (define symbol-color "schemesymbol") - (define variable-color "schemevariable") - (define opt-color "schemeopt") + (define scheme-variants + (let ([abs (lambda (s) + (path->main-collects-relative (build-path (collection-path "scribble") s)))]) + (list (make-css-addition (abs "scheme.css")) + (make-tex-addition (abs "scheme.tex"))))) + + (define (make-scheme-style s #:tt? [tt? #t]) + (make-style s (if tt? + (cons 'tt-chars scheme-variants) + scheme-variants))) + + (define output-color (make-scheme-style "ScmOut")) + (define input-color (make-scheme-style "ScmIn")) + (define input-background-color (make-scheme-style "ScmInBG")) + (define no-color (make-scheme-style "ScmPlain")) + (define reader-color (make-scheme-style "ScmRdr")) + (define result-color (make-scheme-style "ScmRes")) + (define keyword-color (make-scheme-style "ScmKw")) + (define comment-color (make-scheme-style "ScmCmt")) + (define paren-color (make-scheme-style "ScmPn")) + (define meta-color (make-scheme-style "ScmMeta")) + (define value-color (make-scheme-style "ScmVal")) + (define symbol-color (make-scheme-style "ScmSym")) + (define variable-color (make-scheme-style "ScmVar")) + (define opt-color (make-scheme-style "ScmOpt")) + (define error-color (make-scheme-style "ScmErr" #:tt? #f)) + (define syntax-link-color (make-scheme-style "ScmStxLink")) + (define value-link-color (make-scheme-style "ScmValLink")) + (define module-color (make-scheme-style "ScmMod")) + (define module-link-color (make-scheme-style "ScmModLink")) + (define block-color (make-scheme-style "ScmBlk")) + (define highlighted-color (make-scheme-style "highlighted" #:tt? #f)) (define current-keyword-list (make-parameter null)) @@ -66,7 +112,7 @@ i))) - (define line-breakable-space (make-element 'tt (list " "))) + (define line-breakable-space (make-element 'tt " ")) ;; These caches intentionally record a key with the value. ;; That way, when the value is no longer used, the key @@ -96,12 +142,12 @@ (list (case (car tag) [(form) - (make-link-element "schemesyntaxlink" (list s) tag)] + (make-link-element syntax-link-color (list s) tag)] [else - (make-link-element "schemevaluelink" (list s) tag)])) + (make-link-element value-link-color (list s) tag)])) (list (make-element "badlink" - (list (make-element "schemevaluelink" (list s)))))))) + (make-element value-link-color s)))))) (lambda () s) (lambda () s) key)]) @@ -111,10 +157,8 @@ (define (make-element/cache style content) (if (and element-cache - (pair? content) - (string? (car content)) - (null? (cdr content))) - (let ([key (vector style (car content))]) + (string? content)) + (let ([key (vector style content)]) (let ([b (hash-ref element-cache key #f)]) (or (and b (weak-box-value b)) (let ([e (make-cached-element style content key)]) @@ -184,6 +228,8 @@ [else paren-color]) (string-length s)))))) + (define omitable (make-style #f '(omitable))) + (define (gen-typeset c multi-line? prefix1 prefix suffix color?) (let* ([c (syntax-ize c 0)] [content null] @@ -200,7 +246,7 @@ [line (or (syntax-line first) 0)]) (define (finish-line!) (when multi-line? - (set! docs (cons (make-flow (list (make-omitable-paragraph (reverse content)))) + (set! docs (cons (make-paragraph omitable (reverse content)) docs)) (set! content null))) (define out @@ -209,16 +255,14 @@ (out v cls (let sz-loop ([v v]) (cond [(string? v) (string-length v)] + [(list? v) (for/fold ([s 0]) ([v (in-list v)]) (+ s (sz-loop v)))] [(sized-element? v) (sized-element-length v)] - [(and (element? v) - (= 1 (length (element-content v)))) - (sz-loop (car (element-content v)))] [(element? v) - (element-width v)] + (sz-loop (element-content v))] [(delayed-element? v) - (element-width v)] + (content-width v)] [(part-relative-element? v) - (element-width v)] + (content-width v)] [(spaces? v) (+ (sz-loop (car (element-content v))) (spaces-cnt v) @@ -240,10 +284,10 @@ [else (set! content (cons ((if highlight? (lambda (c) - (make-element "highlighted" (list c))) + (make-element highlighted-color c)) values) (if (and color? cls) - (make-element/cache cls (list v)) + (make-element/cache cls v) v)) content)) (set! dest-col (+ dest-col len))]))])) @@ -300,9 +344,9 @@ (make-sized-element (if val? value-color #f) (list - (make-element/cache (if val? value-color paren-color) '(". ")) + (make-element/cache (if val? value-color paren-color) '". ") (typeset a #f "" "" "" (not val?)) - (make-element/cache (if val? value-color paren-color) '(" ."))) + (make-element/cache (if val? value-color paren-color) '" .")) (+ (syntax-span a) 4))) (list (syntax-source a) (syntax-line a) @@ -564,8 +608,8 @@ (finish-line!)) (if multi-line? (if (= 1 (length docs)) - (car (flow-paragraphs (car docs))) - (make-table "schemeblock" (map list (reverse docs)))) + (car docs) + (make-table block-color (map list (reverse docs)))) (make-sized-element #f (reverse content) dest-col)))) (define (typeset c multi-line? prefix1 prefix suffix color?) @@ -590,8 +634,8 @@ [(elem color len) (if (and (string? elem) (= len (string-length elem))) - (make-element/cache (and color? color) (list elem)) - (make-sized-element (and color? color) (list elem) len))])]) + (make-element/cache (and color? color) elem) + (make-sized-element (and color? color) elem len))])]) mk) color? 0)))) diff --git a/collects/scribble/scheme.tex b/collects/scribble/scheme.tex new file mode 100644 index 0000000000..d53260bb95 --- /dev/null +++ b/collects/scribble/scheme.tex @@ -0,0 +1,52 @@ + +% Redefine \SColorize to produce B&W Scheme text +\newcommand{\SColorize}[2]{\color{#1}{#2}} + +\newcommand{\inColor}[2]{{\Scribtexttt{\SColorize{#1}{#2}}}} +\definecolor{PaleBlue}{rgb}{0.90,0.90,1.0} +\definecolor{LightGray}{rgb}{0.90,0.90,0.90} +\definecolor{CommentColor}{rgb}{0.76,0.45,0.12} +\definecolor{ParenColor}{rgb}{0.52,0.24,0.14} +\definecolor{IdentifierColor}{rgb}{0.15,0.15,0.50} +\definecolor{ResultColor}{rgb}{0.0,0.0,0.69} +\definecolor{ValueColor}{rgb}{0.13,0.55,0.13} +\definecolor{OutputColor}{rgb}{0.59,0.00,0.59} + +\newcommand{\ScmPlain}[1]{\inColor{black}{#1}} +\newcommand{\ScmKw}[1]{{\SColorize{black}{\Scribtexttt{\textbf{#1}}}}} +\newcommand{\ScmStxLink}[1]{\ScmKw{#1}} +\newcommand{\ScmCmt}[1]{\inColor{CommentColor}{#1}} +\newcommand{\ScmPn}[1]{\inColor{ParenColor}{#1}} +\newcommand{\ScmInBG}[1]{\inColor{ParenColor}{#1}} +\newcommand{\ScmSym}[1]{\inColor{IdentifierColor}{#1}} +\newcommand{\ScmVal}[1]{\inColor{ValueColor}{#1}} +\newcommand{\ScmValLink}[1]{\inColor{blue}{#1}} +\newcommand{\ScmModLink}[1]{\inColor{blue}{#1}} +\newcommand{\ScmRes}[1]{\inColor{ResultColor}{#1}} +\newcommand{\ScmOut}[1]{\inColor{OutputColor}{#1}} +\newcommand{\ScmMeta}[1]{\inColor{IdentifierColor}{#1}} +\newcommand{\ScmMod}[1]{\inColor{black}{#1}} +\newcommand{\ScmRdr}[1]{\inColor{black}{#1}} +\newcommand{\ScmVarCol}[1]{\inColor{IdentifierColor}{#1}} +\newcommand{\ScmVar}[1]{{\ScmVarCol{\textsl{#1}}}} +\newcommand{\ScmErrCol}[1]{\inColor{red}{#1}} +\newcommand{\ScmErr}[1]{{\ScmErrCol{\textrm{\textit{#1}}}}} +\newcommand{\ScmOpt}[1]{#1} +\newcommand{\ScmIn}[1]{\incolorbox{LightGray}{\ScmInBG{#1}}} +\newcommand{\highlighted}[1]{\colorbox{PaleBlue}{\hspace{-0.5ex}\ScmInBG{#1}\hspace{-0.5ex}}} + +\newenvironment{ScmBlk}{}{} +\newenvironment{defmodule}{}{} +\newenvironment{prototype}{}{} +\newenvironment{argcontract}{}{} +\newenvironment{together}{}{} + +\newenvironment{specgrammar}{}{} + + +\newenvironment{SBibliography}{}{} +\newcommand{\bibentry}[1]{\parbox[t]{0.8\linewidth}{#1}} + +\newenvironment{leftindent}{\begin{quote}}{\end{quote}} +\newenvironment{insetpara}{\begin{quote}}{\end{quote}} + diff --git a/collects/scribble/scribble-prefix.tex b/collects/scribble/scribble-prefix.tex index daa2013971..55b52ddb5c 100644 --- a/collects/scribble/scribble-prefix.tex +++ b/collects/scribble/scribble-prefix.tex @@ -1,12 +1,2 @@ % This is the default prefix for Scribble-generated Latex \documentclass{article} - -\parskip=10pt -\parindent=0pt -\partopsep=0pt - -% Adjust margins to match HTML width for -% fixed-width font -\advance \oddsidemargin by -0.15in -\advance \evensidemargin by -0.15in -\advance \textwidth by 0.3in diff --git a/collects/scribble/scribble-style.css b/collects/scribble/scribble-style.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/collects/scribble/scribble-style.tex b/collects/scribble/scribble-style.tex new file mode 100644 index 0000000000..e69de29bb2 diff --git a/collects/scribble/scribble.css b/collects/scribble/scribble.css index 2d680fc860..f2c9ff81dd 100644 --- a/collects/scribble/scribble.css +++ b/collects/scribble/scribble.css @@ -8,20 +8,17 @@ see if any font is set. */ /* Monospace: */ -.maincolumn, .refpara, .tocset, .stt, .hspace, -.schemeinput, .schemereader, .schemeparen, .schememeta, -.schememod, .schemekeyword, .schemevariable, .schemesymbol, -.schemeresult, .schemestdout, .schemecomment, .schemevalue { +.maincolumn, .refpara, .tocset, .stt, .hspace { font-family: monospace; } /* Serif: */ -.main, .refcontent, .tocview, .tocsub, .inheritedlbl, i { +.main, .refcontent, .tocview, .tocsub, i { font-family: serif; } /* Sans-serif: */ -.version { +.version, .versionNoNav { font-family: sans-serif; } @@ -136,6 +133,9 @@ table td { .version { font-size: small; } +.versionNoNav { + font-size: xx-small; /* avoid overlap with author */ +} /* ---------------------------------------- */ /* Margin notes */ @@ -292,122 +292,9 @@ table td { font-size: 70%; } -/* ---------------------------------------- */ -/* 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; -} - -/* ---------------------------------------- */ -/* Scheme text styles */ - -.schemeinput { - color: #cc6633; - background-color: #eeeeee; -} - -.schemeinputbg { - background-color: #eeeeee; -} - -.schemereader { -} - -.schemeparen { - color: #843c24; -} - -.schememeta { - color: #262680; -} - -.schememod { - color: black; -} - -.schemeopt { - color: black; -} - -.schemekeyword { - color: black; - font-weight: bold; -} - -.schemeerror { - color: red; - font-style: italic; -} - -.schemevariable { - color: #262680; - font-style: italic; -} - -.schemesymbol { - color: #262680; -} - -.schemevaluelink { - text-decoration: none; - color: blue; -} - -.schememodlink { - text-decoration: none; - color: blue; -} - -.schemesyntaxlink { - text-decoration: none; - color: black; - font-weight: bold; -} - -.schemeresult { - color: #0000af; -} - -.schemestdout { - color: #960096; -} - -.schemecomment { - color: #c2741f; -} - -.schemevalue { - color: #228b22; -} - /* ---------------------------------------- */ /* Some inline styles */ -.leftindent { - margin-left: 1em; - margin-right: 0em; -} - -.insetpara { - margin-left: 1em; - margin-right: 1em; -} - .indexlink { text-decoration: none; } @@ -437,52 +324,15 @@ ol ol ol ol { list-style-type: upper-alpha; } i { } +.SubFlow { + display: block; +} + .boxed { width: 100%; background-color: #E8E8FF; } -.inlinetop{ - display: inline; - vertical-align: text-top; -} - -.together { - width: 100%; -} - -.prototype td { - vertical-align: text-top; -} -.longprototype td { - vertical-align: bottom; -} - -.schemeblock td { - vertical-align: baseline; -} - -.argcontract td { - vertical-align: text-top; -} - -.ghost { - color: white; -} - -.highlighted { - background-color: #ddddff; -} - -.defmodule { - width: 100%; - background-color: #F5F5DC; -} - -.specgrammar { - float: right; -} - .hspace { } @@ -490,14 +340,6 @@ i { font-style: oblique; } -.inferencetop td { - border-bottom: 1px solid black; - text-align: center; -} -.inferencebottom td { - text-align: center; -} - .badlink { text-decoration: underline; color: red; @@ -518,10 +360,6 @@ i { .techinside:hover { color: blue; } .techoutside:hover>.techinside { color: inherit; } -.SBibliography td { - vertical-align: text-top; -} - .SCentered { text-align: center; } @@ -531,10 +369,14 @@ i { margin-right: 0.3em; } -.smaller{ +.Smaller{ font-size: 82%; } +.Larger{ + font-size: 122%; +} + /* A hack, inserted to break some Scheme ids: */ .mywbr { width: 0; @@ -550,16 +392,22 @@ i { border: 0; } -.author { +.SAuthorListBox { position: relative; float: right; left: 2em; - top: -3em; + top: -2.5em; height: 0em; - width: 23em; /* very wide to keep author names on separate lines */ - margin: 0em -23em 0em 0em; + width: 13em; + margin: 0em -13em 0em 0em; +} +.SAuthorList { font-size: 82%; } -.author:before { +.SAuthorList:before { content: "by "; } +.author { + display: inline; + white-space: nowrap; +} \ No newline at end of file diff --git a/collects/scribble/scribble.tex b/collects/scribble/scribble.tex index 8cee8cb9e0..d5caa7cef4 100644 --- a/collects/scribble/scribble.tex +++ b/collects/scribble/scribble.tex @@ -11,47 +11,36 @@ \usepackage[usenames,dvipsnames]{color} \hypersetup{bookmarks=true,bookmarksopen=true,bookmarksnumbered=true} -\newcommand{\SColorize}[2]{\color{#1}{#2}} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Configuration that is especially meant to be overridden: -\newcommand{\inColor}[2]{{\Scribtexttt{\SColorize{#1}{#2}}}} -\definecolor{CommentColor}{rgb}{0.76,0.45,0.12} -\definecolor{ParenColor}{rgb}{0.52,0.24,0.14} -\definecolor{IdentifierColor}{rgb}{0.15,0.15,0.50} -\definecolor{ResultColor}{rgb}{0.0,0.0,0.69} -\definecolor{ValueColor}{rgb}{0.13,0.55,0.13} -\definecolor{OutputColor}{rgb}{0.59,0.00,0.59} -\definecolor{PaleBlue}{rgb}{0.90,0.90,1.0} -\definecolor{LightGray}{rgb}{0.90,0.90,0.90} +% Inserted before every ``chapter'', useful for starting each one on a new page: +\newcommand{\sectionNewpage}{} +% Hooks for actions within the `document' environment: +\newcommand{\preDoc}{} +\newcommand{\postDoc}{} + +% Generated by `secref'; first arg is section number, second is section title: +\newcommand{\BookRef}[2]{\emph{#2}} +\newcommand{\ChapRef}[2]{\SecRef{#1}{#2}} +\newcommand{\SecRef}[2]{section~#1} +% Generated by `Secref': +\newcommand{\BookRefUC}[2]{\BookRef{#1}{#2}} +\newcommand{\ChapRefUC}[2]{\SecRefUC{#1}{#2}} +\newcommand{\SecRefUC}[2]{Section~#1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Fonts + +% Font commands used by generated text: \newcommand{\Scribtexttt}[1]{{\texttt{#1}}} -\newcommand{\schemeplain}[1]{\inColor{black}{#1}} -\newcommand{\schemekeyword}[1]{{\SColorize{black}{\Scribtexttt{\textbf{#1}}}}} -\newcommand{\schemesyntaxlink}[1]{\schemekeyword{#1}} -\newcommand{\schemecomment}[1]{\inColor{CommentColor}{#1}} -\newcommand{\schemeparen}[1]{\inColor{ParenColor}{#1}} -\newcommand{\schemeinputbg}[1]{\inColor{ParenColor}{#1}} -\newcommand{\schemesymbol}[1]{\inColor{IdentifierColor}{#1}} -\newcommand{\schemevalue}[1]{\inColor{ValueColor}{#1}} -\newcommand{\schemevaluelink}[1]{\inColor{blue}{#1}} -\newcommand{\schememodlink}[1]{\inColor{blue}{#1}} -\newcommand{\schemeresult}[1]{\inColor{ResultColor}{#1}} -\newcommand{\schemestdout}[1]{\inColor{OutputColor}{#1}} -\newcommand{\schememeta}[1]{\inColor{IdentifierColor}{#1}} -\newcommand{\schememod}[1]{\inColor{black}{#1}} -\newcommand{\schemereader}[1]{\inColor{black}{#1}} -\newcommand{\schemevariablecol}[1]{\inColor{IdentifierColor}{#1}} -\newcommand{\schemevariable}[1]{{\schemevariablecol{\textsl{#1}}}} -\newcommand{\schemeerrorcol}[1]{\inColor{red}{#1}} -\newcommand{\schemeerror}[1]{{\schemeerrorcol{\textrm{\textit{#1}}}}} -\newcommand{\schemeopt}[1]{#1} \newcommand{\textsub}[1]{$_{\hbox{\textsmaller{#1}}}$} \newcommand{\textsuper}[1]{$^{\hbox{\textsmaller{#1}}}$} \newcommand{\intextcolor}[2]{\textcolor{#1}{#2}} \newcommand{\intextrgbcolor}[2]{\textcolor[rgb]{#1}{#2}} \newcommand{\incolorbox}[2]{{\fboxrule=0pt\fboxsep=0pt\colorbox{#1}{#2}}} \newcommand{\inrgbcolorbox}[2]{{\fboxrule=0pt\fboxsep=0pt\colorbox[rgb]{#1}{#2}}} -\newcommand{\schemeinput}[1]{\incolorbox{LightGray}{\schemeinputbg{#1}}} -\newcommand{\highlighted}[1]{\colorbox{PaleBlue}{\hspace{-0.5ex}\schemeinputbg{#1}\hspace{-0.5ex}}} \newcommand{\plainlink}[1]{#1} \newcommand{\techoutside}[1]{#1} \newcommand{\techinside}[1]{#1} @@ -59,65 +48,75 @@ \newcommand{\indexlink}[1]{#1} \newcommand{\noborder}[1]{#1} \newcommand{\imageleft}[1]{} % drop it -\renewcommand{\smaller}[1]{\textsmaller{#1}} +\newcommand{\Smaller}[1]{\textsmaller{#1}} +\newcommand{\Larger}[1]{\textlarger{#1}} \newcommand{\planetName}[1]{PLane\hspace{-0.1ex}T} - -\newcommand{\refpara}[1]{\marginpar{\raggedright \footnotesize #1}} -\newenvironment{refcolumn}{}{} -\newenvironment{refcontent}{}{} - -\newcommand{\titleAndEmptyVersion}[2]{\title{#1}\maketitle} -\newcommand{\titleAndVersion}[2]{\title{#1\\{\normalsize Version #2}}\maketitle} - -\newcommand{\sectionNewpage}{\newpage} - -\newcommand{\preDoc}{\sloppy} -\newcommand{\postDoc}{} - \newcommand{\slant}[1]{{\textsl{#1}}} -\newenvironment{leftindent}{\begin{quote}}{\end{quote}} -\newenvironment{insetpara}{\begin{quote}}{\end{quote}} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Tables -\newcommand{\bibentry}[1]{\parbox[t]{0.8\linewidth}{#1}} - -% stabular seems to be the lesser of all page-breaking table evironments +% The `stabular' environment seems to be the lesser of evils among +% page-breaking table environments: \newenvironment{bigtabular}{\begin{stabular}}{\end{stabular}} -% used to keep the horizontal line for a definition on the same page: +% Used to keep the horizontal line for a definition on the same page: \newcommand{\SEndFirstHead}[0]{ \nopagebreak \\ } -% attempts to correct weirdness when a table is the first thing in +% Corrects weirdness when a table is the first thing in % an itemization: \newcommand{\bigtableinlinecorrect}[0]{~ \vspace{-\baselineskip}\vspace{\parskip}} -% used to indent the table correctly in an itemization, since that's -% one of the things stabular gets wrong +% Used to indent the table correctly in an itemization, since that's +% one of the things stabular gets wrong: \newlength{\stabLeft} \newcommand{\bigtableleftpad}{\hspace{\stabLeft}} \newcommand{\atItemizeStart}[0]{\addtolength{\stabLeft}{\labelsep} \addtolength{\stabLeft}{\labelwidth}} +% For a single-column table in simple environments, it's better to +% use the `list' environment instead of `stabular'. \newenvironment{SingleColumn}{\begin{list}{}{\topsep=0pt\partopsep=0pt% \listparindent=0pt\itemindent=0pt\labelwidth=0pt\leftmargin=0pt\rightmargin=0pt% \itemsep=0pt\parsep=0pt}\item}{\end{list}} -\newenvironment{schemeblock}{}{} -\newenvironment{defmodule}{}{} -\newenvironment{prototype}{}{} -\newenvironment{argcontract}{}{} -\newenvironment{together}{}{} -\newenvironment{SBibliography}{}{} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Etc. +% Default style for a nested flow: +\newenvironment{Subflow}{\begin{list}{}{\topsep=0pt\partopsep=0pt% +\listparindent=0pt\itemindent=0pt\labelwidth=0pt\leftmargin=0pt\rightmargin=0pt% +\itemsep=0pt}\item}{\end{list}} + +% The 'inset neested-flow style uses the `quote' environment + +% The 'compact itemization style: \newenvironment{compact}{\begin{itemize}}{\end{itemize}} \newcommand{\compactItem}[1]{\item #1} -\newcommand{\SecRef}[2]{\S#1 ``#2''} +% The nested-flow style for `centerline': +\newenvironment{SCentered}{\begin{trivlist}\item \centering}{\end{trivlist}} +% The \refpara command corresponds to `margin-note'. The +% refcolumn and refcontent environments also wrap the note, +% because they simplify the CSS side. +\newcommand{\refpara}[1]{\marginpar{\raggedright \footnotesize #1}} +\newenvironment{refcolumn}{}{} +\newenvironment{refcontent}{}{} + +% Macros used by `title' and `author': +\newcommand{\titleAndVersionAndAuthors}[3]{\title{#1\\{\normalsize Version #2}}\author{#3}\maketitle} +\newcommand{\titleAndVersionAndEmptyAuthors}[3]{\title{#1\\{\normalsize Version #2}}#3\maketitle} +\newcommand{\titleAndEmptyVersionAndAuthors}[3]{\title{#1}\author{#3}\maketitle} +\newcommand{\titleAndEmptyVersionAndEmptyAuthors}[3]{\title{#1}\maketitle} +\newcommand{\SAuthor}[1]{#1} +\newcommand{\SAuthorSep}[1]{\qquad} + +% Used for parts with the 'hidden style variant: \newcommand{\sectionhidden}[1]{\section{#1}} \newcommand{\subsectionhidden}[1]{\subsection{#1}} \newcommand{\subsubsectionhidden}[1]{\subsubsection{#1}} -\newenvironment{SCentered}{\begin{trivlist}\item \centering}{\end{trivlist}} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Scribble then generates the following: % diff --git a/collects/scribble/sigplan.ss b/collects/scribble/sigplan.ss new file mode 100644 index 0000000000..4999d26d26 --- /dev/null +++ b/collects/scribble/sigplan.ss @@ -0,0 +1,109 @@ +#lang scheme/base +(require setup/main-collects + scribble/core + scribble/base + scribble/decode + scribble/html-variants + scribble/latex-variants + (for-syntax scheme/base)) + +(provide preprint + abstract include-abstract + authorinfo + conferenceinfo copyrightyear copyrightdata + category terms keywords) + +(define-syntax (preprint stx) + (raise-syntax-error #f + "option must appear on the same line as `#lang scribble/sigplan'" + stx)) + +(define sigplan-extras + (let ([abs (lambda (s) + (path->main-collects-relative + (build-path (collection-path "scribble") "sigplan" s)))]) + (list + (make-css-addition (abs "sigplan.css")) + (make-tex-addition (abs "sigplan.tex"))))) + +;; ---------------------------------------- +;; Abstracts: + +(define abstract-style (make-style "abstract" sigplan-extras)) + +(define (abstract . strs) + (make-nested-flow + abstract-style + (decode-flow strs))) + +(define (extract-abstract p) + (unless (part? p) + (error 'include-abstract "doc binding is not a part: ~e" p)) + (unless (null? (part-parts p)) + (error 'include-abstract "abstract part has sub-parts: ~e" (part-parts p))) + (when (part-title-content p) + (error 'include-abstract "abstract part has title content: ~e" (part-title-content p))) + (part-blocks p)) + +(define-syntax-rule (include-abstract mp) + (begin + (require (only-in mp [doc abstract-doc])) + (make-nested-flow abstract-style (extract-abstract abstract-doc)))) + +;; ---------------------------------------- +;; Authors and conference info: + +(define (authorinfo name affiliation e-mail) + (author + (make-multiarg-element + (make-style "SAuthorinfo"sigplan-extras) + (list + (make-element #f (decode-content (list name))) + (make-element (make-style "SAuthorPlace" sigplan-extras) + (decode-content (list affiliation))) + (make-element (make-style "SAuthorEmail" sigplan-extras) + (decode-content (list e-mail))))))) + +(define (conferenceinfo what where) + (make-paragraph + (make-style 'pretitle null) + (make-multiarg-element + (make-style "SConferenceInfo" sigplan-extras) + (list + (make-element #f (decode-content (list what))) + (make-element #f (decode-content (list where))))))) + +(define (copyrightyear . when) + (make-paragraph + (make-style 'pretitle null) + (make-element + (make-style "SCopyrightYear" sigplan-extras) + (decode-content when)))) + +(define (copyrightdata . what) + (make-paragraph + (make-style 'pretitle null) + (make-element + (make-style "SCopyrightData" sigplan-extras) + (decode-content what)))) + +;; ---------------------------------------- +;; Categories, terms, and keywords: + +(define (category sec title sub [more #f]) + (make-multiarg-element + (make-style (format "SCategory~a" (if more "Plus" "")) sigplan-extras) + (append + (list + (make-element #f (decode-content (list sec))) + (make-element #f (decode-content (list title))) + (make-element #f (decode-content (list sub)))) + (if more + (list (make-element #f (decode-content (list more)))) + null)))) + +(define (terms . str) + (make-element (make-style "STerms" sigplan-extras) (decode-content str))) + +(define (keywords . str) + (make-element (make-style "SKeywords" sigplan-extras) (decode-content str))) diff --git a/collects/scribble/sigplan/lang.ss b/collects/scribble/sigplan/lang.ss new file mode 100644 index 0000000000..cdaaa287c1 --- /dev/null +++ b/collects/scribble/sigplan/lang.ss @@ -0,0 +1,41 @@ +#lang scheme/base +(require scribble/doclang + scribble/core + scribble/base + scribble/decode + scribble/sigplan + "../private/defaults.ss" + (for-syntax scheme/base)) +(provide (except-out (all-from-out scribble/doclang) #%module-begin) + (all-from-out scribble/sigplan) + (all-from-out scribble/base) + (rename-out [module-begin #%module-begin])) + +(define-syntax (module-begin stx) + (syntax-case* stx (preprint) (lambda (a b) (eq? (syntax-e a) (syntax-e b))) + [(_ id ws . body) + ;; Skip intraline whitespace to find options: + (and (string? (syntax-e #'ws)) + (regexp-match? #rx"^ *$" (syntax-e #'ws))) + #'(module-begin id . body)] + [(_ id preprint . body) + #'(#%module-begin id (post-process #t) () . body)] + [(_ id . body) + #'(#%module-begin id (post-process #f) () . body)])) + +(define ((post-process preprint?) doc) + (add-sigplan-styles + (add-defaults doc + (string->bytes/utf-8 + (format "\\documentclass~a{sigplanconf}\n\\usepackage{times}\n\\usepackage{qcourier}\n" + (if preprint? "[preprint]" ""))) + (scribble-file "sigplan/style.tex") + (list (scribble-file "sigplan/sigplanconf.cls")) + #f))) + +(define (add-sigplan-styles doc) + ;; Ensure that "sigplan.tex" is used, since "style.tex" + ;; re-defines commands. + (struct-copy part doc [to-collect + (cons (terms) + (part-to-collect doc))])) diff --git a/collects/scribble/sigplan/lang/reader.ss b/collects/scribble/sigplan/lang/reader.ss new file mode 100644 index 0000000000..f0fd21629f --- /dev/null +++ b/collects/scribble/sigplan/lang/reader.ss @@ -0,0 +1,10 @@ +#lang s-exp syntax/module-reader + +scribble/sigplan/lang + +#:read scribble:read-inside +#:read-syntax scribble:read-syntax-inside +#:whole-body-readers? #t +#:wrapper1 (lambda (t) (cons 'doc (t))) + +(require (prefix-in scribble: "../../reader.ss")) diff --git a/collects/scribble/sigplan/sigplan.css b/collects/scribble/sigplan/sigplan.css new file mode 100644 index 0000000000..1d7a936655 --- /dev/null +++ b/collects/scribble/sigplan/sigplan.css @@ -0,0 +1,8 @@ + +/* Support for styles in scribble/sigplan */ + +.SAuthorPlace, .SAuthorEmail, +.SConferenceInfo, .SCopyrightYear, .SCopyrightData, +.SCategory, .SCategoryPlus, .STerms, .SKeywords { + display: none; +} diff --git a/collects/scribble/sigplan/sigplan.tex b/collects/scribble/sigplan/sigplan.tex new file mode 100644 index 0000000000..b9c81c6468 --- /dev/null +++ b/collects/scribble/sigplan/sigplan.tex @@ -0,0 +1,18 @@ + +% Support for styles in scribble/sigplan + +% These are replaced by scribble/sigplan/style.tex, +% which is used in combination with sigplanconf.sty + +\newcommand{\SAuthorinfo}[3]{#1} +\newcommand{\SAuthorPlace}[1]{#1} +\newcommand{\SAuthorEmail}[1]{#1} + +\newcommand{\SConferenceInfo}[2]{} +\newcommand{\SCopyrightYear}[1]{} +\newcommand{\SCopyrightData}[1]{} + +\newcommand{\SCategory}[3]{} +\newcommand{\SCategoryPlus}[4]{} +\newcommand{\STerms}[1]{} +\newcommand{\SKeywords}[1]{} diff --git a/collects/scribble/sigplan/sigplanconf.cls b/collects/scribble/sigplan/sigplanconf.cls new file mode 100644 index 0000000000..a5891f7561 --- /dev/null +++ b/collects/scribble/sigplan/sigplanconf.cls @@ -0,0 +1,1222 @@ +%----------------------------------------------------------------------------- +% +% LaTeX Class/Style File +% +% Name: sigplanconf.cls +% Purpose: A LaTeX 2e class file for SIGPLAN conference proceedings. +% This class file supercedes acm_proc_article-sp, +% sig-alternate, and sigplan-proc. +% +% Author: Paul C. Anagnostopoulos +% Windfall Software +% 978 371-2316 +% paul@windfall.com +% +% Created: 12 September 2004 +% +% Revisions: See end of file. +% +%----------------------------------------------------------------------------- + + +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesClass{sigplanconf}[2009/04/29 v1.9 ACM SIGPLAN Proceedings] + +% The following few pages contain LaTeX programming extensions adapted +% from the ZzTeX macro package. + +% Token Hackery +% ----- ------- + + +\def \@expandaftertwice {\expandafter\expandafter\expandafter} +\def \@expandafterthrice {\expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter} + +% This macro discards the next token. + +\def \@discardtok #1{}% token + +% This macro removes the `pt' following a dimension. + +{\catcode `\p = 12 \catcode `\t = 12 + +\gdef \@remover #1pt{#1} + +} % \catcode + +% This macro extracts the contents of a macro and returns it as plain text. +% Usage: \expandafter\@defof \meaning\macro\@mark + +\def \@defof #1:->#2\@mark{#2} + +% Control Sequence Names +% ------- -------- ----- + + +\def \@name #1{% {\tokens} + \csname \expandafter\@discardtok \string#1\endcsname} + +\def \@withname #1#2{% {\command}{\tokens} + \expandafter#1\csname \expandafter\@discardtok \string#2\endcsname} + +% Flags (Booleans) +% ----- ---------- + +% The boolean literals \@true and \@false are appropriate for use with +% the \if command, which tests the codes of the next two characters. + +\def \@true {TT} +\def \@false {FL} + +\def \@setflag #1=#2{\edef #1{#2}}% \flag = boolean + +% IF and Predicates +% -- --- ---------- + +% A "predicate" is a macro that returns \@true or \@false as its value. +% Such values are suitable for use with the \if conditional. For example: +% +% \if \@oddp{\x} \else \fi + +% A predicate can be used with \@setflag as follows: +% +% \@setflag \flag = {} + +% Here are the predicates for TeX's repertoire of conditional +% commands. These might be more appropriately interspersed with +% other definitions in this module, but what the heck. +% Some additional "obvious" predicates are defined. + +\def \@eqlp #1#2{\ifnum #1 = #2\@true \else \@false \fi} +\def \@neqlp #1#2{\ifnum #1 = #2\@false \else \@true \fi} +\def \@lssp #1#2{\ifnum #1 < #2\@true \else \@false \fi} +\def \@gtrp #1#2{\ifnum #1 > #2\@true \else \@false \fi} +\def \@zerop #1{\ifnum #1 = 0\@true \else \@false \fi} +\def \@onep #1{\ifnum #1 = 1\@true \else \@false \fi} +\def \@posp #1{\ifnum #1 > 0\@true \else \@false \fi} +\def \@negp #1{\ifnum #1 < 0\@true \else \@false \fi} +\def \@oddp #1{\ifodd #1\@true \else \@false \fi} +\def \@evenp #1{\ifodd #1\@false \else \@true \fi} +\def \@rangep #1#2#3{\if \@orp{\@lssp{#1}{#2}}{\@gtrp{#1}{#3}}\@false \else + \@true \fi} +\def \@tensp #1{\@rangep{#1}{10}{19}} + +\def \@dimeqlp #1#2{\ifdim #1 = #2\@true \else \@false \fi} +\def \@dimneqlp #1#2{\ifdim #1 = #2\@false \else \@true \fi} +\def \@dimlssp #1#2{\ifdim #1 < #2\@true \else \@false \fi} +\def \@dimgtrp #1#2{\ifdim #1 > #2\@true \else \@false \fi} +\def \@dimzerop #1{\ifdim #1 = 0pt\@true \else \@false \fi} +\def \@dimposp #1{\ifdim #1 > 0pt\@true \else \@false \fi} +\def \@dimnegp #1{\ifdim #1 < 0pt\@true \else \@false \fi} + +\def \@vmodep {\ifvmode \@true \else \@false \fi} +\def \@hmodep {\ifhmode \@true \else \@false \fi} +\def \@mathmodep {\ifmmode \@true \else \@false \fi} +\def \@textmodep {\ifmmode \@false \else \@true \fi} +\def \@innermodep {\ifinner \@true \else \@false \fi} + +\long\def \@codeeqlp #1#2{\if #1#2\@true \else \@false \fi} + +\long\def \@cateqlp #1#2{\ifcat #1#2\@true \else \@false \fi} + +\long\def \@tokeqlp #1#2{\ifx #1#2\@true \else \@false \fi} +\long\def \@xtokeqlp #1#2{\expandafter\ifx #1#2\@true \else \@false \fi} + +\long\def \@definedp #1{% + \expandafter\ifx \csname \expandafter\@discardtok \string#1\endcsname + \relax \@false \else \@true \fi} + +\long\def \@undefinedp #1{% + \expandafter\ifx \csname \expandafter\@discardtok \string#1\endcsname + \relax \@true \else \@false \fi} + +\def \@emptydefp #1{\ifx #1\@empty \@true \else \@false \fi}% {\name} + +\let \@emptylistp = \@emptydefp + +\long\def \@emptyargp #1{% {#n} + \@empargp #1\@empargq\@mark} +\long\def \@empargp #1#2\@mark{% + \ifx #1\@empargq \@true \else \@false \fi} +\def \@empargq {\@empargq} + +\def \@emptytoksp #1{% {\tokenreg} + \expandafter\@emptoksp \the#1\@mark} + +\long\def \@emptoksp #1\@mark{\@emptyargp{#1}} + +\def \@voidboxp #1{\ifvoid #1\@true \else \@false \fi} +\def \@hboxp #1{\ifhbox #1\@true \else \@false \fi} +\def \@vboxp #1{\ifvbox #1\@true \else \@false \fi} + +\def \@eofp #1{\ifeof #1\@true \else \@false \fi} + + +% Flags can also be used as predicates, as in: +% +% \if \flaga \else \fi + + +% Now here we have predicates for the common logical operators. + +\def \@notp #1{\if #1\@false \else \@true \fi} + +\def \@andp #1#2{\if #1% + \if #2\@true \else \@false \fi + \else + \@false + \fi} + +\def \@orp #1#2{\if #1% + \@true + \else + \if #2\@true \else \@false \fi + \fi} + +\def \@xorp #1#2{\if #1% + \if #2\@false \else \@true \fi + \else + \if #2\@true \else \@false \fi + \fi} + +% Arithmetic +% ---------- + +\def \@increment #1{\advance #1 by 1\relax}% {\count} + +\def \@decrement #1{\advance #1 by -1\relax}% {\count} + +% Options +% ------- + + +\@setflag \@blockstyle = \@false +\@setflag \@copyrightwanted = \@true +\@setflag \@explicitsize = \@false +\@setflag \@mathtime = \@false +\@setflag \@natbib = \@false +\@setflag \@ninepoint = \@true +\newcount{\@numheaddepth} \@numheaddepth = 3 +\@setflag \@onecolumn = \@false +\@setflag \@preprint = \@false +\@setflag \@reprint = \@false +\@setflag \@tenpoint = \@false +\@setflag \@times = \@false + +% Note that all the dangerous article class options are trapped. + +\DeclareOption{9pt}{\@setflag \@ninepoint = \@true + \@setflag \@explicitsize = \@true} + +\DeclareOption{10pt}{\PassOptionsToClass{10pt}{article}% + \@setflag \@ninepoint = \@false + \@setflag \@tenpoint = \@true + \@setflag \@explicitsize = \@true} + +\DeclareOption{11pt}{\PassOptionsToClass{11pt}{article}% + \@setflag \@ninepoint = \@false + \@setflag \@explicitsize = \@true} + +\DeclareOption{12pt}{\@unsupportedoption{12pt}} + +\DeclareOption{a4paper}{\@unsupportedoption{a4paper}} + +\DeclareOption{a5paper}{\@unsupportedoption{a5paper}} + +\DeclareOption{b5paper}{\@unsupportedoption{b5paper}} + +\DeclareOption{blockstyle}{\@setflag \@blockstyle = \@true} + +\DeclareOption{cm}{\@setflag \@times = \@false} + +\DeclareOption{computermodern}{\@setflag \@times = \@false} + +\DeclareOption{executivepaper}{\@unsupportedoption{executivepaper}} + +\DeclareOption{indentedstyle}{\@setflag \@blockstyle = \@false} + +\DeclareOption{landscape}{\@unsupportedoption{landscape}} + +\DeclareOption{legalpaper}{\@unsupportedoption{legalpaper}} + +\DeclareOption{letterpaper}{\@unsupportedoption{letterpaper}} + +\DeclareOption{mathtime}{\@setflag \@mathtime = \@true} + +\DeclareOption{natbib}{\@setflag \@natbib = \@true} + +\DeclareOption{nocopyrightspace}{\@setflag \@copyrightwanted = \@false} + +\DeclareOption{notitlepage}{\@unsupportedoption{notitlepage}} + +\DeclareOption{numberedpars}{\@numheaddepth = 4} + +%%%\DeclareOption{onecolumn}{\@setflag \@onecolumn = \@true} + +\DeclareOption{preprint}{\@setflag \@preprint = \@true} + +\DeclareOption{reprint}{\@setflag \@reprint = \@true} + +\DeclareOption{times}{\@setflag \@times = \@true} + +\DeclareOption{titlepage}{\@unsupportedoption{titlepage}} + +\DeclareOption{twocolumn}{\@setflag \@onecolumn = \@false} + +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} + +\ExecuteOptions{9pt,indentedstyle,times} +\@setflag \@explicitsize = \@false +\ProcessOptions + +\if \@onecolumn + \if \@notp{\@explicitsize}% + \@setflag \@ninepoint = \@false + \PassOptionsToClass{11pt}{article}% + \fi + \PassOptionsToClass{twoside,onecolumn}{article} +\else + \PassOptionsToClass{twoside,twocolumn}{article} +\fi +\LoadClass{article} + +\def \@unsupportedoption #1{% + \ClassError{proc}{The standard '#1' option is not supported.}} + +% This can be used with the 'reprint' option to get the final folios. + +\def \setpagenumber #1{% + \setcounter{page}{#1}} + +\AtEndDocument{\label{sigplanconf@finalpage}} + +% Utilities +% --------- + + +\newcommand{\setvspace}[2]{% + #1 = #2 + \advance #1 by -1\parskip} + +% Document Parameters +% -------- ---------- + + +% Page: + +\setlength{\hoffset}{-1in} +\setlength{\voffset}{-1in} + +\setlength{\topmargin}{1in} +\setlength{\headheight}{0pt} +\setlength{\headsep}{0pt} + +\if \@onecolumn + \setlength{\evensidemargin}{.75in} + \setlength{\oddsidemargin}{.75in} +\else + \setlength{\evensidemargin}{.75in} + \setlength{\oddsidemargin}{.75in} +\fi + +% Text area: + +\newdimen{\standardtextwidth} +\setlength{\standardtextwidth}{42pc} + +\if \@onecolumn + \setlength{\textwidth}{40.5pc} +\else + \setlength{\textwidth}{\standardtextwidth} +\fi + +\setlength{\topskip}{8pt} +\setlength{\columnsep}{2pc} +\setlength{\textheight}{54.5pc} + +% Running foot: + +\setlength{\footskip}{30pt} + +% Paragraphs: + +\if \@blockstyle + \setlength{\parskip}{5pt plus .1pt minus .5pt} + \setlength{\parindent}{0pt} +\else + \setlength{\parskip}{0pt} + \setlength{\parindent}{12pt} +\fi + +\setlength{\lineskip}{.5pt} +\setlength{\lineskiplimit}{\lineskip} + +\frenchspacing +\pretolerance = 400 +\tolerance = \pretolerance +\setlength{\emergencystretch}{5pt} +\clubpenalty = 10000 +\widowpenalty = 10000 +\setlength{\hfuzz}{.5pt} + +% Standard vertical spaces: + +\newskip{\standardvspace} +\setvspace{\standardvspace}{5pt plus 1pt minus .5pt} + +% Margin paragraphs: + +\setlength{\marginparwidth}{36pt} +\setlength{\marginparsep}{2pt} +\setlength{\marginparpush}{8pt} + + +\setlength{\skip\footins}{8pt plus 3pt minus 1pt} +\setlength{\footnotesep}{9pt} + +\renewcommand{\footnoterule}{% + \hrule width .5\columnwidth height .33pt depth 0pt} + +\renewcommand{\@makefntext}[1]{% + \noindent \@makefnmark \hspace{1pt}#1} + +% Floats: + +\setcounter{topnumber}{4} +\setcounter{bottomnumber}{1} +\setcounter{totalnumber}{4} + +\renewcommand{\fps@figure}{tp} +\renewcommand{\fps@table}{tp} +\renewcommand{\topfraction}{0.90} +\renewcommand{\bottomfraction}{0.30} +\renewcommand{\textfraction}{0.10} +\renewcommand{\floatpagefraction}{0.75} + +\setcounter{dbltopnumber}{4} + +\renewcommand{\dbltopfraction}{\topfraction} +\renewcommand{\dblfloatpagefraction}{\floatpagefraction} + +\setlength{\floatsep}{18pt plus 4pt minus 2pt} +\setlength{\textfloatsep}{18pt plus 4pt minus 3pt} +\setlength{\intextsep}{10pt plus 4pt minus 3pt} + +\setlength{\dblfloatsep}{18pt plus 4pt minus 2pt} +\setlength{\dbltextfloatsep}{20pt plus 4pt minus 3pt} + +% Miscellaneous: + +\errorcontextlines = 5 + +% Fonts +% ----- + + +\if \@times + \renewcommand{\rmdefault}{ptm}% + \if \@mathtime + \usepackage[mtbold,noTS1]{mathtime}% + \else +%%% \usepackage{mathptm}% + \fi +\else + \relax +\fi + +\if \@ninepoint + +\renewcommand{\normalsize}{% + \@setfontsize{\normalsize}{9pt}{10pt}% + \setlength{\abovedisplayskip}{5pt plus 1pt minus .5pt}% + \setlength{\belowdisplayskip}{\abovedisplayskip}% + \setlength{\abovedisplayshortskip}{3pt plus 1pt minus 2pt}% + \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} + +\renewcommand{\tiny}{\@setfontsize{\tiny}{5pt}{6pt}} + +\renewcommand{\scriptsize}{\@setfontsize{\scriptsize}{7pt}{8pt}} + +\renewcommand{\small}{% + \@setfontsize{\small}{8pt}{9pt}% + \setlength{\abovedisplayskip}{4pt plus 1pt minus 1pt}% + \setlength{\belowdisplayskip}{\abovedisplayskip}% + \setlength{\abovedisplayshortskip}{2pt plus 1pt}% + \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} + +\renewcommand{\footnotesize}{% + \@setfontsize{\footnotesize}{8pt}{9pt}% + \setlength{\abovedisplayskip}{4pt plus 1pt minus .5pt}% + \setlength{\belowdisplayskip}{\abovedisplayskip}% + \setlength{\abovedisplayshortskip}{2pt plus 1pt}% + \setlength{\belowdisplayshortskip}{\abovedisplayshortskip}} + +\renewcommand{\large}{\@setfontsize{\large}{11pt}{13pt}} + +\renewcommand{\Large}{\@setfontsize{\Large}{14pt}{18pt}} + +\renewcommand{\LARGE}{\@setfontsize{\LARGE}{18pt}{20pt}} + +\renewcommand{\huge}{\@setfontsize{\huge}{20pt}{25pt}} + +\renewcommand{\Huge}{\@setfontsize{\Huge}{25pt}{30pt}} + +\else\if \@tenpoint + +\relax + +\else + +\relax + +\fi\fi + +% Abstract +% -------- + + +\renewenvironment{abstract}{% + \section*{Abstract}% + \normalsize}{% + } + +% Bibliography +% ------------ + + +\renewenvironment{thebibliography}[1] + {\section*{\refname + \@mkboth{\MakeUppercase\refname}{\MakeUppercase\refname}}% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \@openbib@code + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \bibfont + \softraggedright%%%\sloppy + \clubpenalty4000 + \@clubpenalty \clubpenalty + \widowpenalty4000% + \sfcode`\.\@m} + {\def\@noitemerr + {\@latex@warning{Empty `thebibliography' environment}}% + \endlist} + +\if \@natbib + +\usepackage{natbib} +\setlength{\bibsep}{3pt plus .5pt minus .25pt} +\bibpunct{[}{]}{,}{A}{}{,} +\let \cite = \citep + +\fi + +\def \bibfont {\small} + +% Categories +% ---------- + + +\@setflag \@firstcategory = \@true + +\newcommand{\category}[3]{% + \if \@firstcategory + \paragraph*{Categories and Subject Descriptors}% + \@setflag \@firstcategory = \@false + \else + \unskip ;\hspace{.75em}% + \fi + \@ifnextchar [{\@category{#1}{#2}{#3}}{\@category{#1}{#2}{#3}[]}} + +\def \@category #1#2#3[#4]{% + {\let \and = \relax + #1 [\textit{#2}]% + \if \@emptyargp{#4}% + \if \@notp{\@emptyargp{#3}}: #3\fi + \else + :\space + \if \@notp{\@emptyargp{#3}}#3---\fi + \textrm{#4}% + \fi}} + +% Copyright Notice +% --------- ------ + + +\def \ftype@copyrightbox {8} +\def \@toappear {} +\def \@permission {} +\def \@reprintprice {} + + +\def \@copyrightspace {% + \@float{copyrightbox}[b]% + \vbox to 1in{% + \vfill + \parbox[b]{20pc}{% + \scriptsize + \if \@preprint + [Copyright notice will appear here + once 'preprint' option is removed.]\par + \else + \@toappear + \fi + \if \@reprint + \noindent Reprinted from \@conferencename, + \@proceedings, + \@conferenceinfo, + pp.~\number\thepage--\pageref{sigplanconf@finalpage}.\par + \fi}}% + \end@float} + +\long\def \toappear #1{% + \def \@toappear {#1}} + +\toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + \noindent Copyright \copyright\ \@copyrightyear\ ACM \@copyrightdata + \dots \@reprintprice\par} + +\newcommand{\reprintprice}[1]{% + \gdef \@reprintprice {#1}} +\reprintprice{\$10.00} + +\newcommand{\permission}[1]{% + \gdef \@permission {#1}} + +\permission{% + Permission to make digital or hard copies of all or + part of this work for personal or classroom use is granted without + fee provided that copies are not made or distributed for profit or + commercial advantage and that copies bear this notice and the full + citation on the first page. To copy otherwise, to republish, to + post on servers or to redistribute to lists, requires prior specific + permission and/or a fee.} + +% Here we have some alternate permission statements and copyright lines: + +\newcommand{\ACMCanadapermission}{% + \permission{% + Copyright \@copyrightyear\ Association for Computing Machinery. + ACM acknowledges that + this contribution was authored or co-authored by an affiliate of the + National Research Council of Canada (NRC). + As such, the Crown in Right of + Canada retains an equal interest in the copyright, however granting + nonexclusive, royalty-free right to publish or reproduce this article, + or to allow others to do so, provided that clear attribution + is also given to the authors and the NRC.}} + +\newcommand{\ACMUSpermission}{% + \permission{% + Copyright \@copyrightyear\ Association for + Computing Machinery. ACM acknowledges that + this contribution was authored or co-authored + by a contractor or affiliate + of the U.S. Government. As such, the Government retains a nonexclusive, + royalty-free right to publish or reproduce this article, + or to allow others to do so, for Government purposes only.}} + +\newcommand{\authorpermission}{% + \permission{% + Copyright is held by the author/owner(s).} + \toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + ACM \@copyrightdata.}} + +\newcommand{\Sunpermission}{% + \permission{% + Copyright is held by Sun Microsystems, Inc.}% + \toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + ACM \@copyrightdata.}} + +\newcommand{\USpublicpermission}{% + \permission{% + This paper is authored by an employee(s) of the United States + Government and is in the public domain.}% + \toappear{% + \noindent \@permission \par + \vspace{2pt} + \noindent \textsl{\@conferencename}\quad \@conferenceinfo \par + ACM \@copyrightdata.}} + +% Enunciations +% ------------ + + +\def \@begintheorem #1#2{% {name}{number} + \trivlist + \item[\hskip \labelsep \textsc{#1 #2.}]% + \itshape\selectfont + \ignorespaces} + +\def \@opargbegintheorem #1#2#3{% {name}{number}{title} + \trivlist + \item[% + \hskip\labelsep \textsc{#1\ #2}% + \if \@notp{\@emptyargp{#3}}\nut (#3).\fi]% + \itshape\selectfont + \ignorespaces} + +% Figures +% ------- + + +\@setflag \@caprule = \@true + +\long\def \@makecaption #1#2{% + \addvspace{4pt} + \if \@caprule + \hrule width \hsize height .33pt + \vspace{4pt} + \fi + \setbox \@tempboxa = \hbox{\@setfigurenumber{#1.}\nut #2}% + \if \@dimgtrp{\wd\@tempboxa}{\hsize}% + \noindent \@setfigurenumber{#1.}\nut #2\par + \else + \centerline{\box\@tempboxa}% + \fi} + +\newcommand{\nocaptionrule}{% + \@setflag \@caprule = \@false} + +\def \@setfigurenumber #1{% + {\rmfamily \bfseries \selectfont #1}} + +% Hierarchy +% --------- + + +\setcounter{secnumdepth}{\@numheaddepth} + +\newskip{\@sectionaboveskip} +\setvspace{\@sectionaboveskip}{10pt plus 3pt minus 2pt} + +\newskip{\@sectionbelowskip} +\if \@blockstyle + \setlength{\@sectionbelowskip}{0.1pt}% +\else + \setlength{\@sectionbelowskip}{4pt}% +\fi + +\renewcommand{\section}{% + \@startsection + {section}% + {1}% + {0pt}% + {-\@sectionaboveskip}% + {\@sectionbelowskip}% + {\large \bfseries \raggedright}} + +\newskip{\@subsectionaboveskip} +\setvspace{\@subsectionaboveskip}{8pt plus 2pt minus 2pt} + +\newskip{\@subsectionbelowskip} +\if \@blockstyle + \setlength{\@subsectionbelowskip}{0.1pt}% +\else + \setlength{\@subsectionbelowskip}{4pt}% +\fi + +\renewcommand{\subsection}{% + \@startsection% + {subsection}% + {2}% + {0pt}% + {-\@subsectionaboveskip}% + {\@subsectionbelowskip}% + {\normalsize \bfseries \raggedright}} + +\renewcommand{\subsubsection}{% + \@startsection% + {subsubsection}% + {3}% + {0pt}% + {-\@subsectionaboveskip} + {\@subsectionbelowskip}% + {\normalsize \bfseries \raggedright}} + +\newskip{\@paragraphaboveskip} +\setvspace{\@paragraphaboveskip}{6pt plus 2pt minus 2pt} + +\renewcommand{\paragraph}{% + \@startsection% + {paragraph}% + {4}% + {0pt}% + {\@paragraphaboveskip} + {-1em}% + {\normalsize \bfseries \if \@times \itshape \fi}} + +\renewcommand{\subparagraph}{% + \@startsection% + {subparagraph}% + {4}% + {0pt}% + {\@paragraphaboveskip} + {-1em}% + {\normalsize \itshape}} + +% Standard headings: + +\newcommand{\acks}{\section*{Acknowledgments}} + +\newcommand{\keywords}{\paragraph*{Keywords}} + +\newcommand{\terms}{\paragraph*{General Terms}} + +% Identification +% -------------- + + +\def \@conferencename {} +\def \@conferenceinfo {} +\def \@copyrightyear {} +\def \@copyrightdata {[to be supplied]} +\def \@proceedings {[Unknown Proceedings]} + + +\newcommand{\conferenceinfo}[2]{% + \gdef \@conferencename {#1}% + \gdef \@conferenceinfo {#2}} + +\newcommand{\copyrightyear}[1]{% + \gdef \@copyrightyear {#1}} + +\let \CopyrightYear = \copyrightyear + +\newcommand{\copyrightdata}[1]{% + \gdef \@copyrightdata {#1}} + +\let \crdata = \copyrightdata + +\newcommand{\proceedings}[1]{% + \gdef \@proceedings {#1}} + +% Lists +% ----- + + +\setlength{\leftmargini}{13pt} +\setlength\leftmarginii{13pt} +\setlength\leftmarginiii{13pt} +\setlength\leftmarginiv{13pt} +\setlength{\labelsep}{3.5pt} + +\setlength{\topsep}{\standardvspace} +\if \@blockstyle + \setlength{\itemsep}{1pt} + \setlength{\parsep}{3pt} +\else + \setlength{\itemsep}{1pt} + \setlength{\parsep}{3pt} +\fi + +\renewcommand{\labelitemi}{{\small \centeroncapheight{\textbullet}}} +\renewcommand{\labelitemii}{\centeroncapheight{\rule{2.5pt}{2.5pt}}} +\renewcommand{\labelitemiii}{$-$} +\renewcommand{\labelitemiv}{{\Large \textperiodcentered}} + +\renewcommand{\@listi}{% + \leftmargin = \leftmargini + \listparindent = 0pt} +%%% \itemsep = 1pt +%%% \parsep = 3pt} +%%% \listparindent = \parindent} + +\let \@listI = \@listi + +\renewcommand{\@listii}{% + \leftmargin = \leftmarginii + \topsep = 1pt + \labelwidth = \leftmarginii + \advance \labelwidth by -\labelsep + \listparindent = \parindent} + +\renewcommand{\@listiii}{% + \leftmargin = \leftmarginiii + \labelwidth = \leftmarginiii + \advance \labelwidth by -\labelsep + \listparindent = \parindent} + +\renewcommand{\@listiv}{% + \leftmargin = \leftmarginiv + \labelwidth = \leftmarginiv + \advance \labelwidth by -\labelsep + \listparindent = \parindent} + +% Mathematics +% ----------- + + +\def \theequation {\arabic{equation}} + +% Miscellaneous +% ------------- + + +\newcommand{\balancecolumns}{% + \vfill\eject + \global\@colht = \textheight + \global\ht\@cclv = \textheight} + +\newcommand{\nut}{\hspace{.5em}} + +\newcommand{\softraggedright}{% + \let \\ = \@centercr + \leftskip = 0pt + \rightskip = 0pt plus 10pt} + +% Program Code +% ------- ---- + + +\newcommand{\mono}[1]{% + {\@tempdima = \fontdimen2\font + \texttt{\spaceskip = 1.1\@tempdima #1}}} + +% Running Heads and Feet +% ------- ----- --- ---- + + +\def \@preprintfooter {} + +\newcommand{\preprintfooter}[1]{% + \gdef \@preprintfooter {#1}} + +\if \@preprint + +\def \ps@plain {% + \let \@mkboth = \@gobbletwo + \let \@evenhead = \@empty + \def \@evenfoot {\scriptsize \textit{\@preprintfooter}\hfil \thepage \hfil + \textit{\@formatyear}}% + \let \@oddhead = \@empty + \let \@oddfoot = \@evenfoot} + +\else\if \@reprint + +\def \ps@plain {% + \let \@mkboth = \@gobbletwo + \let \@evenhead = \@empty + \def \@evenfoot {\scriptsize \hfil \thepage \hfil}% + \let \@oddhead = \@empty + \let \@oddfoot = \@evenfoot} + +\else + +\let \ps@plain = \ps@empty +\let \ps@headings = \ps@empty +\let \ps@myheadings = \ps@empty + +\fi\fi + +\def \@formatyear {% + \number\year/\number\month/\number\day} + +% Special Characters +% ------- ---------- + + +\DeclareRobustCommand{\euro}{% + \protect{\rlap{=}}{\sf \kern .1em C}} + +% Title Page +% ----- ---- + + +\@setflag \@addauthorsdone = \@false + +\def \@titletext {\@latex@error{No title was provided}{}} +\def \@subtitletext {} + +\newcount{\@authorcount} + +\newcount{\@titlenotecount} +\newtoks{\@titlenotetext} + +\def \@titlebanner {} + +\renewcommand{\title}[1]{% + \gdef \@titletext {#1}} + +\newcommand{\subtitle}[1]{% + \gdef \@subtitletext {#1}} + +\newcommand{\authorinfo}[3]{% {names}{affiliation}{email/URL} + \global\@increment \@authorcount + \@withname\gdef {\@authorname\romannumeral\@authorcount}{#1}% + \@withname\gdef {\@authoraffil\romannumeral\@authorcount}{#2}% + \@withname\gdef {\@authoremail\romannumeral\@authorcount}{#3}} + +\renewcommand{\author}[1]{% + \@latex@error{The \string\author\space command is obsolete; + use \string\authorinfo}{}} + +\newcommand{\titlebanner}[1]{% + \gdef \@titlebanner {#1}} + +\renewcommand{\maketitle}{% + \pagestyle{plain}% + \if \@onecolumn + {\hsize = \standardtextwidth + \@maketitle}% + \else + \twocolumn[\@maketitle]% + \fi + \@placetitlenotes + \if \@copyrightwanted \@copyrightspace \fi} + +\def \@maketitle {% + \begin{center} + \@settitlebanner + \let \thanks = \titlenote + {\leftskip = 0pt plus 0.25\linewidth + \rightskip = 0pt plus 0.25 \linewidth + \parfillskip = 0pt + \spaceskip = .7em + \noindent \LARGE \bfseries \@titletext \par} + \vskip 6pt + \noindent \Large \@subtitletext \par + \vskip 12pt + \ifcase \@authorcount + \@latex@error{No authors were specified for this paper}{}\or + \@titleauthors{i}{}{}\or + \@titleauthors{i}{ii}{}\or + \@titleauthors{i}{ii}{iii}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{xi}{}\or + \@titleauthors{i}{ii}{iii}\@titleauthors{iv}{v}{vi}% + \@titleauthors{vii}{viii}{ix}\@titleauthors{x}{xi}{xii}% + \else + \@latex@error{Cannot handle more than 12 authors}{}% + \fi + \vspace{1.75pc} + \end{center}} + +\def \@settitlebanner {% + \if \@andp{\@preprint}{\@notp{\@emptydefp{\@titlebanner}}}% + \vbox to 0pt{% + \vskip -32pt + \noindent \textbf{\@titlebanner}\par + \vss}% + \nointerlineskip + \fi} + +\def \@titleauthors #1#2#3{% + \if \@andp{\@emptyargp{#2}}{\@emptyargp{#3}}% + \noindent \@setauthor{40pc}{#1}{\@false}\par + \else\if \@emptyargp{#3}% + \noindent \@setauthor{17pc}{#1}{\@false}\hspace{3pc}% + \@setauthor{17pc}{#2}{\@false}\par + \else + \noindent \@setauthor{12.5pc}{#1}{\@false}\hspace{2pc}% + \@setauthor{12.5pc}{#2}{\@false}\hspace{2pc}% + \@setauthor{12.5pc}{#3}{\@true}\par + \relax + \fi\fi + \vspace{20pt}} + +\def \@setauthor #1#2#3{% {width}{text}{unused} + \vtop{% + \def \and {% + \hspace{16pt}} + \hsize = #1 + \normalfont + \centering + \large \@name{\@authorname#2}\par + \vspace{5pt} + \normalsize \@name{\@authoraffil#2}\par + \vspace{2pt} + \textsf{\@name{\@authoremail#2}}\par}} + +\def \@maybetitlenote #1{% + \if \@andp{#1}{\@gtrp{\@authorcount}{3}}% + \titlenote{See page~\pageref{@addauthors} for additional authors.}% + \fi} + +\newtoks{\@fnmark} + +\newcommand{\titlenote}[1]{% + \global\@increment \@titlenotecount + \ifcase \@titlenotecount \relax \or + \@fnmark = {\ast}\or + \@fnmark = {\dagger}\or + \@fnmark = {\ddagger}\or + \@fnmark = {\S}\or + \@fnmark = {\P}\or + \@fnmark = {\ast\ast}% + \fi + \,$^{\the\@fnmark}$% + \edef \reserved@a {\noexpand\@appendtotext{% + \noexpand\@titlefootnote{\the\@fnmark}}}% + \reserved@a{#1}} + +\def \@appendtotext #1#2{% + \global\@titlenotetext = \expandafter{\the\@titlenotetext #1{#2}}} + +\newcount{\@authori} + +\iffalse +\def \additionalauthors {% + \if \@gtrp{\@authorcount}{3}% + \section{Additional Authors}% + \label{@addauthors}% + \noindent + \@authori = 4 + {\let \\ = ,% + \loop + \textbf{\@name{\@authorname\romannumeral\@authori}}, + \@name{\@authoraffil\romannumeral\@authori}, + email: \@name{\@authoremail\romannumeral\@authori}.% + \@increment \@authori + \if \@notp{\@gtrp{\@authori}{\@authorcount}} \repeat}% + \par + \fi + \global\@setflag \@addauthorsdone = \@true} +\fi + +\let \addauthorsection = \additionalauthors + +\def \@placetitlenotes { + \the\@titlenotetext} + +% Utilities +% --------- + + +\newcommand{\centeroncapheight}[1]{% + {\setbox\@tempboxa = \hbox{#1}% + \@measurecapheight{\@tempdima}% % Calculate ht(CAP) - ht(text) + \advance \@tempdima by -\ht\@tempboxa % ------------------ + \divide \@tempdima by 2 % 2 + \raise \@tempdima \box\@tempboxa}} + +\newbox{\@measbox} + +\def \@measurecapheight #1{% {\dimen} + \setbox\@measbox = \hbox{ABCDEFGHIJKLMNOPQRSTUVWXYZ}% + #1 = \ht\@measbox} + +\long\def \@titlefootnote #1#2{% + \insert\footins{% + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore +%%% \protected@edef\@currentlabel{% +%%% \csname p@footnote\endcsname\@thefnmark}% + \color@begingroup + \def \@makefnmark {$^{#1}$}% + \@makefntext{% + \rule\z@\footnotesep\ignorespaces#2\@finalstrut\strutbox}% + \color@endgroup}} + +% LaTeX Modifications +% ----- ------------- + +\def \@seccntformat #1{% + \@name{\the#1}% + \@expandaftertwice\@seccntformata \csname the#1\endcsname.\@mark + \quad} + +\def \@seccntformata #1.#2\@mark{% + \if \@emptyargp{#2}.\fi} + +% Revision History +% -------- ------- + +% SNC = Stephen Chong (chong@seas.harvard.edu) + +% Date Person Ver. Change +% ---- ------ ---- ------ + +% 2004.09.12 PCA 0.1--5 Preliminary development. + +% 2004.11.18 PCA 0.5 Start beta testing. + +% 2004.11.19 PCA 0.6 Obsolete \author and replace with +% \authorinfo. +% Add 'nocopyrightspace' option. +% Compress article opener spacing. +% Add 'mathtime' option. +% Increase text height by 6 points. + +% 2004.11.28 PCA 0.7 Add 'cm/computermodern' options. +% Change default to Times text. + +% 2004.12.14 PCA 0.8 Remove use of mathptm.sty; it cannot +% coexist with latexsym or amssymb. + +% 2005.01.20 PCA 0.9 Rename class file to sigplanconf.cls. + +% 2005.03.05 PCA 0.91 Change default copyright data. + +% 2005.03.06 PCA 0.92 Add at-signs to some macro names. + +% 2005.03.07 PCA 0.93 The 'onecolumn' option defaults to '11pt', +% and it uses the full type width. + +% 2005.03.15 PCA 0.94 Add at-signs to more macro names. +% Allow margin paragraphs during review. + +% 2005.03.22 PCA 0.95 Implement \euro. +% Remove proof and newdef environments. + +% 2005.05.06 PCA 1.0 Eliminate 'onecolumn' option. +% Change footer to small italic and eliminate +% left portion if no \preprintfooter. +% Eliminate copyright notice if preprint. +% Clean up and shrink copyright box. + +% 2005.05.30 PCA 1.1 Add alternate permission statements. + +% 2005.06.29 PCA 1.1 Publish final first edition of guide. + +% 2005.07.14 PCA 1.2 Add \subparagraph. +% Use block paragraphs in lists, and adjust +% spacing between items and paragraphs. + +% 2006.06.22 PCA 1.3 Add 'reprint' option and associated +% commands. + +% 2006.08.24 PCA 1.4 Fix bug in \maketitle case command. + +% 2007.03.13 PCA 1.5 The title banner only displays with the +% 'preprint' option. + +% 2007.06.06 PCA 1.6 Use \bibfont in \thebibliography. +% Add 'natbib' option to load and configure +% the natbib package. + +% 2007.11.20 PCA 1.7 Balance line lengths in centered article +% title (thanks to Norman Ramsey). + +% 2009.01.26 PCA 1.8 Change natbib \bibpunct values. + +% 2009.04.29 SNC 1.9 Added \reprintprice to allow the +% specification of the price of a reprint, and +% set it to default to \$10.00 diff --git a/collects/scribble/sigplan/style.tex b/collects/scribble/sigplan/style.tex new file mode 100644 index 0000000000..39f4f6b98a --- /dev/null +++ b/collects/scribble/sigplan/style.tex @@ -0,0 +1,20 @@ + +\renewcommand{\titleAndVersionAndAuthors}[3]{\title{#1}#3\maketitle} +\renewcommand{\titleAndEmptyVersionAndAuthors}[3]{\titleAndVersionAndAuthors{#1}{#2}{#3}} +\renewcommand{\titleAndVersionAndEmptyAuthors}[3]{\title{#1}\authorinfo{Anonymous}{}{}\maketitle} +\renewcommand{\titleAndEmptyVersionAndEmptyAuthors}[3]{\titleAndVersionAndEmptyAuthors{#1}{#2}{#3}} + +% Disable plain `author', enable `authorinfo:' +\renewcommand{\SAuthor}[1]{#1} +\renewcommand{\SAuthorinfo}[3]{\authorinfo{#1}{#2}{#3}} +\renewcommand{\SAuthorSep}[1]{} + +\renewcommand{\SConferenceInfo}[2]{\conferenceinfo{#1}{#2}} +\renewcommand{\SCopyrightYear}[1]{\copyrightyear{#1}} +\renewcommand{\SCopyrightData}[1]{\copyrightdata{#1}} + + +\renewcommand{\SCategory}[3]{\category{#1}{#2}{#3}} +\renewcommand{\SCategoryPlus}[4]{\category{#1}{#2}{#3}[#4]} +\renewcommand{\STerms}[1]{\terms{#1}} +\renewcommand{\SKeywords}[1]{\keywords{#1}} diff --git a/collects/scribble/struct.ss b/collects/scribble/struct.ss index d75c729df1..a9e515f80a 100644 --- a/collects/scribble/struct.ss +++ b/collects/scribble/struct.ss @@ -1,544 +1,401 @@ #lang scheme/base -(require scheme/serialize +(require (rename-in (except-in "core.ss" + target-url struct:target-url target-url? target-url-addr + deserialize-info:target-url-v0) + [make-target-url core:make-target-url]) + "private/provide-structs.ss" + "html-variants.ss" + scheme/provide-syntax + scheme/struct-info scheme/contract (for-syntax scheme/base)) -;; ---------------------------------------- +(define-provide-syntax (compat**-out stx) + (syntax-case stx () + [(_ struct-out o) + (let ([id (syntax-case #'o () + [(id (field-id ...)) #'id] + [id #'id])]) + (with-syntax ([make-id (datum->syntax id + (string->symbol (format "make-~a" (syntax-e id))) + id)] + [make-id/compat (datum->syntax id + (string->symbol (format "make-~a/compat" (syntax-e id))) + id)]) + #'(combine-out + (except-out (struct-out o) make-id) + (rename-out [make-id/compat make-id]))))] + [(_ struct-out o ...) #'(combine-out (compat**-out struct-out o) ...)])) -(define-struct collect-info (ht ext-ht parts tags gen-prefix relatives parents)) -(define-struct resolve-info (ci delays undef searches)) +(define-provide-syntax (compat-out stx) + (syntax-case stx () + [(_ . outs) #'(compat**-out struct-out . outs)])) -(define (part-collected-info part ri) - (hash-ref (collect-info-parts (resolve-info-ci ri)) - part)) +(define-provide-syntax (compat*-out stx) + (syntax-case stx () + [(_ . outs) #'(compat**-out struct*-out . outs)])) -(define (collect-put! ci key val) - (let ([ht (collect-info-ht ci)]) - (let ([old-val (hash-ref ht key #f)]) - (when old-val - (fprintf (current-error-port) - "WARNING: collected information for key multiple times: ~e; values: ~e ~e\n" - key old-val val)) - (hash-set! ht key val)))) - -(define (resolve-get/where part ri key) - (let ([key (tag-key key ri)]) - (let ([v (hash-ref (if part - (collected-info-info (part-collected-info part ri)) - (collect-info-ht (resolve-info-ci ri))) - key - #f)]) - (cond - [v (values v #f)] - [part (resolve-get/where - (collected-info-parent (part-collected-info part ri)) - ri key)] - [else - (values (hash-ref (collect-info-ext-ht (resolve-info-ci ri)) key #f) - #t)])))) - -(define (resolve-get/ext? part ri key) - (let-values ([(v ext?) (resolve-get/where part ri key)]) - (when ext? - (hash-set! (resolve-info-undef ri) (tag-key key ri) #t)) - (values v ext?))) - -(define (resolve-get part ri key) - (let-values ([(v ext?) (resolve-get/ext? part ri key)]) - v)) - -(define (resolve-get/tentative part ri key) - (let-values ([(v ext?) (resolve-get/where part ri key)]) - v)) - -(define (resolve-search search-key part ri key) - (let ([s-ht (hash-ref (resolve-info-searches ri) - search-key - (lambda () - (let ([s-ht (make-hash)]) - (hash-set! (resolve-info-searches ri) - search-key s-ht) - s-ht)))]) - (hash-set! s-ht key #t)) - (resolve-get part ri key)) - -(define (resolve-get-keys part ri key-pred) - (let ([l null]) - (hash-for-each - (collected-info-info (part-collected-info part ri)) - (lambda (k v) (when (key-pred k) (set! l (cons k l))))) - l)) +(define-provide-syntax (struct*-out stx) + (syntax-case stx () + [(_ [id (field-id ...)]) + (with-syntax ([id? (datum->syntax #'id + (string->symbol (format "~a?" (syntax-e #'id))) + #'id)] + [struct:id (datum->syntax #'id + (string->symbol (format "struct:~a" (syntax-e #'id))) + #'id)] + [make-id (datum->syntax #'id + (string->symbol (format "make-~a" (syntax-e #'id))) + #'id)] + [(sel-id ...) + (map (lambda (field-id) + (datum->syntax field-id + (string->symbol (format "~a-~a" (syntax-e #'id) (syntax-e field-id))) + field-id)) + (syntax->list #'(field-id ...)))]) + #'(combine-out + id struct:id make-id id? sel-id ...))] + [(_ [id (field-id ...)]...) + #'(combine-out (struct*-out [id (field-id ...)]) ...)])) (provide (struct-out collect-info) - (struct-out resolve-info)) + (struct-out resolve-info) + tag? block? + + make-flow flow? flow-paragraphs -;; ---------------------------------------- + (except-out (compat-out part) part-title-content) + (rename-out [part-blocks part-flow] + [part-title-content/compat part-title-content]) + make-versioned-part versioned-part? + make-unnumbered-part unnumbered-part? -(provide provide-structs) + (except-out (compat-out paragraph) paragraph-content) + (rename-out [paragraph-content/compat paragraph-content]) + make-styled-paragraph + (rename-out [paragraph? styled-paragraph?] + [paragraph-style styled-paragraph-style]) + make-omitable-paragraph omitable-paragraph? -(define-syntax (provide-structs stx) - (syntax-case stx () - [(_ (id ([field ct] ...)) ...) - #`(begin - (define-serializable-struct id (field ...)) ... - (provide/contract - #,@(let ([ids (syntax->list #'(id ...))] - [fields+cts (syntax->list #'(([field ct] ...) ...))]) - (define (get-fields super-id) - (ormap (lambda (id fields+cts) - (if (identifier? id) - (and (free-identifier=? id super-id) - fields+cts) - (syntax-case id () - [(my-id next-id) - (free-identifier=? #'my-id super-id) - #`[#,@(get-fields #'next-id) - #,@fields+cts]] - [_else #f]))) - ids fields+cts)) - (map (lambda (id fields+cts) - (if (identifier? id) - #`[struct #,id #,fields+cts] - (syntax-case id () - [(id super) - #`[struct id (#,@(get-fields #'super) - #,@fields+cts)]]))) - ids - fields+cts))))])) + (compat-out table) + table-flowss + make-auxiliary-table auxiliary-table? -(provide tag?) -(define (tag? s) - (and (pair? s) - (symbol? (car s)) - (pair? (cdr s)) - (or (string? (cadr s)) - (generated-tag? (cadr s)) - (and (pair? (cadr s)) - (list? (cadr s)))) - (null? (cddr s)))) + (struct-out delayed-block) -(provide block?) -(define (block? p) - (or (paragraph? p) - (table? p) - (itemization? p) - (blockquote? p) - (compound-paragraph? p) - (delayed-block? p))) + (compat-out itemization) + (rename-out [itemization-blockss itemization-flows] + [itemization? styled-itemization?] + [itemization-style styled-itemization-style]) + make-styled-itemization -(define (string-without-newline? s) - (and (string? s) - (not (regexp-match? #rx"\n" s)))) + make-blockquote + + (compat-out compound-paragraph) + + (except-out (compat-out element) element? element-style element-content) + (rename-out [element?/compat element?] + [element-style/compat element-style] + [element-content/compat element-content]) + (except-out (compat*-out [toc-element (toc-content)]) + toc-element-toc-content) + (rename-out [toc-element-toc-content/compat toc-element-toc-content]) + (compat*-out [target-element (tag)] + [toc-target-element ()] + [page-target-element ()] + [redirect-target-element (alt-path alt-anchor)] + [link-element (tag)] + [index-element (tag plain-seq entry-seq desc)]) + make-aux-element aux-element? + make-hover-element hover-element? hover-element-text + make-script-element script-element? script-element-type script-element-script + + (struct-out collected-info) + + (struct-out delayed-element) + ; delayed-element-content delayed-block-blocks current-serialize-resolve-info + + (struct-out part-relative-element) + ; part-relative-element-content collect-info-parents + + (struct-out delayed-index-desc) + + (struct*-out [collect-element (collect)]) + + (struct*-out [render-element (render)]) + + (struct-out generated-tag) + ; generate-tag tag-key current-tag-prefixes add-current-tag-prefix + + content->string + (rename-out [content->string element->string] + [content-width element-width]) + ; strip-aux + + block-width + + info-key? part-collected-info collect-put! + resolve-get resolve-get/tentative resolve-get/ext? resolve-search resolve-get-keys) (provide-structs - [part ([tag-prefix (or/c false/c string?)] - [tags (listof tag?)] - [title-content (or/c false/c list?)] - [style any/c] - [to-collect list?] - [flow flow?] - [parts (listof part?)])] - [(unnumbered-part part) ()] - [(versioned-part part) ([version (or/c string? false/c)])] - [flow ([paragraphs (listof block?)])] - [paragraph ([content list?])] - [(styled-paragraph paragraph) ([style any/c])] - [(omitable-paragraph paragraph) ()] - [table ([style any/c] - [flowss (listof (listof (or/c flow? (one-of/c 'cont))))])] - [(auxiliary-table table) ()] - [delayed-block ([resolve (any/c part? resolve-info? . -> . block?)])] - [itemization ([flows (listof flow?)])] - [(styled-itemization itemization) ([style any/c])] - [blockquote ([style any/c] - [paragraphs (listof block?)])] - [compound-paragraph ([style any/c] - [blocks (listof block?)])] - ;; content = list of elements - [element ([style any/c] - [content list?])] - [(toc-element element) ([toc-content list?])] - [(target-element element) ([tag tag?])] - [(toc-target-element target-element) ()] - [(page-target-element target-element) ()] - [(redirect-target-element target-element) ([alt-path path-string?] - [alt-anchor string?])] - [(link-element element) ([tag tag?])] - [(index-element element) ([tag tag?] - [plain-seq (and/c pair? (listof string-without-newline?))] - [entry-seq list?] - [desc any/c])] - [(aux-element element) ()] - [(hover-element element) ([text string?])] - [(script-element element) ([type string?] - [script (or/c path-string? (listof string?))])] - ;; specific renders support other elements, especially strings - [with-attributes ([style any/c] [assoc (listof (cons/c symbol? string?))])] - - [collected-info ([number (listof (or/c false/c integer?))] - [parent (or/c false/c part?)] - [info any/c])] - - [target-url ([addr path-string?] [style any/c])] - [url-anchor ([name string?])] [image-file ([path (or/c path-string? (cons/c (one-of/c 'collects) (listof bytes?)))] - [scale real?])]) + [scale real?])] + [target-url ([addr path-string?] [style any/c])]) -;; ---------------------------------------- +(define (make-flow l) l) +(define (flow? l) (and (list? l) (andmap block? l))) +(define (flow-paragraphs l) l) -;; Delayed element has special serialization support: -(define-struct delayed-element (resolve sizer plain) - #:property - prop:serializable - (make-serialize-info - (lambda (d) - (let ([ri (current-serialize-resolve-info)]) - (unless ri - (error 'serialize-delayed-element - "current-serialize-resolve-info not set")) - (with-handlers ([exn:fail:contract? - (lambda (exn) - (error 'serialize-delayed-element - "serialization failed (wrong resolve info? delayed element never rendered?); ~a" - (exn-message exn)))]) - (vector - (let ([l (delayed-element-content d ri)]) - (if (and (pair? l) (null? (cdr l))) - (car l) - (make-element #f l))))))) - #'deserialize-delayed-element - #f - (or (current-load-relative-directory) (current-directory)))) +(define (list->content l) + (if (and (pair? l) (null? (cdr l))) + (car l) + l)) -(provide/contract - (struct delayed-element ([resolve (any/c part? resolve-info? . -> . list?)] - [sizer (-> any)] - [plain (-> any)]))) +(define (content->list v) + (if (list? v) + v + (list v))) -(provide deserialize-delayed-element) -(define deserialize-delayed-element - (make-deserialize-info values values)) +(define (make-part/compat tag-prefix tags title-content orig-style to-collect flow parts) + (make-part tag-prefix + tags + (list->content title-content) + (convert-style orig-style) + to-collect + (flow-paragraphs flow) + parts)) -(provide delayed-element-content) -(define (delayed-element-content e ri) - (hash-ref (resolve-info-delays ri) e)) +(define (part-title-content/compat p) + (list (part-title-content p))) -(provide delayed-block-blocks) -(define (delayed-block-blocks p ri) - (hash-ref (resolve-info-delays ri) p)) +(define (make-versioned-part tag-prefix tags title-content orig-style to-collect flow parts version) + (make-part tag-prefix + tags + (list->content title-content) + (let ([s (convert-style orig-style)]) + (make-style (style-name s) + (cons + (make-document-version version) + (style-variants s)))) + to-collect + (flow-paragraphs flow) + parts)) +(define (versioned-part? p) + (and (part? p) (ormap document-version? (style-variants (part-style p))))) -(provide current-serialize-resolve-info) -(define current-serialize-resolve-info (make-parameter #f)) +(define (make-unnumbered-part tag-prefix tags title-content orig-style to-collect flow parts) + (make-part tag-prefix + tags + (list->content title-content) + (let ([s (convert-style orig-style)]) + (make-style (style-name s) + (cons 'unnumbered (style-variants s)))) + to-collect + (flow-paragraphs flow) + parts)) +(define (unnumbered-part? p) + (and (part? p) (memq 'unnumbered (style-variants (part-style p))))) -;; ---------------------------------------- +(define (make-paragraph/compat content) + (make-paragraph plain (list->content content))) +(define (paragraph-content/compat p) + (content->list (paragraph-content p))) +(define (make-styled-paragraph content style) + (make-paragraph (convert-style style) (list->content content))) -;; part-relative element has special serialization support: -(define-struct part-relative-element (collect sizer plain) - #:property - prop:serializable - (make-serialize-info - (lambda (d) - (let ([ri (current-serialize-resolve-info)]) - (unless ri - (error 'serialize-part-relative-element - "current-serialize-resolve-info not set")) - (with-handlers ([exn:fail:contract? - (lambda (exn) - (error 'serialize-part-relative-element - "serialization failed (wrong resolve info? part-relative element never rendered?); ~a" - (exn-message exn)))]) - (vector - (make-element #f (part-relative-element-content d ri)))))) - #'deserialize-part-relative-element - #f - (or (current-load-relative-directory) (current-directory)))) +(define (make-omitable-paragraph content) + (make-paragraph (make-style #f '(omitable)) (list->content content))) +(define (omitable-paragraph? p) + (and (paragraph? p) (memq 'omitable (style-variants (paragraph-style p))))) -(provide/contract - (struct part-relative-element ([collect (collect-info? . -> . list?)] - [sizer (-> any)] - [plain (-> any)]))) +(define (make-table/compat style cellss) + (make-table (convert-style style) + (map (lambda (cells) + (map (lambda (cell) + (cond + [(eq? cell 'cont) 'cont] + [(= 1 (length cell)) (car cell)] + [else (make-nested-flow plain cell)])) + cells)) + cellss))) +(define (table-flowss t) + (map (lambda (row) (map (lambda (c) (make-flow (list c))) row)) + (table-blockss t))) -(provide deserialize-part-relative-element) -(define deserialize-part-relative-element - (make-deserialize-info values values)) +(define (make-auxiliary-table style cells) + (let ([t (make-table/compat style cells)]) + (make-table (make-style (style-name (table-style t)) + (cons 'aux + (style-variants (table-style t)))) + (table-blockss t)))) -(provide part-relative-element-content) -(define (part-relative-element-content e ci/ri) - (hash-ref (collect-info-relatives - (if (resolve-info? ci/ri) (resolve-info-ci ci/ri) ci/ri)) - e)) +(define (auxiliary-table? t) + (ormap (lambda (v) (eq? v 'aux) (style-variants (table-style t))))) -(provide collect-info-parents) +(define (make-itemization/compat flows) + (make-itemization plain flows)) +(define (make-styled-itemization style flows) + (make-itemization (convert-style style) flows)) -;; ---------------------------------------- +(define (make-blockquote style blocks) + (make-nested-flow (convert-style (or style 'inset)) blocks)) -;; Delayed index entry also has special serialization support. -;; It uses the same delay -> value table as delayed-element -(define-struct delayed-index-desc (resolve) - #:mutable - #:property - prop:serializable - (make-serialize-info - (lambda (d) - (let ([ri (current-serialize-resolve-info)]) - (unless ri - (error 'serialize-delayed-index-desc - "current-serialize-resolve-info not set")) - (with-handlers ([exn:fail:contract? - (lambda (exn) - (error 'serialize-index-desc - "serialization failed (wrong resolve info?); ~a" - (exn-message exn)))]) - (vector - (delayed-element-content d ri))))) - #'deserialize-delayed-index-desc - #f - (or (current-load-relative-directory) (current-directory)))) +(define (make-compound-paragraph/compat style blocks) + (make-compound-paragraph (convert-style style) blocks)) -(provide/contract - (struct delayed-index-desc ([resolve (any/c part? resolve-info? . -> . any)]))) +(define (element-style-name s) + (if (style? s) + (style-name s) + s)) +(define (element-style-variants s) + (if (style? s) + (style-variants s) + null)) -(provide deserialize-delayed-index-desc) -(define deserialize-delayed-index-desc - (make-deserialize-info values values)) +(define (add-element-variant v e) + (make-element (make-style (element-style-name (element-style e)) + (cons v + (element-style-variants (element-style e)))) + (element-content e))) +(define (check-element-style e pred) + (ormap pred (style-variants (element-style e)))) -;; ---------------------------------------- +(define (handle-image-style ctr style . args) + (if (image-file? style) + (make-image-element #f (list (apply ctr #f args)) + (image-file-path style) + null + (image-file-scale style)) + (apply ctr (convert-element-style style) args))) -(define-struct (collect-element element) (collect) - #:mutable - #:property - prop:serializable - (make-serialize-info - (lambda (d) - (vector (make-element - (element-style d) - (element-content d)))) - #'deserialize-collect-element - #f - (or (current-load-relative-directory) (current-directory)))) - -(provide deserialize-collect-element) -(define deserialize-collect-element - (make-deserialize-info values values)) - -(provide/contract - [struct collect-element ([style any/c] - [content list?] - [collect (collect-info? . -> . any)])]) - -;; ---------------------------------------- - -(define-struct (render-element element) (render) - #:property - prop:serializable - (make-serialize-info - (lambda (d) - (vector (make-element - (element-style d) - (element-content d)))) - #'deserialize-render-element - #f - (or (current-load-relative-directory) (current-directory)))) - -(provide deserialize-render-element) -(define deserialize-render-element - (make-deserialize-info values values)) - -(provide/contract - [struct render-element ([style any/c] - [content list?] - [render (any/c part? resolve-info? . -> . any)])]) - -;; ---------------------------------------- - -(define-struct generated-tag () - #:property - prop:serializable - (make-serialize-info - (lambda (g) - (let ([ri (current-serialize-resolve-info)]) - (unless ri - (error 'serialize-generated-tag - "current-serialize-resolve-info not set")) - (let ([t (hash-ref (collect-info-tags (resolve-info-ci ri)) g #f)]) - (if t - (vector t) - (error 'serialize-generated-tag - "serialization failed (wrong resolve info?)"))))) - #'deserialize-generated-tag - #f - (or (current-load-relative-directory) (current-directory)))) - -(provide (struct-out generated-tag)) - -(provide deserialize-generated-tag) -(define deserialize-generated-tag - (make-deserialize-info values values)) - -(provide generate-tag tag-key - current-tag-prefixes - add-current-tag-prefix) - -(define (generate-tag tg ci) - (if (generated-tag? (cadr tg)) - (let ([t (cadr tg)]) - (list (car tg) - (let ([tags (collect-info-tags ci)]) - (or (hash-ref tags t #f) - (let ([key (list* 'gentag - (hash-count tags) - (collect-info-gen-prefix ci))]) - (hash-set! tags t key) - key))))) - tg)) - -(define (tag-key tg ri) - (if (generated-tag? (cadr tg)) - (list (car tg) - (hash-ref (collect-info-tags (resolve-info-ci ri)) (cadr tg))) - tg)) - -(define current-tag-prefixes (make-parameter null)) -(define (add-current-tag-prefix t) - (let ([l (current-tag-prefixes)]) - (if (null? l) - t - (cons (car t) (append l (cdr t)))))) - -;; ---------------------------------------- - -(provide content->string - element->string - strip-aux) - -(define content->string - (case-lambda - [(c) (c->s c element->string)] - [(c renderer sec ri) - (c->s c (lambda (e) (element->string e renderer sec ri)))])) - -(define (c->s c do-elem) - (apply string-append (map do-elem c))) - -(define element->string - (case-lambda - [(c) - (cond - [(element? c) (content->string (element-content c))] - [(part-relative-element? c) (element->string ((part-relative-element-plain c)))] - [(delayed-element? c) (element->string ((delayed-element-plain c)))] - [(string? c) c] - [else (case c - [(mdash) "---"] - [(ndash) "--"] - [(ldquo rdquo) "\""] - [(rsquo) "'"] - [(rarr) "->"] - [(lang) "<"] - [(rang) ">"] - [else (format "~s" c)])])] - [(c renderer sec ri) - (cond - [(and (link-element? c) - (null? (element-content c))) - (let ([dest (resolve-get sec ri (link-element-tag c))]) - ;; FIXME: this is specific to renderer - (if dest - (content->string (strip-aux - (if (pair? dest) (cadr dest) (vector-ref dest 1))) - renderer sec ri) - "???"))] - [(element? c) (content->string (element-content c) renderer sec ri)] - [(delayed-element? c) - (content->string (delayed-element-content c ri) renderer sec ri)] - [(part-relative-element? c) - (content->string (part-relative-element-content c ri) renderer sec ri)] - [else (element->string c)])])) - -(define (strip-aux content) +(define (convert-element-style style) (cond - [(null? content) null] - [(aux-element? (car content)) (strip-aux (cdr content))] - [else (cons (car content) (strip-aux (cdr content)))])) + [(not style) style] + [(string? style) style] + [(symbol? style) style] + [else (convert-style style)])) -;; ---------------------------------------- - -(provide block-width - element-width) - -(define (element-width s) +(define (element?/compat e) + (or (element? e) (and (list? e) (content? e)))) +(define (element-content/compat e) (cond - [(string? s) (string-length s)] - [(element? s) (apply + (map element-width (element-content s)))] - [(delayed-element? s) (element-width ((delayed-element-sizer s)))] - [(part-relative-element? s) (element-width ((part-relative-element-sizer s)))] - [else 1])) - -(define (paragraph-width s) - (apply + (map element-width (paragraph-content s)))) - -(define (flow-width f) - (apply max 0 (map block-width (flow-paragraphs f)))) - -(define (block-width p) + [(element? e) (content->list (element-content e))] + [else e])) +(define (element-style/compat e) (cond - [(paragraph? p) (paragraph-width p)] - [(table? p) (table-width p)] - [(itemization? p) (itemization-width p)] - [(blockquote? p) (blockquote-width p)] - [(compound-paragraph? p) (compound-paragraph-width p)] - [(delayed-block? p) 1])) + [(element? e) (element-style e)] + [else #f])) -(define (table-width p) - (let ([flowss (table-flowss p)]) - (if (null? flowss) - 0 - (let loop ([flowss flowss]) - (if (null? (car flowss)) - 0 - (+ (apply max 0 (map flow-width (map car flowss))) - (loop (map cdr flowss)))))))) +(define (make-element/compat style content) + (handle-image-style make-element style (list->content content))) +(define (make-toc-element/compat style content toc-content) + (handle-image-style make-toc-element style (list->content content) (list->content toc-content))) +(define (toc-element-toc-content/compat e) + (content->list (toc-element-toc-content e))) +(define (make-target-element/compat style content tag) + (handle-image-style make-target-element style (list->content content) tag)) +(define (make-toc-target-element/compat style content tag) + (handle-image-style make-toc-target-element style (list->content content) tag)) +(define (make-page-target-element/compat style content tag) + (handle-image-style make-page-target-element style (list->content content) tag)) +(define (make-redirect-target-element/compat style content tag alt-path alt-anchor) + (handle-image-style make-redirect-target-element style (list->content content) tag alt-path alt-anchor)) +(define (make-link-element/compat style content tag) + (handle-image-style make-link-element style (list->content content) tag)) +(define (make-index-element/compat style content tag plain-seq etry-seq desc) + (handle-image-style make-index-element style (list->content content) tag plain-seq etry-seq desc)) -(define (itemization-width p) - (apply max 0 (map flow-width (itemization-flows p)))) +(define (make-aux-element style content) + (add-element-variant 'aux (make-element/compat style content))) +(define (aux-element? e) + (check-element-style e (lambda (v) (eq? v 'aux)))) -(define (blockquote-width p) - (+ 4 (apply max 0 (map block-width (blockquote-paragraphs p))))) +(define (make-hover-element style content text) + (add-element-variant (make-hover-variant text) + (make-element/compat style content))) +(define (hover-element? e) + (check-element-style e hover-variant?)) +(define (hover-element-text e) + (ormap (lambda (v) + (and (hover-variant? v) (hover-variant-text e))) + (style-variants (element-style e)))) -(define (compound-paragraph-width p) - (apply max 0 (map block-width (compound-paragraph-blocks p)))) +(define (make-script-element style content type script) + (add-element-variant (make-script-variant type script) + (make-element/compat style content))) +(define (script-element? e) + (check-element-style e script-variant?)) +(define (script-element-type e) + (ormap (lambda (v) + (and (script-variant? v) (script-variant-type e))) + (style-variants (element-style e)))) +(define (script-element-script e) + (ormap (lambda (v) + (and (script-variant? v) (script-variant-script e))) + (style-variants (element-style e)))) ;; ---------------------------------------- -(provide part-style?) - -(define (part-style? p s) - (let ([st (part-style p)]) - (or (eq? s st) - (and (list? st) (memq s st))))) - -;; ---------------------------------------- - -(define (info-key? l) - (and (pair? l) - (symbol? (car l)) - (pair? (cdr l)))) - -(provide info-key?) -(provide/contract - [part-collected-info (part? resolve-info? . -> . collected-info?)] - [collect-put! (collect-info? info-key? any/c . -> . 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/ext? ((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)]) - -;; ---------------------------------------- +(define (convert-style s) + (cond + [(not s) plain] + [(style? s) s] + [(string? s) (make-style s null)] + [(symbol? s) (make-style s null)] + [(and (list? s) (andmap symbol? s)) (make-style #f s)] + [(with-attributes? s) (let* ([wa (flatten-style s)] + [s (convert-style (with-attributes-style wa))]) + (make-style (style-name s) + (cons + (make-attributes (with-attributes-assoc wa)) + (style-variants s))))] + [(target-url? s) (let ([s (convert-style (target-url-style s))]) + (make-style (style-name s) + (cons + (core:make-target-url (target-url-addr s)) + (style-variants s))))] + [(image-file? s) (make-style #f null)] + [(and (list? s) (pair? s) (eq? (car s) 'color)) + (make-style #f (list (make-color-variant + (if (string? (cadr s)) (cadr s) (cdr s)))))] + [(and (list? s) (pair? s) (eq? (car s) 'bg-color)) + (make-style #f (list (make-background-color-variant + (if (string? (cadr s)) (cadr s) (cdr s)))))] + [(and (pair? s) + (list? s) + (andmap (lambda (v) (and (pair? v) + (memq (car v) '(alignment valignment row-styles style)))) + s)) + (let ([gen-columns (lambda (sn a va) + (map (lambda (sn a va) + (make-style sn + (append (if a (list a) null) + (if va (list va) null)))) + (cdr (or sn (map (lambda (x) #f) (or va a)))) + (cdr (or a (map (lambda (x) #f) (or va sn)))) + (cdr (or va (map (lambda (x) #f) (or a sn))))))]) + (make-style (let ([s (assq 'style s)]) + (and s (cadr s))) + (let ([a (assq 'alignment s)] + [va (assq 'valignment s)]) + (if (or a va) + (list (make-table-columns (gen-columns #f a va))) + (let ([l (cdr (assq 'row-styles s))]) + (list + (make-table-cells + (map (lambda (row) + (let ([sn (assq 'style row)] + [a (assq 'alignment row)] + [va (assq 'valignment row)]) + (if (or sn a va) + (gen-columns sn a va) + (error 'convert-style "no row style found")))) + l))))))))] + [else (error 'convert-style "unrecognized style: ~e" s)])) (define (flatten-style s) (cond @@ -568,5 +425,3 @@ (target-url-addr s) rest)))] [else s])) - -(provide flatten-style) diff --git a/collects/scribble/text-render.ss b/collects/scribble/text-render.ss index 8370264db6..7b8acd8cde 100644 --- a/collects/scribble/text-render.ss +++ b/collects/scribble/text-render.ss @@ -1,6 +1,6 @@ (module text-render mzscheme - (require "struct.ss" + (require "core.ss" mzlib/class) (provide render-mixin) @@ -35,7 +35,7 @@ (part-title-content d)) (newline)) (newline) - (render-flow (part-flow d) d ht #f) + (render-flow (part-blocks d) d ht #f) (let loop ([pos 1] [secs (part-parts d)]) (unless (null? secs) @@ -44,31 +44,30 @@ (loop (add1 pos) (cdr secs)))))) (define/override (render-flow f part ht starting-item?) - (let ([f (flow-paragraphs f)]) - (if (null? f) - null - (apply - append - (render-block (car f) part ht starting-item?) - (map (lambda (p) - (newline) (newline) - (render-block p part ht #f)) - (cdr f)))))) + (if (null? f) + null + (apply + append + (render-block (car f) part ht starting-item?) + (map (lambda (p) + (newline) (newline) + (render-block p part ht #f)) + (cdr f))))) (define/override (render-table i part ht inline?) - (let ([flowss (table-flowss i)]) + (let ([flowss (table-blockss i)]) (if (null? flowss) null (apply append - (map (lambda (d) (unless (eq? d 'cont) (render-flow d part ht #f))) (car flowss)) + (map (lambda (d) (unless (eq? d 'cont) (render-block d part ht #f))) (car flowss)) (map (lambda (flows) (newline) (map (lambda (d) (unless (eq? d 'cont) (render-flow d part ht #f))) flows)) (cdr flowss)))))) (define/override (render-itemization i part ht) - (let ([flows (itemization-flows i)]) + (let ([flows (itemization-blockss i)]) (if (null? flows) null (apply append diff --git a/collects/scribblings/drscheme/interface-essentials.scrbl b/collects/scribblings/drscheme/interface-essentials.scrbl index 9e3f12e60e..322203abb4 100644 --- a/collects/scribblings/drscheme/interface-essentials.scrbl +++ b/collects/scribblings/drscheme/interface-essentials.scrbl @@ -3,13 +3,14 @@ scribble/decode scribble/eval scribble/struct + scribble/scheme (for-label htdp/convert scheme/gui/base)) @(define (ioinputfont . s) (apply tt s)) @(define (iooutputfont . s) - (make-element "schemestdout" (decode-content s))) + (make-element output-color (decode-content s))) @title[#:tag "interface-essentials" #:style 'toc]{Interface Essentials} diff --git a/collects/scribblings/guide/guide.scrbl b/collects/scribblings/guide/guide.scrbl index 6f191e6fd9..a180cd03fc 100644 --- a/collects/scribblings/guide/guide.scrbl +++ b/collects/scribblings/guide/guide.scrbl @@ -1,6 +1,5 @@ -#lang scribble/doc -@(require scribble/manual - scribble/eval +#lang scribble/manual +@(require scribble/eval "guide-utils.ss") @title{@bold{Guide}: PLT Scheme} diff --git a/collects/scribblings/guide/paths.scrbl b/collects/scribblings/guide/paths.scrbl index 9f218bcdc7..d9aba06895 100644 --- a/collects/scribblings/guide/paths.scrbl +++ b/collects/scribblings/guide/paths.scrbl @@ -38,11 +38,11 @@ values, instead of strings. Although it's sometimes tempting to directly manipulate strings that represent filesystem paths, correctly manipulating a path can be surprisingly difficult. For example, if you start under Unix with the -absolute path @file{/tmp/~} and take just the last part, you end up -with @file{~}---which looks like a reference to the current user's +absolute path @filepath{/tmp/~} and take just the last part, you end up +with @filepath{~}---which looks like a reference to the current user's home directory, instead of a relative path to a file of directory -named @file{~}. Windows path manipulation, furthermore, is far -trickier, because path elements like @file{aux} can have special +named @filepath{~}. Windows path manipulation, furthermore, is far +trickier, because path elements like @filepath{aux} can have special meanings. @refdetails/gory["windows-path"]{Windows filesystem paths} diff --git a/collects/scribblings/guide/regexp.scrbl b/collects/scribblings/guide/regexp.scrbl index 96eee236fc..020315eb6f 100644 --- a/collects/scribblings/guide/regexp.scrbl +++ b/collects/scribblings/guide/regexp.scrbl @@ -1,6 +1,7 @@ #lang scribble/doc @(require scribble/manual scribble/eval + scribble/core "guide-utils.ss") @title[#:tag "regexp" #:style 'toc]{Regular Expressions} @@ -358,7 +359,7 @@ the form @litchar{[:}...@litchar{:]} that can be used only inside a bracketed expression in @litchar{#px} syntax. The POSIX classes supported are -@itemize[#:style "compact" +@itemize[#:style (make-style "compact" null) @item{@litchar{[:alnum:]} --- ASCII letters and digits} diff --git a/collects/scribblings/guide/unit.scrbl b/collects/scribblings/guide/unit.scrbl index f5e587758f..4b409a6365 100644 --- a/collects/scribblings/guide/unit.scrbl +++ b/collects/scribblings/guide/unit.scrbl @@ -51,10 +51,10 @@ describes the exports of a component that implements a toy factory: scheme] (define-signature toy-factory^ - (build-toys (code:comment (integer? -> (listof toy?))) - repaint (code:comment (toy? symbol? -> toy?)) - toy? (code:comment (any/c -> boolean?)) - toy-color)) (code:comment (toy? -> symbol?)) + (build-toys (code:comment #, @tt{(integer? -> (listof toy?))}) + repaint (code:comment #, @tt{(toy? symbol? -> toy?)}) + toy? (code:comment #, @tt{(any/c -> boolean?)}) + toy-color)) (code:comment #, @tt{(toy? -> symbol?)}) (provide toy-factory^) ] @@ -101,9 +101,9 @@ is willing to sell only toys in a particular color.) scheme] (define-signature toy-store^ - (store-color (code:comment (-> symbol?)) - stock! (code:comment (integer? -> void?)) - get-inventory)) (code:comment (-> (listof toy?))) + (store-color (code:comment #, @tt{(-> symbol?)}) + stock! (code:comment #, @tt{(integer? -> void?)}) + get-inventory)) (code:comment #, @tt{(-> (listof toy?))}) (provide toy-store^) ] @@ -420,10 +420,10 @@ For example, @filepath{toy-factory-sig.ss} can be written as @schememod[ scheme/signature -build-toys (code:comment (integer? -> (listof toy?))) -repaint (code:comment (toy? symbol? -> toy?)) -toy? (code:comment (any/c -> boolean?)) -toy-color (code:comment (toy? -> symbol?)) +build-toys (code:comment #, @tt{(integer? -> (listof toy?))}) +repaint (code:comment #, @tt{(toy? symbol? -> toy?)}) +toy? (code:comment #, @tt{(any/c -> boolean?)}) +toy-color (code:comment #, @tt{(toy? -> symbol?)}) ] The signature @scheme[toy-factory^] is automatically provided from the diff --git a/collects/scribblings/inside/utils.ss b/collects/scribblings/inside/utils.ss index cc28c6f25c..a66adf95f6 100644 --- a/collects/scribblings/inside/utils.ss +++ b/collects/scribblings/inside/utils.ss @@ -3,6 +3,7 @@ (require scribble/manual scribble/struct scribble/decode + scribble/scheme (for-syntax scheme/base) (for-label scheme/base)) @@ -140,7 +141,7 @@ (let ([d (resolve-get/tentative part ri `(cpp ,x))]) (list (if d - (make-link-element "schemesyntaxlink" (list e) `(cpp ,x)) + (make-link-element syntax-link-color (list e) `(cpp ,x)) e)))) (lambda () e) (lambda () e))) diff --git a/collects/scribblings/main/private/make-search.ss b/collects/scribblings/main/private/make-search.ss index 37f3548654..888665b581 100644 --- a/collects/scribblings/main/private/make-search.ss +++ b/collects/scribblings/main/private/make-search.ss @@ -4,7 +4,9 @@ (require scribble/decode scribble/decode-struct scribble/basic - scribble/struct + scribble/core + scribble/scheme + scribble/html-variants scribble/manual-struct scheme/list scheme/string @@ -98,16 +100,16 @@ `(,@e ,(make-element "smaller" `(" (method of " ,(make-element - "schemesymbol" + symbol-color (list (make-element - "schemevaluelink" + value-link-color (list (symbol->string (exported-index-desc-name desc)))))) ")"))) e)] [e (make-link-element "indexlink" e tag)] - [e (send renderer render-element e sec ri)]) + [e (send renderer render-content e sec ri)]) (match e ; should always render to a single `a' [`((a ([href ,href] [class "indexlink"]) . ,body)) (cond [(and (part-index-desc? desc) @@ -181,12 +183,15 @@ (make-splice (list (make-paragraph + plain (list (script-ref "plt-index.js" #:noscript @list{Sorry, you must have JavaScript to use this page.}) (script-ref "search.js") - (make-render-element null null + (make-render-element #f null (lambda (r s i) (make-script user-dir? r s i))))) - (make-styled-paragraph '() - (make-with-attributes 'div '([id . "plt_search_container"])))))) + (make-paragraph (make-style #f + (list 'div + (make-attributes '([id . "plt_search_container"])))) + '())))) diff --git a/collects/scribblings/main/private/search.js b/collects/scribblings/main/private/search.js index 00601a221c..fbd567ca9e 100644 --- a/collects/scribblings/main/private/search.js +++ b/collects/scribblings/main/private/search.js @@ -565,7 +565,7 @@ function UpdateResults() { note += (j==0 ? "" : ", ") + '")))) -((1) 0 () 0 () () (c define c (c series c mk) c (c hc-append c 4 c (c mk c 5) c (c mk c 10) c (c mk c 20)))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c series c circle)) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img10.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c series c square)) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img11.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c series c (c lambda c (c size) c (c checkerboard c (c square c size))))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img12.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c define c (c rgb-series c mk) c (c vc-append c (c series c (c lambda c (c sz) c (c colorize c (c mk c sz) c "red"))) c (c series c (c lambda c (c sz) c (c colorize c (c mk c sz) c "green"))) c (c series c (c lambda c (c sz) c (c colorize c (c mk c sz) c "blue")))))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c rgb-series c circle)) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img13.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c rgb-series c square)) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img14.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c define c (c rgb-maker c mk) c (c lambda c (c sz) c (c vc-append c (c colorize c (c mk c sz) c "red") c (c colorize c (c mk c sz) c "green") c (c colorize c (c mk c sz) c "blue"))))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c series c (c rgb-maker c circle))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img15.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c series c (c rgb-maker c square))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img16.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c list c "red" c "green" c "blue")) -((1) 0 () 0 () () (c "red" c "green" c "blue")) -((1) 0 () 0 () () (c list c (c circle c 10) c (c square c 10))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 1 ("[image]") () (c (0 #f (c (0 (1 (u . "images/img17.pdf") 1.0) (c (? . 0))))) c (0 #f (c (0 (1 (u . "images/img18.pdf") 1.0) (c (? . 0))))))) -((1) 0 () 0 () () (c define c (c rainbow c p) c (c map c (c lambda c (c color) c (c colorize c p c color)) c (c list c "red" c "orange" c "yellow" c "green" c "blue" c "purple")))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c rainbow c (c square c 5))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 1 ("[image]") () (c (0 #f (c (0 (1 (u . "images/img19.pdf") 1.0) (c (? . 0))))) c (0 #f (c (0 (1 (u . "images/img20.pdf") 1.0) (c (? . 0))))) c (0 #f (c (0 (1 (u . "images/img21.pdf") 1.0) (c (? . 0))))) c (0 #f (c (0 (1 (u . "images/img22.pdf") 1.0) (c (? . 0))))) c (0 #f (c (0 (1 (u . "images/img23.pdf") 1.0) (c (? . 0))))) c (0 #f (c (0 (1 (u . "images/img24.pdf") 1.0) (c (? . 0))))))) -((1) 0 () 0 () () (c apply c vc-append c (c rainbow c (c square c 5)))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img25.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c require c slideshow/flash)) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c filled-flash c 40 c 30)) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img26.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c require c (c planet c "random.ss" c (c "schematics" c "random.plt" c 1 c 0)))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c random-gaussian)) -((1) 0 () 0 () () 0.7386912134436788) -((1) 0 () 0 () () (c require c slideshow/code)) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c code c (c circle c 10))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img27.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c define-syntax c pict+code c (c syntax-rules c () c (c (c pict+code c expr) c (c hc-append c 10 c expr c (c code c expr)))))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c pict+code c (c circle c 10))) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img28.pdf") 1.0) (c "[image]"))))) -((1) 0 () 0 () () (c require c scheme/class c scheme/gui/base)) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c define c f c (c new c frame% c (c label c "My Art") c (c width c 300) c (c height c 300) c (c alignment c (c quote c (c center c center)))))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c send c f c show c #t)) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c send c f c show c #f)) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c define c (c add-drawing c p) c (c let c (c (c drawer c (c make-pict-drawer c p))) c (c new c canvas% c (c parent c f) c (c style c (c quote c (c border))) c (c paint-callback c (c lambda c (c self c dc) c (c drawer c dc c 0 c 0))))))) -((1) 0 () 0 () () (void)) -((1) 0 () 0 () () (c add-drawing c (c pict+code c (c circle c 10)))) -((1) 1 (((lib "scribble/struct.ss") . deserialize-info:element-v0)) 0 () () (0 #f (c (u . "#(struct:object:canvas% ...)")))) -((1) 0 () 0 () () (c add-drawing c (c colorize c (c filled-flash c 50 c 30) c "yellow"))) -((1) 1 (((lib "scribble/struct.ss") . deserialize-info:element-v0)) 0 () () (0 #f (c (u . "#(struct:object:canvas% ...)")))) -((1) 0 () 0 () () (c scale c (c bitmap c (c build-path c (c collection-path c "scribblings/quick") c "art.png")) c 0.5)) -((1) 2 (((lib "scribble/struct.ss") . deserialize-info:element-v0) ((lib "scribble/struct.ss") . deserialize-info:image-file-v0)) 0 () () (0 #f (c (0 (1 (u . "images/img29.pdf") 1.0) (c "[image]"))))) +((2) 0 () 0 () () 5) +((2) 0 () 0 () () 5) +((2) 0 () 0 () () (c begin c "art gallery")) +((2) 0 () 0 () () "art gallery") +((2) 0 () 0 () () (c circle c 10)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img0") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c rectangle c 10 c 20)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img1") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c circle c 10 c 20)) +((2) 1 (((lib "scriblib/private/gui-eval-exn.ss") . deserialize-info:gui-exn-v0)) 0 () () (0 "procedure circle: expects 1 argument, given 2: 10 20")) +((2) 0 () 0 () () (c hc-append c (c circle c 10) c (c rectangle c 10 c 20))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img2") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c c c (c circle c 10))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c define c r c (c rectangle c 10 c 20))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () r) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img3") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c hc-append c c c r)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img4") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c hc-append c 20 c c c r c c)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img5") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c (c square c n) c (c filled-rectangle c n c n))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c square c 10)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img6") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c (c four c p) c (c define c two-p c (c hc-append c p c p)) c (c vc-append c two-p c two-p))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c four c (c circle c 10))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img7") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c (c checker c p1 c p2) c (c let c (c (c p12 c (c hc-append c p1 c p2)) c (c p21 c (c hc-append c p2 c p1))) c (c vc-append c p12 c p21)))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c checker c (c colorize c (c square c 10) c "red") c (c colorize c (c square c 10) c "black"))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img8") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c (c checkerboard c p) c (c let* c (c (c rp c (c colorize c p c "red")) c (c bp c (c colorize c p c "black")) c (c c c (c checker c rp c bp)) c (c c4 c (c four c c))) c (c four c c4)))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c checkerboard c (c square c 10))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img9") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () circle) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:element-v0)) 0 () () (0 #f (c (u . "#")))) +((2) 0 () 0 () () (c define c (c series c mk) c (c hc-append c 4 c (c mk c 5) c (c mk c 10) c (c mk c 20)))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c series c circle)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img10") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c series c square)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img11") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c series c (c lambda c (c size) c (c checkerboard c (c square c size))))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img12") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c (c rgb-series c mk) c (c vc-append c (c series c (c lambda c (c sz) c (c colorize c (c mk c sz) c "red"))) c (c series c (c lambda c (c sz) c (c colorize c (c mk c sz) c "green"))) c (c series c (c lambda c (c sz) c (c colorize c (c mk c sz) c "blue")))))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c rgb-series c circle)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img13") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c rgb-series c square)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img14") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define c (c rgb-maker c mk) c (c lambda c (c sz) c (c vc-append c (c colorize c (c mk c sz) c "red") c (c colorize c (c mk c sz) c "green") c (c colorize c (c mk c sz) c "blue"))))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c series c (c rgb-maker c circle))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img15") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c series c (c rgb-maker c square))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img16") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c list c "red" c "green" c "blue")) +((2) 0 () 0 () () (c "red" c "green" c "blue")) +((2) 0 () 0 () () (c list c (c circle c 10) c (c square c 10))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 2 ("[image]" (c ".pdf" c ".png")) () (c (0 #f (c (? . 0)) (u . "images/img17") (? . 1) 1.0) c (0 #f (c (? . 0)) (u . "images/img18") (? . 1) 1.0))) +((2) 0 () 0 () () (c define c (c rainbow c p) c (c map c (c lambda c (c color) c (c colorize c p c color)) c (c list c "red" c "orange" c "yellow" c "green" c "blue" c "purple")))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c rainbow c (c square c 5))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 2 ("[image]" (c ".pdf" c ".png")) () (c (0 #f (c (? . 0)) (u . "images/img19") (? . 1) 1.0) c (0 #f (c (? . 0)) (u . "images/img20") (? . 1) 1.0) c (0 #f (c (? . 0)) (u . "images/img21") (? . 1) 1.0) c (0 #f (c (? . 0)) (u . "images/img22") (? . 1) 1.0) c (0 #f (c (? . 0)) (u . "images/img23") (? . 1) 1.0) c (0 #f (c (? . 0)) (u . "images/img24") (? . 1) 1.0))) +((2) 0 () 0 () () (c apply c vc-append c (c rainbow c (c square c 5)))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img25") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c require c slideshow/flash)) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c filled-flash c 40 c 30)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img26") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c require c (c planet c "random.ss" c (c "schematics" c "random.plt" c 1 c 0)))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c random-gaussian)) +((2) 0 () 0 () () 0.7386912134436788) +((2) 0 () 0 () () (c require c slideshow/code)) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c code c (c circle c 10))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img27") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c define-syntax c pict+code c (c syntax-rules c () c (c (c pict+code c expr) c (c hc-append c 10 c expr c (c code c expr)))))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c pict+code c (c circle c 10))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img28") (c ".pdf" c ".png") 1.0)) +((2) 0 () 0 () () (c require c scheme/class c scheme/gui/base)) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c define c f c (c new c frame% c (c label c "My Art") c (c width c 300) c (c height c 300) c (c alignment c (c quote c (c center c center)))))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c send c f c show c #t)) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c send c f c show c #f)) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c define c (c add-drawing c p) c (c let c (c (c drawer c (c make-pict-drawer c p))) c (c new c canvas% c (c parent c f) c (c style c (c quote c (c border))) c (c paint-callback c (c lambda c (c self c dc) c (c drawer c dc c 0 c 0))))))) +((2) 0 () 0 () () (void)) +((2) 0 () 0 () () (c add-drawing c (c pict+code c (c circle c 10)))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:element-v0)) 0 () () (0 #f (c (u . "#(struct:object:canvas% ...)")))) +((2) 0 () 0 () () (c add-drawing c (c colorize c (c filled-flash c 50 c 30) c "yellow"))) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:element-v0)) 0 () () (0 #f (c (u . "#(struct:object:canvas% ...)")))) +((2) 0 () 0 () () (c scale c (c bitmap c (c build-path c (c collection-path c "scribblings/quick") c "art.png")) c 0.5)) +((2) 1 (((lib "scribble/core.ss") . deserialize-info:image-element-v0)) 0 () () (0 #f (c "[image]") (u . "images/img29") (c ".pdf" c ".png") 1.0)) diff --git a/collects/scribblings/quick/images/img0.pdf b/collects/scribblings/quick/images/img0.pdf index 1f1d2322896436facd3afb63742a8cc0e96b3289..fdf8c77dfe776478c65ae71bfa2febca76e21f76 100644 GIT binary patch delta 291 zcmca1d_#Cc6*F&|L0VF(r9ql*Vw!Q%GBUL? zwa_&%o7})6jVZXAB@wHBuF2M{<`^=VB4Af+e#9!lq-SnqWN2Yz3bst$z(8G-OW!v? z#U-&MRl~)~$iTqT09nOm4US+&Cs$)fS0@t}BNI1c6BA=cOCx7DM*{;l7fVMABTF+k O6FVD1Dkksclm-A>KugvD delta 291 zcmca1d_#Cc6*I3{qM=!`xw*NniGi8XNC?L0VF(r9ql*Vw!Q%Fi=;hNGz~&E=o--Np%5YTXiD?14~^4bfuGPSrT!W%*ASjA!CjqBC&Zb zt2~pQxsj2fg^?-PdUc@nnq2z6`6(cqHC(JfRvRFz*!+tPY>Vq%(UN}9Q@iGi8X - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -55,8 +55,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -73,7 +73,7 @@ xref 0000000640 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [<5B9C18337FC8389A1DFF2A1017EF4F38><5B9C18337FC8389A1DFF2A1017EF4F38>] +/ID [<359940CD83EE8F3FC014C34CE1255CDE><359940CD83EE8F3FC014C34CE1255CDE>] >> startxref 2278 diff --git a/collects/scribblings/quick/images/img11.pdf b/collects/scribblings/quick/images/img11.pdf index 04a82e45b59d2140f974e235b4fb7d1fee5df65c..b71cc76089009d472bb68c13a78fd1f0052d39d7 100644 GIT binary patch delta 301 zcmX>td|G%zE;DbMQL<@bvPGJ1Vw!Q%WFA)e$upT#F+`On>#~?xo9h}Gg&0~`8JSrb z80s1TNdt9-io^md=c3fal2jKUwpBMWFtF4$Kvz0>9!nyIsgW2W5|g`Ftd|G%zE;FxLQmTPPVw$#~?x8|xYvhZve#nHpM| znCTjrTNxOrD^w&FSUDG^CYGeS0I{vQk%56FP#v1m$@5qeF-(ob5RsVN#VU^>D!=(E zs|1stv4OFnsi`5@YIUI1nq2z6`6(bS|ub6jS_OLpEgqh!;>WQ#Q2#5Cii$?rHNCNJP*pDfCeidBYd@=6Xf0drj=qYy(2 zDjv)ee#pXaR2_`*rBO^l#BQvl?>IMetnq2z6 z`6(`mC8-)NRz?N}mIlZwHc#gXW^^)fHFa}xF?Vrub9OQ}Fmg1sG<0?`b1^n|ax!#r PHFveMA*5om4xcmtgo#hd delta 291 zcmX>ub6jS_OLktfq*Mco#58kV69Y4&$?rHNCNJP*pDfCeidBYd@=6Xf0b^YQ;}Anr zD^o)&6Ej@{^U3cyq%j4hI1{m&;fNt>jv)ee#pXaR2_`*b17kx|Q$w&t>IMetnq2z6 z`6(`mC8-)NRz?N}mIlZwHc#gXW^}SNGcqzaGc&eyvM{nRu{3veF}HMcbaQnyH8*rN PGBmZbA*5om4xcmta;Zxy diff --git a/collects/scribblings/quick/images/img13.pdf b/collects/scribblings/quick/images/img13.pdf index 8266f4fae11ecf0a162218fafe989a1139826ac8..f67ca20c7c7aed443d585584e2821cceded613d2 100644 GIT binary patch delta 285 zcmZ21wpeV#Q5N1bqh!;>WQ#Q2#5Cii$$aeclRvVgVi9d(wG=SdH8Kh@w6HQVvobK$ zH87ienpGN8@EdC)7X8g^Rv4lZlOM6kql#|kV>f5wF*h%@me>W}wVx>vx delta 285 zcmZ21wpeV#Q5Igaq*Mco#58kV69Y4&$$aeclRvVgVi9d(wG=ScH82h_G_^7{v@$W% zH87uinpGN8@EdC)7X8g^Rv4lZlOM6kql#|kV>f5wF*YzZG&MDZSQ5x7h9a=Jm@}9$ z*3`+!#njZr($K=(&Dhe-)WE>P$=TA})zZwu$jRBo$j*kKidZf?JFeoA#G;alqSQ1l PBNIytE>%@me>W}whD%0Z diff --git a/collects/scribblings/quick/images/img14.pdf b/collects/scribblings/quick/images/img14.pdf index c2b005af55..56bb978304 100644 --- a/collects/scribblings/quick/images/img14.pdf +++ b/collects/scribblings/quick/images/img14.pdf @@ -42,10 +42,10 @@ endobj - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -55,8 +55,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -73,7 +73,7 @@ xref 0000000577 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [] +/ID [] >> startxref 2215 diff --git a/collects/scribblings/quick/images/img15.pdf b/collects/scribblings/quick/images/img15.pdf index b1cbc9a98711152399b68e9ba6246d8bc6d34b52..4375287b58cb323c0b164996b88b5a0ab8ec32cb 100644 GIT binary patch delta 300 zcmbO&Hd}1NUKZXoqh!;>WQ#Q2#5Cii$uVs5lV7r=Vu&hDu4Of|HrF*W3Nf^>GBUF= zFw`{wk_PGu6^R8_&PAz-C8;hzY^!c$U|^|hfUb1%JJv)DQzJ1%BqrZtlgAL1->k|m z!K7zyWMpVzWCpfc9cZ;Cm%eX)3dmLs7b}pp2FNNlXLANKIvJWfSvt8|nwdE}Ihq<9 d7@C+^xVjlTnmCy_8d;jTIN8|{QZb2J8UTjKPe}j( delta 300 zcmbO&Hd}1NUKU=nWOGX+LvwRo69Y4&$uVs5lV7r=Vu&hDu4Of|Hr6#T4ly*fGBva^ zG1oOPw=ytLSExuVuyQU+O)N=u0b*NqBLf3VpgJ_Ali#r>Vwf6 - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -55,8 +55,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -73,7 +73,7 @@ xref 0000000588 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [<1AE0C6090561E21FACDD570510EAE550><1AE0C6090561E21FACDD570510EAE550>] +/ID [<3F728FBF71FC3EE42151B158C78C6E47><3F728FBF71FC3EE42151B158C78C6E47>] >> startxref 2226 diff --git a/collects/scribblings/quick/images/img17.pdf b/collects/scribblings/quick/images/img17.pdf index c0d1d37f9368dd4a1ea11aec4ce32bbb06a753f8..92fd33a72a5da2c55cfffbf5d5cc0d737679bf42 100644 GIT binary patch delta 290 zcmca1d_#Cc6*F&|v1zJ_u|b+{Vw!Q%GBUF= zFw!+Jo7})6jVZXAB@wHBuF2M{<`^=VB4Af+e#9!lq-SnqWN2Yz2DVJyz(8G-OW!v? z#U-&MRl~)~$iTqT09nOm4US+&M<-KfM>k_A6kBR2yxM>khNC?v1zJ_u|b+{Vw!Q%IxN!1y;^Qsfi`2E4)4 dJGohyn;5ye8M(Qb85ujf*x3+LF}a^p8UV**Pw@Z% delta 313 zcmZ1_yh?b34>PY>vbm*^p}D!PiGi8Xz) fz|zdv(#+h|)WXuu%*4#q($US%hLDQM{hZPOBK1pw diff --git a/collects/scribblings/quick/images/img19.pdf b/collects/scribblings/quick/images/img19.pdf index 8380ccb19f13543968d7434c48afa46e4efe04a8..45b4b91d19a5282eef990ab93bd78187f8e2340a 100644 GIT binary patch delta 291 zcmZ1}yi$0BH#2XVv1zJ_u|b+{Vw!Q%6sfD8Cn>bfh|)vFi_Xz()Z0z zaY-ym)o`&gGBB_-KvuE&CwnlXld+S5i?flLvyrQdiMgezg^{_blcRyNnUSlRiIJnL Nqn!;Q6_fior2$0PNL>H` delta 291 zcmZ1}yi$0BH#4tUilJeWd78PdiGi8X - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -57,8 +57,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -75,7 +75,7 @@ xref 0000000546 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [<390C745AD3529AFF7AA2F07ADD0F632F><390C745AD3529AFF7AA2F07ADD0F632F>] +/ID [] >> startxref 2184 diff --git a/collects/scribblings/quick/images/img20.pdf b/collects/scribblings/quick/images/img20.pdf index 95bb37c2fa4e7ed645fcfdd9f49abb13b793dc85..7377683ff33744bf2e20c7c27ce55dba04090216 100644 GIT binary patch delta 285 zcmdlayh(UN2s3Y*ahh3*rA3-<_riNA~7P3EG*6KYzV4|<+8KmDlSPZDyb++P2(~$ OG_vGURdw}u;{pJdGDKnk diff --git a/collects/scribblings/quick/images/img21.pdf b/collects/scribblings/quick/images/img21.pdf index 3f408c33b40fee2af11e7b25c4a088368aa48be6..0d081d40bcceb6bb51db266d4b3716a4f6f8d64d 100644 GIT binary patch delta 301 zcmZ22yjpmJFEekNahh3*rA3-o42w` zFzJ~a85vp_nSrfV2U@MkrSF@c0wZX=-F=LrBHs37paZ&~8lS diff --git a/collects/scribblings/quick/images/img22.pdf b/collects/scribblings/quick/images/img22.pdf index f27ab75406d58bd1f2916174211ff3e3d2a5885a..5b6ef6524b95024af090ca0a66ad539e0c3d5dae 100644 GIT binary patch delta 301 zcmZ1@yheC~A2V;7ahh3*rA3-o42t_ zFzJ~a85vp_nSrfV2U@MkrSF@c096jZf0WY=4NK$ fW?<%K;b?AR?&|2|WN2Yv;%s1NLrBHsiJZ~^+}uqB diff --git a/collects/scribblings/quick/images/img23.pdf b/collects/scribblings/quick/images/img23.pdf index 06be15da566fadb2132ba10944a987ea2285f043..1308619bbe78433706b0589a3faecc0f7368cfa4 100644 GIT binary patch delta 301 zcmZ22yjpmJFEekNahh3*rA3-o42w` zFzJ~a85vp_nSrfV2U@MkrSF@c0FnleZt7%iX>91~>SSVPLrBHs37paZ!AeZC diff --git a/collects/scribblings/quick/images/img24.pdf b/collects/scribblings/quick/images/img24.pdf index 6e31d991b2b2a058561f3524912df444013c2150..f6af0e500cd8b5460c68e0459b68489af5daa090 100644 GIT binary patch delta 285 zcmX>od{B5pGBaBxq($4LsWkAX;uj)9&;ljLklA_h(+(&#ZUw`3vvWA z###bp-JC2eO}&|Ch~=`g<0>vmEGnreN=@T3 PGBh#aQdM>JcjE#8F&ale delta 285 zcmX>od{B5pGBdAPN@Ai(s=2wYiGi8XWJVVG$^Fc!7@`pZ#<~W^A%><_riNA~mbwP! zlQUVQF$JfvBx2}QnykWVjv*>Bxq($4LsWkAX;uj)9%BPzLsL^jh(+(&#ZUw`3vvWA z#=4prTRJ;gxEUB&n3@qCR1wQ%XUA1sl2}wyQIwj- QWn^e#!lkO}>hHz{0N>$6i2wiq diff --git a/collects/scribblings/quick/images/img25.pdf b/collects/scribblings/quick/images/img25.pdf index df7858d076..e8d08c445a 100644 --- a/collects/scribblings/quick/images/img25.pdf +++ b/collects/scribblings/quick/images/img25.pdf @@ -43,10 +43,10 @@ endobj - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -56,8 +56,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -74,7 +74,7 @@ xref 0000000577 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [] +/ID [] >> startxref 2215 diff --git a/collects/scribblings/quick/images/img26.pdf b/collects/scribblings/quick/images/img26.pdf index dc8d47295f..d3f53f6e63 100644 --- a/collects/scribblings/quick/images/img26.pdf +++ b/collects/scribblings/quick/images/img26.pdf @@ -42,10 +42,10 @@ endobj - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -55,8 +55,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -73,7 +73,7 @@ xref 0000000622 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [] +/ID [<5B1279F9960652F0F9499AE6C2394568><5B1279F9960652F0F9499AE6C2394568>] >> startxref 2260 diff --git a/collects/scribblings/quick/images/img27.pdf b/collects/scribblings/quick/images/img27.pdf index d38263bd0c2562c1c6110ac663c6fccd56e52c4c..885aa953ec4fde0d15db1e576a8981089e3533fe 100644 GIT binary patch delta 291 zcmdn4yj^(%CpT}JiA9>ZfkB#XVw!Q%WIkSr$p?7YC!2DoVwK^Ve3IKtz+BhJD8$gh z%E-*hz(m);Y%)KOG^U^xPa;+`95F=AF+{+w*j&gf!K7zyWMpVzWCpfK-M~OylS|(> zKgA`nBvr%3%E-XL(g0b-=I#888J!GF4a|%z4IPb~oSj^pTn(I!OdTDKjLe-a&CHBV P3>@uj2&tGnM^G97=`Tp~ delta 291 zcmdn4yj^(%CpWLTp>axzskynXiGi8XWIkSr$p?7YC!2DoVwK^Ve3IKtz*yJ7IK+}Y5{ P%+ZfkB#XVw!Q%WItYsNxbZnOSx0ANpMZ(y$K1%s(89dB=VEt-F uCr4*DBVz+6OBWYIb0Y&cQ&(40M^_6sBPUZ!BR4Z=V>=r{DkcjU$^ZasokyPl delta 262 zcmZ3Jv?gi8QY~I{!xS^Kq%?C~69Y4&$?tUJCtuV`#Uh%dZ7E=^YhWB=Xli9@Xk}`q zYhXTkwYD^-;5F?;Ec%mmtT03+CLhv~M-|=tPRE>y$JoHw(A3lrVu_)?7>dB=VEt-F uCsR`sCv!tfQ)dek6GKBw0}~fZCr2|&7XwE(6C-CgS34U*DkcjU$^ZZXEk!i| diff --git a/collects/scribblings/quick/images/img3.pdf b/collects/scribblings/quick/images/img3.pdf index 38eda2d263cf5d319b21509f6d50baa0eb9acd37..42c8531d155599f0e5ad6ff9635c9ea2d626ff54 100644 GIT binary patch delta 313 zcmZ1_yh?b34>NC?p{0p=nnjv!Vw!Q%Fi=;hNGz~&E=o--Np%5YTXiD?1E3tb(#f?fi8xH=Vzt7MF~<;**u0ii zo=MN#$jH#b$P{e7I?#GeE`8tp6p+mtE><9`4UkoA{>2{5=w#|ZeieL;b><=NX6uSPH6xfEKpbg delta 313 zcmZ1_yh?b34>PY>Vq%(UN}9Q@iGi8X?))Yup(=Vst+ dVC-z*YGh_=3^c^a*u~t<*v^KKipl+)(f|u_PKy8l diff --git a/collects/scribblings/quick/images/img4.pdf b/collects/scribblings/quick/images/img4.pdf index 1502bfe87f..f00b183fa2 100644 --- a/collects/scribblings/quick/images/img4.pdf +++ b/collects/scribblings/quick/images/img4.pdf @@ -44,10 +44,10 @@ endobj - -PLT Scheme - -Untitledmflatt@Macintosh \(Matthew Flatt\) + +PLT Scheme + +Untitledmflatt@Macintosh \(Matthew Flatt\) @@ -57,8 +57,8 @@ endstream endobj 2 0 obj <>endobj xref @@ -75,7 +75,7 @@ xref 0000000546 00000 n trailer << /Size 10 /Root 1 0 R /Info 2 0 R -/ID [] +/ID [<6E7272D6B2731DC8CB2BE347FB5EA742><6E7272D6B2731DC8CB2BE347FB5EA742>] >> startxref 2184 diff --git a/collects/scribblings/quick/images/img5.pdf b/collects/scribblings/quick/images/img5.pdf index ad579eb9f4045317816492c2673e0faea29ae90b..772d873b337f4c36f703bcd2018bfe5adab69e44 100644 GIT binary patch delta 285 zcmbOvGD&2^7G~ZwLrW9$G>bId#5Cii$p@KRFht}h7qVCinCluDg&0~`8JSv{TIw2@ zP2R;KjVbt)B@v7MB33I5QHjYHS>-WA5zH8C zY;0iUXl!X|Xz6I;gZ%)XG2g$ESH@fS8+*VQAtHnY8sc3 Ok&!8vs;aBM8y5hBLP`Dr delta 285 zcmbOvGD&2^7G_?vBop&A6LWK269Y4&$p@KRFht}h7qVCi80#7shZve#nHpM|nCcps zPu|5MjVbt)B@v7MB33I5QHjYHS>-WA5zH9t zYHs1`VrXb;Zfs`iNC?p{0p=nnjv!Vw!Q%Fi=;hNGz~&E=o--Np%5YTXiD?1E3tb(#f?fi8xH=Vzt7MF~<;**u0ii zo=MN#$jH#b$P{e7I?#GeE`8tp6p+mtE><9`4UkoA{>2{5=;UTPY>l8JemiMhG1iGi8XhLDQM{hZPO?($5K diff --git a/collects/scribblings/quick/images/img7.pdf b/collects/scribblings/quick/images/img7.pdf index f6abd6e42d325b0141029b5a4985001809ccf73f..d2bcfd4e61d548248a9993d9537ddc7f51deee05 100644 GIT binary patch delta 324 zcmdllvR`DwLuTGIBcl{UGlMkU#5Cii$qlUXlX+QEF+`OnFJv*ZHrF*W3Nf^>GBUF= zFwivsk?IN+i3L{9MX8A;sV+clt8QdqV5w_>u5_{xYa)iJkr*NplmD^GV~EOc_GFV_ z(la+QGPE!<16!>Qv|5u(-#0%6WUGdY706lxWEGqHIf5Bu4UC+fOf5`}ot+F^%#17z z+{~Q}oSn=KEiH_UoDGcK>}&|Ch~=`g<0>vmEGnreN=@T3GBP*dQdM>JcjE#8GJsQ3 delta 324 zcmdllvR`DwLuOvHBop&A6LWK269Y4&$qlUXlX+QEF+`OnFJv*ZHr6#T4ly*fGBva^ zG1WCNw=ytLSExuVuyQU+O)N=u0b*NqBLf3VpgJ_AlZ99lF-(ob5RsVtk5wK+RDQE3 zn*@`dv4OFnsi`5@YIUI1nq2z6`6(bSADEVd3OzW@=(& z=xpR_Zs_FX>gwX=YHna^;%I4SLr_I5mz^C~aYn7XU$T BP*eZ_ diff --git a/collects/scribblings/quick/images/img8.pdf b/collects/scribblings/quick/images/img8.pdf index a3ea21224837636345c64029482512baf27eadd7..9d824c87534034d1b8f1161093fa0eced58fb5a4 100644 GIT binary patch delta 279 zcmX>md`x&l1~YG(kx`1FnL(OvVw!Q%IFlt2i+(j$D-2PI$*rvNsG^%UvYIpLnHw1yS{RvuEm1cxP}k(r_svgn zNi0d#aIrEnFt9X0R(!kZw#K6fMBxYuAWNBwZ KNX6vUoYDYmd`x&l1~ac&l8JemiMhG1iGi8XIFlt2i+(j$D-2PI$*rvNsG^%UvYIpL85string s))] [(QUOTE LIST LIST-REST LIST-NO-ORDER VECTOR HASH-TABLE BOX STRUCT REGEXP PREGEXP AND OR NOT APP ? QUASIQUOTE CONS MCONS) - (make-element "schemesymbol" (list (string-downcase (symbol->string s))))] + (make-element symbol-color (list (string-downcase (symbol->string s))))] [(***) - (make-element "schemesymbol" '("..."))] - [(___) (make-element "schemesymbol" '("___"))] + (make-element symbol-color '("..."))] + [(___) (make-element symbol-color '("___"))] [(__K) - (make-element #f (list (make-element "schemesymbol" '("__")) + (make-element #f (list (make-element symbol-color '("__")) (match-nonterm "k")))] [(..K) - (make-element #f (list (make-element "schemesymbol" '("..")) + (make-element #f (list (make-element symbol-color '("..")) (match-nonterm "k")))] [else s])] diff --git a/collects/scribblings/reference/procedures.scrbl b/collects/scribblings/reference/procedures.scrbl index 58d6aefb2a..1332e6707e 100644 --- a/collects/scribblings/reference/procedures.scrbl +++ b/collects/scribblings/reference/procedures.scrbl @@ -220,7 +220,7 @@ is @scheme[#f], then the resulting procedure still accepts any keyword, otherwise the keywords in @scheme[required-kws] must be a subset of those in @scheme[allowed-kws]. The original @scheme[proc] must require no more keywords than the ones listed din -@scheme[required-kws], and it must allow at least the keywors in +@scheme[required-kws], and it must allow at least the keywords in @scheme[allowed-kws] (or it must allow all keywords if @scheme[allowed-kws] is @scheme[#f]). diff --git a/collects/scribblings/reference/reader-example.ss b/collects/scribblings/reference/reader-example.ss index 75daf8304e..62ad950f07 100644 --- a/collects/scribblings/reference/reader-example.ss +++ b/collects/scribblings/reference/reader-example.ss @@ -43,7 +43,7 @@ [(eof-object? v) (make-element 'italic '("nothing"))] [(string? v) - (make-element "schemevalue" + (make-element value-color (list (schemefont (regexp-replace* #rx"[\\]\"" (regexp-replace* diff --git a/collects/scribblings/reference/reference.scrbl b/collects/scribblings/reference/reference.scrbl index 752c8d7bbf..d9a0300eff 100644 --- a/collects/scribblings/reference/reference.scrbl +++ b/collects/scribblings/reference/reference.scrbl @@ -1,5 +1,10 @@ #lang scribble/doc -@(require "mz.ss" scribble/struct scheme/list) +@(require "mz.ss" + scribble/core + scribble/html-variants + scribble/latex-variants + scribble/core + scheme/list) @(define (scheme-extra-libs) (make-delayed-element @@ -15,7 +20,12 @@ (lambda () "...") (lambda () "..."))) -@title{@bold{Reference}: PLT Scheme} +@(define (extras) + (make-style #f (list + (make-css-addition "extras.css") + (make-tex-addition "extras.tex")))) + +@title[#:style (extras)]{@bold{Reference}: PLT Scheme} @author["Matthew Flatt" "PLT"] diff --git a/collects/scribblings/reference/rx.ss b/collects/scribblings/reference/rx.ss index 57a15d9b47..b4894db403 100644 --- a/collects/scribblings/reference/rx.ss +++ b/collects/scribblings/reference/rx.ss @@ -1,5 +1,5 @@ (module rx scheme/base - (require scribble/struct + (require scribble/core scribble/manual scribble/bnf) @@ -240,13 +240,15 @@ Category ::= Ll | Lu | Lt | Lm Unicode general category lines)) (make-table - '((alignment left left center left left left)) + (make-style #f (list (make-table-columns (map (lambda (s) + (make-style #f (list s))) + '(left left center left left left))))) (map (lambda (line) - (cons (make-flow (list (make-paragraph (list (hspace 1))))) + (cons (make-paragraph plain (list (hspace 1))) (map (lambda (i) (if (eq? i 'cont) i - (make-flow (list (make-paragraph (list i)))))) + (make-paragraph plain (list i)))) line))) table-lines))) @@ -398,35 +400,32 @@ Class : <1,1> (list (list line)) (cons (cons line (car r)) (cdr r))))))))]) (make-table - '((alignment center)) + (make-style #f (list (make-table-columns (list (make-style #f '(center)))))) (insert - (list (make-flow (list (make-paragraph (list spacer))))) + (list (make-paragraph plain (list spacer))) (map (lambda (line) (list - (make-flow - (list (make-table - #f + plain (list (insert - (make-flow (list (make-paragraph (list (hspace 3))))) + (make-paragraph plain (list (hspace 3))) (map (lambda (line) - (make-flow - (list (call-with-values (lambda () (apply values (regexp-split " iff " line))) (case-lambda [(bottom top) (make-table - '((alignment center) - (row-styles "inferencetop" "inferencebottom")) + (make-style #f + (list + (make-table-cells (list (list (make-style "inferencetop" '(center))) + (list (make-style "inferencebottom" '(center))))))) (list - (list (make-flow (list (make-paragraph (append (list spacer) (fixup-type top) (list spacer)))))) - (list (make-flow (list (make-paragraph (append (list spacer) (fixup-type bottom) (list spacer))))))))] + (list (make-paragraph plain (append (list spacer) (fixup-type top) (list spacer)))) + (list (make-paragraph plain (append (list spacer) (fixup-type bottom) (list spacer))))))] [(single) - (make-paragraph - (fixup-type line))]))))) - line)))))))) + (make-paragraph plain (fixup-type line))]))) + line)))))) lines))))) (provide type-table)) diff --git a/collects/scribblings/scribble/base.scrbl b/collects/scribblings/scribble/base.scrbl new file mode 100644 index 0000000000..a6beca5e12 --- /dev/null +++ b/collects/scribblings/scribble/base.scrbl @@ -0,0 +1,494 @@ +#lang scribble/doc +@(require scribble/manual + "utils.ss" + (for-syntax scheme/base) + (for-label setup/main-collects)) + +@(define-syntax def-section-like + (syntax-rules () + [(_ id result/c x ...) + (defproc (id [#:tag tag (or/c false/c string? (listof string?)) #f] + [#:tag-prefix tag-prefix (or/c false/c string? module-path?) #f] + [#:style style (or/c style? #f string? symbol? (listof symbol?)) #f] + [pre-content pre-content?] (... ...+)) + result/c + x ...)])) + +@(define-syntax def-elem-proc + (syntax-rules () + [(_ id x ...) + (defproc (id [pre-content pre-content?] (... ...)) + element? + x ...)])) +@(define-syntax def-style-proc + (syntax-rules () + [(_ id) + @def-elem-proc[id]{Like @scheme[elem], but with style @scheme['id].}])) + +@title[#:tag "base"]{Base Document Forms} + +@defmodule[scribble/base]{The @schememodname[scribble/base] library +provides functions and forms that can be used from code written either +in Scheme or with @elem["@"] expressions. + +The @schememodname[scribble/base] name can also be used as a +language with @hash-lang[]. It acts like the +@schememodname[scribble/doc] language, except that the +@schememodname[scribble/base] library is also required into +the module.} + +Functions provided by this library, such as @scheme[title] and +@scheme[italic], might be called from Scheme as + +@schemeblock[ +(title #:tag "how-to" + "How to Design " (italic "Great") " Programs") +] + +They can also be called with @elem["@"] notation as + +@verbatim[#:indent 2]|{ + @title[#:tag "how-to"]{How to Design @italic{Great} Programs} +}| + +Although the procedures are mostly design to be used from @elem["@"] +mode, they are easier to document in Scheme mode (partly because we +have @schememodname[scribble/manual]). + +@; ------------------------------------------------------------------------ + +@section{Document Structure} + +@defproc[(title [#:tag tag (or/c false/c string? (listof string?)) #f] + [#:tag-prefix tag-prefix (or/c false/c string? module-path?) #f] + [#:style style (or/c style? #f string? symbol? (listof symbol?)) #f] + [#:version vers (or/c string? false/c) #f] + [pre-content pre-content?] ...+) + title-decl?]{ + +Generates a @scheme[title-decl] to be picked up by @scheme[decode] or +@scheme[decode-part]. The @tech{decode}d @scheme[pre-content] (i.e., +parsed with @scheme[decode-content]) supplies the title content. If +@scheme[tag] is @scheme[#f], a tag string is generated automatically +from the content. The tag string is combined with the symbol +@scheme['part] to form the full tag. + +The @scheme[style] argument can be a style structure, or it can be one +of the following: a @scheme[#f] that corresponds to a ``plain'' style, +a string that is used as a @tech{style name}, a symbol that is used as +a @tech{variant}, or a list of symbols to be used as @tech{variants}. +For information on styles, see @scheme[part]. For example, a style of +@scheme['toc] causes sub-sections to be generated as separate pages in +multi-page HTML output. + +The @scheme[tag-prefix] argument is propagated to the generated +structure (see @secref["tags"]). If @scheme[tag-prefix] is a module +path, it is converted to a string using +@scheme[module-path-prefix->string]. + +The @scheme[vers] argument is propagated to the @scheme[title-decl] +structure. Use @scheme[""] as @scheme[vers] to suppress version +rendering in the output. + +The section title is automatically indexed by +@scheme[decode-part]. For the index key, leading whitespace and a +leading ``A'', ``An'', or ``The'' (followed by more whitespace) is +removed.} + + +@def-section-like[section part-start?]{ Like @scheme[title], but + generates a @scheme[part-start] of depth @scheme[0] to be by + @scheme[decode] or @scheme[decode-part].} + +@def-section-like[subsection part-start?]{ Like @scheme[section], but + generates a @scheme[part-start] of depth @scheme[1].} + +@def-section-like[subsubsection part-start?]{ Like @scheme[section], but + generates a @scheme[part-start] of depth @scheme[2].} + +@def-section-like[subsubsub*section paragraph?]{ Similar to + @scheme[section], but merely generates a paragraph that looks like an + unnumbered section heading (for when the nesting gets too deep to + include in a table of contents).} + +@defform[(include-section module-path)]{ Requires @scheme[module-path] + and returns its @scheme[doc] export (without making any imports + visible to the enclosing context). Since this form expands to + @scheme[require], it must be used in a module or top-level context.} + +@defproc[(author [auth content?] ...) block?]{ + +Generates a @scheme[paragraph] with style name @scheme['author] to +show the author(s) of a document, where each author is represented by +@tech{content}. Normally, this function is used after +@scheme[title] for the beginning of a document. See also +@scheme[author+email].} + +@defproc[(author+email [author elem] [email string?]) element?]{ + +Combines an author name with an e-mail address, obscuring the e-mail +address slightly to avoid address-harvesting robots.} + +@; ------------------------------------------------------------------------ + +@section{Blocks} + +@defproc[(para [#:style style (or/c style? string? symbol? #f)] + [pre-content pre-content?] ...) paragraph?]{ + + Creates a @tech{paragraph} containing the @tech{decode}d + @scheme[pre-content] (i.e., parsed with @scheme[decode-paragraph]). + + The @scheme[style] argument can be a style, @scheme[#f] to indicate a + ``plain'' style, a string that is used as a @tech{style name}, or a + symbol that is used as a @tech{style name}. (Note that + @scheme[section] and @scheme[para] treat symbols differently as + @scheme[style] arguments.)} + + +@defproc[(nested [#:style style (or/c style? string? symbol? #f)] + [pre-flow pre-flow?] ...) nested-flow?]{ + + Creates a @tech{nested flow} containing the @tech{decode}d + @scheme[pre-flow] (i.e., parsed with @scheme[decode-flow]). + + The @scheme[style] argument is handled the same as @scheme[para]. + The @scheme['inset] style causes the nested flow to be inset compared + to surrounding text.} + + +@defproc[(centered [pre-flow pre-flow?] ...) nested-flow?]{ + +Produces a @tech{nested flow} whose content is centered.} + + +@defproc[(margin-note [pre-content pre-content?] ...) blockquote?]{ + +Produces a @tech{nested flow} that is typeset in the margin, instead +of inlined.} + + +@defproc[(itemlist [itm item?] ... + [#:style style (or/c style? string? symbol? #f) #f]) + itemization?]{ + + Constructs an @scheme[itemization] given a sequence of items + constructed by @scheme[item]. + + The @scheme[style] argument is handled the same as @scheme[para]. The + @scheme['ordered] style numbers items, instead of just using a + bullet.} + + +@defproc[(item [pre-flow pre-flow?] ...) item?]{ + +Creates an item for use with @scheme[itemlist]. The @tech{decode}d +@scheme[pre-flow] (i.e., parsed with @scheme[decode-flow]) is the item +content.} + + +@defproc[(item? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is an item produced by +@scheme[item], @scheme[#f] otherwise.} + + +@defproc[(tabular [cells (listof (listof (or/c block? content? 'cont)))] + [#:style style (or/c style? string? symbol? #f) #f]) + table?]{ + +Creates a @tech{table} with the given content, which is supplies as a +list of rows, where each row has a list of cells. The length of all +rows must match. + +Use @scheme['cont] as a cell to continue the content of the preceding +cell in a row in the space that would otherwise be used for a new +cell. A @scheme['cont] must not appear as the first cell in a row. + +The @scheme[style] argument is handled the same as @scheme[para].} + +@defproc[(verbatim [#:indent indent exact-nonnegative-integer? 0] [str string?] ...+) + block?]{ + +Typesets @scheme[str]s in typewriter font with the linebreaks +specified by newline characters in @scheme[str]. Consecutive spaces in +the @scheme[str]s are converted to @scheme[hspace] to ensure that they +are all preserved in the output. Additional space (via +@scheme[hspace]) as specified by @scheme[indent] is added to the +beginning of each line. + +The @scheme[str]s are @emph{not} decoded with @scheme[decode-content], +so @scheme[(verbatim "---")] renders with three hyphens instead of an +em-dash. Beware, however, that @litchar["@"] for a @scheme[verbatim] +call performs some processing before delivering arguments to +@scheme[verbatim]. The @scheme[verbatim] form is typically used with +@litchar["|{"]...@litchar["}|"] or similar brackets to disable +@litchar["@"] notation within the @scheme[verbatim] argument, like +this: + +@verbatim[#:indent 2]|{ + @verbatim|{ + Use @bold{---} like this... + }| +}| + +which renders as + +@verbatim[#:indent 2]|{ + Use @bold{---} like this... +}| + +Even with @litchar["|{"]...@litchar["}|"], beware that consistent +leading whitespace is removed; see @secref["alt-body-syntax"] for more +information. + +See also @scheme[literal].} + +@; ------------------------------------------------------------------------ + +@section{Text Styles and Content} + +@defproc[(elem [pre-content pre-content?] ... + [#:style style (or style? string? symbol? #f) #f]) + element?]{ + +Wraps the @tech{decode}d @scheme[pre-content] as an element with style +@scheme[style].} + + +@def-style-proc[italic] +@def-style-proc[bold] +@def-style-proc[tt] +@def-style-proc[subscript] +@def-style-proc[superscript] + +@def-elem-proc[smaller]{Like @scheme[elem], but with style +@scheme['smaller]. When uses of @scheme[smaller] are nested, text +gets progressively smaller.} + +@def-elem-proc[larger]{Like @scheme[elem], but with style +@scheme['larger]. When uses of @scheme[larger] are nested, text +gets progressively larger.} + +@defproc[(emph [pre-content pre-content?] ...) element?]{ +The same as @scheme[italic].} + +@defproc[(hspace [n exact-nonnegative-integer?]) element?]{ + +Produces an element containing @scheme[n] spaces and style +@scheme['hspace].} + +@defproc[(literal [str string?] ...+) element?]{ + +Produces an element containing literally @scheme[str]s with no +decoding via @scheme[decode-content]. + +Beware that @litchar["@"] for a @scheme[literal] call performs some +processing before delivering arguments to @scheme[literal]. The +@scheme[literal] form can be used with @litchar["|{"]...@litchar["}|"] +or similar brackets to disable @litchar["@"] notation within the +@scheme[literal] argument, like this: + +@verbatim[#:indent 2]|{ + @literal|{@bold{---}}| +}| + +which renders as + +@verbatim[#:indent 2]|{ + @literal|{@bold{---}}| +}| + +See also @scheme[verbatim].} + + +@defproc[(image [path (or/c path-string? (cons/c 'collects (listof bytes?)))] + [#:scale scale real? 1.0] + [#:suffixes suffixes (listof #rx"^[.]") null] + [pre-content pre-content?] ...) + element?]{ + + Creates an image element from the given path. The @tech{decode}d + @scheme[pre-content] serves as the alternate text for contexts where + the image cannot be displayed. + + The path is relative to the current directory, which is set by + @exec{setup-plt} and @exec{scribble} to the directory of the main + document file. The @scheme[path] argument also can be a result of + @scheme[path->main-collects-relative]. + + The strings in @scheme[suffixes] are filtered to those supported by + given renderer, and then the acceptable suffixes are tried in + order. The HTML renderer supports @scheme[".png"] and + @scheme[".gif"], while the Latex renderer supports @scheme[".png"], + @scheme[".pdf"], and @scheme[".ps"] (but @scheme[".ps"] works only + when converting Latex output to DVI, and @scheme[".png"] and + @scheme[".pdf"] work only for converting Latex output to PDF).} + + +@; ------------------------------------------------------------------------ +@section[#:tag "base-links"]{Links} + +@defproc[(hyperlink [url string?] [pre-content pre-content?] ... + [#:underline? underline? any/c #t] + [#:style style (or/c style? string? symbol? #f) (if underline? #f "plainlink")]) + element?]{ + +The @tech{decode}d @scheme[pre-content] is hyperlinked to +@scheme[url]. If @scheme[style] is not supplied, then +@scheme[underline?] determines how the link is rendered.} + + +@defproc[(url [dest string?]) element?]{ + +Generates a literal hyperlinked URL.} + + +@defproc[(secref [tag string?] + [#:doc module-path (or/c module-path? false/c) #f] + [#:tag-prefixes prefixes (or/c (listof string?) false/c) #f] + [#:underline? underline? any/c #t]) + element?]{ + +Inserts the hyperlinked title of the section tagged @scheme[tag], but +elements in the title content with the @scheme['aux] @tech{variant} +are omitted in the hyperlink label. + +If @scheme[#:doc module-path] is provided, the @scheme[tag] refers to +a tag with a prefix determined by @scheme[module-path]. When +@exec{setup-plt} renders documentation, it automatically adds a tag +prefix to the document based on the source module. Thus, for example, +to refer to a section of the PLT Scheme reference, +@scheme[module-path] would be @scheme['(lib +"scribblings/reference/reference.scrbl")]. + +The @scheme[#:tag-prefixes prefixes] argument similarly supports +selecting a particular section as determined by a path of tag +prefixes. When a @scheme[#:doc] argument is provided, then +@scheme[prefixes] should trace a path of tag-prefixed subsections to +reach the @scheme[tag] section. When @scheme[#:doc] is not provided, +the @scheme[prefixes] path is relative to any enclosing section (i.e., +the youngest ancestor that produces a match). + +If @scheme[underline?] is @scheme[#f], then the hyperlink is rendered +in HTML without an underline.} + + +@defproc[(seclink [tag string?] + [#:doc module-path (or/c module-path? false/c) #f] + [#:tag-prefixes prefixes (or/c (listof string?) false/c) #f] + [#:underline? underline? any/c #t] + [pre-content pre-content?] ...) element?]{ + +Like @scheme[secref], but the link label is the @tech{decode}d +@scheme[pre-content] instead of the target section's name.} + + +@defproc[(other-doc [module-path module-path?] + [#:underline? underline? any/c #t]) + element?]{ + +Like @scheme[secref] for the document's implicit @scheme["top"] +tag. Use this function to refer to a whole manual instead of +@scheme[secref], in case a special style in the future is used for +manual titles.} + + +@defproc[(elemtag [t (or/c tag? string?)] [pre-content pre-content?] ...) element?]{ + +The tag @scheme[t] refers to the content form of +@scheme[pre-content].} + + +@defproc[(elemref [t (or/c tag? string?)] [pre-content pre-content?] ... + [#:underline? underline? any/c #t]) element?]{ + +The @tech{decode}d @scheme[pre-content] is hyperlinked to @scheme[t], +which is normally defined using @scheme[elemtag].} + +@defproc[(module-path-prefix->string [mod-path module-path?]) + string?]{ + +Converts a module path to a string by resolving it to a path, and +using @scheme[path->main-collects-relative].} + +@; ------------------------------------------------------------------------ + +@section[#:tag "base-indexing"]{Indexing} + +@defproc[(index [words (or/c string? (listof string?))] + [pre-content pre-content?] ...) + index-element?]{ + +Creates an index element given a plain-text string---or list of +strings for a hierarchy, such as @scheme['("strings" "plain")] for a +``plain'' entry below a more general ``strings'' entry. As index keys, +the strings are ``cleaned'' using @scheme[clean-up-index-strings]. The +strings (without clean-up) also serve as the text to render in the +index. The @tech{decode}d @scheme[pre-content] is the text to appear +inline as the index target. + +Use @scheme[index] when an index entry should point to a specific word +or phrase within the typeset document (i.e., the +@scheme[pre-content]). Use @scheme[section-index], instead, to create +an index entry that leads to a section, instead of a specific word or +phrase within the section.} + + +@defproc[(index* [words (listof string?)] + [word-contents (listof list?)] + [pre-content pre-content?] ...) + index-element?]{ +Like @scheme[index], except that @scheme[words] must be a list, and +the list of contents render in the index (in parallel to +@scheme[words]) is supplied as @scheme[word-contents]. +} + +@defproc[(as-index [pre-content pre-content?] ...) + index-element?]{ + +Like @scheme[index], but the word to index is determined by applying +@scheme[content->string] on the @tech{decode}d @scheme[pre-content].} + + +@defproc[(section-index [word string?] ...) + part-index-decl?]{ + +Creates a @scheme[part-index-decl] to be associated with the enclosing +section by @scheme[decode]. The @scheme[word]s serve as both the keys +and as the rendered forms of the keys within the index.} + + +@defproc[(index-section [#:tag tag (or/c false/c string?) "doc-index"]) + part?]{ + +Produces a part that shows the index the enclosing document. The +optional @scheme[tag] argument is used as the index section's tag.} + + +@; ------------------------------------------------------------------------ + +@section{Tables of Contents} + +@defproc[(table-of-contents) delayed-block?]{ + +Returns a delayed flow element that expands to a table of contents for +the enclosing section. For Latex output, however, the table of +contents currently spans the entire enclosing document.} + + +@defproc[(local-table-of-contents [#:style style (or/c symbol? #f) #f]) + delayed-block?]{ + +Returns a delayed flow element that may expand to a table of contents +for the enclosing section, depending on the output type. For +multi-page HTML output, the flow element is a table of contents; for +Latex output, the flow element is empty. + +The meaning of the @scheme[style] argument depends on the output type, +but @scheme['immediate-only] normally creates a table of contents that +contains only immediate sub-sections of the enclosing section. See +also the @scheme['quiet] style of @scheme[part] (i.e., in a +@scheme[part] structure, not supplied as the @scheme[style] argument +to @scheme[local-table-of-contents]), which normally suppresses +sub-part entries in a table of contents.} diff --git a/collects/scribblings/scribble/basic.scrbl b/collects/scribblings/scribble/basic.scrbl index ddf32095c3..8eebd3de90 100644 --- a/collects/scribblings/scribble/basic.scrbl +++ b/collects/scribblings/scribble/basic.scrbl @@ -1,265 +1,27 @@ -#lang scribble/doc -@(require scribble/manual - "utils.ss" - (for-syntax scheme/base) - (for-label setup/main-collects)) +#lang scribble/manual +@(require "utils.ss" + (for-label (only-in scribble/basic span-class))) -@(define-syntax def-section-like - (syntax-rules () - [(_ id result/c x ...) - (defproc (id [#:tag tag (or/c false/c string?) #f] - [#:tag-prefix tag-prefix (or/c false/c string? module-path?) #f] - [#:style style any/c #f] - [pre-content any/c] (... ...+)) - result/c - x ...)])) +@(define (compat) + @italic{For backward compatibility.}) -@(define-syntax def-elem-proc - (syntax-rules () - [(_ id x ...) - (defproc (id [pre-content any/c] (... ...)) - element? - x ...)])) -@(define-syntax def-style-proc - (syntax-rules () - [(_ id) - @def-elem-proc[id]{Like @scheme[elem], but with style @scheme['id].}])) - -@title[#:tag "basic"]{Basic Document Forms} - -@defmodule[scribble/basic]{The @schememodname[scribble/basic] library -provides functions and forms that can be used from code written either -in Scheme or with @elem["@"] expressions.} - -For example, the @scheme[title] and @scheme[italic] functions might be -called from Scheme as - -@schemeblock[ -(title #:tag "how-to" - "How to Design " (italic "Great") " Programs") -] - -or with an @elem["@"] expression as - -@verbatim[#:indent 2]|{ - @title[#:tag "how-to"]{How to Design @italic{Great} Programs} -}| - -Although the procedures are mostly design to be used from @elem["@"] -mode, they are easier to document in Scheme mode (partly because we -have @schememodname[scribble/manual]). - -@; ------------------------------------------------------------------------ - -@section{Document Structure} - -@defproc[(title [#:tag tag (or/c false/c string?) #f] - [#:tag-prefix tag-prefix (or/c false/c string? module-path?) #f] - [#:style style any/c #f] - [#:version vers (or/c string? false/c) #f] - [pre-content any/c] ...+) - title-decl?]{ - -Generates a @scheme[title-decl] to be picked up by @scheme[decode] or -@scheme[decode-part]. The @tech{decode}d @scheme[pre-content] (i.e., -parsed with @scheme[decode-content]) supplies the title content. If -@scheme[tag] is @scheme[#f], a tag string is generated automatically -from the content. The tag string is combined with the symbol -@scheme['part] to form the full tag. - -A style of @scheme['toc] causes sub-sections to be generated as -separate pages in multi-page HTML output. A style of @scheme['index] -indicates an index section whose body is rendered in two columns for -Latex output. - -The @scheme[tag-prefix] argument is propagated to the generated -structure (see @secref["tags"]). If @scheme[tag-prefix] is a module -path, it is converted to a string using -@scheme[module-path-prefix->string]. - -The @scheme[vers] argument is propagated to the @scheme[title-decl] -structure. Use @scheme[""] as @scheme[vers] to suppress version -rendering in the output. - -The section title is automatically indexed by -@scheme[decode-part]. For the index key, leading whitespace and a -leading ``A'', ``An'', or ``The'' (followed by more whitespace) is -removed.} - - -@def-section-like[section part-start?]{ Like @scheme[title], but - generates a @scheme[part-start] of depth @scheme[0] to be by - @scheme[decode] or @scheme[decode-part].} - -@def-section-like[subsection part-start?]{ Like @scheme[section], but - generates a @scheme[part-start] of depth @scheme[1].} - -@def-section-like[subsubsection part-start?]{ Like @scheme[section], but - generates a @scheme[part-start] of depth @scheme[2].} - -@def-section-like[subsubsub*section paragraph?]{ Similar to - @scheme[section], but merely generates a paragraph that looks like an - unnumbered section heading (for when the nesting gets too deep to - include in a table of contents).} - -@defproc[(itemize [itm (or/c whitespace? an-item?)] ... - [#:style style any/c #f]) itemization?]{ - - Constructs an @scheme[itemization] or (when @scheme[style] is not - @scheme[#f]) @scheme[styled-itemization] given a sequence of items - constructed by @scheme[item]. Whitespace strings among the - @scheme[itm]s are ignored. - - } - -@defproc[(item [pre-flow any/c] ...) item?]{ - -Creates an item for use with @scheme[itemize]. The @tech{decode}d -@scheme[pre-flow] (i.e., parsed with @scheme[decode-flow]) is the item -content.} - - -@defproc[(item? [v any/c]) boolean?]{ - -Returns @scheme[#t] if @scheme[v] is an item produced by -@scheme[item], @scheme[#f] otherwise.} - - -@defform[(include-section module-path)]{ Requires @scheme[module-path] - and returns its @scheme[doc] export (without making any imports - visible to the enclosing context). Since this form expands to - @scheme[require], it must be used in a module or top-level context.} - -@defproc[(author [auth any/c] ...) block?]{ - -Generates a @scheme[styled-paragraph] to show the author(s) of a -document, where each author is represented by an -@tech{element}. Normally, this function is used after @scheme[title] -for the beginning of a document. See also @scheme[author+email].} - -@defproc[(author+email [author elem] [email string?]) element?]{ - -Combines an author name with an e-mail address, obscuring the e-mail -address slightly to avoid address-harvesting robots.} - -@defproc[(module-path-prefix->string [mod-path module-path?]) - string?]{ - -Converts a module path to a string by resolving it to a path, and -using @scheme[path->main-collects-relative].} - - -@; ------------------------------------------------------------------------ - -@section{Text Styles} - -@defproc[(elem [pre-content any/c] ... - [#:style style any/c #f]) - element?]{ - -Wraps the @tech{decode}d @scheme[pre-content] as an element with style -@scheme[style].} - -@def-elem-proc[aux-elem]{Like @scheme[elem], but creates an -@scheme[aux-element].} - -@def-style-proc[italic] -@def-style-proc[bold] -@def-style-proc[tt] -@def-style-proc[subscript] -@def-style-proc[superscript] - -@def-elem-proc[smaller]{Like @scheme[elem], but with style -@scheme["smaller"]. When uses of @scheme[smaller] are nested, text -gets progressively smaller.} - -@defproc[(hspace [n exact-nonnegative-integer?]) element?]{ - -Produces an element containing @scheme[n] spaces and style -@scheme['hspace].} +@title[#:tag "basic"]{Compatibility Basic Functions} +@defmodule[scribble/basic]{The @schememodname[scribble/basic] +compatibility library mostly just re-exports +@schememodname[scribble/base].} @defproc[(span-class [style-name string?] [pre-content any/c] ...) element?]{ -Wraps the @tech{decode}d @scheme[pre-content] as an element with style -@scheme[style-name].} - -@; ------------------------------------------------------------------------ - -@section{Indexing} - -@defproc[(index [words (or/c string? (listof string?))] - [pre-content any/c] ...) - index-element?]{ - -Creates an index element given a plain-text string---or list of -strings for a hierarchy, such as @scheme['("strings" "plain")] for a -``plain'' entry below a more general ``strings'' entry. As index keys, -the strings are ``cleaned'' using @scheme[clean-up-index-strings]. The -strings (without clean-up) also serve as the text to render in the -index. The @tech{decode}d @scheme[pre-content] is the text to appear -inline as the index target. - -Use @scheme[index] when an index entry should point to a specific word -or phrase within the typeset document (i.e., the -@scheme[pre-content]). Use @scheme[section-index], instead, to create -an index entry that leads to a section, instead of a specific word or -phrase within the section.} +@compat[] Wraps the @tech{decode}d +@scheme[pre-content] as an element with style @scheme[style-name].} -@defproc[(index* [words (listof string?)] - [word-contents (listof list?)] - [pre-content any/c] ...) - index-element?]{ -Like @scheme[index], except that @scheme[words] must be a list, and -the list of contents render in the index (in parallel to -@scheme[words]) is supplied as @scheme[word-contents]. -} -@defproc[(as-index [pre-content any/c] ...) - index-element?]{ +@defproc[(itemize [itm (or/c whitespace? an-item?)] ... + [#:style style (or/c style? string? symbol? #f) #f]) + itemization?]{ -Like @scheme[index], but the word to index is determined by applying -@scheme[content->string] on the @tech{decode}d @scheme[pre-content].} - - -@defproc[(section-index [word string?] ...) - part-index-decl?]{ - -Creates a @scheme[part-index-decl] to be associated with the enclosing -section by @scheme[decode]. The @scheme[word]s serve as both the keys -and as the rendered forms of the keys within the index.} - - -@defproc[(index-section [#:tag tag (or/c false/c string?) "doc-index"]) - part?]{ - -Produces a part that shows the index the enclosing document. The -optional @scheme[tag] argument is used as the index section's tag.} - - -@; ------------------------------------------------------------------------ - -@section{Tables of Contents} - -@defproc[(table-of-contents) delayed-block?]{ - -Returns a delayed flow element that expands to a table of contents for -the enclosing section. For LaTeX output, however, the table of -contents currently spans the entire enclosing document.} - - -@defproc[(local-table-of-contents [#:style style any/c #f]) - delayed-block?]{ - -Returns a delayed flow element that may expand to a table of contents -for the enclosing section, depending on the output type. For -multi-page HTML output, the flow element is a table of contents; for -Latex output, the flow element is empty. - -The meaning of the @scheme[style] argument depends on the output type, -but @scheme['immediate-only] normally creates a table of contents that -contains only immediate sub-sections of the enclosing section. See -also the @scheme['quiet] style of @scheme[part], which normally -suppresses sub-part entries in the table of contents.} +@compat[] Like @scheme[itemlist], but whitespace strings among the +@scheme[itm]s are ignored.} diff --git a/collects/scribblings/scribble/compat.scrbl b/collects/scribblings/scribble/compat.scrbl new file mode 100644 index 0000000000..45d8f1c94a --- /dev/null +++ b/collects/scribblings/scribble/compat.scrbl @@ -0,0 +1,6 @@ +#lang scribble/manual + +@title{Compatibility Libraries} + +@include-section["struct.scrbl"] +@include-section["basic.scrbl"] diff --git a/collects/scribblings/scribble/config.scrbl b/collects/scribblings/scribble/config.scrbl index 9b930c8f2f..ed8e92dbc8 100644 --- a/collects/scribblings/scribble/config.scrbl +++ b/collects/scribblings/scribble/config.scrbl @@ -1,12 +1,12 @@ #lang scribble/doc @(require scribble/manual - scribble/struct + scribble/core scribble/decode + scribble/html-variants + scribble/latex-variants "utils.ss" (for-label scheme/base)) -@(define (nested . str) - (make-blockquote #f (flow-paragraphs (decode-flow str)))) @(define (fake-title . str) (apply bold str)) @title[#:tag "config"]{Extending and Configuring Scribble Output} @@ -18,66 +18,87 @@ extend or configure Scribble fall into two groups: @itemize[ @item{You may need to drop into the back-end ``language'' of CSS or - Tex to create a specific output effect. For this kind of - extension, you will mostly likely attach a @scheme[`(css - ,_file)] or @scheme[`(tex ,_file)] style to a @scheme[section] - and then use a string defined in the @scheme[_file] as an - @scheme[element] or @tech{block} style. This kind of extension - is described in @secref["extra-style"].} + Latex to create a specific output effect. For this kind of + extension, you will mostly likely attach a + @scheme[css-addition] or @scheme[tex-addition] @tech{variant} + to style, where the addition implements the style name. This + kind of extension is described in @secref["extra-style"].} @item{You may need to produce a document whose page layout is different from the PLT Scheme documentation style. For that - kind of configuration, you will most likely run the - @exec{scribble} command-line tool and supply flags like - @DFlag{prefix} or @DPFlag{style}. This kind of configuration - is described in @secref["config-style"].} + kind of configuration, you can run the @exec{scribble} command-line + tool and supply flags like @DFlag{prefix} or @DPFlag{style}, or + you can associate a @scheme[html-defaults] or + @scheme[latex-defaults] @tech{variant} to the main document's + style. This kind of configuration is described in + @secref["config-style"].} ] @; ------------------------------------------------------------ @section[#:tag "extra-style" - #:style `((css "inbox.css") (tex "inbox.tex"))]{Adding a Style} + #:style (make-style #f (list (make-css-addition "inbox.css") + (make-tex-addition "inbox.tex"))) + ]{Implementing Styles} -When a string is uses as a style in an @scheme[element], -@scheme[styled-paragraph], @scheme[table], -@scheme[styled-itemization], @scheme[blockquote], or @scheme[compound-paragraph], it corresponds to -a CSS class for HTML output or a Tex macro/environment for Latex -output. In Latex output, the string is used as a command name for a -@scheme[styled-paragraph] and an environment name for a -@scheme[table], @scheme[itemization], @scheme[blockquote], or @scheme[compound-paragraph], except -that a @scheme[blockquote] or @scheme[compound-paragraph] style name that starts with @litchar{\} is -used (sans @litchar{\}) as a command instead of an environment. -In addition, for an itemization, the style string is -suffixed with @scheme["Item"] and used as a CSS class or Tex macro -name to use for the itemization's items (in place of @tt{item} in the -case of Latex). - -Scribble includes a number of predefined styles that are used by the -exports of @scheme[scribble/manual], but they are not generally -intended for direct use. For now, use them or redefine them at your -own risk. +When a string is uses as a style in an @scheme[element], +a @scheme[multiarg-element], @scheme[paragraph], @scheme[table], +@scheme[itemization], @scheme[nested-flow], or +@scheme[compound-paragraph], it corresponds to a CSS class for HTML +output or a Latex macro/environment for Latex output. In Latex output, +the string is used as a command name for a @scheme[paragraph] +and an environment name for a @scheme[table], @scheme[itemization], +@scheme[nested-flow], or @scheme[compound-paragraph]; the if style has +a @scheme['commad] @tech{variant} for a @scheme[nested-flow] or +@scheme[compound-paragraph], then the style name is used as a command +instead of an environment. In addition, for an itemization, the style +string is suffixed with @scheme["Item"] and used as a CSS class or Latex +macro name to use for the itemization's items (in place of @tt{item} +in the case of Latex). To add a mapping from your own style name to a CSS configuration, add -a @scheme[`(css ,_file)] style (in a list of styles) to an enclosing -@scheme[part]. To map a style name to a Tex macro (or Latex -environment), add a @scheme[`(tex ,_file)] style to an enclosing part. +a @scheme[css-addition] structure instance to a style's @tech{variant} +list. To map a style name to a Latex macro or environment, add a +scheme[tex-addition] structure instance. A @scheme[css-addition] or +@scheme[tex-addition] is normally associated with the style whose name +is implemented by the adition, but it can also be added to the style +for an enclosing part. + +Scribble includes a number of predefined styles that are used by the +exports of @scheme[scribble/base]. You can use them or redefine +them. The styles are specified by @filepath{scribble.css} and +@filepath{scribble.tex} in the @filepath{scribble} collection. + +The styles used by @schememodname[scribble/manual] are implemented by +@filepath{scheme.css} and @filepath{scheme.tex} in the +@filepath{scribble} collection. Other libraries, such as +@schememodname[scriblib/autobib], similarly implement styles through files +that are associated by @scheme[css-addition] and @scheme[tex-addition] +@tech{variants}. To avoid collisions with future additions to Scribble, start your style name with an uppercase letter that is not @litchar{S}. An uppercase letter helps to avoid collisions with macros defined by -Latex packages, and future styles needed by @scheme[scribble/manual] -will start with @litchar{S}. +Latex packages, and future styles needed by @schememodname[scribble/base] and +@schememodname[scribble/manual] will start with @litchar{S}. For example, a Scribble document @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require manual) + #lang scribble/manual + @(require scribble/core + scribble/html-variants + scribble/latex-variants) - @title[#:style `((css "inbox.css") (tex "inbox.tex"))]{Quantum Pet} + (define inbox-style + (make-style "InBox" + (list (make-css-addition "inbox.css") + (make-tex-addition "inbox.tex")))) - Do not open: @elem[#:style "InBox"]{Cat} + @title{Quantum Pet} + + Do not open: @elem[#:style inbox-style]{Cat} }| combined with an @filepath{inbox.css} that contains @@ -97,7 +118,7 @@ and an @filepath{inbox.tex} that contains generates -@nested{ +@nested[#:style 'inset]{ @fake-title{Quantum Pet} Do not open: @elem[#:style "InBox"]{Cat} @@ -107,38 +128,87 @@ generates @section[#:tag "config-style"]{Configuring Output} -Scribble's output is configured in two layers: +The implementation of styles used by libraries depends to some degree +on separately configurable parameters, and configuration is also +possible by replacing style implementations. Latex output is more +configurable in the former way, since a document class determines a +set of page-layout and font properties that are used by other +commands. The style-replacement kind of configuration corresponds to +re-defining Latex macros or overriding CSS class attributes. When +@exec{setup-plt} builds PDF documentation, it uses both kinds of +configuration to produce a standard layout for PLT Scheme manuals; +that is, it selects a particular page layout, and it replaces some +@schememodname[scheme/base] styles. + +Two kinds of files implement the two kinds of configuration: @itemize[ - @item{A prefix determines the @tt{DOCTYPE} line for HTML output or - the @tt{documentclass} configuration (and perhaps some addition - package uses or other configuration) for Latex output. The - default prefix is @filepath{scribble-prefix.html} or - @filepath{scribble-prefix.tex} in the @filepath{scribble} + @item{A @deftech{prefix file} determines the @tt{DOCTYPE} line for + HTML output or the @tt{documentclass} configuration (and + perhaps some addition package uses or other configurations) for + Latex output. + + The default prefix files are @filepath{scribble-prefix.html} + and @filepath{scribble-prefix.tex} in the @filepath{scribble} collection.} - @item{Style definitions for all of the ``built-in'' styles used by - @scheme[scribble/manual] (as described in - @secref["extra-style"]). The default style definitions are - @filepath{scribble.css} or @filepath{scribble.tex} in the - @filepath{scribble} collection.} + @item{A @deftech{style file} refines the implementation of styles + nused in the document---typically just the ``built-in'' styles + used by @schememodname[scribble/base]. + + The default style files, @filepath{scribble-style.css} and + @filepath{scribble-style.tex} in the @filepath{scribble} + collection, change no style implementations.} ] -When using the @exec{scribble} command-line utility: +For a given configuration of output, typically a particular prefix +file works with a particular style file. Some prefix or style files +may be more reusable. For now, reading the default files is the best +way to understand how they interact. A prefix and/or style file may +also require extra accomanying files; for example, a prefix file for +Latex mode may require a corresponding Latex class file. The default +prefix and style files require no extra files. + +When rendering a document through the @exec{scribble} command-line +tool, use flags to select a prefix file, style file, and additional +accompanying files: @itemize[ - @item{Replace the prefix using the @as-index{@DFlag{prefix}} flag.} + @item{Select the prefix file using the @as-index{@DFlag{prefix}} + flag. (Selecting the prefix file also cancels the default list + of accompanying files, if any.)} - @item{Replace the style definitions using the - @as-index{@DFlag{style}} flag.} + @item{Replace the style file using the @as-index{@DFlag{style}} + flag. Add additional style definitions and re-definitions using + the @as-index{@DPFlag{style}} flag.} - @item{Add style definitions (that can override earlier ones) - using the @as-index{@DPFlag{style}} flag.} + @item{Add additional accompanying files with @as-index{@DFlag{extra}}.} ] -For now, reading the default files is the best way to understand how -they interact. +When using the @exec{scribble} command-line utility, a document can +declare its default style, prefix, and extra files through a +@scheme[html-defaults] and/or @scheme[latex-defaults] style +@tech{variant}. In particular, when using the @exec{scribble} +command-line tool to generate Latex or PDF a document whose main part +is implemented with @scheme[#, @hash-lang[] #, +@schememodname[scribble/manual]], the result has the standard PLT +Scheme manual configuration, because @schememodname[scribble/manual] +associates a @scheme[latex-defaults] @tech{variant} with the exported +document. The @schememodname[scribble/sigplan] language similarly +associates a default configuration with an exported document. As +libraries imported with @scheme[require], however, +@schememodname[scribble/manual] and @schememodname[scribble/sigplan] +simply implement new styles in a composable way. + +Whether or not a document has a default prefix- and style-file +configuration through a style @tech{variant}, the defaults can be +overridden using @exec{scribble} command-line flags. Furthermore, +languages like @schememodname[scribble/manual] and +@schememodname[scribble/sigplan] add a @scheme[html-defaults] and/or +@scheme[latex-defaults] @tech{variant} to a main-document part only if +it does not already have such a variant added through the +@scheme[#:style] argument of @scheme[title]. diff --git a/collects/scribblings/scribble/core.scrbl b/collects/scribblings/scribble/core.scrbl new file mode 100644 index 0000000000..2c5c570443 --- /dev/null +++ b/collects/scribblings/scribble/core.scrbl @@ -0,0 +1,1153 @@ +#lang scribble/doc +@(require scribble/manual + "utils.ss" + (for-label scribble/manual-struct + setup/main-collects)) + +@title[#:tag "core"]{Structures And Processing} + +@defmodule[scribble/core] + +A document is represented as a @techlink{part}, as described in + @secref["parts"]. This representation is intended to + independent of its eventual rendering, and it is intended to be + immutable; rendering extensions and specific data in a document can + collude arbitrarily, however. + +A document is processed in three passes. The first pass is the + @deftech{collect pass}, which globally collects information in the + document, such as targets for hyperlinking. The second pass is the + @deftech{resolve pass}, which matches hyperlink references with + targets and expands delayed elements (where the expansion should not + contribute new hyperlink targets). The final pass is the + @deftech{render pass}, which generates the resulting document. None + of the passes mutate the document, but instead collect information in + side @scheme[collect-info] and @scheme[resolve-info] tables. + +@; ------------------------------------------------------------------------ + +@section[#:tag "parts"]{Parts} + +A @deftech{part} is an instance of @scheme[part]; among other things, + it has a title @techlink{content}, an initial @techlink{flow}, and a + list of subsection @techlink{parts}. There is no difference between + a part and a full document; a particular source module just as easily + defines a subsection (incorporated via @scheme[include-section]) as a + document. + +A @deftech{flow} is a list of @techlink{blocks}. + +A @deftech{block} is either a @techlink{table}, an + @techlink{itemization}, a @techlink{nested flow}, a @techlink{paragraph}, + a @techlink{compound paragraph}, or a @techlink{delayed block}. + +@itemize[ + + @item{A @deftech{table} is an instance of @scheme[table]; it + has a list of list of @techlink{blocks} corresponding to + table cells.} + + @item{A @deftech{itemization} is an instance of @scheme[itemization]; + it has a list of @techlink{flows}.} + + @item{A @deftech{nested flow} is an instance of + @scheme[nested-flow]; it has a @tech{flow} that + is typeset as sub-flow.} + + @item{A @deftech{paragraph} is an instance of + @scheme[paragraph]; it has a @tech{content}: + + @itemize[ + + @item{An @deftech{content} can be a string, one of a few + symbols, an instance of @scheme[element] (possibly + @scheme[link-element], etc.), a @scheme[multiarg-element], a + @techlink{part-relative element}, a + @techlink{delayed element}, or a list of content. + + @itemize[ + + @item{A string is included in the result + document verbatim, except for space, and + unless the content's enclosing @tech{style} is + @scheme['hspace]. In a style other than + @scheme['hspace], consecutive spaces in the + output may be collapsed togther or replaced + with a line break. In the style + @scheme['hspace], all text is converted to + uncollapsable spaces that cannot be broken + across lines.} + + @item{A symbol content is either @scheme['mdash], + @scheme['ndash], @scheme['ldquo], + @scheme['lsquo], @scheme['rsquo], @scheme['larr], + @scheme['rarr], or @scheme['prime]; it is + rendered as the corresponding HTML entity + (even for Latex output).} + + @item{An instance of @scheme[element] has a + @techlink{content} plus a @tech{style}. The style's + interpretation depends on the renderer, but it + can be one of a few special symbols (such as + @scheme['bold]) that are recognized by all + renderers.} + + @item{An instance of @scheme[link-element] has a + @techlink{tag} for the target of the link.} + + @item{An instance of @scheme[target-element] has a + @techlink{tag} to be referenced by + @scheme[link-element]s. An instance of the + subtype @scheme[toc-target-element] is + treated like a kind of section label, to be + shown in the ``on this page'' table for HTML + output.} + + @item{An instance of @scheme[index-element] has a + @techlink{tag} (as a target), a list of + strings for the keywords (for sorting and + search), and a list of @techlink{contents} to + appear in the end-of-document index.} + + @item{An instance of @scheme[image-element] + incorporates an image from a file into the rendered + document.} + + @item{An instance of @scheme[multiarg-element] + combines a style with a list of content, + where the style corresponds to a rendered + command that takes multiple arguments.} + + @item{An instance of @scheme[collect-element] has a + procedure that is called in the + @techlink{collect pass} of document + processing to record information used by + later passes.} + + @item{A @deftech{part-relative element} is an + instance of @scheme[part-relative-element], + which has a procedure that is called in the + @techlink{collect pass} of document + processing to obtain @defterm{content}. When the + part-relative element's procedure is called, + collected information is not yet available, + but information about the enclosing parts is + available.} + + @item{A @deftech{delayed element} is an instance of + @scheme[delayed-element], which has a + procedure that is called in the + @techlink{resolve pass} of document + processing to obtain @defterm{content}.} + + @item{An instance of @scheme[render-element] has a + procedure that is called in the + @techlink{render pass} of document + processing.} + + ]}]} + + @item{A @deftech{compound paragraph} is an instance of + @scheme[compound-paragraph]; like @scheme[blockquote], it + has list of @tech{blocks}, but the blocks are typeset as + a single paragraph (e.g., no indentation after the first + block) instead of inset.} + + @item{A @deftech{delayed block} is an instance of + @scheme[delayed-block], which has a procedure that + is called in the @techlink{resolve pass} of document + processing to obtain a @defterm{block}.} + +] + +@; ------------------------------------------------------------------------ + +@section[#:tag "tags"]{Tags} + +A @deftech{tag} is a list containing a symbol and either a string, a +@scheme[generated-tag] instance, or an arbitrary list. The symbol +effectively identifies the type of the tag, such as @scheme['part] for +a tag that links to a part, or @scheme['def] for a Scheme function +definition. The symbol also effectively determines the interpretation +of the second half of the tag. + +A part can have a @deftech{tag prefix}, which is effectively added +onto the second item within each tag whose first item is +@scheme['part] or @scheme['tech]. The prefix is added to a string +value by creating a list containing the prefix and string, and it is +added to a list value using @scheme[cons]; a prefix is not added to a +@scheme[generated-tag] instance. The prefix is used for reference +outside the part, including the use of tags in the part's +@scheme[tags] field. Typically, a document's main part has a tag +prefix that applies to the whole document; references to sections and +defined terms within the document from other documents must include the prefix, +while references within the same document omit the prefix. Part +prefixes can be used within a document as well, to help disambiguate +references within the document. + +Some procedures accept a ``tag'' that is just the string part of the +full tag, where the symbol part is supplied automatically. For +example, @scheme[section] and @scheme[secref] both accept a string +``tag'', where @scheme['part] is implicit. + +@; ------------------------------------------------------------------------ + +@section[#:tag "style"]{Styles} + +A @deftech{style} combines a @tech{style name} with a list of +@tech{variants} in a @scheme[style] structure. A @deftech{style name} +is either a string, symbol, of @scheme[#f]. A @deftech{variant} can be +anything, including a symbol a structure such as +@scheme[color-variant]. + +A style has a single @tech{style name}, because the name typically +corresponds to a configurable instruction to a renderer. For example, +with Latex output, a string style name corresponds to a Latex command +or environment. For more information on how string style names +interact with configuration of a renderer, see +@secref["config"]. Symbolic style names, meanwhile, provide a simple +layer of abstraction between the renderer and documents for widely +supported style; for example, the @scheme['italic] style name is +supported by all renderers. + +@tech{Variants} within a style compose with style names and other +variants. Again, symbols are often used for variants that are directly +supported by renderers. For example, @scheme['unnumbered] style +variant for a @tech{part} renders the part without a section number. +Many variants are renderer-specific, such as a @scheme[hover-variant] +structure that associates text with an element to be shown in an +HTML display when the mouse hovers over the text. + +@; ------------------------------------------------------------------------ + +@section[#:tag "passes"]{Collected and Resolved Information} + +The @techlink{collect pass}, @techlink{resolve pass}, and +@techlink{render pass} processing steps all produce information that +is specific to a rendering mode. Concretely, the operations are all +represented as methods on a @scheme[render%] object. + +The result of the @method[render% collect] method is a +@scheme[collect-info] instance. This result is provided back as an +argument to the @method[render% resolve] method, which produces a +@scheme[resolve-info] value that encapsulates the results from both +iterations. The @scheme[resolve-info] value is provided back to the +@method[render% resolve] method for final rendering. + +Optionally, before the @method[render% resolve] method is called, +serialized information from other documents can be folded into the +@scheme[collect-info] instance via the @method[render% +deserialize-info] method. Other methods provide serialized information +out of the collected and resolved records. + +During the @techlink{collect pass}, the procedure associated with a +@scheme[collect-element] instance can register information with +@scheme[collect-put!]. + +During the @techlink{resolve pass}, collected information for a part +can be extracted with @scheme[part-collected-info], which includes a +part's number and its parent part (or @scheme[#f]). More generally, +the @scheme[resolve-get] method looks up information previously +collected. This resolve-time information is normally obtained by the +procedure associated with a @techlink{delayed block} or +@techlink{delayed element}. + +The @scheme[resolve-get] information accepts both a @scheme[part] and +a @scheme[resolve-info] argument. The @scheme[part] argument enables +searching for information in each enclosing part before sibling parts. + +@; ------------------------------------------------------------------------ + +@section{Structure Reference} + +@defstruct[part ([tag-prefix (or/c false/c string?)] + [tags (listof tag?)] + [title-content (or/c false/c list?)] + [style style?] + [to-collect list?] + [blocks (listof block?)] + [parts (listof part?)])]{ + +The @scheme[tag-prefix] field determines the optional @techlink{tag +prefix} for the part. + +The @scheme[tags] indicates a list of @techlink{tags} that each link +to the section. + +The @scheme[title-content] field holds the part's title, if any. + +For the @scheme[style] field, the currently recognized symbolic style +names are as follows: + +@itemize[ + + @item{@scheme['index] --- The part represents an index.} + +] + +The recognized @tech{variants} are as follows: + +@itemize[ + + @item{@scheme['unnumbered] --- A section number is computed for an + unnumbered section during the @techlink{collect pass}, but the + number is not rendered.} + + @item{@scheme['toc] --- Sub-parts of the part are rendered on separate + pages for multi-page HTML mode.} + + @item{@scheme['non-toc] --- Initial sub-parts of the part are + @emph{not} rendered on separate pages for multi-page HTML + mode; this style applies only to the main part.} + + @item{@scheme['reveal] --- Shows sub-parts when this part is + displayed in a table-of-contents panel in HTML output (which + normally shows only the top-level sections).} + + @item{@scheme['hidden] --- The part title is not shown in rendered + HTML output.} + + @item{@scheme['quiet] --- In HTML output and most other output modes, + hides entries for sub-parts of this part in a + @scheme[table-of-contents] or @scheme[local-table-of-contents] + listing except when those sub-parts are top-level entries in + the listing.} + + @item{@scheme['no-toc] --- As a style for the main part of a + document, causes the HTML output to not include a margin box + for the main table of contents; the ``on this page'' box that + contains @scheme[toc-element] and @scheme[toc-target-element] + links (and that only includes an ``on this page'' label for + multi-page documents) takes on the location and color of the + main table of contents, instead.} + + @item{@scheme[document-version] structure --- A version number for + this part and its sub-parts (except as overridden). When it is + not @scheme[""] may be used when rendering a document; at a + minimum, a non-@scheme[""] version is rendered when it is + attached to a part representing the whole document. The default + version for a document is @scheme[(version)].} + + @item{@scheme[body-id] structure --- Generated HTML uses the given + string @tt{id} attribute of the @tt{body} tag; this style can + be set separately for parts that start different HTML pages, + otherwise it is effectively inherited by sub-parts; the + default is @scheme["scribble-plt-scheme.org"], but + @exec{setup-plt} installs @scheme["doc-plt-scheme.org"] as the + @tt{id} for any document that it builds.} + +] + +The @scheme[to-collect] field contains @techlink{content} that is +inspected during the @techlink{collect pass}, but ignored in later +passes (i.e., it doesn't directly contribute to the output). + +The @scheme[blocks] field contains the part's initial flow (before +sub-parts). + +The @scheme[parts] field contains sub-parts. + +} + + +@defstruct[paragraph ([style style?] [content content?])]{ + +A @techlink{paragraph} has a @tech{style} and a @tech{content}. + +For the @scheme[style] field, a string @tech{style name} corresponds +to a CSS class for HTML output or a macro for Latex output (see +@secref["extra-style"]). The following symbolic @tech{style names} are +recognized: + +@itemize[ + + @item{@scheme['author] --- Typeset as the author of a document. Such + paragraphs normally should appear only in the initial flow of a + @scheme[part] for a document, where they are treated specially + by the Latex renderer by moving the author information to the + title.} + +] + +The currently recognized style @tech{variants} are as follows: + +@itemize[ + + @item{@scheme['omitable] --- When a table cell contains a single + @scheme[omitable-paragraph], then when rendering to HTML, no + @tt{p} tag wraps the cell content.} + + @item{@scheme['div] --- Generates @tt{

} HTML output instead of + @tt{

}.} + + @item{@scheme[attributes] structure --- Provides additional HTML + attributes for the @tt{

} or @tt{

} tag.} + + @item{@scheme[body-id] structure --- For HTML, uses the given string + as an @tt{id} attribute of the @tt{

} or @tt{

} tag.} + +]} + + +@defstruct[table ([style style?] + [blockss (listof (listof (or/c block? (one-of/c 'cont))))])]{ + +A @techlink{table} has, roughly, a list of list of blocks. A cell in +the table can span multiple columns by using @scheme['cont] instead of +a block in the following columns (i.e., for all but the first in a set +of cells that contain a single block). + +Within @scheme[style], a string @tech{style name} corresponds to a CSS +class for HTML output or an environment for Latex output (see +@secref["extra-style"]). The following symbolic style names are also +recognized: + +@itemize[ + + @item{@scheme['boxed] --- Renders as a definition.} + + @item{@scheme['centered] --- Centers HTML output horizontally.} + +] + +The following style @tech{variants} are currently recognized: + +@itemize[ + + @item{@scheme[table-columns] structure --- Provides column-specific + styles, but only if a @scheme[table-cells] structure is not + included as a @tech{variant}.} + + @item{@scheme[table-cells] structure --- Provides cell-specific + styles.} + + @item{@scheme[attributes] structure --- Provides additional HTML + attributes for the @tt{} tag.} + + @item{@scheme[body-id] structure --- For HTML, uses the given string + as an @tt{id} attribute of the @tt{
} tag.} + + @item{@scheme['aux] --- For HTML, include the table in the + table-of-contents display for the enclosing part.} + +] + +For Latex output, a paragraph as a cell value is not automatically +line-wrapped, unless a vertical alignment is specified for the cell +through a @scheme[table-cells] or @scheme[table-columns] style +@tech{variant}. To get a line-wrapped paragraph, use a +@scheme[compound-paragraph] or use an element with a string style and +define a corresponding Latex macro in terms of @tt{parbox}. For Latex +output of blocks in the flow that are @scheme[nested-flow]s, +@scheme[itemization]s, @scheme[compound-paragraph]s, or +@scheme[delayed-block]s, the block is wrapped with @tt{minipage} using +@tt{linewidth} divided by the column count as the width.} + + +@defstruct[itemization ([style style?] + [blockss (listof (listof block?))])]{ + +A @techlink{itemization} has a @tech{style} and a list of @tech{flows}. + +In @scheme[style], a string @tech{style name} corresponds to a CSS +class for HTML output or a macro for Latex output (see +@secref["extra-style"]). In addition, the following symbolic style +names are recognized: + +@itemize[ + + @item{@scheme['compact] --- Reduces space between items.} + + @item{@scheme['ordered] --- Generates @tt{
    } HTML output instead + of @tt{
      } or an Latex enumeration instead of an + itemization.} +] + +The following style @tech{variants} are currently recognized: + +@itemize[ + + @item{@scheme[attributes] structure --- Provides additional HTML + attributes for the @tt{
        } or @tt{
          } tag.} + + @item{@scheme[body-id] structure --- For HTML, uses the given string + as an @tt{id} attribute of the @tt{
            } or @tt{
              } tag.} + +]} + + +@defstruct[nested-flow ([style any/c] + [paragraphs (listof block?)])]{ + +A @techlink{nested flow} has a style and a @tech{flow}. + +In @scheme[style], the @scheme{style name} is normally a string that +corresponds to a CSS class for HTML @tt{blockquote} output or a Latex +environment (see @secref["extra-style"]). The following symbolic style +names are recognized: + +@itemize[ + + @item{@scheme['inset] --- Insets the nested flow relative to + surrounding text.} + +] + +The following style @tech{variants} are currently recognized: + +@itemize[ + + @item{@scheme['command] --- For Latex output, a string @tech{style + name} is used as a command name instead of an environment + name.} + + @item{@scheme[attributes] structure --- Provides additional HTML + attributes for the @tt{
              } tag.} + + @item{@scheme[body-id] structure --- For HTML, uses the given string + as an @tt{id} attribute of the @tt{
              } tag.} + +]} + + +@defstruct[compound-paragraph ([style any/c] + [blocks (listof block?)])]{ + +A @techlink{compound paragraph} has a @tech{style} and a list of +@tech{blocks}. + +For HTML, a @scheme[paragraph] block in @scheme[blocks] is rendered +without a @tt{

              } tag, unless the paragraph has a style with a +non-@scheme[#f] @tech{style name}. + +The @scheme[style] field of a compound paragraph is normally a string +that corresponds to a CSS class for HTML output or Latex environment +for Latex output (see @secref["extra-style"]). The following style +@tech{variants} are currently recognized: + +@itemize[ + + @item{@scheme['command] --- For Latex output, a string @tech{style + name} is used as a command name instead of an environment + name.} + + @item{@scheme[attributes] structure --- Provides additional HTML + attributes for the @tt{

              } tag.} + + @item{@scheme[body-id] structure --- For HTML, uses the given string + as an @tt{id} attribute of the @tt{

              } tag.} + +]} + + +@defstruct[delayed-block ([resolve (any/c part? resolve-info? . -> . block?)])]{ + +The @scheme[resolve] procedure is called during the @techlink{resolve +pass} to obtain a normal @tech{block}. The first argument to +@scheme[resolve] is the renderer. + +} + + +@defstruct[element ([style element-style?] + [content content?])]{ + +Styled @tech{content} within an enclosing @tech{paragraph} or other content. + +The @scheme[style] field can be a @scheme[style] structure, but it can +also be just a @tech{style name}. + +In @scheme[style], a string @tech{style name} corresponds to a CSS +class for HTML output and a macro name for Latex output (see +@secref["extra-style"]). The following symbolic style names are +recognized: + +@itemize[ + + @item{@scheme['tt], @scheme['italic], @scheme['bold], @scheme['sf], + @scheme['url], @scheme['subscript], @scheme['superscript], + @scheme['smaller], @scheme['larger] --- + Basic styles recognized by all renders.} + + @item{@scheme['hspace] --- Renders its @scheme[content] as monospace + blanks.} + + @item{@scheme['newline] --- Renders a line break independent of + the @scheme[content].} + +] + +The following style @tech{variants} are currently recognized: + +@itemize[ + + @item{@scheme[target-url] structure --- Generates a hyperlink.} + + @item{@scheme[url-anchor] structure --- For HTML, inserts a hyperlink + target before @scheme[content].} + + @item{@scheme[color-variant] structure --- Applies a color to the + text of @scheme[content].} + + @item{@scheme[background-color-variant] structure --- Applies a color to the + background of @scheme[content].} + + @item{@scheme[attributes] structure --- Provides additional HTML + attributes for a @tt{} tag.} + + @item{@scheme[hover-variant] structure --- For HTML, adds a text + label to the content to be shown when the mouse hovers over + it.} + + @item{@scheme[script-variant] structure --- For HTML, supplies a + script alternative to @scheme[content].} + + @item{@scheme[body-id] structure --- For HTML uses the given + string as an @tt{id} attribute of the @tt{span} tag.} + + @item{@scheme['aux] --- Intended for use in titles, where the + auxiliary part of the title can be omitted in hyperlinks. See, + for example, @scheme[secref].} + +]} + + +@defstruct[(image-element element) ([path (or/c path-string? + (cons/c 'collects (listof bytes?)))] + [suffixes (listof #rx"^[.]")] + [scale real?])]{ + +Used as a style for an @scheme[element] to inline an image. The +@scheme[path] field can be a result of +@scheme[path->main-collects-relative]. + +For each string in @scheme[suffixes], if the rendered works with the +corresponding suffix, the suffix is added to @scheme[path] and used if +the resulting path refers to a file that exists. The order in +@scheme[suffixes] determines the order in which suffixes are +tried. The HTML renderer supports @scheme[".png"] and @scheme[".gif"], +while the Latex renderer supports @scheme[".png"], @scheme[".pdf"], +and @scheme[".ps"] (but rendering Latex output to PDF will not work +with @scheme[".ps"] files, while rendering to Latex DVI output works +only with @scheme[".ps"] files). If @scheme[suffixes] is empty or if +none of the suffixes lead to files that exist, @scheme[path] is used +as-is. + +The @scheme[scale] field scales the image in its rendered form.} + + +@defstruct[(target-element element) ([tag tag?])]{ + +Declares the content as a hyperlink target for @scheme[tag].} + + +@defstruct[(toc-target-element target-element) ()]{ + +Like @scheme[target-element], the content is also a kind of section +label to be shown in the ``on this page'' table for HTML output.} + + +@defstruct[(page-target-element target-element) ()]{ + +Like @scheme[target-element], but a link to the element goes to the +top of the containing page.} + + +@defstruct[(redirect-target-element target-element) ([alt-path path-string?] + [alt-anchor string?])]{ + +Like @scheme[target-element], but a link to the element is redirected +to the given URL.} + + +@defstruct[(toc-element element) ([toc-content content?])]{ + +Similar to @scheme[toc-target-element], but with specific content for +the ``on this page'' table specified in the @scheme[toc-content] +field.} + + +@defstruct[(link-element element) ([tag tag?])]{ + +Hyperlinks the content to @scheme[tag]. + +When @scheme[tag] is a part tag and the content of the element is +@scheme[null], then the hyperlink uses the target part's number and/or +title as the content. In that case, if the section number is preceded +by a word, the word starts in uppercase if the element's style includes a +@scheme['uppercase] variant.} + + +@defstruct[(index-element element) ([tag tag?] + [plain-seq (and/c pair? (listof string?))] + [entry-seq (listof content?)] + [desc any/c])]{ + +The @scheme[plain-seq] specifies the keys for sorting, where the first +string is the main key, the second is a sub-key, etc. For +example, an ``night'' portion of an index might have sub-entries for +``night, things that go bump in'' and ``night, defender of the''. The +former would be represented by @scheme[plain-seq] @scheme['("night" +"things that go bump in")], and the latter by @scheme['("night" +"defender of the")]. Naturally, single-string +@scheme[plain-seq] lists are the common case, and at least one word is +required, but there is no limit to the word-list length. The strings in +@scheme[plain-seq] must not contain a newline character. + +The @scheme[entry-seq] list must have the same length as +@scheme[plain-seq]. It provides the form of each key to render in the +final document. + +The @scheme[desc] field provides additional information about the +index entry as supplied by the entry creator. For example, a reference +to a procedure binding can be recognized when @scheme[desc] is an +instance of @scheme[procedure-index-desc]. See +@schememodname[scribble/manual-struct] for other typical types of +@scheme[desc] values. + +See also @scheme[index].} + + +@defstruct[multiarg-element ([style element-style?] + [content (listof content?)])]{ + +Like @scheme[element] with a list for content, except that for Latex +output, if the @tech{style name} in @scheme[style] is a string, then +it corresponds to a Latex command that accepts as many arguments (each +in curly braces) as elements of @scheme[content].} + + +@defstruct[delayed-element ([resolve (any/c part? resolve-info? . -> . list?)] + [sizer (-> any/c)] + [plain (-> any/c)])]{ + +The @scheme[render] procedure's arguments are the same as for +@scheme[delayed-block], but the result is @techlink{content}. +Unlike @scheme[delayed-block], the +result of the @scheme[render] procedure's argument is remembered on +the first call for re-use for a particular resolve pass. + +The @scheme[sizer] field is a procedure that produces a substitute +@techlink{content} for the delayed element for the purposes of +determining the delayed element's width (see @scheme[element-width]). + +The @scheme[plain] field is a procedure that produces a substitute +@techlink{content} when needed before the @techlink{collect pass}, +such as when @scheme[element->string] is used before the @tech{collect +pass}.} + + +@defstruct[part-relative-element ([resolve (collect-info? . -> . list?)] + [sizer (-> any/c)] + [plain (-> any/c)])]{ + +Similar to @scheme[delayed-block], but the replacement +@techlink{content} is obtained in the @techlink{collect pass} by +calling the function in the @scheme[resolve] field. + +The @scheme[resolve] function can call @scheme[collect-info-parents] +to obtain a list of @techlink{parts} that enclose the element, +starting with the nearest enclosing section. Functions like +@scheme[part-collected-info] and @scheme[collected-info-number] can +extract information like the part number.} + + +@defstruct[(collect-element element) ([collect (collect-info . -> . any)])]{ + +Like @scheme[element], but the @scheme[collect] procedure is called +during the @techlink{collect pass}. The @scheme[collect] procedure +normally calls @scheme[collect-put!]. + +Unlike @scheme[delayed-element] or @scheme[part-relative-element], the +element remains intact (i.e., it is not replaced) by either the +@tech{collect pass} or @tech{resolve pass}.} + + +@defstruct[(render-element element) ([render (any/c part? resolve-info? . -> . any)])]{ + +Like @scheme[delayed-element], but the @scheme[render] procedure is called +during the @techlink{render pass}. + +If a @scheme[render-element] instance is serialized (such as when +saving collected info), it is reduced to a @scheme[element] instance.} + + +@defstruct[collected-info ([number (listof (or/c false/c integer?))] + [parent (or/c false/c part?)] + [info any/c])]{ + +Computed for each part by the @techlink{collect pass}.} + + +@defstruct[target-url ([addr path-string?])]{ + +Used as a style @tech{variant} for an @scheme[element]. A path is +allowed for @scheme[addr], but a string is interpreted as a URL rather +than a file path.} + + +@defstruct[document-version ([text (or/c string? false/c)])]{ + +Used as a style @tech{variant} for a @scheme[path] to indicate a +version number.} + + +@defstruct[color-variant ([color (or/c string? (list/c byte? byte? byte?))])]{ + +Used as a style @tech{variant} for an @scheme[element] to set its +color. Recognized string names for @scheme[color] depend on the +renderer, but at the recognized set includes at least +@scheme["white"], @scheme["black"], @scheme["red"], @scheme["green"], +@scheme["blue"], @scheme["cyan"], @scheme["magenta"], and +@scheme["yellow"]. When @scheme[color] is a list of bytes, the values +are used as RGB levels.} + + +@defstruct[background-color-variant ([color (or/c string? (list/c byte? byte? byte?))])]{ + +Like @scheme[color-variant], but sets the background color.} + +@defstruct[table-cells ([styless (listof (listof style?))])]{ + +Used as a style @tech{variant} for a @scheme[table] to set its cells' +styles. + +If a cell style has a string name, it is used as an HTML class for the +@tt{

} tag or as a Latex command name. + +The following symbols are recognized as cell-style @tech{variants}: + +@itemize[ + + @item{@scheme['left] --- Left-align the cell content.} + + @item{@scheme['right] --- Right-align the cell content top baselines.} + + @item{@scheme['center] --- Center the cell content horizontally.} + + @item{@scheme['top] --- Top-align the cell content.} + + @item{@scheme['baseline] --- Align the cell content top baselines.} + + @item{@scheme['bottom] --- bottom-align the cell content.} + + @item{@scheme['vcenter] --- Center the cell content vertically.} + +]} + + +@defstruct[table-columns ([styles (listof style?)])]{ + +Like @scheme[table-cells], but the @scheme[styles] list is duplicated +for each row in the table. This @tech{variant} is only when a +@scheme[table-cells] is not present in a style's list of variants.} + +@defproc[(block? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a @scheme[paragraph], +@scheme[table], @scheme[itemization], @scheme[nested-flow], or +@scheme[delayed-block], @scheme[#f] otherwise.} + + +@defproc[(content? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a string, symbol, +@scheme[element], @scheme[multiarg-element], @scheme[delayed-element], +@scheme[part-relative-element], or list of @tech{content}, @scheme[#f] +otherwise.} + + +@defstruct[style ([name (or/c string? symbol? #f)] + [variants list?])]{ + +Represents a @techlink{style}.} + + +@defthing[plain style?]{ + +A style @scheme[(make-style #f null)].} + + +@defproc[(element-style? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a string, symbol, @scheme[#f], +or @scheme[style] structure.} + + +@defproc[(tag? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is acceptable as a link +@techlink{tag}, which is a list containing a symbol and either a +string, a @scheme[generated-tag] instance, or a list (of arbitrary +values).} + + +@defstruct[generated-tag ()]{ + +A placeholder for a tag to be generated during the @techlink{collect + pass}. Use @scheme[tag-key] to convert a tag containing a + @scheme[generated-tag] instance to one containing a string. + +} + + +@defproc*[([(content->string (content content?)) string?] + [(content->string (content content?) (renderer any/c) (p part?) (info resolve-info?)) string?])]{ + +Converts @tech{content} to a single string (essentially +rendering the content as ``plain text''). + +If @scheme[p] and @scheme[info] arguments are not supplied, then a +pre-``collect'' substitute is obtained for @tech{delayed +elements}. Otherwise, the two arguments are used to force the +@tech{delayed element} (if it has not been forced already).} + +@defproc[(content-width [c content?]) exact-nonnegative-integer?]{ + +Returns the width in characters of the given @tech{content}. + +} + + +@defproc[(block-width (e block?)) exact-nonnegative-integer?]{ + +Returns the width in characters of the given @tech{block}.} + + +@defstruct[collect-info ([ht any/c] [ext-ht any/c] [parts any/c] + [tags any/c] [gen-prefix any/c] + [relatives any/c] + [parents (listof part?)])]{ + +Encapsulates information accumulated (or being accumulated) from the +@techlink{collect pass}. The fields are exposed, but not currently +intended for external use, except that @scheme[collect-info-parents] +is intended for external use. + +} + +@defstruct[resolve-info ([ci any/c] [delays any/c] [undef any/c])]{ + +Encapsulates information accumulated (or being accumulated) from the +@techlink{resolve pass}. The fields are exposed, but not currently +intended for external use. + +} + +@defproc[(info-key? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is an @deftech{info key}: a list of +at least two elements whose first element is a symbol. The result is +@scheme[#f] otherwise. + +For a list that is an info tag, the interpretation of the second +element of the list is effectively determined by the leading symbol, +which classifies the key. However, a @scheme[#f] value as the second +element has an extra meaning: collected information mapped by such +info keys is not propagated out of the part where it is collected; +that is, the information is available within the part and its +sub-parts, but not in ancestor or sibling parts. + +Note that every @techlink{tag} is an info key. + +} + +@defproc[(collect-put! [ci collect-info?] [key info-key?] [val any/c]) + void?]{ + +Registers information in @scheme[ci]. This procedure should be called +only during the @techlink{collect pass}. + +} + +@defproc[(resolve-get [p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) + any/c]{ + +Extract information during the @techlink{resolve pass} or +@techlink{render pass} for @scheme[p] from @scheme[ri], where the +information was previously registered during the @techlink{collect +pass}. See also @secref["passes"]. + +The result is @scheme[#f] if the no value for the given key is found. +Furthermore, the search failure is recorded for potential consistency +reporting, such as when @exec{setup-plt} is used to build +documentation. + +} + + +@defproc[(resolve-get/ext? [p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) + (values any/c boolean?)]{ + +Like @scheme[render-get], but returns a second value to indicate +whether the resulting information originated from an external source +(i.e., a different document).} + + +@defproc[(resolve-search [dep-key any/c][p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) + void?]{ + +Like @scheme[resolve-get], but a shared @scheme[dep-key] groups +multiple searches as a single request for the purposes of consistency +reporting and dependency tracking. That is, a single success for the +same @scheme[dep-key] means that all of the failed attempts for the +same @scheme[dep-key] have been satisfied. However, for dependency +checking, such as when using @exec{setup-plt} to re-build +documentation, all attempts are recorded (in case external changes +mean that an earlier attempt would succeed next time). + +} + +@defproc[(resolve-get/tentative [p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) + any/c]{ + +Like @scheme[resolve-search], but without dependency tracking. For +multi-document settings where dependencies are normally tracked, such +as when using @exec{setup-plt} to build documentation, this function +is suitable for use only for information within a single document. + +} + +@defproc[(resolve-get-keys [p (or/c part? false/c)] + [ri resolve-info?] + [pred (info-key? . -> . any/c)]) + list?]{ + +Applies @scheme[pred] to each key mapped for @scheme[p] in +@scheme[ri], returning a list of all keys for which @scheme[pred] +returns a true value. + +} + +@defproc[(part-collected-info [p part?] + [ri resolve-info?]) + collected-info?]{ + +Returns the information collected for @scheme[p] as recorded within +@scheme[ri]. + +} + +@defproc[(tag-key [t tag?] [ri resolve-info?]) tag?]{ + +Converts a @scheme[generated-tag] value with @scheme[t] to a string. + +} + +@; ---------------------------------------- + +@section{HTML Style Variants} + +@defmodule[scribble/html-variants]{ The +@scheme[scribble/html-variants] library provides datatypes used as +style @tech{variants} for HTML rendering.} + + +@defstruct[attributes ([assoc (listof (cons/c symbol? string?))])]{ + +Used as a style @tech{variant} to add arbitrary attributes to an HTML +tag.} + + +@defstruct[url-anchor ([name string?])]{ + +Used as a style @tech{variant} with @scheme[element] to insert an +anchor before the element.} + + +@defstruct[hover-variant ([text string?])]{ + +Used as a style @tech{variant} with @scheme[element] to add text that +is shown when the mouse hovers over the element.} + + +@defstruct[script-variant ([type string?] + [script (or/c path-string? (listof string?))])]{ + +Used as a style @tech{variant} with @scheme[element] to supply a +script alternative to the element content.} + + +@defstruct[css-addition ([path (or/c path-string? + (cons/c 'collects (listof bytes?)))])]{ + +Used as a style @tech{variant} to supply a CSS file to be referenced +in the generated HTML. This variant can be attached to any style, and +all additions are collected to the top of the generated HTML page. + +The @scheme[path] field can be a result of +@scheme[path->main-collects-relative].} + + +@defstruct[body-id ([value string?])]{ + +Used as a style @tech{variant} to associate an @tt{id} attribute with +an HTML tag.} + + +@defstruct[html-defaults ([prefix (or/c bytes? path-string? + (cons/c 'collects (listof bytes?)))] + [style (or/c bytes? path-string? + (cons/c 'collects (listof bytes?)))] + [extra-files (listof (or/c path-string? + (cons/c 'collects (listof bytes?))))])]{ + +Like @scheme[latex-defaults], but use for the +@exec{scribble} command-line tool's @DFlag{html} and +@DFlag{htmls} modes.} + + +@; ---------------------------------------- + +@section{Latex Style Variants} + +@defmodule[scribble/latex-variants]{ The +@scheme[scribble/latex-variants] library provides datatypes used as +style @tech{variants} for Latex rendering.} + + +@defstruct[tex-addition ([path (or/c path-string? + (cons/c 'collects (listof bytes?)))])]{ + +Used as a style @tech{variant} to supply a @filepath{.tex} file to be +included in the generated Latex. This variant can be attached to any +style, and all additions are collected to the top of the generated +Latex file. + +The @scheme[path] field can be a result of +@scheme[path->main-collects-relative].} + + +@defstruct[latex-defaults ([prefix (or/c bytes? path-string? + (cons/c 'collects (listof bytes?)))] + [style (or/c bytes? path-string? + (cons/c 'collects (listof bytes?)))] + [extra-files (listof (or/c path-string? + (cons/c 'collects (listof bytes?))))])]{ + +Used as a style @tech{variant} on the main @scheme[part] of a document +to set a default prefix file, style file, and extra files (see +@secref["config-style"]). The defaults are used by the +@exec{scribble} command-line tool for and @DFlag{latex} or @DFlag{pdf} +mode if none are supplied via @DFlag{prefix} and @DFlag{style} (where +@scheme[extra-files] are used only when @scheme[prefix] is used). A +byte-string value is used directly like file content, and a path can +be a result of @scheme[path->main-collects-relative]. + +Languages (used with @hash-lang[]) like +@schememodname[scribble/manual] and @schememodname[scribble/sigplan] +add this variant to a document to specify appropriate files for Latex +rendering.} + + +@defstruct[latex-auto-extra-files ([paths (listof (or/c path-string? + (cons/c 'collects (listof bytes?))))])]{ + +Used as a style @tech{variant} for the main @scheme[part] of a +document to supply extra files needed to build the document via the +@exec{scribble} command-line tool (for @DFlag{latex} and @DFlag{pdf} +mode). + +Languages (used with @hash-lang[]) like +@schememodname[scribble/sigplan] add this variant to a document to specify +appropriate extra files.} diff --git a/collects/scribblings/scribble/decode.scrbl b/collects/scribblings/scribble/decode.scrbl index db2e76824b..436df85d45 100644 --- a/collects/scribblings/scribble/decode.scrbl +++ b/collects/scribblings/scribble/decode.scrbl @@ -14,7 +14,7 @@ At the @tech{flow} level, decoding recognizes a blank line as a @tech{paragraph} separator. Blocks and paragraphs without blank lines in between are collected into a @tech{compound paragraph}. -At the @tech{paragraph}-content level, decoding makes just a few +At the @tech{content} level, decoding makes just a few special text conversions: @itemize[ @@ -44,6 +44,29 @@ that in the @litchar{``apple''} argument is decoded to use fancy quotes, and then it is bolded. + +@defproc[(pre-flow? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a @deftech{pre-flow} value: a +string or other non-list @scheme[content], a @scheme[block?], or a +@scheme[splice] containing a list of @tech{pre-flow} values; otherwise +returns @scheme[#f]. + +Pre-flow is decoded into a @tech{flow} (i.e., a list of @tech{blocks}) +by functions like @scheme[decode] and @scheme[decode-flow].} + + +@defproc[(pre-content? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a @deftech{pre-content} value: a +string or other non-list @scheme[content], or a @scheme[splice] +containing a list of @tech{pre-content} values; otherwise returns +@scheme[#f]. + +Pre-content is decoded into @tech{content} by functions like +@scheme[decode-content] and @scheme[decode-paragraph].} + + @defproc[(decode [lst list?]) part?]{ Decodes a document, producing a part. In @scheme[lst], instances of @@ -74,7 +97,7 @@ parsing. } -@defproc[(decode-flow [lst list?]) flow?]{ +@defproc[(decode-flow [lst (listof pre-flow?)]) flow?]{ Decodes a flow. A sequence of two or more newlines separated only by whitespace counts is parsed as a paragraph separator. In @scheme[lst], @@ -84,7 +107,7 @@ the enclosing flow. } -@defproc[(decode-compound-paragraph [lst list?]) block?]{ +@defproc[(decode-compound-paragraph [lst (listof pre-flow?)]) block?]{ Decodes a compound paragraph. If the compound paragraph contains a single block, the block is returned without a @@ -92,26 +115,26 @@ single block, the block is returned without a } -@defproc[(decode-paragraph [lst list?]) paragraph?]{ +@defproc[(decode-paragraph [lst (listof pre-content?)]) paragraph?]{ Decodes a paragraph. } -@defproc[(decode-content [lst list?]) list?]{ +@defproc[(decode-content [lst (listof pre-content?)]) list?]{ -Decodes a sequence of elements. +Decodes @tech{content}. } -@defproc[(decode-elements [lst list?]) list?]{ +@defproc[(decode-elements [lst (listof pre-content?)]) list?]{ An alias for @scheme[decode-content]. } -@defproc[(decode-string [s string?]) list?]{ +@defproc[(decode-string [s string?]) (listof content?)]{ -Decodes a single string to produce a list of elements. +Decodes a single string to produce @tech{content}. } @@ -127,7 +150,7 @@ otherwise. [tags (listof string?)] [version (or/c string? false/c)] [style any/c] - [content list?])]{ + [content content?])]{ See @scheme[decode] and @scheme[decode-part]. The @scheme[tag-prefix] and @scheme[style] fields are propagated to the resulting @@ -139,7 +162,7 @@ and @scheme[style] fields are propagated to the resulting [tag-prefix (or/c false/c string?)] [tags (listof string?)] [style any/c] - [title list?])]{ + [title content?])]{ Like @scheme[title-decl], but for a sub-part. See @scheme[decode] and @scheme[decode-part]. diff --git a/collects/scribblings/scribble/doclang.scrbl b/collects/scribblings/scribble/doclang.scrbl index 6d062ee882..080e7d70ba 100644 --- a/collects/scribblings/scribble/doclang.scrbl +++ b/collects/scribblings/scribble/doclang.scrbl @@ -1,6 +1,5 @@ -#lang scribble/doc -@(require scribble/manual - "utils.ss") +#lang scribble/manual +@(require "utils.ss") @title[#:tag "doclang"]{Document Language} diff --git a/collects/scribblings/scribble/generic.scrbl b/collects/scribblings/scribble/generic.scrbl new file mode 100644 index 0000000000..295c1cdb16 --- /dev/null +++ b/collects/scribblings/scribble/generic.scrbl @@ -0,0 +1,7 @@ +#lang scribble/manual +@(require "utils.ss") + +@title[#:tag "generic-prose"]{General Documents} + +@include-section["base.scrbl"] +@include-section["other.scrbl"] diff --git a/collects/scribblings/scribble/getting-started.scrbl b/collects/scribblings/scribble/getting-started.scrbl new file mode 100644 index 0000000000..a79f0d5b4f --- /dev/null +++ b/collects/scribblings/scribble/getting-started.scrbl @@ -0,0 +1,13 @@ +#lang scribble/manual + +@title[#:tag "getting-started" #:style 'toc]{Getting Started} + +No matter what you want to do with Scribble, it's best to start with +an introduction on producing HTML and PDF documents in +@secref["how-to-paper"]. The end of the chapter, @secref["roadmap"], +offers advice on where to go afterward depending on your goals. + +@local-table-of-contents[] + +@include-section["how-to-paper.scrbl"] +@include-section["how-to.scrbl"] diff --git a/collects/scribblings/scribble/how-to-paper.scrbl b/collects/scribblings/scribble/how-to-paper.scrbl new file mode 100644 index 0000000000..2799ced703 --- /dev/null +++ b/collects/scribblings/scribble/how-to-paper.scrbl @@ -0,0 +1,622 @@ +#lang scribble/doc +@(require scribble/manual + scribble/bnf + "utils.ss") + +@(define (sample . text) (nested #:style 'inset (apply verbatim text))) +@(define (result . text) (apply nested #:style 'inset text)) + +@title[#:tag "how-to-paper"]{How to Scribble Documents} + +This chapter demonstrates the basics of generating stand-alone HTML +and PDF (through Latex) documents with Scribble. + +@section[#:tag "first-example"]{A First Example} + +Create a file @filepath{mouse.scrbl} with this content: + + @sample|{ + #lang scribble/base + + @title{On the Cookie-Eating Habits of Mice} + + If you give a mouse a cookie, he's going to ask for a + glass of milk. + }| + +The first line's @scheme[#, @hash-lang[] #, +@schememodname[scribble/base]] indicates that the file implements a +Scribble document. The document starts in ``text mode,'' and the +@litchar["@"] character escapes to operators like @scheme[title], +where the curly braces return to text mode for the arguments to the +operator. The rest is document content. + +Now run the @exec{scribble} command-line program, specifying a mode +for the kind of document that you want as output: + + @itemize[ + + @item{Run + @commandline{scribble --pdf mouse.scrbl} + to generate PDF as @filepath{mouse.pdf}. This will + work only if you have @exec{pdflatex} installed. + If you'd like to see the intermediate Latex, try + @commandline{scribble --latex mouse.scrbl} + to generate @filepath{mouse.tex}.} + + @item{Run + @commandline{scribble --html mouse.scrbl} + to generate HTML as @filepath{mouse.html}. You may + notice that the apostrophe in ``he's'' turned into a + curly apostrophe.} + + @item{Run + @commandline{scribble --htmls mouse.scrbl} + to generate HTML as @filepath{mouse/index.html}. + Sub-sections (which we add next) will appear as separate + HTML files in the @filepath{mouse} directory.} + + ] + +@section{Multiple Sections} + +Add more text to @filepath{mouse.scrbl} so that it looks like this: + + @sample|{ + #lang scribble/base + + @title{On the Cookie-Eating Habits of Mice} + + If you give a mouse a cookie, he's going to ask for a + glass of milk. + + @section{The Consequences of Milk} + + That ``squeak'' was the mouse asking for milk. Let's + suppose that you give him some in a big glass. + + He's a small mouse. The glass is too big---way too + big. So, he'll probably ask you for a straw. You might as + well give it to him. + + @section{Not the Last Straw} + + For now, to handle the milk moustache, it's enough to give + him a napkin. But it doesn't end there... oh, no. + }| + + Now, after the first paragraph of the paper, we have two + sub-sections, each created by calling @scheme[section] to + generate a sub-section declaration. The first sub-section has + two paragraphs. The second section, as initiated by the result + of the second @scheme[section] call, has a single paragraph. + +Run the @exec{scribble} command(s) from @secref["first-example"] +again. You may notice the curly double-quotes in the output; in PDF +output, the @litchar{---} turned into an em-dash. For HTML, it turned +into a en-dash with surrounding spaces, which is a typical convention +for em-dashes in HTML. + +@;---------------------------------------- +@section{Splitting the Document Source} + +As a document grows larger, it's better to split sections into +separate source files. The @scheme[include-section] operation +incorporates a document defined by a @filepath{.scrbl} file into a +larger document. + +To split the example document into multiple files, change +@filepath{mouse.scrbl} to just + + @sample|{ + #lang scribble/base + + @title{On the Cookie-Eating Habits of Mice} + + If you give a mouse a cookie, he's going to ask for a + glass of milk. + + @include-section["milk.scrbl"] + @include-section["straw.scrbl"] + }| + +Create @filepath{milk.scrbl} and @filepath{straw.scrbl} in the same +directory as @filepath{mouse.scrbl}. In @filepath{milk.scrbl}, put + + @sample|{ + #lang scribble/base + + @title{The Consequences of Milk} + + That ``squeak'' was the mouse asking for milk... + }| + +and in @filepath{straw.scbl}, put + + @sample|{ + #lang scribble/base + + @title{Not the Last Straw} + + For now, to handle the milk moustache, ... + }| + +Notice that the new files both start with @hash-lang[], like the +original document, and the @scheme[section]s from the original +document become @scheme[title]s in the new documents. Both +@filepath{milk.scrbl} and @filepath{straw.scrbl} are documents in +their own right with their own titles, and they can be individually +rendered using @exec{scribble}. Running @exec{scribble} on +@filepath{mouse.scrbl}, meanwhile, incorporates the smaller documents +into one document that is the same as before. + +@; ---------------------------------------- +@section{Document Styles} + +Scribble currently supports only one from of HTML output. You can +replace the @filepath{scribble.css} file for the generated pages, and +that's about it. (We expect to add more styles in the future.) + +For Latex-based PDF output, Scribble includes support for +multiple page-layout configurations. The @filepath{mouse.scrbl} +example so far uses the default Latex style. If you plan on submitting +the paper to a workshop on programming languages, then---well, you +probably need a different topic. But you can start making the current +content look right by changing the first line to + + @sample|{ + #lang scribble/sigplan + }| + +If you're instead working toward PLT Scheme library documentation, +try changing the first line to + + @sample|{ + #lang scribble/manual + }| + +which produces output with a separate title page, initial content on +that page (intended as a brief orientation to the document), and +top-level sections turned into chapters that each start on a new page. +If you have split the document into multiple files, the first line of +the main document file determines the output format. + +Using @schememodname[scribble/sigplan] or +@schememodname[scribble/manual] does not change the rendered HTML for +a document---aside from @schememodname[scribble/manual] adding a +version number---but it changes the set of bindings available in the +document body. For example, with @schememodname[scribble/sigplan], the +introductory text can be marked as an abstract: + + @sample|{ + #lang scribble/sigplan + + @title{On the Cookie-Eating Habits of Mice} + + @abstract{If you give a mouse a cookie, he's going to + ask for a glass of milk.} + + @section{The Consequences of Milk} + + ....}| + +When rendered as HTML, the abstract shows up as an inset paragraph. If +you try to use @scheme[abstract] with the +@schememodname[scribble/base] or @schememodname[scribble/manual] +language, then you get an error, because @scheme[abstract] is not +defined. + +When a document is implemented across multiple files, changing the +language of the man document can set the style for all of the parts, +but it does not introduce bindings into the other part files. For +example, if you change the language of @filepath{mouse.scrbl} to +@schememodname[scribble/sigplan], then @scheme[abstract] becomes +available in @filepath{mouse.scrbl} but not in @filepath{milk.scrbl} +or @filepath{straw.scrbl}. In other words, operator names are +lexically scoped. + +@; ---------------------------------------- +@section{More Functions} + +The @schememodname[scribble/sigplan] and +@schememodname[scribble/manual] languages are supersets of the +@schememodname[scribble/base] language, which provides a collection of +basic operations. Many of the operations are style variations that you +can apply to text: + + @sample|{ + He's a @smaller{small mouse}. The glass is too + @larger{big}---@bold{way @larger{too @larger{big}}}. So, he'll + @italic{probably} ask you for a straw. + }| + +which renders as + + @result{ + He's a @smaller{small mouse}. The glass is too + @larger{big}---@bold{way @larger{too @larger{big}}}. So, he'll + @italic{probably} ask you for a straw. + } + +As you would expect, calls to functions like @scheme[smaller], +@scheme[larger], and @scheme[bold] can be nested in other calls. They +can also be nested within calls to @scheme[title] or @scheme[section]: + + @sample|{ + @section{@italic{Not} the Last Straw} + }| + +The @scheme[centered] operation centers a flow of text: + + @sample|{ + If a mouse eats all your cookies, put up a sign that says + @centerline{ + @bold{Cookies Wanted} + + @italic{Chocolate chip preferred!} + } + and see if anyone brings you more. + }| + +which renders as + + @result{ + If a mouse eats all your cookies, put up a sign that says + @centerline{ + @bold{Cookies Wanted} + + @italic{Chocolate chip preferred!} + } + and see if anyone brings you more. + } + +The @scheme[margin-note] operation is used in a similar way, but the +rendered text is moved to the margins. + +@margin-note{If you use @scheme[margin-note], then the content shows + up over here.} + +The @scheme[itemlist] operation creates a sequence of bulleted text, +where the @scheme[item] operation groups text to appear in a single +bullet. The @scheme[itemlist] operation is different from the others +that we have seen before, because it only accepts values produced by +@scheme[item] instead of arbitrary text. This difference is reflected +in the use of @litchar{[}...@litchar{]} for the arguments to +@scheme[itemlist] instead of @litchar["{"]...@litchar["}"]: + + @sample|{ + @centered{@bold{Notice to Mice}} + + @itemlist[@item{We have cookies for you.} + @item{If you want to eat a cookie, + you must bring your own straw.}] + }| + +which renders as + + @result{ + @centered{@bold{Notice to Mice}} + + @itemlist[@item{We have cookies for you.} + @item{If you want to eat a cookie, + you must bring your own straw.}] + } + +@; ---------------------------------------- +@section{Text Mode vs. Scheme Mode for Arguments} + +When @litchar{[}...@litchar{]} sounds the arguments of an +operation, the argument expressions are in Scheme mode rather than +text mode. Even in Scheme mode, @litchar["@"] can be used to apply +operations; once the @"@" syntax is enabled through a +language like @schememodname[scribble/base] (as opposed to +@schememodname[scheme]), it behaves the same in both Scheme mode and +text mode. + +One advantage of using Scheme mode for the arguments to +@scheme[itemlist] is that we can pass a keyword-tagged optional +argument to @scheme[itemlist]. In particular, if you want a list with +numbers instead of bullets, supply the @scheme['ordered] style to +@scheme[itemlist] using the @scheme[#:style] keyword: + + @sample|{ + @itemlist[#:style 'ordered + @item{Eat cookie.} + @item{Drink milk.} + @item{Wipe mouth.} + @item{...}] + }| + +An operation doesn't care whether it's used with +@litchar{[}...@litchar{]} or @litchar["{"]...@litchar["}"]. Roughly, +@litchar["{"]...@litchar["}"] forms an argument that is a +string. (Only roughly, though. Newlines or uses of @litchar["@"] +within @litchar["{"]...@litchar["}"] complicate the picture, and we'll +get back to that soon.) So, + + @sample|{ + @italic{Yummy!} + }| + +is equivalent to + + @sample|{ + @italic["Yummy!"] + }| + +which is equivalent to the Scheme expression + + @schemeblock[ + (italic "Yummy!") + ] + +These equivalences explain why Scribble functions are documented in +Scheme notation. If you're reading this in HTML format, you can click +@scheme[italic] above to access its documentation. The documentation +won't completely make sense, yet, because it will be the end of this +chapter. + +What if you want to provide arguments in text mode, but you also want +to supply other optional arguments? You can use both +@litchar{[}...@litchar{]} and @litchar["{"]...@litchar["}"] for an +operation, as long as the @litchar{[}...@litchar{]} is first, and as +long as no character separate the closing @litchar{]} from the +opening @litchar["{"]. For example, calling @scheme[italic] is the +same as using @scheme[elem] with the @scheme['italic] style: + + @sample|{ + @elem[#:style 'italic]{Yummy!} + }| + +You can also @emph{omit} both @litchar{[}...@litchar{]} and +@litchar["{"]...@litchar["}"]. In that case, the Scheme expression +after @litchar["@"] is used directly instead of applied as an +operation. For example, + + @sample|{ + 1 plus 2 is @(number->string (+ 1 2)). + }| + +renders as + + @result{ + 1 plus 2 is @(number->string (+ 1 2)). + } + +The call to @scheme[number->string] is needed because a naked number +is not valid as document content. + +@; ---------------------------------------- +@section[#:tag "how-to:reader"]{The @"@" Syntax} + +The @"@" notation provided by Scribble is just another way of +writing Scheme expressions. Scribble documents could be constructed +using normal Scheme notation, without using @"@" at all, but +that would be inconvenient for most purposes. The @"@" +notation makes dealing with textual content much easier. + +Whether in text mode or Scheme mode, @litchar["@"] in a document +provides an escape to Scheme mode. The basic syntax of @litchar["@"] is + +@schemeblock[ + @#,BNF-seq[@litchar["@"] + @nonterm{cmd} + @litchar{[} @kleenestar{@nonterm{datum}} @litchar{]} + @litchar["{"] @nonterm{text-body} @litchar["}"]] +] + +where all three parts after @litchar["@"] are optional, but at least +one must be present. No spaces are allowed between + +@itemize[ + + @item{@litchar["@"] and @nonterm{cmd}, @litchar{[}, or @litchar["{"]} + + @item{@nonterm{cmd} and @litchar{[} or @litchar["{"]; or} + + @item{@litchar{]} and @litchar["{"].} + +] + +A @nonterm{cmd} or @nonterm{datum} is normal Scheme notation, while a +@nonterm{text-body} is itself in text mode. A @nonterm{cmd} obviously +must not start with @litchar{[} or @litchar["{"], even though Scheme +forms could otherwise start with those characters. + +The expansion of just @litchar["@"]@nonterm{cmd} into Scheme code is + +@schemeblock[ + @#,nonterm{cmd} +] + +When either @litchar{[} @litchar{]} or @litchar["{"] @litchar["}"] +are used, the expansion is + +@schemeblock[ + (@#,nonterm{cmd} @#,kleenestar{@nonterm{datum}} @#,kleenestar{@nonterm{parsed-body}}) +] + +where @kleenestar{@nonterm{parsed-body}} is the parse result of the +@nonterm{text-body}. The @kleenestar{@nonterm{parsed-body}} part often +turns out to be a sequence of Scheme strings. + +In practice, the @nonterm{cmd} is normally a Scheme identifier that is +bound to a procedure or syntactic form. If the procedure or form +expects further text to typeset, then @litchar["{"]...@litchar["}"] +supplies the text. If the form expects other data, typically +@litchar{[}...@litchar{]} is used to surround Scheme arguments, +instead. Even if an operation's argument is a string, if the string is +not used as content text (but instead used as, say, a hyperlink +label), then the string is typically provided through +@litchar{[}...@litchar{]} instead of @litchar["{"]...@litchar["}"]. +Sometimes, both @litchar{[}...@litchar{]} and +@litchar["{"]...@litchar["}"] are used, where the former surround +Scheme arguments that precede text to typeset. Finally, if a form is a +purely Scheme-level form with not typeset result, such as a +@scheme[require] to import more operations, then typically just +@litchar["@"] is used. + +For example the text-mode stream + + @sample|{ + @(require scriblib/figure) + + @section[#:tag "poetry"]{Of Mice and Cookies} + See @secref["milk"]. + + @section[#:tag "milk"]{@italic{Important} Things About Milk} + @figure["straw" @elem{A straw}]{@image["straw.png"]} + }| + +is equivalent to the Scheme-mode sequence + +@schemeblock[ + (require scriblib/figure) "\n" + "\n" + (section #:tag "poetry" "Of Mice and Cookies") "\n" + "See " (secref "milk") "." "\n" + "\n" + (section #:tag "milk" (italic "Important") " Things About Milk") "\n" + (figure "straw" (elem "A straw") (image "straw.png")) "\n" +] + +Besides showing how different argument conventions are used for +different operations, the above example illustrates how whitespace is +preserved in the Scheme form of a text-mode stream---including +newlines preserved as their own strings. Notice how the second +@scheme[section] gets two arguments for its content, since the +argument content for @scheme[section] in the source stream includes +both the use of an operator and additional text. When an operation +like @scheme[section] or @scheme[italic] accepts content to typeset, +it normally accepts an arbitrary number of arguments that together +form the content. + +For more information on the syntax of @litchar["@"], see +@secref["reader"]. The full syntax includes a few more details, such +as brackets like @litchar["|{"]...@litchar["}|"] for text-mode +arguments while disabling @litchar["@"] between the brackets. + +@; ---------------------------------------- +@section{Decoding Sequences} + +In a document that starts @scheme[#, @hash-lang[] #, +@schememodname[scribble/base]], the top level is a text-mode stream, +just like the @nonterm{text-body} in a @litchar["@"] form. As +illustrated in the previous section, such a top-level sequence +corresponds to a mixture of Scheme-mode strings and operation +applications. There's an implicit operation, @scheme[decode], that +wraps the whole document to consume this mixture of strings and other +values and turn them into a document description. + +The @scheme[decode] operation implements @defterm{flow decoding}, +which takes a document stream and breaks it up into sections and +paragraphs. Blank lines delimit paragraphs, and the results of +operations like @scheme[title] and @scheme[section] generate ``here's +the title'' or ``a new section starts here'' declarations that are +recognized by @scheme[decode]. + +A different but related @defterm{content decoding} takes place within +a paragraph or section title. Content decoding is responsible for +converting @litchar{---} to an em-dash or for converting @litchar{"} +and @litchar{'} to suitable curly quotes. + +The decoding process for document's stream is ultimately determined by +the @hash-lang[] line that starts the document. The @schememodname[scribble/base], +@schememodname[scribble/manual], and @schememodname[scribble/sigplan] +languages all use the same @scheme[decode] operation. The +@schememodname[scribble/text] language, however, acts more like a +plain-text preprocessor and it does not perform any such decoding +rules. (For more on @schememodname[scribble/text], see +@secref["preprocessor"].) + +@margin-note{More precisely, languages like + @schememodname[scribble/base] apply @scheme[decode] only after + lifting out all definitions and imports from the document + stream.} + +When the flow decoder is used, after it breaks the input stream into +paragraphs, it applies content decoding to strings within the +paragraph. When content is wrapped with an operation, however, content +decoding does not apply automatically. An operation is responsible for +calling a content or flow decoder as it sees fit. Most operations call +the decoder; for example, @scheme[italic], @scheme[bold], +@scheme[smaller], etc., all decode their arguments. Similarly, +@scheme[title] and @scheme[section] decode the given content for the +title or section name. The @scheme[literal] and @scheme[verbatim] +operators, however, do not decode the given strings. For example, + + @sample|{ + @verbatim{---} + }| + +renders as + + @result{ + @verbatim{---} + } + +Don't confuse decoding with the expansion of @"@" +notation. The source form + + @sample|{ + @verbatim{@(number->string (+ 1 2))} + }| + +renders as + + @result{ + @verbatim{@(number->string (+ 1 2))} + } + +because the source is equivalent to + + @sample|{ + (verbatim (number->string (+ 1 2))) + }| + +where @scheme[(number->string (+ 1 2))] is evaluated to produce the +argument to @scheme[verbatim]. The @litchar["|{"]...@litchar["}|"] +style of brackets is often used with @scheme[verbatim], because +@litchar["|{"]...@litchar["}|"] disables @"@" notation for +arguments. For example, + + @sample|{ + @verbatim|{@(number->string (+ 1 2))}| + }| + +renders as + + @result{ + @verbatim|{@(number->string (+ 1 2))}| + } + +@; ---------------------------------------- +@section[#:tag "roadmap"]{The Big Picture and Next Steps} + +Although it may not look like it, @filepath{mouse.scrbl} is a Scheme +program. You could run it directly in DrScheme or with MzScheme, the +latter like this: + + @commandline{mzscheme mouse.scrbl} + +If you do that though, nothing much seems to happen. As a program +module, @filepath{mouse.scrbl} builds a document description and +exports it as @scheme[doc], but exporting a binding is not a visible +operation. The @exec{scribble} tool runs @filepath{mouse.scrbl} to get +the exported description, and then it uses the description to generate +an output document. + +Despite a suspicious lack of parentheses compared to most Scheme +programs, and despite the fact that running @filepath{mouse.scrbl} by +itself has no apparent effect, it's important to understand that +@filepath{mouse.scrbl} is a Scheme program. @emph{Data is code.} +Scribble tools vary in the kinds of documents they transform and +generate, but all share the twin principles of @"@" notation +for convenience and data-as-code for expressiveness. + +If your immediate goal is to document a PLT Scheme library or write +literate programs, continue with @secref["how-to-doc"]. If you are more +interested in producing documents unrelated to PLT Scheme, move on to +the main documentation at @secref["generic-prose"], and then read +@secref["internals"] when you need more power. If you are interested +in text preprocessing, go instead to @secref["preprocessor"]. diff --git a/collects/scribblings/scribble/how-to.scrbl b/collects/scribblings/scribble/how-to.scrbl index 6056192634..62862edf11 100644 --- a/collects/scribblings/scribble/how-to.scrbl +++ b/collects/scribblings/scribble/how-to.scrbl @@ -3,20 +3,19 @@ scribble/bnf "utils.ss") -@title{How to Scribble Documentation} +@title[#:tag "how-to-doc"]{How to Scribble PLT Scheme Documentation} Although the @exec{scribble} command-line utility generates output -from a Scribble document (run @exec{scribble -h} for more -information), documentation of PLT Scheme libraries is normally built -by @exec{setup-plt}. This chapter emphasizes the @exec{setup-plt} -approach, which more automatically supports links across -documents. +from a Scribble document, documentation of PLT Scheme libraries is +normally built by @exec{setup-plt}. This chapter emphasizes the +@exec{setup-plt} approach, which more automatically supports links +across documents. -@margin-note{See @secref["config"] for information on using the +@margin-note{See @secref["how-to-paper"] for information on using the @exec{scribble} command-line utility.} @;---------------------------------------- -@section[#:tag "getting-started"]{Getting Started} +@section[#:tag "setting-up"]{Setting Up Documentation} To document a collection or @|PLaneT| package: @@ -30,20 +29,17 @@ To document a collection or @|PLaneT| package: @item{Start @filepath{manual.scrbl} like this: @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual) + #lang scribble/manual @title{My Library} Welcome to my documentation: @scheme[(list 'testing 1 2 3)]. }| - The first line starts the file in ``text'' mode, and - introduces the @litchar["@"] syntax to use Scheme bindings. - The second line introduces bindings like @scheme[title] and - @scheme[scheme] for writing PLT Scheme documentation. The - @scheme[title] call (using @litchar["@"]) produces a title - declaration in the text stream.} + The first line starts the file in ``text'' mode and selects + the PLT Scheme manual output format. + It also introduces bindings like @scheme[title] and + @scheme[scheme] for writing PLT Scheme documentation.} @item{Add the following entry to your collect or package's @filepath{info.ss}: @@ -82,105 +78,19 @@ To document a collection or @|PLaneT| package: ] -@; ---------------------------------------- -@section[#:tag "how-to:reader"]{Document Syntax} - -Whether in ``text'' mode or Scheme mode, @litchar["@"] in a document -provides an escape to Scheme mode. The syntax of @litchar["@"] is - -@schemeblock[ - @#,BNF-seq[@litchar["@"] - @nonterm{cmd} - @litchar{[} @kleenestar{@nonterm{datum}} @litchar{]} - @litchar["{"] @nonterm{text-body} @litchar["}"]] -] - -where all three parts after @litchar["@"] are optional, but at least -one must be present. No spaces are allowed between - -@itemize[ - - @item{@litchar["@"] and @nonterm{cmd}, @litchar{[}, or @litchar["{"]} - - @item{@nonterm{cmd} and @litchar{[} or @litchar["{"]; or} - - @item{@litchar{]} and @litchar["{"].} - -] - -A @nonterm{cmd} or @nonterm{datum} is a Scheme datum, while a -@nonterm{text-body} is itself in text mode. - -The expansion of @litchar["@"]@nonterm{cmd} into Scheme code is - -@schemeblock[ - @#,nonterm{cmd} -] - -When either @litchar{[} @litchar{]} or @litchar["{"] @litchar["}"] -are used, the expansion is - -@schemeblock[ - (@#,nonterm{cmd} @#,kleenestar{@nonterm{datum}} @#,kleenestar{@nonterm{parsed-body}}) -] - -where @kleenestar{@nonterm{parsed-body}} is the parse result of the -@nonterm{text-body}. The @kleenestar{@nonterm{parsed-body}} part often -turns out to be a sequence of Scheme strings. - -In practice, the @nonterm{cmd} is normally a Scheme identifier that is -bound to a procedure or syntactic form. If the procedure or form -expects further text to typeset, then @litchar["{"] @litchar["}"] -supplies the text. If the form expects other data, typically -@litchar{[} @litchar{]} is used to surround Scheme arguments, -instead. Sometimes, both @litchar{[} @litchar{]} and @litchar["{"] -@litchar["}"] are used, where the former surround Scheme arguments -that precede text to typeset. - -Thus, - -@verbatim[#:indent 2]|{ - @(require scribble/manual) - @title{My Library} - @scheme[(list 'testing 1 2 3)] - @section[#:tag "here"]{You Are Here} -}| - -means - -@schemeblock[ -(require scribble/manual) -(title "My Library") -(scheme (list 'testing 1 2 3)) -(section #:tag "here" "You Are Here") -] - -For more information on the syntax of @litchar["@"], see -@secref["reader"]. - -In a document that starts @hash-lang[] @schememodname[scribble/doc], -the top level is a text-mode sequence, as the @nonterm{text-body} in a -@litchar["@"] form. The parsed sequence is further -decoded to turn it into a hierarchy of sections and paragraphs. For -example, a linear sequence of @scheme[section] declarations with -interleaved text is turned into a list of @scheme[part] instances with -all text assigned to a particular part. See @secref["layers"] for more -information on these layers. - @; ---------------------------------------- @section[#:tag "scheme-hyperlinks"]{Scheme Typesetting and Hyperlinks} In the document source at the start of this chapter -(@secref["getting-started"]), the Scheme expression +(@secref["setting-up"]), the Scheme expression @scheme[(#,(schemeidfont "list") 'testing 1 2 3)] is typeset properly, but the @schemeidfont{list} identifier is not hyperlinked to the usual -definition. To cause @schemeidfont{list} to be hyperlinked, extend the +definition. To cause @schemeidfont{list} to be hyperlinked, add a @scheme[require] form like this: -@schemeblock[ -(require scribble/manual - (for-label #,(schememodname scheme))) -] +@verbatim[#:indent 2]|{ + @(require (for-label scheme)) +}| This @scheme[require] with @scheme[for-label] declaration introduces a document-time binding for each export of the @schememodname[scheme] @@ -197,9 +107,8 @@ document. Such links require no information about where and how a binding is documented elsewhere: @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - (for-label scheme)) + #lang scribble/manual + @(require (for-label scheme)) @title{My Library} @@ -212,9 +121,8 @@ so it ignores the source formatting of the expression. The and it preserves the expression's formatting from the document source. @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - (for-label scheme)) + #lang scribble/manual + @(require (for-label scheme)) @title{My Library} @@ -242,9 +150,8 @@ hyperlink with text other than the section title. The following example illustrates section hyperlinks: @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - (for-label scheme)) + #lang scribble/manual + @(require (for-label scheme)) @title{My Library} @@ -281,9 +188,8 @@ following example links to a section in the PLT Scheme reference manual: @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - (for-label scheme)) + #lang scribble/manual + @(require (for-label scheme)) @(define ref-src '(lib "scribblings/reference/reference.scrbl")) @@ -336,9 +242,8 @@ following: @; [Eli] This is also using `my-lib/helper' which doesn't work with @; planet libraries @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - (for-label scheme + #lang scribble/manual + @(require (for-label scheme "helper.ss")) @title{My Library} @@ -408,9 +313,8 @@ from the previous section, @filepath{helper.ss} must be imported both via @scheme[require-for-label] and @scheme[require]: @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - scribble/eval ; <--- added + #lang scribble/manual + @(require scribble/eval ; <--- added "helper.ss" ; <--- added (for-label scheme "helper.ss")) @@ -432,58 +336,6 @@ via @scheme[require-for-label] and @scheme[require]: ]} }| -@;---------------------------------------- -@section{Splitting the Document Source} - -In general, a @filepath{.scrbl} file produces a @techlink{part}. A part -produced by a document's main source (as specified in the -@filepath{info.ss} file) represents the whole document. The -@scheme[include-section] procedure can be used to incorporate a part -as a sub-part of the enclosing part. - -In @filepath{manual.scrbl}: - -@verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual) - - @title{My Library} - - @defmodule[my-lib/helper]{The @schememodname[my-lib/helper] - module---now with extra cows!} - - @include-section["cows.scrbl"] - @include-section["aardvarks.scrbl"] -}| - -In @filepath{cows.scrbl}: - -@verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual) - - @title{Cows} - - Wherever they go, it's a quite a show. -}| - -In @filepath{aardvarks.scrbl}: - -@verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual - (for-label scheme - "helper.ss")) - - @title{Aardvarks} - - @defproc[(my-helper [lst list?]) - (listof (not/c (one-of/c 'cow)))]{ - - Replaces each @scheme['cow] in @scheme[lst] with - @scheme['aardvark].} -}| - @;---------------------------------------- @section{Multi-Page Sections} @@ -500,8 +352,7 @@ sub-sections. Revising @filepath{cows.scrbl} from the previous section: @verbatim[#:indent 2]|{ - #lang scribble/doc - @(require scribble/manual) + #lang scribble/manual @title[#:style '(toc)]{Cows} diff --git a/collects/scribblings/scribble/internals.scrbl b/collects/scribblings/scribble/internals.scrbl new file mode 100644 index 0000000000..786d781bb1 --- /dev/null +++ b/collects/scribblings/scribble/internals.scrbl @@ -0,0 +1,16 @@ +#lang scribble/manual +@(require "utils.ss") + +@title[#:tag "internals" #:style 'toc]{Low-Level Scribble} + +@local-table-of-contents[] + +@include-section["layers.scrbl"] +@include-section["reader.scrbl"] +@include-section["core.scrbl"] +@include-section["renderer.scrbl"] +@include-section["decode.scrbl"] +@include-section["doclang.scrbl"] +@include-section["docreader.scrbl"] +@include-section["xref.scrbl"] +@include-section["config.scrbl"] diff --git a/collects/scribblings/scribble/layers.scrbl b/collects/scribblings/scribble/layers.scrbl index 2da14f7d33..db1aea9fc3 100644 --- a/collects/scribblings/scribble/layers.scrbl +++ b/collects/scribblings/scribble/layers.scrbl @@ -16,14 +16,34 @@ and instead use the document-generation structure directly. A Scribble document normally starts +@schememod[ +scribble/manual +] + +but it could also start + +@schememod[ +scribble/base +] + +or + @schememod[ scribble/doc ] -Besides making the file a module, this declaration selects the -Scribble reader (instead of the usual Scheme reader), and it starts -the body of the file in ``text'' mode. The reader layer mostly leaves -text alone, but @litchar["@"] forms escape to S-expression mode. +The last one introduces the smallest number of typesetting bindings in +the document body. Using @schememodname[scribble/base] after +@hash-lang[] is the same as using @schememodname[scribble/doc] plus +@scheme[(require scribble/base)], and using +@schememodname[scribble/manual] after @hash-lang[] is the same as using +@schememodname[scribble/doc] plus @scheme[(require scribble/manual)]. + +Besides making the file a module, each of the @hash-lang[] +declarations selects the Scribble reader (instead of the usual Scheme +reader), and it starts the body of the file in ``text'' mode. The +reader layer mostly leaves text alone, but @litchar["@"] forms escape +to S-expression mode. A module written as @@ -150,10 +170,10 @@ Working roughly from the bottom up, the Scribble layers are: syntax of Scheme with @"@"-forms for conveniently embedding a mixin of text and escapes. See @secref["reader"].} - @item{@schememodname[scribble/struct]: A set of document datatypes + @item{@schememodname[scribble/core]: A set of document datatypes and utilities that define the basic layout and processing of a document. For example, the @scheme[part] datatype is defined in - this layer. See @secref["struct"].} + this layer. See @secref["core"].} @item{@schememodname[scribble/base-render] with @schememodname[scribble/html-render], @@ -165,7 +185,7 @@ Working roughly from the bottom up, the Scribble layers are: @item{@schememodname[scribble/decode]: Processes a stream of text, section-start markers, etc. to produce instances of the - @schememodname[scribble/struct] datatypes. See + @schememodname[scribble/core] datatypes. See @secref["decode"].} @item{@schememodname[scribble/doclang]: A language to be used for the @@ -177,19 +197,22 @@ Working roughly from the bottom up, the Scribble layers are: @schememodname[scribble/reader] with @schememodname[scribble/doclang]. See @secref["docreader"].} - @item{@schememodname[scribble/basic]: A library of basic document + @item{@schememodname[scribble/base]: A library of basic document operators---such as @scheme[title], @scheme[section], and @scheme[secref]---for use with @schememodname[scribble/decode] - and a renderer. See @secref["basic"].} + and a renderer. This library name also can be used as a + language, where it combines @schememodname[scribble/doc] with + the exports of @schememodname[scribble/base]. See + @secref["base"].} @item{@schememodname[scribble/scheme]: A library of functions for typesetting Scheme code. See @secref["scheme"]. These functions - are not normally used directly, but instead through + are not normally used directly, but instead used through @schememodname[scribble/manual].} @item{@schememodname[scribble/manual]: A library of functions for writing PLT Scheme documentation; re-exports - @schememodname[scribble/basic]. Also, the + @schememodname[scribble/base]. Also, the @schememodname[scribble/manual-struct] library provides types for index-entry descriptions created by functions in @schememodname[scribble/manual]. See @secref["manual"].} diff --git a/collects/scribblings/scribble/lp.scrbl b/collects/scribblings/scribble/lp.scrbl index b300e4a0ea..6370bf1cf3 100644 --- a/collects/scribblings/scribble/lp.scrbl +++ b/collects/scribblings/scribble/lp.scrbl @@ -1,12 +1,18 @@ #lang scribble/doc @(require scribble/manual - scribble/struct + scribble/core + scribble/html-variants + scribble/latex-variants scheme/runtime-path (prefix-in lp-ex: "lp-ex-doc.scrbl") "utils.ss" (for-label scribble/lp-include scribble/lp)) -@title[#:tag "lp" #:style `((css "lp.css") (tex "lp.tex")) ]{Literate Programming} +@title[#:tag "lp" + #:style (make-style #f + (list (make-css-addition "lp.css") + (make-tex-addition "lp.tex"))) + ]{Literate Programming} Programs written using @schememodname[scribble/lp] are simultaneously two things: a program and a document describing the program. @@ -43,9 +49,9 @@ function @scheme[f] that squares its argument, and the documentation is ignored. When it is included with @scheme[lp-include], it looks like this: -@(make-blockquote - "LPBoxed" - (flow-paragraphs (part-flow lp-ex:doc))) +@(make-nested-flow + (make-style "LPBoxed" null) + (part-blocks lp-ex:doc)) @section{@schememodname[scribble/lp] Language} @@ -73,7 +79,11 @@ provides core support for literate programming.} @section{@schememodname[scribble/lp-include] Module} -@defmodule[scribble/lp-include]{} +@defmodule[scribble/lp-include]{The +@schememodname[scribble/lp-include] library is normally used within a +Scribble document---that is, a module that starts with something like +@scheme[#, @hash-lang[] scribble/base] or @scheme[#, @hash-lang[] +scribble/manual], instead of @scheme[#, @hash-lang[] scheme].} @defform[(lp-include filename)]{ Includes the source of @scheme[filename] as the typeset version of the literate diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl index c57bec5244..e267ff19a6 100644 --- a/collects/scribblings/scribble/manual.scrbl +++ b/collects/scribblings/scribble/manual.scrbl @@ -11,14 +11,20 @@ @defmodule[scribble/manual]{The @schememodname[scribble/manual] library provides all of @schememodname[scribble/basic] plus additional -functions, including many that are relatively specific to writing PLT -Scheme documentation. +functions, including all of @scheme[scribble/base] plus many others +that are relatively specific to writing PLT Scheme documentation. The @schememodname[scribble/manual] name can also be used as a language with @hash-lang[]. It acts like the @schememodname[scribble/doc] language, except that the -@schememodname[scribble/manual] library is also required into -the module.} +@schememodname[scribble/manual] library is also required into the +module. + +In addition, @scheme[#, @hash-lang[] #, @schememodname[scribble/manual]] +associates a @scheme[latex-defaults] style @tech{variant} with its +@scheme[doc] export to select the default PLT Scheme manual style for +Latex rendering---unless a style is supplied to @scheme[title] that +already includes a @scheme[latex-defaults] @tech{variant}.} @local-table-of-contents[] @@ -163,12 +169,6 @@ representation of literal text. Use this when you have to talk about the individual characters in a stream of text, as as when documenting a reader extension.} -@defproc[(verbatim [#:indent indent integer? 0] [str string?] ...) - flow-element?]{Typesets @scheme[str] -as a table/paragraph in typewriter font with the linebreaks specified -by newline characters in @scheme[str]. ``Here strings'' are often -useful with @scheme[verbatim].} - @defproc[(schemefont [pre-content any/c] ...) element?]{Typesets @tech{decode}d @scheme[pre-content] as uncolored, unhyperlinked Scheme. This procedure is useful for typesetting things like @@ -819,8 +819,8 @@ as a member of the signature named by @scheme[sig-id].} @; ------------------------------------------------------------------------ @section[#:tag "doc-strings"]{Various String Forms} -@defproc[(emph [pre-content any/c] ...) element?]{Typesets the -@tech{decode}d @scheme[pre-content] with emphasis (e.g., in italic).} +@defproc[(aux-elem [pre-content any/c] ...) element?]{ +Like @scheme[elem], but adds an @scheme['aux] style @tech{variant}.} @defproc[(defterm [pre-content any/c] ...) element?]{Typesets the @tech{decode}d @scheme[pre-content] as a defined term (e.g., in @@ -862,101 +862,28 @@ font with a leading @litchar{+}).} @tech{decode}d @scheme[pre-content] a long @litchar{+} flag (e.g., in typewriter font with two leading @litchar{+}s).} -@defproc[(math [pre-content any/c] ...) element?]{The @tech{decode}d -@scheme[pre-content] is further transformed: - - @itemize[ - - @item{Any immediate @scheme['rsquo] is converted to @scheme['prime].} - - @item{Parentheses and sequences of decimal digits in immediate - strings are left as-is, but any other immediate string is - italicized.} - ] - -Extensions to @scheme[math] are likely, such as recognizing @litchar{_} -and @litchar{^} for subscripts and superscripts.} - @; ------------------------------------------------------------------------ @section[#:tag "section-links"]{Links} -@defproc[(secref [tag string?] - [#:doc module-path (or/c module-path? false/c) #f] - [#:tag-prefixes prefixes (or/c (listof string?) false/c) #f] - [#:underline? underline? any/c #t]) - element?]{ - -Inserts the hyperlinked title of the section tagged @scheme[tag], but -@schemeidfont{aux-element} items in the title content are omitted in the -hyperlink label. - -If @scheme[#:doc module-path] is provided, the @scheme[tag] refers to -a tag with a prefix determined by @scheme[module-path]. When -@exec{setup-plt} renders documentation, it automatically adds a tag -prefix to the document based on the source module. Thus, for example, -to refer to a section of the PLT Scheme reference, -@scheme[module-path] would be @scheme['(lib -"scribblings/reference/reference.scrbl")]. - -The @scheme[#:tag-prefixes prefixes] argument similarly supports -selecting a particular section as determined by a path of tag -prefixes. When a @scheme[#:doc] argument is provided, then -@scheme[prefixes] should trace a path of tag-prefixed subsections to -reach the @scheme[tag] section. When @scheme[#:doc] is not provided, -the @scheme[prefixes] path is relative to any enclosing section (i.e., -the youngest ancestor that produces a match). - -If @scheme[underline?] is @scheme[#f], then the hyperlink is rendered -in HTML without an underline.} - - -@defproc[(seclink [tag string?] - [#:doc module-path (or/c module-path? false/c) #f] - [#:tag-prefixes prefixes (or/c (listof string?) false/c) #f] - [#:underline? underline? any/c #t] - [pre-content any/c] ...) element?]{ - -Like @scheme[secref], but the link label is the @tech{decode}d -@scheme[pre-content] instead of the target section's name.} - -@defproc[(other-manual [module-path module-path?] - [#:underline? underline? any/c #t]) - element?]{ - -Like @scheme[secref] for the document's implicit @scheme["top"] -tag. Use this function to refer to a whole manual instead of -@scheme[secref], in case a special style in the future is used for -manual titles.} - +See also @secref["base-links"]. @defproc[(schemelink [id symbol?] [pre-content any/c] ...) element?]{ The @tech{decode}d @scheme[pre-content] is hyperlinked to the definition of @scheme[id].} - @defproc[(link [url string?] [pre-content any/c] ... - [#:underline? underline? any/c #t] - [#:style style any/c (if underline? #f "plainlink")]) + [#:underline? underline? any/c #t] + [#:style style (or/c style? string? symbol? #f) (if underline? #f "plainlink")]) element?]{ -The @tech{decode}d @scheme[pre-content] is hyperlinked to -@scheme[url]. If @scheme[style] is not supplied, then -@scheme[underline?] determines how the link is rendered.} +An alias of @scheme[hyperlink] for backward compatibility.} +@defproc[(other-manual [module-path module-path?] + [#:underline? underline? any/c #t]) + element?]{ -@defproc[(elemtag [t tag?] [pre-content any/c] ...) element?]{ - -The tag @scheme[t] refers to the content form of -@scheme[pre-content].} - - -@defproc[(elemref [t tag?] [pre-content any/c] ... - [#:underline? underline? any/c #t]) element?]{ - -The @tech{decode}d @scheme[pre-content] is hyperlinked to @scheme[t], -which is normally defined using @scheme[elemtag].} - +An alias of @scheme[other-doc] for backward compatibility.} @defproc[(deftech [pre-content any/c] ... [#:style? style? any/c #t]) element?]{ @@ -1022,6 +949,8 @@ the link.} @; ------------------------------------------------------------------------ @section[#:tag "manual-indexing"]{Indexing} +See also @secref["base-indexing"]. + @defform[(indexed-scheme datum ...)]{ A combination of @scheme[scheme] and @scheme[as-index], with the @@ -1055,28 +984,13 @@ key for the index iterm does not include quotes.} combination of @scheme[envvar] and @scheme[as-index].} @; ------------------------------------------------------------------------ -@section{Images} - -@defproc[(image [filename-relative-to-source string?] - [pre-element any/c] ...) - flow-element?]{ - Creates a centered image from the given relative source path. The - @tech{decode}d @scheme[pre-content] serves as the alternate text for - contexts where the image cannot be displayed. - - The path is relative to the current directory, which is set by - @exec{setup-plt} and @exec{scribble} to the directory of the main - document file. - - When generating Latex output, if the filename has a @filepath{.gif} - suffix, then the suffix is changed to @filepath{.png} (so a PNG file - must exist in addition to the GIF file).} +@section[#:tag "manual-images"]{Images} @defproc[(image/plain [filename-relative-to-source string?] [pre-element any/c] ...) element?]{ - Like @scheme[image], but the result is an element to appear inline in - a paragraph.} + + An alias for @scheme[image] for backward compatibility.} @; ------------------------------------------------------------------------ @section{Bibliography} @@ -1160,15 +1074,31 @@ that is hyperlinked to an explanation.} @defthing[undefined-const element?]{Returns an element for @|undefined-const|.} -@defproc[(centerline [pre-flow any/c] ...) table?]{Produces a -centered table with the @scheme[pre-flow] parsed by -@scheme[decode-flow].} - @defproc[(commandline [pre-content any/c] ...) paragraph?]{Produces an inset command-line example (e.g., in typewriter font).} -@defproc[(margin-note [pre-content any/c] ...) blockquote?]{Produces -a @tech{blockquote} to be typeset in the margin instead of inlined.} +@defproc[(centerline [pre-flow pre-flow?] ...) nested-flow?]{ + +An alias for @scheme[centered] for backward compatibility.} + +@defproc[(math [pre-content any/c] ...) element?]{The @tech{decode}d +@scheme[pre-content] is further transformed: + + @itemize[ + + @item{Any immediate @scheme['rsquo] is converted to @scheme['prime].} + + @item{Parentheses and sequences of decimal digits in immediate + strings are left as-is, but any other immediate string is + italicized.} + + @item{When @litchar{_} appears before a non-empty sequence of numbers + and letters, the sequence is typeset as a subscript.} + + @item{When @litchar{^} appears before a non-empty sequence of numbers + and letters, the sequence is typeset as a superscript.} + + ]} @; ------------------------------------------------------------------------ @section[#:tag "index-entries"]{Index-Entry Descriptions} diff --git a/collects/scribblings/scribble/other.scrbl b/collects/scribblings/scribble/other.scrbl new file mode 100644 index 0000000000..ce3f17a5b3 --- /dev/null +++ b/collects/scribblings/scribble/other.scrbl @@ -0,0 +1,26 @@ +#lang scribble/manual +@(require "utils.ss" + (for-label scribble/sigplan)) + +@title{More Document Styles} + +In addition to @schememodname[scribble/base] and +@schememodname[scribble/manual], Scribble provides a few extra +document styles as a convenience. + +@section{SIGPLAN Paper Format} + +@defmodulelang[scribble/sigplan]{The @schememodname[scribble/sigplan] +language is like @schememodname[scribble/manual], but configured with +Latex style defaults to use the @filepath{sigplanconf.cls} class +file that is included with Scribble.} + +@defidform[preprint]{ + +Enables the @tt{preprint} option. Use @scheme[preprint] only on the +same line as @hash-lang[], with only whitespace between +@schememodname[scribble/sigplan] and @scheme[preprint]: + +@verbatim[#:indent 2]|{ + #lang scribble/sigplan @preprint +}|} diff --git a/collects/scribblings/scribble/plt.scrbl b/collects/scribblings/scribble/plt.scrbl new file mode 100644 index 0000000000..d0d49bd180 --- /dev/null +++ b/collects/scribblings/scribble/plt.scrbl @@ -0,0 +1,13 @@ +#lang scribble/manual +@(require "utils.ss") + +@title[#:tag "plt-manuals" #:style 'toc]{PLT Scheme Manuals} + +@local-table-of-contents[] + +@include-section["manual.scrbl"] +@include-section["scheme.scrbl"] +@include-section["eval.scrbl"] +@include-section["srcdoc.scrbl"] +@include-section["bnf.scrbl"] +@include-section["compat.scrbl"] diff --git a/collects/scribblings/scribble/preprocessor.scrbl b/collects/scribblings/scribble/preprocessor.scrbl index e2ffc1c38b..b4ef3d7caa 100644 --- a/collects/scribblings/scribble/preprocessor.scrbl +++ b/collects/scribblings/scribble/preprocessor.scrbl @@ -1,12 +1,17 @@ #lang scribble/doc -@(require scribble/manual scribble/struct "utils.ss" +@(require scribble/manual + scribble/core scribble/html-variants scribble/latex-variants + "utils.ss" (for-label scheme/base ;; FIXME: need to get this in ;; scribble/text )) @initialize-tests -@title[#:tag "preprocessor"]{Text Preprocessor} +@title[#:tag "preprocessor" + #:style (make-style #f (list (make-tex-addition "shaded.tex") + (make-css-addition "shaded.css"))) + ]{Text Preprocessing} @defmodulelang[scribble/text]{The @schememodname[scribble/text] language provides everything from @scheme[scheme/base] with a few diff --git a/collects/scribblings/scribble/reader.scrbl b/collects/scribblings/scribble/reader.scrbl index e725cbfb5e..e6217a7c5c 100644 --- a/collects/scribblings/scribble/reader.scrbl +++ b/collects/scribblings/scribble/reader.scrbl @@ -440,7 +440,7 @@ of the text. This works for @litchar["@"] too: }===| @;-------------------------------------------------------------------- -@subsubsub*section{Alternative Body Syntax} +@subsubsub*section[#:tag "alt-body-syntax"]{Alternative Body Syntax} In addition to the above, there is an alternative syntax for the body, one that specifies a new marker for its end: use @litchar["|{"] for diff --git a/collects/scribblings/scribble/scheme.scrbl b/collects/scribblings/scribble/scheme.scrbl index fd72294a31..4f98ff2b50 100644 --- a/collects/scribblings/scribble/scheme.scrbl +++ b/collects/scribblings/scribble/scheme.scrbl @@ -69,7 +69,7 @@ Like @scheme[to-paragraph], but @scheme[prefix1] is prefixed onto the first line, @scheme[prefix] is prefix to any subsequent line, and @scheme[suffix] is added to the end. The @scheme[prefix1], @scheme[prefix], and @scheme[suffix] arguments are used as -@tech{elements}, except that if @scheme[suffix] is a list of elements, +@tech{content}, except that if @scheme[suffix] is a list of elements, it is added to the end on its own line.} @@ -152,3 +152,29 @@ Provided @scheme[for-syntax]; like @scheme[make-element-id-transformer] for a transformer that produces @scheme[sym] typeset as a variable (like @scheme[schemevarfont])---unless it appears under quote or quasiquote, in which case @scheme[sym] is typeset as a symbol.} + +@deftogether[( +@defthing[output-color style?] +@defthing[input-color style?] +@defthing[input-background-color style?] +@defthing[no-color style?] +@defthing[reader-color style?] +@defthing[result-color style?] +@defthing[keyword-color style?] +@defthing[comment-color style?] +@defthing[paren-color style?] +@defthing[meta-color style?] +@defthing[value-color style?] +@defthing[symbol-color style?] +@defthing[variable-color style?] +@defthing[opt-color style?] +@defthing[error-color style?] +@defthing[syntax-link-color style?] +@defthing[value-link-color style?] +@defthing[module-color style?] +@defthing[module-link-color style?] +@defthing[block-color style?] +@defthing[highlighted-color style?] +)]{ + +Styles that are used for coloring Scheme programs, results, and I/O.} diff --git a/collects/scribblings/scribble/scribble.scrbl b/collects/scribblings/scribble/scribble.scrbl index f01c66a27d..070906c9ad 100644 --- a/collects/scribblings/scribble/scribble.scrbl +++ b/collects/scribblings/scribble/scribble.scrbl @@ -1,19 +1,15 @@ -#lang scribble/doc -@(require scribble/manual - scribble/bnf +#lang scribble/manual +@(require scribble/bnf "utils.ss") -@title{@bold{Scribble}: PLT Documentation Tool} +@title{@bold{Scribble}: PLT Documentation Tools} @author["Matthew Flatt" "Eli Barzilay"] -Scribble is a collection of tools for creating prose documents, -especially those that document libraries, and especially for HTML and -PDF (via LaTeX) output. More generally, it is useful for cases where -you need to deal with Scheme code that is rich in textual content: it -has a syntactic extension for writing almost free-form text and a tool -for using the scribble syntax for preprocessing text files with -embedded Scheme code. +Scribble is a collection of tools for creating ASCII, HTML, and +Latex/PDF documents with PLT Scheme. Suitable uses include the +creation of papers, books, literate programs, preprocessed text, and +PLT Scheme library documentation. This document itself is written using Scribble. At the time that it was written, its source was available at @@ -24,23 +20,11 @@ starting with the @filepath{scribble.scrbl} file. @table-of-contents[] @; ------------------------------------------------------------------------ -@include-section["how-to.scrbl"] -@include-section["layers.scrbl"] -@include-section["reader.scrbl"] -@include-section["struct.scrbl"] -@include-section["renderer.scrbl"] -@include-section["decode.scrbl"] -@include-section["doclang.scrbl"] -@include-section["docreader.scrbl"] -@include-section["basic.scrbl"] -@include-section["scheme.scrbl"] -@include-section["manual.scrbl"] -@include-section["eval.scrbl"] -@include-section["srcdoc.scrbl"] -@include-section["bnf.scrbl"] +@include-section["getting-started.scrbl"] +@include-section["generic.scrbl"] +@include-section["plt.scrbl"] @include-section["lp.scrbl"] -@include-section["xref.scrbl"] @include-section["preprocessor.scrbl"] -@include-section["config.scrbl"] +@include-section["internals.scrbl"] @index-section[] diff --git a/collects/scribblings/scribble/shaded.css b/collects/scribblings/scribble/shaded.css new file mode 100644 index 0000000000..75b47e814d --- /dev/null +++ b/collects/scribblings/scribble/shaded.css @@ -0,0 +1,5 @@ + +.Shaded { + width: 100%; + background-color: #E8E8FF; +} diff --git a/collects/scribblings/scribble/shaded.tex b/collects/scribblings/scribble/shaded.tex new file mode 100644 index 0000000000..4814ac887f --- /dev/null +++ b/collects/scribblings/scribble/shaded.tex @@ -0,0 +1,5 @@ + +\newenvironment{Shaded}{}{} +\newcommand{\Short}[1]{\begin{minipage}[c]{6ex}#1\end{minipage}} +\newcommand{\Medium}[1]{\begin{minipage}[c]{20ex}#1\end{minipage}} + diff --git a/collects/scribblings/scribble/struct.scrbl b/collects/scribblings/scribble/struct.scrbl index 62a4a22547..2f0ad66536 100644 --- a/collects/scribblings/scribble/struct.scrbl +++ b/collects/scribblings/scribble/struct.scrbl @@ -1,728 +1,263 @@ -#lang scribble/doc -@(require scribble/manual - "utils.ss" +#lang scribble/manual +@(require (except-in "utils.ss" + make-part make-paragraph make-table make-itemization make-compound-paragraph + make-element make-toc-element make-target-element make-toc-target-element + make-page-target-element make-redirect-target-element make-link-element + make-index-element + make-target-url target-url struct:target-url target-url? target-url-addr + deserialize-info:target-url-v0 + toc-element-toc-content part-title-content paragraph-content + element? element-content element-style) (for-label scribble/manual-struct + scribble/struct setup/main-collects)) -@title[#:tag "struct"]{Structures And Processing} - -@defmodule[scribble/struct] - -A document is represented as a @techlink{part}, as described in - @secref["parts"]. This representation is intended to - independent of its eventual rendering, and it is intended to be - immutable; rendering extensions and specific data in a document can - collude arbitrarily, however. - -A document is processed in three passes. The first pass is the - @deftech{collect pass}, which globally collects information in the - document, such as targets for hyperlinking. The second pass is the - @deftech{resolve pass}, which matches hyperlink references with - targets and expands delayed elements (where the expansion should not - contribute new hyperlink targets). The final pass is the - @deftech{render pass}, which generates the resulting document. None - of the passes mutate the document, but instead collect information in - side @scheme[collect-info] and @scheme[resolve-info] tables. - -@; ------------------------------------------------------------------------ - -@section[#:tag "parts"]{Parts} - -A @deftech{part} is an instance of @scheme[part]; among other things, - it has a title @techlink{content}, an initial @techlink{flow}, and a - list of subsection @techlink{parts}. An @scheme[unnumbered-part] is - the same as a @scheme[part], but it isn't numbered. A - @scheme[versioned-part] is add a version field to - @scheme[part]. There's no difference between a part and a full - document; a particular source module just as easily defines a - subsection (incorporated via @scheme[include-section]) as a document. - -A @deftech{flow} is an instance of @scheme[flow]; it has a list of - @techlink{blocks}. - -A @deftech{block} is either a @techlink{table}, an - @techlink{itemization}, a @techlink{blockquote}, a @techlink{paragraph}, - @techlink{compound paragraph}, or a @techlink{delayed block}. - -@itemize[ - - @item{A @deftech{table} is an instance of @scheme[table]; it - has a list of list of @techlink{flows} with a particular - style. In Latex output, each table cell is typeset as a - single line.} - - @item{A @deftech{itemization} is an instance of @scheme[itemization]; - it has a list of @techlink{flows}.} - - @item{A @deftech{blockquote} is an instance of - @scheme[blockquote]; it has list of @tech{blocks} that - are typeset as sub-flow, and by default the subflow is - inset.} - - @item{A @deftech{paragraph} is an instance of - @scheme[paragraph]; it has a @deftech{content}, which is - a list of @techlink{elements}: - - @itemize[ - - @item{An @deftech{element} can be a string, one of a few - symbols, an instance of @scheme[element] (possibly - @scheme[link-element], etc.), a - @techlink{part-relative element}, a - @techlink{delayed element}, or anything else - allowed by the current renderer. - - @itemize[ - - @item{A string element is included in the result - document verbatim, except for space, and - unless the element's style is - @scheme['hspace]. In a style other than - @scheme['hspace], consecutive spaces in the - output may be collapsed togther or replaced - with a line break. In the style - @scheme['hspace], all text is converted to - uncollapsable spaces that cannot be broken - across lines.} - - @item{A symbol element is either @scheme['mdash], - @scheme['ndash], @scheme['ldquo], - @scheme['lsquo], @scheme['rsquo], - @scheme['rarr], or @scheme['prime]; it is - rendered as the corresponding HTML entity - (even for Latex output).} - - @item{An instance of @scheme[element] has a list of - @techlink{elements} plus a style. The style's - interpretation depends on the rendrer, but it - can be one of a few special symbols (such as - @scheme['bold]) that are recognized by all - renderers.} - - @item{An instance of @scheme[link-element] has a - @techlink{tag} for the target of the link.} - - @item{An instance of @scheme[target-element] has a - @techlink{tag} to be referenced by - @scheme[link-element]s. An instance of the - subtype @scheme[toc-target-element] is - treated like a kind of section label, to be - shown in the ``on this page'' table for HTML - output.} - - @item{An instance of @scheme[index-element] has a - @techlink{tag} (as a target), a list of - strings for the keywords (for sorting and - search), and a list of @techlink{elements} to - appear in the end-of-document index.} - - @item{An instance of @scheme[collect-element] has a - procedure that is called in the - @techlink{collect pass} of document - processing to record information used by - later passes.} - - @item{A @deftech{part-relative element} is an - instance of @scheme[part-relative-element], - which has a procedure that is called in the - @techlink{collect pass} of document - processing to obtain @defterm{content} (i.e., - a list of @defterm{elements}). When the - part-relative element's procedure is called, - collected information is not yet available, - but information about the enclosing parts is - available.} - - @item{A @deftech{delayed element} is an instance of - @scheme[delayed-element], which has a - procedure that is called in the - @techlink{resolve pass} of document - processing to obtain @defterm{content} (i.e., - a list of @defterm{elements}).} - - @item{An instance of @scheme[aux-element] is - excluded in the text of a link when it - appears in a referenced section name.} - - @item{An instance of @scheme[hover-element] adds - text to show in render HTML when the mouse - hovers over the elements.} - - @item{An instance of @scheme[script-element] - provides script code (usually - @as-index{Javascript}) to run in the browser - to generate the element; the element's normal - content is used when scripting is disabled in - the browser, or for rendering to other - formats.} - - @item{An instance of @scheme[render-element] has a - procedure that is called in the - @techlink{render pass} of document - processing.} - - ]}]} - - @item{A @deftech{compound paragraph} is an instance of - @scheme[compound-paragraph]; like @scheme[blockquote], it - has list of @tech{blocks}, but the blocks are typeset as - a single paragraph (e.g., no indentation after the first - block) instead of inset.} - - @item{A @deftech{delayed block} is an instance of - @scheme[delayed-block], which has a procedure that - is called in the @techlink{resolve pass} of document - processing to obtain a @defterm{block}.} - -] - -@; ------------------------------------------------------------------------ - -@section[#:tag "tags"]{Tags} - -A @deftech{tag} is a list containing a symbol and either a string, a -@scheme[generated-tag] instance, or an arbitrary list. The symbol -effectively identifies the type of the tag, such as @scheme['part] for -a tag that links to a part, or @scheme['def] for a Scheme function -definition. The symbol also effectively determines the interpretation -of the second half of the tag. - -A part can have a @deftech{tag prefix}, which is effectively added -onto the second item within each tag whose first item is -@scheme['part] or @scheme['tech]. The prefix is added to a string -value by creating a list containing the prefix and string, and it is -added to a list value using @scheme[cons]; a prefix is not added to a -@scheme[generated-tag] instance. The prefix is used for reference -outside the part, including the use of tags in the part's -@scheme[tags] field. Typically, a document's main part has a tag -prefix that applies to the whole document; references to sections and -defined terms within the document from other documents must include the prefix, -while references within the same document omit the prefix. Part -prefixes can be used within a document as well, to help disambiguate -references within the document. - -Some procedures accept a ``tag'' that is just the string part of the -full tag, where the symbol part is supplied automatically. For -example, @scheme[section] and @scheme[secref] both accept a string -``tag'', where @scheme['part] is implicit. - -@; ------------------------------------------------------------------------ - -@section[#:tag "passes"]{Collected and Resolved Information} - -The @techlink{collect pass}, @techlink{resolve pass}, and -@techlink{render pass} processing steps all produce information that -is specific to a rendering mode. Concretely, the operations are all -represented as methods on a @scheme[render%] object. - -The result of the @method[render% collect] method is a -@scheme[collect-info] instance. This result is provided back as an -argument to the @method[render% resolve] method, which produces a -@scheme[resolve-info] value that encapsulates the results from both -iterations. The @scheme[resolve-info] value is provided back to the -@method[render% resolve] method for final rendering. - -Optionally, before the @method[render% resolve] method is called, -serialized information from other documents can be folded into the -@scheme[collect-info] instance via the @method[render% -deserialize-info] method. Other methods provide serialized information -out of the collected and resolved records. - -During the @techlink{collect pass}, the procedure associated with a -@scheme[collect-element] instance can register information with -@scheme[collect-put!]. - -During the @techlink{resolve pass}, collected information for a part -can be extracted with @scheme[part-collected-info], which includes a -part's number and its parent part (or @scheme[#f]). More generally, -the @scheme[resolve-get] method looks up information previously -collected. This resolve-time information is normally obtained by the -procedure associated with a @techlink{delayed block} or -@techlink{delayed element}. - -The @scheme[resolve-get] information accepts both a @scheme[part] and -a @scheme[resolve-info] argument. The @scheme[part] argument enables -searching for information in each enclosing part before sibling parts. - -@; ------------------------------------------------------------------------ - -@section{Structure Reference} - -@defstruct[part ([tag-prefix (or/c false/c string?)] - [tags (listof tag?)] - [title-content (or/c false/c list?)] - [style any/c] - [to-collect list?] - [flow flow?] - [parts (listof part?)])]{ - -The @scheme[tag-prefix] field determines the optional @techlink{tag -prefix} for the part. - -The @scheme[tags] indicates a list of @techlink{tags} that each link -to the section. - -The @scheme[title-content] field holds the part's title, if any. - -The @scheme[style] field is normally either a symbol or a list. The -currently recognized style symbols (alone or in a list) or other -values (must be in a list) are as follows: - -@itemize[ - - @item{@scheme['toc] --- sub-parts of the part are rendered on separate - pages for multi-page HTML mode.} - - @item{@scheme['non-toc] --- initial sub-parts of the part are - @emph{not} rendered on separate pages for multi-page HTML - mode; this style applies only to the main part.} - - @item{@scheme['index] --- the part represents an index.} - - @item{@scheme['reveal] --- shows sub-parts when this part is - displayed in a table-of-contents panel in HTML output (which - normally shows only the top-level sections).} - - @item{@scheme['hidden] --- the part title is not shown in rendered output.} - - @item{@scheme['quiet] --- in HTML output and most other output modes, - hides entries for sub-parts of this part in a - @scheme[table-of-contents] or @scheme[local-table-of-contents] - listing except when those sub-parts are top-level entries in - the listing.} - - @item{@scheme['no-toc] --- as a style for the main part of a - document, causes the HTML output to not include a margin box - for the main table of contents; the ``on this page'' box that - contains @scheme[toc-element] and @scheme[toc-target-element] - links (and that only includes an ``on this page'' label for - multi-page documents) takes on the location and color of the - main table of contents, instead.} - - @item{@scheme[`(css ,_path)] --- generated HTML refers to (a copy - of) @scheme[_path] as CSS.} - - @item{@scheme[`(tex ,_path)] --- generated Latex includes - (a copy of) @scheme[_path] in the document header.} - - @item{@scheme[`(body-id ,_string)] --- generated HTML uses - @scheme[_string] as the @tt{id} attribute of the @tt{body} - tag; this style can be set separately for parts that start - different HTML pages, otherwise it is effectively inherited by - sub-parts; the default is @scheme["scribble-plt-scheme.org"], - but @exec{setup-plt} installs @scheme["doc-plt-scheme.org"] - as the @tt{id} for any document that it builds.} - -] - -The @scheme[to-collect] field contains @techlink{content} that is -inspected during the @techlink{collect pass}, but ignored in later -passes (i.e., it doesn't directly contribute to the output). - -The @scheme[flow] field contains the part's initial flow (before -sub-parts). - -The @scheme[parts] field contains sub-parts. - +@(define (compat) @italic{For backward compatibility.}) +@(define-syntax-rule (compat/comp id) + @elem{@compat[] Compared to the normal constructor for @scheme[id]}) + +@title[#:tag "struct"]{Compatibility Structures And Processing} + +@defmodule[scribble/struct]{ +The @scheme[scribble/struct] compatibility library mostly re-exports +@scheme[scribble/core], but using some different names (e.g., +@scheme[blockquote] instead of @scheme[nested-flow]).} + +The following structure types and functions are re-exported directly: + +@schemeblock[collect-info resolve-info tag? block? + delayed-block collected-info delayed-element ; delayed-element-content delayed-block-blocks current-serialize-resolve-info + part-relative-element collect-info-parents ; part-relative-element-content delayed-index-desc + collect-element render-element generated-tag ; generate-tag current-tag-prefixes add-current-tag-prefix + tag-key content->string element->string ; strip-aux + block-width element-width + info-key? part-collected-info collect-put! + resolve-get resolve-get/tentative resolve-get/ext? + resolve-search resolve-get-keys] + +The following structure types are re-exported, but the constructors and some selectors +are replaced as documented further below: + +@schemeblock[part paragraph table itemization compound-paragraph + element toc-element target-element toc-target-element + page-target-element redirect-target-element link-element + index-element] + +Several additional compatibility functions and structure types are +also exported. + +@defproc[(make-part [tag-prefix (or/c false/c string?)] + [tags (listof tag?)] + [title-content (or/c false/c list?)] + [style any/c] + [to-collect list?] + [blocks (listof block?)] + [parts (listof part?)]) + part?]{ + +@compat/comp[part], parses @scheme[style] to convert old formats to +the current one. Also, if @scheme[title-content] is a list with a +single item, the item by itself is stored in the resulting +@scheme[part].} + +@defproc[(part-flow [p part?]) (listof block?)]{ + +@compat[] An alias for @scheme[part-blocks].} + +@defproc[(part-title-content [p part?]) list?]{ + +@compat[] Like the normal selector, but if the result would not be a list, it is +coerced to one.} + +@deftogether[( +@defproc[(make-versioned-part [tag-prefix (or/c false/c string?)] + [tags (listof tag?)] + [title-content (or/c false/c list?)] + [style any/c] + [to-collect list?] + [blocks (listof block?)] + [parts (listof part?)] + [version string?]) + part?] +@defproc[(versioned-part? [v any/c]) boolean?] +)]{ + +@compat[] Like @scheme[make-part], but adds a the +@scheme[document-version] style @tech{variant} using the given +@scheme[version]. The @scheme[versioned-part?] predicate recognizes a +@scheme[part] with a @scheme[document-version] variant.} + +@deftogether[( +@defproc[(make-unnumbered-part [tag-prefix (or/c false/c string?)] + [tags (listof tag?)] + [title-content (or/c false/c list?)] + [style any/c] + [to-collect list?] + [blocks (listof block?)] + [parts (listof part?)]) + part?] +@defproc[(unnumbered-part? [v any/c]) boolean?] +)]{ + +@compat[] Like @scheme[make-part], but adds the @scheme['unnumbered] +style @tech{variant}. The @scheme[unnumbered-part?] predicate +recognizes a @scheme[part] with the @scheme['unnumbered] variant.} + + +@defproc[(make-paragraph [content list?]) paragraph?]{ + +@compat/comp[paragraph], omits a style argument. Also, if +@scheme[content] is a list containing a single item, the item by +itself is stored in the resulting @scheme[paragraph].} + +@defproc[(paragraph-content [p paragraph?]) list?]{ + +@compat[] Like the normal selector, but if the result would not be a list, it is +coerced to one. } -@defstruct[(unnumbered-part part) ()]{ +@deftogether[( +@defproc[(make-styled-paragraph [style any/c][content list?]) paragraph?] +@defproc[(styled-paragraph? [v any/c]) boolean?] +@defproc[(styled-paragraph-style [p paragraph?]) style?] +)]{ -Although a section number is computed for an ``unnumbered'' section -during the @techlink{collect pass}, the number is not rendered. +@compat/comp[paragraph], parses @scheme[style] to convert old formats +to the current one. The @scheme[styled-paragraph?] predicate and +@scheme[styled-paragraph-style] accessor are aliases for +@scheme[paragraph?] and @scheme[paragraph-style].} -} +@deftogether[( +@defproc[(make-omitable-paragraph [content list?]) paragraph?] +@defproc[(omitable-paragraph? [v any/c]) boolean?] +)]{ -@defstruct[(versioned-part part) ([version (or/c string? false/c)])]{ +@compat[] Like @scheme[make-paragraph], but adds the +@scheme['omitable] style @tech{variant}. The +@scheme[omitable-paragraph?] predicate checks for a paragraph with the +variant.} -Supplies a version number for this part and its sub-parts (except as -overridden). A @scheme[#f] version is the same as not supplying a -specific version. -The version number that is not @scheme[""] may be used when rendering -a document. At a minimum, a non-@scheme[""] version is rendered when -it is attached to a part representing the whole document. The default -version for a document is @scheme[(version)].} +@defproc[(make-table [style any/c] + [blocksss (listof (listof (or/c (listof block?) (one-of/c 'cont))))]) + table?]{ +@compat/comp[table], the style is converted, and each cell has a list +of blocks instead of a single block. If any such list has multiple +blocks, they are combined into a @scheme[nested-flow].} -@defstruct[flow ([paragraphs (listof block?)])]{ +@defproc[(table-flowss [table table?]) + (listof (listof (or/c (listof block?) (one-of/c 'cont))))]{ -A @techlink{flow} has a list of @tech{blocks}. +@compat[] Like @scheme[table-blockss], but adds a list wrapper to be +consistent with @scheme[make-table].} -} +@defproc[(make-itemization [blockss (listof (listof block?))]) itemization?]{ -@defstruct[paragraph ([content list?])]{ +@compat/comp[itemization], omits a style argument.} -A @techlink{paragraph} has a list of @tech{elements}. +@deftogether[( +@defproc[(make-styled-itemization [style any/c] + [blockss (listof (listof block?))]) itemization?] +@defproc[(styled-itemization? [v any/c]) boolean?] +@defproc[(styled-itemization-style [i itemization?]) style?] +)]{ -} +@compat/comp[itemization], parses @scheme[style] to convert old +formats to the current one. The @scheme[styled-itemization?] predicate +is an alias for @scheme[itemization?], and +@scheme[styled-itemization-style] is an alias for +@scheme[itemization-style].} -@defstruct[(omitable-paragraph paragraph) ()]{ +@defproc[(make-blockquote [style any/c][blocks (listof block?)]) + nested-flow?]{ -Equivalent to a @scheme[paragraph], except that when a table cell -contains a single @scheme[omitable-paragraph], then when rendering to -HTML, no @tt{p} tag wraps the cell content. +@compat[] Like @scheme[make-nested-flow], but @scheme[style] is +parsed to the current format.} -} +@deftogether[( +@defproc[(make-auxiliary-table [style any/c] + [blocksss (listof (listof (or/c (listof block?) (one-of/c 'cont))))]) + table?] +@defproc[(auxiliary-table? [v any/c]) boolean?] +)]{ -@defstruct[(styled-paragraph paragraph) ([style any/c])]{ +@compat[] Like @scheme[make-table], but adds the @scheme['aux] style +@tech{variant}. The @scheme[auxiliary-table?] predicate recognizes +tables with the @scheme['aux] variant.} -The @scheme[style] can be -@itemize[ +@defproc[(make-compound-paragraph [style any/c] + [blocks (listof block?)]) + compound-paragraph?]{ - @item{A string that corresponds to a CSS class for HTML output or a - macro for Latex output (see @secref["extra-style"]).} +@compat/comp[compound-paragraph], parses @scheme[style] to convert old +formats to the current one.} - @item{An instance of @scheme[with-attributes], which combines a base - style with a set of additional HTML attributes.} +@deftogether[( +@defproc[(make-element [style any/c] [content list?]) element?] +@defproc[(make-toc-element [style any/c] [content list?][toc-content list?]) toc-element?] +@defproc[(make-target-element [style any/c] [content list?][tag tag?]) target-element?] +@defproc[(make-toc-target-element [style any/c] [content list?][tag tag?]) toc-target-element?] +@defproc[(make-page-target-element [style any/c] [content list?][tag tag?]) page-target-element?] +@defproc[(make-redirect-target-element [style any/c] [content list?][tag tag?] + [alt-path path-string?] [alt-anchor string?]) redirect-target-element?] +@defproc[(make-link-element [style any/c] [content list?][tag tag?]) link-element?] +@defproc[(make-index-element [style any/c] [content list?][tag tag?] + [tag tag?] [plain-seq (and/c pair? (listof string?))] + [entry-seq list?] [desc any/c]) index-element?] +)]{ - @item{The symbol @scheme['div], which generates @tt{
} HTML - output instead of @tt{

}. For Latex output, a string for a - macro name is extracted from the @scheme['class] mapping of a - @scheme[with-attributes] wrapper, if one is present.} +@compat[] Compared to the normal constructors, parses @scheme[style] to convert old +formats to the current one.} -]} +@deftogether[( +@defproc[(element? [v any/c]) boolean?] +@defproc[(element-content [e element?]) list?] +@defproc[(element-style [e element?]) element-style?] +)]{ -@defstruct[table ([style any/c] - [flowss (listof (listof (or/c flow? (one-of/c 'cont))))])]{ +@compat[] A @tech{content} list is treated as an element by these functions, +and the result of @scheme[element-content] is always a list.} -A @techlink{table} has, roughly, a list of list of flows. A cell in -the table can span multiple columns by using @scheme['cont] instead of -a flow in the following columns (i.e., for all but the first in a set -of cells that contain a single flow). -When a table cell's flow has multiple paragraphs, the rendered output -starts each paragraph on its own line, but generally doesn't insert -space between the paragraphs (as it would at the top level). For Latex -output, individual paragraphs are not automatically line-wrapped; to -get a line-wrapped paragraph, use an element with a string style and -define a corresponding Latex macro in terms of @tt{parbox}. For Latex -output of blocks in the flow that are @scheme[blockquote]s, -@scheme[itemization]s, @scheme[compound-paragraph]s, or -@scheme[delayed-block]s, the block is wrapped with @tt{minipage} using -@tt{linewidth} as the width. +@defproc[(make-aux-element [style any/c] [content list?]) element?]{ -The @scheme[style] can be any of the following: +@compat[] Like @scheme[make-element], but adds the @scheme['aux] style +@tech{variant}.} -@itemize[ - @item{A string that corresponds to a CSS class for HTML output or an - environment for Latex output (see @secref["extra-style"]).} +@defproc[(make-hover-element [style any/c] [content list?] [text string?]) element?]{ - @item{@scheme['boxed] to render as a definition.} +@compat[] Like @scheme[make-element], but adds @scheme[hover-variant] +containing @scheme[text] to the element's style.} - @item{@scheme['centered] to render centered horizontally.} - @item{@scheme['at-left] to render left-aligned (HTML only).} +@defproc[(make-script-element [style any/c] [content list?] [type string?] + [script (or/c path-string? (listof string?))]) element?]{ - @item{@scheme['at-right] to render right-aligned (HTML only).} +@compat[] Like @scheme[make-element], but adds @scheme[script-variant] +containing @scheme[type] and @scheme[script] to the element's style.} - @item{An association list with the following optional mappings: - - @itemize[ - - @item{@scheme['style] to a string for a CSS class for HTML output.} - - @item{@scheme['alignment] to a list of symbols and - @scheme[#f]s (one for each column); each symbol can be - @scheme['left], @scheme['right], or @scheme['center].} - - @item{@scheme['valignment] to a list of symbols and - @scheme[#f]s (one for each column); each symbol can be - @scheme['top], @scheme['baseline], @scheme['center], - or @scheme['bottom].} - - @item{@scheme['row-styles] to a list of association lists, - one for each row in the table. Each of these nested - association lists can map @scheme['alignment] and - @scheme['valignment] to a list of symbols and - @scheme[#f]s (one for each column cell) and/or - @scheme['style] to a list of strings and @scheme[#f]s - (one for each column cell) for a CSS class in HTML - output. Row-specific @scheme['valignment] and - @scheme['alignment] associations override row-independent - associations.} - - ]} - - @item{An instance of @scheme[with-attributes], which combines a base - style with a set of additional HTML attributes.} - -]} - - -@defstruct[itemization ([flows (listof flow?)])]{ - -A @techlink{itemization} has a list of flows. - -} - - -@defstruct[(styled-itemization itemization) ([style any/c])]{ - -The @scheme[style] can be - -@itemize[ - - @item{A string that corresponds to a CSS class for HTML output or a - macro for Latex output (see @secref["extra-style"]).} - - @item{The symbol @scheme['ordered], which generates @tt{

    } HTML - output instead of @tt{
  1. } or an Latex enumeration instead of - an itemization.} - -]} - - -@defstruct[blockquote ([style any/c] - [paragraphs (listof block?)])]{ - -A @techlink{blockquote} has a style and a list of @tech{blocks}. The -@scheme[style] field is normally a string that corresponds to a CSS -class for HTML output or Latex environment for Latex output where a -leading @litchar{\} in the style name is treated specially (see -@secref["extra-style"]). - -} - -@defstruct[compound-paragraph ([style any/c] - [blocks (listof block?)])]{ - -A @techlink{compound paragraph} has a style and a list of @tech{blocks}. The -@scheme[style] field is normally a string that corresponds to a CSS -class for HTML output or Latex environment for Latex output where a -leading @litchar{\} in the style name is treated specially (see -@secref["extra-style"]). - -} - -@defstruct[delayed-block ([resolve (any/c part? resolve-info? . -> . block?)])]{ - -The @scheme[resolve] procedure is called during the @techlink{resolve -pass} to obtain a normal @tech{block}. The first argument to -@scheme[resolve] is the renderer. - -} - - -@defstruct[element ([style any/c] - [content list?])]{ - -The @scheme[style] field is normally either - -@itemize[ - - @item{a string, which corresponds to a CSS class for HTML output and - a macro name for Latex output (see @secref["extra-style"]);} - - @item{one of the symbols that all renderers recognize: @scheme['tt], - @scheme['italic], @scheme['bold], @scheme['sf], @scheme['url], - @scheme['subscript], @scheme['superscript], @scheme['hspace], - or @scheme['newline] (which renders a line break independent of - the @scheme[content]);} - - @item{a list of the form @scheme[(list 'color _name)] or - @scheme[(list 'color _byte _byte _byte)] to set the text color, - where @scheme[_name] is one of @scheme["white"], - @scheme["black"], @scheme["red"], @scheme["green"], - @scheme["blue"], @scheme["cyan"], @scheme["magenta"], or - @scheme["yellow"], or three @scheme[_byte]s specify RGB - values;} - - @item{a list of the form @scheme[(list 'bg-color _name)] or - @scheme[(list 'bg-color _byte _byte _byte)] to set the text - background color (with the same constraints and meanings as for - @scheme['color]);} - - @item{an instance of @scheme[target-url] to generate a hyperlink;} - - @item{an instance of @scheme[image-file] to support an inline image; or} - - @item{an instance of @scheme[with-attributes], which combines a base - style with a set of additional HTML attributes.} - -] - -The @scheme[content] field is a list of @techlink{elements}. - -} - - -@defstruct[(target-element element) ([tag tag?])]{ - -Declares the content as a hyperlink target for @scheme[tag]. - -} - - -@defstruct[(toc-target-element target-element) ()]{ - -Like @scheme[target-element], the content is also a kind of section -label to be shown in the ``on this page'' table for HTML output. - -} - - -@defstruct[(toc-element element) ([toc-content list?])]{ - -Similar to @scheme[toc-target-element], but with specific content for -the ``on this page'' table specified in the @scheme[toc-content] -field. - -} - - -@defstruct[(link-element element) ([tag tag?])]{ - -Hyperlinks the content to @scheme[tag]. - -} - - -@defstruct[(index-element element) ([tag tag?] - [plain-seq (and/c pair? (listof string?))] - [entry-seq list?] - [desc any/c])]{ - -The @scheme[plain-seq] specifies the keys for sorting, where the first -@tech{element} is the main key, the second is a sub-key, etc. For -example, an ``night'' portion of an index might have sub-entries for -``night, things that go bump in'' and ``night, defender of the''. The -former would be represented by @scheme[plain-seq] @scheme['("night" -"things that go bump in")], and the latter by @scheme['("night" -"defender of the")]. Naturally, single-@tech{element} -@scheme[plain-seq] lists are the common case, and at least one word is -required, but there is no limit to the word-list length. The strings in -@scheme[plain-seq] must not contain a newline character. - -The @scheme[entry-seq] list must have the same length as -@scheme[plain-seq]. It provides the form of each key to render in the -final document. - -The @scheme[desc] field provides additional information about the -index entry as supplied by the entry creator. For example, a reference -to a procedure binding can be recognized when @scheme[desc] is an -instance of @scheme[procedure-index-desc]. See -@schememodname[scribble/manual-struct] for other typical types of -@scheme[desc] values. - -See also @scheme[index].} - - -@defstruct[(aux-element element) ()]{ - -Instances of this structure type are intended for use in titles, where - the auxiliary part of the title can be omitted in hyperlinks. See, - for example, @scheme[secref]. - -} - -@defstruct[(hover-element element) ([text string?])]{ - -The @scheme[text] is displayed in HTML output when the mouse hovers -over the element's content.} - - -@defstruct[(script-element element) ([type string?] - [script (or/c path-string? - (listof string?))])]{ - -For HTML rendering, when scripting is enabled in the browser, -@scheme[script] is used for the element instead of its normal -content---it can be either path naming a script file to refer to, or -the contents of the script. The @scheme[type] string is normally -@scheme["text/javascript"].} - - -@defstruct[delayed-element ([resolve (any/c part? resolve-info? . -> . list?)] - [sizer (-> any/c)] - [plain (-> any/c)])]{ - -The @scheme[render] procedure's arguments are the same as for -@scheme[delayed-block], but the result is @techlink{content} (i.e., -a list of @techlink{elements}). Unlike @scheme[delayed-block], the -result of the @scheme[render] procedure's argument is remembered on -the first call for re-use for a particular resolve pass. - -The @scheme[sizer] field is a procedure that produces a substitute -@techlink{element} for the delayed element for the purposes of -determining the delayed element's width (see @scheme[element-width]). - -The @scheme[plain] field is a procedure that produces a substitute -@techlink{element} when needed before the @techlink{collect pass}, -such as when @scheme[element->string] is used before the @tech{collect -pass}. - -} - - -@defstruct[part-relative-element ([resolve (collect-info? . -> . list?)] - [sizer (-> any/c)] - [plain (-> any/c)])]{ - -Similar to @scheme[delayed-block], but the replacement -@techlink{content} is obtained in the @techlink{collect pass} by -calling the function in the @scheme[resolve] field. - -The @scheme[resolve] function can call @scheme[collect-info-parents] -to obtain a list of @techlink{parts} that enclose the element, -starting with the nearest enclosing section. Functions like -@scheme[part-collected-info] and @scheme[collected-info-number] can -extract information like the part number. - -} - - -@defstruct[(collect-element element) ([collect (collect-info . -> . any)])]{ - -Like @scheme[element], but the @scheme[collect] procedure is called -during the @techlink{collect pass}. The @scheme[collect] procedure -normally calls @scheme[collect-put!]. - -Unlike @scheme[delayed-element] or @scheme[part-relative-element], the -element remains intact (i.e., it is not replaced) by either the -@tech{collect pass} or @tech{resolve pass}. - -} - -@defstruct[(render-element element) ([render (any/c part? resolve-info? . -> . any)])]{ - -Like @scheme[delayed-element], but the @scheme[render] procedure is called -during the @techlink{render pass}. - -If a @scheme[render-element] instance is serialized (such as when -saving collected info), it is reduced to a @scheme[element] instance. - -} @defstruct[with-attributes ([style any/c] [assoc (listof (cons/c symbol? string?))])]{ -Used for an @scheme[element]'s style to combine a base style with +@compat[] Used for an @scheme[element]'s style to combine a base style with arbitrary HTML attributes. When the @scheme[style] field is itself an instance of @scheme[with-attributes], its content is automatically flattened into the enclosing @scheme[with-attributes] when it is used -(when, e.g., rendering an @tech{element} or a styled @tech{paragraph}).} - - -@defstruct[collected-info ([number (listof (or/c false/c integer?))] - [parent (or/c false/c part?)] - [info any/c])]{ - -Computed for each part by the @techlink{collect pass}. - -} +(when, e.g., rendering an @scheme[element] or @scheme[paragraph]).} @defstruct[target-url ([addr path-string?] [style any/c])]{ -Used as a style for an @scheme[element]. The @scheme[style] at this +@compat[] Used as a style for an @scheme[element]. The @scheme[style] at this layer is a style for the hyperlink.} @@ -730,191 +265,16 @@ layer is a style for the hyperlink.} (cons/c 'collects (listof bytes?)))] [scale real?])]{ -Used as a style for an @scheme[element] to inline an image. The +@compat[] Used as a style for an @scheme[element] to inline an image. The @scheme[path] field can be a result of -@scheme[path->main-collects-relative]. - -For Latex output, a @filepath{.gif} suffix on @scheme[path] is -replaced with a @filepath{.png} suffix (because animated GIFs can be -useful in HTML output, but Latex does not support GIFs). For HTML -output, a @filepath{.pdf} suffix on @scheme[path] is replaced with a -@filepath{.png} suffix (because PDF line drawings can be more -appropriate for Latex output, but HTML output needs bitmaps).} +@scheme[path->main-collects-relative].} -@defproc[(block? [v any/c]) boolean?]{ - -Returns @scheme[#t] if @scheme[v] is a @scheme[paragraph], -@scheme[table], @scheme[itemization], @scheme[blockquote], or -@scheme[delayed-block], @scheme[#f] otherwise. - -} -@defproc[(tag? [v any/c]) boolean?]{ +@defproc*[([(element->string (element content?)) string?] + [(element->string (element content?) (renderer any/c) (p part?) (info resolve-info?)) string?])]{ -Returns @scheme[#t] if @scheme[v] is acceptable as a link -@techlink{tag}, which is a list containing a symbol and either a -string, a @scheme[generated-tag] instance, or a list (of arbitrary -values).} +@compat[] An alias for @scheme[content->string]. - -@defstruct[generated-tag ()]{ - -A placeholder for a tag to be generated during the @techlink{collect - pass}. Use @scheme[tag-key] to convert a tag containing a - @scheme[generated-tag] instance to one containing a string. - -} - - -@defproc*[([(content->string (content list?)) string?] - [(content->string (content list?) (renderer any/c) (p part?) (info resolve-info?)) string?])]{ - -Converts a list of @tech{elements} to a single string (essentially -rendering the content as ``plain text''). - -If @scheme[p] and @scheme[info] arguments are not supplied, then a -pre-``collect'' substitute is obtained for @tech{delayed -elements}. Otherwise, the two arguments are used to force the -@tech{delayed element} (if it has not been forced already).} - - -@defproc*[([(element->string (element any/c)) string?] - [(element->string (element any/c) (renderer any/c) (p part?) (info resolve-info?)) string?])]{ - -Like @scheme[content->string], but for a single @tech{element}. - -} - -@defproc[(element-width (element any/c)) exact-nonnegative-integer?]{ - -Returns the width in characters of the given @tech{element}. - -} - - -@defproc[(block-width (e block?)) exact-nonnegative-integer?]{ - -Returns the width in characters of the given @tech{block}.} - - -@defstruct[collect-info ([ht any/c] [ext-ht any/c] [parts any/c] - [tags any/c] [gen-prefix any/c] - [relatives any/c] - [parents (listof part?)])]{ - -Encapsulates information accumulated (or being accumulated) from the -@techlink{collect pass}. The fields are exposed, but not currently -intended for external use, except that @scheme[collect-info-parents] -is intended for external use. - -} - -@defstruct[resolve-info ([ci any/c] [delays any/c] [undef any/c])]{ - -Encapsulates information accumulated (or being accumulated) from the -@techlink{resolve pass}. The fields are exposed, but not currently -intended for external use. - -} - -@defproc[(info-key? [v any/c]) boolean?]{ - -Returns @scheme[#t] if @scheme[v] is an @deftech{info key}: a list of -at least two elements whose first element is a symbol. The result is -@scheme[#f] otherwise. - -For a list that is an info tag, the interpretation of the second -element of the list is effectively determined by the leading symbol, -which classifies the key. However, a @scheme[#f] value as the second -element has an extra meaning: collected information mapped by such -info keys is not propagated out of the part where it is collected; -that is, the information is available within the part and its -sub-parts, but not in ancestor or sibling parts. - -Note that every @techlink{tag} is an info key. - -} - -@defproc[(collect-put! [ci collect-info?] [key info-key?] [val any/c]) - void?]{ - -Registers information in @scheme[ci]. This procedure should be called -only during the @techlink{collect pass}. - -} - -@defproc[(resolve-get [p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) - any/c]{ - -Extract information during the @techlink{resolve pass} or -@techlink{render pass} for @scheme[p] from @scheme[ri], where the -information was previously registered during the @techlink{collect -pass}. See also @secref["passes"]. - -The result is @scheme[#f] if the no value for the given key is found. -Furthermore, the search failure is recorded for potential consistency -reporting, such as when @exec{setup-plt} is used to build -documentation. - -} - - -@defproc[(resolve-get/ext? [p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) - (values any/c boolean?)]{ - -Like @scheme[render-get], but returns a second value to indicate -whether the resulting information originated from an external source -(i.e., a different document).} - - -@defproc[(resolve-search [dep-key any/c][p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) - void?]{ - -Like @scheme[resolve-get], but a shared @scheme[dep-key] groups -multiple searches as a single request for the purposes of consistency -reporting and dependency tracking. That is, a single success for the -same @scheme[dep-key] means that all of the failed attempts for the -same @scheme[dep-key] have been satisfied. However, for dependency -checking, such as when using @exec{setup-plt} to re-build -documentation, all attempts are recorded (in case external changes -mean that an earlier attempt would succeed next time). - -} - -@defproc[(resolve-get/tentative [p (or/c part? false/c)] [ri resolve-info?] [key info-key?]) - any/c]{ - -Like @scheme[resolve-search], but without dependency tracking. For -multi-document settings where dependencies are normally tracked, such -as when using @exec{setup-plt} to build documentation, this function -is suitable for use only for information within a single document. - -} - -@defproc[(resolve-get-keys [p (or/c part? false/c)] - [ri resolve-info?] - [pred (info-key? . -> . any/c)]) - list?]{ - -Applies @scheme[pred] to each key mapped for @scheme[p] in -@scheme[ri], returning a list of all keys for which @scheme[pred] -returns a true value. - -} - -@defproc[(part-collected-info [p part?] - [ri resolve-info?]) - collected-info?]{ - -Returns the information collected for @scheme[p] as recorded within -@scheme[ri]. - -} - -@defproc[(tag-key [t tag?] [ri resolve-info?]) tag?]{ - -Converts a @scheme[generated-tag] value with @scheme[t] to a string. - -} +} \ No newline at end of file diff --git a/collects/scribblings/scribble/utils.ss b/collects/scribblings/scribble/utils.ss index abf1581aeb..b585c13454 100644 --- a/collects/scribblings/scribble/utils.ss +++ b/collects/scribblings/scribble/utils.ss @@ -1,6 +1,7 @@ #lang scheme/base -(require scribble/struct +(require scribble/core + scribble/html-variants scribble/manual (prefix-in scheme: scribble/scheme) (prefix-in scribble: scribble/reader)) @@ -15,25 +16,27 @@ [(_ mod ...) (begin (bounce-for-label mod) ...)])) (bounce-for-label (all-except scheme (link) ()) - scribble/struct + scribble/core scribble/base-render scribble/decode scribble/manual scribble/scheme + scribble/html-variants + scribble/latex-variants scribble/eval scribble/bnf) (provide scribble-examples litchar/lines) (define (as-flow e) - (make-flow (list (if (block? e) e (make-paragraph (list e)))))) + (if (block? e) e (make-paragraph plain (list e)))) (define (litchar/lines . strs) (let ([strs (regexp-split #rx"\n" (apply string-append strs))]) (if (= 1 (length strs)) (litchar (car strs)) (make-table - #f + plain (map (lambda (s) ; the nbsp is needed for IE (list (as-flow (if (string=? s "") 'nbsp (litchar s))))) strs))))) @@ -69,7 +72,7 @@ p)])) (define (scribble-examples . lines) - (define reads-as (make-paragraph (list spacer "reads as" spacer))) + (define reads-as (make-paragraph plain (list spacer "reads as" spacer))) (let* ([lines (apply string-append lines)] [p (open-input-string lines)]) (port-count-lines! p) @@ -87,7 +90,7 @@ (cdr (apply append (map (lambda (x) (list #f x)) r))) r)]) (make-table - #f + plain (map (lambda (x) (let ([@expr (if x (litchar/lines (car x)) "")] [sexpr (if x @@ -122,9 +125,10 @@ (list (as-flow (make-element 'newline '()))) (list (as-flow (make-element 'tt (str->elts str)))))) (define (small-attr attr) - (make-with-attributes attr '([style . "font-size: 82%;"]))) + (make-style attr (list + (make-attributes '([style . "font-size: 82%;"]))))) (define (make-box strs) - (make-table (small-attr 'boxed) (map make-line strs))) + (make-table (small-attr "Shaded") (map make-line strs))) (define filenames (map car more)) (define indent (let ([d (- max-textsample-width (for*/fold ([m 0]) @@ -138,16 +142,20 @@ ;; Note: the font-size property is reset for every table, so we need it ;; everywhere there's text, and they don't accumulate for nested tables (values - (make-table (make-with-attributes - '([alignment right left] [valignment top top]) - '()) + (make-table + (make-style #f + (list (make-table-columns (list (make-style (if (null? filenames) + "Short" + "Medium") + '(right top)) + (make-style #f '(left top)))))) (cons (list (as-flow (make-table (small-attr #f) (list (list (as-flow indent))))) (as-flow (make-box strs1))) (map (lambda (file strs) (let* ([file (make-element 'tt (list file ":" 'nbsp))] [file (list (make-element 'italic (list file)))]) - (list (as-flow (make-element '(bg-color 232 232 255) file)) + (list (as-flow (make-element (make-style #f (list (make-background-color-variant '(232 232 255)))) file)) (as-flow (make-box strs))))) filenames strsm))) (make-box strs2))) @@ -155,8 +163,11 @@ (define (textsample line in-text out-text more) (define-values (box1 box2) (textsample-verbatim-boxes line in-text out-text more)) - (make-table '([alignment left left left] [valignment center center center]) - (list (map as-flow (list box1 (make-paragraph '(nbsp rarr nbsp)) box2))))) + (make-table + (make-style #f (list (make-table-columns (list (make-style #f '(left vcenter)) + (make-style "Short" '(left vcenter)) + (make-style #f '(left vcenter)))))) + (list (map as-flow (list box1 (make-paragraph plain '(nbsp rarr nbsp)) box2))))) (define-for-syntax tests-ids #f) diff --git a/collects/scriblib/autobib.css b/collects/scriblib/autobib.css index 4bee199bf0..55823bfe60 100644 --- a/collects/scriblib/autobib.css +++ b/collects/scriblib/autobib.css @@ -1,5 +1,9 @@ -.SBibliography p { +.AutoBibliography p { padding-left: 1em; text-indent: -1em; } + +.AutoBibliography td { + vertical-align: text-top; +} diff --git a/collects/scriblib/autobib.ss b/collects/scriblib/autobib.ss index e2faeb514a..f4e201959e 100644 --- a/collects/scriblib/autobib.ss +++ b/collects/scriblib/autobib.ss @@ -1,21 +1,29 @@ #lang at-exp scheme/base (require scribble/manual - scribble/struct + scribble/core scribble/decode - scheme/string) + scribble/html-variants + scribble/latex-variants + scheme/string + setup/main-collects) -(provide autobib-style-extras - define-cite +(provide define-cite make-bib in-bib (rename-out [auto-bib? bib?]) proceedings-location journal-location book-location techrpt-location dissertation-location author-name org-author-name authors other-authors editor) -(define (autobib-style-extras) +(define autobib-style-extras (let ([abs (lambda (s) - (build-path (collection-path "scriblib") s))]) - `((css ,(abs "autobib.css")) (tex ,(abs "autobib.tex"))))) + (path->main-collects-relative + (build-path (collection-path "scriblib") s)))]) + (list + (make-css-addition (abs "autobib.css")) + (make-tex-addition (abs "autobib.tex"))))) +(define bib-table-style (make-style "AutoBibliography" autobib-style-extras)) +(define bibentry-style (make-style "Autobibentry" autobib-style-extras)) + (define-struct auto-bib (author date entry-element key specific)) (define-struct bib-group (ht)) @@ -57,48 +65,46 @@ [bibs (sort (hash-map (bib-group-ht group) (lambda (k v) k)) authorstring e))) + (regexp-match? #rx"[.!?,]$" (content->string e))) (define (make-bib #:title title #:author [author #f] @@ -125,7 +131,7 @@ [(author-element? author) author] [else (parse-author author)])] [elem (make-element - "bibentry" + bibentry-style (append (if author `(,author @@ -144,13 +150,13 @@ (if location `(" " ,@(decode-content (list location)) ,(if date "," ".")) null) - (if date `(" " ,@(decode-content (list date)) ".") null) + (if date `(" " ,@(decode-content (list (to-string date))) ".") null) (if url `(" " ,(link url (make-element 'url (list url)))) null)))]) (make-auto-bib (or author (org-author-name title)) - date + (to-string date) elem - (element->string elem) + (content->string elem) ""))) (define (in-bib bib where) @@ -164,7 +170,7 @@ (define (parse-author a) (if (author-element? a) a - (let* ([s (element->string a)] + (let* ([s (content->string a)] [m (regexp-match #rx"^(.*) ([A-Za-z]+)$" s)]) (make-author-element #f @@ -183,13 +189,13 @@ #:volume [volume #f]) (let* ([s @elem{In @italic{@elem{Proc. @|location|}}}] [s (if series - @elem{@|s|, @|series|} + @elem{@|s|, @(format "~a" series)} s)] [s (if volume - @elem{@|s| volume @|volume|} + @elem{@|s| volume @(format "~a" volume)} s)] [s (if pages - @elem{@|s|, pp. @(car pages)--@(cadr pages)} + @elem{@|s|, pp. @(to-string (car pages))--@(to-string (cadr pages))} s)]) s)) @@ -200,13 +206,13 @@ #:volume [volume #f]) (let* ([s @italic{@|location|}] [s (if volume - @elem{@|s| @|volume|} + @elem{@|s| @(to-string volume)} s)] [s (if number - @elem{@|s|(@|number|)} + @elem{@|s|(@(to-string number))} s)] [s (if pages - @elem{@|s|, pp. @(car pages)--@(cadr pages)} + @elem{@|s|, pp. @(to-string (car pages))--@(to-string (cadr pages))} s)]) s)) @@ -301,3 +307,5 @@ '(" (Ed.)")) (author-element-names name) (author-element-cite name)))) + +(define (to-string v) (format "~a" v)) diff --git a/collects/scriblib/autobib.tex b/collects/scriblib/autobib.tex index b762d9da08..3d50de7bab 100644 --- a/collects/scriblib/autobib.tex +++ b/collects/scriblib/autobib.tex @@ -1,3 +1,3 @@ -\renewenvironment{SBibliography}{\begin{small}}{\end{small}} -\renewcommand{\bibentry}[1]{\hspace{0.05\linewidth}\parbox[t]{0.95\linewidth}{\parindent=-0.05\linewidth#1\vspace{1.0ex}}} +\newenvironment{AutoBibliography}{\begin{small}}{\end{small}} +\newcommand{\Autobibentry}[1]{\hspace{0.05\linewidth}\parbox[t]{0.95\linewidth}{\parindent=-0.05\linewidth#1\vspace{1.0ex}}} diff --git a/collects/scriblib/figure.ss b/collects/scriblib/figure.ss index 5db55c6aa4..8cbdb74ae0 100644 --- a/collects/scriblib/figure.ss +++ b/collects/scriblib/figure.ss @@ -1,58 +1,67 @@ #lang scheme/base (require scribble/manual - scribble/struct + scribble/core scribble/decode + scribble/html-variants + scribble/latex-variants + setup/main-collects "private/counter.ss") (provide figure figure* figure** Figure-target - Figure-ref - figure-style-extras) + Figure-ref) -(define (figure-style-extras) +(define figure-style-extras (let ([abs (lambda (s) (build-path (collection-path "scriblib") s))]) - `((css ,(abs "figure.css")) (tex ,(abs "figure.tex"))))) + (list (make-css-addition (abs "figure.css")) + (make-tex-addition (abs "figure.tex"))))) + +(define centerfigure-style (make-style "Centerfigure" figure-style-extras)) +(define figureinside-style (make-style "FigureInside" figure-style-extras)) +(define legend-style (make-style "Legend" figure-style-extras)) +(define centerfiguremulti-style (make-style "CenterfigureMulti" figure-style-extras)) +(define centerfiguremultiwide-style (make-style "CenterfigureMultiWide" figure-style-extras)) (define (figure tag caption . content) - (make-blockquote - "Centerfigure" + (make-nested-flow + centerfigure-style (list - (make-blockquote - "FigureInside" + (make-nested-flow + figureinside-style (append - (flow-paragraphs - (decode-flow content)) + (decode-flow content) (list (make-paragraph + plain (list - (make-element "Legend" + (make-element legend-style (list* (Figure-target tag) ": " (decode-content (list caption)))))))))))) (define (*figure style tag caption content) - (make-blockquote + (make-nested-flow style (list - (make-blockquote - "FigureInside" + (make-nested-flow + figureinside-style (append - (flow-paragraphs - (decode-flow content)) + (decode-flow content) (list (make-paragraph + plain (list - (make-element "Legend" + (make-element legend-style (list* (Figure-target tag) ": " (decode-content (list caption)))))))))))) (define (figure* tag caption . content) - (*figure "CenterfigureMulti" tag caption content)) + (*figure centerfiguremulti-style tag caption content)) (define (figure** tag caption . content) - (*figure "CenterfigureMultiWide" tag caption content)) + (*figure centerfiguremultiwide-style tag caption content)) (define figures (new-counter "figure")) (define (Figure-target tag) diff --git a/collects/scriblib/figure.tex b/collects/scriblib/figure.tex index 164518fd62..429e996d3d 100644 --- a/collects/scriblib/figure.tex +++ b/collects/scriblib/figure.tex @@ -12,4 +12,4 @@ \newenvironment{CenterfigureMulti}{\begin{figure*}\centering}{\end{figure*}} \newenvironment{CenterfigureMultiWide}{\begin{CenterfigureMulti}}{\end{CenterfigureMulti}} \newenvironment{Centerfigure}{\begin{figure}\centering}{\end{figure}} -\newenvironment{FigureInside}{\begin{list}{}{\leftmargin=0pt\parsep=\FigOrigskip}\item}{\end{list}} +\newenvironment{FigureInside}{\begin{list}{}{\leftmargin=0pt\topsep=0pt\parsep=\FigOrigskip\partopsep=0pt}\item}{\end{list}} diff --git a/collects/scriblib/gui-eval.ss b/collects/scriblib/gui-eval.ss index af33dd3069..a18629f73e 100644 --- a/collects/scriblib/gui-eval.ss +++ b/collects/scriblib/gui-eval.ss @@ -1,7 +1,7 @@ #lang scheme/base (require scribble/eval - scribble/struct + scribble/core scribble/scheme scheme/class scheme/file @@ -127,13 +127,14 @@ (send dc clear) (((gui-eval 'make-pict-drawer) v) dc 0 0) (send bm save-file fn 'png) - (make-element #f (list (make-element (make-image-file - ;; For HTML output, .pdf is automatically changed to .png. - ;; Be sure to use a string rather than a path, because - ;; it gets recorded in "exprs.dat". - (path->string (path-replace-suffix fn #".pdf")) - 1.0) - (list "[image]"))))))] + (make-image-element + #f + (list "[image]") + ;; Be sure to use a string rather than a path, because + ;; it gets recorded in "exprs.dat". + (path->string (path-replace-suffix fn #"")) + '(".pdf" ".png") + 1.0)))] [(pair? v) (cons (fixup-picts (car v)) (fixup-picts (cdr v)))] [(serializable? v) v] diff --git a/collects/setup/scribble.ss b/collects/setup/scribble.ss index 5be34e7324..2d0a1a8cae 100644 --- a/collects/setup/scribble.ss +++ b/collects/setup/scribble.ss @@ -12,8 +12,8 @@ scheme/serialize syntax/modread scribble/base-render - scribble/struct - scribble/basic + scribble/core + scribble/html-variants scribble/manual ; really shouldn't be here... see dynamic-require-doc scribble/private/run-pdflatex (prefix-in html: scribble/html-render) @@ -265,7 +265,10 @@ (define (make-renderer latex-dest doc) (if latex-dest (new (latex:render-mixin render%) - [dest-dir latex-dest]) + [dest-dir latex-dest] + ;; Use PLT manual style: + [prefix-file (build-path (collection-path "scribble") "manual-prefix.tex")] + [style-file (build-path (collection-path "scribble") "manual-style.tex")]) (let* ([flags (doc-flags doc)] [multi? (memq 'multi-page flags)] [main? (doc-under-main? doc)] @@ -277,8 +280,15 @@ [dest-dir (if multi? (let-values ([(base name dir?) (split-path ddir)]) base) ddir)] - [css-path (and main? "../scribble.css")] - [script-path (and main? "../scribble-common.js")] + [alt-paths (if main? + (let ([std-path (lambda (s) + (cons (build-path (collection-path "scribble") s) + (format "../~a" s)))]) + (list (std-path "scribble.css") + (std-path "scribble-style.css") + (std-path "scheme.css") + (std-path "scribble-common.js"))) + null)] ;; up-path is #t, which makes it go to the (user's) start page ;; (using cookies) -- except when it is the start page itself ;; (one of the two) @@ -315,22 +325,24 @@ [tags (if (member '(part "top") (part-tags v)) (part-tags v) (cons '(part "top") (part-tags v)))] - [style (if (list? (part-style v)) - (part-style v) - (list (part-style v)))]) - (make-versioned-part + [style (part-style v)]) + (make-part tag-prefix tags (part-title-content v) - (if (ormap (lambda (s) - (and (pair? s) (eq? (car s) 'body-id))) - style) - style - (cons '(body-id "doc-plt-scheme-org") style)) + (let* ([v (style-variants style)] + [v (if (ormap body-id? v) + v + (cons (make-body-id "doc-plt-scheme-org") + v))] + [v (if (ormap document-version? v) + v + (cons (make-document-version (version)) + v))]) + (make-style (style-name style) v)) (part-to-collect v) - (part-flow v) - (part-parts v) - (and (versioned-part? v) (versioned-part-version v)))))) + (part-blocks v) + (part-parts v))))) (define (omit? cat) (or (eq? cat 'omit) diff --git a/collects/sgl/scribblings/gl.scrbl b/collects/sgl/scribblings/gl.scrbl index 272eedb08e..24cbefad8e 100644 --- a/collects/sgl/scribblings/gl.scrbl +++ b/collects/sgl/scribblings/gl.scrbl @@ -14,7 +14,7 @@ C-language OpenGL API. It provides a binding for each @tt{#defined} constant (these start with @schemeidfont{GL_}) and for the functions in the GL 1.5 and GLU 1.3 specifications, except for the following: -@itemize[#:style "compact" +@itemize[#:style 'compact @item{Vertex arrays (GL 1.5, Section 2.8)} @item{Buffer objects (GL 1.5, Section 2.9)} @item{@tt{glGetPointerv} (GL 1.5, Section 6.1.11)} diff --git a/collects/teachpack/2htdp/scribblings/universe.scrbl b/collects/teachpack/2htdp/scribblings/universe.scrbl index f477637733..22aaa12c4d 100644 --- a/collects/teachpack/2htdp/scribblings/universe.scrbl +++ b/collects/teachpack/2htdp/scribblings/universe.scrbl @@ -1057,7 +1057,7 @@ Say we want to represent a universe that consists of a number of worlds and Here is an image that illustrates how this universe would work if two worlds participated: -@image["balls.gif"] +@image["balls" #:suffixes '(".gif" ".png")] The two @tech{world} programs could be located on two distinct computers or on just one. A @tech{server} mediates between the two worlds, including diff --git a/src/mzscheme/src/schvers.h b/src/mzscheme/src/schvers.h index 373b0c1277..2efdbbc561 100644 --- a/src/mzscheme/src/schvers.h +++ b/src/mzscheme/src/schvers.h @@ -13,12 +13,12 @@ consistently.) */ -#define MZSCHEME_VERSION "4.2.1.1" +#define MZSCHEME_VERSION "4.2.1.2" #define MZSCHEME_VERSION_X 4 #define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Z 1 -#define MZSCHEME_VERSION_W 1 +#define MZSCHEME_VERSION_W 2 #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)