[part quickbook
[version 1.1]
[authors [de Guzman, Joel], [Niebler, Eric]]
[copyright 2002 2004 Joel de Guzman, Eric Niebler]
[purpose WikiWiki style documentation tool]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
)
]
[last-revision $Date: 2005/04/30 01:48:44 $]
]
[/ QuickBook Document version 1.1 ]
[/ Sept 24, 2002 ]
[/ Sept 2, 2004 ]
[/ Feb 14, 2005 ]
[/ Some links]
[def __note__ [$images/note.png]]
[def __alert__ [$images/alert.png]]
[def __tip__ [$images/tip.png]]
[def :-) [$images/smiley.png]]
[def __spirit__ [@http://spirit.sourceforge.net Spirit]]
[def __boostbook__ [@http://www.boost.org/doc/html/boostbook.html BoostBook]]
[def __docbook__ [@http://www.docbook.org/ DocBook]]
[section:intro Introduction]
[:[*['"Why program by hand in five days what you can spend five years of your
life automating?"]]\n\n-- Terrence Parr, author ANTLR/PCCTS]
Well, QuickBook started as a weekend hack. It was originally intended to be a
sample application using __spirit__. What is it? What you are viewing now, this
documentation, is autogenerated by QuickBook. These files were generated from
one master:
[:[@../quickbook.qbk quickbook.qbk]]
Originally named QuickDoc, this funky tool that never dies evolved into a
funkier tool thanks to Eric Niebler who resurrected the project making it
generate __boostbook__ instead of HTML. The __boostbook__ documentation format
is an extension of __docbook__, an SGML- or XML- based format for describing
documentation.
QuickBook is a WikiWiki style documentation tool geared towards C++
documentation using simple rules and markup for simple formatting tasks.
QuickBook extends the WikiWiki concept. Like the WikiWiki, QuickBook documents are
simple text files. A single QuickBook document can generate a fully linked set
of nice HTML and PostScript/PDF documents complete with images and syntax-
colorized source code.
Features include:
* generate __boostbook__ xml, to generate HTML, PostScript and PDF
* simple markup to link to Doxygen-generated entities
* macro system for simple text substitution
* simple markup for italics, bold, preformatted, blurbs, code samples,
tables, URLs, anchors, images, etc.
* automatic syntax coloring of code samples
* CSS support
[endsect]
[section:syntax Syntax Summary]
A QuickBook document is composed of one or more blocks. An example of
a block is the paragraph or a C++ code snippet. Some blocks have
special mark-ups. Blocks, except code snippets which have their own
grammar (C++ or Python), are composed of one or more phrases. A phrase
can be a simple contiguous run of characters. Phrases can have special
mark-ups. Marked up phrases can recursively contain other phrases, but
cannot contain blocks. A terminal is a self contained block-level or
phrase- level element that does not nest anything.
Blocks, in general, are delimited by two end-of-lines (the block terminator).
Phrases in each block cannot contain a block terminator. This way, syntax errors
such as un-matched closing brackets do not go haywire and corrupt anything past
a single block.
[h2 Comments]
Can be placed anywhere.
[pre
'''[/ comment (no output generated) ]'''
]
[h2 Phrase Level Elements]
[h3 Font Styles]
[pre'''
['italic], [*bold], [_underline], [^teletype]
''']
will generate:
['italic], [*bold], [_underline], [^teletype]
Like all non-terminal phrase level elements, this can of course be nested:
[pre'''
[*['bold-italic]]
''']
will generate:
[*['bold-italic]]
[h3 Simple formatting]
Simple markup for formatting text, common in many applications, is now supported:
[pre'''
/italic/, *bold*, _underline_, =teletype=
''']
will generate:
/italic/, *bold*, _underline_, =teletype=
Unlike QuickBook's standard formatting scheme, the rules for simpler alternatives
are much stricter.
* Simple markups cannot nest. You can combine a simple markup with a nestable markup.
* A non-space character must follow the leading markup
* A non-space character must precede the trailing markup
* A space or a punctuation must follow the trailing markup
* If the matching markup cannot be found within a line, the formatting
will not be applied. This is to ensure that un-matched formatting markups,
which can be a common mistake, does not corrupt anything past a single line.
We do not want the rest of the document to be rendered bold just because we
forgot a trailing '*'.
* A line starting with the star will be interpreted as an unordered list.
See [link syntax.unordered_lists Unordered lists].
[table More Formatting Samples
[[Markup] [Result]]
[[[^'''*Bold*''']] [*Bold*]]
[[[^'''*Is bold*''']] [*Is bold*]]
[[[^'''* Not bold* *Not bold * * Not bold *''']] [* Not bold* *Not bold * * Not bold *]]
[[[^'''This*Isn't*Bold (no bold)''']] [This*Isn't*Bold (no bold)]]
[[[^'''(*Bold Inside*) (parenthesis not bold)''']] [(*Bold Inside*) (parenthesis not bold)]]
[[[^'''*(Bold Outside)* (parenthesis bold)''']] [*(Bold Outside)* (parenthesis bold)]]
[[[^'''3*4*5 = 60 (no bold)''']] [3*4*5 = 60 (no bold)]]
[[[^'''3 * 4 * 5 = 60 (no bold)''']] [3 * 4 * 5 = 60 (no bold)]]
[[[^'''3 *4* 5 = 60 (4 is bold)''']] [3 *4* 5 = 60 (4 is bold)]]
[[[^'''*This is bold* this is not *but this is*''']][*This is bold* this is not *but this is*]]
[[[^'''*This is bold*.''']] [*This is bold*.]]
[[[^'''*B*. (bold B)''']] [*B*. (bold B)]]
[[[^'''['*Bold-Italic*]''']] [['*Bold-Italic*]]]
]
[blurb __note__ Thanks to David Barrett, author of
[@http://quinthar.com/qwikiwiki/index.php?page=Home Qwiki], for sharing these samples
and teaching me these obscure formatting rules. I wasn't sure at all if __spirit__,
being more or less a formal EBNF parser, can handle the context sensitivity and ambiguity.]
[h3 Inline code]
Inlining code in paragraphs is quite common when writing C++ documentation. We
provide a very simple markup for this. For example, this:
[pre'''
This text has inlined code `int main() { return 0; }` in it.
''']
will generate:
This text has inlined code `int main() { return 0; }` in it. The code will be
syntax highlighted.
[blurb __note__
Note that we simply enclose the code with the tick: [^'''"`"'''], not the
single quote: `"'"`. Note too that [^'''`some code`'''] is prefered over
[^'''[^some code]'''].
]
[h3 Source Mode]
If a document contains more than one type of source code then the source mode
may be changed dynamically as the document is processed. All QuickBook
documents are initially in C++ mode by default, though an alternative initial value
may be set in the [link syntax.document Document Info] section.
To change the source mode, use the [^\[source-mode\]] markup, where
=source-mode= is one of the supported modes. For example, this:
[pre'''
Python's [python] `import` is rather like C++'s [c++] `#include`. A
C++ comment `// looks like this` whereas a Python comment [python]
`# looks like this`.
''']
will generate:
Python's [python] `import` is rather like C++'s [c++] `#include`. A
C++ comment `// looks like this` whereas a Python comment [python]
`#looks like this`.
[table Supported Source Modes
[[Mode] [Source Mode Markup]]
[[C++] [[^\[c++\]]]]
[[Python] [[^\[python\]]]]
]
[blurb __note__ The source mode strings are lowercase.]
[h3 line-break]
[pre'''
[br]
''']
[blurb __note__ Note that `\n` is now preferred over `[br]`.]
[h3 Anchors]
[pre'''
[#named_anchor]
''']
A named anchor is a hook that can be referenced by a link elsewhere in the
document. You can then reference an anchor with [^'''[link named_anchor Some link text]'''].
More on anchors [link syntax.anchor_links here], [link syntax.section here] and
[link syntax.headings here].
[h3 Links]
[pre'''
[@http://www.boost.org this is [*boost's] website....]
''']
will generate:
[@http://www.boost.org this is [*boost's] website....]
URL links where the link text is the link itself is common. Example:
[pre'''
see http://spirit.sourceforge.net/
''']
so, when the text is absent in a link markup, the URL is assumed. Example:
[pre
see '''[@http://spirit.sourceforge.net/]'''
]
will generate:
see [@http://spirit.sourceforge.net/]
[h3 Anchor links]
You can link within a document using:
[pre'''
[link section_id.normalized_header_text The link text]
''']
See sections [link syntax.section Section] and [link syntax.headings Headings]
for more info.
[h3 refentry links]
In addition, you can link internally to an XML refentry like:
[pre'''
[link xml.refentry The link text]
''']
This gets converted into [^The link text].
Like URLs, the link text is optional. If this is not present, the link text will
automatically be the refentry. Example:
[pre'''
[link xml.refentry]
''']
This gets converted into [^xml.refentry].
[h3 function, class, member, enum or header links]
If you want to link to a function, class, member, enum or header in the reference
section, you can use:
[pre'''
[funcref fully::qualified::function_name The link text]
[classref fully::qualified::class_name The link text]
[memberref fully::qualified::member_name The link text]
[enumref fully::qualified::enum_name The link text]
[headerref path/to/header.hpp The link text]
''']
Again, the link text is optional. If this is not present, the link text will
automatically be the function, class, member or enum. Example:
[pre'''
[classref boost::bar::baz]
''']
would have "boost::bar::baz" as the link text.
[h3 Escape]
The escape mark-up is used when we don't want to do any processing.
[pre
\'\'\'
escape (no processing/formatting)
\'\'\'
]
Escaping allows us to pass XML markup to __boostbook__ or __docbook__. For example:
[pre
\'\'\'
This is direct XML markup
\'\'\'
]
'''
This is direct XML markup
'''
[blurb __alert__ Be careful when using the escape. The text must conform to
__boostbook__/__docbook__ syntax.]
[h3 Single char escape]
The backslash may be used to escape a single punctuation character. The
punctuation immediately after the backslash is passed without any processing.
This is useful when we need to escape QuickBook punctuations such as `[` and `]`.
For example, how do you escape the triple quote? Simple: [^\\'\\'\\']
`\n` has a special meaning. It is used to generate line breaks. Note that `\n`
is now preferred over `[br]`.
[h3 Images (terminal)]
[pre'''
[$image.jpg]
''']
[h2 Block Level Elements]
[h3 Document]
Every document must begin with a Document Info section, which should look
like this:
[pre'''
[document-type The Document Title
[version 1.0]
[id the_document_name]
[dirname the_document_dir]
[copyright 2000 2002 2003 Joe Blow, Jane Doe]
[purpose The document's reason for being]
[category The document's category]
[authors [Blow, Joe], [Doe, Jane]]
[license The document's license]
[last-revision $Date: 2005/04/30 01:48:44 $]
[source-mode source-type]
]
''']
Where document-type is one of:
* book
* library
* part
* article
* chapter
and =version=, =id=, =dirname=, =copyright=, =purpose=, =category=, =authors=,
=license=, =last-revision= and =source-mode= are optional information.
Here =source-type= is a lowercase string setting the initial
[link syntax.source_mode source mode]. If the =source-mode= field is omitted, a
default value of =c++= will be used.
[h3 Section]
Starting a new section is accomplished with:
[pre'''
[section:id The Section Title]
''']
where /id/ is optional. id will be the filename of the generated section.
If it is not present, "The Section Title" will be normalized and become the id.
Valid characters are =a-Z=, =A-Z=, =0-9= and =_=. All non-valid characters are
converted to underscore and all upper-case are converted to lower case.
Thus: "The Section Title" will be normalized to "the_section_title".
End a section with:
[pre'''
[endsect]
''']
Sections can nest, and that results in a hierarchy in the table of contents.
[h3 xinclude]
You can include another XML file with:
[pre'''
[xinclude file.xml]
''']
This is useful when file.xml has been generated by Doxygen and contains your
reference section.
[h3 Paragraphs]
Paragraphs start left-flushed and are terminated by two or more newlines. No
markup is needed for paragraphs. QuickBook automatically detects paragraphs from
the context.
[h3 Ordered lists]
[pre
# One
# Two
# Three
]
will generate:
# One
# Two
# Three
[h3 List Hierarchies]
List hierarchies are supported. Example:
[pre
# One
# Two
# Three
# Three.a
# Three.b
# Three.c
# Four
# Four.a
# Four.a.i
# Four.a.ii
# Five
]
will generate:
# One
# Two
# Three
# Three.a
# Three.b
# Three.c
# Fourth
# Four.a
# Four.a.i
# Four.a.ii
# Five
[h3 Long List Lines]
Long lines will be wrapped appropriately. Example:
[pre
# A short item.
# A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
# A short item.
]
# A short item.
# A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
A very long item. A very long item. A very long item.
# A short item.
[h3 Unordered lists]
[pre'''
* First
* Second
* Third
''']
will generate:
* First
* Second
* Third
[h3 Mixed lists]
Mixed lists (ordered and unordered) are supported. Example:
[pre'''
# One
# Two
# Three
* Three.a
* Three.b
* Three.c
# Four
''']
will generate:
# One
# Two
# Three
* Three.a
* Three.b
* Three.c
# Four
And...
[pre'''
# 1
* 1.a
# 1.a.1
# 1.a.2
* 1.b
# 2
* 2.a
* 2.b
# 2.b.1
# 2.b.2
* 2.b.2.a
* 2.b.2.b
''']
will generate:
# 1
* 1.a
# 1.a.1
# 1.a.2
* 1.b
# 2
* 2.a
* 2.b
# 2.b.1
# 2.b.2
* 2.b.2.a
* 2.b.2.b
[h3 Code]
Preformatted code starts with a space or a tab. The code will be
syntax highlighted according to the current [link syntax.source_mode source mode]:
[c++]
#include
int main()
{
// Sample code
std::cout << "Hello, World\n";
return 0;
}
[python]
import cgi
def cookForHtml(text):
'''"Cooks" the input text for HTML.'''
return cgi.escape(text)
Macros that are already defined are expanded in source code. Example:
[pre'''
[def __syntax_highlight__ [@quickbook/highlight.html syntax_highlight]]
[def __quickbook__ [@index.html quickbook]]
using __quickbook__::__syntax_highlight__;
''']
Generates:
[def __syntax_highlight__ [@quickbook/highlight.html syntax_highlight]]
[def __quickbook__ [@index.html quickbook]]
using __quickbook__::__syntax_highlight__;
[h3 Preformatted]
Sometimes, you don't want some preformatted text to be parsed as C++. In such
cases, use the [^[pre ... \]] markup block.
[pre'''
[pre
Some *preformatted* text Some *preformatted* text
Some *preformatted* text Some *preformatted* text
Some *preformatted* text Some *preformatted* text
]
''']
Spaces, tabs and newlines are rendered as-is. Unlike all quickbook block level
markup, pre (and Code) are the only ones that allow multiple newlines. The
markup above will generate:
[pre
Some *preformatted* text Some *preformatted* text
Some *preformatted* text Some *preformatted* text
Some *preformatted* text Some *preformatted* text
]
Notice that unlike Code, phrase markup such as font style is still permitted
inside =pre= blocks.
[h3 Blockquote]
[pre
'''[:sometext...]'''
]
[:Indents the paragraph. This applies to one paragraph only.]
[h3 Headings]
[pre'''
[h1 Heading 1]
[h2 Heading 2]
[h3 Heading 3]
[h4 Heading 4]
[h5 Heading 5]
[h6 Heading 6]
''']
[h1 Heading 1]
[h2 Heading 2]
[h3 Heading 3]
[h4 Heading 4]
[h5 Heading 5]
[h6 Heading 6]
Headings 1-3 [h1 h2 and h3] will automatically have anchors with normalized
names with [^name="section_id.normalized_header_text"] (i.e. valid characters are
=a-z=, =A-Z=, =0-9= and =_=. All non-valid characters are converted to underscore
and all upper-case are converted to lower-case. For example: Heading
1 in section Section 2 will be normalized to [^section_2.heading_1]). You can use:
[pre'''
[link section_id.normalized_header_text The link text]
''']
to link to them. See [link syntax.anchor_links Anchor links] and
[link syntax.section Section] for more info.
[h3 Macros]
[pre'''
[def macro_identifier some text]
''']
When a macro is defined, the identifier replaces the text anywhere in the file,
in paragraphs, in markups, etc. macro_identifier is a string of non- white space
characters except '\]' while the replacement text can be any phrase (even
marked up). Example:
[pre'''
[def sf_logo [$http://sourceforge.net/sflogo.php?group_id=28447&type=1]]
sf_logo
''']
Now everywhere the sf_logo is placed, the picture will be inlined.
[def sf_logo [$http://sourceforge.net/sflogo.php?group_id=28447&type=1]]
sf_logo
[blurb __tip__ It's a good idea to use macro identifiers that are distinguishable.
For instance, in this document, macro identifiers have two leading and trailing
underscores (e.g. [^'''__spirit__''']). The reason is to avoid unwanted macro replacement.]
Links (URLS) and images are good candidates for macros. *1*) They tend to
change a lot. It is a good idea to place all links and images in one place near the top
to make it easy to make changes. *2*) The syntax is not pretty. It's easier to read and
write, e.g. [^'''__spirit__'''] than [^'''[@http://spirit.sourceforge.net Spirit]'''].
Some more examples:
[pre'''
[def :-) [$theme/smiley.png]]
[def __spirit__ [@http://spirit.sourceforge.net Spirit]]
''']
(See [link syntax.images__terminal_ Images]
and [link syntax.links Links])
Invoking these macros:
[pre'''
Hi __spirit__ :-)
''']
will generate this:
Hi __spirit__ :-)
[h3 Predefined Macros]
Quickbook has some predefined macros that you can already use.
[table Predefined Macros
[[Macro] [Meaning] [Example]]
[['''__DATE__'''] [Today's date] [__DATE__]]
[['''__TIME__'''] [The current time] [__TIME__]]
[['''__FILENAME__'''] [Quickbook source filename] [__FILENAME__]]
]
[h3 Blurbs]
[pre'''
[blurb :-) [*An eye catching advertisement or note...]\n\n
__spirit__ is an object-oriented recursive-descent parser generator framework
implemented using template meta-programming techniques. Expression templates
allow us to approximate the syntax of Extended Backus-Normal Form (EBNF)
completely in C++.
]
''']
will generate this:
[blurb :-) [*An eye catching advertisement or note...]\n\n
__spirit__ is an object- oriented recursive-descent parser generator
framework implemented using template meta-programming techniques. Expression
templates allow us to approximate the syntax of Extended Backus- Normal Form
(EBNF) completely in C++.
]
[h3 Tables]
[pre'''
[table A Simple Table
[[Heading 1] [Heading 2] [Heading 3]]
[[R0-C0] [R0-C1] [R0-C2]]
[[R1-C0] [R1-C1] [R1-C2]]
[[R2-C0] [R2-C1] [R2-C2]]
]
''']
will generate:
[table A Simple Table
[[Heading 1] [Heading 2] [Heading 3]]
[[R0-C0] [R0-C1] [R0-C2]]
[[R2-C0] [R2-C1] [R2-C2]]
[[R3-C0] [R3-C1] [R3-C2]]
]
The first row of the table is automatically treated as the table header; that is,
it is wrapped in [^...] XML tags. Note that unlike the original QuickDoc,
the columns are nested in [ cells... ]. The syntax is free-format and allows big
cells to be formatted nicely. Example:
[pre'''
[table Table with fat cells
[[Heading 1] [Heading 2]]
[
[Row 0, Col 0: a small cell]
[
Row 0, Col 1:
A very big cell...A very big cell...A very big cell...
A very big cell...A very big cell...A very big cell...
A very big cell...A very big cell...A very big cell...
]
]
[
[Row 1, Col 0: a small cell]
[Row 1, Col 1: a small cell]
]
]
''']
and thus:
[table Table with fat cells
[[Heading 1] [Heading 2]]
[
[Row 0, Col 0: a small cell]
[
Row 0, Col 1:
A very big cell...A very big cell...A very big cell...
A very big cell...A very big cell...A very big cell...
A very big cell...A very big cell...A very big cell...
]
]
[
[Row 1, Col 0: a small cell]
[Row 1, Col 1: a small cell]
]
]
[h3 Variable Lists]
[pre'''
[variablelist A Variable List
[[term 1] [The definition of term 1]]
[[term 2] [The definition of term 2]]
[[term 3] [The definition of term 3]]
]
''']
will generate:
[variablelist A Variable List
[[term 1] [The definition of term 1]]
[[term 2] [The definition of term 2]]
[[term 3] [The definition of term 3]]
]
The rules for variable lists are the same as for tables, except that
only 2 "columns" are allowed. The first column contains the terms, and
the second column contains the definitions. Those familiar with HTML
will recognize this as a "definition list".
[endsect]
[section:ref Quick Reference]
[table Syntax Compendium
[[To do this...] [Use this...]]
[[comment] [[^'''[/ some comment]''']]]
[[['italics]] [[^'''['italics] or /italics/''']]]
[[[*bold]] [[^'''[*bold] or *bold*''']]]
[[[_underline]] [[^'''[_underline] or _underline_''']]]
[[[^teletype]] [[^'''[^teletype] or =teletype=''']]]
[[source mode] [[^\[c++\]] or [^\[python\]]]]
[[inline code] [[^'''`int main();`''']]]
[[line break] [[^'''[br]''']]]
[[line break] [[^'''\n''']]]
[[anchor] [[^'''[#anchor]''']]]
[[link] [[^'''[@http://www.boost.org Boost]''']]]
[[anchor link] [[^'''[link section.anchor Link text]''']]]
[[refentry link] [[^'''[link xml.refentry Link text]''']]]
[[function link] [[^'''[funcref fully::qualified::function_name Link text]''']]]
[[class link] [[^'''[classref fully::qualified::class_name Link text]''']]]
[[member link] [[^'''[memberref fully::qualified::member_name Link text]''']]]
[[enum link] [[^'''[enumref fully::qualified::enum_name Link text]''']]]
[[header link] [[^'''[headerref path/to/header.hpp Link text]''']]]
[[escape] [[^\'\'\'escaped text (no processing/formatting)\'\'\']]]
[[single char escape] [[^\\c]]]
[[images] [[^'''[$image.jpg]''']]]
[[begin section] [[^'''[section The Section Title]''']]]
[[end section] [[^'''[endsect]''']]]
[[paragraph] [No markup. Paragraphs start left-flushed and are terminated by two or more newlines.]]
[[ordered list] [[^# one\n# two\n# three\n]]]
[[unordered list] [[^\* one\n\* two\n\* three\n]]]
[[code] [No markup. Preformatted code starts with a space or a tab.]]
[[preformatted] [[^'''[pre preformatted]''']]]
[[block quote] [[^'''[:sometext...]''']]]
[[heading 1] [[^'''[h1 Heading 1]''']]]
[[heading 2] [[^'''[h2 Heading 2]''']]]
[[heading 3] [[^'''[h3 Heading 3]''']]]
[[heading 4] [[^'''[h4 Heading 4]''']]]
[[heading 5] [[^'''[h5 Heading 5]''']]]
[[heading 6] [[^'''[h6 Heading 6]''']]]
[[macro] [[^'''[def macro_identifier some text]''']]]
[[blurb] [[^'''[blurb advertisement or note...]''']]]
[[table] [[^[table Title\n \[\[a\]\[b\]\[c\]\]\n \[\[a\]\[b\]\[c\]\]\n\]]]]
[[variablelist] [[^[variablelist Title\n \[\[a\]\[b\]\]\n \[\[a\]\[b\]\]\n\]]]]
]
[endsect]
[section:docinfo Library Document Grammar]
[c++]
doc_info =
space
>> '['
>> ( str_p("book")
| "article"
| "library"
| "chapter"
| "part"
)
>> hard_space
>> ( *(anychar_p -
(ch_p('[') | ']' | eol_p)
)
)
>> *( doc_version
| doc_id
| doc_dirname
| doc_copyright
| doc_purpose
| doc_category
| doc_authors
| doc_license
| doc_last_revision
)
>> ']' >> +eol_p
;
doc_version =
space
>> "[version" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_id =
space
>> "[id" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_dirname =
space
>> "[dirname" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_copyright =
space
>> "[copyright" >> hard_space
>> +( repeat_p(4)[digit_p]
>> space
)
>> space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_purpose =
space
>> "[purpose" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_category =
space
>> "[category" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_author =
space
>> '[' >> space
>> (*(anychar_p - ','))
>> ',' >> space
>> (*(anychar_p - ']'))
>> ']'
;
doc_authors =
space
>> "[authors" >> hard_space
>> doc_author
>> *( ','
>> doc_author
)
>> ']' >> +eol_p
;
doc_license =
space
>> "[license" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_last_revision =
space
>> "[last-revision" >> hard_space
>> (*(anychar_p - ']'))
>> ']' >> +eol_p
;
doc_source_mode =
space
>> "[source-mode" >> hard_space
>> (
str_p("c++")
| "python"
)
>> space >> ']' >> +eol_p
;
comment =
"[/" >> *(anychar_p - ']') >> ']'
;
space =
*(space_p | comment)
;
hard_space =
(eps_p - (alnum_p | '_')) >> space // must not be followed by
; // alpha-numeric or underscore
[endsect]
[section:quickbook QuickBook Grammar]
library =
*(space_p | comment) >> blocks >> blank
;
blocks =
+( block_markup
| code
| list
| hr
| comment >> *eol
| paragraph
| eol
)
;
space =
*(space_p | comment)
;
blank =
*(blank_p | comment)
;
eol = blank >> eol_p
;
close_bracket =
']' |
if_p(var(is_not_preformatted))
[
eol_p >> eol_p // Make sure that we don't go
] // past a single block, except
; // when preformatted.
hard_space =
(eps_p - (alnum_p | '_')) >> space // must not be followed by
; // alpha-numeric or underscore
comment =
"[/" >> *(anychar_p - ']') >> ']'
;
hr =
str_p("----")
>> *(anychar_p - eol)
>> +eol
;
block_markup =
'['
>> ( begin_section
| end_section
| headings
| blurb
| blockquote
| preformatted
| def_macro
| table
| variablelist
| xinclude
)
>> ( (']' >> +eol)
| eps_p
)
;
begin_section =
"section"
>> hard_space
>> (':' >> (*(alnum_p | '_'))
| eps_p
)
>> (*(anychar_p -
close_bracket))
;
end_section =
str_p("endsect")
;
headings =
h1 | h2 | h3 | h4 | h5 | h6
;
h1 = "h1" >> hard_space >> phrase
h2 = "h2" >> hard_space >> phrase
h3 = "h3" >> hard_space >> phrase
h4 = "h4" >> hard_space >> phrase
h5 = "h5" >> hard_space >> phrase
h6 = "h6" >> hard_space >> phrase
blurb =
"blurb" >> hard_space
>> phrase
;
blockquote =
':' >> blank >>
phrase
;
preformatted =
"pre" >> hard_space
>> !eol >> phrase
>> eps_p
;
def_macro =
"def" >> hard_space
>> identifier
>> blank >> phrase
;
table =
"table" >> hard_space
>> (*(anychar_p - eol))
>> +eol
>> *table_row
>> eps_p
;
table_row =
space
>> ch_p('[')
>>
(
(
*table_cell
>> ch_p(']')
>> space
)
| eps_p
)
;
table_cell =
space
>> ch_p('[')
>>
(
(
phrase
>> ch_p(']')
>> space
)
| eps_p
)
;
variablelist =
"variablelist" >> hard_space
>> (*(anychar_p - eol))
>> +eol
>> *varlistentry
>> eps_p
;
varlistentry =
space
>> ch_p('[')
>>
(
(
varlistterm
>> +varlistitem
>> ch_p(']')
>> space
)
| eps_p
)
;
varlistterm =
space
>> ch_p('[')
>>
(
(
phrase
>> ch_p(']')
>> space
)
| eps_p
)
;
varlistitem =
space
>> ch_p('[')
>>
(
(
phrase
>> ch_p(']')
>> space
)
| eps_p
)
;
xinclude =
"xinclude"
>> hard_space
>> (*(anychar_p -
close_bracket))
;
identifier =
*(anychar_p - (space_p | ']'))
;
source_mode =
(
str_p("c++")
| "python"
)
;
code =
(
code_line
>> *(*eol >> code_line)
)
>> +eol
;
code_line =
((ch_p(' ') | '\t'))
>> *(anychar_p - eol) >> eol
;
list =
eps_p(ch_p('*') | '#') >>
+(
(*blank_p
>> (ch_p('*') | '#'))
>> *blank_p
>> list_item
)
;
list_item =
*( common
| (anychar_p -
( eol_p >> *blank_p >> eps_p(ch_p('*') | '#')
| (eol >> eol)
)
)
)
>> +eol
;
common =
self.actions.macro
| phrase_markup
| inline_code
| simple_format
| escape
| comment
;
inline_code =
'`' >>
(
*(anychar_p -
( '`'
| (eol >> eol) // Make sure that we don't go
) // past a single block
) >> eps_p('`')
)
>> '`'
;
simple_format =
simple_bold
| simple_italic
| simple_underline
| simple_teletype
;
simple_bold =
'*' >>
(
( graph_p >> // graph_p must follow '*'
*(anychar_p -
( eol // Make sure that we don't go
| (graph_p >> '*') // past a single line
)
) >> graph_p // graph_p must precede '*'
>> eps_p('*'
>> (space_p | punct_p)) // space_p or punct_p must
) // follow '*'
| (
graph_p // A single char. e.g. *c*
>> eps_p('*'
>> (space_p | punct_p))
)
)
>> '*'
;
simple_italic =
'/' >>
(
( graph_p >> // graph_p must follow '/'
*(anychar_p -
( eol // Make sure that we don't go
| (graph_p >> '/') // past a single line
)
) >> graph_p // graph_p must precede '/'
>> eps_p('/'
>> (space_p | punct_p)) // space_p or punct_p must
) // follow '/'
| (
graph_p // A single char. e.g. /c/
>> eps_p('/'
>> (space_p | punct_p))
)
)
>> '/'
;
simple_underline =
'_' >>
(
( graph_p >> // graph_p must follow '_'
*(anychar_p -
( eol // Make sure that we don't go
| (graph_p >> '_') // past a single line
)
) >> graph_p // graph_p must precede '_'
>> eps_p('_'
>> (space_p | punct_p)) // space_p or punct_p must
) // follow '_'
| (
graph_p // A single char. e.g. _c_
>> eps_p('_'
>> (space_p | punct_p))
)
)
>> '_'
;
simple_teletype =
'=' >>
(
( graph_p >> // graph_p must follow '='
*(anychar_p -
( eol // Make sure that we don't go
| (graph_p >> '=') // past a single line
)
) >> graph_p // graph_p must precede '='
>> eps_p('='
>> (space_p | punct_p)) // space_p or punct_p must
) // follow '='
| (
graph_p // A single char. e.g. =c=
>> eps_p('='
>> (space_p | punct_p))
)
)
>> '='
;
paragraph =
*( common
| (anychar_p - // Make sure we don't go past
(eol >> eol) // a single block.
)
)
>> +eol
;
phrase =
*( common
| comment
| (anychar_p -
close_bracket)
)
;
phrase_markup =
'['
>> ( image
| url
| link
| anchor
| source_mode
| funcref
| classref
| memberref
| enumref
| headerref
| bold
| italic
| underline
| teletype
| str_p("br")
)
>> ']'
;
escape =
str_p("\\n")
| '\\' >> punct_p
| (
"'''" >> !eol
>> *(anychar_p - "'''")
>> "'''"
)
;
image =
'$' >> blank
>> (*(anychar_p -
close_bracket))
;
url =
'@'
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
link =
"link" >> hard_space
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
anchor =
'#'
>> blank
>> ( *(anychar_p -
close_bracket)
)
;
funcref =
"funcref" >> hard_space
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
classref =
"classref" >> hard_space
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
memberref =
"memberref" >> hard_space
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
enumref =
"enumref" >> hard_space
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
headerref =
"headerref" >> hard_space
>> (*(anychar_p -
(']' | hard_space)))
>> ( eps_p(']')
| (hard_space >> phrase)
)
;
bold =
ch_p('*')
>> blank >> phrase
;
italic =
ch_p('\'')
>> blank >> phrase
;
underline =
ch_p('_')
>> blank >> phrase
;
teletype =
ch_p('^')
>> blank >> phrase
;
[endsect]
[section:highlight C++ Syntax Highlighting Grammar]
program
=
*( macro
| preprocessor
| comment
| keyword
| identifier
| special
| string_
| char_
| number
| space_p
| anychar_p
)
;
macro
= *space_p >> self.macro
;
preprocessor
= *space_p >> '#' >> ((alpha_p | '_') >> *(alnum_p | '_'))
;
comment
= +(*space_p >> (comment_p("//") | comment_p("/*", "*/")))
;
keyword
= *space_p >> keyword_ >> (eps_p - (alnum_p | '_'))
; // make sure we recognize whole words only
keyword_
= "and_eq", "and", "asm", "auto", "bitand", "bitor",
"bool", "break", "case", "catch", "char", "class",
"compl", "const_cast", "const", "continue", "default",
"delete", "do", "double", "dynamic_cast", "else",
"enum", "explicit", "export", "extern", "false",
"float", "for", "friend", "goto", "if", "inline",
"int", "long", "mutable", "namespace", "new", "not_eq",
"not", "operator", "or_eq", "or", "private",
"protected", "public", "register", "reinterpret_cast",
"return", "short", "signed", "sizeof", "static",
"static_cast", "struct", "switch", "template", "this",
"throw", "true", "try", "typedef", "typeid",
"typename", "union", "unsigned", "using", "virtual",
"void", "volatile", "wchar_t", "while", "xor_eq", "xor"
;
special
= *space_p >> +chset_p("~!%^&*()+={[}]:;,<.>?/|\\-")
;
string_
= *space_p >> !as_lower_d['l'] >> confix_p('"', *c_escape_ch_p, '"')
;
char_
= *space_p >> !as_lower_d['l'] >> confix_p('\'', *c_escape_ch_p, '\'')
;
number
= *space_p >>
( as_lower_d["0x"] >> hex_p
| '0' >> oct_p
| real_p
)
>> *as_lower_d[chset_p("ldfu")]
;
identifier
= *space_p >> ((alpha_p | '_') >> *(alnum_p | '_'))
;
[endsect]
[section:pyhighlight Python Syntax Highlighting Grammar]
[c++]
program
=
*( macro
| comment
| keyword
| identifier
| special
| string_
| number
| space_p
| anychar_p
)
;
macro
= *space_p >> self.macro
;
comment
= +(*space_p >> comment_p("#"))
;
keyword
= *space_p >> keyword_ >> (eps_p - (alnum_p | '_'))
; // make sure we recognize whole words only
keyword_
=
"and", "del", "for", "is", "raise",
"assert", "elif", "from", "lambda", "return",
"break", "else", "global", "not", "try",
"class", "except", "if", "or", "while",
"continue", "exec", "import", "pass", "yield",
"def", "finally", "in", "print",
// Technically "as" and "None" are not yet keywords (at Python
// 2.4). They are destined to become keywords, and we treat them
// as such for syntax highlighting purposes.
"as", "None"
;
special
= *space_p >> +chset_p("~!%^&*()+={[}]:;,<.>/|\\-")
;
string_prefix
= as_lower_d[str_p("u") >> ! str_p("r")]
;
string_
= *space_p >> ! string_prefix >> (long_string | short_string)
;
short_string
= confix_p('"', * c_escape_ch_p, '"') |
confix_p('\'', * c_escape_ch_p, '\'')
;
long_string
= confix_p("'''", * lex_escape_ch_p, "'''") |
confix_p("\"\"\"", * lex_escape_ch_p, "\"\"\"")
;
number
= *space_p >>
(
as_lower_d["0x"] >> hex_p
| '0' >> oct_p
| real_p
)
>> *as_lower_d[chset_p("lj")]
;
identifier
= *space_p >> ((alpha_p | '_') >> *(alnum_p | '_'))
;
[endsect]