382 lines
13 KiB
Racket
382 lines
13 KiB
Racket
#lang scribble/doc
|
|
@(require scribble/manual scribble/bnf "utils.rkt")
|
|
|
|
@(define pkg-doc '(lib "pkg/scribblings/pkg.scrbl"))
|
|
|
|
@title[#:tag "how-to-doc"]{Getting Started with Documentation}
|
|
|
|
Although the @exec{scribble} command-line utility generates output
|
|
from a Scribble document, documentation of Racket libraries is
|
|
normally built by @exec{raco setup}. This chapter emphasizes the
|
|
@exec{raco setup} approach, which more automatically supports links
|
|
across documents.
|
|
|
|
@margin-note{See @secref["getting-started"] for information on using the
|
|
@exec{scribble} command-line utility.}
|
|
|
|
@;----------------------------------------
|
|
@section[#:tag "setting-up"]{Setting Up Library Documentation}
|
|
|
|
To document a collection, including a collection implemented by a
|
|
@seclink["getting-started" #:doc pkg-doc]{package}:
|
|
|
|
@itemize[
|
|
|
|
@item{Create a file in your collection with the
|
|
file extension @filepath{.scrbl}. Beware that the file name
|
|
you choose will determine the output directory's name, and
|
|
the directory name must be unique across all installed documents. The
|
|
remainder of these instructions assume that the file is called
|
|
@filepath{manual.scrbl} (but pick a more specific name in practice).}
|
|
|
|
@item{Start @filepath{manual.scrbl} like this:
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
|
|
@title{My Library}
|
|
|
|
Welcome to my documentation: @racket[(list 'testing 1 2 3)].
|
|
}|
|
|
|
|
The first line starts the file in ``text'' mode and selects
|
|
the Racket manual output format.
|
|
It also introduces bindings like @racket[title] and
|
|
@racket[racket] for writing Racket documentation.}
|
|
|
|
@item{Add the following entry to your collection's
|
|
@filepath{info.rkt}:
|
|
|
|
@racketblock[
|
|
(define scribblings '(("manual.scrbl" ())))
|
|
]
|
|
|
|
The @racket[()] above is a list of options. When your document
|
|
gets large enough that you want it split into multiple pages,
|
|
add the @racket['multi-page] option (omitting the quote, since
|
|
the whole right-hand side of the definition is already
|
|
quoted).
|
|
|
|
If you do not already have an @filepath{info.rkt} module,
|
|
here's a suitable complete module:
|
|
|
|
@racketmod[
|
|
info
|
|
(define scribblings '(("manual.scrbl" ())))
|
|
]}
|
|
|
|
@item{Run @exec{raco setup} to build your documentation. For a
|
|
collection, optionally supply @Flag{l} followed by the
|
|
collection name to limit the build process to that
|
|
collection.}
|
|
|
|
@item{For a collection that is installed as user-specific
|
|
(e.g., the user @tech[#:doc pkg-doc]{package scope}), the generated
|
|
documentation is @filepath{doc/manual/index.html} within the
|
|
collection directory. If the collection is installation-wide,
|
|
however, then the documentation
|
|
is generated as @filepath{manual/index.html} in the
|
|
installation's @filepath{doc} directory.}
|
|
|
|
]
|
|
|
|
@; ----------------------------------------
|
|
@section[#:tag "racket-hyperlinks"]{Racket Typesetting and Hyperlinks}
|
|
|
|
In the document source at the start of this chapter
|
|
(@secref["setting-up"]), the Racket expression
|
|
@racket[(#,(racketidfont "list") 'testing 1 2 3)] is typeset properly,
|
|
but the @racketidfont{list} identifier is not hyperlinked to the usual
|
|
definition. To cause @racketidfont{list} to be hyperlinked, add a
|
|
@racket[require] form like this:
|
|
|
|
@codeblock[#:keep-lang-line? #f]|{
|
|
#lang scribble/base
|
|
@(require (for-label racket))
|
|
}|
|
|
|
|
This @racket[require] with @racket[for-label] declaration introduces a
|
|
document-time binding for each export of the @racketmodname[racket]
|
|
module. When the document is built, the @racket[racket] form detects
|
|
the binding for @racket[list], and so it generates a reference to the
|
|
specification of @racket[list]. The setup process detects the
|
|
reference, and it finds the matching specification in the existing
|
|
documentation, and ultimately directs the hyperlink to that
|
|
specification.
|
|
|
|
Hyperlinks based on @racket[for-label] and @racket[racket] are the
|
|
preferred mechanism for linking to information outside of a single
|
|
document. Such links require no information about where and how a
|
|
binding is documented elsewhere:
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
@(require (for-label racket))
|
|
|
|
@title{My Library}
|
|
|
|
See also @racket[list].
|
|
}|
|
|
|
|
The @racket[racket] form typesets a Racket expression for inline text,
|
|
so it ignores the source formatting of the expression. The
|
|
@racket[racketblock] form, in contrast, typesets inset Racket code,
|
|
and it preserves the expression's formatting from the document source.
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
@(require (for-label racket))
|
|
|
|
@title{My Library}
|
|
|
|
Some example Racket code:
|
|
|
|
@racketblock[
|
|
(define (nobody-understands-me what)
|
|
(list "When I think of all the"
|
|
what
|
|
"I've tried so hard to explain!"))
|
|
(nobody-understands-me "glorble snop")
|
|
]
|
|
}|
|
|
|
|
|
|
@; ----------------------------------------
|
|
@section[#:tag "section-hyperlinks"]{Section Hyperlinks}
|
|
|
|
A @racket[section] declaration in a document can include a
|
|
@racket[#:tag] argument that declares a hyperlink-target tag. The
|
|
@racket[secref] function generates a hyperlink, using the section name
|
|
as the text of the hyperlink. Use @racket[seclink] to create a
|
|
hyperlink with text other than the section title.
|
|
|
|
The following example illustrates section hyperlinks:
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
@(require (for-label racket))
|
|
|
|
|
|
@title{My Library}
|
|
|
|
Welcome to my documentation: @racket[(list 'testing 1 2 3)].
|
|
|
|
@table-of-contents[]
|
|
|
|
|
|
@section[#:tag "chickens"]{Philadelphia Chickens}
|
|
|
|
Dancing tonight!
|
|
|
|
|
|
@section{Reprise}
|
|
|
|
See @secref{chickens}.
|
|
}|
|
|
|
|
Since the page is so short, the hyperlinks in the above example are
|
|
more effective if you change the @filepath{info.rkt} file to add the
|
|
@racket['multi-page] flag:
|
|
|
|
@racketblock[
|
|
(define scribblings '(("manual.scrbl" (multi-page))))
|
|
]
|
|
|
|
A section can have a @techlink{tag prefix} that applies to all tags as
|
|
seen from outside the section. Such a prefix is automatically given to
|
|
each top-level document as processed by @exec{raco setup}. Thus,
|
|
referencing a section tag in a different document requires using a
|
|
prefix, which is based on the target document's main source file. The
|
|
following example links to a section in the Racket reference
|
|
manual:
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
@(require (for-label racket))
|
|
@(define ref-src
|
|
'(lib "scribblings/reference/reference.scrbl"))
|
|
|
|
@title{My Library}
|
|
|
|
See also @italic{@secref[#:doc ref-src]{pairs}}.
|
|
}|
|
|
|
|
As mentioned in @secref{racket-hyperlinks}, however, cross-document
|
|
references based on @racket[(require (for-label ....))] and
|
|
@racket[racket] are usually better than cross-document references
|
|
using @racket[secref].
|
|
|
|
@; ----------------------------------------
|
|
@section{Defining Racket Bindings}
|
|
|
|
Use @racket[defproc] to document a procedure, @racket[defform] to
|
|
document a syntactic form, @racket[defstruct] to document a structure
|
|
type, etc. These forms provide consistent formatting of definitions,
|
|
and they declare hyperlink targets for @racket[racket]-based
|
|
hyperlinks.
|
|
|
|
To document a @racket[my-helper] procedure that is exported by
|
|
@filepath{helper.rkt} in the @filepath{my-lib} collection that contains
|
|
@filepath{manual.scrbl}:
|
|
|
|
@itemize[
|
|
|
|
@item{Use @racket[(require (for-label "helper.rkt"))] to import the
|
|
binding information about the bindings of @filepath{helper.rkt}
|
|
for use when typesetting identifiers. A relative reference
|
|
@racket["helper.rkt"] works since it is relative to the
|
|
documentation source.}
|
|
|
|
@item{Add a @tt|{@defmodule[my-lib/helper]}| declaration, which
|
|
specifies the library that is being documented within the
|
|
section. The @racket[defmodule] form needs an absolute module
|
|
name @racket[mylib/helper], instead of a relative reference
|
|
@racket["helper.rkt"], since the module path given to
|
|
@racket[defmodule] appears verbatim in the generated
|
|
documentation.}
|
|
|
|
@item{Use @racket[defproc] to document the procedure.}
|
|
|
|
]
|
|
|
|
Adding these pieces to @filepath{manual.scrbl} gives us the
|
|
following:
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
@(require (for-label racket
|
|
"helper.rkt"))
|
|
|
|
@title{My Library}
|
|
|
|
@defmodule[my-lib/helper]
|
|
|
|
@defproc[(my-helper [lst list?])
|
|
(listof
|
|
(not/c (one-of/c 'cow)))]{
|
|
|
|
Replaces each @racket['cow] in @racket[lst] with
|
|
@racket['aardvark].}
|
|
}|
|
|
|
|
In @racket[defproc], a contract is specified with each argument to the
|
|
procedure. In this example, the contract for the @racket[_lst]
|
|
argument is @racket[list?], which is the contract for a list. After
|
|
the closing parenthesis that ends the argument sequence, the contract
|
|
of the result must be given; in this case, @racket[my-helper]
|
|
guarantees a result that is a list where none of the elements are
|
|
@racket['cow].
|
|
|
|
Some things to notice in this example and the documentation that it
|
|
generates:
|
|
|
|
@itemize[
|
|
|
|
@item{The @racket[list?], @racket[listof], @|etc| elements of
|
|
contracts are hyperlinked to their documentation.}
|
|
|
|
@item{The result contract is formatted in the generated documentation
|
|
in the same way as in the source. That is, the source layout of
|
|
contracts is preserved. (In this case, putting the contract all
|
|
on one line would be better.)}
|
|
|
|
@item{In the prose that documents @racket[my-helper], @racket[_lst]
|
|
is automatically typeset in italic, matching the typesetting in
|
|
the blue box. The @racket[racket] form essentially knows that
|
|
it's used in the scope of a procedure with argument
|
|
@racket[_lst].}
|
|
|
|
@item{If you hover the mouse pointer over @racket[my-helper], a popup
|
|
reports that it is provided from @racketidfont{my-lib/helper}.}
|
|
|
|
@item{If you use @racket[my-helper] in any documentation now, as long
|
|
as that documentation source also has a @racket[(require
|
|
(for-label ....))] of @filepath{helper.rkt}, then the
|
|
reference is hyperlinked to the definition above.}
|
|
|
|
]
|
|
|
|
See @racket[defproc*], @racket[defform], @|etc| for more information
|
|
on forms to document Racket bindings.
|
|
|
|
@; ----------------------------------------
|
|
@section{Showing Racket Examples}
|
|
|
|
The @racket[examples] form from @racket[scribble/eval] helps you
|
|
generate examples in your documentation. To use @racket[examples], the
|
|
procedures to document must be suitable for use at documentation time,
|
|
but the @racket[examples] form does not use any binding introduced
|
|
into the document source by @racket[require]. Instead, create a new
|
|
evaluator with its own namespace using @racket[make-base-eval], and
|
|
use @racket[interaction-eval] to require @filepath{helper.rkt} in that
|
|
evaluator. Finally, supply the same evaluator to @racket[examples]:
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
@(require scribble/eval
|
|
(for-label racket
|
|
"helper.rkt"))
|
|
|
|
@title{My Library}
|
|
|
|
@defmodule[my-lib/helper]
|
|
|
|
@defproc[(my-helper [lst list?])
|
|
(listof
|
|
(not/c (one-of/c 'cow)))]{
|
|
Replaces each @racket['cow] in @racket[lst] with
|
|
@racket['aardvark].
|
|
|
|
@(define helper-eval (make-base-eval))
|
|
@interaction-eval[#:eval helper-eval
|
|
(require "helper.rkt")]
|
|
@examples[
|
|
#:eval helper-eval
|
|
(my-helper '())
|
|
(my-helper '(cows such remarkable cows))
|
|
]}
|
|
}|
|
|
|
|
@;----------------------------------------
|
|
@section{Multi-Page Sections}
|
|
|
|
Setting the @racket['multi-page] option (see
|
|
@secref["section-hyperlinks"]) causes each top-level section of a
|
|
document to be rendered as a separate HTML page.
|
|
|
|
To push sub-sections onto separate pages, use the @racket['toc] style
|
|
for the enclosing section (as started by @racket[title],
|
|
@racket[section], @racket[subsection], etc.) and use
|
|
@racket[local-table-of-contents] to generate hyperlinks to the
|
|
sub-sections.
|
|
|
|
Revising @filepath{cows.scrbl} from the previous section:
|
|
|
|
@codeblock|{
|
|
#lang scribble/manual
|
|
|
|
@title[#:style '(toc)]{Cows}
|
|
|
|
@local-table-of-contents[]
|
|
|
|
@section[#:tag "singing"]{Singing}
|
|
Wherever they go, it's a quite a show.
|
|
|
|
@section{Dancing}
|
|
See @secref["singing"].
|
|
}|
|
|
|
|
To run this example, remember to change @filepath{info.rkt} to add the
|
|
@racket['multi-page] style. You may also want to add a call to
|
|
@racket[table-of-contents] in @filepath{manual.scrbl}.
|
|
|
|
The difference between @racket[table-of-contents] and
|
|
@racket[local-table-of-contents] is that the latter is ignored for
|
|
Latex output.
|
|
|
|
When using @racket[local-table-of-contents], it often makes sense to
|
|
include introductory text before the call of
|
|
@racket[local-table-of-contents]. When the introductory text is less
|
|
important and when local table of contents is short, putting the
|
|
introductory text after the call of @racket[local-table-of-contents]
|
|
may be appropriate.
|