fix up scribble manual reader examples

svn: r6876
This commit is contained in:
Matthew Flatt 2007-07-10 01:46:46 +00:00
parent 006ab0f79d
commit 966a9a41a6
6 changed files with 134 additions and 61 deletions

View File

@ -89,7 +89,24 @@
(make-element 'bold (decode-content str))) (make-element 'bold (decode-content str)))
(define (tt . str) (define (tt . str)
(make-element 'tt (decode-content str))) (let ([l (decode-content str)])
(let ([l (let ([m (and (pair? l)
(string? (car l))
(regexp-match-positions #rx"^ +" (car l)))])
(if m
(cons (hspace (- (cdar m) (caar m)))
(cons
(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) (define (span-class classname . str)
(make-element classname (decode-content str))) (make-element classname (decode-content str)))

View File

@ -54,6 +54,7 @@
(define-color "schemestdout" "OutputColor") (define-color "schemestdout" "OutputColor")
(define-color "schememeta" "IdentifierColor") (define-color "schememeta" "IdentifierColor")
(define-color "schememod" "black") (define-color "schememod" "black")
(define-color "schemereader" "black")
(define-color "schemevariablecol" "IdentifierColor") (define-color "schemevariablecol" "IdentifierColor")
(printf "\\newcommand{\\schemevariable}[1]{{\\schemevariablecol{\\textsl{#1}}}}\n") (printf "\\newcommand{\\schemevariable}[1]{{\\schemevariablecol{\\textsl{#1}}}}\n")
(define-color "schemeerrorcol" "red") (define-color "schemeerrorcol" "red")

View File

@ -22,7 +22,7 @@
(struct just-context (val ctx))) (struct just-context (val ctx)))
(define no-color "schemeplain") (define no-color "schemeplain")
(define reader-color "schemeplain") (define reader-color "schemereader")
(define keyword-color "schemekeyword") (define keyword-color "schemekeyword")
(define comment-color "schemecomment") (define comment-color "schemecomment")
(define paren-color "schemeparen") (define paren-color "schemeparen")
@ -253,7 +253,7 @@
[(and (pair? (syntax-e c)) [(and (pair? (syntax-e c))
(memq (syntax-e (car (syntax-e c))) (memq (syntax-e (car (syntax-e c)))
'(quote quasiquote unquote unquote-splicing '(quote quasiquote unquote unquote-splicing
syntax unsyntax))) quasisyntax syntax unsyntax unsyntax-splicing)))
(advance c init-line!) (advance c init-line!)
(let-values ([(str quote-delta) (let-values ([(str quote-delta)
(case (syntax-e (car (syntax-e c))) (case (syntax-e (car (syntax-e c)))
@ -262,7 +262,9 @@
[(unquote-splicing) (values ",@" -1)] [(unquote-splicing) (values ",@" -1)]
[(quasiquote) (values "`" +1)] [(quasiquote) (values "`" +1)]
[(syntax) (values "#'" 0)] [(syntax) (values "#'" 0)]
[(unsyntax) (values "#," 0)])]) [(quasisyntax) (values "#`" 0)]
[(unsyntax) (values "#," 0)]
[(unsyntax-splicing) (values "#,@" 0)])])
(out str (if (positive? (+ quote-depth quote-delta)) (out str (if (positive? (+ quote-depth quote-delta))
value-color value-color
reader-color)) reader-color))
@ -308,7 +310,9 @@
c)]) c)])
(cond (cond
[(and (syntax? l) [(and (syntax? l)
(pair? (syntax-e l))) (pair? (syntax-e l))
(not (memq (syntax-e (car (syntax-e l)))
'(quote unquote syntax unsyntax quasiquote quasiunsyntax))))
(lloop (syntax-e l))] (lloop (syntax-e l))]
[(or (null? l) [(or (null? l)
(and (syntax? l) (and (syntax? l)
@ -318,6 +322,7 @@
((loop init-line! quote-depth) (car l)) ((loop init-line! quote-depth) (car l))
(lloop (cdr l))] (lloop (cdr l))]
[else [else
(advance l init-line! -2) (advance l init-line! -2)
(out ". " (if (positive? quote-depth) value-color paren-color)) (out ". " (if (positive? quote-depth) value-color paren-color))
(set! src-col (+ src-col 3)) (set! src-col (+ src-col 3))

View File

@ -238,6 +238,10 @@
background-color: #eeeeee; background-color: #eeeeee;
} }
.schemereader {
font-family: Courier; font-size: 80%;
}
.schemeparen { .schemeparen {
color: #843c24; color: #843c24;
font-family: Courier; font-size: 80%; font-family: Courier; font-size: 80%;

View File

@ -67,14 +67,13 @@ object, @scheme[#f] otherwise. See also @secref["mz:model-eq"].}
@guideintro["guide:symbols"]{symbols} @guideintro["guide:symbols"]{symbols}
A symbol is like an immutable string, but symbols are normally A symbol is like an immutable string, but symbols are normally
@index["interned symbols"]{@defterm{interned}}, so that two symbols @deftech{interned}, so that two symbols with the same character
with the same character content are normally @scheme[eq?]. All symbols content are normally @scheme[eq?]. All symbols produced by the default
produced by the default reader (see @secref["mz:parse-symbol"]) are reader (see @secref["mz:parse-symbol"]) are interned.
interned.
@index['("symbols" "generating")]{@index['("symbols" "unique")]{The}} two @index['("symbols" "generating")]{@index['("symbols" "unique")]{The}} two
procedures @scheme[string->uninterned-symbol] and @scheme[gensym] procedures @scheme[string->uninterned-symbol] and @scheme[gensym]
generate @idefterm{uninterned symbols}, i.e., a symbols that are not generate @deftech{uninterned} symbols, i.e., symbols that are not
@scheme[eq?], @scheme[eqv?], or @scheme[equal?] to any other symbol, @scheme[eq?], @scheme[eqv?], or @scheme[equal?] to any other symbol,
although they may print the same as other symbols. although they may print the same as other symbols.
@ -98,22 +97,23 @@ ephemeron key (see @secref["mz:ephemerons"]).
@examples[(symbol->string 'Apple)] @examples[(symbol->string 'Apple)]
@defproc[(string->symbol [str string?]) symbol?]{Returns an interned @defproc[(string->symbol [str string?]) symbol?]{Returns an
symbol whose characters are the same as in @scheme[str].} @tech{interned} symbol whose characters are the same as in
@scheme[str].}
@examples[(string->symbol "Apple") (string->symbol "1")] @examples[(string->symbol "Apple") (string->symbol "1")]
@defproc[(string->uninterned-symbol [str string?]) symbol?]{Like @defproc[(string->uninterned-symbol [str string?]) symbol?]{Like
@scheme[(string->symbol str)], but the resulting symbol is a new @scheme[(string->symbol str)], but the resulting symbol is a new
uninterned symbol. Calling @scheme[string->uninterned-symbol] twice @tech{uninterned} symbol. Calling @scheme[string->uninterned-symbol]
with the same @scheme[str] returns two distinct symbols.} twice with the same @scheme[str] returns two distinct symbols.}
@examples[(string->uninterned-symbol "Apple") (eq? 'a (string->uninterned-symbol "a"))] @examples[(string->uninterned-symbol "Apple") (eq? 'a (string->uninterned-symbol "a"))]
@defproc[(gensym [base (or/c string? symbol?) "g"]) symbol?]{Returns a @defproc[(gensym [base (or/c string? symbol?) "g"]) symbol?]{Returns a
new uninterned symbol with an automatically-generated name. The new @tech{uninterned} symbol with an automatically-generated name. The
optional @scheme[base] argument is a prefix symbol or string.} optional @scheme[base] argument is a prefix symbol or string.}
@examples[(gensym "apple")] @examples[(gensym "apple")]
@ -122,7 +122,39 @@ ephemeron key (see @secref["mz:ephemerons"]).
@include-section["regexps.scrbl"] @include-section["regexps.scrbl"]
@; ------------------------------------------------------------ @; ------------------------------------------------------------
@section[#:tag "keywords"]{Keywords} @section[#:tag "mz:keywords"]{Keywords}
@guideintro["guide:keywords"]{keywords}
A keyword is like an @tech{interned} symbol, but its printed form
starts with @litchar{#:}, and a keyword cannot be used as an
identifier. Furthermore, a keyword by itself is not a valid
expression, though a keyword can be @scheme[quote]d to form an
expression that produces the symbol.
Two keywords are @scheme[eq?] if and only if they print the same.
Like symbols, keywords are only weakly held by the internal keyword
table; see @secref["mz:symbols"] for more information.
@item{@defproc[(keyword? [v any/c]) any] returns @scheme[#t] if @scheme[v] is a
keyword, @scheme[#f] otherwise.}
@defproc[(keyword->string [keyword keyword?]) string?]{
Returns a string for the @scheme[display]ed form of @scheme[keyword],
not including the leading @litchar{#:}.}
@defproc[(string->keyword [str string?]) keyword]{
Returns a keyword whose @scheme[display]ed form is the same as that of
@scheme[str], but with a leading @litchar{#:}.}
@defproc[(keyword<? [a-keyword keyword?][b-keyword keyword?] ...+) boolean?]{
Returns @scheme[#t] if the arguments are sorted, where the comparison
for each pair of keywords is the same as using
@scheme[keyword->string] and @scheme[string<?].}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@section[#:tag "mz:pairs"]{Pairs and Lists} @section[#:tag "mz:pairs"]{Pairs and Lists}

View File

@ -1,7 +1,9 @@
#reader(lib "docreader.ss" "scribble") #reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")] @require[(lib "manual.ss" "scribble")]
@require[(lib "bnf.ss" "scribble")] @require[(lib "bnf.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["utils.ss"] @require["utils.ss"]
@require-for-syntax[mzscheme]
@title[#:tag "reader"]{The Scribble Reader} @title[#:tag "reader"]{The Scribble Reader}
@ -112,16 +114,23 @@ When the above @"@"-forms appear in a Scheme expression context, the
lexical environment must provide bindings for @scheme[foo] (as a procedure or lexical environment must provide bindings for @scheme[foo] (as a procedure or
a macro). a macro).
@; FIXME: need to show evaluation here (with the scribble syntax) @; FIXME: unfortunate code duplication
@schemeblock[ @interaction[
(eval:alts
(let* ([formatter (lambda (fmt) (let* ([formatter (lambda (fmt)
(lambda args (format fmt (apply string-append args))))] (lambda args (format fmt (apply string-append args))))]
[bf (formatter "*~a*")] [bf (formatter "*~a*")]
[it (formatter "/~a/")] [it (formatter "/~a/")]
[ul (formatter "_~a_")] [ul (formatter "_~a_")]
[text string-append]) [text string-append])
@text{@it{Note}: @bf{This is @ul{not} a pipe}.}) #,(tt "@text{@it{Note}: @bf{This is @ul{not} a pipe}.}"))
--> "/Note/: *This is _not_ a pipe*." (let* ([formatter (lambda (fmt)
(lambda args (format fmt (apply string-append args))))]
[bf (formatter "*~a*")]
[it (formatter "/~a/")]
[ul (formatter "_~a_")]
[text string-append])
@text{@it{Note}: @bf{This is @ul{not} a pipe}.}))
] ]
If you want to see the expression that is actually being read, you can If you want to see the expression that is actually being read, you can
@ -310,15 +319,15 @@ This is particularly useful with strings, which can be used to include
arbitrary text. arbitrary text.
@scribble-examples|==={ @scribble-examples|==={
@foo{This @"}" is a closing brace} @foo{@"}" is a closing brace}
}===| }===|
Note that the escaped string is (intentionally) merged with the rest Note that the escaped string is (intentionally) merged with the rest
of the text. This works for @litchar["@"] too: of the text. This works for @litchar["@"] too:
@scribble-examples|==={ @scribble-examples|==={
@foo{The command prefix is @"@".} @foo{Command prefix: @"@".}
@foo{@"@foo{bar}" reads as (foo "bar")} @foo{@"@f{b}" -> (f "b")}
}===| }===|
@subsubsub*section{Alternative Body Syntax} @subsubsub*section{Alternative Body Syntax}
@ -340,7 +349,7 @@ prefixed with a @litchar["|"]:
@foo|{Maze @foo|{Maze
|@bar{is} |@bar{is}
Life!}| Life!}|
@foo|{Works for |@bar|{subforms}| too}| @foo|{|@bar|{subforms}| ok}|
}===| }===|
Note that the subform uses its own delimiters, @litchar["{...}"] or Note that the subform uses its own delimiters, @litchar["{...}"] or
@ -357,8 +366,8 @@ in reverse order with paren-like characters (@litchar["("],
@litchar["["], @litchar["<"]) mirrored. @litchar["["], @litchar["<"]) mirrored.
@scribble-examples|==={ @scribble-examples|==={
@foo|<<<{Some @x{more} |@{text}|.}>>>| @foo|<<<{@x{m} |@{t}|.}>>>|
@foo|!!{Blah |!!@bold{blah}...}!!| @foo|!!{B |!!@bold{b}...}!!|
}===| }===|
Finally, remember that you can use an expression escape with a Scheme Finally, remember that you can use an expression escape with a Scheme
@ -430,7 +439,7 @@ rules for @"@"-forms), and @litchar["@;..."] is a line-comment.
@scribble-examples|==={ @scribble-examples|==={
@foo{First line@;{there is still a @foo{First line@;{there is still a
newline at this point;} newline here;}
Second line} Second line}
}===| }===|
@ -439,10 +448,8 @@ of the line @italic{and} all following spaces (or tabs). Using this,
you can get further control of the subforms. you can get further control of the subforms.
@scribble-examples|==={ @scribble-examples|==={
@foo{This is @; @foo{A long single-@;
a pretty long @; string arg.}
single string-@;
argument.}
}===| }===|
Note how this is different from using @litchar["@||"]s in that strings Note how this is different from using @litchar["@||"]s in that strings
@ -467,7 +474,7 @@ A single newline that follows an open brace or precedes a closing
brace is discarded, unless there are only newlines in the body; other brace is discarded, unless there are only newlines in the body; other
newlines are read as a @scheme["\n"] string newlines are read as a @scheme["\n"] string
@;FIXME empty lines are ignored in generated HTML output @;FIXME empty lines are ignored in generated HTML output (with IE?)
@scribble-examples|==={ @scribble-examples|==={
@foo{bar @foo{bar
} }
@ -497,20 +504,23 @@ In the parsed S-expression syntax, a single newline string is used for
all newlines; you can use @scheme[eq?] to identify this line. This all newlines; you can use @scheme[eq?] to identify this line. This
can be used to identify newlines in the original @nonterm{text-body}. can be used to identify newlines in the original @nonterm{text-body}.
@; FIXME: need to show printout here (with the scribble syntax) @; FIXME: unfortunate code duplication (again):
@schemeblock[ @interaction[
(eval:alts
(let ([nl (car #, @tt["@'{"]
#, @tt[" }"])])
(for-each (lambda (x) (display (if (eq? x nl) "\n... " x)))
#, @tt["@`{foo"]
#, @elem[@tt[" @"] @scheme[,@(list "bar" "\n" "baz")]]
#, @tt[" blah}}"])
(newline))
(let ([nl (car @'{ (let ([nl (car @'{
})]) })])
(for-each (lambda (x) (display (if (eq? x nl) "\n... " x))) (for-each (lambda (x) (display (if (eq? x nl) "\n... " x)))
@`{foo @`{foo
@,@(list "bar" "\n" "baz") @,@(list "bar" "\n" "baz")
blah}) blah})
(newline)) (newline)))
--prints-->
foo
... bar
baz
... blah
] ]
Spaces at the beginning of body lines do not appear in the resulting Spaces at the beginning of body lines do not appear in the resulting
@ -543,7 +553,6 @@ syntax object used for indentation). This makes sense when formatting
structured code as well as text (see the last example in the following structured code as well as text (see the last example in the following
block). block).
@;FIXME: last example too long, messes up output
@scribble-examples|==={ @scribble-examples|==={
@foo{bar @foo{bar
baz baz
@ -560,8 +569,8 @@ block).
@foo{ bar @foo{ bar
baz baz
bbb} bbb}
@text{Some text@footnote{And a @text{Text@note{And
footnote comment.}. More text.} note.}. More.}
}===| }===|
Note that each @"@"-form is parsed to an S-expression that has its own Note that each @"@"-form is parsed to an S-expression that has its own
@ -634,28 +643,33 @@ To implement a verbatim environment you need to drop indentation
strings, and use the original newline strings instead of the strings, and use the original newline strings instead of the
single-newline string. Here is an example of this. single-newline string. Here is an example of this.
@; FIXME: need to show evaluation here (with the scribble syntax) @; FIXME: a bit of code duplication here
@schemeblock[ @def+int[
(define-syntax (verb stx) (define-syntax (verb stx)
(syntax-case stx () (syntax-case stx ()
[(_ cmd item ...) [(_ cmd item ...)
;;FIXME: show a "#`" in the rendering of the following line #`(cmd
#`(cmd . #,@(let loop ([items (syntax->list #'(item ...))])
;;FIXME: the next line should begin with a #, (if (null? items)
,(let loop ([items (syntax->list #'(item ...))]) '()
(if (null? items) (let* ([fst (car items)]
'() [prop (syntax-property fst 'scribble)]
(let* ([fst (car items)] [rst (loop (cdr items))])
[prop (syntax-property fst 'scribble)] (cond [(not prop) (cons fst rst)]
[rst (loop (cdr items))]) [(eq? prop 'indentation) rst]
(cond [(not prop) (cons fst rst)] [else (cons (datum->syntax-object
[(eq? prop 'indentation) rst] fst (cadr prop) fst)
[else (cons (datum->syntax-object rst)])))))]))
fst (cadr prop) fst) (eval:alts
rst)])))))]))
(code:line
#, @tt["@verb[string-append]{"]
#, @tt[" foo"]
#, @tt[" bar"]
#, @tt["}"])
@verb[string-append]{ @verb[string-append]{
foo foo
bar bar
} })
--> "foo\n bar"
] ]