[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]