bkyk8rc3zvpnsf5inmcqq4n3k98cv6hj-my-site-hyper-literate-git.test.suzanne.soy-0.0.1

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit d893680ac26bdf13e60f6fef9966632aaf477ddc
parent 9b7993ea02d8f90f176e6305e8e1e7e46f5d4384
Author: Matthew Flatt <mflatt@racket-lang.org>
Date:   Thu, 24 May 2007 02:20:28 +0000

new documentation source moved to the trunk collects

svn: r6249

original commit: 858c8024efa41ebfdb5f05383c70be5412448570

Diffstat:
Acollects/scribblings/scribble/basic.scrbl | 151+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/decode.scrbl | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/doclang.scrbl | 18++++++++++++++++++
Acollects/scribblings/scribble/docreader.scrbl | 13+++++++++++++
Acollects/scribblings/scribble/eval.scrbl | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/manual.scrbl | 328+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/reader.scrbl | 499+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/renderer.scrbl | 31+++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/scribble.scrbl | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/struct.scrbl | 212+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acollects/scribblings/scribble/utils.ss | 44++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 1553 insertions(+), 0 deletions(-)

diff --git a/collects/scribblings/scribble/basic.scrbl b/collects/scribblings/scribble/basic.scrbl @@ -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. +} diff --git a/collects/scribblings/scribble/decode.scrbl b/collects/scribblings/scribble/decode.scrbl @@ -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]. + +} + diff --git a/collects/scribblings/scribble/doclang.scrbl b/collects/scribblings/scribble/doclang.scrbl @@ -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. diff --git a/collects/scribblings/scribble/docreader.scrbl b/collects/scribblings/scribble/docreader.scrbl @@ -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. diff --git a/collects/scribblings/scribble/eval.scrbl b/collects/scribblings/scribble/eval.scrbl @@ -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.} diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl @@ -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).} diff --git a/collects/scribblings/scribble/reader.scrbl b/collects/scribblings/scribble/reader.scrbl @@ -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 +] diff --git a/collects/scribblings/scribble/renderer.scrbl b/collects/scribblings/scribble/renderer.scrbl @@ -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. diff --git a/collects/scribblings/scribble/scribble.scrbl b/collects/scribblings/scribble/scribble.scrbl @@ -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"] diff --git a/collects/scribblings/scribble/struct.scrbl b/collects/scribblings/scribble/struct.scrbl @@ -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''). + +} + diff --git a/collects/scribblings/scribble/utils.ss b/collects/scribblings/scribble/utils.ss @@ -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))))