new documentation source moved to the trunk collects

svn: r6249

original commit: 858c8024efa41ebfdb5f05383c70be5412448570
This commit is contained in:
Matthew Flatt 2007-05-24 02:20:28 +00:00
parent 9b7993ea02
commit d893680ac2
11 changed files with 1553 additions and 0 deletions

View File

@ -0,0 +1,151 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@require-for-syntax[mzscheme]
@define-syntax[def-title-like
(syntax-rules ()
[(_ id result/c x ...) (defproc (id [#:tag tag (or/c false/c string?) #f]
[pre-content any/c] ...0)
result/c
x ...)])]
@define-syntax[def-elem-proc
(syntax-rules ()
[(_ id x ...) (defproc (id [pre-content any/c] ...0)
element?
x ...)])]
@define-syntax[def-style-proc
(syntax-rules ()
[(_ id) @def-elem-proc[id]{Like @scheme[elem], but with style @scheme['id]}])]
@title[#:tag "basic"]{Basic Document Forms}
The @file{basic.ss} libraryprovides functions and forms that can be
used from code written either in Scheme or with @elem["@"]
expressions. For example, the @scheme[title] and @scheme[italic]
functions might be called from Scheme as
@schemeblock[
(title #:tag "how-to" "How to Design " (italic "Great") " Programs")
]
or with an @elem["@"] expression as
@verbatim[
#<<EOS
@title[#:tag "how-to"]{How to Design @italic{Great} Programs}
EOS
]
Although the procedures are mostly design to be used from @elem["@"]
mode, they are easier to document in Scheme mode (partly because we
have Scribble's @file{scheme.ss} and @file{manual.ss}).
@section{Document Structure}
@def-title-like[title title-decl?]{ Generates a @scheme[title-decl] to
be picked up by @scheme[decode] or @scheme[decode-part]. The
@scheme[pre-content]s list is parsed with @scheme[decode-content] for
the title content. If @scheme[tag] is @scheme[#f], a tag string is
generated automatically from the content. The tag string is combined
with the symbol @scheme['section] to form the full tag.}
@def-title-like[section section-start?]{ Like @scheme[title], but
generates a @scheme[section-start] of depth @scheme[0] to be by
@scheme[decode] or @scheme[decode-part].}
@def-title-like[subsection section-start?]{ Like @scheme[section], but
generates a @scheme[section-start] of depth @scheme[1].}
@def-title-like[subsubsection section-start?]{ Like @scheme[section], but
generates a @scheme[section-start] of depth @scheme[2].}
@def-title-like[subsubsub*section paragraph?]{ Similar to
@scheme[section], but merely generates a paragraph that looks like an
unnumbered section heading (for when the nesting gets too deep to
include in a table of contents).}
@defproc[(itemize [itm (or/c whitespace? an-item?)] ...0) itemization?]{
Constructs an itemization given a sequence of items constructed by
@scheme[item]. Whitespace strings among the @scheme[itm]s are
ignored.
}
@defproc[(item pre-flow ...0) item?]{
Creates an item for use with @scheme[itemize]. The
@scheme[pre-flow] list is parsed with @scheme[decode-flow].
}
@defform[(include-section module-path)]{ Requires @scheme[module-path]
and returns its @scheme[doc] export (without making any imports
visible to the enclosing context). Since this form expands to
@scheme[require], it must be used in a module or top-level context.}
@section{Text Styles}
@def-elem-proc[elem]{ Parses the @scheme[pre-content] list using
@scheme[decode-content], and wraps the result as an element with
style @scheme[#f].}
@def-style-proc[italic]
@def-style-proc[bold]
@def-style-proc[tt]
@def-style-proc[subscript]
@def-style-proc[superscript]
@defproc[(hspace [n nonnegative-exact-integer?]) element?]{
Produces an element containing @scheme[n] spaces and style @scheme['hspace].
}
@defproc[(span-class [style-name string?] [pre-content any/c] ...0)
element?]{
Parses the @scheme[pre-content] list using @scheme[decode-content],
and produces an element with style @scheme[style-name].
}
@section{Indexing}
@defproc[(index [words (or/c string? (listof string?))]
[pre-content any/c] ...0)
index-element?] {
Creates an index element given a plain-text string---or list of
strings for a hierarchy, such as @scheme['("strings" "plain")] for a
``plain'' entry until a more general ``strings'' entry. The strings
also serve as the text to render in the index. The
@scheme[pre-content] list, as parsed by @scheme[decode-content] is the
text to appear in place of the element, to which the index entry
refers.
}
@defproc[(index* [words (listof string?)]
[word-contents (listof list?)]
[pre-content any/c] ...0)
index-element?] {
Like @scheme[index], except that @scheme[words] must be a list, and
the list of contents render in the index (in parallel to
@scheme[words]) is supplied as @scheme[word-contents].
}
@defproc[(as-index [pre-content any/c] ...0)
index-element?] {
Like @scheme[index], but the word to index is determined by applying
@scheme[content->string] on the parsed @scheme[pre-content] list.
}
@section{Tables of Contents}
@defproc[(table-of-contents) delayed-flow-element?]{
Returns a flow element that expands to a table of contents for the
enclosing section. For LaTeX output, however, the table of contents
currently spans the entire enclosing document.
}

View File

@ -0,0 +1,111 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@title[#:tag "decode"]{Text Decoder}
The @file{decode.ss} library helps you write document content in a
natural way---more like plain text, except for @elem["@"] escapes.
Roughly, it processes a stream of strings to produces instances of the
@file{struct.ss} datatypes (see @secref["struct"]).
At the flow level, decoding recognizes a blank line as a paragraph
separator. At the paragraph-content level, decoding makes just a few
special text conversions:
@itemize{
@item{@litchar{---}: converted to @scheme['mdash], which the HTML render
outputs as an en-dash surrounded by space (so don't put spaces around
@litchar{---} in a document)}
@item{@litchar{--}: converted to @scheme['ndash]}
@item{@litchar{``}: converted to @scheme['ldquo], which is fancy open quotes: ``}
@item{@litchar{''}: converted to @scheme['rdquo], which is fancy closing quotes: ''}
@item{@litchar{'}: converted to @scheme['rsquo], which is a fancy apostrophe: '}
}
@defproc[(decode [lst list?]) part?]{
Decodes a document, producing a part. In @scheme[lst], instances of
@scheme[splice] are inlined into the list. An instance of
@scheme[title-decl] supplies the title for the part. Instances of
@scheme[part-start] at level 0 trigger sub-part parsing. Instances of
@scheme[section] trigger are used as-is as subsections, and instances
of @scheme[paragraph] and other flow-element datatypes are used as-is
in the enclosing flow.
}
@defproc[(decode-part [lst list?]
[tag string?]
[title (or/c false/c list?)]
[depth excat-nonnegative-integer?])
part?]{
Like @scheme[decode], but given a tag for the section, a title (if
@scheme[#f], then a @scheme[title-decl] instance is used if found),
and a depth for @scheme[part-start]s to trigger sub-part parsing.
}
@defproc[(decode-flow [lst list?]) (listof flow-element?)]{
Decodes a flow. A sequence of two or more newlines separated only by
whitespace counts is parsed as a paragraph separator. In @scheme[lst],
instances of @scheme[splice] are inlined into the list. Instances of
@scheme[paragraph] and other flow-element datatypes are used as-is in
the enclosing flow.
}
@defproc[(decode-paragraph [lst list?]) paragraph?]{
Decodes a paragraph.
}
@defproc[(decode-content [lst list?]) list?]{
Decodes a sequence of elements.
}
@defproc[(decode-string [s string?]) list?]{
Decodes a single string to produce a list of elements.
}
@defproc[(whitespace? [s string?]) boolean?]{
Returns @scheme[#t] if @scheme[s] contains only whitespace, @scheme[#f]
otherwise.
}
@defstruct[title-decl ([tag any/c]
[content list?])]{
See @scheme[decode] and @scheme[decode-part].
}
@defstruct[part-start ([depth integer?]
[tag (or/c false/c string?)]
[title list?])]{
See @scheme[decode] and @scheme[decode-part].
}
@defstruct[splice ([run list?])]{
See @scheme[decode], @scheme[decode-part], and @scheme[decode-flow].
}

View File

@ -0,0 +1,18 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@title[#:tag "doclang"]{Document Module Languegs}
The @file{doclang.ss} module is suitable for use as a module
language. It provides everything from @scheme[mzscheme], except that
it replaces the @scheme[#%module-begin] form.
The @file{doclang.ss} @scheme[#%module-begin] essentially packages the
body of the module into a call to @scheme[decode], binds the result to
@scheme[doc], and exports @scheme[doc].
Any module-level form other than an expression (e.g., a
@scheme[require] or @scheme[define]) is remains at the top level, and
the @scheme[doc] binding is put at the end of the module. As usual, a
module-top-level @scheme[begin] slices into the module top level.

View File

@ -0,0 +1,13 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["../bnf.ss"]
@require["utils.ss"]
@title[#:tag "docreader"]{Document Reader}
The @file{docreader.ss} module is suitable for use with
@schemefont{#reader} at the beginning of a file. It reads the entire
file with @scheme[read-inside-syntax] from Scribble's
@file{reader.ss}, and then wraps the result with @scheme[(module #,
@nonterm{name} (lib "doclang.ss" "scribble") ...)], where
@nonterm{name} is derived from the enclosing file's name.

View File

@ -0,0 +1,56 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@title[#:tag "eval"]{Evaluation and Examples}
The @file{eval.ss} library provides utilities for evaluating code at
document-build time and incorporating the results in the document,
especially to show example uses of defined procedures and syntax.
@defform[(interaction datum ...)]{Like @scheme[schemeinput], except
that the result for each input @scheme[datum] is shown on the next
line. The result is determined by evaluating the quoted form of the
datum.
Uses of @scheme[code:comment] and @schemeidfont{code:blank} are
stipped from each @scheme[datum] before evaluation.
If a datum has the form @scheme[(#,(scheme code:line) #,(svar datum)
(#,(scheme code:comment) ...))], then only the @svar[datum] is
evaluated.
If a datum has the form @scheme[(eval:alts #,(svar show-datum) #,(svar
eval-datum))], then @svar[show-datum] is typeset, while
@svar[eval-datum] is evaluated.}
@defform[(interaction-eval datum)]{Evaluates the quoted form of
each @scheme[datum] via @scheme[do-eval] and returns the empty string.}
@defform[(interaction-eval-show datum)]{Evaluates the quoted form of
@scheme[datum] and produces an element represeting the printed form of
the result.}
@defform[(schemeblock+eval datum ...)]{Combines @scheme[schemeblock]
and @scheme[interaction-eval].}
@defform[(schememod+eval name datum ...)]{Combines @scheme[schememod]
and @scheme[interaction-eval].}
@defform[(def+int defn-datum expr-datum ...)]{Like
@scheme[interaction], except the the @scheme[defn-datum] is typeset as
for @scheme[schemeblock] (i.e., no prompt) with a line of space
between the definition and the interactions.}
@defform[(defs+int (defn-datum ...) expr-datum ...)]{Like
@scheme[def+int], but for multiple leading definitions.}
@defform[(examples datum ...)]{Like @scheme[interaction], but with an
``Examples:'' label prefixed.}
@defform[(defexamples datum ...)]{Like @scheme[examples], but each
definition using @scheme[define] among the @scheme[datum]s is typeset
without a prompt, and with space after it.}
@defthing[current-int-namespace parameter?]{A parameter to hold the
namespace used by @scheme[interaction], etc.}

View File

@ -0,0 +1,328 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@require-for-syntax[mzscheme]
@title[#:tag "manual"]{PLT Manual Forms}
The @file{manual.ss} module provides all of @file{basic.ss}, and
more...
@; ------------------------------------------------------------------------
@section{Typesetting Code}
@defform[(schemeblock datum ...)]{
Typesets the @scheme[datum] sequence as a table of Scheme code inset
by two spaces. The source locations of the @scheme[datum]s determines
the generated layout. For example,
@schemeblock[
(schemeblock
(define (loop x)
(loop (not x))))
]
produces the output
@schemeblock[
(define (loop x)
(loop (not x)))
]
with the @scheme[(loop (not x))] indented under @scheme[define],
because that's the way it is idented the use of @scheme[schemeblock].
Furthermore, @scheme[define] is typeset as a keyword (bold and black)
and as a hyperlink to @scheme[define]'s definition in the reference
manual, because this document was built using information about the
MzScheme manual. Similarly, @scheme[not] is a hyperlink to the its
definition in the reference manual.
Use @scheme[unsyntax] to escape back to an expression that produces an
@scheme[element]. For example,
@let[([unsyntax #f])
(schemeblock
(schemeblock
(+ 1 (unsyntax (elem (scheme x) (subscript "2"))))))
]
produces
@schemeblock[
(+ 1 (unsyntax (elem (scheme x) (subscript "2"))))
]
The @scheme[unsyntax] form is regonized via
@scheme[module-identifier=?], so if you want to typeset code that
includes @scheme[unsyntax], you can simply hide the usual binding:
@SCHEMEBLOCK[
(schemeblock
(let ([(UNSYNTAX (scheme unsyntax)) #f])
(schemeblock
(syntax (+ 1 (unsyntax x))))))
]
Or use @scheme[SCHEMEBLOCK], whose escape form is @scheme[UNSYNTAX]
instead of @scheme[unsyntax]. See also @scheme[define-code] from
@file{scheme.ss}.
A few other escapes are recognized symbolically:
@itemize{
@item{@scheme[(#,(scheme code:line) datum ...)] typesets as the
sequence of @scheme[datum]s (i.e., without the
@scheme[code:line] wrapper.}
@item{@scheme[(#,(scheme code:comment) content-expr)] typesets as a
comment whose content (i.e., sequence of elements) is produced
by @scheme[content-expr].}
@item{@schemeidfont{code:blank} typesets as a blank line.}
}
}
@defform[(SCHEMEBLOCK datum ...)]{Like @scheme[schemeblock], but with
the expression escape @scheme[UNSYNTAX] instead of @scheme[unsyntax].}
@defform[(schemeblock0 datum ...)]{Like @scheme[schemeblock], but
without insetting the code.}
@defform[(SCHEMEBLOCK0 datum ...)]{Like @scheme[SCHEMEBLOCK], but
without insetting the code.}
@defform[(schemeinput datum ...)]{Like @scheme[schemeblock], but the
@scheme[datum] are typeset after a prompt representing a REPL.}
@defform[(schememod lang datum ...)]{Like @scheme[schemeblock], but
the @scheme[datum] are typeset inside a @schemefont{#module}-form
module whose language is @scheme[lang].}
@defform[(scheme datum ...)]{Like @scheme[schemeblock], but typeset on
a single line and wrapped with its enclosing paragraph, independent of
the formatting of @scheme[datum].}
@defform[(schemeresult datum ...)]{Like @scheme[scheme], but typeset
as a REPL value (i.e., a single color with no hperlinks).}
@defform[(schemeid datum ...)]{Like @scheme[scheme], but typeset
as an unbound identifier (i.e., no coloring or hyperlink).}
@defform[(schememodname datum ...)]{Like @scheme[scheme], but typeset
as a @schemefont{#module} language name.}
@defproc[(litchar [str string?]) element?]{Typesets @scheme[str] as a
representation of literal text. Use this when you have to talk about
the individual characters in a stream of text, as as when documenting
a reader extension.}
@defproc[(verbatim [str string?]) flow-element?]{Typesets @scheme[str]
as a table/paragraph in typewriter font with the linebreaks specified
by newline characters in @scheme[str]. ``Here strings'' are often
useful with @scheme[verbatim].}
@defproc[(schemefont [pre-content any/c] ...0) element?]{Typesets the given
content as uncolored, unhyperlinked Scheme. This procedure is useful
for typesetting thngs like @scheme{#module}, which are not
@scheme[read]able by themselves.}
@defproc[(schemevalfont [pre-content any/c] ...0) element?]{Like
@scheme[schemefont], but colored as a value.}
@defproc[(schemeresultfont [pre-content any/c] ...0) element?]{Like
@scheme[schemefont], but colored as a REPL result.}
@defproc[(schemeidfont [pre-content any/c] ...0) element?]{Like
@scheme[schemefont], but colored as an identifier.}
@defproc[(schemekeywordfont [pre-content any/c] ...0) element?]{Like
@scheme[schemefont], but colored as a syntactic form name.}
@defproc[(procedure [pre-content any/c] ...0) element?]{Typesets the given
content as a procedure name in a REPL result (e.g., in typewrite font
with a @schemefont{#<procedure:} prefix and @schemefont{>} suffix.).}
@defform[(var datum)]{Typesets @scheme[var] as an identifier that is
an argument or sub-form in a procedure being
documented. Normally, the @scheme[defproc] and @scheme[defform]
arrange for @scheme[scheme] to format such identifiers automatically
in the description of the procedure, but use @scheme[var] if that
cannot work for some reason.}
@defform[(svar datum)]{Like @scheme[var], but for subform non-terminals
in a form definition.}
@; ------------------------------------------------------------------------
@section{Definition Reference}
@defform[(defproc (identifier arg-spec ...) result-contract-expr-datum pre-flow ...)]{Produces
a sequence of flow elements (encaptured in a @scheme[splice]) to
document a procedure named @scheme[identifier]. The
@scheme[identifier] is registered so that @scheme[scheme]-typeset uses
of the identifier are hyperlinked to this documentation.
Each @scheme[arg-spec] must have one of the following forms:
@itemize{
@item{@specsubform/inline[(arg-identifier contract-expr-datum)]{---
an argument whose contract is specified by
@scheme[contract-expr-datum] which is typeset via
@scheme[scheme].}}
@item{@specsubform/inline[(arg-identifier contract-expr-datum
default-expr)]{ --- like the previous case, but with a default
value. All arguments with a default value must be grouped
together, but they can be in the middle of required
arguments.}}
@item{@specsubform/inline[(keyword arg-identifier
contract-expr-datum)]{ --- like the first case, but for a
keyword-based argument.}}
@item{@specsubform/inline[(keyword arg-identifier contract-expr-datum
default-expr)]{ --- like the previous case, but with a default
value.}}
@item{@scheme[...0] --- any number of the preceding argument
(normally at the end)}
@item{@scheme[...1] --- one or more of the preceding argument
(normally at the end)}
}
The @scheme[result-contract-expr-datum] is typeset via
@scheme[scheme], and it represents a contract on the procedure's
result.
The @scheme[pre-flow]s list is parsed as a flow that documents the
procedure. In this description, references to @svar[arg-identifier]s
are typeset as procedure arguments.
The typesetting of all data before the @scheme[pre-flow]s ignores the
source layout.}
@defform[(defproc* (((identifier arg-spec ...) result-contract-expr-datum) ...) pre-flow ...)]{Like
@scheme[defproc], but for multiple cases with the same @scheme[identifier].
}
@defform[(defform (identifier . datum) pre-flow ...)]{Produces a
a sequence of flow elements (encaptured in a @scheme[splice]) to
document a syntaic form named by @scheme[identifier]. The
@scheme[identifier] is registered so that @scheme[scheme]-typeset uses
of the identifier are hyperlinked to this documentation.
The @scheme[pre-flow]s list is parsed as a flow that documents the
procedure. In this description, a reference to any identifier in
@scheme[datum] is typeset as a sub-form non-terminal.
The typesetting of @scheme[(identifier . datum)] preserves the source
layout, like @scheme[scheme], and unlike @scheme[defproc].}
@defform[(specsubform/inline datum pre-flow ...)]{Similar to
@scheme[defform], but without any specific identifier being defined,
without the output format that highlights a definition, and with
@scheme[datum] as an element rather than a table. This form is
intended for use when refining the syntax of a non-terminal used in a
@scheme[defform], @scheme[specsubform], or other
@scheme[specsubform/inline]. For example, it is used in the
documentation for @scheme[defproc] in the itemization of possible
shapes for @svar[arg-spec].
The @scheme[pre-flow]s list is parsed as a flow that documents the
procedure. In this description, a reference to any identifier in
@scheme[datum] is typeset as a sub-form non-terminal.}
@defform[(specsubform datum pre-flow ...)]{Like
@scheme[specsubform/inline], but the @scheme[datum] is typeset in the
resulting flow as a table instead of an element.}
@defform[(defthing identifier contract-expr-datum pre-flow ...)]{Like
@scheme[defproc], but for a non-procedure binding.}
@defform[(defstruct struct-name ([field-name contract-expr-datum] ...) pre-flow ...)]{Similar
to @scheme[defform], but for a structure definition.
The @scheme[struct-name] can be either of the following:
@itemize{
@item{@specsubform/inline[identifier]{--- a structure type with no
specified supertype.}}
@item{@specsubform/inline[(identifier super-identifier)]{ --- a structure
type with indicated supertype.}}
}}
@; ------------------------------------------------------------------------
@section{Various String Forms}
@defproc[(defterm [pre-content any/c] ...0) element?]{Typesets the given
content as a defined term (e.g., in italic).}
@defproc[(onscreen [pre-content any/c] ...0) element?]{ Typesets the given
content as a string that appears in a GUI, such as the name of a
button.}
@defproc[(menuitem [menu-name string?] [item-name string?]) element?]{
Typesets the given combination of a GUI's menu and item name.}
@defproc[(file [pre-content any/c] ...0) element?]{Typesets the given content
as a file name (e.g., in typewriter font and in in quotes).}
@defproc[(exec [pre-content any/c] ...0) element?]{Typesets the given content
as a command line (e.g., in typewriter font).}
@; ------------------------------------------------------------------------
@section{Section Links}
@defproc[(secref [tag string?]) element?]{Inserts the hyperlinked
title of the section tagged @scheme[tag].}
@defproc[(seclink [tag string?] [pre-content any/c] ...0) element?]{The content from
@scheme[pre-content] is hyperlinked to the section tagged @scheme[tag].}
@defproc[(schemelink [id symbol?] [pre-content any/c] ...0) element?]{The content from
@scheme[pre-content] is hyperlinked to the definition of @scheme[id].}
@; ------------------------------------------------------------------------
@section{Indexing}
@defproc[(idefterm [pre-content any/c] ...0) element?]{Combines
@scheme[as-index] and @scheme[defterm]. The content normally should be
plurarl, rather than singular.}
@defproc[(pidefterm [pre-content any/c] ...0) element?]{Like
@scheme[idefterm], but plural: adds an ``s'' on the end of the content
for the index entry.}
@; ------------------------------------------------------------------------
@section{Miscellaneous}
@defthing[PLaneT string?]{@scheme["PLaneT"] (to help make sure you get
the letters in the right case).}
@defproc[(void-const) any/c]{Returns @scheme["void"], as opposed to
@scheme[(scheme void)]---but we may eventually find a clearer way to
refer to @void-const in prose.}
@defproc[(centerline [pre-flow any/c] ...0) table?]{Produces a
centered table with the @scheme[pre-flow] parsed by
@scheme[decode-flow].}
@defproc[(commandline [pre-content any/c] ...0) paragraph?]{Produces a
an inset command-line example (e.g., in typewriter font).}

View File

@ -0,0 +1,499 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["../bnf.ss"]
@require["utils.ss"]
@title[#:tag "reader"]{Scribble Reader}
The Scribble @|at|-reader is designed to be a convenient facility for
using free-form text in Scheme code, where ``@at'' is chosen as one of
the least-used characters in Scheme code.
You can use the reader via MzScheme's @schemefont{#reader} form:
@schemeblock[
#, @schemefont[#<<EOS
#reader(lib "reader.ss" "scribble")@{This is free-form text!}
EOS
]
]
Note that the reader will only perform a translation from @at
forms to S-expressions. It not give you any bindings to give meaning
to the S-expression.
A PLT Scheme manual more likely starts with
@schemeblock[
#, @schemefont{#reader(lib "docreader.ss" "scribble")}
]
which installs a reader, wraps the file content afterward into a
MzScheme module, and parses the body into a document using
@file{decode.ss}. See @secref["docreader"] for more information.
Another way to use the reader is to use the @scheme[use-at-readtable]
function to switch the current readtable to a readtable that parses
@at forms. You can do this in a single command line:
@commandline{mzscheme -Le reader.ss scribble "(use-at-readtable)"}
In addition to @scheme[read] and @scheme[read-syntax], which are used
by @schemefont{#reader}, the @file{reader.ss} library provides the
procedures @scheme[read-inside] and @scheme[read-inside-syntax]; these
@schemeid[-inner] variants parse as if starting inside a
@litchar["@{"]...@litchar["}"], and they return a (syntactic) list.
@section{Concrete Syntax}
Informally, the concrete syntax of @|at|-commands is
@schemeblock[
#, @BNF-seq[@litchar["@"] @nonterm{cmd}
@litchar{[} @kleenestar{@nonterm{datum}} @litchar{]}
@litchar["{"] @kleenestar{@nonterm{text-body}} @litchar["}"]]
]
where all three parts after @litchar["@"] are optional, but at least one
should be present. (Since the reader will try to see if there is a
"{...body...}" in the input, it can be awkward to use body-less
constructs on an interactive REPL since reading an expression succeeds
only when there is a new expression available.) In the readtable,
@litchar["@"] is set as a terminating reader macro, so if you want to
use it in Scheme code, you need to quote it as @scheme{\@} or the whole
identifier with @scheme[|ba@rs|]. Of course, @litchar["@"] is not treated
specially in Scheme strings, character constants, etc.
Roughly, a form matching the grammar above is read as
@schemeblock[
(#, @nonterm{cmd} #, @kleenestar{@nonterm{datum}} #, @kleenestar{@nonterm{parsed-body}})
]
where @nonterm{parsed-body} is the translation of each
@nonterm{text-body} in the input.
Thus, the initial @nonterm{cmd} determines the Scheme code that
the input is translated into. The common case is when @nonterm{cmd} is a
Scheme identifier, which generates a plain Scheme form.
A @nonterm{text-body} is either a sequence of characters without
@litchar["@"] or newlines, a newline by itself, or the translation of a
@at form. Note that the syntax for @at forms is the same in a
@nonterm{text-body} context as in a Scheme context. A
@nonterm{text-body} that isn't a @at form is converted to a string for
its @nonterm{parsed-body}:
@scribble-examples[
#<<EOS
@foo{bar baz
blah}
EOS
#f
#<<EOS
@foo{bar @baz[3]
blah}
EOS
#f
#<<EOS
@foo{bar @baz{3}
blah}
EOS
#f
#<<EOS
@foo{bar @baz[2 3]{4 5}
blah}
EOS
]
When the above @at forms appear in a Scheme expression context,
the surrounding context must provide a binding for @scheme[foo]
(either as a procedure or macro). To just see the read result for a
@at form, you can always use Scheme's @scheme[quote]:
@scribble-examples[(list @litchar["'@foo{bar}"] @scheme['(foo "bar")])]
@; - - - - - - - - - - - - - - - - - - - - - - - -
@subsection{The Command Part}
Besides being a Scheme identifier, the @nonterm{cmd} part of an @at
form can have Scheme punctuation prefixes, which will end up wrapping
the @italic{whole} expression.
@scribble-examples[
"@`',@foo{blah}"
]
When writing Scheme code, this means that @litchar["@`',@foo{blah}"]
is exactly the same as @litchar["`@',@foo{blah}"] and
@litchar["`',@@foo{blah}"], but unlike the latter two, the first
construct can appear in body texts with the same meaning, whereas the
other two would not work (see below).
Even after Scheme punctuation, the @nonterm{cmd} itself is not limited
to a Scheme identifier; it can be any Scheme expression.
@scribble-examples[
"@(lambda (x) x){blah}"
]
In addition, the command can be omitted altogether, which will omit it
from the translation, resulting in an S-expression that usually
contains, say, just strings:
@scribble-examples[
#<<EOS
@{foo bar
baz}
EOS
#f
#<<EOS
@'{foo bar
baz}
EOS
]
If the command part begins with a @litchar{;} (with no newline between
the @litchar["@"] and the @litchar{;}), then the construct is a
comment. There are two comment forms, one for arbitrary-text and
possibly nested comments, and another one for line comments:
@schemeblock[
#, @BNF-seq[@litchar["@;"] @kleenestar{@nonterm{whitespace}} @litchar["{"] @kleenestar{@nonterm{any}} @litchar["@"]]
#, @BNF-seq[@litchar["@;"] @kleenestar{@nonterm{anythign-else-without-newline}}]
]
In the first form, the commented body must still parse correctly; see
the description of the body syntax below.
Tip: if you're editing in some Scheme-mode, it is useful to comment out
blocks like this:
@verbatim[#<<EOS
@;
{
...
}
EOS
]
or
@verbatim[#<<EOS
@;{
...
;}
EOS
]
otherwise you will probably confuse the editor into treating the file as
having imbalanced parenthesis.
If only the @nonterm{cmd} part is specified of an @at form, then the
result is the command part only, without an extra set of parenthesis.
This makes it suitable for Scheme escapes in body texts. More below,
in the description of the body part.
Finally, note that there are currently no special rules for using
@litchar["@"] in the command itself, which can lead to things like:
@scribble-examples[
"@@foo{bar}{baz}"
]
You should not rely on such behavior, since @litchar["@@"] might be used
differently in the future (e.g., making @litchar["@@"] be ``@at'' in a
body text).
@subsection{The Datum Part}
The datum part can contains arbitrary Scheme expressions, which
are simply stacked before the body text arguments:
@scribble-examples[
"@foo[1 (* 2 3)]{bar}"
"@foo[@bar{...}]{blah}"
]
@italic{This following is going to be removed, I think...}
But there is one change that makes it easy to use for keyword/values:
@litchar{=} is a terminating character in the textual scope, and it if
there is a @BNF-seq[@nonterm{identifier} @litchar{=} @nonterm{expr}]
sequence (spaces optional), then it is converted to
@schemefont{#:}@nonterm{identifier} @nonterm{expr}.
@scribble-examples[
"@foo[(* 2 3) a=b]{bar}"
]
@subsection{The Body Part}
The syntax of the body part is intended to be as convenient as
possible for writing free text. It can contain almost any text---the
only character with special meaning is @litchar["@"]. In addition,
@litchar["{"], @litchar["}"], @litchar["|"], and @litchar["\\"] can
have special meanings, but only in a few contexts. As described
above, the text turns to a sequence of string arguments for the
resulting form. Spaces at the beginning of lines are discarded (but
see the information about indentation below), and newlines turn to
individual @scheme["\n"] strings. (Spcaces are preserved on a
single-line text.) As part of trying to do the ``right thing,'' an
empty line at the beginning and at the end are discarded, so:
@scribble-examples[
#<<EOS
@foo{
bar
}
EOS
#f
"@foo{bar}"
"@foo{ bar }"
]
If @litchar["@"] appears in a body, then it is interpreted as Scheme
code, which means that the @|at|-reader will be applied recursively,
and the resulting syntax will appear as an argument, among other
string contents.
@scribble-examples[
"@foo{a @bar{b} c}"
]
If the nested @at construct has only a command---no body part---then
it does not appear in a subform. Given that the command part can be
any Scheme expression, this makes @at a general escape to arbitrary
Scheme code.
@scribble-examples[
"@foo{a @bar c}"
"@foo{a @(bar 2) c}"
]
In some cases, you may want to use a Scheme identifier (or a number or
a boolean) in a position that touches other text that can make an
identifier; in these situations you should surround the Scheme
identifier (or number or boolean) by a pair of @litchar["|"]. The
text inside the bars is parsed as a Scheme expression, but if that
fails, it is used as a quoted identifier; do not rely on this
behavior, and avoid using whitespace inside the bars. Also, if bars
are used, then no body text is used even if they are followed by
braces (see the next paragraph).
@scribble-examples[
"@foo{foo @bar foo}"
"@foo{foo@bar.}"
"@foo{foo@|bar|.}"
"@foo{foo@3.}"
"@foo{foo@|3|.}"
"@foo{foo@|(f 1)|{bar}.}"
]
Braces are only problematic because a @litchar["}"] is used to mark
the end of the text. They are therefore allowed, as long as they are
balanced.
@scribble-examples[
"@foo{f{o}o}"]
]
There is also an alternative syntax for the body, one that specifies a
new marker for the end: use @litchar["|{"] for the openning marker,
optionally with additional characters between them (excluding
@litchar["{"], whitespace, and alphanumerics); the matching closing
marker should be the mirrored form of the openning marker (reverse the
characters and swap round, square, curly, and angle parentheses).
@scribble-examples[
"@foo|{...}|"
"@foo|{foo{{{bar}|"
"@foo|<{{foo{{{bar}}>|"
]
More simply, if you get into too much trouble with special characters
in a body, then it's often a good idea to use the Scheme part,
instead.
@scribble-examples[
"@foo[\"}\"]"
"@foo[\"@literally{}\"]"
]
@; - - - - - - - - - - - - - - - - - - - - - - - -
@subsubsub*section{Quoting in Body Texts}
To quote braces or @at, precede them with a backslash. Note that this
is an irregular use of backslash quoting! To use @litchar["\\@"] in
your text, simply precede it with a backslash. The general rule is
that to use N backslashes-and-a-special-character, you should precede
it with one extra backslash. Any other use of a backslash (one that
is not followed by more back-slashes and a special character) is
preserved in the text as usual.
@scribble-examples[
"@foo{b\\@ar}"
"@foo{b\\\\@ar}"
"@foo{b\\\\\\@ar}"
"@foo{b\\{\\@\\@ar}"
"@foo{b\\ar}"
"@foo{b\\\\ar}"
]
@; - - - - - - - - - - - - - - - - - - - - - - - -
@subsubsub*section{Newlines and Indentation}
When indentation is used, all-space indentation string syntaxes are
perpended to the beginning of each line. The rule for adding these
string is:
@itemize{
@item{A spaces-string is added to each line according to its distance from
the leftmost syntax object;}
@item{The first string is not prepended with indentation if it appears on
the first line of output.}
}
@scribble-examples[
#<<EOS
@foo{
bar
baz
bbb}
EOS
#f
#<<EOS
@foo{bar
baz
bbb}
EOS
#f
#<<EOS
@foo{ bar
baz
bbb}
EOS
#f
#<<EOS
@foo{bar
baz
bbb}
EOS
#f
#<<EOS
@foo{ bar
baz
bbb}
EOS
#f
#<<EOS
@foo{ bar
baz
bbb}
EOS
]
Additional notes:
@itemize{
@item{You can identify indentation strings at the syntax level by the fact
that they have the same location information as the following syntax
object.}
@item{This mechanism depends on line and column number information
(@scheme[use-at-readtable] turns them on for the current input port);}
@item{To use this mechanism with nested commands that should preserve
indentation, you will need to do some additional work since the nested
use will have only its own indentation;}
@item{When using it on a command-line, you note that the reader is not aware
of the ``> '' prompt, which might lead to confusing results.}
}
@italic{The following is likely to change.}
For situations where spaces at the beginning of lines matter (various
verbatim environments), you should begin a line with a @litchar["|"].
It has no other special meaning -- so to use a @litchar["|"] as the
first character in the text, simply use another before it.
@scribble-examples[
#<<EOS
@code{
|(define (foo x)
| |error|)
}
EOS
]
In other situations, newlines matter; you might want to avoid a
newline token in some place. To avoid a newline and still break the
source line, use a line comment. As in TeX, these will consume text
up-to and including the end of the line and all following whitespace.
@bold{@italic{The following examples from the original docs didn't
work. They have been changed!}}
@scribble-examples[
#<<EOS
@foo{bar @;
baz@;
!}
EOS
] @bold{The "!" above used to be a "."}
A @litchar["|"] that follows this is still used for marking the
beginning of the text:
@scribble-examples[
#<<EOS
@foo{bar @;
baz@;
? .}
EOS
] @bold{The "?" above used to be a "|", which is surely part of the point.}
@; ------------------------------------------------------------------------
@subsection{How To Use the Reader}
The reader can be used in any way you want. All you need is to use
function names that you bind. You can even use quasi-quotes, skipping
the need for functions, for example:
@verbatim[
#<<EOS
> (define (important . text) @`b{@u{@big{@,@text}}})
> (important @`p{This is an important announcement!
Read it!})
(b (u (big (p "This is an important announcement!" "\n" "Read it!"))))
EOS
]

View File

@ -0,0 +1,31 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@title[#:tag "renderer"]{Renderer}
A renderer is an object that provides two main methods:
@scheme[collect] and @scheme[render]. The first method is called to
collect global information about the document, including information
that spans multiple documents rendered together; the collection pass
tends to be format-independent, and it usually implemented completely
by the base renderer. The latter method generates the actual output,
which is naturally specific to a particular format.
The @file{base-render.ss} module provides @scheme[render%], which
implements the core of a renderer. The @file{html-renderer.ss},
@file{latex-renderer.ss}, and @file{text-renderer.ss} modules each
provide @scheme[renderer-mixin] to extend the base. The
@file{html-renderer.ss} module also provides
@scheme[multi-renderer-mixin] to produce multi-file HTML instead
instead of single-file HTML.
The mixin structure is meant to support document-specific extensions
to the renderers. For example, the @exec{scribble} command-line tool
might, in the future, extract rendering mixins from a document module
(in addition to the document proper).
See @file{base-render.ss} for more information about the methods of
the renderer. Documents built with higher layers, such as
@file{manual.ss}, generally do not call the render object's methods
directly.

View File

@ -0,0 +1,90 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["../bnf.ss"]
@require["utils.ss"]
@title{PLT Scribble}
The @file{scribble} collection provides libraries that can be used to
create documents from Scheme.
@table-of-contents[]
@; ------------------------------------------------------------------------
@section{Scribble Layers}
Scribble is made of independently usable parts. For example, the
Scribble reader can be used in any situation that requires lots of
free-form text. You can also skip Scribble's special reader support,
and instead use the document-generation structure directly.
The layers are:
@itemize{
@item{@file{reader.ss}: a reader that extends the syntax of Scheme
with @at forms for conveniently embedding a mixin of text and
escapes. See @secref["reader"].}
@item{@file{struct.ss}: a set of document datatypes, which define the
basic layout of a document. See @secref["struct"].}
@item{@file{base-render.ss} with @file{html-render.ss},
@file{latex-render.ss}, or @file{text-render.ss}: A base
renderer and mixins that generate documents in various formats
from instances of the @file{struct.ss} datatype. See
@secref["renderer"].}
@item{@file{decode.ss}: Processes a stream of text, section-start
markers, etc. to produce instances of the @file{struct.ss}
datatype. See @secref["decode"].}
@item{@file{doclang.ss}: to be used for the initial import of a
module; processes the module top level through
@file{decode.ss}, and otherwise provides all of
@scheme[mzscheme]. See @secref["doclang"].}
@item{@file{docreader.ss}: a reader that is meant to tbe used to
process an entire file; it essentially combines
@file{reader.ss} with @file{doclang.ss}. See
@secref["docreader"].}
@item{@file{basic.ss}: a library of basic document operators---such
as @scheme[title], @scheme[section], and @scheme[secref]---for
use with @file{decode.ss} and a renderer. See
@secref["basic"].}
@item{@file{scheme.ss}: a library of support functions for
typesetting Scheme code.}
@item{@file{manual.ss}: a library of support functions for writing
PLT Scheme documentation; re-exports @file{basic.ss}. See
@secref["manual"].}
@item{@file{eval.ss}: a library of support functions for ealuating
code at document-build time, especially for showing
examples. See @secref["eval"].}
@item{@file{bnf.ss}: a library of support functions for writing
grammars.}
}
The @exec{scribble} command-line utility works with a module that
exports a @scheme{struct.ss}-based document, generating output with a
specified renderer. More specifically, the executable installs a
renderer, loads the specified modules and extracts the @scheme[doc]
export of each (which must be an instance of @scheme[section] from
@file{struct.ss}), and renders each. Use @exec{scribble -h} for more
information.
@; ------------------------------------------------------------------------
@include-section["reader.scrbl"]
@include-section["struct.scrbl"]
@include-section["renderer.scrbl"]
@include-section["decode.scrbl"]
@include-section["doclang.scrbl"]
@include-section["docreader.scrbl"]
@include-section["basic.scrbl"]
@include-section["manual.scrbl"]
@include-section["eval.scrbl"]

View File

@ -0,0 +1,212 @@
#reader"../docreader.ss"
@require["../manual.ss"]
@require["utils.ss"]
@title[#:tag "struct"]{Document Structures}
A single document is reprsented as a @defterm{part}:
@itemize{
@item{A @defterm{part} is an instance of @scheme[part]; it has a
title @defterm{content}, an initial @defterm{flow}, and a list
of subsection @defterm{part}s. After the ``collect'' phase of
rendering, it also has @defterm{collected info}. An
@scheme[unnumbered-part] is the same as a @scheme[part], but it
isn't numbered.}
@item{A @defterm{flow} is an instance of @scheme[flow]; it has a list
of @defterm{flow element}s.}
@item{A @defterm{flow element} is either a @defterm{table}, an
@defterm{itemization}, @defterm{paragraph}, or a
@defterm{delayed flow element}.
@itemize{
@item{A @defterm{table} is an instance of @scheme[table]; it has a
list of list of @defterm{flow}s with a particular style.}
@item{A @defterm{itemization} is an instance of @scheme[itemization];
it has a list of flows.}
@item{A @defterm{paragraph} is an instance of @scheme[paragraph]; it
has a list of @defterm{element}s.
@itemize{
@item{An element can be a string, one of a few symbols, an instance of
@scheme[element] (possibly @scheme[link-element],
@scheme[target-element], or
@scheme[index-element]), a @defterm{delayed
element}, or anything else allowed by the current
renderer.
@itemize{
@item{A string element is included in the result
document verbatim.}
@item{A symbol element is either @scheme['mdash],
@scheme['ndash], @scheme['ldquo],
@scheme['lsquo], @scheme['rsquo], or
@scheme['rarr]; it is drawn as the
corresponding HTML entity.}
@item{An instance of @scheme[element] has a list of
@defterm{element}s plus a style. The style's
interpretation depends on the rendrer; it can
be one of a few special symbols that are
recognized by all renderers: @scheme['tt],
@scheme['italic], @scheme['bold],
@scheme['sf], @scheme['subscript],
@scheme['superscript], or @scheme['hspace].
A string corresponds to a CSS class, LaTeX
macro, or something else renderer-specific.
Instances of @scheme[target-url] and
@scheme[image-file] may also be supported.}
@item{An instance of @scheme[link-element] has a
@defterm{tag} for the target of the link.}
@item{An instance of @scheme[target-element] has a
@defterm{tag} to be referenced by
@scheme[link-element]s.}
@item{An instance of @scheme[index-element] has a
@defterm{tag} (as a target), a list of
strings for the keywords (for sorting and
search), and a list of @defterm{element}s to
appear in the end-of-document index.}
@item{A @defterm{delayed element} is an instance of
@scheme[delayed-element], which has a
procedure that produces a
@defterm{element}. The ``collect'' phase of
rendering ignores delayed flow elements.}
}}}}
@item{A @defterm{delayed flow element} is an instance of
@scheme[delayed-flow-element], which has a procedure that
produces a @defterm{flow element}. The ``collect'' phase
of rendering ignores delayed flow elements.}
}}
@item{The @defterm{collected info} of a part includes its number, its
parent part (or @scheme[#f]), and information about link
targets and index entries within the part.}
@item{A @defterm{tag} is eiter a string or a list containing a symbol
and a string.}
}
Note that there's no difference between a part and a full document. A
particular source module just as easily defines a subsection
(incoprated via @scheme[include-section]) as a document.
@defstruct[part ([tag (or/c false/c tag?)]
[title-content (or/c false/c list?)]
[collected-info (or/c false/c collected-info?)]
[flow flow?]
[parts (listof part?)])]{
}
@defstruct[(unnumbered-part part) ()]{
}
@defstruct[flow ([paragraphs (listof flow-element?)])]{
}
@defstruct[paragraph ([content list?])]{
}
@defstruct[table ([style any/c]
[flowss (listof (listof flow?))])]{
}
@defstruct[delayed-flow-element ([render (any/c part? any/c . -> . flow-element?)])]{
For the @scheme[render] procedure, the first argument corresponds to
the rendering context, the second to the immediately enclosing
section, and the last argument correspond to global information
(possibly psanning multiple documents).
}
@defstruct[itemization ([flows (listof flow?)])]{
}
@defstruct[element ([style any/c]
[content list?])]{
}
@defstruct[(target-element element) ([tag tag?])]{
}
@defstruct[(link-element element) ([tag any/c]
[complain-if-fail? boolean?])]{
}
@defstruct[(index-element element) ([tag tag?]
[plain-seq (listof string?)]
[entry-seq list?])]{
}
@defstruct[delayed-element ([render (any/c part? any/c . -> . list?)])]{
The @scheme[render] procedure's arguments are the same as for
@scheme[delayed-flow-element]. Unlike @scheme[delayed-flow-element],
the result of the @scheme[render] procedure's argument is remembered
on the first call. Furthemore, the element can be marshelled (e.g.,
for an index entry or a section-title entry) only if it has been
rendered first.
}
@defstruct[collected-info ([number (listof (or/c false/c integer?))]
[parent (or/c false/c part?)]
[info any/c])]{
}
@defproc[(flow-element? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is a @scheme[paragraph],
@scheme[table], @scheme[itemization], or
@scheme[delayed-flow-element], @scheme[#f] otherwise.
}
@defproc[(tag? [v any/c]) boolean?]{
Returns @scheme[#t] if @scheme[v] is acceptable as a link tag,
@scheme[#f], otherwise. Currently, an acceptable tag is either a
string or a list containing a symbol and a string.
}
@defproc[(content->string (content list?)) string?]{
Converts a list of elements to a single string (essentially
rendering the content as ``plain text'').
}

View File

@ -0,0 +1,44 @@
(module utils mzscheme
(require "../struct.ss"
"../manual.ss"
(prefix scheme: "../scheme.ss")
(prefix scribble: "../reader.ss")
(lib "string.ss"))
(provide at
litchar/lines
scribble-examples)
(define at "@")
(define (litchar/lines s)
(let ([strs (regexp-split #rx"\n" s)])
(if (= 1 (length strs))
(litchar s)
(make-table
#f
(map (lambda (s)
(list (make-flow (list (make-paragraph (list (litchar s)))))))
strs)))))
(define (as-flow e)
(make-flow (list (if (flow-element? e)
e
(make-paragraph (list e))))))
(define spacer (hspace 2))
(define (scribble-examples . lines)
(make-table
#f
(map (lambda (line)
(let ([line (if (string? line)
(list (litchar/lines line)
(scheme:to-element (scribble:read (open-input-string line))))
line)])
(list (as-flow spacer)
(as-flow (if line (car line) ""))
(as-flow (if line (make-paragraph (list spacer "reads as" spacer)) ""))
(as-flow (if line (cadr line) "")))))
lines))))