mirror of
https://github.com/boostorg/quickbook.git
synced 2026-01-27 07:02:15 +00:00
574 lines
22 KiB
C++
Executable File
574 lines
22 KiB
C++
Executable File
/*=============================================================================
|
|
Copyright (c) 2002 2004 Joel de Guzman
|
|
Copyright (c) 2004 Eric Niebler
|
|
http://spirit.sourceforge.net/
|
|
|
|
Use, modification and distribution is subject to 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)
|
|
=============================================================================*/
|
|
#if !defined(BOOST_SPIRIT_QUICKBOOK_HPP)
|
|
#define BOOST_SPIRIT_QUICKBOOK_HPP
|
|
|
|
#include "detail/utils.hpp"
|
|
#include <boost/spirit/core.hpp>
|
|
#include <boost/spirit/utility/confix.hpp>
|
|
#include <boost/spirit/utility/chset.hpp>
|
|
#include <boost/spirit/actor/assign_actor.hpp>
|
|
#include <boost/spirit/dynamic/if.hpp>
|
|
|
|
namespace quickbook
|
|
{
|
|
using namespace boost::spirit;
|
|
|
|
template <typename Actions>
|
|
struct quickbook_grammar
|
|
: public grammar<quickbook_grammar<Actions> >
|
|
{
|
|
quickbook_grammar(Actions& actions_)
|
|
: actions(actions_) {}
|
|
|
|
template <typename Scanner>
|
|
struct definition
|
|
{
|
|
definition(quickbook_grammar const& self)
|
|
: is_not_preformatted(true)
|
|
{
|
|
using detail::var;
|
|
|
|
library =
|
|
*(space_p | comment) >> blocks >> blank
|
|
;
|
|
|
|
blocks =
|
|
+( block_markup
|
|
| code
|
|
| list [self.actions.list]
|
|
| hr [self.actions.hr]
|
|
| comment >> *eol
|
|
| paragraph [self.actions.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 [self.actions.error]
|
|
)
|
|
;
|
|
|
|
begin_section =
|
|
"section"
|
|
>> hard_space
|
|
>> (':' >> (*(alnum_p | '_')) [assign_a(self.actions.section_id)]
|
|
| eps_p [assign_a(self.actions.section_id)]
|
|
)
|
|
>> (*(anychar_p -
|
|
close_bracket)) [self.actions.begin_section]
|
|
;
|
|
|
|
end_section =
|
|
str_p("endsect") [self.actions.end_section]
|
|
;
|
|
|
|
headings =
|
|
h1 | h2 | h3 | h4 | h5 | h6
|
|
;
|
|
|
|
h1 = "h1" >> hard_space >> phrase [self.actions.h1];
|
|
h2 = "h2" >> hard_space >> phrase [self.actions.h2];
|
|
h3 = "h3" >> hard_space >> phrase [self.actions.h3];
|
|
h4 = "h4" >> hard_space >> phrase [self.actions.h4];
|
|
h5 = "h5" >> hard_space >> phrase [self.actions.h5];
|
|
h6 = "h6" >> hard_space >> phrase [self.actions.h6];
|
|
|
|
blurb =
|
|
"blurb" >> hard_space
|
|
>> phrase [self.actions.blurb]
|
|
;
|
|
|
|
blockquote =
|
|
':' >> blank >>
|
|
phrase [self.actions.blockquote]
|
|
;
|
|
|
|
preformatted =
|
|
"pre" >> hard_space [assign_a(is_not_preformatted, false)]
|
|
>> !eol >> phrase [self.actions.preformatted]
|
|
>> eps_p [assign_a(is_not_preformatted, true)]
|
|
;
|
|
|
|
def_macro =
|
|
"def" >> hard_space
|
|
>> identifier [self.actions.identifier]
|
|
>> blank >> phrase [self.actions.macro_def]
|
|
;
|
|
|
|
variablelist =
|
|
"variablelist" >> hard_space
|
|
>> (*(anychar_p - eol)) [assign_a(self.actions.table_title)]
|
|
>> +eol
|
|
>> *varlistentry
|
|
>> eps_p [self.actions.variablelist]
|
|
;
|
|
|
|
varlistentry =
|
|
space
|
|
>> ch_p('[') [self.actions.start_varlistentry]
|
|
>>
|
|
(
|
|
(
|
|
varlistterm
|
|
>> +varlistitem
|
|
>> ch_p(']') [self.actions.end_varlistentry]
|
|
>> space
|
|
)
|
|
| eps_p [self.actions.error]
|
|
)
|
|
;
|
|
|
|
varlistterm =
|
|
space
|
|
>> ch_p('[') [self.actions.start_varlistterm]
|
|
>>
|
|
(
|
|
(
|
|
phrase
|
|
>> ch_p(']') [self.actions.end_varlistterm]
|
|
>> space
|
|
)
|
|
| eps_p [self.actions.error]
|
|
)
|
|
;
|
|
|
|
varlistitem =
|
|
space
|
|
>> ch_p('[') [self.actions.start_varlistitem]
|
|
>>
|
|
(
|
|
(
|
|
phrase [self.actions.end_varlistitem]
|
|
>> ch_p(']')
|
|
>> space
|
|
)
|
|
| eps_p [self.actions.error]
|
|
)
|
|
;
|
|
|
|
table =
|
|
"table" >> hard_space
|
|
>> (*(anychar_p - eol)) [assign_a(self.actions.table_title)]
|
|
>> +eol
|
|
>> *table_row
|
|
>> eps_p [self.actions.table]
|
|
;
|
|
|
|
table_row =
|
|
space
|
|
>> ch_p('[') [self.actions.start_row]
|
|
>>
|
|
(
|
|
(
|
|
*table_cell
|
|
>> ch_p(']') [self.actions.end_row]
|
|
>> space
|
|
)
|
|
| eps_p [self.actions.error]
|
|
)
|
|
;
|
|
|
|
table_cell =
|
|
space
|
|
>> ch_p('[') [self.actions.start_cell]
|
|
>>
|
|
(
|
|
(
|
|
phrase
|
|
>> ch_p(']') [self.actions.end_cell]
|
|
>> space
|
|
)
|
|
| eps_p [self.actions.error]
|
|
)
|
|
;
|
|
|
|
xinclude =
|
|
"xinclude"
|
|
>> hard_space
|
|
>> (*(anychar_p -
|
|
close_bracket)) [self.actions.xinclude]
|
|
;
|
|
|
|
identifier =
|
|
*(anychar_p - (space_p | ']'))
|
|
;
|
|
|
|
source_mode =
|
|
(
|
|
str_p("c++")
|
|
| "python"
|
|
) [assign_a(self.actions.source_mode)]
|
|
;
|
|
|
|
code =
|
|
(
|
|
code_line
|
|
>> *(*eol >> code_line)
|
|
) [self.actions.code]
|
|
>> +eol
|
|
;
|
|
|
|
code_line =
|
|
((ch_p(' ') | '\t'))
|
|
>> *(anychar_p - eol) >> eol
|
|
;
|
|
|
|
list =
|
|
eps_p(ch_p('*') | '#') >>
|
|
+(
|
|
(*blank_p
|
|
>> (ch_p('*') | '#')) [self.actions.list_format]
|
|
>> *blank_p
|
|
>> list_item
|
|
) [self.actions.list_item]
|
|
;
|
|
|
|
list_item =
|
|
*( common
|
|
| (anychar_p -
|
|
( eol_p >> *blank_p >> eps_p(ch_p('*') | '#')
|
|
| (eol >> eol)
|
|
)
|
|
) [self.actions.plain_char]
|
|
)
|
|
>> +eol
|
|
;
|
|
|
|
common =
|
|
self.actions.macro [self.actions.do_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('`')
|
|
) [self.actions.inline_code]
|
|
>> '`'
|
|
;
|
|
|
|
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))
|
|
)
|
|
) [self.actions.simple_bold]
|
|
>> '*'
|
|
;
|
|
|
|
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))
|
|
)
|
|
) [self.actions.simple_italic]
|
|
>> '/'
|
|
;
|
|
|
|
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))
|
|
)
|
|
) [self.actions.simple_underline]
|
|
>> '_'
|
|
;
|
|
|
|
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))
|
|
)
|
|
) [self.actions.simple_teletype]
|
|
>> '='
|
|
;
|
|
|
|
paragraph =
|
|
*( common
|
|
| (anychar_p - // Make sure we don't go past
|
|
(eol >> eol) // a single block.
|
|
) [self.actions.plain_char]
|
|
)
|
|
>> +eol
|
|
;
|
|
|
|
phrase =
|
|
*( common
|
|
| comment
|
|
| (anychar_p -
|
|
close_bracket) [self.actions.plain_char]
|
|
)
|
|
;
|
|
|
|
phrase_markup =
|
|
'['
|
|
>> ( image
|
|
| url
|
|
| link
|
|
| anchor
|
|
| source_mode
|
|
| funcref
|
|
| classref
|
|
| memberref
|
|
| enumref
|
|
| headerref
|
|
| bold
|
|
| italic
|
|
| underline
|
|
| teletype
|
|
| str_p("br") [self.actions.break_]
|
|
)
|
|
>> ']'
|
|
;
|
|
|
|
escape =
|
|
str_p("\\n") [self.actions.break_]
|
|
| '\\' >> punct_p [self.actions.raw_char]
|
|
| (
|
|
"'''" >> !eol
|
|
>> *(anychar_p - "'''") [self.actions.raw_char]
|
|
>> "'''"
|
|
)
|
|
;
|
|
|
|
image =
|
|
'$' >> blank
|
|
>> (*(anychar_p -
|
|
close_bracket)) [self.actions.image]
|
|
;
|
|
|
|
url =
|
|
'@'
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.url_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.url_post]
|
|
;
|
|
|
|
link =
|
|
"link" >> hard_space
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.link_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.link_post]
|
|
;
|
|
|
|
anchor =
|
|
'#'
|
|
>> blank
|
|
>> ( *(anychar_p -
|
|
close_bracket)
|
|
) [self.actions.anchor]
|
|
;
|
|
|
|
funcref =
|
|
"funcref" >> hard_space
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.funcref_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.funcref_post]
|
|
;
|
|
|
|
classref =
|
|
"classref" >> hard_space
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.classref_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.classref_post]
|
|
;
|
|
|
|
memberref =
|
|
"memberref" >> hard_space
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.memberref_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.memberref_post]
|
|
;
|
|
|
|
enumref =
|
|
"enumref" >> hard_space
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.enumref_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.enumref_post]
|
|
;
|
|
|
|
headerref =
|
|
"headerref" >> hard_space
|
|
>> (*(anychar_p -
|
|
(']' | hard_space))) [self.actions.headerref_pre]
|
|
>> ( eps_p(']')
|
|
| (hard_space >> phrase)
|
|
) [self.actions.headerref_post]
|
|
;
|
|
|
|
bold =
|
|
ch_p('*') [self.actions.bold_pre]
|
|
>> blank >> phrase [self.actions.bold_post]
|
|
;
|
|
|
|
italic =
|
|
ch_p('\'') [self.actions.italic_pre]
|
|
>> blank >> phrase [self.actions.italic_post]
|
|
;
|
|
|
|
underline =
|
|
ch_p('_') [self.actions.underline_pre]
|
|
>> blank >> phrase [self.actions.underline_post]
|
|
;
|
|
|
|
teletype =
|
|
ch_p('^') [self.actions.teletype_pre]
|
|
>> blank >> phrase [self.actions.teletype_post]
|
|
;
|
|
}
|
|
|
|
bool is_not_preformatted;
|
|
|
|
rule<Scanner> library, blocks, lib_info, block_markup, source_mode, code,
|
|
code_line, paragraph, space, blank, comment, headings,
|
|
h1, h2, h3, h4, h5, h6, hr, blurb, blockquote,
|
|
phrase, phrase_markup, image, list, close_bracket,
|
|
ordered_list, bold, italic, underline, teletype,
|
|
escape, def_macro, identifier, url, table, table_row,
|
|
variablelist, varlistentry, varlistterm, varlistitem,
|
|
table_cell, preformatted, list_item, common,
|
|
funcref, classref, memberref, enumref, headerref, anchor, link,
|
|
begin_section, end_section, xinclude, hard_space, eol,
|
|
inline_code, simple_format, simple_bold, simple_italic,
|
|
simple_underline, simple_teletype;
|
|
|
|
rule<Scanner> const&
|
|
start() const { return library; }
|
|
};
|
|
|
|
Actions& actions;
|
|
};
|
|
}
|
|
|
|
#endif // BOOST_SPIRIT_QUICKBOOK_HPP
|
|
|