commit 4431dff8d9540d8bfbef1676bc4d0fea1ebb40d9
parent f660f2c161866d0efabc601f8c62d919b29f7b90
Author: Matthew Flatt <mflatt@racket-lang.org>
Date: Fri, 6 Sep 2013 08:02:42 -0600
scribble/base: extend `verbatim` to accept non-string arguments
original commit: 0f439667bfbbfbf1c78ea63dec17534b3280a295
Diffstat:
6 files changed, 155 insertions(+), 17 deletions(-)
diff --git a/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl b/pkgs/scribble-pkgs/scribble-doc/scribblings/scribble/base.scrbl
@@ -272,17 +272,18 @@ Examples:
(list "makizushi" 'cont))]
}|
-@defproc[(verbatim [#:indent indent exact-nonnegative-integer? 0] [str string?] ...+)
+@defproc[(verbatim [#:indent indent exact-nonnegative-integer? 0] [elem content?] ...+)
block?]{
-Typesets @racket[str]s in typewriter font with the linebreaks
-specified by newline characters in @racket[str]. Consecutive spaces in
-the @racket[str]s are converted to @racket[hspace] to ensure that they
+Typesets string @racket[elem]s in typewriter font with linebreaks
+specified by newline characters in string @racket[elem]s. Consecutive spaces in
+the string @racket[elem]s are converted to @racket[hspace] to ensure that they
are all preserved in the output. Additional space (via
@racket[hspace]) as specified by @racket[indent] is added to the
-beginning of each line.
+beginning of each line. A non-string @racket[elem] is treated as
+content within a single line.
-The @racket[str]s are @emph{not} decoded with @racket[decode-content],
+The string @racket[elem]s are @emph{not} decoded with @racket[decode-content],
so @racket[(verbatim "---")] renders with three hyphens instead of an
em dash. Beware, however, that @emph{reading}
@litchar["@"]@racket[verbatim] converts @litchar["@"] syntax
@@ -304,7 +305,21 @@ which renders as
Use @bold{---} like this...
}|
-Even with @litchar["|{"]...@litchar["}|"], beware that consistent
+while
+
+@verbatim[#:indent 2]||{
+ @verbatim|{
+ Use |@bold{---} like this...
+ }|
+}||
+
+renders as
+
+@verbatim[#:indent 2]|{
+ Use |@bold{---} like this...
+}|
+
+Even with brackets like @litchar["|{"]...@litchar["}|"], beware that consistent
leading whitespace is removed by the parser; see
@secref["alt-body-syntax"] for more information.
diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/HISTORY.txt b/pkgs/scribble-pkgs/scribble-lib/scribble/HISTORY.txt
@@ -0,0 +1,6 @@
+Version 1.1
+Change `verbatim' to support non-string arguments
+
+Older versions
+See the "Racket core" release notes for a history of changes before
+ the "scribble-lib" package was created.
diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/base.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/base.rkt
@@ -486,7 +486,7 @@
[margin-note (->* () (#:left? any/c) #:rest (listof pre-flow?) block?)]
[margin-note* (->* () (#:left? any/c) #:rest (listof pre-content?) element?)]
[centered (->* () () #:rest (listof pre-flow?) block?)]
- [verbatim (->* (string?) (#:indent exact-nonnegative-integer?) #:rest (listof string?) block?)])
+ [verbatim (->* (content?) (#:indent exact-nonnegative-integer?) #:rest (listof content?) block?)])
(define (centered . s)
(make-nested-flow (make-style "SCentered" null) (decode-flow s)))
@@ -530,19 +530,61 @@
(decode-content 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 lines
+ ;; Break input into a list of lists, where each inner
+ ;; list is a single line. Break lines on "\n" in the
+ ;; input strings, while non-string content is treated
+ ;; as an element within a line.
+ (let loop ([l (cons s more)] [strs null])
+ (cond
+ [(null? l) (if (null? strs)
+ null
+ (map
+ list
+ (regexp-split
+ #rx"\n"
+ (apply string-append (reverse strs)))))]
+ [(string? (car l))
+ (loop (cdr l) (cons (car l) strs))]
+ [else
+ (define post-lines (loop (cdr l) null))
+ (define pre-lines (loop null strs))
+ (define-values (post-line rest-lines)
+ (if (null? post-lines)
+ (values null null)
+ (values (car post-lines) (cdr post-lines))))
+ (define-values (first-lines pre-line)
+ (if (null? pre-lines)
+ (values null null)
+ (values (drop-right pre-lines 1)
+ (last pre-lines))))
+ (append first-lines
+ (list (append pre-line (list (car l)) post-line))
+ rest-lines)])))
(define (str->elts str)
+ ;; Convert a single string in a line to typewriter font,
+ ;; and also convert multiple adjacent spaces to `hspace` so
+ ;; that the space is preserved exactly:
(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 (strs->elts line)
+ ;; Convert strings in the line:
+ (apply append (map (lambda (e)
+ (if (string? e)
+ (str->elts e)
+ (list e)))
+ line)))
+ (define indent
+ ;; Add indentation to a line:
+ (if (zero? i)
+ values
+ (let ([hs (hspace i)]) (lambda (line) (cons hs line)))))
(define (make-nonempty l)
+ ;; If a line has no content, then add a single space:
(if (let loop ([l l])
(cond
[(null? l) #t]
@@ -553,11 +595,12 @@
[else #f]))
(list l (hspace 1))
l))
- (define (make-line str)
- (let* ([line (indent (str->elts str))]
- [line (list (make-element 'tt line))])
+ (define (make-line line)
+ ;; Convert a list of line elements --- a mixture of strings
+ ;; and non-strings --- to a paragraph for the line:
+ (let* ([line (indent (strs->elts line))])
(list (make-paragraph omitable-style (make-nonempty line)))))
- (make-table plain (map make-line strs)))
+ (make-table plain (map make-line lines)))
(define omitable-style (make-style 'omitable null))
diff --git a/pkgs/scribble-pkgs/scribble-lib/scribble/info.rkt b/pkgs/scribble-pkgs/scribble-lib/scribble/info.rkt
@@ -9,3 +9,7 @@
'(("scribble" scribble/run "render a Scribble document" #f)))
(define purpose "This collect contains the implementation of scribble.")
+
+(define release-note-files '(("Scribble" "HISTORY.txt")))
+
+(define version "1.1")
diff --git a/pkgs/scribble-pkgs/scribble-test/tests/scribble/docs/verbatim.scrbl b/pkgs/scribble-pkgs/scribble-test/tests/scribble/docs/verbatim.scrbl
@@ -0,0 +1,39 @@
+#lang scribble/base
+
+@verbatim{One fish.}
+
+@verbatim{
+ One fish.
+ Two fish.
+}
+
+@verbatim[#:indent 3]{
+ One fish.
+ Two fish.
+}
+
+@verbatim[#:indent 3]{
+ One fish.
+ Two fish.
+ @bold{Red} fish.
+}
+
+@verbatim[#:indent 3]|{
+ One fish.
+ Two fish.
+ @bold{Red} fish.
+}|
+
+@verbatim[#:indent 3]|{
+ One fish.
+ Two fish.
+ |@bold{Red} fish.
+}|
+
+@verbatim[@bold{One fish.} "\nTwo fish."]
+
+@verbatim["One fish\n" @bold{Two fish.}]
+
+@verbatim[@bold{One fish.}]
+
+@verbatim["One fish\n" @bold{Two fish.} "\nRed fish."]
diff --git a/pkgs/scribble-pkgs/scribble-test/tests/scribble/docs/verbatim.txt b/pkgs/scribble-pkgs/scribble-test/tests/scribble/docs/verbatim.txt
@@ -0,0 +1,31 @@
+One fish.
+
+One fish.
+Two fish.
+
+ One fish.
+ Two fish.
+
+ One fish.
+ Two fish.
+ Red fish.
+
+ One fish.
+ Two fish.
+ @bold{Red} fish.
+
+ One fish.
+ Two fish.
+ Red fish.
+
+One fish.
+Two fish.
+
+One fish
+Two fish.
+
+One fish.
+
+One fish
+Two fish.
+Red fish.