2. Skribilo User Manual — Syntax
Contents↑ Skribilo User Manual

This chapter describes the syntax or Skribilo documents---or rather, the available syntaxes Skribilo documents can use. Skribilo actually supports several input syntaxes, each of which is implemented by a reader. The input syntax (and reader) can be selected at document compilation time using the --reader option of the compiler (see Chapter 14). Nevertheless, it has a ``preferred'' syntax (the default syntax), which is that of the Skribe document preparation system. Thus, the Skribe syntax is first described, and then alternate syntaxes are presented.

2.1 The Skribe Syntax

By default or when the --reader=skribe option is passed to the compiler, a Skribilo document is composed of Skribe expressions, which resemble expressions in the Scheme programming language, with a few extensions to make them more convenient to use within documents. A Skribe expression can be:

Here are several examples of correct Skribe expressions:
  • "foo", a string of characters composed of the characters `f', `o' and `o'.
  • 123 3.14, two numbers.
  • #t #f, the true and false Skribe value.
  • (bold "foo bar"), a list.
  • [A text sample], a simple text containing three words and no escape sequence.
  • [Another text sample (that is still) simple], another simple text.
  • [Another ,(bold "text") sample], a more complex text that contains two words (Another and sample) and an expression (bold "text"). The escape sequence is introduced with the `,(' characters.

Expressions are evaluated, thus (bold "foo") has the effect of typesetting the word foo in bold face to produce foo. Escape sequences enable evaluation of expressions inside the text. Thus the text [Another ,(bold "text") sample] produces `Another text sample'. On the other hand [Another (bold "text") sample] produces `Another (bold "text") sample' because it does not contain the escape sequence `,('.

2.1.1 Formal Syntax

<expr>    --> <atom>
            | <text>
            | <list>
<list>    --> (<expr>+)
<text>    --> [any sequence but `,(' or a `,<list>']
<atom>    --> <boolean>
            | <integer>
            | <float>
            | <string>
            | <color>
<integer> --> [0-9]+
<float>   --> [0-9]+.[0-9]*
            | [0-9]*.[0-9]+
<string>  --> ...
<color>   --> <string>
            | #[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]

2.1.2 Values Width

A Skribe width refers to the horizontal size a construction occupies on an output document. There are three different ways for specifying a width:

An absolute pixel size
This is represented by an exact integer value (such as 350).
A relative size
This is represented by an inexact integer value (such as 50.0) which ranges in the interval [-100.0 .. 100.0]
An engine dependent representation
This is represented by a string that is directly emitted in the output document (such as HTML column "0*" specification). Note that this way of specifying width is strictly unportable.

2.2 The Outline Syntax

Alternatively, Skribilo allows documents to be written in a plain text format, with almost no markup. Instead, conventions borrowed from Emacs' Outline Mode to denote the text structure as well as other common conventions are used to express various formatting ideas. This syntax is implemented by the outline reader; thus, it is made available by passing the --reader=outline option to the compiler. The major elements of this syntax are the following:

Document title and author
The document title is introduced by adding a line starting with Title: at the beginning of the text file, and followed by the title. Likewise, the author can be specified with a line starting with Author:.
Chapters are introduced using a heading preceding by a single * (star) character. For instance, * The First Part on a line on its own, followed by an empty line, introduces a new chapter entitled ``The First Part''. Likewise, two stars introduce a section, three stars introduce a subsection, etc.
Emphasis, italics, bold
Words or phrases surrounded by the _ (underscore) character are emphasized; those surrounded by / (slash) characters are italicized; finally, those surrounded by * (star) characters are typeset in boldface (see Section Ornaments).
Words enclosed in double quotes (i.e., two back-quote characters, then two single-quote characters) are interpreted as quoted text, as per q.
Words enclosed in single quotes (i.e., one back-quote character, then one single-quote) are interpreted as code and are typeset using a fixed-width font, as per tt.
URLs are automatically recognized and converted into a (ref :url ...) form (see ref). In addition, outline has limited support for Org-Mode-style hyperlinks; for instance, [[http://gnu.org/][The GNU Project]] yields The GNU Project.

Here is an example showing how the outline syntax maps to the native skribe syntax:

-*- mode: outline; coding: iso-8859-1; -*-

Title: Demonstrating Skribilo's Outline Syntax
Author: Ludovic Courtes
Keywords: Skribilo outline Emacs

This document aims to *demonstrate*
[[http://skribilo.nongnu.org/][Skribilo]]'s outline syntax.

* The First Chapter

The first chapter contains a couple of sections.
They look as though they had been introduced with
the `section' markup of the Skribe syntax.

** The First Section

This section is pretty much empty.

** The Second Section

This section introduces lists.

*** Bullet Lists

This section contains a wonderful `itemize'-style bullet list:

  - the first item;

  - the second item;

  - the last one, which spans
    two lines of text.

And that's it.  Note that list items had to be
separated by empty lines.

*** Enumerations

This section shows an `enumerate'-style list:

  1. The first item;

  2. The second one;

  3. The last one.

Note that list items are numbered this time.

* The Second Chapter

The second chapter does _not_ add anything useful.

Text like this that starts after an empty line is
put into a new paragraph.

Ex. 1: The outline syntax

... produces:

  "Demonstrating Skribilo's Outline Syntax"
  (author #:name "Ludovic Courtes")
  '("Skribilo outline Emacs")
  (p (list (list (list "This document aims to "
                       (bold "demonstrate")
           (list ""
                 (ref #:url
                 "'s outline syntax.")
    "The First Chapter"
    (p (list (list (list "The first chapter contains a couple of sections."
                   "They look as though they had been introduced with"
             (list "the "
                   (tt "section")
                   " markup of the Skribe syntax.")
      "The First Section"
      (p (list "This section is pretty much empty." "\n")))
      "The Second Section"
      (p (list "This section introduces lists." "\n"))
        "Bullet Lists"
        (p (list (list "This section contains a wonderful "
                       (tt "itemize")
                       "-style bullet list:")
          (item (list "the first item;"))
          (item (list "the second item;"))
          (item (list (list "the last one, which spans")
                      "    two lines of text.")))
        (p (list (list "And that's it.  Note that list items had to be"
                 "separated by empty lines."
        (p (list (list "This section shows an "
                       (tt "enumerate")
                       "-style list:")
          (item (list "The first item;"))
          (item (list "The second one;"))
          (item (list "The last one.")))
        (p (list "Note that list items are numbered this time."
    "The Second Chapter"
    (p (list (list "The second chapter does "
                   (emph "not")
                   " add anything useful.")
    (p (list (list "Text like this that starts after an empty line is"
             "put into a new paragraph."

The outline mode makes it possible to quickly create documents that can be output in variety of formats (see Chapter 13). The downside is that, being a very simple markup-less document format, there are many things that cannot be done using it, most notably tables, bibliographies, and cross-references.

2.3 The Gemtext Syntax

Gemtext, the lightweight markup language used by the Gemini protocol, is supported as an input syntax. To use it, just pass --reader=gemtext to the compiler. When used programmatically, the Gemtext reader can be customized using the following options.

(make-gemtext-reader :section-numbers? :join-lines?)
:join-lines? If #t, lines which are not separated by a blank line are joined into a single paragraph. This is a relaxation of the Gemtext standard, and is not done by default.
:section-numbers? If #t, sections are numbered. Else, they are not.

2.4 The RSS 2.0 Syntax

RSS 2.0 (aka. Really Simple Syndication) is supported as an input syntax. To use it, just pass --reader=rss-2 to the compiler. This makes it possible to generate Skribilo documents from RSS 2.0 feeds, which can be useful or at least funny. Consider the following example:

$ wget http://planet.gnu.org/rss20.xml
$ skribilo -R rss-2 -t lout -c column-number=2 < rss20.xml \
  | lout | ps2pdf - > gnu-planet.pdf
It produces a two-column PDF file with the contents of the RSS feed of GNU Planet, where each item of the feed is mapped to a Skribilo ``chapter''.

2.5 Documents in Scheme Programs

It is also possible to create and output Skribilo documents from a Guile Scheme program. In that case, you get to use the Scheme syntax, which is close to the Skribe syntax described above, modulo the [...] constructs. A typical Scheme program that would produce and output a document, pretty much like what the skribilo compiler does, would look like this:

Ex. 2: Programming Skribilo documents in Scheme.
This should give you an idea of the wonderful, life-changing things that can be achieved with a bit of document programming.

2.6 Writing New Readers

Skribilo is extensible and makes it easy to add custom readers, allowing the use of virtually any input syntax. A reader is essentially a procedure like R5RS' read, i.e., a one-argument procedure that takes a port and returns an S-expression. The returned S-expression should be a valid ``document program'' as shown in scheme-syntax.

The are a few additional details, though. Implementations of readers are required to use the (skribilo reader) modules and the define-reader macro. In addition, the reader must live in its own module, under the (skribilo reader) module hierarchy, so that the reader lookup mechanism (used by the --reader option of the compiler) can find it. This mechanism is the same as that used for engines (see Section 13.1.5). A skeleton for a reader would be like this:

Ex. 3: Writing a new reader.
Users and encouraged to look at examples in the Skribilo source for additional details.

(made with skribilo)