, except for a trailing table + ;; when `special-last?' is #t + (let loop ([f (flow-paragraphs p)][inline? start-inline?]) + (cond + [(null? f) null] + [(and (table? (car f)) + (or (not special-last?) (not (null? (cdr f))))) + (cons `(p ,@(render-block (car f) part ri inline?)) + (loop (cdr f) #f))] + [else (append (render-block (car f) part ri inline?) + (loop (cdr f) #f))]))) + + (define/override (render-flow p part ri start-inline?) + (render-flow* p part ri start-inline? #t)) + + (define/override (render-paragraph p part ri) + `((p ,(if (styled-paragraph? p) + `([class ,(styled-paragraph-style p)]) + `()) + ,@(super render-paragraph p part ri)))) + + (define/override (render-element e part ri) + (cond + [(hover-element? e) + `((span ((title ,(hover-element-text e))) ,@(render-plain-element e part ri)))] + [(target-element? e) + `((a ((name ,(format "~a" (anchor-name (tag-key (target-element-tag e) ri)))))) + ,@(render-plain-element e part ri))] + [(and (link-element? e) (not (current-no-links))) + (parameterize ([current-no-links #t]) + (let-values ([(dest ext?) (resolve-get/ext? part ri (link-element-tag e))]) + (if dest + `((a [(href ,(if (and ext? external-tag-path) + ;; Redirected to search: + (format "~a;tag=~a" + external-tag-path + (base64-encode + (string->bytes/utf-8 + (format "~a" (serialize (link-element-tag e)))))) + ;; Normal link: + (format "~a~a~a" + (from-root (relative->path (dest-path dest)) + (get-dest-directory)) + (if (dest-page? dest) "" "#") + (if (dest-page? dest) + "" + (anchor-name (dest-anchor 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)))) + (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)) + `(,(format "~s" (tag-key (link-element-tag e) ri))) + (render-plain-element e part ri))))))))] + [else (render-plain-element e part ri)])) + + (define/private (render-plain-element e part ri) + (let ([style (and (element? e) (element-style e))]) + (cond + [(symbol? style) + (case style + [(italic) `((i ,@(super render-element e part ri)))] + [(bold) `((b ,@(super render-element e part ri)))] + [(tt) `((span ([class "stt"]) ,@(super render-element e part ri)))] + [(no-break) `((span ([class "nobreak"]) ,@(super render-element e part ri)))] + [(sf) `((b (font ([size "-1"][face "Helvetica"]) ,@(super render-element e part ri))))] + [(subscript) `((sub ,@(super render-element e part ri)))] + [(superscript) `((sup ,@(super render-element e part ri)))] + [(hspace) `((span ([class "hspace"]) + ,@(let ([str (content->string (element-content e))]) + (map (lambda (c) 'nbsp) (string->list str)))))] + [(newline) `((br))] + [else (error 'html-render "unrecognized style symbol: ~e" style)])] + [(string? style) + `((span ([class ,style]) ,@(super render-element e part ri)))] + [(and (pair? style) + (or (eq? (car style) 'bg-color) + (eq? (car style) 'color))) + (unless (and (list? style) + (or (and (= 4 (length style)) + (andmap byte? (cdr style))) + (and (= 2 (length style)) + (member (cadr style) + '("white" "black" "red" "green" "blue" + "cyan" "magenta" "yellow"))))) + (error 'render-font "bad color style: ~e" style)) + `((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 (format "0~x" v)]) + (substring s (- (string-length s) 2)))) + (cdr style)))))]) + ,@(super render-element e part ri)))] + [(target-url? style) + (if (current-no-links) + (super render-element e part ri) + (parameterize ([current-no-links #t]) + `((a ([href ,(let ([addr (target-url-addr style)]) + (if (path? addr) + (from-root addr (get-dest-directory)) + addr))] + ,@(if (string? (target-url-style style)) + `([class ,(target-url-style style)]) + null)) + ,@(super render-element e part ri)))))] + [(url-anchor? style) + `((a ([name ,(url-anchor-name style)]) + ,@(super render-element e part ri)))] + [(image-file? style) + (let* ([src (main-collects-relative->path (image-file-path style))] + [scale (image-file-scale style)] + [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) + (let ([w (read-bytes 4 in)] + [h (read-bytes 4 in)] + [to-num (lambda (s) + (number->string + (inexact->exact + (floor (* scale (integer-bytes->integer s #f #t))))))]) + `([width ,(to-num w)] + [height ,(to-num h)])) + null))))]) + `((img ([src ,(let ([p (install-file src)]) + (if (path? p) + (url->string (path->url (path->complete-path p))) + p))]) + ,@sz)))] + [else (super render-element e part ri)]))) + + (define/override (render-table t part ri need-inline?) + (define index? (eq? 'index (table-style t))) + `(,@(if index? `(,search-script ,search-field) '()) + (table ([cellspacing "0"] + ,@(if need-inline? + '([style "display: inline; vertical-align: top;"]) + null) + ,@(case (table-style t) + [(boxed) '([class "boxed"])] + [(centered) '([align "center"])] + [(at-right) '([align "right"])] + [(at-left) '([align "left"])] + [else null]) + ,@(let ([a (and (list? (table-style t)) + (assoc 'style (table-style t)))]) + (if (and a (string? (cadr a))) + `([class ,(cadr a)]) + null)) + ,@(if (string? (table-style t)) + `([class ,(table-style t)]) null)) - (div ([class "navright"]) - ,@(render - (make-element - (if parent - (make-target-url - (if prev (derive-filename prev) "index.html") - #f) - "nonavigation") - prev-content) - sep-element - (make-element - (if (or parent up-path) - (make-target-url - (if parent - (if (and (toc-part? parent) - (part-parent parent ri)) - (derive-filename parent) - "index.html") - up-path) - #f) - "nonavigation") - up-content) - sep-element - (make-element - (if next - (make-target-url (derive-filename next) #f) - "nonavigation") - next-content))) - (p nbsp))))) + ,@(map (lambda (flows style) + `(tr (,@(if style `([class ,style]) null)) + ,@(let loop ([ds flows] + [as (cdr (or (and (list? (table-style t)) + (assoc 'alignment (or (table-style t) null))) + (cons #f (map (lambda (x) #f) flows))))] + [vas + (cdr (or (and (list? (table-style t)) + (assoc 'valignment (or (table-style t) null))) + (cons #f (map (lambda (x) #f) flows))))]) + (cond + [(null? ds) null] + [(eq? (car ds) 'cont) + (loop (cdr ds) (cdr as) (cdr vas))] + [else + (let ([d (car ds)] + [a (car as)] + [va (car vas)]) + (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"))] + [(bottom) '((valign "bottom"))]) + ,@(if (and (pair? (cdr ds)) + (eq? 'cont (cadr ds))) + `([colspan + ,(number->string + (let loop ([n 2] + [ds (cddr ds)]) + (cond + [(null? ds) n] + [(eq? 'cont (car ds)) (loop (+ n 1) (cdr ds))] + [else n])))]) + null)) + ,@(render-flow d part ri #f)) + (loop (cdr ds) (cdr as) (cdr vas))))])))) + (table-flowss t) + (cdr (or (and (list? (table-style t)) + (assoc 'row-styles (or (table-style t) null))) + (cons #f (map (lambda (x) #f) (table-flowss t))))))))) - (define/override (render-one d ri fn) - (render-one-part d ri fn null)) + (define/override (render-blockquote t part ri) + `((blockquote ,(if (string? (blockquote-style t)) + `([class ,(blockquote-style t)]) + `()) + ,@(append-map (lambda (i) (render-block i part ri #f)) + (blockquote-paragraphs t))))) - (define/public (render-version d ri) - `((div ([class "versionbox"]) - ,@(render-content - (list - (make-element "version" - (list "Version: " - (current-version)))) - d - ri)))) - - (define/override (render-part d ri) - (let ([number (collected-info-number (part-collected-info d ri))]) - `(,@(if (and (not (part-title-content d)) - (null? number)) - null - (if (part-style? d 'hidden) - (map (lambda (t) - `(a ((name ,(format "~a" (anchor-name (tag-key t ri))))))) - (part-tags d)) - `((,(case (length number) - [(0) 'h2] - [(1) 'h3] - [(2) 'h4] - [else 'h5]) - ,@(format-number number '((tt nbsp))) - ,@(map (lambda (t) - `(a ((name ,(format "~a" (anchor-name (tag-key t ri))))))) - (part-tags d)) - ,@(if (part-title-content d) - (render-content (part-title-content d) d ri) - null))))) - ,@(render-flow* (part-flow d) d ri #f #f) - ,@(let loop ([pos 1] - [secs (part-parts d)]) - (if (null? secs) - null - (append - (render-part (car secs) ri) - (loop (add1 pos) (cdr secs)))))))) - - (define/private (render-flow* p part ri start-inline? special-last?) - ;; Wrap each table with
, except for a trailing table - ;; when `special-last?' is #t - (let loop ([f (flow-paragraphs p)][inline? start-inline?]) - (cond - [(null? f) null] - [(and (table? (car f)) - (or (not special-last?) - (not (null? (cdr f))))) - (cons `(p ,@(render-block (car f) part ri inline?)) - (loop (cdr f) #f))] - [else - (append (render-block (car f) part ri inline?) - (loop (cdr f) #f))]))) - - (define/override (render-flow p part ri start-inline?) - (render-flow* p part ri start-inline? #t)) - - (define/override (render-paragraph p part ri) - `((p ,@(if (styled-paragraph? p) - `(((class ,(styled-paragraph-style p)))) - null) - ,@(super render-paragraph p part ri)))) - - (define/override (render-element e part ri) - (cond - [(hover-element? e) - `((span ((title ,(hover-element-text e))) ,@(render-plain-element e part ri)))] - [(target-element? e) - `((a ((name ,(format "~a" (anchor-name (tag-key (target-element-tag e) ri)))))) - ,@(render-plain-element e part ri))] - [(and (link-element? e) - (not (current-no-links))) - (parameterize ([current-no-links #t]) - (let-values ([(dest ext?) (resolve-get/ext? part ri (link-element-tag e))]) - (if dest - `((a ((href ,(if (and ext? external-tag-path) - ;; Redirected to search: - (format "~a;tag=~a" - external-tag-path - (base64-encode - (string->bytes/utf-8 - (format "~a" (serialize (link-element-tag e)))))) - ;; Normal link: - (format "~a~a~a" - (from-root (relative->path (dest-path dest)) - (get-dest-directory)) - (if (dest-page? dest) - "" - "#") - (if (dest-page? dest) - "" - (anchor-name (dest-anchor 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)))) - (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)) - `(,(format "~s" (tag-key (link-element-tag e) ri))) - (render-plain-element e part ri))))))))] - [else (render-plain-element e part ri)])) - - (define/private (render-plain-element e part ri) - (let ([style (and (element? e) - (element-style e))]) - (cond - [(symbol? style) - (case style - [(italic) `((i ,@(super render-element e part ri)))] - [(bold) `((b ,@(super render-element e part ri)))] - [(tt) `((span ([class "stt"]) ,@(super render-element e part ri)))] - [(no-break) `((span ([class "nobreak"]) ,@(super render-element e part ri)))] - [(sf) `((b (font ([size "-1"][face "Helvetica"]) ,@(super render-element e part ri))))] - [(subscript) `((sub ,@(super render-element e part ri)))] - [(superscript) `((sup ,@(super render-element e part ri)))] - [(hspace) `((span ([class "hspace"]) - ,@(let ([str (content->string (element-content e))]) - (map (lambda (c) 'nbsp) (string->list str)))))] - [(newline) `((br))] - [else (error 'html-render "unrecognized style symbol: ~e" style)])] - [(string? style) - `((span ([class ,style]) ,@(super render-element e part ri)))] - [(and (pair? style) - (or (eq? (car style) 'bg-color) - (eq? (car style) 'color))) - (unless (and (list? style) - (or (and (= 4 (length style)) - (andmap byte? (cdr style))) - (and (= 2 (length style)) - (member (cadr style) - '("white" "black" "red" "green" "blue" "cyan" "magenta" "yellow"))))) - (error 'render-font "bad color style: ~e" style)) - `((font ((style ,(format "~acolor: ~a" - (if (eq? (car style) 'bg-color) - "background-" - "") - (if (= 2 (length style)) - (cadr style) - (apply string-append "#" - (map (lambda (v) (let ([s (format "0~x" v)]) - (substring s (- (string-length s) 2)))) - (cdr style))))))) - ,@(super render-element e part ri)))] - [(target-url? style) - (if (current-no-links) - (super render-element e part ri) - (parameterize ([current-no-links #t]) - `((a ((href ,(let ([addr (target-url-addr style)]) - (if (path? addr) - (from-root addr - (get-dest-directory)) - addr))) - ,@(if (string? (target-url-style style)) - `((class ,(target-url-style style))) - null)) - ,@(super render-element e part ri)))))] - [(url-anchor? style) - `((a ((name ,(url-anchor-name style))) - ,@(super render-element e part ri)))] - [(image-file? style) - (let* ([src (main-collects-relative->path (image-file-path style))] - [scale (image-file-scale style)] - [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) - (let ([w (read-bytes 4 in)] - [h (read-bytes 4 in)] - [to-num (lambda (s) - (number->string - (inexact->exact - (floor (* scale (integer-bytes->integer s #f #t))))))]) - `((width ,(to-num w)) - (height ,(to-num h)))) - null))))]) - `((img ((src ,(let ([p (install-file src)]) - (if (path? p) - (url->string (path->url (path->complete-path p))) - p)))) - ,@sz)))] - [else (super render-element e part ri)]))) - - (define/override (render-table t part ri need-inline?) - (define index? (eq? 'index (table-style t))) - `(,@(if index? `(,search-script ,search-field) '()) - (table ((cellspacing "0") - ,@(if need-inline? - '((style "display: inline; vertical-align: top;")) - null) - ,@(case (table-style t) - [(boxed) '((class "boxed"))] - [(centered) '((align "center"))] - [(at-right) '((align "right"))] - [(at-left) '((align "left"))] - [else null]) - ,@(let ([a (and (list? (table-style t)) - (assoc 'style (table-style t)))]) - (if (and a (string? (cadr a))) - `((class ,(cadr a))) - null)) - ,@(if (string? (table-style t)) - `((class ,(table-style t))) - null)) - ,@(map (lambda (flows style) - `(tr (,@(if style - `((class ,style)) - null)) - ,@(let loop ([ds flows] - [as (cdr (or (and (list? (table-style t)) - (assoc 'alignment (or (table-style t) null))) - (cons #f (map (lambda (x) #f) flows))))] - [vas - (cdr (or (and (list? (table-style t)) - (assoc 'valignment (or (table-style t) null))) - (cons #f (map (lambda (x) #f) flows))))]) - (if (null? ds) - null - (if (eq? (car ds) 'cont) - (loop (cdr ds) (cdr as) (cdr vas)) - (let ([d (car ds)] - [a (car as)] - [va (car vas)]) - (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"))] - [(bottom) '((valign "bottom"))]) - ,@(if (and (pair? (cdr ds)) - (eq? 'cont (cadr ds))) - `((colspan - ,(number->string - (let loop ([n 2] - [ds (cddr ds)]) - (cond - [(null? ds) n] - [(eq? 'cont (car ds)) (loop (+ n 1) (cdr ds))] - [else n]))))) - null)) - ,@(render-flow d part ri #f)) - (loop (cdr ds) (cdr as) (cdr vas))))))))) - (table-flowss t) - (cdr (or (and (list? (table-style t)) - (assoc 'row-styles (or (table-style t) null))) - (cons #f (map (lambda (x) #f) (table-flowss t))))))))) - - (define/override (render-blockquote t part ri) - `((blockquote ,@(if (string? (blockquote-style t)) - `(((class ,(blockquote-style t)))) - null) - ,@(apply append - (map (lambda (i) - (render-block i part ri #f)) - (blockquote-paragraphs t)))))) - - (define/override (render-itemization t part ri) - `((ul - ,@(if (and (styled-itemization? t) + (define/override (render-itemization t part ri) + `((ul ,(if (and (styled-itemization? t) (string? (styled-itemization-style t))) - `(((class ,(styled-itemization-style t)))) - null) - ,@(map (lambda (flow) - `(li ,@(render-flow flow part ri #t))) - (itemization-flows t))))) + `([class ,(styled-itemization-style t)]) + `()) + ,@(map (lambda (flow) `(li ,@(render-flow flow part ri #t))) + (itemization-flows t))))) - (define/override (render-other i part ri) - (cond - [(string? i) - (let ([m (and (extra-breaking?) - (regexp-match-positions #rx"[-:/+_]|[a-z](?=[A-Z])" i))]) - (if m - (list* (substring i 0 (cdar m)) - ;; Most browsers wrap after a hyphen. The - ;; one that doesn't, Firefox, pays attention - ;; to wbr. Some browsers ignore wbr, but - ;; at least they don't do strange things with it. - (if (equal? #\- (string-ref i (caar m))) - '(wbr) - `(span ((class "mywbr")) " ")) - (render-other (substring i (cdar m)) part ri)) - (ascii-ize i)))] - [(eq? i 'mdash) `(" " ndash " ")] - [(symbol? i) (list i)] - [else (list (format "~s" i))])) + (define/override (render-other i part ri) + (cond + [(string? i) + (let ([m (and (extra-breaking?) + (regexp-match-positions #rx"[-:/+_]|[a-z](?=[A-Z])" i))]) + (if m + (list* (substring i 0 (cdar m)) + ;; Most browsers wrap after a hyphen. The one that + ;; doesn't, Firefox, pays attention to wbr. Some + ;; browsers ignore wbr, but at least they don't do + ;; strange things with it. + (if (equal? #\- (string-ref i (caar m))) + '(wbr) + `(span ([class "mywbr"]) " ")) + (render-other (substring i (cdar m)) part ri)) + (ascii-ize i)))] + [(eq? i 'mdash) `(" " ndash " ")] + [(symbol? i) (list i)] + [else (list (format "~s" i))])) - (define/private (ascii-ize s) - (let ([m (regexp-match-positions #rx"[^\u01-\u7E]" s)]) - (if m - (append (ascii-ize (substring s 0 (caar m))) - (list (char->integer (string-ref s (caar m)))) - (ascii-ize (substring s (cdar m)))) - (list s)))) - - ;; ---------------------------------------- + (define/private (ascii-ize s) + (let ([m (regexp-match-positions #rx"[^\u01-\u7E]" s)]) + (if m + (append (ascii-ize (substring s 0 (caar m))) + (list (char->integer (string-ref s (caar m)))) + (ascii-ize (substring s (cdar m)))) + (list s)))) - (super-new))) + ;; ---------------------------------------- - ;; ---------------------------------------- - ;; multi-file output + (super-new))) - (define (render-multi-mixin %) - (class % - (inherit render-one - render-one-part - render-content - part-whole-page? - format-number) +;; ---------------------------------------- +;; multi-file output - (inherit-field report-output?) +(define (render-multi-mixin %) + (class % + (inherit render-one + render-one-part + render-content + part-whole-page? + format-number) - (define/override (get-suffix) #"") + (inherit-field report-output?) - (define/override (get-dest-directory) - (or (and (current-subdirectory) - (build-path (or (super get-dest-directory) (current-directory)) (current-subdirectory))) - (super get-dest-directory))) + (define/override (get-suffix) #"") - (define/override (derive-filename d) - (let ([fn (format "~a.html" (regexp-replace* - "[^-a-zA-Z0-9_=]" - (let ([s (cadr (car (part-tags d)))]) - (if (string? s) - s - (if (part-title-content d) - (content->string (part-title-content d)) - ;; last-ditch effort to make up a unique name: - (format "???~a" (eq-hash-code d))))) - "_"))]) - (when ((string-length fn) . >= . 48) - (error "file name too long (need a tag):" fn)) - fn)) + (define/override (get-dest-directory) + (or (and (current-subdirectory) + (build-path (or (super get-dest-directory) (current-directory)) (current-subdirectory))) + (super get-dest-directory))) - (define/override (collect ds fns) - (super collect ds (map (lambda (fn) - (build-path fn "index.html")) - fns))) + (define/override (derive-filename d) + (let ([fn (format "~a.html" + (regexp-replace* + "[^-a-zA-Z0-9_=]" + (let ([s (cadr (car (part-tags d)))]) + (cond [(string? s) s] + [(part-title-content d) + (content->string (part-title-content d))] + [else + ;; last-ditch effort to make up a unique name: + (format "???~a" (eq-hash-code d))])) + "_"))]) + (when ((string-length fn) . >= . 48) + (error "file name too long (need a tag):" fn)) + fn)) - (define/override (current-part-whole-page? d) - ((collecting-sub) . <= . 2)) + (define/override (collect ds fns) + (super collect ds (map (lambda (fn) (build-path fn "index.html")) fns))) - (define/override (collect-part d parent ci number) - (let ([prev-sub (collecting-sub)]) - (parameterize ([collecting-sub (if (toc-part? d) - 1 - (add1 prev-sub))]) - (if (= 1 prev-sub) - (let ([filename (derive-filename d)]) - (parameterize ([current-output-file (build-path (path-only (current-output-file)) - filename)]) - (super collect-part d parent ci number))) - (super collect-part d parent ci number))))) - - (define/override (render ds fns ri) - (map (lambda (d fn) - (when report-output? - (printf " [Output to ~a/index.html]\n" fn)) - (unless (directory-exists? fn) - (make-directory fn)) - (parameterize ([current-subdirectory (file-name-from-path fn)]) - (let ([fn (build-path fn "index.html")]) - (with-output-to-file fn - #:exists 'truncate/replace - (lambda () - (render-one d ri fn)))))) - ds - fns)) + (define/override (current-part-whole-page? d) + ((collecting-sub) . <= . 2)) - (define/override (nearly-top? d ri top) - (eq? top (collected-info-parent (part-collected-info d ri)))) + (define/override (collect-part d parent ci number) + (let ([prev-sub (collecting-sub)]) + (parameterize ([collecting-sub (if (toc-part? d) 1 (add1 prev-sub))]) + (if (= 1 prev-sub) + (let ([filename (derive-filename d)]) + (parameterize ([current-output-file + (build-path (path-only (current-output-file)) + filename)]) + (super collect-part d parent ci number))) + (super collect-part d parent ci number))))) - (define/override (get-onthispage-label) - `((div ((class "tocsubtitle")) - "On this page:"))) - - (define/override (toc-wrap p) - (list p)) + (define/override (render ds fns ri) + (map (lambda (d fn) + (when report-output? + (printf " [Output to ~a/index.html]\n" fn)) + (unless (directory-exists? fn) + (make-directory fn)) + (parameterize ([current-subdirectory (file-name-from-path fn)]) + (let ([fn (build-path fn "index.html")]) + (with-output-to-file fn #:exists 'truncate/replace + (lambda () (render-one d ri fn)))))) + ds + fns)) - (inherit render-table - render-paragraph) + (define/override (nearly-top? d ri top) + (eq? top (collected-info-parent (part-collected-info d ri)))) - (define/override (render-part d ri) - (parameterize ([current-version - (if (and (versioned-part? d) - (versioned-part-version d)) - (versioned-part-version d) - (current-version))]) - (let ([number (collected-info-number (part-collected-info d ri))]) - (cond - [(and (not (on-separate-page)) + (define/override (get-onthispage-label) + `((div ([class "tocsubtitle"]) "On this page:"))) + + (define/override (toc-wrap p) + (list p)) + + (inherit render-table + render-paragraph) + + (define/override (render-part d ri) + (parameterize ([current-version + (if (and (versioned-part? d) + (versioned-part-version d)) + (versioned-part-version d) + (current-version))]) + (let ([number (collected-info-number (part-collected-info d ri))]) + (if (and (not (on-separate-page)) (or (= 1 (length number)) (next-separate-page))) - ;; Render as just a link, and put the actual - ;; content in a new file: - (let* ([filename (derive-filename d)] - [full-path (build-path (path-only (current-output-file)) - filename)]) - (parameterize ([on-separate-page #t]) - (with-output-to-file full-path - #:exists 'truncate/replace - (lambda () - (render-one-part d ri full-path number))) - null))] - [else - (let ([sep? (on-separate-page)]) - (parameterize ([next-separate-page (toc-part? d)] - [on-separate-page #f]) - ;; Normal section render - (super render-part d ri)))])))) + ;; Render as just a link, and put the actual content in a + ;; new file: + (let* ([filename (derive-filename d)] + [full-path (build-path (path-only (current-output-file)) + filename)]) + (parameterize ([on-separate-page #t]) + (with-output-to-file full-path #:exists 'truncate/replace + (lambda () (render-one-part d ri full-path number))) + null)) + (let ([sep? (on-separate-page)]) + (parameterize ([next-separate-page (toc-part? d)] + [on-separate-page #f]) + ;; Normal section render + (super render-part d ri))))))) - (super-new))) + (super-new))) - ;; ---------------------------------------- - ;; utils +;; ---------------------------------------- +;; utils - (define (from-root p d) - (if (not d) - (url->string (path->url (path->complete-path p))) - (let ([e-d (explode (path->complete-path d (current-directory)))] - [e-p (explode (path->complete-path p (current-directory)))]) - (let loop ([e-d e-d] - [e-p e-p]) - (cond - [(null? e-d) - (let loop ([e-p e-p]) - (cond - [(null? e-p) "/"] - [(null? (cdr e-p)) (car e-p)] - [(eq? 'same (car e-p)) (loop (cdr e-p))] - [(eq? 'up (car e-p)) (string-append "../" (loop (cdr e-p)))] - [else (string-append (car e-p) "/" (loop (cdr e-p)))]))] - [(equal? (car e-d) (car e-p)) (loop (cdr e-d) (cdr e-p))] - [(eq? 'same (car e-d)) (loop (cdr e-d) e-p)] - [(eq? 'same (car e-p)) (loop e-d (cdr e-p))] - [else (string-append - (apply string-append (map (lambda (x) "../") e-d)) - (loop null e-p))]))))) +(define (from-root p d) + (if (not d) + (url->string (path->url (path->complete-path p))) + (let ([e-d (explode (path->complete-path d (current-directory)))] + [e-p (explode (path->complete-path p (current-directory)))]) + (let loop ([e-d e-d] [e-p e-p]) + (cond + [(null? e-d) + (let loop ([e-p e-p]) + (cond [(null? e-p) "/"] + [(null? (cdr e-p)) (car e-p)] + [(eq? 'same (car e-p)) (loop (cdr e-p))] + [(eq? 'up (car e-p)) (string-append "../" (loop (cdr e-p)))] + [else (string-append (car e-p) "/" (loop (cdr e-p)))]))] + [(equal? (car e-d) (car e-p)) (loop (cdr e-d) (cdr e-p))] + [(eq? 'same (car e-d)) (loop (cdr e-d) e-p)] + [(eq? 'same (car e-p)) (loop e-d (cdr e-p))] + [else (string-append (string-append* (map (lambda (x) "../") e-d)) + (loop null e-p))]))))) - (define (explode p) - (reverse (let loop ([p p]) - (let-values ([(base name dir?) (split-path p)]) - (let ([name (if base - (if (path? name) - (path-element->string name) - name) - name)]) - (if (path? base) - (cons name (loop base)) - (list name)))))))) +(define (explode p) + (reverse (let loop ([p p]) + (let-values ([(base name dir?) (split-path p)]) + (let ([name (if base + (if (path? name) + (path-element->string name) + name) + name)]) + (if (path? base) + (cons name (loop base)) + (list name)))))))