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)))
(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)
(make-element classname (decode-content str)))

View File

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

View File

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

View File

@ -238,6 +238,10 @@
background-color: #eeeeee;
}
.schemereader {
font-family: Courier; font-size: 80%;
}
.schemeparen {
color: #843c24;
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}
A symbol is like an immutable string, but symbols are normally
@index["interned symbols"]{@defterm{interned}}, so that two symbols
with the same character content are normally @scheme[eq?]. All symbols
produced by the default reader (see @secref["mz:parse-symbol"]) are
interned.
@deftech{interned}, so that two symbols with the same character
content are normally @scheme[eq?]. All symbols produced by the default
reader (see @secref["mz:parse-symbol"]) are interned.
@index['("symbols" "generating")]{@index['("symbols" "unique")]{The}} two
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,
although they may print the same as other symbols.
@ -98,22 +97,23 @@ ephemeron key (see @secref["mz:ephemerons"]).
@examples[(symbol->string 'Apple)]
@defproc[(string->symbol [str string?]) symbol?]{Returns an interned
symbol whose characters are the same as in @scheme[str].}
@defproc[(string->symbol [str string?]) symbol?]{Returns an
@tech{interned} symbol whose characters are the same as in
@scheme[str].}
@examples[(string->symbol "Apple") (string->symbol "1")]
@defproc[(string->uninterned-symbol [str string?]) symbol?]{Like
@scheme[(string->symbol str)], but the resulting symbol is a new
uninterned symbol. Calling @scheme[string->uninterned-symbol] twice
with the same @scheme[str] returns two distinct symbols.}
@tech{uninterned} symbol. Calling @scheme[string->uninterned-symbol]
twice with the same @scheme[str] returns two distinct symbols.}
@examples[(string->uninterned-symbol "Apple") (eq? 'a (string->uninterned-symbol "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.}
@examples[(gensym "apple")]
@ -122,7 +122,39 @@ ephemeron key (see @secref["mz:ephemerons"]).
@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}

View File

@ -1,7 +1,9 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "bnf.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["utils.ss"]
@require-for-syntax[mzscheme]
@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
a macro).
@; FIXME: need to show evaluation here (with the scribble syntax)
@schemeblock[
@; FIXME: unfortunate code duplication
@interaction[
(eval:alts
(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}.})
--> "/Note/: *This is _not_ a pipe*."
#,(tt "@text{@it{Note}: @bf{This is @ul{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
@ -310,15 +319,15 @@ This is particularly useful with strings, which can be used to include
arbitrary text.
@scribble-examples|==={
@foo{This @"}" is a closing brace}
@foo{@"}" is a closing brace}
}===|
Note that the escaped string is (intentionally) merged with the rest
of the text. This works for @litchar["@"] too:
@scribble-examples|==={
@foo{The command prefix is @"@".}
@foo{@"@foo{bar}" reads as (foo "bar")}
@foo{Command prefix: @"@".}
@foo{@"@f{b}" -> (f "b")}
}===|
@subsubsub*section{Alternative Body Syntax}
@ -340,7 +349,7 @@ prefixed with a @litchar["|"]:
@foo|{Maze
|@bar{is}
Life!}|
@foo|{Works for |@bar|{subforms}| too}|
@foo|{|@bar|{subforms}| ok}|
}===|
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.
@scribble-examples|==={
@foo|<<<{Some @x{more} |@{text}|.}>>>|
@foo|!!{Blah |!!@bold{blah}...}!!|
@foo|<<<{@x{m} |@{t}|.}>>>|
@foo|!!{B |!!@bold{b}...}!!|
}===|
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|==={
@foo{First line@;{there is still a
newline at this point;}
newline here;}
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.
@scribble-examples|==={
@foo{This is @;
a pretty long @;
single string-@;
argument.}
@foo{A long single-@;
string arg.}
}===|
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
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|==={
@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
can be used to identify newlines in the original @nonterm{text-body}.
@; FIXME: need to show printout here (with the scribble syntax)
@schemeblock[
@; FIXME: unfortunate code duplication (again):
@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 @'{
})])
(for-each (lambda (x) (display (if (eq? x nl) "\n... " x)))
@`{foo
@,@(list "bar" "\n" "baz")
blah})
(newline))
--prints-->
foo
... bar
baz
... blah
(newline)))
]
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
block).
@;FIXME: last example too long, messes up output
@scribble-examples|==={
@foo{bar
baz
@ -560,8 +569,8 @@ block).
@foo{ bar
baz
bbb}
@text{Some text@footnote{And a
footnote comment.}. More text.}
@text{Text@note{And
note.}. More.}
}===|
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
single-newline string. Here is an example of this.
@; FIXME: need to show evaluation here (with the scribble syntax)
@schemeblock[
@; FIXME: a bit of code duplication here
@def+int[
(define-syntax (verb stx)
(syntax-case stx ()
[(_ cmd item ...)
;;FIXME: show a "#`" in the rendering of the following line
#`(cmd .
;;FIXME: the next line should begin with a #,
,(let loop ([items (syntax->list #'(item ...))])
(if (null? items)
'()
(let* ([fst (car items)]
[prop (syntax-property fst 'scribble)]
[rst (loop (cdr items))])
(cond [(not prop) (cons fst rst)]
[(eq? prop 'indentation) rst]
[else (cons (datum->syntax-object
fst (cadr prop) fst)
rst)])))))]))
#`(cmd
#,@(let loop ([items (syntax->list #'(item ...))])
(if (null? items)
'()
(let* ([fst (car items)]
[prop (syntax-property fst 'scribble)]
[rst (loop (cdr items))])
(cond [(not prop) (cons fst rst)]
[(eq? prop 'indentation) rst]
[else (cons (datum->syntax-object
fst (cadr prop) fst)
rst)])))))]))
(eval:alts
(code:line
#, @tt["@verb[string-append]{"]
#, @tt[" foo"]
#, @tt[" bar"]
#, @tt["}"])
@verb[string-append]{
foo
bar
}
--> "foo\n bar"
})
]