scribble/base: extend verbatim to accept non-string arguments

original commit: 0f439667bfbbfbf1c78ea63dec17534b3280a295
This commit is contained in:
Matthew Flatt 2013-09-06 08:02:42 -06:00
parent f660f2c161
commit 4431dff8d9
6 changed files with 155 additions and 17 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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))

View File

@ -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")

View File

@ -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."]

View File

@ -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.