Using Scribble Programatically
Danny Yoo <dyoo@hashcollision.org>
There are times when generating Scribble documentation through the command line option doesn’t provide fine-enough control over the output. This quick guide shows how to generate Scribble documents programmatically through pure Racket.
"hello.scrbl"
#lang scribble/base Hello @emph{beautiful} world!
> (define my-doc (dynamic-require "hello.scrbl" 'doc))
> my-doc
(part
#f
(list (list 'part (generated-tag)))
#f
(style #f '())
'()
(list
(paragraph
(style #f '())
(list "Hello " (element 'italic '("beautiful")) " world!")))
'())
> (require scribble/core)
> (require scribble/base)
> (part-blocks my-doc)
(list
(paragraph
(style #f '())
(list "Hello " (element 'italic '("beautiful")) " world!")))
Subtle: note that, for this particular example, we also rip out the existing tags associated to the document. Scribble uses tags to represent data such as cross-referencing between documents. If we try to generate documentation simultaneously for my-doc and my-updated-doc, Scribble will get rightfully confused. As an exercise, preserve the existing tags and try to render both documents at once: you should see warnings.
> (define my-updated-doc (struct-copy part my-doc [tags (list)] [blocks (append (part-blocks my-doc) (list (para "Here's something we added")))]))
The most common operation we can perform on a part is to render it. Let’s render the original document as well as our updated version of the document:
> (require scribble/render)
> (render (list my-doc my-updated-doc) (list "hello.scrbl" "updated-hello.scrbl"))
Ok, that was quiet. What just happened?
By default, the renderer generates HTML text, using filenames based on the second list of paths we pass to render. In this case, it wrote out to "hello.html" and "updated-hello.html" in the current directory. render also writes out auxiliary files, such as "scribble.css", in the current directory too.
Don’t try to control current-directory directly, as Scribble itself can muck with it throughout the rendering process.
> (render #:dest-dir "dest" (list my-doc my-updated-doc) (list "hello.scrbl" "updated-hello.scrbl"))
> (directory-list "dest")
'(#<path:hello.html>
#<path:scribble-common.js>
#<path:scribble-style.css>
#<path:scribble.css>
#<path:updated-hello.html>)