1 Getting Started
No matter what you want to do with Scribble, it’s best to start by generating a few simple HTML and/or PDF documents. This chapter steps you through the basics.
1.1 A First Example
Create a file "mouse.scrbl" with this content:
@title{On the Cookie-Eating Habits of Mice}
If you give a mouse a cookie, he's going to ask for a
glass of milk.
The first line’s #lang rhombus/scribble indicates that the file implements a Rhombus Scribble document. The document starts in “text mode,” and the @ character escapes to functions like title, where the curly braces return to text mode for the arguments to the function. The rest is document content.
Now run the scribble command-line program, specifying a mode for the kind of document that you want as output:
Run
scribble mouse.scrbl
to generate HTML as "mouse.html". You may notice that the apostrophe in “he’s” turned into a curly apostrophe.
Run
scribble --htmls mouse.scrbl
to generate HTML as "mouse/index.html". Sub-sections (which we add next) will appear as separate HTML files in the "mouse" directory.
Run
scribble --pdf mouse.scrbl
to generate PDF as "mouse.pdf". This will work only if you have pdflatex installed. If you’d like to see the intermediate Latex, try
scribble --latex mouse.scrbl
to generate "mouse.tex".
See Running scribble in the Racket Scribble documentation for more information on the scribble command-line tool.
1.2 Multiple Sections
Add more text to "mouse.scrbl" so that it looks like this:
@title{On the Cookie-Eating Habits of Mice}
If you give a mouse a cookie, he's going to ask for a
glass of milk.
@section{The Consequences of Milk}
That ``squeak'' was the mouse asking for milk. Let's
suppose that you give him some in a big glass.
He's a small mouse. The glass is too big---way too
big. So, he'll probably ask you for a straw. You might as
well give it to him.
@section{Not the Last Straw}
For now, to handle the milk moustache, it's enough to give
him a napkin. But it doesn't end there... oh, no.
Now, after the first paragraph of the paper, we have two sub-sections, each created by calling section to generate a sub-section declaration. The first sub-section has two paragraphs. The second section, as initiated by the result of the second section call, has a single paragraph.
Run the scribble command(s) from A First Example again. You may notice the curly double-quotes in the output, and the --- turned into an em dash.
1.3 Splitting the Document Source
As a document grows larger, it’s better to split sections into separate source files. The include_section function incorporates a document defined by a ".scrbl" file into a larger document.
To split the example document into multiple files, change "mouse.scrbl" to just
@title{On the Cookie-Eating Habits of Mice}
If you give a mouse a cookie, he's going to ask for a
glass of milk.
@include_section("milk.scrbl")
@include_section("straw.scrbl")
Create "milk.scrbl" and "straw.scrbl" in the same directory as "mouse.scrbl". In "milk.scrbl", put
@title{The Consequences of Milk}
That ``squeak'' was the mouse asking for milk...
and in "straw.scrbl", put
@title{Not the Last Straw}
For now, to handle the milk moustache, ...
Notice that the new files both start with #lang, like the original document, and the sections from the original document become titles in the new documents. Both "milk.scrbl" and "straw.scrbl" are documents in their own right with their own titles, and they can be individually rendered using scribble. Running scribble on "mouse.scrbl", meanwhile, incorporates the smaller documents into one document that is the same as before.
1.4 More Functions
The rhombus/scribble language provides a collection of basic functions (and rhombus/scribble/manual is a supersets of rhombus/scribble). Many of the functions are style variations that you can apply to text:
He's a @smaller{small mouse}. The glass is too
@larger{big}---@bold{way @larger{too @larger{big}}}. So, he'll
@italic{probably} ask you for a straw.
which renders as
He’s a small mouse. The glass is too big—
way too big. So, he’ll probably ask you for a straw.
As you would expect, calls to functions like smaller, larger, and bold can be nested in other calls. They can also be nested within calls to title or section:
1.4.1 Centering
The centered function centers a flow of text:
If a mouse eats all your cookies, put up a sign that says
@centered{
@bold{Cookies Wanted}
@italic{Chocolate chip preferred!}
}
and see if anyone brings you more.
which renders as
If a mouse eats all your cookies, put up a sign that saysCookies Wanted
Chocolate chip preferred!
and see if anyone brings you more.
1.4.2 Margin Notes
The margin_note function is used in a similar way, but the rendered text is moved to the margins. If you use margin_note, then the content shows up over here.
1.4.3 Itemizations
The itemlist function creates a sequence of bulleted text, where the item function groups text to appear in a single bullet. The itemlist function is different from the others that we have seen before, because it only accepts values produced by item instead of arbitrary text. This difference is reflected in the use of (…) for the arguments to itemlist instead of {…}:
@item{If you want to eat a cookie,
you must bring your own straw.})
which renders as
Notice to Mice
We have cookies for you.
If you want to eat a cookie, you must bring your own straw.
1.4.4 Tables
The tabular function takes a list of lists to organize into a two-dimensional table. By default, no spacing is added between columns, so supply a ~sep argument to act as a column separator. For example,
["mouse", "cookie"],
["moose", "muffin"]])
renders as
Animal
Food
mouse
cookie
moose
muffin
1.5 Text Mode vs. Rhombus Mode for Arguments
When (…) surrounds the arguments of a function, the argument expressions are in Rhombus mode rather than text mode. Even in Rhombus mode, @ can be used to apply functions. In rhombus/scribble or even plain rhombus, @ behaves the same in both Rhombus mode and text mode.
One advantage of using Rhombus mode for the arguments to itemlist is that we can pass a keyword-tagged optional argument to itemlist. In particular, if you want a list with numbers instead of bullets, supply the #'ordered style to itemlist using the ~style keyword:
@item{Eat cookie.}
@item{Drink milk.}
@item{Wipe mouth.}
@item{...})
A function doesn’t care whether it’s used with (…) or {…}. Roughly, {…} forms an argument that is a list containing a string. (Only roughly, though. Newlines or uses of @ within {…} complicate the picture, and we’ll get back to that soon.) So,
@italic{Yummy!}
is equivalent to
@italic(["Yummy!"])
which is equivalent to the Rhombus expression
italic(["Yummy!"])
These equivalences explain why Scribble functions are documented in Rhombus notation. If you’re reading this in HTML format, you can click italic above to access its documentation. The documentation won’t completely make sense, yet, but it will by the end of this chapter.
What if you want to provide arguments in text mode, but you also want to supply other optional arguments? You can use both (…) and {…} for a function, as long as the (…) part is first, and as long as no characters separate the closing ) from the opening {. For example, calling italic is the same as using elem with the #'italic style:
You can also omit both (…) and {…}. In that case, the
Rhombus expression after @ is used directly instead of applied as an
operation—
renders as
1 plus 2 is 3
The call to to_string is needed because a naked number is not valid as document content.
1.6 More @ Syntax
The @ notation used by Scribble is just another way of writing Rhombus expressions. Scribble documents could be constructed using normal Rhombus notation, without using @ at all, but that would be inconvenient for most purposes. The @ notation makes dealing with textual content much easier.
Whether in text mode or Rhombus mode, @ in a document provides an escape to Rhombus mode. The basic syntax of @ is
@ ‹cmd› ( ‹group›* ) { ‹text-body› }
where all three parts after @ are optional, but at least one must be present. No spaces are allowed between
@ and ‹cmd›, (, or {;
‹cmd› and ( or {; or
) and {.
A ‹cmd› or ‹group› is normal Rhombus notation, while a ‹text-body› is itself in text mode. A ‹cmd› obviously must not start with ( or {, even though Rhombus forms could otherwise start with those characters.
The expansion of just @‹cmd› into Rhombus code is
‹cmd›
When either (…) or {…} are used, the expansion is
‹cmd›(‹group›*, ‹parsed-body›)
where ‹parsed-body› is the parse result of the ‹text-body›. The ‹parsed-body› part often turns out to be a list of Rhombus strings.
In practice, the ‹cmd› is normally a Rhombus identifier that is bound to a function or macro. If the function or macro expects further text to typeset, then {…} supplies the text. If the form expects other data, typically (…) is used to surround Rhombus arguments, instead. Even if a function’s argument is a string, if the string is not used as content text (but instead used as, say, a hyperlink label), then the string is typically provided through (…) instead of {…}. Sometimes, both (…) and {…} are used, where the former surround Rhombus arguments that precede text to typeset.
Finally, if a form is a purely Rhombus-level form with no typeset result, such as a import to import more operations, then typically @ is used with immediate (…). This is s second allowed form of @:
@ ( ‹form› )
where the expansion of @(‹form›) is just ‹form›.
For example the text-mode stream
@section(~tag: "poetry"){Of Mice and Cookies}
See @secref("milk").
is equivalent to the Rhombus-mode sequence
"\n"
"\n"
section(~tag: "poetry", ["Of Mice and Cookies"]) "\n"
"See " @secref("milk") "." "\n"
"\n"
section(~tag "milk", [italic(["Important"]), " Milk Supplies"]) "\n"
figure("straw", elem("A straw"), [@image("straw.png")]) "\n"
Besides showing how different argument conventions are used for
different operations, the above example illustrates how whitespace is
preserved in the Racket form of a text-mode stream—
In addition to its role for command, a @ can be followed by // to start a comment. If the character after // is {, then the comment runs until a matching }, otherwise the comment runs until the end-of-line:
@//{ ‹text-mode-multi-line-comment› }
@// ‹single-line-comment›
For more information on the syntax of @, see At-Notation Parsing. The full syntax includes a few more details, such as brackets like |{…}| for text-mode arguments while disabling @ between the brackets.