#lang scribble/doc
@(require "common.ss" (prefix-in c: "collatz-doc.ss") scribble/struct
(for-label (only-in scribble/lp chunk)))
@title[#:tag "literate"]{Literate programming}
The techniques used for in-source documentation extend to the creation
of WEB-like literate programming tools. @Figure-ref["Collatz"] shows
an example use of our literate-programming library; the left-hand side
shows a screenshot of DrScheme editing the source code for a short,
literate discussion of the Collatz conjecture, while the right-hand
side shows the rendered output.
In general, literate programs using this library look the same as
other Scribble documents, except that they start with
@code-elem|{#lang scribble/lp}| and use @scheme[chunk] to introduces a
chunk of an implementation. A use of @scheme[chunk] consists of a name
followed by definitions and/or expressions:
@code-block|{
@chunk[
... definitions ...
... expressions ...]
}|
The definitions and expressions in a chunk can refer to other chunks
by their names.
Unlike a normal Scribble program, running a
@schememodname[scribble/lp] program ignores the prose exposition and
instead evaluates the chunks, also known as @defterm{tangled} program
in literate programming terminology. Thus, to a client module, a
literate program behaves just like its illiterate variant. The
compiled form of a literate program in does not contain any of the
documentation, nor does it depend on the runtime support for Scribble,
to the literate implementation suffers no overhead due to the prose.
To recover the prose, a @code-block|{@lp-include[_filename]}| form
extracts a literate view of the program in @scheme[_filename], also
known as @defterm{weaving} the program in literate programming
terminology. The right-hand side of @Figure-ref["Collatz"] shows the
woven version of the code in the screenshot.
As with all of Scribble's libraries, literate programs in Scribble
support ordinary lexical scoping. One advantage of this is that tools
like Check Syntax work properly, meaning that the arrows in
@Figure-ref["Collatz"] correctly connect bound and binding occurrences
of the same identifier, without any work on the part of the author of
Scribble's literate programming library. Even better, the literate
programming language is extensible through additional macros and
libraries.
@;{ Literate programming Scribble is, for now, restricted to languages
that use S-expressions in order to make chunk parsing straightforward,
but given PLT Scheme's flexibility, we expect that we could generalize
the parsing of Literate programs to support other languages easily, if
the need arises. }
To gain some experience with non-trivial literate programming in
Scribble, we have written a 34-page literate program that describes
our implementation of the Chat Noir game. The literate rendering of
the implementation is available at
@show-link{http://docs.plt-scheme.org/games/chat-noir.html}, and the
source is available at
@show-link{http://svn.plt-scheme.org/plt/trunk/collects/games/chat-noir/chat-noir-literate.ss}).
@(figure**
"Collatz"
"Literate Programming Example"
(make-table
'((row-styles . ([#;(valignment . (top top)) (style . ("Half" "Half"))])))
(list
(list (make-flow (list (make-paragraph (list "")) (make-paragraph (list (image #:scale .6 "collatz.png")))))
(make-flow (list (lp-minipage (make-splice (flow-paragraphs (part-flow c:doc))))))))))