README.fab

§1. This is Maui, the Mau Independent Fabricator.

Fabricator is a literate programming engine with an unobtrusive, wiki-like syntax. Modern Fabricator lives normally inside Mau, a PIM-oriented wiki engine, but Maui makes it available through a command line interface or a Ruby API without requiring a full Mau installation.

Contents

1. Inline markup

§2. Fabricator's markup can be viewed as a particular wiki markup with literate programming extensions. Here are the inline markup elements:

2. Narrative structure

§3. Paragraphs are separated from each other and other input by blank lines.

§4. Two adjacent blank lines separate sections.

§5. An indented block of text will be treated as a piece of sample code, like this:

These lines were indented.  Note that a block can contain
blank lines,

but only one at a time.  Two consecutive blank lines would be
parsed as a section break, and the new section would contain a
new block.

§6.

Like this.

§7. Items in a bullet list are marked by leading dash and space, and can be nested:

- 1
  - 1.1
  - 1.2
    - 1.2.1
- 2

will produce:

§8. A document can be divided into chapters, subchapters, and subsubchapters by titles. A title should be separated with preceding and following with a blank line and is marked, correspondingly, with a leading ==, ===, or ==== together with a following separating space.

Furthermore, the document structure can be presented with the use of rubrics, which correspond to Knuth WEB's starred chunks. A rubric is marked similarly to a title except with a leading * instead of equal signs. The star must be separated from the rubric's name with a space lest the parser think it's just a bold text marker. Because rubrics are, if a paragraph follows, embedded into the paragraph by Fabricator's weaving subsystem, it's a good idea to formulate rubric names as full sentences, together with a trailing period or other punctuation.

3. Chunks and transclusion

§9. Each section can contain one or more chunks, with the following notation:

<< Chunk name >>:
  Chunk content, possibly on many lines,
  including single blank lines.

Note that the declaration must be unindented, and the chunk's content must be indented.

Some programming languages make use of << and >> for other purposes. In order to make the plain Fabricator input easy to read, no escaping for double brokets is provided. You'll have to structure the input in such a way as to avoid false transclusion references.

§10. A chunk can be marked as a root chunk by prepending a .file or .script to directive, like this:

<< .script hello.rb >>:
  #! /usr/bin/ruby -rubygems

  puts "<< Friendly, familiar greeting >>"

§11. The (mechanical) power of literate programming comes from transclusion, which is notated by adding the target chunk's name into another chunk, as seen above.

<< Friendly, familiar greeting >>:
  Hello, world!

It is permitted to define multiple chunks with the same name. When the name is referred in a transclusion, all these chunks will then be processed, separated with a single blank line. In cases when the separating blank line is undesirable, it can be suppressed by the .dense directive:

@cat_names = qw(
  << The names of cats .dense >>
)

§12. Normally, Fabricator obeys indentation in a nested manner. In certain cases --- most importantly, the 'here-documents' in shell scripts and languages borrowing their notation ---, you may want to suppress this. This is achieved by the .clearindent directive:

<< ... >>:
  module Beast
    DATA = {
      :cows => << .clearindent Cows heredoc >>
    }

<< Cows heredoc >>:
  << 'END-OF-COWS',
  << Cows >>
  END-OF-COWS

The extra wrapper, << Cows heredoc >>, serves two purposes in this example:

§13. It's often useful to intersperse many chunks of the same name with a narrative explaining the actions taken. Mau facilitates this via diversions. The notation for a diversion is a chunk header without the chunk; the subsequent indented blocks --- which would otherwise be interpreted as example code --- are then treated as chunks of this name. A diversion is effect until another diversion replaces it or until a title begins a new narrative unit of the document. Note that a rubric does not cancel a diversion's effect.

4. Postprocessing

§14. Fabricator provides experimental support for postprocessing text constructed using the standard LP transclusion mechanism. The notation for this is subject to change in future versions, and the available postprocessors are environment-dependent.

In the current version, Maui defines two postprocessors related to Sass, the preprocessor for CSS. These are |scss->css and |sass->css, and they are invoked by attaching their names to the transclusion notation like this:

<< ... >>:
  ...
  puts << EOS
    Content-type: text/css; charset=UTF-8

    << stylesheet.sass |sass->css >>
  EOS
  ...

<< stylesheet.sass >>:
  .footer
    font-size: smaller

  ...

5. Invocation

§15. Last but not least, the way to run maui goes like this:

$ maui foo.fab

By default, this outputs warnings about probable problems with the input to the standard error stream and both weaves the input into foo.html and foo.ctxt as well as tangles all the defined roots. It's also possible to specify that only some of these files are to be written out, like this:

$ maui foo.fab hello.c foo.html

Note, however, that Fabricator necessarily tangles everything (into core memory) defined in the fab file while processing it, so such a command will not take significantly less runtime than a general maui command. It only suppresses writing the unwanted results as files.