From b783f785dfd5fab4d10deb7df89513b34fe27846 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 15 Sep 2010 22:54:21 +0000 Subject: [PATCH] Merge quickbook from trunk. [SVN r65433] --- doc/quickbook.qbk | 7 +- src/actions.cpp | 141 ++++----- src/actions.hpp | 160 ++++------ src/actions_class.cpp | 62 ++-- src/actions_class.hpp | 26 +- src/block_grammar.cpp | 219 +++++++------- src/code_snippet.cpp | 169 ++++++----- src/doc_info_actions.cpp | 36 ++- src/doc_info_grammar.cpp | 116 ++++--- src/fwd.hpp | 27 ++ src/grammar.hpp | 20 +- src/phrase_grammar.cpp | 498 ++----------------------------- src/phrase_grammar.hpp | 439 +++++++++++++++++++++++++++ src/post_process.cpp | 44 +-- src/quickbook.cpp | 46 ++- src/quickbook.hpp | 38 +-- src/scoped_block.hpp | 134 +++++++++ src/syntax_highlight.cpp | 13 +- src/syntax_highlight.hpp | 152 +++++----- src/template_stack.hpp | 29 +- test/Jamfile.v2 | 3 +- test/blocks.gold | 3 + test/blocks.quickbook | 5 +- test/callouts.cpp | 2 + test/doc-info-1.gold | 1 + test/doc-info-1.quickbook | 5 +- test/doc-info-2.gold | 16 +- test/doc-info-2.quickbook | 9 +- test/link-side-by-side.gold | 16 - test/link-side-by-side.quickbook | 13 - test/link.gold | 30 ++ test/link.quickbook | 39 +++ test/list_test.gold | 21 ++ test/list_test.quickbook | 7 + test/macro.gold | 14 + test/macro.quickbook | 16 + test/templates.gold | 43 +++ test/templates.quickbook | 22 ++ test/xml-escape_1_5.gold | 8 +- test/xml-escape_1_5.quickbook | 2 +- 40 files changed, 1521 insertions(+), 1130 deletions(-) create mode 100644 src/fwd.hpp create mode 100644 src/scoped_block.hpp delete mode 100644 test/link-side-by-side.gold delete mode 100644 test/link-side-by-side.quickbook create mode 100644 test/link.gold create mode 100644 test/link.quickbook create mode 100644 test/macro.gold create mode 100644 test/macro.quickbook diff --git a/doc/quickbook.qbk b/doc/quickbook.qbk index 5139322..95fcd64 100644 --- a/doc/quickbook.qbk +++ b/doc/quickbook.qbk @@ -230,11 +230,12 @@ Features include: * In docbook, variable list entries can only have one `listitem`, so if an entry has multiple values, merge them into one `listitem`. * Support nested code snippets. -* Allow escapes in doc info fields (apart from `\n`). -* Don't escape the raw markup for versions less than 1.3, for better - compatibility with older documentation. +* Revert xml escaping document info, it broke some documentation files + (now a 1.6 feature). * Further work on quickbook 1.6, still not stable. * Allow heading to have ids, using the syntax: `[heading:id title]`. + * XML escape documentation fields, with escapes to allow encoding unicode + in ASCII. [endsect] diff --git a/src/actions.cpp b/src/actions.cpp index 6a1e620..8c51b66 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -26,6 +26,10 @@ namespace quickbook char const* quickbook_get_date = "__quickbook_get_date__"; char const* quickbook_get_time = "__quickbook_get_time__"; + int qbk_major_version = -1; + int qbk_minor_version = -1; + unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version + namespace { std::string fully_qualified_id(std::string const& library_id, std::string const& qualified_section_id, @@ -43,7 +47,7 @@ namespace quickbook // Handles line-breaks (DEPRECATED!!!) void break_action::operator()(iterator first, iterator) const { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", " << "[br] and \\n are deprecated" << ".\n"; phrase << break_mark; @@ -51,12 +55,17 @@ namespace quickbook void error_action::operator()(iterator first, iterator /*last*/) const { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Syntax Error near column " << pos.column << ".\n"; ++error_count; } + void tagged_action::operator()(std::string const& str) const + { + out << pre << str << post; + } + void phrase_action::operator()(iterator first, iterator last) const { std::string str; @@ -271,7 +280,7 @@ namespace quickbook if (mark != list_marks.top().first) // new_indent == list_indent { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Illegal change of list style near column " << pos.column << ".\n"; detail::outwarn(pos.file,pos.line) @@ -290,7 +299,7 @@ namespace quickbook void unexpected_char::operator()(iterator first, iterator last) const { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outwarn(pos.file, pos.line) << "in column:" << pos.column @@ -371,7 +380,7 @@ namespace quickbook phrase.swap(save); // print the code with syntax coloring - std::string str = syntax_p(first_, last_); + std::string str = syntax_highlight(first_, last_, actions, actions.source_mode); phrase.swap(save); @@ -390,7 +399,7 @@ namespace quickbook out.swap(save); // print the code with syntax coloring - std::string str = syntax_p(first, last); + std::string str = syntax_highlight(first, last, actions, actions.source_mode); out.swap(save); @@ -440,7 +449,7 @@ namespace quickbook void attribute_action::operator()(iterator first, iterator last) const { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); if (!attributes.insert( attribute_map::value_type(attribute_name, std::string(first, last)) @@ -563,6 +572,7 @@ namespace quickbook void macro_definition_action::operator()(iterator first, iterator last) const { + actions.copy_macros_for_write(); actions.macro.add( actions.macro_id.begin() , actions.macro_id.end() @@ -577,7 +587,7 @@ namespace quickbook std::string(first, last), first.get_position(), actions.template_block, &actions.templates.top_scope()))) { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Template Redefinition: " << actions.template_identifier << std::endl; ++actions.error_count; @@ -647,7 +657,7 @@ namespace quickbook bool break_arguments( std::vector& args , std::vector const& params - , boost::spirit::classic::file_position const& pos + , position const& pos ) { // Quickbook 1.4-: If there aren't enough parameters seperated by @@ -668,7 +678,8 @@ namespace quickbook // arguments, or if there are no more spaces left. template_body& body = args.back(); - iterator begin(body.content.begin(), body.content.end(), body.position.file); + iterator begin(body.content.begin(), body.content.end(), + position(body.position.file.c_str(), body.position.line, body.position.column)); iterator end(body.content.end(), body.content.end()); iterator l_pos = find_first_seperator(begin, end); @@ -680,7 +691,7 @@ namespace quickbook while(r_pos != end && std::find(whitespace, whitespace_end, *r_pos) != whitespace_end) ++r_pos; if (r_pos == end) break; - template_body second(std::string(r_pos, end), begin.get_position(), false); + template_body second(std::string(r_pos, end), r_pos.get_position(), false); body.content = std::string(begin, l_pos); args.push_back(second); } @@ -705,7 +716,7 @@ namespace quickbook std::vector& args , std::vector const& params , template_scope const& scope - , boost::spirit::classic::file_position const& pos + , position const& pos , quickbook::actions& actions ) { @@ -734,7 +745,6 @@ namespace quickbook bool parse_template( template_body const& body , bool escape - , std::string& result , quickbook::actions& actions ) { @@ -749,7 +759,7 @@ namespace quickbook { // escape the body of the template // we just copy out the literal body - result = body.content; + (body.is_block ? actions.out : actions.phrase) << body.content; return true; } else if (!body.is_block) @@ -757,11 +767,10 @@ namespace quickbook simple_phrase_grammar phrase_p(actions); // do a phrase level parse - iterator first(body.content.begin(), body.content.end(), body.position); + iterator first(body.content.begin(), body.content.end(), + position(body.position.file.c_str(), body.position.line, body.position.column)); iterator last(body.content.end(), body.content.end()); - bool r = quickbook::parse(first, last, phrase_p).full; - actions.phrase.swap(result); - return r; + return call_parse(first, last, phrase_p).full; } else { @@ -772,12 +781,10 @@ namespace quickbook // the need to check for end of file in the grammar. std::string content = body.content + "\n\n"; - iterator first(content.begin(), content.end(), body.position); + iterator first(content.begin(), content.end(), + position(body.position.file.c_str(), body.position.line, body.position.column)); iterator last(content.end(), content.end()); - bool r = quickbook::parse(first, last, block_p).full; - actions.inside_paragraph(); - actions.out.swap(result); - return r; + return call_parse(first, last, block_p).full; } } } @@ -804,7 +811,7 @@ namespace quickbook std::string identifier; std::swap(args, actions.template_args); std::swap(identifier, actions.template_identifier); - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); ++actions.template_depth; if (actions.template_depth > actions.max_template_depth) @@ -825,8 +832,10 @@ namespace quickbook template_symbol const* symbol = actions.templates.find(identifier); BOOST_ASSERT(symbol); - - std::string result; + + std::string block; + std::string phrase; + actions.push(); // scope the actions' states { // Store the current section level so that we can ensure that @@ -902,9 +911,9 @@ namespace quickbook /////////////////////////////////// // parse the template body: - if (!parse_template(symbol->body, actions.template_escape, result, actions)) + if (!parse_template(symbol->body, actions.template_escape, actions)) { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Expanding " << (symbol->body.is_block ? "block" : "phrase") @@ -922,7 +931,7 @@ namespace quickbook if (actions.section_level != actions.min_section_level) { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Mismatched sections in template " << identifier << std::endl; actions.pop(); // restore the actions' states @@ -932,11 +941,14 @@ namespace quickbook } } + actions.out.swap(block); + actions.phrase.swap(phrase); actions.pop(); // restore the actions' states if(symbol->callout && symbol->callouts.size() > 0) { - result += ""; + BOOST_ASSERT(phrase.empty()); + block += ""; BOOST_FOREACH(template_body const& c, symbol->callouts) { std::string callout_id = actions.doc_id + @@ -944,31 +956,38 @@ namespace quickbook std::string callout_value; actions.push(); - bool r = parse_template(c, false, callout_value, actions); + bool r = parse_template(c, false, actions); + actions.out.swap(callout_value); actions.pop(); if(!r) { detail::outerr(c.position.file, c.position.line) - << "Expanding callout." << std::endl; + << "Expanding callout." << std::endl + << "------------------begin------------------" << std::endl + << c.content + << std::endl + << "------------------end--------------------" << std::endl + ; ++actions.error_count; return; } - result += ""; - result += callout_value; - result += ""; + block += ""; + block += callout_value; + block += ""; } - result += ""; + block += ""; } - if(symbol->body.is_block) { + if(symbol->body.is_block || !block.empty()) { actions.inside_paragraph(); - actions.temp_para << result; // print it!!! + actions.out << block; + actions.phrase << phrase; } else { - actions.phrase << result; // print it!!! + actions.phrase << phrase; } --actions.template_depth; } @@ -1015,20 +1034,6 @@ namespace quickbook actions.table_title.clear(); } - void start_varlistitem_action::operator()() const - { - phrase << start_varlistitem_; - phrase.push(); - } - - void end_varlistitem_action::operator()() const - { - std::string str; - temp_para.swap(str); - phrase.pop(); - phrase << str << end_varlistitem_; - } - void table_action::operator()(iterator, iterator) const { std::string::iterator first = actions.table_title.begin(); @@ -1114,21 +1119,12 @@ namespace quickbook (*this)(*f); } - void start_col_action::operator()(char) const + void col_action::operator()(std::string const& contents) const { - phrase << start_cell_; - phrase.push(); + phrase << start_cell_ << contents << end_cell_; ++span; } - void end_col_action::operator()(char) const - { - std::string str; - temp_para.swap(str); - phrase.pop(); - phrase << str << end_cell_; - } - void begin_section_action::operator()(iterator first, iterator last) const { section_id = element_id.empty() ? @@ -1175,7 +1171,7 @@ namespace quickbook { if (section_level <= min_section_level) { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outerr(pos.file,pos.line) << "Mismatched [endsect] near column " << pos.column << ".\n"; ++error_count; @@ -1200,7 +1196,7 @@ namespace quickbook void element_id_warning_action::operator()(iterator first, iterator) const { - boost::spirit::classic::file_position const pos = first.get_position(); + position const pos = first.get_position(); detail::outwarn(pos.file,pos.line) << "Empty id.\n"; } @@ -1291,7 +1287,7 @@ namespace quickbook ts.parent = &actions.templates.top_scope(); if (!actions.templates.add(ts)) { - boost::spirit::classic::file_position const pos = ts.body.position; + cl::file_position const pos = ts.body.position; detail::outerr(pos.file, pos.line) << "Template Redefinition: " << tname << std::endl; ++actions.error_count; @@ -1329,6 +1325,7 @@ namespace quickbook // scope the macros string_symbols macro = actions.macro; + std::size_t macro_change_depth = actions.macro_change_depth; // scope the templates //~ template_symbols templates = actions.templates; $$$ fixme $$$ @@ -1363,6 +1360,7 @@ namespace quickbook // restore the macros actions.macro = macro; + actions.macro_change_depth = macro_change_depth; // restore the templates //~ actions.templates = templates; $$$ fixme $$$ } @@ -1379,11 +1377,4 @@ namespace quickbook phrase.swap(out.encoded); out.raw = std::string(first, last); } - - void copy_stream_action::operator()(iterator first, iterator last) const - { - std::string str; - phrase.swap(str); - out << str; - } } diff --git a/src/actions.hpp b/src/actions.hpp index 601a1b5..17c32eb 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -10,16 +10,15 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP) #define BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP -#include #include #include #include #include #include -#include #include #include #include +#include "fwd.hpp" #include "collector.hpp" #include "template_stack.hpp" #include "utils.hpp" @@ -35,22 +34,44 @@ namespace quickbook namespace cl = boost::spirit::classic; namespace fs = boost::filesystem; - typedef cl::position_iterator iterator; + extern int qbk_major_version; + extern int qbk_minor_version; + extern unsigned qbk_version_n; // qbk_major_version * 100 + qbk_minor_version + + struct quickbook_range { + template + struct result + { + typedef bool type; + }; + + quickbook_range(unsigned min_, unsigned max_) + : min_(min_), max_(max_) {} + + bool operator()() const { + return qbk_version_n >= min_ && qbk_version_n < max_; + } + + unsigned min_, max_; + }; + + inline quickbook_range qbk_since(unsigned min_) { + return quickbook_range(min_, 999); + } + + inline quickbook_range qbk_before(unsigned max_) { + return quickbook_range(0, max_); + } + typedef cl::symbols string_symbols; typedef std::map attribute_map; - struct actions; - extern tm* current_time; // the current time - extern tm* current_gm_time; // the current UTC time - extern bool debug_mode; - extern std::vector include_path; - extern std::vector preset_defines; - - // forward declarations - struct actions; - int parse_file(char const* filein_, actions& actor, bool ignore_docinfo = false); int load_snippets(std::string const& file, std::vector& storage, std::string const& extension, std::string const& doc_id); + std::string syntax_highlight( + iterator first, iterator last, + actions& escape_actions, + std::string const& source_mode); struct error_action { @@ -65,6 +86,23 @@ namespace quickbook int& error_count; }; + struct tagged_action + { + tagged_action( + collector& out, + std::string const& pre, + std::string const& post) + : out(out) + , pre(pre) + , post(post) {} + + void operator()(std::string const&) const; + + collector& out; + std::string pre; + std::string post; + }; + struct phrase_action { // blurb, blockquote, preformatted, list_item, @@ -471,29 +509,6 @@ namespace quickbook std::string str; }; - struct syntax_highlight - { - syntax_highlight( - collector& temp - , std::string const& source_mode - , string_symbols const& macro - , actions& escape_actions) - : temp(temp) - , source_mode(source_mode) - , macro(macro) - , escape_actions(escape_actions) - { - } - - std::string operator()(iterator begin, iterator end) const; - - collector& temp; - std::string const& source_mode; - string_symbols const& macro; - actions& escape_actions; - }; - - struct code_action { // Does the actual syntax highlighing of code @@ -501,10 +516,10 @@ namespace quickbook code_action( collector& out , collector& phrase - , syntax_highlight& syntax_p) + , quickbook::actions& actions) : out(out) , phrase(phrase) - , syntax_p(syntax_p) + , actions(actions) { } @@ -512,7 +527,7 @@ namespace quickbook collector& out; collector& phrase; - syntax_highlight& syntax_p; + quickbook::actions& actions; }; struct inline_code_action @@ -521,46 +536,15 @@ namespace quickbook inline_code_action( collector& out - , syntax_highlight& syntax_p) + , quickbook::actions& actions) : out(out) - , syntax_p(syntax_p) + , actions(actions) {} void operator()(iterator first, iterator last) const; collector& out; - syntax_highlight& syntax_p; - }; - - struct start_varlistitem_action - { - start_varlistitem_action(collector& phrase) - : phrase(phrase) {} - - void operator()() const; - - template - void operator()(T1 const&) const { return (*this)(); } - template - void operator()(T1 const&, T2 const&) const { return (*this)(); } - - collector& phrase; - }; - - struct end_varlistitem_action - { - end_varlistitem_action(collector& phrase, collector& temp_para) - : phrase(phrase), temp_para(temp_para) {} - - void operator()() const; - - template - void operator()(T1 const&) const { return (*this)(); } - template - void operator()(T1 const&, T2 const&) const { return (*this)(); } - - collector& phrase; - collector& temp_para; + quickbook::actions& actions; }; struct break_action @@ -687,30 +671,17 @@ namespace quickbook std::string& header; }; - struct start_col_action + struct col_action { - // Handles table columns - - start_col_action(collector& phrase, unsigned& span) + col_action(collector& phrase, unsigned& span) : phrase(phrase), span(span) {} - void operator()(char) const; + void operator()(std::string const&) const; collector& phrase; unsigned& span; }; - struct end_col_action - { - end_col_action(collector& phrase, collector& temp_para) - : phrase(phrase), temp_para(temp_para) {} - - void operator()(char) const; - - collector& phrase; - collector& temp_para; - }; - struct begin_section_action { // Handles begin page @@ -854,17 +825,6 @@ namespace quickbook docinfo_string& out; collector& phrase; }; - - struct copy_stream_action - { - copy_stream_action(collector& out, collector& phrase) - : out(out) , phrase(phrase) {} - - void operator()(iterator first, iterator last) const; - - collector& out; - collector& phrase; - }; } #ifdef BOOST_MSVC diff --git a/src/actions_class.cpp b/src/actions_class.cpp index a88819b..cbe2a25 100644 --- a/src/actions_class.cpp +++ b/src/actions_class.cpp @@ -10,6 +10,7 @@ =============================================================================*/ #include "actions_class.hpp" #include "markups.hpp" +#include "quickbook.hpp" #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) #pragma warning(disable:4355) @@ -37,12 +38,12 @@ namespace quickbook // auxilliary streams , phrase() - , temp() , list_buffer() // state , filename(fs::complete(fs::path(filein_))) , outdir(outdir_) + , macro_change_depth(0) , macro() , section_level(0) , min_section_level(0) @@ -81,12 +82,11 @@ namespace quickbook , extract_name_first(name.first, phrase) , extract_doc_last_revision(doc_last_revision, phrase) , extract_doc_category(doc_category, phrase) - , syntax_p(temp, source_mode, macro, *this) - , code(out, phrase, syntax_p) - , code_block(phrase, phrase, syntax_p) - , inline_code(phrase, syntax_p) - , inside_paragraph(temp_para, phrase, paragraph_pre, paragraph_post) - , write_paragraphs(out, temp_para) + , extract_doc_biblioid(doc_biblioid.second, phrase) + , code(out, phrase, *this) + , code_block(phrase, phrase, *this) + , inline_code(phrase, *this) + , inside_paragraph(out, phrase, paragraph_pre, paragraph_post) , h(out, phrase, element_id, doc_id, section_id, qualified_section_id, section_level) , h1(out, phrase, element_id, doc_id, section_id, qualified_section_id, h1_pre, h1_post) , h2(out, phrase, element_id, doc_id, section_id, qualified_section_id, h2_pre, h2_post) @@ -95,14 +95,14 @@ namespace quickbook , h5(out, phrase, element_id, doc_id, section_id, qualified_section_id, h5_pre, h5_post) , h6(out, phrase, element_id, doc_id, section_id, qualified_section_id, h6_pre, h6_post) , hr(out, hr_) - , blurb(out, temp_para, blurb_pre, blurb_post) - , blockquote(out, temp_para, blockquote_pre, blockquote_post) + , blurb(out, blurb_pre, blurb_post) + , blockquote(out, blockquote_pre, blockquote_post) , preformatted(out, phrase, preformatted_pre, preformatted_post) - , warning(out, temp_para, warning_pre, warning_post) - , caution(out, temp_para, caution_pre, caution_post) - , important(out, temp_para, important_pre, important_post) - , note(out, temp_para, note_pre, note_post) - , tip(out, temp_para, tip_pre, tip_post) + , warning(out, warning_pre, warning_post) + , caution(out, caution_pre, caution_post) + , important(out, important_pre, important_post) + , note(out, note_pre, note_post) + , tip(out, tip_pre, tip_post) , plain_char(phrase) , raw_char(phrase) , escape_unicode(phrase) @@ -160,8 +160,7 @@ namespace quickbook , end_varlistentry(phrase, end_varlistentry_) , start_varlistterm(phrase, start_varlistterm_) , end_varlistterm(phrase, end_varlistterm_) - , start_varlistitem(phrase) - , end_varlistitem(phrase, temp_para) + , varlistitem(phrase, start_varlistitem_, end_varlistitem_) , break_(phrase) , macro_identifier(*this) @@ -177,8 +176,7 @@ namespace quickbook , table(*this) , start_row(phrase, table_span, table_header) , end_row(phrase, end_row_) - , start_cell(phrase, table_span) - , end_cell(phrase, temp_para) + , cell(phrase, table_span) , anchor(out) , begin_section(out, phrase, doc_id, section_id, section_level, qualified_section_id, element_id) @@ -209,7 +207,7 @@ namespace quickbook boost::make_tuple( filename , outdir - , macro + , macro_change_depth , section_level , min_section_level , section_id @@ -220,18 +218,36 @@ namespace quickbook out.push(); phrase.push(); - temp.push(); - temp_para.push(); list_buffer.push(); templates.push(); } + + // Pushing and popping the macro symbol table is pretty expensive, so + // instead implement a sort of 'stack on write'. Call this whenever a + // change is made to the macro table, and it'll stack the current macros + // if necessary. Would probably be better to implement macros in a less + // expensive manner. + void actions::copy_macros_for_write() + { + if(macro_change_depth != state_stack.size()) + { + macro_stack.push(macro); + macro_change_depth = state_stack.size(); + } + } void actions::pop() { + if(macro_change_depth == state_stack.size()) + { + macro = macro_stack.top(); + macro_stack.pop(); + } + boost::tie( filename , outdir - , macro + , macro_change_depth , section_level , min_section_level , section_id @@ -242,8 +258,6 @@ namespace quickbook out.pop(); phrase.pop(); - temp.pop(); - temp_para.pop(); list_buffer.pop(); templates.pop(); } diff --git a/src/actions_class.hpp b/src/actions_class.hpp index 39fb34d..25574f8 100644 --- a/src/actions_class.hpp +++ b/src/actions_class.hpp @@ -33,6 +33,8 @@ namespace quickbook typedef std::vector author_list; typedef std::pair copyright_item; typedef std::vector copyright_list; + typedef std::pair biblioid_item; + typedef std::vector biblioid_list; typedef std::pair mark_type; static int const max_template_depth = 100; @@ -48,8 +50,10 @@ namespace quickbook author_list doc_authors; docinfo_string doc_license; docinfo_string doc_last_revision; + biblioid_list doc_biblioid_items; std::string include_doc_id; //temporary state + biblioid_item doc_biblioid; docinfo_string doc_id_tmp; author name; copyright_item copyright; @@ -61,13 +65,12 @@ namespace quickbook // auxilliary streams collector phrase; - collector temp; - collector temp_para; collector list_buffer; // state fs::path filename; fs::path outdir; + std::size_t macro_change_depth; string_symbols macro; int section_level; int min_section_level; @@ -78,7 +81,7 @@ namespace quickbook typedef boost::tuple< fs::path , fs::path - , string_symbols + , std::size_t , int , int , std::string @@ -87,6 +90,8 @@ namespace quickbook state_tuple; std::stack state_stack; + // Stack macros separately as copying macros is expensive. + std::stack macro_stack; // temporary or global state std::string element_id; @@ -111,6 +116,7 @@ namespace quickbook attribute_map attributes; // push/pop the states and the streams + void copy_macros_for_write(); void push(); void pop(); @@ -129,18 +135,18 @@ namespace quickbook phrase_to_docinfo_action extract_name_first; phrase_to_docinfo_action extract_doc_last_revision; phrase_to_docinfo_action extract_doc_category; + phrase_to_docinfo_action extract_doc_biblioid; - syntax_highlight syntax_p; code_action code; code_action code_block; inline_code_action inline_code; implicit_paragraph_action inside_paragraph; - copy_stream_action write_paragraphs; generic_header_action h; header_action h1, h2, h3, h4, h5, h6; markup_action hr; - phrase_action blurb, blockquote, preformatted; - phrase_action warning, caution, important, note, tip; + tagged_action blurb, blockquote; + phrase_action preformatted; + tagged_action warning, caution, important, note, tip; plain_char_action plain_char; raw_char_action raw_char; escape_unicode_action escape_unicode; @@ -198,8 +204,7 @@ namespace quickbook markup_action end_varlistentry; markup_action start_varlistterm; markup_action end_varlistterm; - start_varlistitem_action start_varlistitem; - end_varlistitem_action end_varlistitem; + tagged_action varlistitem; break_action break_; macro_identifier_action macro_identifier; @@ -215,8 +220,7 @@ namespace quickbook table_action table; start_row_action start_row; markup_action end_row; - start_col_action start_cell; - end_col_action end_cell; + col_action cell; anchor_action anchor; begin_section_action begin_section; diff --git a/src/block_grammar.cpp b/src/block_grammar.cpp index 50baca2..7e2f777 100644 --- a/src/block_grammar.cpp +++ b/src/block_grammar.cpp @@ -9,9 +9,9 @@ =============================================================================*/ #include "phrase_grammar.hpp" -#include "quickbook.hpp" #include "utils.hpp" #include "actions_class.hpp" +#include "scoped_block.hpp" #include #include #include @@ -21,7 +21,7 @@ namespace quickbook { - using namespace boost::spirit::classic; + namespace cl = boost::spirit::classic; template struct block_grammar::definition @@ -30,7 +30,8 @@ namespace quickbook bool no_eols; - rule start_, blocks, block_markup, code, code_line, blank_line, + cl::rule + start_, blocks, block_markup, code, code_line, blank_line, paragraph, space, blank, comment, headings, h, h1, h2, h3, h4, h5, h6, hr, blurb, blockquote, admonition, phrase, list, phrase_end, ordered_list, def_macro, @@ -43,11 +44,11 @@ namespace quickbook inside_paragraph, element_id, element_id_1_5, element_id_1_6; - symbols<> paragraph_end_markups; + cl::symbols<> paragraph_end_markups; phrase_grammar common; - rule const& + cl::rule const& start() const { return start_; } }; @@ -62,7 +63,7 @@ namespace quickbook if (self.skip_initial_spaces) { start_ = - *(blank_p | comment) >> blocks >> blank + *(cl::blank_p | comment) >> blocks >> blank ; } else @@ -79,45 +80,46 @@ namespace quickbook | hr [actions.hr] | +eol | paragraph [actions.inside_paragraph] - [actions.write_paragraphs] ) ; space = - *(space_p | comment) + *(cl::space_p | comment) ; blank = - *(blank_p | comment) + *(cl::blank_p | comment) ; - eol = blank >> eol_p + eol = blank >> cl::eol_p ; phrase_end = ']' | - if_p(var(no_eols)) + cl::if_p(var(no_eols)) [ - eol >> *blank_p >> eol_p + eol >> *cl::blank_p >> cl::eol_p // Make sure that we don't go ] // past a single block, except ; // when preformatted. + // Follows after an alphanumeric identifier - ensures that it doesn't + // match an empty space in the middle of the identifier. hard_space = - (eps_p - (alnum_p | '_')) >> space // must not be preceded by + (cl::eps_p - (cl::alnum_p | '_')) >> space // must not be preceded by ; // alpha-numeric or underscore comment = - "[/" >> *(dummy_block | (anychar_p - ']')) >> ']' + "[/" >> *(dummy_block | (cl::anychar_p - ']')) >> ']' ; dummy_block = - '[' >> *(dummy_block | (anychar_p - ']')) >> ']' + '[' >> *(dummy_block | (cl::anychar_p - ']')) >> ']' ; hr = - str_p("----") - >> *(anychar_p - eol) + cl::str_p("----") + >> *(cl::anychar_p - eol) >> +eol ; @@ -139,7 +141,7 @@ namespace quickbook | template_ ) >> ( (space >> ']' >> +eol) - | eps_p [actions.error] + | cl::eps_p [actions.error] ) ; @@ -147,29 +149,29 @@ namespace quickbook ':' >> ( - if_p(qbk_since(105u)) [space] - >> (+(alnum_p | '_')) [assign_a(actions.element_id)] - | eps_p [actions.element_id_warning] - [assign_a(actions.element_id)] + cl::if_p(qbk_since(105u)) [space] + >> (+(cl::alnum_p | '_')) [cl::assign_a(actions.element_id)] + | cl::eps_p [actions.element_id_warning] + [cl::assign_a(actions.element_id)] ) - | eps_p [assign_a(actions.element_id)] + | cl::eps_p [cl::assign_a(actions.element_id)] ; element_id_1_5 = - if_p(qbk_since(105u)) [ + cl::if_p(qbk_since(105u)) [ element_id ] .else_p [ - eps_p [assign_a(actions.element_id)] + cl::eps_p [cl::assign_a(actions.element_id)] ] ; element_id_1_6 = - if_p(qbk_since(106u)) [ + cl::if_p(qbk_since(106u)) [ element_id ] .else_p [ - eps_p [assign_a(actions.element_id)] + cl::eps_p [cl::assign_a(actions.element_id)] ] ; @@ -182,7 +184,7 @@ namespace quickbook ; end_section = - str_p("endsect") [actions.end_section] + cl::str_p("endsect") [actions.end_section] ; headings = @@ -209,40 +211,46 @@ namespace quickbook blurb = "blurb" >> hard_space - >> inside_paragraph [actions.blurb] - >> eps_p + >> scoped_block(actions)[inside_paragraph] + [actions.blurb] ; blockquote = ':' >> blank >> - inside_paragraph [actions.blockquote] + scoped_block(actions)[inside_paragraph] + [actions.blockquote] ; admonition = - "warning" >> blank >> - inside_paragraph [actions.warning] + "warning" >> hard_space >> + scoped_block(actions)[inside_paragraph] + [actions.warning] | - "caution" >> blank >> - inside_paragraph [actions.caution] + "caution" >> hard_space >> + scoped_block(actions)[inside_paragraph] + [actions.caution] | - "important" >> blank >> - inside_paragraph [actions.important] + "important" >> hard_space >> + scoped_block(actions)[inside_paragraph] + [actions.important] | - "note" >> blank >> - inside_paragraph [actions.note] + "note" >> hard_space >> + scoped_block(actions)[inside_paragraph] + [actions.note] | - "tip" >> blank >> - inside_paragraph [actions.tip] + "tip" >> hard_space >> + scoped_block(actions)[inside_paragraph] + [actions.tip] ; preformatted = - "pre" >> hard_space [assign_a(no_eols, false_)] + "pre" >> hard_space [cl::assign_a(no_eols, false_)] >> !eol >> phrase [actions.preformatted] - >> eps_p [assign_a(no_eols, true_)] + >> cl::eps_p [cl::assign_a(no_eols, true_)] ; macro_identifier = - +(anychar_p - (space_p | ']')) + +(cl::anychar_p - (cl::space_p | ']')) ; def_macro = @@ -252,142 +260,142 @@ namespace quickbook ; identifier = - (alpha_p | '_') >> *(alnum_p | '_') + (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; template_id = - identifier | (punct_p - (ch_p('[') | ']')) + identifier | (cl::punct_p - (cl::ch_p('[') | ']')) ; template_ = "template" >> hard_space - >> template_id [assign_a(actions.template_identifier)] - [clear_a(actions.template_info)] + >> template_id [cl::assign_a(actions.template_identifier)] + [cl::clear_a(actions.template_info)] >> !( space >> '[' >> *( - space >> template_id [push_back_a(actions.template_info)] + space >> template_id [cl::push_back_a(actions.template_info)] ) >> space >> ']' ) - >> ( eps_p(*blank_p >> eol_p) [assign_a(actions.template_block, true_)] - | eps_p [assign_a(actions.template_block, false_)] + >> ( cl::eps_p(*cl::blank_p >> cl::eol_p) + [cl::assign_a(actions.template_block, true_)] + | cl::eps_p [cl::assign_a(actions.template_block, false_)] ) >> template_body [actions.template_body] ; template_body = - *(('[' >> template_body >> ']') | (anychar_p - ']')) - >> eps_p(space >> ']') + *(('[' >> template_body >> ']') | (cl::anychar_p - ']')) + >> cl::eps_p(space >> ']') >> space ; variablelist = "variablelist" - >> (eps_p(*blank_p >> eol_p) | hard_space) - >> (*(anychar_p - eol)) [assign_a(actions.table_title)] + >> (cl::eps_p(*cl::blank_p >> cl::eol_p) | hard_space) + >> (*(cl::anychar_p - eol)) [cl::assign_a(actions.table_title)] >> +eol >> *varlistentry - >> eps_p [actions.variablelist] + >> cl::eps_p [actions.variablelist] ; varlistentry = space - >> ch_p('[') [actions.start_varlistentry] + >> cl::ch_p('[') [actions.start_varlistentry] >> ( ( - varlistterm [actions.start_varlistitem] - >> ( +varlistitem - | eps_p [actions.error] - ) [actions.end_varlistitem] - >> ch_p(']') [actions.end_varlistentry] + varlistterm + >> ( scoped_block(actions) [+varlistitem] + [actions.varlistitem] + | cl::eps_p [actions.error] + ) + >> cl::ch_p(']') [actions.end_varlistentry] >> space ) - | eps_p [actions.error] + | cl::eps_p [actions.error] ) ; varlistterm = space - >> ch_p('[') [actions.start_varlistterm] + >> cl::ch_p('[') [actions.start_varlistterm] >> ( ( phrase - >> ch_p(']') [actions.end_varlistterm] + >> cl::ch_p(']') [actions.end_varlistterm] >> space ) - | eps_p [actions.error] + | cl::eps_p [actions.error] ) ; varlistitem = space - >> ch_p('[') + >> cl::ch_p('[') >> ( ( inside_paragraph - >> ch_p(']') + >> cl::ch_p(']') >> space ) - | eps_p [actions.error] + | cl::eps_p [actions.error] ) ; table = "table" - >> (eps_p(*blank_p >> eol_p) | hard_space) + >> (cl::eps_p(*cl::blank_p >> cl::eol_p) | hard_space) >> element_id_1_5 - >> (eps_p(*blank_p >> eol_p) | space) - >> (*(anychar_p - eol)) [assign_a(actions.table_title)] + >> (cl::eps_p(*cl::blank_p >> cl::eol_p) | space) + >> (*(cl::anychar_p - eol)) [cl::assign_a(actions.table_title)] >> +eol >> *table_row - >> eps_p [actions.table] + >> cl::eps_p [actions.table] ; table_row = space - >> ch_p('[') [actions.start_row] + >> cl::ch_p('[') [actions.start_row] >> ( ( *table_cell - >> ch_p(']') [actions.end_row] + >> cl::ch_p(']') [actions.end_row] >> space ) - | eps_p [actions.error] + | cl::eps_p [actions.error] ) ; table_cell = - space - >> ch_p('[') [actions.start_cell] - >> - ( - ( - inside_paragraph - >> ch_p(']') [actions.end_cell] + space + >> cl::ch_p('[') + >> ( scoped_block(actions) [ + inside_paragraph + >> cl::ch_p(']') >> space + ] [actions.cell] + | cl::eps_p [actions.error] ) - | eps_p [actions.error] - ) ; xinclude = "xinclude" >> hard_space - >> (*(anychar_p - + >> (*(cl::anychar_p - phrase_end)) [actions.xinclude] ; import = "import" >> hard_space - >> (*(anychar_p - + >> (*(cl::anychar_p - phrase_end)) [actions.import] ; @@ -397,10 +405,11 @@ namespace quickbook >> !( ':' - >> (*((alnum_p | '_') - space_p))[assign_a(actions.include_doc_id)] + >> (*((cl::alnum_p | '_') - cl::space_p)) + [cl::assign_a(actions.include_doc_id)] >> space ) - >> (*(anychar_p - + >> (*(cl::anychar_p - phrase_end)) [actions.include] ; @@ -413,27 +422,27 @@ namespace quickbook ; code_line = - blank_p >> *(anychar_p - eol_p) >> eol_p + cl::blank_p >> *(cl::anychar_p - cl::eol_p) >> cl::eol_p ; blank_line = - *blank_p >> eol_p + *cl::blank_p >> cl::eol_p ; list = - eps_p(ch_p('*') | '#') >> + cl::eps_p(cl::ch_p('*') | '#') >> +( - (*blank_p - >> (ch_p('*') | '#')) [actions.list_format] - >> *blank_p + (*cl::blank_p + >> (cl::ch_p('*') | '#')) [actions.list_format] + >> *cl::blank_p >> list_item ) [actions.list_item] ; list_item = *( common - | (anychar_p - - ( eol_p >> *blank_p >> eps_p(ch_p('*') | '#') + | (cl::anychar_p - + ( cl::eol_p >> *cl::blank_p >> cl::eps_p(cl::ch_p('*') | '#') | (eol >> eol) ) ) [actions.plain_char] @@ -449,34 +458,30 @@ namespace quickbook ; paragraph_end = - '[' >> space >> paragraph_end_markups >> hard_space | eol >> *blank_p >> eol_p + '[' >> space >> paragraph_end_markups >> hard_space | eol >> *cl::blank_p >> cl::eol_p ; paragraph = +( common - | (anychar_p - // Make sure we don't go past + | (cl::anychar_p - // Make sure we don't go past paragraph_end // a single block. ) [actions.plain_char] ) - >> (eps_p('[') | +eol) + >> (cl::eps_p('[') | +eol) ; phrase = *( common | comment - | (anychar_p - + | (cl::anychar_p - phrase_end) [actions.plain_char] ) ; } - template - parse_info parse(Iterator& first, Iterator last, Grammar& g) + cl::parse_info call_parse( + iterator& first, iterator last, block_grammar& g) { return boost::spirit::classic::parse(first, last, g); } - - void instantiate_block_grammar(quickbook::iterator i, block_grammar& g) { - parse(i, i, g); - } } diff --git a/src/code_snippet.cpp b/src/code_snippet.cpp index 8419cbc..01091ce 100644 --- a/src/code_snippet.cpp +++ b/src/code_snippet.cpp @@ -6,11 +6,10 @@ 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_CODE_SNIPPET_HPP) -#define BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP #include #include +#include #include #include #include "template_stack.hpp" @@ -18,7 +17,7 @@ namespace quickbook { - using namespace boost::spirit::classic; + namespace cl = boost::spirit::classic; struct code_snippet_actions { @@ -69,7 +68,7 @@ namespace quickbook }; struct python_code_snippet_grammar - : grammar + : cl::grammar { typedef code_snippet_actions actions_type; @@ -90,7 +89,7 @@ namespace quickbook start_ = *code_elements; identifier = - (alpha_p | '_') >> *(alnum_p | '_') + (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; code_elements = @@ -98,45 +97,55 @@ namespace quickbook | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)] | escaped_comment | ignore - | anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)] + | cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)] ; start_snippet = - "#[" >> *space_p - >> identifier [assign_a(actions.id)] + "#[" >> *cl::space_p + >> identifier [cl::assign_a(actions.id)] ; end_snippet = - str_p("#]") + cl::str_p("#]") ; - ignore = - *blank_p >> "#<-" - >> (*(anychar_p - "#->")) - >> "#->" >> *blank_p >> eol_p - | "\"\"\"<-\"\"\"" - >> (*(anychar_p - "\"\"\"->\"\"\"")) - >> "\"\"\"->\"\"\"" - | "\"\"\"<-" - >> (*(anychar_p - "->\"\"\"")) - >> "->\"\"\"" + ignore + = cl::confix_p( + *cl::blank_p >> "#<-", + *cl::anychar_p, + "#->" >> *cl::blank_p >> cl::eol_p + ) + | cl::confix_p( + "\"\"\"<-\"\"\"", + *cl::anychar_p, + "\"\"\"->\"\"\"" + ) + | cl::confix_p( + "\"\"\"<-", + *cl::anychar_p, + "->\"\"\"" + ) ; escaped_comment = - *space_p >> "#`" - >> ((*(anychar_p - eol_p)) - >> eol_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)] - | *space_p >> "\"\"\"`" - >> (*(anychar_p - "\"\"\"")) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)] - >> "\"\"\"" + cl::confix_p( + *cl::space_p >> "#`", + (*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)], + cl::eol_p + ) + | cl::confix_p( + *cl::space_p >> "\"\"\"`", + (*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)], + "\"\"\"" + ) ; } - rule + cl::rule start_, identifier, code_elements, start_snippet, end_snippet, escaped_comment, ignore; - rule const& + cl::rule const& start() const { return start_; } }; @@ -144,7 +153,7 @@ namespace quickbook }; struct cpp_code_snippet_grammar - : grammar + : cl::grammar { typedef code_snippet_actions actions_type; @@ -162,7 +171,7 @@ namespace quickbook start_ = *code_elements; identifier = - (alpha_p | '_') >> *(alnum_p | '_') + (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; code_elements = @@ -172,64 +181,78 @@ namespace quickbook | ignore | line_callout | inline_callout - | anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)] + | cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)] ; start_snippet = - "//[" >> *space_p - >> identifier [assign_a(actions.id)] + "//[" >> *cl::space_p + >> identifier [cl::assign_a(actions.id)] | - "/*[" >> *space_p - >> identifier [assign_a(actions.id)] - >> *space_p >> "*/" + "/*[" >> *cl::space_p + >> identifier [cl::assign_a(actions.id)] + >> *cl::space_p >> "*/" ; end_snippet = - str_p("//]") | "/*]*/" + cl::str_p("//]") | "/*]*/" ; - inline_callout = - "/*<" - >> *space_p - >> (*(anychar_p - ">*/")) [boost::bind(&actions_type::callout, &actions, _1, _2)] - >> ">*/" + inline_callout + = cl::confix_p( + "/*<" >> *cl::space_p, + (*cl::anychar_p) [boost::bind(&actions_type::callout, &actions, _1, _2)], + ">*/" + ) + ; + + line_callout + = cl::confix_p( + "/*<<" >> *cl::space_p, + (*cl::anychar_p) [boost::bind(&actions_type::callout, &actions, _1, _2)], + ">>*/" + ) + >> *cl::space_p ; - line_callout = - "/*<<" - >> *space_p - >> (*(anychar_p - ">>*/")) [boost::bind(&actions_type::callout, &actions, _1, _2)] - >> ">>*/" - >> *space_p + ignore + = cl::confix_p( + *cl::blank_p >> "//<-", + *cl::anychar_p, + "//->" + ) + >> *cl::blank_p + >> cl::eol_p + | cl::confix_p( + "/*<-*/", + *cl::anychar_p, + "/*->*/" + ) + | cl::confix_p( + "/*<-", + *cl::anychar_p, + "->*/" + ) ; - ignore = - *blank_p >> "//<-" - >> (*(anychar_p - "//->")) - >> "//->" >> *blank_p >> eol_p - | "/*<-*/" - >> (*(anychar_p - "/*->*/")) - >> "/*->*/" - | "/*<-" - >> (*(anychar_p - "->*/")) - >> "->*/" - ; - - escaped_comment = - *space_p >> "//`" - >> ((*(anychar_p - eol_p)) - >> eol_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)] - | *space_p >> "/*`" - >> (*(anychar_p - "*/")) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)] - >> "*/" + escaped_comment + = cl::confix_p( + *cl::space_p >> "//`", + (*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)], + cl::eol_p + ) + | cl::confix_p( + *cl::space_p >> "/*`", + (*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)], + "*/" + ) ; } - rule - start_, identifier, code_elements, start_snippet, end_snippet, + cl::rule + start_, identifier, code_elements, start_snippet, end_snippet, escaped_comment, inline_callout, line_callout, ignore; - rule const& + cl::rule const& start() const { return start_; } }; @@ -248,9 +271,8 @@ namespace quickbook if (err != 0) return err; // return early on error - typedef position_iterator iterator_type; - iterator_type first(code.begin(), code.end(), file); - iterator_type last(code.end(), code.end()); + iterator first(code.begin(), code.end(), file.c_str()); + iterator last(code.end(), code.end()); size_t fname_len = file.size(); bool is_python = fname_len >= 3 @@ -406,6 +428,3 @@ namespace quickbook } } } - -#endif // BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP - diff --git a/src/doc_info_actions.cpp b/src/doc_info_actions.cpp index 8f46f08..d8ad10a 100644 --- a/src/doc_info_actions.cpp +++ b/src/doc_info_actions.cpp @@ -31,7 +31,7 @@ namespace quickbook // *before* anything else. if (!actions.doc_id_tmp.empty()) - actions.doc_id = actions.doc_id_tmp.get(103); + actions.doc_id = actions.doc_id_tmp.get(106); if (actions.doc_id.empty()) actions.doc_id = detail::make_identifier( @@ -145,18 +145,18 @@ namespace quickbook if(actions.doc_type == "library") { - out << " name=\"" << actions.doc_title.get(103) << "\"\n"; + out << " name=\"" << actions.doc_title.get(106) << "\"\n"; } if(!actions.doc_dirname.empty()) { out << " dirname=\"" - << actions.doc_dirname.get(103) + << actions.doc_dirname.get(106) << "\"\n"; } out << " last-revision=\"" - << actions.doc_last_revision.get(103) + << actions.doc_last_revision.get(106) << "\" \n" << " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n"; @@ -188,9 +188,9 @@ namespace quickbook if (!actions.doc_title.empty()) { out << " " - << actions.doc_title.get(103); + << actions.doc_title.get(106); if (!actions.doc_version.empty()) { - out << ' ' << actions.doc_version.get(103); + out << ' ' << actions.doc_version.get(106); } out<< "\n\n\n"; } @@ -210,10 +210,10 @@ namespace quickbook { tmp << " \n" << " " - << it->first.get(103) + << it->first.get(106) << "\n" << " " - << it->second.get(103) + << it->second.get(106) << "\n" << " \n"; } @@ -238,7 +238,7 @@ namespace quickbook } tmp << " " - << it->second.get(103) + << it->second.get(106) << "\n" << " \n" << "\n" @@ -274,13 +274,27 @@ namespace quickbook it != end; ++it) { tmp << " <" << actions.doc_type << "category name=\"category:" - << it->get(103) + << it->get(106) << "\">\n" << "\n" ; } } + for (actions::biblioid_list::const_iterator + it = actions.doc_biblioid_items.begin(), + end = actions.doc_biblioid_items.end(); + it != end; ++it) + { + tmp << " first + << "\">" + << it->second.get(103) + << "" + << "\n" + ; + } + std::string value = tmp.str(); if(!value.empty()) { @@ -291,4 +305,4 @@ namespace quickbook ; } } -} \ No newline at end of file +} diff --git a/src/doc_info_grammar.cpp b/src/doc_info_grammar.cpp index ea9aaec..8ce99e7 100644 --- a/src/doc_info_grammar.cpp +++ b/src/doc_info_grammar.cpp @@ -9,7 +9,6 @@ =============================================================================*/ #include "phrase_grammar.hpp" -#include "quickbook.hpp" #include "actions_class.hpp" #include #include @@ -19,26 +18,27 @@ namespace quickbook { - using namespace boost::spirit::classic; + namespace cl = boost::spirit::classic; template struct doc_info_grammar::definition { definition(doc_info_grammar const&); - typedef uint_parser uint2_t; + typedef cl::uint_parser uint2_t; bool unused; std::string category; - rule doc_info, doc_title, doc_version, doc_id, doc_dirname, + cl::rule + doc_info, doc_title, doc_version, doc_id, doc_dirname, doc_copyright, doc_purpose, doc_category, doc_authors, doc_author, comment, space, hard_space, doc_license, - doc_last_revision, doc_source_mode, phrase, quickbook_version, - char_; + doc_last_revision, doc_source_mode, doc_biblioid, + phrase, quickbook_version, char_; phrase_grammar common; - symbols<> doc_types; + cl::symbols<> doc_types; - rule const& + cl::rule const& start() const { return doc_info; } }; @@ -57,9 +57,9 @@ namespace quickbook doc_info = space >> '[' >> space - >> (doc_types >> eps_p) [assign_a(actions.doc_type)] + >> (doc_types >> cl::eps_p) [cl::assign_a(actions.doc_type)] >> hard_space - >> ( *(~eps_p(ch_p('[') | ']' | eol_p) >> char_) + >> ( *(~cl::eps_p(cl::ch_p('[') | ']' | cl::eol_p) >> char_) ) [actions.extract_doc_title] >> !( space >> '[' >> @@ -73,51 +73,57 @@ namespace quickbook doc_version | doc_id | doc_dirname - | doc_copyright [push_back_a(actions.doc_copyrights, actions.copyright)] + | doc_copyright [cl::push_back_a(actions.doc_copyrights, actions.copyright)] | doc_purpose | doc_category | doc_authors | doc_license | doc_last_revision | doc_source_mode + | doc_biblioid ) - >> space >> ']' >> +eol_p + >> space >> ']' >> +cl::eol_p ) - >> space >> ']' >> +eol_p + >> space >> ']' >> +cl::eol_p ; quickbook_version = "quickbook" >> hard_space - >> ( uint_p [assign_a(qbk_major_version)] + >> ( cl::uint_p [cl::assign_a(qbk_major_version)] >> '.' - >> uint2_t() [assign_a(qbk_minor_version)] + >> uint2_t() [cl::assign_a(qbk_minor_version)] ) ; doc_version = "version" >> hard_space - >> (*(~eps_p(']') >> char_)) [actions.extract_doc_version] + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_doc_version] ; // TODO: Restrictions on doc_id? doc_id = "id" >> hard_space - >> (*(~eps_p(']') >> char_)) [actions.extract_doc_id] + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_doc_id] ; // TODO: Restrictions on doc_dirname? doc_dirname = "dirname" >> hard_space - >> (*(~eps_p(']') >> char_)) [actions.extract_doc_dirname] + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_doc_dirname] ; doc_copyright = - "copyright" >> hard_space [clear_a(actions.copyright.first)] - >> +( repeat_p(4)[digit_p] [push_back_a(actions.copyright.first)] + "copyright" >> hard_space [cl::clear_a(actions.copyright.first)] + >> +( cl::repeat_p(4)[cl::digit_p] + [cl::push_back_a(actions.copyright.first)] >> space ) >> space - >> (*(~eps_p(']') >> char_)) [actions.extract_copyright_second] + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_copyright_second] ; doc_purpose = @@ -127,25 +133,28 @@ namespace quickbook doc_category = "category" >> hard_space - >> (*(~eps_p(']') >> char_)) [actions.extract_doc_category] - [push_back_a(actions.doc_categories, actions.doc_category)] + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_doc_category] + [cl::push_back_a(actions.doc_categories, actions.doc_category)] ; doc_author = '[' >> space - >> (*(~eps_p(',') >> char_)) [actions.extract_name_second] // surname + >> (*(~cl::eps_p(',') >> char_)) + [actions.extract_name_second] >> ',' >> space - >> (*(~eps_p(']') >> char_)) [actions.extract_name_first] // firstname + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_name_first] >> ']' ; doc_authors = "authors" >> hard_space - >> doc_author [push_back_a(actions.doc_authors, actions.name)] + >> doc_author [cl::push_back_a(actions.doc_authors, actions.name)] >> space - >> *( !(ch_p(',') >> space) - >> doc_author [push_back_a(actions.doc_authors, actions.name)] + >> *( !(cl::ch_p(',') >> space) + >> doc_author [cl::push_back_a(actions.doc_authors, actions.name)] >> space ) ; @@ -157,61 +166,70 @@ namespace quickbook doc_last_revision = "last-revision" >> hard_space - >> (*(~eps_p(']') >> char_)) [actions.extract_doc_last_revision] + >> (*(~cl::eps_p(']') >> char_)) + [actions.extract_doc_last_revision] ; doc_source_mode = "source-mode" >> hard_space >> ( - str_p("c++") + cl::str_p("c++") | "python" | "teletype" - ) [assign_a(actions.source_mode)] + ) [cl::assign_a(actions.source_mode)] + ; + + doc_biblioid = + "biblioid" + >> hard_space + >> (+cl::alnum_p) [cl::assign_a(actions.doc_biblioid.first)] + >> hard_space + >> (+(~cl::eps_p(']') >> char_)) + [actions.extract_doc_biblioid] + [cl::push_back_a(actions.doc_biblioid_items, actions.doc_biblioid)] ; comment = - "[/" >> *(anychar_p - ']') >> ']' + "[/" >> *(cl::anychar_p - ']') >> ']' ; space = - *(space_p | comment) + *(cl::space_p | comment) ; hard_space = - (eps_p - (alnum_p | '_')) >> space // must not be preceded by + (cl::eps_p - (cl::alnum_p | '_')) >> space // must not be preceded by ; // alpha-numeric or underscore phrase = *( common | comment - | (anychar_p - ']') [actions.plain_char] + | (cl::anychar_p - ']') [actions.plain_char] ) ; char_ = - str_p("\\n") [actions.break_] + cl::str_p("\\n") [actions.break_] | "\\ " // ignore an escaped space - | '\\' >> punct_p [actions.raw_char] - | "\\u" >> repeat_p(4) [chset<>("0-9a-fA-F")] + | '\\' >> cl::punct_p [actions.raw_char] + | "\\u" >> cl::repeat_p(4) + [cl::chset<>("0-9a-fA-F")] [actions.escape_unicode] - | "\\U" >> repeat_p(8) [chset<>("0-9a-fA-F")] + | "\\U" >> cl::repeat_p(8) + [cl::chset<>("0-9a-fA-F")] [actions.escape_unicode] | ( - ("'''" >> !eol_p) [actions.escape_pre] - >> *(anychar_p - "'''") [actions.raw_char] - >> str_p("'''") [actions.escape_post] + ("'''" >> !cl::eol_p) [actions.escape_pre] + >> *(cl::anychar_p - "'''")[actions.raw_char] + >> cl::str_p("'''") [actions.escape_post] ) - | anychar_p [actions.plain_char] + | cl::anychar_p [actions.plain_char] ; } - template - parse_info parse(Iterator& first, Iterator last, Grammar& g) + cl::parse_info call_parse( + iterator& first, iterator last, doc_info_grammar& g) { return boost::spirit::classic::parse(first, last, g); } - - void instantiate_doc_info_grammar(quickbook::iterator i, doc_info_grammar& g) { - parse(i, i, g); - } } diff --git a/src/fwd.hpp b/src/fwd.hpp new file mode 100644 index 0000000..e5ae00c --- /dev/null +++ b/src/fwd.hpp @@ -0,0 +1,27 @@ +/*============================================================================= + Copyright (c) 2002 2004 2006 Joel de Guzman + Copyright (c) 2004 Eric Niebler + Copyright (c) 2010 Daniel James + 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_FWD_HPP) +#define BOOST_SPIRIT_FWD_HPP + +#include +#include +#include + +namespace quickbook +{ + struct actions; + + typedef boost::spirit::classic::file_position_base position; + typedef boost::spirit::classic::position_iterator< + std::string::const_iterator, position> iterator; +} + +#endif \ No newline at end of file diff --git a/src/grammar.hpp b/src/grammar.hpp index 8a32a09..a980cd9 100644 --- a/src/grammar.hpp +++ b/src/grammar.hpp @@ -11,7 +11,7 @@ #define BOOST_SPIRIT_QUICKBOOK_GRAMMARS_HPP #include -#include "actions.hpp" +#include "fwd.hpp" namespace quickbook { @@ -41,7 +41,8 @@ namespace quickbook bool const skip_initial_spaces; }; - struct phrase_grammar : cl::grammar + struct phrase_grammar + : cl::grammar { phrase_grammar(quickbook::actions& actions, bool& no_eols) : no_eols(no_eols), actions(actions) {} @@ -53,7 +54,8 @@ namespace quickbook quickbook::actions& actions; }; - struct simple_phrase_grammar : public cl::grammar + struct simple_phrase_grammar + : public cl::grammar { simple_phrase_grammar(quickbook::actions& actions) : actions(actions) {} @@ -76,8 +78,16 @@ namespace quickbook quickbook::actions& actions; }; - template - cl::parse_info parse(Iterator&, Iterator, Grammar&); + cl::parse_info call_parse( + iterator&, iterator, doc_info_grammar&); + cl::parse_info call_parse( + iterator&, iterator, block_grammar&); + cl::parse_info call_parse( + iterator&, iterator, phrase_grammar&); + cl::parse_info call_parse( + iterator&, iterator, simple_phrase_grammar&); + cl::parse_info call_parse( + iterator&, iterator, command_line_grammar&); } #endif diff --git a/src/phrase_grammar.cpp b/src/phrase_grammar.cpp index e70cab3..3dbd58a 100644 --- a/src/phrase_grammar.cpp +++ b/src/phrase_grammar.cpp @@ -9,459 +9,9 @@ =============================================================================*/ #include "phrase_grammar.hpp" -#include "quickbook.hpp" -#include "actions_class.hpp" -#include "utils.hpp" -#include -#include -#include -#include -#include -#include -#include namespace quickbook { - using namespace boost::spirit::classic; - - template - inline void - simple_markup( - Rule& simple - , char mark - , Action const& action - , Rule const& close - ) - { - simple = - mark >> - ( - ( - graph_p // A single char. e.g. *c* - >> eps_p(mark - >> (space_p | punct_p | end_p)) - // space_p, punct_p or end_p - ) // must follow mark - | - ( graph_p >> // graph_p must follow mark - *(anychar_p - - ( (graph_p >> mark) // Make sure that we don't go - | close // past a single block - ) - ) >> graph_p // graph_p must precede mark - >> eps_p(mark - >> (space_p | punct_p | end_p)) - // space_p, punct_p or end_p - ) // must follow mark - ) [action] - >> mark - ; - } - - template - phrase_grammar::definition::definition(phrase_grammar const& self) - { - using detail::var; - quickbook::actions& actions = self.actions; - - space = - *(space_p | comment) - ; - - blank = - *(blank_p | comment) - ; - - eol = blank >> eol_p - ; - - phrase_end = - ']' | - if_p(var(self.no_eols)) - [ - eol >> eol // Make sure that we don't go - ] // past a single block, except - ; // when preformatted. - - hard_space = - (eps_p - (alnum_p | '_')) >> space // must not be preceded by - ; // alpha-numeric or underscore - - comment = - "[/" >> *(dummy_block | (anychar_p - ']')) >> ']' - ; - - dummy_block = - '[' >> *(dummy_block | (anychar_p - ']')) >> ']' - ; - - common = - macro - | phrase_markup - | code_block - | inline_code - | simple_format - | escape - | comment - ; - - macro = - eps_p(actions.macro // must not be followed by - >> (eps_p - (alpha_p | '_'))) // alpha or underscore - >> actions.macro [actions.do_macro] - ; - - static const bool true_ = true; - static const bool false_ = false; - - template_ = - ( - ch_p('`') [assign_a(actions.template_escape,true_)] - | - eps_p [assign_a(actions.template_escape,false_)] - ) - >> - ( ( - (eps_p(punct_p) - >> actions.templates.scope - ) [assign_a(actions.template_identifier)] - [clear_a(actions.template_args)] - >> !template_args - ) | ( - (actions.templates.scope - >> eps_p(hard_space) - ) [assign_a(actions.template_identifier)] - [clear_a(actions.template_args)] - >> space - >> !template_args - ) ) - >> eps_p(']') - ; - - template_args = - if_p(qbk_since(105u)) [ - template_args_1_5 - ].else_p [ - template_args_1_4 - ] - ; - - template_args_1_4 = template_arg_1_4 >> *(".." >> template_arg_1_4); - - template_arg_1_4 = - ( eps_p(*blank_p >> eol_p) [assign_a(actions.template_block, true_)] - | eps_p [assign_a(actions.template_block, false_)] - ) - >> template_inner_arg_1_4 [actions.template_arg] - ; - - template_inner_arg_1_4 = - +(brackets_1_4 | (anychar_p - (str_p("..") | ']'))) - ; - - brackets_1_4 = - '[' >> template_inner_arg_1_4 >> ']' - ; - - template_args_1_5 = template_arg_1_5 >> *(".." >> template_arg_1_5); - - template_arg_1_5 = - ( eps_p(*blank_p >> eol_p) [assign_a(actions.template_block, true_)] - | eps_p [assign_a(actions.template_block, false_)] - ) - >> (+(brackets_1_5 | ('\\' >> anychar_p) | (anychar_p - (str_p("..") | '[' | ']')))) - [actions.template_arg] - ; - - template_inner_arg_1_5 = - +(brackets_1_5 | ('\\' >> anychar_p) | (anychar_p - (str_p('[') | ']'))) - ; - - brackets_1_5 = - '[' >> template_inner_arg_1_5 >> ']' - ; - - inline_code = - '`' >> - ( - *(anychar_p - - ( '`' - | (eol >> eol) // Make sure that we don't go - ) // past a single block - ) >> eps_p('`') - ) [actions.inline_code] - >> '`' - ; - - code_block = - ( - "```" >> - ( - *(anychar_p - "```") - >> eps_p("```") - ) [actions.code_block] - >> "```" - ) - | ( - "``" >> - ( - *(anychar_p - "``") - >> eps_p("``") - ) [actions.code_block] - >> "``" - ) - ; - - simple_format = - simple_bold - | simple_italic - | simple_underline - | simple_teletype - ; - - simple_phrase_end = '[' | phrase_end; - - simple_markup(simple_bold, - '*', actions.simple_bold, simple_phrase_end); - simple_markup(simple_italic, - '/', actions.simple_italic, simple_phrase_end); - simple_markup(simple_underline, - '_', actions.simple_underline, simple_phrase_end); - simple_markup(simple_teletype, - '=', actions.simple_teletype, simple_phrase_end); - - phrase = - *( common - | comment - | (anychar_p - phrase_end) [actions.plain_char] - ) - ; - - phrase_markup = - '[' - >> ( cond_phrase - | image - | url - | link - | anchor - | source_mode - | funcref - | classref - | memberref - | enumref - | macroref - | headerref - | conceptref - | globalref - | bold - | italic - | underline - | teletype - | strikethrough - | quote - | replaceable - | footnote - | template_ [actions.do_template] - | str_p("br") [actions.break_] - ) - >> ']' - ; - - escape = - str_p("\\ ") // ignore an escaped space - | '\\' >> punct_p [actions.raw_char] - | "\\u" >> repeat_p(4) [chset<>("0-9a-fA-F")] - [actions.escape_unicode] - | "\\U" >> repeat_p(8) [chset<>("0-9a-fA-F")] - [actions.escape_unicode] - | ( - ("'''" >> !eol) [actions.escape_pre] - >> *(anychar_p - "'''") [actions.raw_char] - >> str_p("'''") [actions.escape_post] - ) - ; - - macro_identifier = - +(anychar_p - (space_p | ']')) - ; - - cond_phrase = - '?' >> blank - >> macro_identifier [actions.cond_phrase_pre] - >> (!phrase) [actions.cond_phrase_post] - ; - - image = - '$' >> blank [clear_a(actions.attributes)] - >> if_p(qbk_since(105u)) [ - (+( - *space_p - >> +(anychar_p - (space_p | phrase_end | '[')) - )) [assign_a(actions.image_fileref)] - >> hard_space - >> *( - '[' - >> (*(alnum_p | '_')) [assign_a(actions.attribute_name)] - >> space - >> (*(anychar_p - (phrase_end | '['))) - [actions.attribute] - >> ']' - >> space - ) - ].else_p [ - (*(anychar_p - - phrase_end)) [assign_a(actions.image_fileref)] - ] - >> eps_p(']') [actions.image] - ; - - url = - '@' - >> (*(anychar_p - - (']' | hard_space))) [actions.url_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.url_post] - ; - - link = - "link" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.link_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.link_post] - ; - - anchor = - '#' - >> blank - >> ( *(anychar_p - - phrase_end) - ) [actions.anchor] - ; - - funcref = - "funcref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.funcref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.funcref_post] - ; - - classref = - "classref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.classref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.classref_post] - ; - - memberref = - "memberref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.memberref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.memberref_post] - ; - - enumref = - "enumref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.enumref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.enumref_post] - ; - - macroref = - "macroref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.macroref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.macroref_post] - ; - - headerref = - "headerref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.headerref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.headerref_post] - ; - - conceptref = - "conceptref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.conceptref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.conceptref_post] - ; - - globalref = - "globalref" >> hard_space - >> (*(anychar_p - - (']' | hard_space))) [actions.globalref_pre] - >> ( eps_p(']') - | (hard_space >> phrase) - ) [actions.globalref_post] - ; - - bold = - ch_p('*') [actions.bold_pre] - >> blank >> phrase [actions.bold_post] - ; - - italic = - ch_p('\'') [actions.italic_pre] - >> blank >> phrase [actions.italic_post] - ; - - underline = - ch_p('_') [actions.underline_pre] - >> blank >> phrase [actions.underline_post] - ; - - teletype = - ch_p('^') [actions.teletype_pre] - >> blank >> phrase [actions.teletype_post] - ; - - strikethrough = - ch_p('-') [actions.strikethrough_pre] - >> blank >> phrase [actions.strikethrough_post] - ; - - quote = - ch_p('"') [actions.quote_pre] - >> blank >> phrase [actions.quote_post] - ; - - replaceable = - ch_p('~') [actions.replaceable_pre] - >> blank >> phrase [actions.replaceable_post] - ; - - source_mode = - ( - str_p("c++") - | "python" - | "teletype" - ) [assign_a(actions.source_mode)] - ; - - footnote = - str_p("footnote") [actions.footnote_pre] - >> blank >> phrase [actions.footnote_post] - ; - } - template struct simple_phrase_grammar::definition { @@ -473,24 +23,24 @@ namespace quickbook phrase = *( common | comment - | (anychar_p - ']') [actions.plain_char] + | (cl::anychar_p - ']') [actions.plain_char] ) ; comment = - "[/" >> *(dummy_block | (anychar_p - ']')) >> ']' + "[/" >> *(dummy_block | (cl::anychar_p - ']')) >> ']' ; dummy_block = - '[' >> *(dummy_block | (anychar_p - ']')) >> ']' + '[' >> *(dummy_block | (cl::anychar_p - ']')) >> ']' ; } bool unused; - rule phrase, comment, dummy_block; + cl::rule phrase, comment, dummy_block; phrase_grammar common; - rule const& + cl::rule const& start() const { return phrase; } }; @@ -503,51 +53,51 @@ namespace quickbook quickbook::actions& actions = self.actions; macro = - *space_p + *cl::space_p >> macro_identifier [actions.macro_identifier] - >> *space_p + >> *cl::space_p >> ( '=' - >> *space_p + >> *cl::space_p >> phrase [actions.macro_definition] - >> *space_p + >> *cl::space_p ) - | eps_p [actions.macro_definition] + | cl::eps_p [actions.macro_definition] ; macro_identifier = - +(anychar_p - (space_p | ']' | '=')) + +(cl::anychar_p - (cl::space_p | ']' | '=')) ; phrase = *( common - | (anychar_p - ']') [actions.plain_char] + | (cl::anychar_p - ']') [actions.plain_char] ) ; } bool unused; - rule macro, macro_identifier, phrase; + cl::rule macro, macro_identifier, phrase; phrase_grammar common; - rule const& + cl::rule const& start() const { return macro; } }; - template - parse_info parse(Iterator& first, Iterator last, Grammar& g) + cl::parse_info call_parse( + iterator& first, iterator last, phrase_grammar& g) { return boost::spirit::classic::parse(first, last, g); } - void instantiate_phrase_grammar(quickbook::iterator i, phrase_grammar& g) { - parse(i, i, g); + cl::parse_info call_parse( + iterator& first, iterator last, simple_phrase_grammar& g) + { + return boost::spirit::classic::parse(first, last, g); } - void instantiate_simple_phrase_grammar(quickbook::iterator i, simple_phrase_grammar& g) { - parse(i, i, g); - } - - void instantiate_command_line_grammar(quickbook::iterator i, command_line_grammar& g) { - parse(i, i, g); + cl::parse_info call_parse( + iterator& first, iterator last, command_line_grammar& g) + { + return boost::spirit::classic::parse(first, last, g); } } diff --git a/src/phrase_grammar.hpp b/src/phrase_grammar.hpp index 88bed65..49e04e5 100644 --- a/src/phrase_grammar.hpp +++ b/src/phrase_grammar.hpp @@ -11,11 +11,54 @@ #define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP #include "grammar.hpp" +#include "actions_class.hpp" +#include "utils.hpp" +#include +#include +#include +#include +#include +#include +#include namespace quickbook { namespace cl = boost::spirit::classic; + template + inline void + simple_markup( + Rule& simple + , char mark + , Action const& action + , Rule const& close + ) + { + simple = + mark >> + ( + ( + cl::graph_p // A single char. e.g. *c* + >> cl::eps_p(mark + >> (cl::space_p | cl::punct_p | cl::end_p)) + // space_p, punct_p or end_p + ) // must follow mark + | + ( cl::graph_p >> // graph_p must follow mark + *(cl::anychar_p - + ( (cl::graph_p >> mark) // Make sure that we don't go + | close // past a single block + ) + ) >> cl::graph_p // graph_p must precede mark + >> cl::eps_p(mark + >> (cl::space_p | cl::punct_p | cl::end_p)) + // space_p, punct_p or end_p + ) // must follow mark + ) [action] + >> mark + ; + } + template struct phrase_grammar::definition { @@ -40,6 +83,402 @@ namespace quickbook cl::rule const& start() const { return common; } }; + + template + phrase_grammar::definition::definition(phrase_grammar const& self) + { + using detail::var; + quickbook::actions& actions = self.actions; + + space = + *(cl::space_p | comment) + ; + + blank = + *(cl::blank_p | comment) + ; + + eol = blank >> cl::eol_p + ; + + phrase_end = + ']' | + cl::if_p(var(self.no_eols)) + [ + eol >> eol // Make sure that we don't go + ] // past a single block, except + ; // when preformatted. + + // Follows an alphanumeric identifier - ensures that it doesn't + // match an empty space in the middle of the identifier. + hard_space = + (cl::eps_p - (cl::alnum_p | '_')) >> space + ; + + comment = + "[/" >> *(dummy_block | (cl::anychar_p - ']')) >> ']' + ; + + dummy_block = + '[' >> *(dummy_block | (cl::anychar_p - ']')) >> ']' + ; + + common = + macro + | phrase_markup + | code_block + | inline_code + | simple_format + | escape + | comment + ; + + macro = + // must not be followed by alpha or underscore + cl::eps_p(actions.macro + >> (cl::eps_p - (cl::alpha_p | '_'))) + >> actions.macro [actions.do_macro] + ; + + static const bool true_ = true; + static const bool false_ = false; + + template_ = + ( + cl::ch_p('`') [cl::assign_a(actions.template_escape,true_)] + | + cl::eps_p [cl::assign_a(actions.template_escape,false_)] + ) + >> + ( ( + (cl::eps_p(cl::punct_p) + >> actions.templates.scope + ) [cl::assign_a(actions.template_identifier)] + [cl::clear_a(actions.template_args)] + >> !template_args + ) | ( + (actions.templates.scope + >> cl::eps_p(hard_space) + ) [cl::assign_a(actions.template_identifier)] + [cl::clear_a(actions.template_args)] + >> space + >> !template_args + ) ) + >> cl::eps_p(']') + ; + + template_args = + cl::if_p(qbk_since(105u)) [ + template_args_1_5 + ].else_p [ + template_args_1_4 + ] + ; + + template_args_1_4 = template_arg_1_4 >> *(".." >> template_arg_1_4); + + template_arg_1_4 = + ( cl::eps_p(*cl::blank_p >> cl::eol_p) + [cl::assign_a(actions.template_block, true_)] + | cl::eps_p [cl::assign_a(actions.template_block, false_)] + ) + >> template_inner_arg_1_4 [actions.template_arg] + ; + + template_inner_arg_1_4 = + +(brackets_1_4 | (cl::anychar_p - (cl::str_p("..") | ']'))) + ; + + brackets_1_4 = + '[' >> template_inner_arg_1_4 >> ']' + ; + + template_args_1_5 = template_arg_1_5 >> *(".." >> template_arg_1_5); + + template_arg_1_5 = + ( cl::eps_p(*cl::blank_p >> cl::eol_p) + [cl::assign_a(actions.template_block, true_)] + | cl::eps_p [cl::assign_a(actions.template_block, false_)] + ) + >> (+(brackets_1_5 | ('\\' >> cl::anychar_p) | (cl::anychar_p - (cl::str_p("..") | '[' | ']')))) + [actions.template_arg] + ; + + template_inner_arg_1_5 = + +(brackets_1_5 | ('\\' >> cl::anychar_p) | (cl::anychar_p - (cl::str_p('[') | ']'))) + ; + + brackets_1_5 = + '[' >> template_inner_arg_1_5 >> ']' + ; + + inline_code = + '`' >> + ( + *(cl::anychar_p - + ( '`' + | (eol >> eol) // Make sure that we don't go + ) // past a single block + ) >> cl::eps_p('`') + ) [actions.inline_code] + >> '`' + ; + + code_block = + ( + "```" >> + ( + *(cl::anychar_p - "```") + >> cl::eps_p("```") + ) [actions.code_block] + >> "```" + ) + | ( + "``" >> + ( + *(cl::anychar_p - "``") + >> cl::eps_p("``") + ) [actions.code_block] + >> "``" + ) + ; + + simple_format = + simple_bold + | simple_italic + | simple_underline + | simple_teletype + ; + + simple_phrase_end = '[' | phrase_end; + + simple_markup(simple_bold, + '*', actions.simple_bold, simple_phrase_end); + simple_markup(simple_italic, + '/', actions.simple_italic, simple_phrase_end); + simple_markup(simple_underline, + '_', actions.simple_underline, simple_phrase_end); + simple_markup(simple_teletype, + '=', actions.simple_teletype, simple_phrase_end); + + phrase = + *( common + | comment + | (cl::anychar_p - phrase_end) [actions.plain_char] + ) + ; + + phrase_markup = + '[' + >> ( cond_phrase + | image + | url + | link + | anchor + | source_mode + | funcref + | classref + | memberref + | enumref + | macroref + | headerref + | conceptref + | globalref + | bold + | italic + | underline + | teletype + | strikethrough + | quote + | replaceable + | footnote + | template_ [actions.do_template] + | cl::str_p("br") [actions.break_] + ) + >> ']' + ; + + escape = + cl::str_p("\\ ") // ignore an escaped space + | '\\' >> cl::punct_p [actions.raw_char] + | "\\u" >> cl::repeat_p(4) [cl::chset<>("0-9a-fA-F")] + [actions.escape_unicode] + | "\\U" >> cl::repeat_p(8) [cl::chset<>("0-9a-fA-F")] + [actions.escape_unicode] + | ( + ("'''" >> !eol) [actions.escape_pre] + >> *(cl::anychar_p - "'''") [actions.raw_char] + >> cl::str_p("'''") [actions.escape_post] + ) + ; + + macro_identifier = + +(cl::anychar_p - (cl::space_p | ']')) + ; + + cond_phrase = + '?' >> blank + >> macro_identifier [actions.cond_phrase_pre] + >> (!phrase) [actions.cond_phrase_post] + ; + + image = + '$' >> blank [cl::clear_a(actions.attributes)] + >> cl::if_p(qbk_since(105u)) [ + (+( + *cl::space_p + >> +(cl::anychar_p - (cl::space_p | phrase_end | '[')) + )) [cl::assign_a(actions.image_fileref)] + >> hard_space + >> *( + '[' + >> (*(cl::alnum_p | '_')) [cl::assign_a(actions.attribute_name)] + >> space + >> (*(cl::anychar_p - (phrase_end | '['))) + [actions.attribute] + >> ']' + >> space + ) + ].else_p [ + (*(cl::anychar_p - phrase_end)) + [cl::assign_a(actions.image_fileref)] + ] + >> cl::eps_p(']') [actions.image] + ; + + url = + '@' + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.url_pre] + >> hard_space + >> phrase [actions.url_post] + ; + + link = + "link" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.link_pre] + >> hard_space + >> phrase [actions.link_post] + ; + + anchor = + blank + >> (*(cl::anychar_p - phrase_end)) [actions.anchor] + ; + + funcref = + "funcref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.funcref_pre] + >> hard_space + >> phrase [actions.funcref_post] + ; + + classref = + "classref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.classref_pre] + >> hard_space + >> phrase [actions.classref_post] + ; + + memberref = + "memberref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.memberref_pre] + >> hard_space + >> phrase [actions.memberref_post] + ; + + enumref = + "enumref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.enumref_pre] + >> hard_space + >> phrase [actions.enumref_post] + ; + + macroref = + "macroref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.macroref_pre] + >> hard_space + >> phrase [actions.macroref_post] + ; + + headerref = + "headerref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.headerref_pre] + >> hard_space + >> phrase [actions.headerref_post] + ; + + conceptref = + "conceptref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.conceptref_pre] + >> hard_space + >> phrase [actions.conceptref_post] + ; + + globalref = + "globalref" >> hard_space + >> (*(cl::anychar_p - + (']' | hard_space))) [actions.globalref_pre] + >> hard_space + >> phrase [actions.globalref_post] + ; + + bold = + cl::ch_p('*') [actions.bold_pre] + >> blank >> phrase [actions.bold_post] + ; + + italic = + cl::ch_p('\'') [actions.italic_pre] + >> blank >> phrase [actions.italic_post] + ; + + underline = + cl::ch_p('_') [actions.underline_pre] + >> blank >> phrase [actions.underline_post] + ; + + teletype = + cl::ch_p('^') [actions.teletype_pre] + >> blank >> phrase [actions.teletype_post] + ; + + strikethrough = + cl::ch_p('-') [actions.strikethrough_pre] + >> blank >> phrase [actions.strikethrough_post] + ; + + quote = + cl::ch_p('"') [actions.quote_pre] + >> blank >> phrase [actions.quote_post] + ; + + replaceable = + cl::ch_p('~') [actions.replaceable_pre] + >> blank >> phrase [actions.replaceable_post] + ; + + source_mode = + ( + cl::str_p("c++") + | "python" + | "teletype" + ) [cl::assign_a(actions.source_mode)] + ; + + footnote = + cl::str_p("footnote") [actions.footnote_pre] + >> blank >> phrase [actions.footnote_post] + ; + } } #endif // BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP diff --git a/src/post_process.cpp b/src/post_process.cpp index 8e48380..9c98aa2 100644 --- a/src/post_process.cpp +++ b/src/post_process.cpp @@ -16,8 +16,7 @@ namespace quickbook { - using namespace boost::spirit::classic; - using boost::bind; + namespace cl = boost::spirit::classic; typedef std::string::const_iterator iter_type; struct printer @@ -256,7 +255,7 @@ namespace quickbook std::string current_tag; }; - struct tidy_grammar : grammar + struct tidy_grammar : cl::grammar { tidy_grammar(tidy_compiler& state, int indent) : state(state), indent(indent) {} @@ -266,43 +265,43 @@ namespace quickbook { definition(tidy_grammar const& self) { - tag = (lexeme_d[+(alpha_p | '_' | ':')]) [boost::bind(&tidy_grammar::do_tag, &self, _1, _2)]; + tag = (cl::lexeme_d[+(cl::alpha_p | '_' | ':')]) [boost::bind(&tidy_grammar::do_tag, &self, _1, _2)]; code = "" - >> *(anychar_p - "") + >> *(cl::anychar_p - "") >> "" ; - // What's the business of lexeme_d['>' >> *space_p]; ? + // What's the business of cl::lexeme_d['>' >> *cl::space_p]; ? // It is there to preserve the space after the tag that is - // otherwise consumed by the space_p skipper. + // otherwise consumed by the cl::space_p skipper. escape = - str_p("") >> - (*(anychar_p - str_p(""))) + cl::str_p("") >> + (*(cl::anychar_p - cl::str_p(""))) [ boost::bind(&tidy_grammar::do_escape, &self, _1, _2) ] - >> lexeme_d + >> cl::lexeme_d [ - str_p("") >> - (*space_p) + cl::str_p("") >> + (*cl::space_p) [ boost::bind(&tidy_grammar::do_escape_post, &self, _1, _2) ] ] ; - start_tag = '<' >> tag >> *(anychar_p - '>') >> lexeme_d['>' >> *space_p]; + start_tag = '<' >> tag >> *(cl::anychar_p - '>') >> cl::lexeme_d['>' >> *cl::space_p]; start_end_tag = - '<' >> tag >> *(anychar_p - ("/>" | ch_p('>'))) >> lexeme_d["/>" >> *space_p] - | "> tag >> *(anychar_p - '?') >> lexeme_d["?>" >> *space_p] - | "") >> lexeme_d["-->" >> *space_p] - | "> tag >> *(anychar_p - '>') >> lexeme_d['>' >> *space_p] + '<' >> tag >> *(cl::anychar_p - ("/>" | cl::ch_p('>'))) >> cl::lexeme_d["/>" >> *cl::space_p] + | "> tag >> *(cl::anychar_p - '?') >> cl::lexeme_d["?>" >> *cl::space_p] + | "") >> cl::lexeme_d["-->" >> *cl::space_p] + | "> tag >> *(cl::anychar_p - '>') >> cl::lexeme_d['>' >> *cl::space_p] ; - content = lexeme_d[ +(anychar_p - '<') ]; - end_tag = "> +(anychar_p - '>') >> lexeme_d['>' >> *space_p]; + content = cl::lexeme_d[ +(cl::anychar_p - '<') ]; + end_tag = "> +(cl::anychar_p - '>') >> cl::lexeme_d['>' >> *cl::space_p]; markup = escape @@ -316,10 +315,11 @@ namespace quickbook tidy = +markup; } - rule const& + cl::rule const& start() { return tidy; } - rule tidy, tag, start_tag, start_end_tag, + cl::rule + tidy, tag, start_tag, start_end_tag, content, end_tag, markup, code, escape; }; @@ -435,7 +435,7 @@ namespace quickbook std::string tidy; tidy_compiler state(tidy, linewidth); tidy_grammar g(state, indent); - parse_info r = parse(in.begin(), in.end(), g, space_p); + cl::parse_info r = parse(in.begin(), in.end(), g, cl::space_p); if (r.full) { out << tidy; diff --git a/src/quickbook.cpp b/src/quickbook.cpp index a85ac78..25571cc 100644 --- a/src/quickbook.cpp +++ b/src/quickbook.cpp @@ -32,14 +32,12 @@ namespace quickbook { - using namespace boost::spirit::classic; + namespace cl = boost::spirit::classic; namespace fs = boost::filesystem; + tm* current_time; // the current time tm* current_gm_time; // the current UTC time bool debug_mode; // for quickbook developers only - int qbk_major_version = -1; - int qbk_minor_version = -1; - unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version bool ms_errors = false; // output errors/warnings as if for VS std::vector include_path; std::vector preset_defines; @@ -53,11 +51,10 @@ namespace quickbook end = preset_defines.end(); it != end; ++it) { - typedef position_iterator iterator_type; - iterator_type first(it->begin(), it->end(), "command line parameter"); - iterator_type last(it->end(), it->end()); + iterator first(it->begin(), it->end(), "command line parameter"); + iterator last(it->end(), it->end()); - parse(first, last, grammar); + call_parse(first, last, grammar); // TODO: Check result? } } @@ -81,19 +78,18 @@ namespace quickbook return err; } - typedef position_iterator iterator_type; - iterator_type first(storage.begin(), storage.end(), filein_); - iterator_type last(storage.end(), storage.end()); + iterator first(storage.begin(), storage.end(), filein_); + iterator last(storage.end(), storage.end()); doc_info_grammar l(actor); - parse_info info = parse(first, last, l); + cl::parse_info info = call_parse(first, last, l); if (info.hit || ignore_docinfo) { pre(actor.out, actor, ignore_docinfo); block_grammar g(actor); - info = parse(info.hit ? info.stop : first, last, g); + info = call_parse(info.hit ? info.stop : first, last, g); if (info.full) { post(actor.out, actor, ignore_docinfo); @@ -102,7 +98,7 @@ namespace quickbook if (!info.full) { - file_position const pos = info.stop.get_position(); + position const pos = info.stop.get_position(); detail::outerr(pos.file,pos.line) << "Syntax Error near column " << pos.column << ".\n"; ++actor.error_count; @@ -140,24 +136,24 @@ namespace quickbook , bool pretty_print) { int result = 0; - std::ofstream fileout(fileout_); fs::path outdir = fs::path(fileout_).parent_path(); if (outdir.empty()) outdir = "."; - if (pretty_print) + string_stream buffer; + result = parse_document(filein_, outdir, buffer); + + if (result == 0) { - string_stream buffer; - result = parse_document(filein_, outdir, buffer); - if (result == 0) + std::ofstream fileout(fileout_); + + if (pretty_print) { result = post_process(buffer.str(), fileout, indent, linewidth); } - } - else - { - string_stream buffer; - result = parse_document(filein_, outdir, buffer); - fileout << buffer.str(); + else + { + fileout << buffer.str(); + } } return result; } diff --git a/src/quickbook.hpp b/src/quickbook.hpp index 01e376b..de480ef 100644 --- a/src/quickbook.hpp +++ b/src/quickbook.hpp @@ -12,36 +12,20 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_QUICKBOOK_HPP) #define BOOST_SPIRIT_QUICKBOOK_QUICKBOOK_HPP +#include +#include +#include +#include "fwd.hpp" + namespace quickbook { - extern int qbk_major_version; - extern int qbk_minor_version; - extern unsigned qbk_version_n; // qbk_major_version * 100 + qbk_minor_version + extern tm* current_time; // the current time + extern tm* current_gm_time; // the current UTC time + extern bool debug_mode; + extern std::vector include_path; + extern std::vector preset_defines; - struct quickbook_range { - template - struct result - { - typedef bool type; - }; - - quickbook_range(unsigned min_, unsigned max_) - : min_(min_), max_(max_) {} - - bool operator()() const { - return qbk_version_n >= min_ && qbk_version_n < max_; - } - - unsigned min_, max_; - }; - - inline quickbook_range qbk_since(unsigned min_) { - return quickbook_range(min_, 999); - } - - inline quickbook_range qbk_before(unsigned max_) { - return quickbook_range(0, max_); - } + int parse_file(char const* filein_, actions& actor, bool ignore_docinfo = false); } #endif diff --git a/src/scoped_block.hpp b/src/scoped_block.hpp new file mode 100644 index 0000000..b346ffa --- /dev/null +++ b/src/scoped_block.hpp @@ -0,0 +1,134 @@ +/*============================================================================= + Copyright (c) 2010 Daniel James + Copyright (c) 2003 Martin Wille + http://spirit.sourceforge.net/ + + 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) + =============================================================================*/ + +// Used to parse an inner block, saves the streams and restores them if the +// parse fails. On success the action is passed the resulting block. +// +// Might be a good idea to do something more generic in the future. +// +// This is based on `boost::spirit::classic::scoped_lock` by Martin Wille + +#ifndef BOOST_QUICKBOOK_SCOPED_BLOCK_HPP +#define BOOST_QUICKBOOK_SCOPED_BLOCK_HPP + +#include +#include +#include "actions_class.hpp" + +namespace quickbook { + + namespace cl = boost::spirit::classic; + + struct scoped_block_push + { + typedef std::string attribute; + + scoped_block_push(quickbook::actions& actions) + : actions(actions) + { + actions.out.push(); + actions.phrase.push(); + } + + ~scoped_block_push() + { + actions.phrase.pop(); + actions.out.pop(); + } + + std::string const& finish() + { + actions.inside_paragraph(); + return actions.out.str(); + } + + quickbook::actions& actions; + }; + + template + struct scoped_block_parser + : public cl::unary< ParserT, cl::parser< scoped_block_parser > > + { + typedef scoped_block_parser self_t; + typedef cl::unary< ParserT, cl::parser< scoped_block_parser > > base_t; + + template + struct result + { + typedef cl::match type; + }; + + scoped_block_parser(quickbook::actions& a, ParserT const &p) + : base_t(p) + , actions(a) + {} + + template + cl::match parse(ScannerT const &scan) const + { + typedef typename ScannerT::iterator_t iterator_t; + iterator_t save = scan.first; + + scoped_block_push push(actions); + typename cl::parser_result::type result + = this->subject().parse(scan); + + if (result) + return scan.create_match(result.length(), push.finish(), save, scan.first); + else + return scan.no_match(); + } + + quickbook::actions& actions; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // scoped_block_parser_gen + // + // generator for scoped_block_parser objects + // operator[] returns scoped_block_parser according to its argument + // + /////////////////////////////////////////////////////////////////////////// + struct scoped_block_parser_gen + { + explicit scoped_block_parser_gen(quickbook::actions& actions) + : actions(actions) {} + + template + scoped_block_parser + < + typename cl::as_parser::type + > + operator[](ParserT const &p) const + { + typedef cl::as_parser as_parser_t; + typedef typename as_parser_t::type parser_t; + + return scoped_block_parser + (actions, as_parser_t::convert(p)); + } + + quickbook::actions& actions; + }; + + + /////////////////////////////////////////////////////////////////////////// + // + // scoped_block_d parser directive + // + // constructs a scoped_block_parser generator from its argument + // + /////////////////////////////////////////////////////////////////////////// + inline scoped_block_parser_gen scoped_block(quickbook::actions& actions) { + return scoped_block_parser_gen(actions); + } + +} +#endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP diff --git a/src/syntax_highlight.cpp b/src/syntax_highlight.cpp index 9260925..20ba63b 100644 --- a/src/syntax_highlight.cpp +++ b/src/syntax_highlight.cpp @@ -43,22 +43,27 @@ namespace quickbook , collector> teletype_p_type; - std::string syntax_highlight::operator()(iterator first, iterator last) const + std::string syntax_highlight( + iterator first, iterator last, + actions& escape_actions, + std::string const& source_mode) { + quickbook::collector temp; + // print the code with syntax coloring if (source_mode == "c++") { - cpp_p_type cpp_p(temp, macro, do_macro_action(temp), escape_actions); + cpp_p_type cpp_p(temp, escape_actions.macro, do_macro_action(temp), escape_actions); boost::spirit::classic::parse(first, last, cpp_p); } else if (source_mode == "python") { - python_p_type python_p(temp, macro, do_macro_action(temp), escape_actions); + python_p_type python_p(temp, escape_actions.macro, do_macro_action(temp), escape_actions); boost::spirit::classic::parse(first, last, python_p); } else if (source_mode == "teletype") { - teletype_p_type teletype_p(temp, macro, do_macro_action(temp), escape_actions); + teletype_p_type teletype_p(temp, escape_actions.macro, do_macro_action(temp), escape_actions); boost::spirit::classic::parse(first, last, teletype_p); } else diff --git a/src/syntax_highlight.hpp b/src/syntax_highlight.hpp index 2592cc5..703ae90 100644 --- a/src/syntax_highlight.hpp +++ b/src/syntax_highlight.hpp @@ -19,7 +19,7 @@ namespace quickbook { - using namespace boost::spirit::classic; + namespace cl = boost::spirit::classic; // Grammar for C++ highlighting template < @@ -32,7 +32,7 @@ namespace quickbook , typename Unexpected , typename Out> struct cpp_highlight - : public grammar > + : public cl::grammar > { cpp_highlight(Out& out, Macro const& macro, DoMacro do_macro, actions& escape_actions) : out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {} @@ -46,7 +46,7 @@ namespace quickbook { program = - *( (+space_p) [Space(self.out)] + *( (+cl::space_p) [Space(self.out)] | macro | escape | preprocessor [Process("preprocessor", self.out)] @@ -57,51 +57,54 @@ namespace quickbook | string_ [Process("string", self.out)] | char_ [Process("char", self.out)] | number [Process("number", self.out)] - | repeat_p(1)[anychar_p] [Unexpected(self.out)] + | cl::repeat_p(1)[cl::anychar_p] + [Unexpected(self.out)] ) ; - macro = - eps_p(self.macro // must not be followed by - >> (eps_p - (alpha_p | '_'))) // alpha or underscore + macro = + // must not be followed by alpha or underscore + cl::eps_p(self.macro + >> (cl::eps_p - (cl::alpha_p | '_'))) >> self.macro [self.do_macro] ; qbk_phrase = *( common - | (anychar_p - str_p("``")) [self.escape_actions.plain_char] + | (cl::anychar_p - cl::str_p("``")) + [self.escape_actions.plain_char] ) ; escape = - str_p("``") [PreEscape(self.escape_actions, save)] + cl::str_p("``") [PreEscape(self.escape_actions, save)] >> ( ( ( - (+(anychar_p - "``") >> eps_p("``")) + (+(cl::anychar_p - "``") >> cl::eps_p("``")) & qbk_phrase ) - >> str_p("``") + >> cl::str_p("``") ) | ( - eps_p [self.escape_actions.error] - >> *anychar_p + cl::eps_p [self.escape_actions.error] + >> *cl::anychar_p ) ) [PostEscape(self.out, self.escape_actions, save)] ; preprocessor - = '#' >> *space_p >> ((alpha_p | '_') >> *(alnum_p | '_')) + = '#' >> *cl::space_p >> ((cl::alpha_p | '_') >> *(cl::alnum_p | '_')) ; comment - = comment_p("//") | comment_p("/*", "*/") + = cl::comment_p("//") | cl::comment_p("/*", "*/") ; keyword - = keyword_ >> (eps_p - (alnum_p | '_')) + = keyword_ >> (cl::eps_p - (cl::alnum_p | '_')) ; // make sure we recognize whole words only keyword_ @@ -122,43 +125,44 @@ namespace quickbook ; special - = +chset_p("~!%^&*()+={[}]:;,<.>?/|\\-") + = +cl::chset_p("~!%^&*()+={[}]:;,<.>?/|\\-") ; - string_char = ('\\' >> anychar_p) | (anychar_p - '\\'); + string_char = ('\\' >> cl::anychar_p) | (cl::anychar_p - '\\'); string_ - = !as_lower_d['l'] >> confix_p('"', *string_char, '"') + = !cl::as_lower_d['l'] >> cl::confix_p('"', *string_char, '"') ; char_ - = !as_lower_d['l'] >> confix_p('\'', *string_char, '\'') + = !cl::as_lower_d['l'] >> cl::confix_p('\'', *string_char, '\'') ; number = ( - as_lower_d["0x"] >> hex_p - | '0' >> oct_p - | real_p + cl::as_lower_d["0x"] >> cl::hex_p + | '0' >> cl::oct_p + | cl::real_p ) - >> *as_lower_d[chset_p("ldfu")] + >> *cl::as_lower_d[cl::chset_p("ldfu")] ; identifier - = (alpha_p | '_') >> *(alnum_p | '_') + = (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; } - rule program, macro, preprocessor, comment, special, string_, + cl::rule + program, macro, preprocessor, comment, special, string_, char_, number, identifier, keyword, qbk_phrase, escape, string_char; - symbols<> keyword_; + cl::symbols<> keyword_; phrase_grammar common; std::string save; bool unused; - rule const& + cl::rule const& start() const { return program; } }; @@ -181,7 +185,7 @@ namespace quickbook , typename Unexpected , typename Out> struct python_highlight - : public grammar > + : public cl::grammar > { python_highlight(Out& out, Macro const& macro, DoMacro do_macro, actions& escape_actions) : out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {} @@ -195,7 +199,7 @@ namespace quickbook { program = - *( (+space_p) [Space(self.out)] + *( (+cl::space_p) [Space(self.out)] | macro | escape | comment [Process("comment", self.out)] @@ -204,47 +208,50 @@ namespace quickbook | special [Process("special", self.out)] | string_ [Process("string", self.out)] | number [Process("number", self.out)] - | repeat_p(1)[anychar_p] [Unexpected(self.out)] + | cl::repeat_p(1)[cl::anychar_p] + [Unexpected(self.out)] ) ; macro = - eps_p(self.macro // must not be followed by - >> (eps_p - (alpha_p | '_'))) // alpha or underscore + // must not be followed by alpha or underscore + cl::eps_p(self.macro + >> (cl::eps_p - (cl::alpha_p | '_'))) >> self.macro [self.do_macro] ; qbk_phrase = *( common - | (anychar_p - str_p("``")) [self.escape_actions.plain_char] + | (cl::anychar_p - cl::str_p("``")) + [self.escape_actions.plain_char] ) ; escape = - str_p("``") [PreEscape(self.escape_actions, save)] + cl::str_p("``") [PreEscape(self.escape_actions, save)] >> ( ( ( - (+(anychar_p - "``") >> eps_p("``")) + (+(cl::anychar_p - "``") >> cl::eps_p("``")) & qbk_phrase ) - >> str_p("``") + >> cl::str_p("``") ) | ( - eps_p [self.escape_actions.error] - >> *anychar_p + cl::eps_p [self.escape_actions.error] + >> *cl::anychar_p ) ) [PostEscape(self.out, self.escape_actions, save)] ; comment - = comment_p("#") + = cl::comment_p("#") ; keyword - = keyword_ >> (eps_p - (alnum_p | '_')) + = keyword_ >> (cl::eps_p - (cl::alnum_p | '_')) ; // make sure we recognize whole words only keyword_ @@ -264,55 +271,56 @@ namespace quickbook ; special - = +chset_p("~!%^&*()+={[}]:;,<.>/|\\-") + = +cl::chset_p("~!%^&*()+={[}]:;,<.>/|\\-") ; string_prefix - = as_lower_d[str_p("u") >> ! str_p("r")] + = cl::as_lower_d[cl::str_p("u") >> ! cl::str_p("r")] ; string_ = ! string_prefix >> (long_string | short_string) ; - string_char = ('\\' >> anychar_p) | (anychar_p - '\\'); + string_char = ('\\' >> cl::anychar_p) | (cl::anychar_p - '\\'); short_string - = confix_p('\'', * string_char, '\'') | - confix_p('"', * string_char, '"') + = cl::confix_p('\'', * string_char, '\'') | + cl::confix_p('"', * string_char, '"') ; long_string - // Note: the "str_p" on the next two lines work around + // Note: the "cl::str_p" on the next two lines work around // an INTERNAL COMPILER ERROR when using VC7.1 - = confix_p(str_p("'''"), * string_char, "'''") | - confix_p(str_p("\"\"\""), * string_char, "\"\"\"") + = cl::confix_p(cl::str_p("'''"), * string_char, "'''") | + cl::confix_p(cl::str_p("\"\"\""), * string_char, "\"\"\"") ; number = ( - as_lower_d["0x"] >> hex_p - | '0' >> oct_p - | real_p + cl::as_lower_d["0x"] >> cl::hex_p + | '0' >> cl::oct_p + | cl::real_p ) - >> *as_lower_d[chset_p("lj")] + >> *cl::as_lower_d[cl::chset_p("lj")] ; identifier - = (alpha_p | '_') >> *(alnum_p | '_') + = (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; } - rule program, macro, comment, special, string_, string_prefix, + cl::rule + program, macro, comment, special, string_, string_prefix, short_string, long_string, number, identifier, keyword, qbk_phrase, escape, string_char; - symbols<> keyword_; + cl::symbols<> keyword_; phrase_grammar common; std::string save; bool unused; - rule const& + cl::rule const& start() const { return program; } }; @@ -331,7 +339,7 @@ namespace quickbook , typename PostEscape , typename Out> struct teletype_highlight - : public grammar > + : public cl::grammar > { teletype_highlight(Out& out, Macro const& macro, DoMacro do_macro, actions& escape_actions) : out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {} @@ -347,49 +355,51 @@ namespace quickbook = *( macro | escape - | repeat_p(1)[anychar_p] [CharProcess(self.out)] + | cl::repeat_p(1)[cl::anychar_p] [CharProcess(self.out)] ) ; - macro = - eps_p(self.macro // must not be followed by - >> (eps_p - (alpha_p | '_'))) // alpha or underscore - >> self.macro [self.do_macro] + macro = + // must not be followed by alpha or underscore + cl::eps_p(self.macro + >> (cl::eps_p - (cl::alpha_p | '_'))) + >> self.macro [self.do_macro] ; qbk_phrase = *( common - | (anychar_p - str_p("``")) [self.escape_actions.plain_char] + | (cl::anychar_p - cl::str_p("``")) + [self.escape_actions.plain_char] ) ; escape = - str_p("``") [PreEscape(self.escape_actions, save)] + cl::str_p("``") [PreEscape(self.escape_actions, save)] >> ( ( ( - (+(anychar_p - "``") >> eps_p("``")) + (+(cl::anychar_p - "``") >> cl::eps_p("``")) & qbk_phrase ) - >> str_p("``") + >> cl::str_p("``") ) | ( - eps_p [self.escape_actions.error] - >> *anychar_p + cl::eps_p [self.escape_actions.error] + >> *cl::anychar_p ) ) [PostEscape(self.out, self.escape_actions, save)] ; } - rule program, macro, qbk_phrase, escape; + cl::rule program, macro, qbk_phrase, escape; phrase_grammar common; std::string save; bool unused; - rule const& + cl::rule const& start() const { return program; } }; diff --git a/src/template_stack.hpp b/src/template_stack.hpp index 6d7badf..a343fe9 100644 --- a/src/template_stack.hpp +++ b/src/template_stack.hpp @@ -25,7 +25,7 @@ namespace quickbook { template_body( std::string const& content, - boost::spirit::classic::file_position position, + boost::spirit::classic::file_position const& position, bool is_block ) : content(content) @@ -33,8 +33,21 @@ namespace quickbook , is_block(is_block) { } + + template_body( + std::string const& content, + boost::spirit::classic::file_position_base const& position, + bool is_block + ) + : content(content) + , position(position.file, position.line, position.column) + , is_block(is_block) + { + } std::string content; + // Note: Using file_position to store the filename after the file + // has been closed. boost::spirit::classic::file_position position; bool is_block; }; @@ -57,6 +70,20 @@ namespace quickbook , callout(false) , callouts() {} + template_symbol( + std::string const& identifier, + std::vector const& params, + std::string const& body, + boost::spirit::classic::file_position_base const& position, + bool is_block, + template_scope const* parent = 0) + : identifier(identifier) + , params(params) + , body(body, position, is_block) + , parent(parent) + , callout(false) + , callouts() {} + std::string identifier; std::vector params; template_body body; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ad27257..871d0a7 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -19,7 +19,7 @@ test-suite quickbook.test : [ quickbook-test code-block-teletype ] [ quickbook-test code-snippet ] [ quickbook-test preformatted ] - [ quickbook-test link-side-by-side ] + [ quickbook-test link ] [ quickbook-test escape ] [ quickbook-test templates ] [ quickbook-test templates_1_4 ] @@ -45,6 +45,7 @@ test-suite quickbook.test : [ quickbook-test image_1_5 ] [ quickbook-test list_test ] [ quickbook-test cond_phrase ] + [ quickbook-test macro ] [ quickbook-test doc-info-1 ] [ quickbook-test doc-info-2 ] [ quickbook-test doc-info-3 ] diff --git a/test/blocks.gold b/test/blocks.gold index 585580d..e0e0b7f 100644 --- a/test/blocks.gold +++ b/test/blocks.gold @@ -83,4 +83,7 @@ . + + [tipping point] + diff --git a/test/blocks.quickbook b/test/blocks.quickbook index 9b4736e..74a9676 100644 --- a/test/blocks.quickbook +++ b/test/blocks.quickbook @@ -36,4 +36,7 @@ Warning second paragraph.] [: Blockquote containing a footnote[footnote Here it is!].] -[/ Unfortunately footnotes currently can't contain blocks.] \ No newline at end of file +[/ Unfortunately footnotes currently can't contain blocks.] + +[/ Quickbook shouldn't think that this is a tip] +[tipping point] \ No newline at end of file diff --git a/test/callouts.cpp b/test/callouts.cpp index fd9394c..82981e7 100644 --- a/test/callouts.cpp +++ b/test/callouts.cpp @@ -3,6 +3,8 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt) +/*< This shouldn't be used. >*/ + //[ example1 /*` diff --git a/test/doc-info-1.gold b/test/doc-info-1.gold index 4a83482..86c8ed8 100644 --- a/test/doc-info-1.gold +++ b/test/doc-info-1.gold @@ -19,5 +19,6 @@ Inline code test: 1 + 2 + http://www.boost.org/tools/quickbook/test/doc-info-1.quickbook diff --git a/test/doc-info-1.quickbook b/test/doc-info-1.quickbook index ffe982e..cb5ecb4 100644 --- a/test/doc-info-1.quickbook +++ b/test/doc-info-1.quickbook @@ -1,9 +1,10 @@ [article Karel Vom\u00E1\u010Dka and Tom\u00E1\u0161 Martin\u00EDk -[quickbook 1.5] +[quickbook 1.6] [authors [Meik\u00E4l\u00E4inen, Matti][Peri\u0107, Pero]] [copyright 2010 Me\u00F0al-J\u00F3n and J\u00F3na J\u00F3nsd\u00F3ttir] [source-mode teletype] [purpose Inline code test: `1 + 2`] [category tests] [category irrelevance] -] \ No newline at end of file +[biblioid uri http://www.boost.org/tools/quickbook/test/doc-info-1.quickbook] +] diff --git a/test/doc-info-2.gold b/test/doc-info-2.gold index 55311c4..83870c7 100644 --- a/test/doc-info-2.gold +++ b/test/doc-info-2.gold @@ -1,20 +1,26 @@ - + - Joe Blow + Matti Meikäläinen - Jane Doe + Pero Perić + + 2010 Meðal-Jón and Jóna Jónsdóttir + Inline code test: 1 + 2 + http://www.boost.org/tools/quickbook/test/doc-info-2.quickbook + 0-937383-18-X - Document Information 1 + Karel Vomáčka and Tomáš Martiník diff --git a/test/doc-info-2.quickbook b/test/doc-info-2.quickbook index c3c812e..3d00865 100644 --- a/test/doc-info-2.quickbook +++ b/test/doc-info-2.quickbook @@ -1,10 +1,13 @@ -[library Document Information 1 +[library Karel Vomáčka and Tomáš Martiník [quickbook 1.5] -[authors [Blow, Joe] [Doe, Jane]] +[authors [Meikäläinen, Matti],[Perić, Pero]] +[copyright 2010 Meðal-Jón and Jóna Jónsdóttir] [source-mode teletype] [purpose Inline code test: `1 + 2`] [category tests] [category irrelevance] +[biblioid uri http://www.boost.org/tools/quickbook/test/doc-info-2.quickbook] +[biblioid isbn 0-937383-18-X] ] -[/ Some comment] \ No newline at end of file +[/ Some comment] diff --git a/test/link-side-by-side.gold b/test/link-side-by-side.gold deleted file mode 100644 index e471641..0000000 --- a/test/link-side-by-side.gold +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/test/link-side-by-side.quickbook b/test/link-side-by-side.quickbook deleted file mode 100644 index aa3e1e4..0000000 --- a/test/link-side-by-side.quickbook +++ /dev/null @@ -1,13 +0,0 @@ -[article Side-by-side links -] - -[section Side-by-side links] - -[link x] and [link y] are two distinct links, which should be separated by -whitespace when they appear together as in [link x] [link y]. Also in [link x] -[link y], and in -[link x] -[link y] -as well. - -[endsect] diff --git a/test/link.gold b/test/link.gold new file mode 100644 index 0000000..36a52f7 --- /dev/null +++ b/test/link.gold @@ -0,0 +1,30 @@ + + + diff --git a/test/link.quickbook b/test/link.quickbook new file mode 100644 index 0000000..c480da1 --- /dev/null +++ b/test/link.quickbook @@ -0,0 +1,39 @@ +[article Link tests +] + +[section Different types of links] + +[@http://www.boost.org/] +[@http://www.boost.org/ Boost] +[link link-id] +[link link-id Link Text] +[#link-id] +[funcref foo] +[funcref foo link text] +[classref foo] +[classref foo link text] +[memberref foo] +[memberref foo link text] +[enumref foo] +[enumref foo link text] +[macroref foo] +[macroref foo link text] +[headerref foo] +[headerref foo link text] +[conceptref foo] +[conceptref foo link text] +[globalref foo] +[globalref foo link text] + +[endsect] + +[section Side-by-side links] + +[link x] and [link y] are two distinct links, which should be separated by +whitespace when they appear together as in [link x] [link y]. Also in [link x] +[link y], and in +[link x] +[link y] +as well. + +[endsect] diff --git a/test/list_test.gold b/test/list_test.gold index 7319570..095e5bc 100644 --- a/test/list_test.gold +++ b/test/list_test.gold @@ -210,4 +210,25 @@ +
+ <link linkend="list_test.list_immediately_following_markup">List immediately + following markup</link> + + + + One + + + + + Two + + + + + Three + + + +
diff --git a/test/list_test.quickbook b/test/list_test.quickbook index 09454b1..ceecbbf 100644 --- a/test/list_test.quickbook +++ b/test/list_test.quickbook @@ -51,3 +51,10 @@ Three level list: # D # G # H + +[section List immediately following markup] +* One +* Two +* Three + +[endsect] diff --git a/test/macro.gold b/test/macro.gold new file mode 100644 index 0000000..b9097a7 --- /dev/null +++ b/test/macro.gold @@ -0,0 +1,14 @@ + + +
+ Macro Test + + 1 + + + 2 + + + two + +
diff --git a/test/macro.quickbook b/test/macro.quickbook new file mode 100644 index 0000000..a979bf7 --- /dev/null +++ b/test/macro.quickbook @@ -0,0 +1,16 @@ +[article Macro Test +[quickbook 1.5] +] + +[def one 1] + +one + +[template foo[] + +[def two 2] +two +] + +[foo] +two [/This shouldn't expand] \ No newline at end of file diff --git a/test/templates.gold b/test/templates.gold index e100d84..1ddb72d 100644 --- a/test/templates.gold +++ b/test/templates.gold @@ -64,4 +64,47 @@
<link linkend="templates.empty_templates">Empty Templates</link>
+
+ <link linkend="templates.nested_templates">Nested Templates</link> + + Start block template. + + + Start block template. + + + Hello! + + + End block template. + + + End block template. + + + Start block template. + + + Start phrase template. Hello! End phrase template. + + + End block template. + + + Start phrase template. + + + Start block template. + + + Hello! + + + End block template. + + + End phrase template. Start phrase template. Start phrase template. Hello! End + phrase template. End phrase template. + +
diff --git a/test/templates.quickbook b/test/templates.quickbook index 3215b7d..586caf6 100644 --- a/test/templates.quickbook +++ b/test/templates.quickbook @@ -143,4 +143,26 @@ x[super 2] [empty_arg1 1] [empty_arg2 1 2] +[endsect] + +[/----------------------------------- Nested templates ] + +[section Nested Templates] + +[template block[content] + +Start block template. + +[content] + +End block template. +] + +[template phrase[content] Start phrase template. [content] End phrase template.] + +[block [block Hello!]] +[block [phrase Hello!]] +[phrase [block Hello!]] +[phrase [phrase Hello!]] + [endsect] \ No newline at end of file diff --git a/test/xml-escape_1_5.gold b/test/xml-escape_1_5.gold index 1d9c859..f2b5eb7 100644 --- a/test/xml-escape_1_5.gold +++ b/test/xml-escape_1_5.gold @@ -1,7 +1,7 @@ - @@ -14,8 +14,8 @@ dirname="test_that______are_being_escaped_" last-revision="DEBUG MODE Date: 2000 Test that &, < are being escaped. -
- <link linkend="test_that______are_being_escaped_.escapes___explicitly_written_markup">Escapes + <section id="test_that__amp____lt__are_being_escaped_.escapes___explicitly_written_markup"> + <title><link linkend="test_that__amp____lt__are_being_escaped_.escapes___explicitly_written_markup">Escapes & explicitly written markup</link> diff --git a/test/xml-escape_1_5.quickbook b/test/xml-escape_1_5.quickbook index 9e9478f..642e1b5 100644 --- a/test/xml-escape_1_5.quickbook +++ b/test/xml-escape_1_5.quickbook @@ -1,4 +1,4 @@ -[library Test that &, < are being escaped. +[library Test that &, < are being escaped. [quickbook 1.5] [purpose & should be &, < should <] [license & should be &, < should <]