#lang scribble/doc @(require "common.ss") @title[#:tag "struct"]{Document Structure} As with most typesetting tools, a Scribble document is meant to be independent of its rendered form (HTML, PDF, etc.), and Scribble's plug-in architecture accommodates new rendering back-ends. Also like many tools, Scribble defers detailed typesetting work to @|latex| or to HTML browsers, so that Scribble's documentation abstraction reflects a least-common denominator among such document formats. For example, Scribble has a baked-in notion of itemization, since @|latex|, HTML, and other document formats provide specific support to typeset itemizations. For many other layout tasks, such as formatting Scheme code, Scribble documents fall back to encoding layout through a generic ``table'' abstraction. Similarly, Scribble itself resolves most forms of cross-references and document dependencies, since different formats provide different levels of automatic support; tables of contents and indexes are mostly built within Scribble, instead of left to the back-end. Overall, this part of Scribble closely resembles Skribe@~cite["Skribe"]. A Scribble document is a program that generates an instance of a @scheme[part] structure type. A @scheme[part] can represent a section or a book, and it can have sub-@scheme[part]s that represent sub-sections or chapters. This paper, for example, is generated by a Scribble document whose resulting @scheme[part] represents the whole paper, and it contains sub-@scheme[part]s for individual sections. The @scheme[part] produced by a Scheme document for a reference manual is rendered as a book, where the immediate sub-@scheme[part]s are chapters. Each @scheme[part] also has a @deftech{flow} that is typeset before its sub-@scheme[part]s (if any), and that represents the main content of a section. A flow is a list of @deftech{blocks}, where each block is one of the following: @itemize[ @item{A @scheme[paragraph], which contains a list of @tech{elements} that are typeset inline with automatic line breaks.} @item{A @scheme[table], which contains a list of rows; each row is a list of flows, one for each cell in the table.} @item{An @scheme[itemization], which contains a list of flows, one for each item.} @item{A @scheme[blockquote], which contains a single flow that is typically typeset with more indentation than its surrounding flow.} @item{A @scheme[delayed-block], which eventually expands to another block, typically using information gathered elsewhere in the document. For example, a @scheme[delayed-block] is used to implement a table of contents.} ] A Scribble document can construct other kinds of blocks that are implemented in terms of the above built-in kinds. For example, a @scheme[defproc] block that describes a procedure is implemented in terms of a @scheme[table]. An @deftech{element} within a paragraph can be any of the following: @itemize[ @item{A plain string.} @item{An instance of the @scheme[element] structure type, which wraps a list of elements with a typesetting style, such as @scheme['bold], whose detailed interpretation depends on the back-end format.} @item{A @scheme[target-element], which associates a cross-reference tag with a list of elements. The typeset elements are the target for cross-references using the tag.} @item{A @scheme[link-element], which associates a cross-reference tag to a list of elements. The tag designates a cross-reference from the elements to elsewhere in the document (which is rendered in HTML as a hyperlink from the elements).} @item{A @scheme[delayed-element] eventually expands to a list of elements. Like a @scheme[delayed-block], it typically generates the elements using information gathered from elsewhere in the document. A @scheme[delayed-element] often generates a @scheme[link-element] after it locates a suitable target for cross-referencing.} @item{A @scheme[collect-element] is the complement of @scheme[delayed-element]: it includes an immediate list of elements, but also a procedure to record information that might be used elsewhere in the document. A @scheme[collect-element] often includes a @scheme[target-element], in which case its procedure might register the target's cross-reference tag for discovery by @scheme[delayed-element] instances.} ] A document as represented by a @scheme[part] instance is an immutable value. This value is transformed in several passes to eliminate @scheme[delayed-block], @scheme[delayed-element], and @scheme[collect-element] instances. The result is a @scheme[part] instance and associated cross-reference information. The @scheme[part] instance is consumed by a rendering back-end, and the cross-reference information may be saved for building separate documents that cross-reference the rendered one. Currently, a document is transformed in two passes: a @defterm{collect} pass that collects information about the document (e.g., though @scheme[collect-element]s), and a @defterm{resolve} pass that turns delayed blocks and elements into normal elements. A consequence of this separation is that a delayed block or element cannot generate new cross-reference targets. This constraint has created no trouble so far, but we will probably generalize Scribble to support arbitrarily many passes, as in Skribe. Another direction for improvement is in the definition of styles that are attached to @scheme[element]s and that can also be attached to @scheme[paragraph]s, @scheme[table]s, @scheme[itemization]s, and @scheme[blockquote]s. Currently, a fixed set of styles are supported by all back-ends, but the set should be extensible by a document author who is willing to provide the appropriate glue for each relevant back-end: a CSS fragment for HTML rendering, a set of macros for @|latex| rendering, and so on. Limited configuration is currently available when rendering a whole document, in that a specific CSS file or @|latex| prefix can be supplied when generating the document, but such extensions should be attached to the document fragments that use them, instead of the rendering command.