Crock Documentation System

(A big name for some tiny software.)

Source text

  1. Summary
  2. Git repository
  3. Installation
  4. Unicode support
  5. Formatting
    1. Top level formatting
      1. Headings
      2. Paragraphs
      3. List
      4. Table
      5. Verbatim text
    2. Paragraph level formatting
      1. Image and url
      2. Styles
      3. Highlight
    3. Macro
      1. Table of contents
  6. Python modules
    1. Parsing
    2. Output
    3. Constructing document
    4. Extracting
  7. Integration with Emacs
  8. Links

See also crock-lisp.

Summary

Crock is a Python script that translates text with light markup into various formats (only XHTML 1.0 currently.)

Git repository

Repositorygit://git.tuxee.net/crock
GitWebWeb interface

Installation

You need the tuxeenet.tx module in addition to Crock. See documentation of this module at http://crock.tuxee.net/tx. Crock requires Python 2.4

To install tuxeenet.tx and tuxeenet.crock modules, just run ./setup install in both projects source directory.

Unicode support

When using Crock from the command line, the input text is first decoded to an Unicode string by Python. The default charset is assumed to be utf-8, but it can be changed from the command line. See -E option.

Formatting

Source text is first split into paragraphs (blocks) according to top level formatting markup. Then each paragraph is processed for applying style and indentation (to build lists in particular.)

Top level formatting

Syntax is very close to the MoinMoin wiki format. The aim of this project is just to make it easy to generate some HTML documentation out of simple formatted text.

Headings

The page title can appear anywhere in the document, but it's recommended to put it at the beginning of the file.

There is only 6 levels of heading supported.

*** Page title ***

= heading at level 1 =

== heading at level 2 ==

...

====== heading at level 6 ======

Paragraphs

A paragraph is a serie of non-empty lines indented at the same level.

One paragraph which spans
several lines.

Another paragrah.

 An indented paragraph.

gives:

One paragraph which spans several lines.

Another paragrah.

List

Lists are made from a series of indented paragraphs.

 * list item 1

   * list item 1.1

   Another paragraph for item 1.1

     * list item 1.1.1

 * list item 2

 * list item 3

   * list item 3.1

   * list item 3.2

 * list item 4

Gives:

Crock supports other list styles such as:

TypePrefix
decimal1.
roman¹i. or I.
alpha¹a. or A.

¹Produces lower or upper case according to prefix case.

Example of a list with mixed styles:

 i. first

  1. sub

  1. sub

 i. second

 i. third

  a. sub

  a. sub

 i. fourth

 i. fifth

Gives:

  1. first

    1. sub

    2. sub

  2. second

  3. third

    1. sub

    2. sub

  4. fourth

  5. fifth

Table

A table description is a serie of list all starting with | at the same indentation level.

The | is used to delimit a cell. It's possible to make a cell span multiple columns by ending it with multiple |.

For example:

| Cell1 | Cell2 | Cell3 | Cell4 |
| Cell5               ||| Cell6 |
| Cell7        || Cell8        ||

gives:

Cell1Cell2Cell3Cell4
Cell5Cell6
Cell7Cell8

You can also add a caption this way:

--- A caption for the following table ---
| Cell1 | Cell2 | Cell3 | Cell4 |
| Cell5               ||| Cell6 |
| Cell7        || Cell8        ||

gives:

A caption for the following table
Cell1Cell2Cell3Cell4
Cell5Cell6
Cell7Cell8

Note: The syntax doesn't allows to write cell text spanning several lines.

Verbatim text

To insert raw text, use -=-=- markers around the block like this:

\-=-=-
some text to include verbatim,
until the next marker is encountered
\-=-=-

Inside the verbatim text, to insert -=-=- itself (if starting a line) use \-=-=-.

To add a caption to a verbatim text, you can use a line such as:

--- caption for the following verbatim text ---
\-=-=-
some text to include verbatim,
until the next marker is encountered
\-=-=-

which gives:

caption for the following verbatim text
some text to include verbatim,
until the next marker is encountered

Paragraph level formatting

Inside paragraph, further processing is done to format the text.

Image and url

It's easy to insert an image and url like this.

[Google logo http://www.google.com/intl/fr_ALL/images/logo.gif]

Pointing to [some url http://www.google.com/] like this.

gives:

http://www.google.com/intl/fr_ALL/images/logo.gif

Pointing to some url like this.

The url is the last part of the text between square brackets.

If no name is given, the url text is the url itself.

Styles

The syntax allows to specify text attribute such as bold, italic or underlined.

Some _underlined_, *bold* and /italic/ words.

We can even mix them _*/like this/*_.

gives:

Some underlined, bold and italic words.

We can even mix them like this.

And backquote can be used for "code" (I call them "keywords".)

Some `keyword` to quote with `backquotes`.

`*`, `/` and `_` have no effect inside backquotes like in `*foo*`.

gives:

Some keyword to quote with backquotes.

*, / and _ have no effect inside backquotes like in *foo*.

Also, to insert /, * and _ you need to double them (//, ** and __ respectively.)

Highlight

Some words are automatically highlighted such as FIXME and TODO.

This list of words is hard written in the code.

Macro

(Deprecated feature)

Macros can be used at two different levels: either at the top level, or paragraph level. Syntax is [[NameOfTheMacro]] where NameOfTheMacro must designate an existing macro.

At the top level, macros produce one or more paragraphs.

At the paragraph level, macros are used to generate text inside the paragraph itself.

The only top level macro currently available is TableOfContents which insert the table of contents of the current document.

Table of contents

To insert table of contents, use [[TableOfContents]]. (See at start of this page for an example.)

Python modules

Parsing

Crock works with an tree representation of a document. To create such a tree given a text, you can use crock.parser.parse.

Example 1
>>> from tuxeenet.crock import parser
>>> doc = parser.parse( '*** Example ***\n\nline 1\n\nline 2' )

Output

Output as debug
>>> doc.asDebug()
DOCUMENT with 3 blocks
  TITLE 'Example'
  PARAGRAPH
    TEXT 'line 1'
  PARAGRAPH
    TEXT 'line 2'
Output as XHTML (the body only)
>>> doc.asXhtml().serialize()
'<body><div class="title">Example</div><p>line 1</p><p>line 2</p></body>'

Note: Look at the crock source to see how to build a complete XHTML document.

Output as Crock document
>>> doc.asCrock()
*** Example ***

line 1

line 2

Note: The document generated by asCrock cannot necessary be read again by Crock itself, because the document tree is richer than the Crock syntax.

Constructing document

Of course it is also possible to build the document by creating the tree structure directly.

The tree generated by the first example is equivalent to:

>>> from tuxeenet.crock.tree import *
>>> Document( Title( 'Example' ) ,
...           Paragraph( 'line 1' ) ,
...           Paragraph( 'line 2' ) )
<tuxeenet.crock.tree.Document instance at 0xb7ad40ac>

Extracting

Here is how to extract title and document structure from a file containing a Crock document.

The document used in the following example is the present document.

Input document
>>> from pprint import pprint
>>> from tuxeenet.crock.parser import parse
>>> doc = parse( file( 'crock.txt' ).read().decode( 'utf-8' ) )
Extracting the document title
>>> doc.getTitle()
u'Crock Documentation System'
Extracting the document structure
>>> pprint( doc.getStructure() )
[[<tuxeenet.crock.tree.Heading instance at 0xb79f7bec>,
  <tuxeenet.crock.tree.Heading instance at 0xb79f7c8c>,
  <tuxeenet.crock.tree.Heading instance at 0xb79fc18c>,
  <tuxeenet.crock.tree.Heading instance at 0xb79fc46c>,
  <tuxeenet.crock.tree.Heading instance at 0xb79fc74c>,
  [<tuxeenet.crock.tree.Heading instance at 0xb79fc78c>,
   [<tuxeenet.crock.tree.Heading instance at 0xb79fc7cc>,
    <tuxeenet.crock.tree.Heading instance at 0xb79fc84c>,
    <tuxeenet.crock.tree.Heading instance at 0xb79fc8ac>,
    <tuxeenet.crock.tree.Heading instance at 0xb79ff6cc>,
    <tuxeenet.crock.tree.Heading instance at 0xb79fff8c>],
...]]]

Using a helper function to show the plain titles:

>>> def t(l):
...     if isinstance(l,list): return map(t,l)
...     else : return str(l.title)
>>> pprint( t( doc.getStructure() ) )
[['Summary',
  'Arch repository',
  'Installation',
  'Unicode support',
  'Formatting',
  ['Top level formatting',
   ['Headings', 'Paragraphs', 'List', 'Table', 'Verbatim text'],
   'Paragraph level formatting',
   ['Image and url', 'Styles', 'Highlight'],
   'Macro',
   ['Table of contents']],
  'Python modules',
  ['Parsing', 'Output', 'Constructing document', 'Extracting'],
  'Integration with Emacs']]

Integration with Emacs

Put the following into your ~/.emacs, then each time you open a file in text mode (which is usually the default) the key sequence C-c C-c will be automatically defined to call the function to publish the current text buffer.

This assume that you have some pcrock script to be used for this purpose (which takes one filename as argument.)

(defvar pcrock-command "/home/fred/bin/pcrock"
  "Command used to publish a crock document")

(defun publish-crock-buffer ()
  "Publish the crock document associated with the current buffer."
  (interactive)
  (cond
    ((not (buffer-file-name))
     (error "This buffer is not associated with a file"))
    ((buffer-modified-p)
     (error "Save buffer prior to publishing this document"))
    (t
     (message "Updating document..")
     (if (/= 0 (call-process pcrock-command
                             nil nil nil
                             (buffer-file-name)))
         (error "Failed to update document")
         (message "Done.")))))

(defun crock-define-keys ()
  "Define C-c C-c for buffer whose filename ends with .txt"
  (if (and (buffer-file-name)
           (string= (substring (buffer-file-name) -4) ".txt"))
      (local-set-key "\C-c\C-c" 'publish-crock-buffer)))

(add-hook 'text-mode-hook 'crock-define-keys)

Links

Generated by Crock on Wed May 14 14:12:30 2008