#lang scribble/doc
@(require scribble/manual scribble/bnf "utils.rkt")

@title[#:tag "layers"]{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.

@; ----------------------------------------------------------------------

@section{Typical Composition}

A Scribble document normally starts

@racketmod[
scribble/manual
]

but it could also start

@racketmod[
scribble/base
]

or

@racketmod[
scribble/doc
]

The last one introduces the smallest number of typesetting bindings in
the document body. Using @racketmodname[scribble/base] after
@hash-lang[] is the same as using @racketmodname[scribble/doc] plus
@racket[(require scribble/base)], and using
@racketmodname[scribble/manual] after @hash-lang[] is the same as using
@racketmodname[scribble/doc] plus @racket[(require scribble/manual)].

Besides making the file a module, each of the @hash-lang[]
declarations selects the Scribble reader (instead of the usual Racket
reader), and it starts the body of the file in ``text'' mode. The
reader layer mostly leaves text alone, but @tech{@"@"-forms} escape
to S-expression mode.

A module written as

@verbatim[#:indent 2]|{
  #lang scribble/doc
  @(require scribble/manual)

  @(define to-be "To Be")

  @title{@|to-be| or Not @|to-be|}

  @bold{That} is the question.
  Whether 'tis nobler...
}|

reads as

@racketblock[
(module #,(nonterm "name") scribble/doc
  (require scribble/manual)
  "\n"
  (define to-be "To Be") "\n"
  "\n"
  (title to-be " or Not " to-be) "\n"
  "\n"
  (bold "That") " is the question." "\n"
  "Whether 'tis nobler..." "\n")
]

As shown in this example, the read result is a module whose content
mingles text and definitions. The @racketmodname[scribble/doc]
language lifts definitions, @racket[require]s, and @racket[provide]s
to the beginning of the module, while everything else is collected
into a document bound to the provided identifier @racket[doc].  That
is, the module is transformed to something like this:

@racketblock[
(module #,(nonterm "name") racket/base
  (require scribble/decode
           scribble/manual)
  (define to-be "To Be")
  (define doc
    (decode
     "\n" "\n" "\n"
     (title to-be " or Not " to-be) "\n"
     "\n"
     (bold "That") " is the question." "\n"
     "Whether 'tis nobler..." "\n"))
  (provide doc))
]

The @racket[decode] function produces a @racket[part] structure
instance that represents the document. To build the @racket[part]
instance, it inspects its arguments to find a @racket[title-decl]
value created by @racket[title] to name the part, @racket[part-start]
values created by @racket[section] to designate sub-parts, etc.

A @racket[part] is the input to a rendering back-end, such as the HTML
renderer. All renderers recognize a fixed structure hierarchy: the
content of a part is a @defterm{flow}, which is a sequence of
@defterm{flow elements}, such as paragraphs and tables; a table, in
turn, consists of a list of list of flows; a paragraph is a list of
@defterm{elements}, which can be instances of the @racket[element]
structure type, plain strings, or certain special symbols.

The value bound to @racket[doc] in the example above is something like

@racketblock[
(make-part ....
           (list "To Be" " or Not " "To Be") (code:comment "title")
           ....
           (make-flow
             (list
              (make-paragraph
               (list (make-element 'bold (list "That"))
                     " is the question." "\n"
                     "Whether " 'rsquo "tis nobler..."))))
           ....)
]

Notice that the @litchar{'} in the input's @litchar{'tis} has turned
into @racket['rsquo] (rendered as a curly apostrophe). The conversion to use
@racket['rsquo] was performed by @racket[decode] via
@racket[decode-flow] via @racket[decode-paragraph] via
@racket[decode-content] via @racket[decode-string].

In contrast, @racket[(make-element 'bold (list "That"))] was produced
by the @racket[bold] function.  The @racket[decode] operation is a
function, not a syntactic form, and so @racket[bold] has control over
its argument before @racket[decode] sees the result. Also, decoding
traverses only immediate string arguments.

As it turns out, @racket[bold] also decodes its argument, because the
@racket[bold] function is implemented as

@racketblock[
(define (bold . strs)
  (make-element 'bold (decode-content strs)))
]

The @racket[verbatim] function, however, does not decode its content,
and instead typesets its text arguments directly.

A document module can construct elements directly using
@racket[make-element], but normally functions like @racket[bold] and
@racket[verbatim] are used to construct them. In particular, the
@racketmodname[scribble/manual] library provides many functions and
forms to typeset elements and flow elements.

The @racket[part] structure hierarchy includes built-in element types
for setting hyperlink targets and references. Again, this machinery is
normally packaged into higher-level functions and forms, such as
@racket[secref], @racket[defproc], and @racket[racket].

@; ----------------------------------------------------------------------

@section{Layer Roadmap}

Working roughly from the bottom up, the Scribble layers are:

@itemize[

 @item{@racketmodname[scribble/reader]: A reader that extends the
       syntax of Racket with @tech{@"@"-forms} for conveniently embedding a
       mixin of text and escapes. See @secref["reader"].}

 @item{@racketmodname[scribble/core]: A set of document datatypes
       and utilities that define the basic layout and processing of a
       document. For example, the @racket[part] datatype is defined in
       this layer. See @secref["core"].}

 @item{@racketmodname[scribble/base-render] with
       @racketmodname[scribble/html-render],
       @racketmodname[scribble/latex-render], or
       @racketmodname[scribble/text-render]: A base renderer and
       mixins that generate documents in various formats from
       instances of the @racketmodname[scribble/struct] datatypes. See
       @secref["renderer"].}

 @item{@racketmodname[scribble/decode]: Processes a stream of text,
       section-start markers, etc. to produce instances of the
       @racketmodname[scribble/core] datatypes. See
       @secref["decode"].}

 @item{@racketmodname[scribble/doclang]: A language to be used for the
       initial import of a module; processes the module top level
       through @racketmodname[scribble/decode], and otherwise provides
       all of @racketmodname[racket/base].  See @secref["doclang"].}

 @item{@racketmodname[scribble/doc]: A language that combines
       @racketmodname[scribble/reader] with
       @racketmodname[scribble/doclang]. See @secref["docreader"].}

 @item{@racketmodname[scribble/base]: A library of basic document
       operators---such as @racket[title], @racket[section], and
       @racket[secref]---for use with @racketmodname[scribble/decode]
       and a renderer. This library name also can be used as a
       language, where it combines @racketmodname[scribble/doc] with
       the exports of @racketmodname[scribble/base]. See
       @secref["base"].}

 @item{@racketmodname[scribble/racket]: A library of functions for
       typesetting Racket code. See @secref["scheme"]. These functions
       are not normally used directly, but instead used through
       @racketmodname[scribble/manual].}

 @item{@racketmodname[scribble/manual]: A library of functions for
       writing Racket documentation; re-exports
       @racketmodname[scribble/base]. Also, the
       @racketmodname[scribble/manual-struct] library provides types
       for index-entry descriptions created by functions in
       @racketmodname[scribble/manual]. See @secref["manual"].}

 @item{@racketmodname[scribble/eval]: A library of functions for
       evaluating code at document-build time, especially for showing
       examples. See @secref["eval"].}

 @item{@racketmodname[scribble/bnf]: A library of support functions
       for writing grammars. See @secref["bnf"].}

 @item{@racketmodname[scribble/xref]: A library of support functions
       for using cross-reference information, typically after a
       document is rendered (e.g., to search). See @secref["xref"].}

 @item{@racketmodname[scribble/text]: A language that uses
       @racketmodname[scribble/reader] preprocessing text files.}

]

The @exec{scribble} command-line utility generates output with a
specified renderer. More specifically, the executable installs a
renderer, loads the modules specified on the command line, extracts
the @racket[doc] export of each module (which must be an instance of
@racket[part]), and renders each---potentially with links that span
documents.
