improve markdown renderer, including support for section links
This commit is contained in:
parent
e44a5bb9f1
commit
431bb95c7b
|
@ -2201,7 +2201,7 @@ For HTML rendering:
|
||||||
@filepath{manual-style.css} from the @filepath{scribble}
|
@filepath{manual-style.css} from the @filepath{scribble}
|
||||||
collection in @racket[html-defaults].}
|
collection in @racket[html-defaults].}
|
||||||
|
|
||||||
@item{The file @filepath{manual-files.css} from the
|
@item{The file @filepath{manual-fonts.css} from the
|
||||||
@filepath{scribble} collection is designated as an additional
|
@filepath{scribble} collection is designated as an additional
|
||||||
accompanying file in @racket[html-defaults].}
|
accompanying file in @racket[html-defaults].}
|
||||||
|
|
||||||
|
|
|
@ -607,6 +607,13 @@ Code blocks are marked using the
|
||||||
"Github convention"] @verbatim{```racket} so that they are lexed and
|
"Github convention"] @verbatim{```racket} so that they are lexed and
|
||||||
formatted as Racket code.}}
|
formatted as Racket code.}}
|
||||||
|
|
||||||
|
@defboolparam[current-markdown-link-sections enabled?]{
|
||||||
|
|
||||||
|
Determines whether section links within an output document are
|
||||||
|
rendered as a section link. The default is @racket[#f].
|
||||||
|
|
||||||
|
@history[#:added "1.31"]}
|
||||||
|
|
||||||
@; ----------------------------------------
|
@; ----------------------------------------
|
||||||
|
|
||||||
@section{HTML Renderer}
|
@section{HTML Renderer}
|
||||||
|
|
|
@ -23,4 +23,4 @@
|
||||||
|
|
||||||
(define pkg-authors '(mflatt eli))
|
(define pkg-authors '(mflatt eli))
|
||||||
|
|
||||||
(define version "1.30")
|
(define version "1.31")
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
"private/render-utils.rkt"
|
"private/render-utils.rkt"
|
||||||
racket/class racket/port racket/list racket/string racket/match
|
racket/class racket/port racket/list racket/string racket/match
|
||||||
scribble/text/wrap)
|
scribble/text/wrap)
|
||||||
(provide render-mixin)
|
(provide render-mixin
|
||||||
|
current-markdown-link-sections)
|
||||||
|
|
||||||
|
(define current-markdown-link-sections (make-parameter #f))
|
||||||
|
|
||||||
(define current-indent (make-parameter 0))
|
(define current-indent (make-parameter 0))
|
||||||
(define (make-indent amt)
|
(define (make-indent amt)
|
||||||
|
@ -17,6 +20,9 @@
|
||||||
(indent))
|
(indent))
|
||||||
|
|
||||||
(define note-depth (make-parameter 0))
|
(define note-depth (make-parameter 0))
|
||||||
|
(define in-toc (make-parameter #f))
|
||||||
|
|
||||||
|
(define markdown-part-tag 'markdown-section)
|
||||||
|
|
||||||
(define (render-mixin %)
|
(define (render-mixin %)
|
||||||
(class %
|
(class %
|
||||||
|
@ -37,6 +43,16 @@
|
||||||
format-number
|
format-number
|
||||||
number-depth)
|
number-depth)
|
||||||
|
|
||||||
|
(define/override (collect-part-tags d ci number)
|
||||||
|
(for ([t (part-tags d)])
|
||||||
|
(let ([t (generate-tag t ci)])
|
||||||
|
(collect-put! ci
|
||||||
|
t
|
||||||
|
(vector (or (part-title-content d) '("???"))
|
||||||
|
(add-current-tag-prefix t)
|
||||||
|
number
|
||||||
|
markdown-part-tag)))))
|
||||||
|
|
||||||
(define/override (render-part d ht)
|
(define/override (render-part d ht)
|
||||||
(let ([number (collected-info-number (part-collected-info d ht))])
|
(let ([number (collected-info-number (part-collected-info d ht))])
|
||||||
(unless (part-style? d 'hidden)
|
(unless (part-style? d 'hidden)
|
||||||
|
@ -153,6 +169,13 @@
|
||||||
(write-string (make-string (note-depth) #\>))
|
(write-string (make-string (note-depth) #\>))
|
||||||
(unless (zero? (note-depth))
|
(unless (zero? (note-depth))
|
||||||
(write-string " ")))
|
(write-string " ")))
|
||||||
|
(cond
|
||||||
|
[(in-toc)
|
||||||
|
(write-note)
|
||||||
|
(super render-paragraph p part ri)
|
||||||
|
;; two spaces at a line end creates a line break:
|
||||||
|
(write-string " ")]
|
||||||
|
[else
|
||||||
(define o (open-output-string))
|
(define o (open-output-string))
|
||||||
(parameterize ([current-output-port o])
|
(parameterize ([current-output-port o])
|
||||||
(super render-paragraph p part ri))
|
(super render-paragraph p part ri))
|
||||||
|
@ -171,7 +194,7 @@
|
||||||
(write-note)
|
(write-note)
|
||||||
(write-string (car lines))
|
(write-string (car lines))
|
||||||
(for ([line (in-list (cdr lines))])
|
(for ([line (in-list (cdr lines))])
|
||||||
(newline) (indent) (write-note) (write-string line))
|
(newline) (indent) (write-note) (write-string line))])
|
||||||
(newline)
|
(newline)
|
||||||
null)
|
null)
|
||||||
|
|
||||||
|
@ -230,10 +253,10 @@
|
||||||
[(and (code? i) (not (in-code?)))
|
[(and (code? i) (not (in-code?)))
|
||||||
(recurse-wrapped "`" in-code?)]
|
(recurse-wrapped "`" in-code?)]
|
||||||
|
|
||||||
[(and (bold? i) (not (in-bold?)))
|
[(and (bold? i) (not (in-bold?)) (not (in-code?)))
|
||||||
(recurse-wrapped "**" in-bold?)]
|
(recurse-wrapped "**" in-bold?)]
|
||||||
|
|
||||||
[(and (italic? i) (not (in-italic?)))
|
[(and (italic? i) (not (in-italic?)) (not (in-code?)))
|
||||||
(recurse-wrapped "_" in-italic?)]
|
(recurse-wrapped "_" in-italic?)]
|
||||||
|
|
||||||
[(and (preserve-spaces? i) (not (preserving-spaces?)))
|
[(and (preserve-spaces? i) (not (preserving-spaces?)))
|
||||||
|
@ -248,15 +271,45 @@
|
||||||
(render-content i part ri))
|
(render-content i part ri))
|
||||||
(printf "](~a)" (sanitize-parens link))))]
|
(printf "](~a)" (sanitize-parens link))))]
|
||||||
|
|
||||||
|
[(and (link-element? i)
|
||||||
|
(current-markdown-link-sections)
|
||||||
|
(not (in-link?))
|
||||||
|
;; Link to a part within this document?
|
||||||
|
(let ([vec (resolve-get part ri (link-element-tag i))])
|
||||||
|
(and (vector? vec)
|
||||||
|
(= 4 (vector-length vec))
|
||||||
|
(eq? markdown-part-tag (vector-ref vec 3))
|
||||||
|
vec)))
|
||||||
|
=> (lambda (vec)
|
||||||
|
(define s (string-append
|
||||||
|
(let ([s (if (vector-ref vec 2)
|
||||||
|
(format-number (vector-ref vec 2) '() #t)
|
||||||
|
'())])
|
||||||
|
(if (null? s)
|
||||||
|
""
|
||||||
|
(string-append (car s) " ")))
|
||||||
|
(content->string (vector-ref vec 0))))
|
||||||
|
(display "[")
|
||||||
|
(begin0
|
||||||
|
(parameterize ([in-link? #t])
|
||||||
|
(super render-content i part ri))
|
||||||
|
(display "](#")
|
||||||
|
(display (regexp-replace* #" "
|
||||||
|
(regexp-replace* #rx"[^a-zA-Z0-9_ -]" (string-downcase s) "")
|
||||||
|
#"-"))
|
||||||
|
(display ")")))]
|
||||||
|
|
||||||
[else (super render-content i part ri)]))
|
[else (super render-content i part ri)]))
|
||||||
|
|
||||||
(define/override (render-nested-flow i part ri starting-item?)
|
(define/override (render-nested-flow i part ri starting-item?)
|
||||||
(define s (nested-flow-style i))
|
(define s (nested-flow-style i))
|
||||||
(unless (memq 'decorative (style-properties s))
|
(unless (memq 'decorative (style-properties s))
|
||||||
(define note? (equal? (style-name s) "refcontent"))
|
(define note? (equal? (style-name s) "refcontent"))
|
||||||
|
(define toc? (equal? (style-name s) 'table-of-contents))
|
||||||
(when note?
|
(when note?
|
||||||
(note-depth (add1 (note-depth))))
|
(note-depth (add1 (note-depth))))
|
||||||
(begin0 (super render-nested-flow i part ri starting-item?)
|
(begin0 (parameterize ([in-toc (or toc? (in-toc))])
|
||||||
|
(super render-nested-flow i part ri starting-item?))
|
||||||
(when note?
|
(when note?
|
||||||
(note-depth (sub1 (note-depth)))))))
|
(note-depth (sub1 (note-depth)))))))
|
||||||
|
|
||||||
|
@ -270,8 +323,8 @@
|
||||||
[(rdquo) "\U201D"]
|
[(rdquo) "\U201D"]
|
||||||
[(lsquo) "\U2018"]
|
[(lsquo) "\U2018"]
|
||||||
[(rsquo) "\U2019"]
|
[(rsquo) "\U2019"]
|
||||||
[(lang) ">"]
|
[(lang) "<"]
|
||||||
[(rang) "<"]
|
[(rang) ">"]
|
||||||
[(rarr) "->"]
|
[(rarr) "->"]
|
||||||
[(nbsp) "\uA0"]
|
[(nbsp) "\uA0"]
|
||||||
[(prime) "'"]
|
[(prime) "'"]
|
||||||
|
@ -280,10 +333,17 @@
|
||||||
[else (error 'markdown-render "unknown element symbol: ~e"
|
[else (error 'markdown-render "unknown element symbol: ~e"
|
||||||
i)]))]
|
i)]))]
|
||||||
[(string? i)
|
[(string? i)
|
||||||
(let* ([i (if (in-code?)
|
(let* ([i (cond
|
||||||
|
[(in-code?)
|
||||||
(regexp-replace** i '([#rx"``" . "\U201C"]
|
(regexp-replace** i '([#rx"``" . "\U201C"]
|
||||||
[#rx"''" . "\U201D"]))
|
[#rx"''" . "\U201D"]))]
|
||||||
(regexp-replace* #px"([#_*`\\[\\(\\]\\)]{1})" i "\\\\\\1"))]
|
[(or (in-link?)
|
||||||
|
(regexp-match? #rx"^[(]" i)
|
||||||
|
(regexp-match? #rx"[]][(]" i))
|
||||||
|
(regexp-replace* #px"([#_*`\\[\\(\\]\\)]{1})" i "\\\\\\1")]
|
||||||
|
[else
|
||||||
|
;; Avoid escaping parentheses
|
||||||
|
(regexp-replace* #px"([#_*`\\[\\]]{1})" i "\\\\\\1")])]
|
||||||
[i (if (preserving-spaces?)
|
[i (if (preserving-spaces?)
|
||||||
(regexp-replace* #rx" " i "\uA0")
|
(regexp-replace* #rx" " i "\uA0")
|
||||||
i)])
|
i)])
|
||||||
|
@ -291,6 +351,26 @@
|
||||||
[else (write i)])
|
[else (write i)])
|
||||||
null)
|
null)
|
||||||
|
|
||||||
|
(define/override (table-of-contents part ri)
|
||||||
|
(define t (super table-of-contents part ri))
|
||||||
|
(cond
|
||||||
|
[(current-markdown-link-sections)
|
||||||
|
;; Table generated by `table-of-contents` always has one
|
||||||
|
;; column, and each row has one paragraph that starts
|
||||||
|
;; with a 'hspace element to indent
|
||||||
|
(nested-flow
|
||||||
|
(style 'table-of-contents null)
|
||||||
|
(for/list ([p (map car (table-blockss t))])
|
||||||
|
(define c (paragraph-content p))
|
||||||
|
(define keep-c (cdr c))
|
||||||
|
(define (spaces->depth n)
|
||||||
|
(add1 (quotient (- n 4) 2)))
|
||||||
|
(for/fold ([p (paragraph plain keep-c)]) ([s (in-range
|
||||||
|
(spaces->depth
|
||||||
|
(string-length (car (element-content (car c))))))])
|
||||||
|
(nested-flow (style "refcontent" null) (list p)))))]
|
||||||
|
[else t]))
|
||||||
|
|
||||||
(super-new)))
|
(super-new)))
|
||||||
|
|
||||||
(define (regexp-replace** str ptns&reps)
|
(define (regexp-replace** str ptns&reps)
|
||||||
|
|
|
@ -106,6 +106,8 @@
|
||||||
(current-style-file file)]
|
(current-style-file file)]
|
||||||
[("--prefix") file "use given .html/.tex prefix (for doctype/documentclass)"
|
[("--prefix") file "use given .html/.tex prefix (for doctype/documentclass)"
|
||||||
(current-prefix-file file)]
|
(current-prefix-file file)]
|
||||||
|
[("--link-section") "support section links for markdown"
|
||||||
|
(markdown:current-markdown-link-sections #t)]
|
||||||
#:multi
|
#:multi
|
||||||
[("++extra") file "add given file"
|
[("++extra") file "add given file"
|
||||||
(current-extra-files (cons file (current-extra-files)))]
|
(current-extra-files (cons file (current-extra-files)))]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user