(A big name for some tiny software.)
See also crock-lisp.
Crock is a Python script that translates text with light markup into various formats (only XHTML 1.0 currently.)
| Repository | git://git.tuxee.net/crock |
| GitWeb | Web interface |
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.
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.
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.)
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.
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 ======
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.
An indented paragraph.
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 4Gives:
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
Crock supports other list styles such as:
| Type | Prefix |
| decimal | 1. |
| 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:
first
sub
sub
second
third
sub
sub
fourth
fifth
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:
| Cell1 | Cell2 | Cell3 | Cell4 |
| Cell5 | Cell6 | ||
| Cell7 | Cell8 | ||
You can also add a caption this way:
--- A caption for the following table --- | Cell1 | Cell2 | Cell3 | Cell4 | | Cell5 ||| Cell6 | | Cell7 || Cell8 ||
gives:
| Cell1 | Cell2 | Cell3 | Cell4 |
| Cell5 | Cell6 | ||
| Cell7 | Cell8 | ||
Note: The syntax doesn't allows to write cell text spanning several lines.
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:
some text to include verbatim, until the next marker is encountered
Inside paragraph, further processing is done to format the text.
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:

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.
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.)
Some words are automatically highlighted such as FIXME and TODO.
This list of words is hard written in the code.
(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.
To insert table of contents, use [[TableOfContents]]. (See at start of this page for an example.)
Crock works with an tree representation of a document. To create such a tree given a text, you can use crock.parser.parse.
>>> from tuxeenet.crock import parser >>> doc = parser.parse( '*** Example ***\n\nline 1\n\nline 2' )
>>> doc.asDebug()
DOCUMENT with 3 blocks
TITLE 'Example'
PARAGRAPH
TEXT 'line 1'
PARAGRAPH
TEXT 'line 2'>>> 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.
>>> 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.
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>
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.
>>> from pprint import pprint >>> from tuxeenet.crock.parser import parse >>> doc = parse( file( 'crock.txt' ).read().decode( 'utf-8' ) )
>>> doc.getTitle() u'Crock Documentation System'
>>> 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']]
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)