| Home | Libraries | People | FAQ | More

## 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
        ;

| Copyright © 2002, 2004 Joel de Guzman, Eric Niebler