From bd75566c9f36e2c1674c4da8723b491a64c9335c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 22 Feb 2011 20:49:11 +0000 Subject: [PATCH 01/24] No longer using macro_id. [SVN r69182] --- src/actions_class.cpp | 1 - src/actions_class.hpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/actions_class.cpp b/src/actions_class.cpp index 5dcb11a..1751224 100644 --- a/src/actions_class.cpp +++ b/src/actions_class.cpp @@ -55,7 +55,6 @@ namespace quickbook , source_mode("c++") // temporary or global state - , macro_id() , template_depth(0) , templates() , error_count(0) diff --git a/src/actions_class.hpp b/src/actions_class.hpp index 14e5724..1d8918b 100644 --- a/src/actions_class.hpp +++ b/src/actions_class.hpp @@ -88,7 +88,6 @@ namespace quickbook std::stack macro_stack; // temporary or global state - std::string macro_id; int template_depth; template_stack templates; int error_count; From f37d4c018b106f1d88c683763a5b40c0a0b13a0b Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 22 Feb 2011 21:27:28 +0000 Subject: [PATCH 02/24] Combine varlistitem and table_cell. [SVN r69187] --- src/block_element_grammar.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/block_element_grammar.cpp b/src/block_element_grammar.cpp index fae9ad0..1133f9c 100644 --- a/src/block_element_grammar.cpp +++ b/src/block_element_grammar.cpp @@ -29,7 +29,7 @@ namespace quickbook cl::rule heading, inner_block, inner_phrase, def_macro, table, table_row, variablelist, - varlistentry, varlistterm, varlistitem, table_cell, + varlistentry, varlistterm, cell, preformatted, begin_section, end_section, xinclude, include, template_, template_id, template_formal_arg, @@ -185,7 +185,7 @@ namespace quickbook [ ( local.varlistterm - >> ( +local.varlistitem + >> ( +local.cell | cl::eps_p [actions.error] ) >> cl::ch_p(']') @@ -205,16 +205,6 @@ namespace quickbook ) ; - local.varlistitem = - space - >> cl::ch_p('[') - >> ( local.inner_block - >> cl::ch_p(']') - >> space - | cl::eps_p [actions.error] - ) - ; - elements.add ("table", element_info(element_info::block, &local.table, block_tags::table)) ; @@ -235,7 +225,7 @@ namespace quickbook ( ( actions.values.list(table_tags::row) - [ *local.table_cell + [ *local.cell ] >> cl::ch_p(']') >> space @@ -244,14 +234,13 @@ namespace quickbook ) ; - local.table_cell = + local.cell = space >> cl::ch_p('[') - >> ( cl::eps_p - >> local.inner_block + >> ( local.inner_block >> cl::ch_p(']') >> space - | cl::eps_p [actions.error] + | cl::eps_p [actions.error] ) ; From d485fdc00f86f216edb79516da9914c404e1057e Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 22 Feb 2011 21:28:07 +0000 Subject: [PATCH 03/24] Handle elements in one rule. [SVN r69188] --- src/actions.cpp | 25 +++++- src/actions.hpp | 19 ++++- src/actions_class.cpp | 1 + src/actions_class.hpp | 3 + src/main_grammar.cpp | 191 ++++++++++++++++++++++-------------------- src/parsers.hpp | 32 ++++--- src/rule_store.hpp | 10 +++ src/scoped.hpp | 8 +- src/values_parse.hpp | 22 +++-- 9 files changed, 192 insertions(+), 119 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 062f1f5..0c97aa8 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -326,7 +326,7 @@ namespace quickbook out << post; } - void cond_phrase_push::start() + bool cond_phrase_push::start() { saved_suppress = actions.suppress; @@ -335,6 +335,8 @@ namespace quickbook values.consume().get_quickbook().c_str()); actions.suppress = actions.suppress || !condition; + + return true; } void cond_phrase_push::cleanup() @@ -1717,11 +1719,13 @@ namespace quickbook return (*this)(actions.out); } - void scoped_output_push::start() + bool scoped_output_push::start() { actions.out.push(); actions.phrase.push(); actions.anchors.swap(saved_anchors); + + return true; } void scoped_output_push::cleanup() @@ -1731,14 +1735,29 @@ namespace quickbook actions.anchors.swap(saved_anchors); } - void set_no_eols_scoped::start() + bool set_no_eols_scoped::start() { saved_no_eols = actions.no_eols; actions.no_eols = false; + + return true; } void set_no_eols_scoped::cleanup() { actions.no_eols = saved_no_eols; } + + bool scoped_context_impl::start(int new_context) + { + saved_context_ = actions_.context; + actions_.context = new_context; + + return true; + } + + void scoped_context_impl::cleanup() + { + actions_.context = saved_context_; + } } diff --git a/src/actions.hpp b/src/actions.hpp index b3e720f..0b858bd 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -162,7 +162,7 @@ namespace quickbook cond_phrase_push(quickbook::actions& x) : actions(x) {} - void start(); + bool start(); void cleanup(); quickbook::actions& actions; @@ -443,7 +443,7 @@ namespace quickbook scoped_output_push(quickbook::actions& actions) : actions(actions) {} - void start(); + bool start(); void cleanup(); quickbook::actions& actions; @@ -455,12 +455,25 @@ namespace quickbook set_no_eols_scoped(quickbook::actions& actions) : actions(actions) {} - void start(); + bool start(); void cleanup(); quickbook::actions& actions; bool saved_no_eols; }; + + struct scoped_context_impl : scoped_action_base + { + scoped_context_impl(quickbook::actions& actions) + : actions_(actions) {} + + bool start(int); + void cleanup(); + + private: + quickbook::actions& actions_; + int saved_context_; + }; } #ifdef BOOST_MSVC diff --git a/src/actions_class.cpp b/src/actions_class.cpp index 1751224..98065c7 100644 --- a/src/actions_class.cpp +++ b/src/actions_class.cpp @@ -42,6 +42,7 @@ namespace quickbook , scoped_cond_phrase(*this) , scoped_output(*this) , scoped_no_eols(*this) + , scoped_context(*this) // state , filename(fs::absolute(filein_)) diff --git a/src/actions_class.hpp b/src/actions_class.hpp index 1d8918b..e3702b1 100644 --- a/src/actions_class.hpp +++ b/src/actions_class.hpp @@ -60,6 +60,8 @@ namespace quickbook scoped_output; scoped_parser scoped_no_eols; + scoped_parser + scoped_context; // state fs::path filename; @@ -95,6 +97,7 @@ namespace quickbook bool no_eols; bool suppress; bool warned_about_breaks; + int context; // push/pop the states and the streams void copy_macros_for_write(); diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 3111cb9..4a858a1 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -14,10 +14,9 @@ #include "template_tags.hpp" #include "block_tags.hpp" #include "parsers.hpp" +#include "scoped.hpp" #include -#include #include -#include #include #include #include @@ -82,24 +81,48 @@ namespace quickbook main_grammar_local& l; }; - struct check_element_type { - check_element_type(main_grammar_local const& l, element_info::context t) - : l(l), t(t) {} + struct process_element_impl : scoped_action_base { + process_element_impl(main_grammar_local& l) + : l(l) {} - bool operator()() const { - return l.element_type & t; + bool start() + { + if (!(l.element_type & l.actions_.context)) + return false; + + // Save the element type because it might + // be overridden by nested markup. + element_type_ = l.element_type; + + if (element_type_ & element_info::block) + l.actions_.paragraph(); + + l.actions_.values.reset()(); + + return true; + } + + template + bool result(ResultT result, ScannerT const& scan) + { + if (result || !(l.element_type & element_info::block)) + return result; + + l.actions_.error(scan.first, scan.first); + return true; } - main_grammar_local const& l; - element_info::context t; + void success() { l.element_type = element_type_; } + void failure() { l.element_type = element_type_; } + + main_grammar_local& l; + element_info::type_enum element_type_; }; cl::rule top_level, blocks, paragraph_separator, - block_element, code, code_line, blank_line, hr, - list, ordered_list, list_item, - phrase_element, extended_phrase_element, element, + list, list_item, element, simple_phrase_end, escape, inline_code, simple_format, @@ -111,6 +134,7 @@ namespace quickbook template_inner_arg_1_4, brackets_1_4, template_args_1_5, template_arg_1_5, template_arg_1_5_content, template_inner_arg_1_5, brackets_1_5, + break_, command_line_macro_identifier, command_line_phrase, dummy_block ; @@ -118,21 +142,23 @@ namespace quickbook element_info::type_enum element_type; cl::rule element_rule; value::tag_type element_tag; - assign_element_type assign_element; - main_grammar_local() - : assign_element(*this) {} - - check_element_type check_element(element_info::context t) const { - return check_element_type(*this, t); - } + quickbook::actions& actions_; + assign_element_type assign_element; + scoped_parser process_element; + + main_grammar_local(quickbook::actions& actions) + : actions_(actions) + , assign_element(*this) + , process_element(*this) + {} }; void quickbook_grammar::impl::init_main() { using detail::var; - main_grammar_local& local = store_.create(); + main_grammar_local& local = store_.add(new main_grammar_local(actions)); block_skip_initial_spaces = *(cl::blank_p | comment) >> block_start @@ -142,15 +168,18 @@ namespace quickbook local.top_level >> blank ; - local.top_level - = local.blocks - >> *( - local.block_element >> !(+eol >> local.blocks) + local.top_level = + actions.scoped_context(element_info::in_block) + [ local.blocks + >> *( local.element + >> !(+eol >> local.blocks) | local.paragraph_separator >> local.blocks | common | cl::space_p [actions.space_char] | cl::anychar_p [actions.plain_char] - ); + ) + ] + ; local.blocks = *( local.code @@ -172,20 +201,20 @@ namespace quickbook >> +eol ; - local.block_element - = '[' >> space - >> local.element - >> cl::eps_p(local.check_element(element_info::in_block)) - [actions.paragraph] - [actions.values.reset()] - >> ( actions.values.list(detail::var(local.element_tag)) - [ local.element_rule - >> ( (space >> ']') - | cl::eps_p [actions.error] - ) - ] [actions.element] - | cl::eps_p [actions.error] + local.element + = '[' + >> ( cl::eps_p(cl::punct_p) + >> elements [local.assign_element] + | elements [local.assign_element] + >> (cl::eps_p - (cl::alnum_p | '_')) ) + >> local.process_element() + [ actions.values.list(detail::var(local.element_tag)) + [ local.element_rule + >> space + >> ']' + ] [actions.element] + ] ; local.code = @@ -233,13 +262,17 @@ namespace quickbook ; common = - local.macro - | local.phrase_element + actions.scoped_context(element_info::in_phrase) + [ local.macro + | local.element + | local.template_ + | local.break_ | local.code_block | local.inline_code | local.simple_format | local.escape | comment + ] ; local.macro = @@ -250,7 +283,8 @@ namespace quickbook ; local.template_ = - cl::eps_p [actions.values.reset()] + ( '[' + >> space [actions.values.reset()] >> !cl::str_p("`") [actions.values.entry(ph::arg1, ph::arg2, template_tags::escape)] >> ( ( @@ -265,8 +299,8 @@ namespace quickbook >> space >> !local.template_args ) ) - >> cl::eps_p(']') - >> cl::eps_p [actions.do_template] + >> ']' + ) [actions.do_template] ; local.template_args = @@ -315,6 +349,15 @@ namespace quickbook '[' >> local.template_inner_arg_1_5 >> ']' ; + local.break_ + = ( '[' + >> space + >> "br" + >> space + >> ']' + ) [actions.break_] + ; + local.inline_code = '`' >> ( @@ -365,18 +408,23 @@ namespace quickbook simple_markup(local.simple_teletype, '=', actions.simple_teletype, local.simple_phrase_end); - phrase = actions.values.save()[ - *( common - | (cl::anychar_p - phrase_end) [actions.plain_char] - ) + phrase = + actions.values.save() + [ *( common + | (cl::anychar_p - phrase_end) + [actions.plain_char] + ) ] ; - extended_phrase = actions.values.save()[ - *( local.extended_phrase_element - | common - | (cl::anychar_p - phrase_end) [actions.plain_char] - ) + extended_phrase = + actions.values.save() + [ *( actions.scoped_context(element_info::in_conditional) + [ local.element ] + | common + | (cl::anychar_p - phrase_end) + [actions.plain_char] + ) ] ; @@ -390,45 +438,6 @@ namespace quickbook ] [actions.paragraph] ; - local.phrase_element - = '[' - >> space - >> ( local.element - >> cl::eps_p(local.check_element(element_info::in_phrase)) - [actions.values.reset()] - >> actions.values.list(detail::var(local.element_tag)) - [ local.element_rule - >> cl::eps_p(space >> ']') - ] [actions.element] - | local.template_ - | cl::str_p("br") [actions.break_] - ) - >> ']' - ; - - local.extended_phrase_element - = '[' >> space - >> local.element - >> cl::eps_p(local.check_element(element_info::in_conditional)) - [actions.paragraph] - [actions.values.reset()] - >> ( actions.values.list(detail::var(local.element_tag)) - [ local.element_rule - >> ( (space >> ']') - | cl::eps_p [actions.error] - ) - ] [actions.element] - | cl::eps_p [actions.error] - ) - ; - - local.element - = cl::eps_p(cl::punct_p) - >> elements [local.assign_element] - | elements [local.assign_element] - >> (cl::eps_p - (cl::alnum_p | '_')) - ; - local.escape = cl::str_p("\\n") [actions.break_] | cl::str_p("\\ ") // ignore an escaped space diff --git a/src/parsers.hpp b/src/parsers.hpp index 88e6720..87935b1 100644 --- a/src/parsers.hpp +++ b/src/parsers.hpp @@ -65,24 +65,24 @@ namespace quickbook { typedef phoenix::tuple_index<0> t0; typedef phoenix::tuple_index<1> t1; - void start(phoenix::tuple<> const&) + bool start(phoenix::tuple<> const&) { - impl_.start(); - in_progress_ = true; + in_progress_ = impl_.start(); + return in_progress_; } template - void start(phoenix::tuple const& x) + bool start(phoenix::tuple const& x) { - impl_.start(x[t0()]); - in_progress_ = true; + in_progress_ = impl_.start(x[t0()]); + return in_progress_; } template - void start(phoenix::tuple const& x) + bool start(phoenix::tuple const& x) { - impl_.start(x[t0()], x[t1()]); - in_progress_ = true; + in_progress_ = impl_.start(x[t0()], x[t1()]); + return in_progress_; } void success() @@ -114,16 +114,22 @@ namespace quickbook { iterator_t save = scan.first; scoped scope(impl_); - scope.start(arguments_); + if (!scope.start(arguments_)) + return scan.no_match(); typename cl::parser_result::type result = this->subject().parse(scan); - //result = scope.match(result); + bool success = scope.impl_.result(result, scan); - if (result) { + if (success) { scope.success(); - return scan.create_match(result.length(), cl::nil_t(), save, scan.first); + if (result) { + return scan.create_match(result.length(), cl::nil_t(), save, scan.first); + } + else { + return scan.create_match(scan.first.base() - save.base(), cl::nil_t(), save, scan.first); + } } else { scope.failure(); diff --git a/src/rule_store.hpp b/src/rule_store.hpp index 514be1a..d9aa6c6 100644 --- a/src/rule_store.hpp +++ b/src/rule_store.hpp @@ -72,6 +72,16 @@ namespace quickbook instantiate i(*this); return i; } + + template + T& add(T* new_) + { + std::auto_ptr obj(new_); + store_.push_back(detail::scoped_void()); + store_.back().store(obj.release(), &detail::delete_impl); + + return *new_; + } std::deque store_; private: diff --git a/src/scoped.hpp b/src/scoped.hpp index 429f405..32df50f 100644 --- a/src/scoped.hpp +++ b/src/scoped.hpp @@ -15,10 +15,16 @@ namespace quickbook { struct scoped_action_base { - void start() {} + bool start() { return true; } void success() {} void failure() {} void cleanup() {} + + template + bool result(ResultT result, ScannerT const&) + { + return result; + } }; } diff --git a/src/values_parse.hpp b/src/values_parse.hpp index e1a351d..a4f8902 100644 --- a/src/values_parse.hpp +++ b/src/values_parse.hpp @@ -11,6 +11,7 @@ #include "values.hpp" #include "parsers.hpp" +#include "scoped.hpp" #include #include @@ -18,28 +19,33 @@ namespace quickbook { namespace ph = phoenix; - struct value_builder_save + struct value_builder_save : scoped_action_base { value_builder_save(value_builder& builder) : builder(builder) {} - void start() { builder.save(); } - void success() {} - void failure() {} + bool start() + { + builder.save(); + return true; + } + void cleanup() { builder.restore(); } value_builder& builder; }; - struct value_builder_list + struct value_builder_list : scoped_action_base { value_builder_list(value_builder& builder) : builder(builder) {} - void start(value::tag_type tag = value::default_tag) - { builder.start_list(tag); } + bool start(value::tag_type tag = value::default_tag) + { + builder.start_list(tag); + return true; + } void success() { builder.finish_list(); } void failure() { builder.clear_list(); } - void cleanup() {} value_builder& builder; }; From d245a879669f32021c217aaba152e6b5f91fc237 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 22 Feb 2011 21:28:49 +0000 Subject: [PATCH 04/24] More nestable elements. Refs #1193 [SVN r69189] --- src/block_element_grammar.cpp | 38 ++++++++++---------- src/grammar_impl.hpp | 9 +++-- src/main_grammar.cpp | 60 ++++++++++++++++++++++++++------ src/syntax_highlight.hpp | 27 ++++++++++----- test/table_1_5.gold | 65 +++++++++++++++++++++++++++++++++++ test/table_1_5.quickbook | 24 +++++++++++++ 6 files changed, 181 insertions(+), 42 deletions(-) diff --git a/src/block_element_grammar.cpp b/src/block_element_grammar.cpp index 1133f9c..5b31726 100644 --- a/src/block_element_grammar.cpp +++ b/src/block_element_grammar.cpp @@ -88,27 +88,27 @@ namespace quickbook ; elements.add - ("heading", element_info(element_info::block, &local.heading, block_tags::generic_heading)) - ("h1", element_info(element_info::block, &local.heading, block_tags::heading1)) - ("h2", element_info(element_info::block, &local.heading, block_tags::heading2)) - ("h3", element_info(element_info::block, &local.heading, block_tags::heading3)) - ("h4", element_info(element_info::block, &local.heading, block_tags::heading4)) - ("h5", element_info(element_info::block, &local.heading, block_tags::heading5)) - ("h6", element_info(element_info::block, &local.heading, block_tags::heading6)) + ("heading", element_info(element_info::conditional_or_block, &local.heading, block_tags::generic_heading)) + ("h1", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading1)) + ("h2", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading2)) + ("h3", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading3)) + ("h4", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading4)) + ("h5", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading5)) + ("h6", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading6)) ; elements.add - ("blurb", element_info(element_info::block, &local.inner_block, block_tags::blurb)) - (":", element_info(element_info::block, &local.inner_block, block_tags::blockquote)) - ("warning", element_info(element_info::block, &local.inner_block, block_tags::warning)) - ("caution", element_info(element_info::block, &local.inner_block, block_tags::caution)) - ("important", element_info(element_info::block, &local.inner_block, block_tags::important)) - ("note", element_info(element_info::block, &local.inner_block, block_tags::note)) - ("tip", element_info(element_info::block, &local.inner_block, block_tags::tip)) + ("blurb", element_info(element_info::nested_block, &local.inner_block, block_tags::blurb)) + (":", element_info(element_info::nested_block, &local.inner_block, block_tags::blockquote)) + ("warning", element_info(element_info::nested_block, &local.inner_block, block_tags::warning)) + ("caution", element_info(element_info::nested_block, &local.inner_block, block_tags::caution)) + ("important", element_info(element_info::nested_block, &local.inner_block, block_tags::important)) + ("note", element_info(element_info::nested_block, &local.inner_block, block_tags::note)) + ("tip", element_info(element_info::nested_block, &local.inner_block, block_tags::tip)) ; elements.add - ("pre", element_info(element_info::block, &local.preformatted, block_tags::preformatted)) + ("pre", element_info(element_info::nested_block, &local.preformatted, block_tags::preformatted)) ; local.preformatted = @@ -120,7 +120,7 @@ namespace quickbook ; elements.add - ("def", element_info(element_info::block, &local.def_macro, block_tags::macro_definition)) + ("def", element_info(element_info::conditional_or_block, &local.def_macro, block_tags::macro_definition)) ; local.def_macro = @@ -139,7 +139,7 @@ namespace quickbook ; elements.add - ("template", element_info(element_info::block, &local.template_, block_tags::template_definition)) + ("template", element_info(element_info::conditional_or_block, &local.template_, block_tags::template_definition)) ; local.template_ = @@ -168,7 +168,7 @@ namespace quickbook ; elements.add - ("variablelist", element_info(element_info::block, &local.variablelist, block_tags::variable_list)) + ("variablelist", element_info(element_info::nested_block, &local.variablelist, block_tags::variable_list)) ; local.variablelist = @@ -206,7 +206,7 @@ namespace quickbook ; elements.add - ("table", element_info(element_info::block, &local.table, block_tags::table)) + ("table", element_info(element_info::nested_block, &local.table, block_tags::table)) ; local.table = diff --git a/src/grammar_impl.hpp b/src/grammar_impl.hpp index 881a645..ab1b20d 100644 --- a/src/grammar_impl.hpp +++ b/src/grammar_impl.hpp @@ -26,12 +26,15 @@ namespace quickbook in_block = 1, in_phrase = 2, in_conditional = 4, + in_nested_block = 8 }; enum type_enum { - block = 1, - phrase = 2, - conditional_or_block = 5 + nothing = 0, + block = in_block, + conditional_or_block = block | in_conditional, + nested_block = conditional_or_block | in_nested_block, + phrase = nested_block | in_phrase }; element_info( diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 4a858a1..7bd937a 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -94,7 +94,7 @@ namespace quickbook // be overridden by nested markup. element_type_ = l.element_type; - if (element_type_ & element_info::block) + if (!(element_type_ & element_info::in_phrase)) l.actions_.paragraph(); l.actions_.values.reset()(); @@ -105,7 +105,7 @@ namespace quickbook template bool result(ResultT result, ScannerT const& scan) { - if (result || !(l.element_type & element_info::block)) + if (result || l.element_type & element_info::in_phrase) return result; l.actions_.error(scan.first, scan.first); @@ -113,11 +113,29 @@ namespace quickbook } void success() { l.element_type = element_type_; } - void failure() { l.element_type = element_type_; } + void failure() { l.element_type = element_info::nothing; } main_grammar_local& l; element_info::type_enum element_type_; }; + + struct is_block_type + { + typedef bool result_type; + template + struct result { typedef bool type; }; + + is_block_type(main_grammar_local& l) + : l_(l) + {} + + bool operator()() const + { + return !(l_.element_type & element_info::in_phrase); + } + + main_grammar_local& l_; + }; cl::rule top_level, blocks, paragraph_separator, @@ -146,11 +164,13 @@ namespace quickbook quickbook::actions& actions_; assign_element_type assign_element; scoped_parser process_element; + is_block_type is_block; main_grammar_local(quickbook::actions& actions) : actions_(actions) , assign_element(*this) , process_element(*this) + , is_block(*this) {} }; @@ -172,7 +192,9 @@ namespace quickbook actions.scoped_context(element_info::in_block) [ local.blocks >> *( local.element - >> !(+eol >> local.blocks) + >> cl::if_p(local.is_block) + [ !(+eol >> local.blocks) + ] | local.paragraph_separator >> local.blocks | common | cl::space_p [actions.space_char] @@ -248,6 +270,8 @@ namespace quickbook ; local.list_item = + actions.scoped_context(element_info::in_phrase) + [ actions.values.save() [ *( common @@ -258,12 +282,12 @@ namespace quickbook ) [actions.plain_char] ) ] + ] >> +eol ; common = - actions.scoped_context(element_info::in_phrase) - [ local.macro + local.macro | local.element | local.template_ | local.break_ @@ -272,7 +296,6 @@ namespace quickbook | local.simple_format | local.escape | comment - ] ; local.macro = @@ -409,26 +432,32 @@ namespace quickbook '=', actions.simple_teletype, local.simple_phrase_end); phrase = + actions.scoped_context(element_info::in_phrase) + [ actions.values.save() [ *( common | (cl::anychar_p - phrase_end) [actions.plain_char] ) ] + ] ; extended_phrase = + actions.scoped_context(element_info::in_conditional) + [ actions.values.save() - [ *( actions.scoped_context(element_info::in_conditional) - [ local.element ] - | common + [ *( common | (cl::anychar_p - phrase_end) [actions.plain_char] ) ] + ] ; inside_paragraph = + actions.scoped_context(element_info::in_nested_block) + [ actions.values.save() [ *( local.paragraph_separator [actions.paragraph] | common @@ -436,6 +465,7 @@ namespace quickbook [actions.plain_char] ) ] [actions.paragraph] + ] ; local.escape = @@ -457,11 +487,16 @@ namespace quickbook // Simple phrase grammar // - simple_phrase = actions.values.save()[ + simple_phrase = + actions.scoped_context(element_info::in_phrase) + [ + actions.values.save() + [ *( common | (cl::anychar_p - ']') [actions.plain_char] ) ] + ] ; // @@ -489,11 +524,14 @@ namespace quickbook local.command_line_phrase = + actions.scoped_context(element_info::in_phrase) + [ actions.values.save() [ *( common | (cl::anychar_p - ']') [actions.plain_char] ) ] + ] ; // Miscellaneous stuff diff --git a/src/syntax_highlight.hpp b/src/syntax_highlight.hpp index 264f886..3a16c99 100644 --- a/src/syntax_highlight.hpp +++ b/src/syntax_highlight.hpp @@ -16,6 +16,7 @@ #include #include #include "grammar.hpp" +#include "grammar_impl.hpp" // Just for context stuff. Should move? namespace quickbook { @@ -69,10 +70,12 @@ namespace quickbook ; qbk_phrase = - *( g.common - | (cl::anychar_p - cl::str_p("``")) + self.escape_actions.scoped_context(element_info::in_phrase) + [ *( g.common + | (cl::anychar_p - cl::str_p("``")) [self.escape_actions.plain_char] - ) + ) + ] ; escape = @@ -218,10 +221,13 @@ namespace quickbook ; qbk_phrase = - *( g.common - | (cl::anychar_p - cl::str_p("``")) + self.escape_actions.scoped_context(element_info::in_phrase) + [ + *( g.common + | (cl::anychar_p - cl::str_p("``")) [self.escape_actions.plain_char] - ) + ) + ] ; escape = @@ -362,10 +368,13 @@ namespace quickbook ; qbk_phrase = - *( g.common - | (cl::anychar_p - cl::str_p("``")) + self.escape_actions.scoped_context(element_info::in_phrase) + [ + *( g.common + | (cl::anychar_p - cl::str_p("``")) [self.escape_actions.plain_char] - ) + ) + ] ; escape = diff --git a/test/table_1_5.gold b/test/table_1_5.gold index e874f4f..942ff4b 100644 --- a/test/table_1_5.gold +++ b/test/table_1_5.gold @@ -233,5 +233,70 @@ + + Nested Tables + + + + + + Header 1 + + + + + Header 2 + + + + + + + +
+ Inner Table + + + + + + 1.1 + + + + + 1.2 + + + + + + + + + 2.1 + + + + + 2.2 + + + + + +
+ + + + + + Something. + + + + + + diff --git a/test/table_1_5.quickbook b/test/table_1_5.quickbook index 867a6bb..c59f8cc 100644 --- a/test/table_1_5.quickbook +++ b/test/table_1_5.quickbook @@ -69,4 +69,28 @@ ] ] +[table Nested Tables + [ + [ + Header 1 + ] + [ + Header 2 + ] + ] + [ + [ + [table Inner Table + [[1.1][1.2]] + [[2.1][2.2]] + ] + ] + ] + [ + [ + Something. + ] + ] +] + [endsect] \ No newline at end of file From a86f19d7bfcb725e8ac780a78a4511b3e52ef4f7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 25 Feb 2011 23:05:36 +0000 Subject: [PATCH 05/24] Invalid list markup again. [SVN r69287] --- src/actions.cpp | 13 +- test/list_test.gold | 236 ++++++++++++++++++------------------- test/quickbook-manual.gold | 226 +++++++++++++++++------------------ 3 files changed, 236 insertions(+), 239 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 0c97aa8..7960afb 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -402,15 +402,14 @@ namespace quickbook { char mark = list_marks.top().first; list_marks.pop(); - actions.out << ""; + actions.out << ""; actions.out << ((mark == '#') ? "\n" : "\n"); } - - actions.out << ""; + actions.out << ""; } else { - actions.out << ""; + actions.out << ""; } if (mark != list_marks.top().first) // new_indent == list_indent @@ -423,10 +422,8 @@ namespace quickbook ++actions.error_count; } - actions.out << ""; - actions.out << "\n"; + actions.out << ""; actions.out << content; - actions.out << "\n"; } assert(!list_marks.empty()); @@ -434,7 +431,7 @@ namespace quickbook { char mark = list_marks.top().first; list_marks.pop(); - actions.out << ""; + actions.out << ""; actions.out << ((mark == '#') ? "\n" : "\n"); } } diff --git a/test/list_test.gold b/test/list_test.gold index 71d6881..2ac1fae 100644 --- a/test/list_test.gold +++ b/test/list_test.gold @@ -39,36 +39,36 @@ A + + + + A + + + + + B + + + - - - - A - - - - - B - - - B + + + + A + + + + + B + + + - - - - A - - - - - B - - - @@ -78,36 +78,36 @@ A + + + + A + + + + + B + + + - - - - A - - - - - B - - - B + + + + A + + + + + B + + + - - - - A - - - - - B - - - @@ -117,53 +117,53 @@ A + + + + A + + + + + B + + + + C + + + + + D + + + + + + + + E + + + + + F + + + + G + + + + + H + + + + + + - - - - A - - - - - B - - - - - C - - - - - D - - - - - - - E - - - - - F - - - - - G - - - - - H - - - - - @@ -173,31 +173,31 @@ A + + + + A + + + + + B + + + + C + + + + + D + + + + + + - - - - A - - - - - B - - - - - C - - - - - D - - - - - diff --git a/test/quickbook-manual.gold b/test/quickbook-manual.gold index 70a4afe..3b3924f 100644 --- a/test/quickbook-manual.gold +++ b/test/quickbook-manual.gold @@ -1272,48 +1272,48 @@ escape (no processing/formatting) Three + + + + Three.a + + + + + Three.b + + + + + Three.c + + + - - - - Three.a - - - - - Three.b - - - - - Three.c - - - Fourth + + + + Four.a + + + + Four.a.i + + + + + Four.a.ii + + + + + + - - - - Four.a - - - - - Four.a.i - - - - - Four.a.ii - - - - - @@ -1418,24 +1418,24 @@ escape (no processing/formatting) Three + + + + Three.a + + + + + Three.b + + + + + Three.c + + + - - - - Three.a - - - - - Three.b - - - - - Three.c - - - @@ -1467,72 +1467,72 @@ escape (no processing/formatting) 1 + + + + 1.a + + + + 1.a.1 + + + + + 1.a.2 + + + + + + + + 1.b + + + - - - - 1.a - - - - - 1.a.1 - - - - - 1.a.2 - - - - - - - 1.b - - - 2 + + + + 2.a + + + + + 2.b + + + + 2.b.1 + + + + + 2.b.2 + + + + 2.b.2.a + + + + + 2.b.2.b + + + + + + + + + - - - - 2.a - - - - - 2.b - - - - - 2.b.1 - - - - - 2.b.2 - - - - - 2.b.2.a - - - - - 2.b.2.b - - - - - - - From e4ddb668deacc88dbbc5e5fae234f6e48e0f02cf Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 25 Feb 2011 23:06:16 +0000 Subject: [PATCH 06/24] Clean up the value consumer interface. [SVN r69288] --- src/actions.cpp | 48 +++++++++++++++++----------------- src/doc_info_actions.cpp | 55 +++++++++++++++++++-------------------- src/values.cpp | 40 ++++++++++++++-------------- src/values.hpp | 21 +++++++++------ test/unit/values_test.cpp | 30 ++++++++++----------- 5 files changed, 98 insertions(+), 96 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 7960afb..2d37232 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -71,9 +71,9 @@ namespace quickbook void element_action::operator()(iterator first, iterator) const { value_consumer values = actions.values.get(); - if(!values.is()) return; + if(!values.check()) return; value v = values.consume(); - if(values.is()) return; + if(values.check()) return; switch(v.get_tag()) { @@ -203,7 +203,7 @@ namespace quickbook value_consumer values = block; actions.out << markup.pre << values.consume().get_boostbook() << markup.post; - assert(!values.is()); + values.finish(); } void phrase_action_(quickbook::actions& actions, value phrase) @@ -213,7 +213,7 @@ namespace quickbook value_consumer values = phrase; actions.phrase << markup.pre << values.consume().get_boostbook() << markup.post; - assert(!values.is()); + values.finish(); } void paragraph_action::operator()() const @@ -260,7 +260,7 @@ namespace quickbook bool generic = heading_list.get_tag() == block_tags::generic_heading; value element_id = values.optional_consume(general_tags::element_id); value content = values.consume(); - assert(!values.is()); + values.finish(); int level; @@ -289,7 +289,7 @@ namespace quickbook else { std::string id = - !element_id.is_empty() ? + !element_id.empty() ? element_id.get_quickbook() : detail::make_identifier( qbk_version_n >= 106 ? @@ -377,7 +377,7 @@ namespace quickbook values.consume(general_tags::list_indent).get_quickbook()); value mark_value = values.consume(general_tags::list_mark); std::string content = values.consume().get_boostbook(); - assert(!values.is()); + values.finish(); char mark = mark_value.get_quickbook()[0]; assert(mark == '*' || mark == '#'); @@ -468,7 +468,7 @@ namespace quickbook value_consumer values = anchor; actions.anchors.push_back(values.consume().get_quickbook()); - assert(!values.is()); + values.finish(); } void do_macro_action::operator()(std::string const& str) const @@ -630,7 +630,7 @@ namespace quickbook value_consumer pair = pair_; value name = pair.consume(); value value = pair.consume(); - assert(!pair.is()); + pair.finish(); if(!attributes.insert(std::make_pair(name.get_quickbook(), value)).second) { detail::outwarn(actions.filename, name.get_position().line) @@ -786,7 +786,7 @@ namespace quickbook value_consumer values = macro_definition; std::string macro_id = values.consume().get_quickbook(); std::string phrase = values.consume().get_boostbook(); - assert(!values.is()); + values.finish(); actions.copy_macros_for_write(); actions.macro.add( @@ -807,9 +807,9 @@ namespace quickbook template_values.push_back(p.get_quickbook()); } - BOOST_ASSERT(values.is(template_tags::block) || values.is(template_tags::phrase)); + BOOST_ASSERT(values.check(template_tags::block) || values.check(template_tags::phrase)); value body = values.consume(); - BOOST_ASSERT(!values.is()); + BOOST_ASSERT(!values.check()); if (!actions.templates.add( template_symbol( @@ -1035,7 +1035,7 @@ namespace quickbook // Get the arguments value_consumer values = actions.values.get(); - bool template_escape = values.is(template_tags::escape); + bool template_escape = values.check(template_tags::escape); if(template_escape) values.consume(); std::string identifier = values.consume(template_tags::identifier).get_quickbook(); @@ -1244,13 +1244,13 @@ namespace quickbook value_consumer values = link; value dst = values.consume(); value content = values.consume(); - assert(!values.is()); + values.finish(); actions.phrase << markup.pre; detail::print_string(dst.get_quickbook(), actions.phrase.get()); actions.phrase << "\">"; - if (content.is_empty()) + if (content.empty()) detail::print_string(dst.get_quickbook(), actions.phrase.get()); else actions.phrase << content.get_boostbook(); @@ -1274,13 +1274,13 @@ namespace quickbook BOOST_FOREACH(value_consumer entry, values) { actions.out << start_varlistentry_; - if(entry.is()) { + if(entry.check()) { actions.out << start_varlistterm_; actions.out << entry.consume().get_boostbook(); actions.out << end_varlistterm_; } - if(entry.is()) { + if(entry.check()) { actions.out << start_varlistitem_; BOOST_FOREACH(value phrase, entry) actions.out << phrase.get_boostbook(); actions.out << end_varlistitem_; @@ -1299,7 +1299,7 @@ namespace quickbook value_consumer values = table; std::string element_id; - if(values.is(general_tags::element_id)) + if(values.check(general_tags::element_id)) element_id = values.consume().get_quickbook(); std::string title = values.consume(table_tags::title).get_quickbook(); @@ -1388,9 +1388,9 @@ namespace quickbook value element_id = values.optional_consume(general_tags::element_id); value content = values.consume(); - assert(!values.is()); + values.finish(); - actions.section_id = !element_id.is_empty() ? + actions.section_id = !element_id.empty() ? element_id.get_quickbook() : detail::make_identifier(content.get_quickbook()); @@ -1527,7 +1527,7 @@ namespace quickbook value_consumer values = xinclude; fs::path path = calculate_relative_path( check_path(values.consume(), actions), actions); - assert(!values.is()); + values.finish(); actions.out << "\n storage; @@ -1599,7 +1599,7 @@ namespace quickbook value include_doc_id = values.optional_consume(general_tags::include_id); fs::path filein = include_search(actions.filename.parent_path(), check_path(values.consume(), actions)); - assert(!values.is()); + values.finish(); std::string doc_type, doc_id; @@ -1630,7 +1630,7 @@ namespace quickbook // if an id is specified in this include (as in [include:id foo.qbk]) // then use it as the doc_id. - if (!include_doc_id.is_empty()) + if (!include_doc_id.empty()) actions.doc_id = include_doc_id.get_quickbook(); // update the __FILENAME__ macro diff --git a/src/doc_info_actions.cpp b/src/doc_info_actions.cpp index 8c502bb..298ff08 100644 --- a/src/doc_info_actions.cpp +++ b/src/doc_info_actions.cpp @@ -33,7 +33,7 @@ namespace quickbook value p; int count = 0; - while(c.is(tag)) { + while(c.check(tag)) { p = c.consume(); ++count; } @@ -47,12 +47,12 @@ namespace quickbook std::vector* duplicates) { value l = consume_last(c, tag, duplicates); - if(l.is_empty()) return l; + if(l.empty()) return l; assert(l.is_list()); value_consumer c2 = l; value p = c2.consume(); - assert(!c2.is()); + c2.finish(); return p; } @@ -61,7 +61,7 @@ namespace quickbook { std::vector values; - while(c.is(tag)) { + while(c.check(tag)) { values.push_back(c.consume()); } @@ -77,12 +77,12 @@ namespace quickbook // Skip over invalid attributes - while (values.is(value::default_tag)) values.consume(); + while (values.check(value::default_tag)) values.consume(); std::vector duplicates; value doc_title; - if (values.is()) + if (values.check()) { actions.doc_type = values.consume(doc_info_tags::type).get_quickbook(); doc_title = values.consume(doc_info_tags::title); @@ -103,10 +103,9 @@ namespace quickbook // Skip over source-mode tags (already dealt with) - while (values.is(doc_info_attributes::source_mode)) values.consume(); + while (values.check(doc_info_attributes::source_mode)) values.consume(); - - BOOST_ASSERT(!values.is()); + values.finish(); if(!duplicates.empty()) { @@ -118,14 +117,14 @@ namespace quickbook ; } - if (!id.is_empty()) + if (!id.empty()) actions.doc_id = id.get_quickbook(); if (actions.doc_id.empty()) actions.doc_id = detail::make_identifier(actions.doc_title_qbk); - if (dirname.is_empty() && actions.doc_type == "library") { - if (!id.is_empty()) { + if (dirname.empty() && actions.doc_type == "library") { + if (!id.empty()) { dirname = id; } else { @@ -133,7 +132,7 @@ namespace quickbook } } - if (last_revision.is_empty()) + if (last_revision.empty()) { // default value for last-revision is now @@ -195,13 +194,13 @@ namespace quickbook { std::vector invalid_attributes; - if (!purpose.is_empty()) + if (!purpose.empty()) invalid_attributes.push_back("purpose"); if (!categories.empty()) invalid_attributes.push_back("category"); - if (!dirname.is_empty()) + if (!dirname.empty()) invalid_attributes.push_back("dirname"); if(!invalid_attributes.empty()) @@ -228,7 +227,7 @@ namespace quickbook << actions.doc_id << "\"\n"; - if(!lang.is_empty()) + if(!lang.empty()) { out << " lang=\"" << doc_info_output(lang, 106) @@ -240,7 +239,7 @@ namespace quickbook out << " name=\"" << doc_info_output(doc_title, 106) << "\"\n"; } - if(!dirname.is_empty()) + if(!dirname.empty()) { out << " dirname=\"" << doc_info_output(dirname, 106) @@ -259,7 +258,7 @@ namespace quickbook tmp << " \n"; BOOST_FOREACH(value_consumer author_values, authors) { - while (author_values.is()) { + while (author_values.check()) { value surname = author_values.consume(doc_info_tags::author_surname); value first = author_values.consume(doc_info_tags::author_first); @@ -278,16 +277,16 @@ namespace quickbook BOOST_FOREACH(value_consumer copyright, copyrights) { - while(copyright.is()) + while(copyright.check()) { tmp << "\n" << " \n"; - while(copyright.is(doc_info_tags::copyright_year)) + while(copyright.check(doc_info_tags::copyright_year)) { int year_start = boost::lexical_cast(copyright.consume().get_quickbook()); int year_end = - copyright.is(doc_info_tags::copyright_year_end) ? + copyright.check(doc_info_tags::copyright_year_end) ? boost::lexical_cast(copyright.consume().get_quickbook()) : year_start; @@ -317,7 +316,7 @@ namespace quickbook } } - if (!license.is_empty()) + if (!license.empty()) { tmp << " \n" << " \n" @@ -328,7 +327,7 @@ namespace quickbook ; } - if (!purpose.is_empty()) + if (!purpose.empty()) { tmp << " <" << actions.doc_type << "purpose>\n" << " " << doc_info_output(purpose, 103) @@ -339,14 +338,14 @@ namespace quickbook BOOST_FOREACH(value_consumer values, categories) { value category = values.optional_consume(); - if(!category.is_empty()) { + if(!category.empty()) { tmp << " <" << actions.doc_type << "category name=\"category:" << doc_info_output(category, 106) << "\">\n" << "\n" ; } - assert(!values.is()); + values.finish(); } BOOST_FOREACH(value_consumer biblioid, biblioids) @@ -361,7 +360,7 @@ namespace quickbook << "" << "\n" ; - assert(!biblioid.is()); + biblioid.finish(); } if(actions.doc_type != "library") { @@ -398,11 +397,11 @@ namespace quickbook static void write_document_title(collector& out, value const& title, value const& version) { - if (!title.is_empty()) + if (!title.empty()) { out << " " << doc_info_output(title, 106); - if (!version.is_empty()) { + if (!version.empty()) { out << ' ' << doc_info_output(version, 106); } out<< "\n\n\n"; diff --git a/src/values.cpp b/src/values.cpp index 8e266aa..b3d5c6a 100644 --- a/src/values.cpp +++ b/src/values.cpp @@ -30,7 +30,7 @@ namespace quickbook std::string value_node::get_boostbook() const { assert(false); } value_node* value_node::get_list() const { assert(false); } - bool value_node::is_empty() const { return false; } + bool value_node::empty() const { return false; } bool value_node::is_list() const { return false; } bool value_node::is_string() const { return false; } } @@ -55,7 +55,7 @@ namespace quickbook virtual value_node* clone() const { return new value_empty_impl(tag_); } - virtual bool is_empty() const + virtual bool empty() const { return true; } friend value quickbook::empty_value(value::tag_type); @@ -192,7 +192,7 @@ namespace quickbook virtual value_node* clone() const; virtual std::string get_boostbook() const; virtual bool is_string() const; - virtual bool is_empty() const; + virtual bool empty() const; std::string value_; }; @@ -211,7 +211,7 @@ namespace quickbook virtual file_position get_position() const; virtual std::string get_quickbook() const; virtual bool is_string() const; - virtual bool is_empty() const; + virtual bool empty() const; std::string value_; file_position position_; @@ -228,7 +228,7 @@ namespace quickbook virtual file_position get_position() const; virtual std::string get_quickbook() const; virtual bool is_string() const; - virtual bool is_empty() const; + virtual bool empty() const; quickbook::iterator begin_; quickbook::iterator end_; @@ -251,7 +251,7 @@ namespace quickbook virtual std::string get_quickbook() const; virtual std::string get_boostbook() const; virtual bool is_string() const; - virtual bool is_empty() const; + virtual bool empty() const; std::string qbk_value_; std::string bbk_value_; @@ -289,7 +289,7 @@ namespace quickbook bool value_string_impl::is_string() const { return true; } - bool value_string_impl::is_empty() const + bool value_string_impl::empty() const { return value_.empty(); } // value_qbk_string_impl @@ -328,7 +328,7 @@ namespace quickbook bool value_qbk_string_impl::is_string() const { return true; } - bool value_qbk_string_impl::is_empty() const + bool value_qbk_string_impl::empty() const { return value_.empty(); } // value_qbk_ref_impl @@ -363,7 +363,7 @@ namespace quickbook bool value_qbk_ref_impl::is_string() const { return true; } - bool value_qbk_ref_impl::is_empty() const + bool value_qbk_ref_impl::empty() const { return begin_ == end_; } // value_qbk_bbk_impl @@ -427,7 +427,7 @@ namespace quickbook { return true; } // Should this test the quickbook, the boostbook or both? - bool value_qbk_bbk_impl::is_empty() const + bool value_qbk_bbk_impl::empty() const { return bbk_value_.empty(); } } @@ -469,9 +469,8 @@ namespace quickbook void list_unref(value_node*); value_node** merge_sort(value_node**); value_node** merge_sort(value_node**, int); - value_node** merge_adjacent_ranges( - value_node**, value_node**, value_node**); - void swap_adjacent_ranges(value_node**, value_node**, value_node**); + value_node** merge(value_node**, value_node**, value_node**); + void rotate(value_node**, value_node**, value_node**); value_node** list_ref_back(value_node** back) { @@ -515,12 +514,12 @@ namespace quickbook count < recurse_limit && *p != &value_nil_impl::instance; ++count) { - p = merge_adjacent_ranges(l, p, merge_sort(p, count)); + p = merge(l, p, merge_sort(p, count)); } return p; } - value_node** merge_adjacent_ranges( + value_node** merge( value_node** first, value_node** second, value_node** third) { for(;;) { @@ -530,7 +529,7 @@ namespace quickbook first = &(*first)->next_; } - swap_adjacent_ranges(first, second, third); + rotate(first, second, third); first = &(*first)->next_; // Since the two ranges were just swapped, the order is now: @@ -546,13 +545,12 @@ namespace quickbook first = &(*first)->next_; } - swap_adjacent_ranges(first, third, second); + rotate(first, third, second); first = &(*first)->next_; } } - void swap_adjacent_ranges( - value_node** first, value_node** second, value_node** third) + void rotate(value_node** first, value_node** second, value_node** third) { value_node* tmp = *first; *first = *second; @@ -576,7 +574,7 @@ namespace quickbook virtual ~value_list_impl(); virtual value_node* clone() const; virtual value_node* store(); - virtual bool is_empty() const; + virtual bool empty() const; virtual bool is_list() const; virtual value_node* get_list() const; @@ -634,7 +632,7 @@ namespace quickbook } - bool value_list_impl::is_empty() const + bool value_list_impl::empty() const { return head_ == &value_nil_impl::instance; } diff --git a/src/values.hpp b/src/values.hpp index a1ba34b..ac0bc70 100644 --- a/src/values.hpp +++ b/src/values.hpp @@ -48,7 +48,7 @@ namespace quickbook virtual std::string get_quickbook() const; virtual std::string get_boostbook() const; - virtual bool is_empty() const; + virtual bool empty() const; virtual bool is_list() const; virtual bool is_string() const; @@ -91,7 +91,7 @@ namespace quickbook public: void swap(value_base& x) { std::swap(value_, x.value_); } - bool is_empty() const { return value_->is_empty(); } + bool empty() const { return value_->empty(); } bool is_list() const { return value_->is_list(); } bool is_string() const { return value_->is_string(); } @@ -281,19 +281,19 @@ namespace quickbook reference consume() { - assert(is()); + assert(check()); return *pos_++; } reference consume(value::tag_type t) { - assert(is(t)); + assert(check(t)); return *pos_++; } value optional_consume() { - if(is()) { + if(check()) { return *pos_++; } else { @@ -303,7 +303,7 @@ namespace quickbook value optional_consume(value::tag_type t) { - if(is(t)) { + if(check(t)) { return *pos_++; } else { @@ -311,15 +311,20 @@ namespace quickbook } } - bool is() + bool check() const { return pos_ != end_; } - bool is(value::tag_type t) + bool check(value::tag_type t) const { return pos_ != end_ && t == pos_->get_tag(); } + + void finish() const + { + assert(pos_ == end_); + } iterator begin() const { return pos_; } iterator end() const { return end_; } diff --git a/test/unit/values_test.cpp b/test/unit/values_test.cpp index 429ae6b..23e7194 100644 --- a/test/unit/values_test.cpp +++ b/test/unit/values_test.cpp @@ -16,7 +16,7 @@ void empty_tests() { quickbook::value q; - BOOST_TEST(q.is_empty()); + BOOST_TEST(q.empty()); BOOST_TEST(!q.is_list()); BOOST_TEST(!q.is_string()); } @@ -40,11 +40,11 @@ void sort_test() b.sort_list(); quickbook::value_consumer c = b.get(); - BOOST_TEST(c.is(2)); BOOST_TEST_EQ(c.consume(2).get_boostbook(), "b"); - BOOST_TEST(c.is(5)); c.consume(5); - BOOST_TEST(c.is(8)); c.consume(8); - BOOST_TEST(c.is(10)); c.consume(10); - BOOST_TEST(!c.is()); + BOOST_TEST(c.check(2)); BOOST_TEST_EQ(c.consume(2).get_boostbook(), "b"); + BOOST_TEST(c.check(5)); c.consume(5); + BOOST_TEST(c.check(8)); c.consume(8); + BOOST_TEST(c.check(10)); c.consume(10); + BOOST_TEST(!c.check()); } void multiple_list_test() @@ -65,17 +65,17 @@ void multiple_list_test() quickbook::value_consumer l1 = list1.get(); list1.reset(); quickbook::value_consumer l2 = list2.get(); list2.reset(); - BOOST_TEST(l1.is(10)); + BOOST_TEST(l1.check(10)); BOOST_TEST_EQ(l1.consume(10).get_boostbook(), "b"); - BOOST_TEST(l1.is(5)); + BOOST_TEST(l1.check(5)); BOOST_TEST_EQ(l1.consume(5).get_boostbook(), "a"); - BOOST_TEST(!l1.is()); + BOOST_TEST(!l1.check()); - BOOST_TEST(l2.is(5)); + BOOST_TEST(l2.check(5)); BOOST_TEST_EQ(l2.consume(5).get_boostbook(), "a"); - BOOST_TEST(l2.is(3)); + BOOST_TEST(l2.check(3)); BOOST_TEST_EQ(l2.consume(3).get_boostbook(), "c"); - BOOST_TEST(!l2.is()); + BOOST_TEST(!l2.check()); } void store_test1() @@ -100,11 +100,11 @@ void store_test1() void store_test2_check(quickbook::value const& q) { quickbook::value_consumer l1 = q; - BOOST_TEST(l1.is(5)); + BOOST_TEST(l1.check(5)); BOOST_TEST_EQ(l1.consume(5).get_quickbook(), "Hello"); - BOOST_TEST(l1.is(10)); + BOOST_TEST(l1.check(10)); BOOST_TEST_EQ(l1.consume(10).get_boostbook(), "World"); - BOOST_TEST(!l1.is()); + BOOST_TEST(!l1.check()); } void store_test2() From 937e30aa53988184e2af2021bb39fe29484c5c7a Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 25 Feb 2011 23:06:41 +0000 Subject: [PATCH 07/24] Consume values when iterating over a consumer. [SVN r69289] --- src/actions.cpp | 12 +++++++++++- src/values.hpp | 33 +++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 2d37232..bec07ac 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -637,6 +637,8 @@ namespace quickbook << "Duplicate image attribute: " << name.get_quickbook() << std::endl; } } + + values.finish(); // Find the file basename and extension. // @@ -1056,6 +1058,8 @@ namespace quickbook arg.get_tag() == template_tags::block )); } + + values.finish(); ++actions.template_depth; if (actions.template_depth > actions.max_template_depth) @@ -1290,6 +1294,8 @@ namespace quickbook } actions.out << "\n"; + + values.finish(); } void table_action(quickbook::actions& actions, value table) @@ -1323,10 +1329,12 @@ namespace quickbook int row_count = 0; int span_count = 0; - BOOST_FOREACH(value row, values) { + value_consumer lookahead = values; + BOOST_FOREACH(value row, lookahead) { ++row_count; span_count = boost::distance(row); } + lookahead.finish(); if (has_title) { @@ -1366,6 +1374,8 @@ namespace quickbook } actions.out << end_row_; } + + values.finish(); actions.out << "\n" << "\n"; diff --git a/src/values.hpp b/src/values.hpp index ac0bc70..ab1a5ab 100644 --- a/src/values.hpp +++ b/src/values.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "fwd.hpp" namespace quickbook @@ -129,6 +130,7 @@ namespace quickbook public: explicit value_proxy(value_node* base) : value_base(base) {} value_proxy* operator->() { return this; } + value_ref operator*() const { return value_ref(value_); } }; //////////////////////////////////////////////////////////////////////// @@ -263,8 +265,27 @@ namespace quickbook class value_consumer { public: - typedef value::iterator iterator; - typedef value::iterator const_iterator; + class iterator + : public boost::input_iterator_helper::type, + boost::iterator_difference::type, + boost::iterator_pointer::type, + boost::iterator_reference::type> + { + public: + iterator(); + explicit iterator(value::iterator* p) : ptr_(p) {} + friend bool operator==(iterator x, iterator y) + { return *x.ptr_ == *y.ptr_; } + iterator& operator++() { ++*ptr_; return *this; } + reference operator*() const { return **ptr_; } + pointer operator->() const { return ptr_->operator->(); } + private: + value::iterator* ptr_; + }; + + + typedef iterator const_iterator; typedef iterator::reference reference; value_consumer(value const& x) @@ -323,14 +344,14 @@ namespace quickbook void finish() const { - assert(pos_ == end_); + assert(pos_ == end_); } - iterator begin() const { return pos_; } - iterator end() const { return end_; } + iterator begin() { return iterator(&pos_); } + iterator end() { return iterator(&end_); } private: value list_; - iterator pos_, end_; + value::iterator pos_, end_; }; } From d94ecdd77ba92e373bfca4d75e302e8948c8f5ff Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 25 Feb 2011 23:07:07 +0000 Subject: [PATCH 08/24] Throw errors for incorrect method calls rather than assert. [SVN r69290] --- src/values.cpp | 35 +++++++++++++++++++++++++++++++---- src/values.hpp | 15 ++++++++++++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/values.cpp b/src/values.cpp index b3d5c6a..f4b1adf 100644 --- a/src/values.cpp +++ b/src/values.cpp @@ -8,9 +8,24 @@ #include "values.hpp" #include +#include + +#define UNDEFINED_ERROR() \ + throw value_error( \ + std::string(BOOST_CURRENT_FUNCTION) +\ + " not defined for " + \ + this->type_name() + \ + " values." \ + ); namespace quickbook { + //////////////////////////////////////////////////////////////////////////// + // Value Error + + value_error::value_error(std::string const& x) + : std::logic_error(x) {} + //////////////////////////////////////////////////////////////////////////// // Node @@ -25,10 +40,10 @@ namespace quickbook value_node* value_node::store() { return this; } - file_position value_node::get_position() const { assert(false); } - std::string value_node::get_quickbook() const { assert(false); } - std::string value_node::get_boostbook() const { assert(false); } - value_node* value_node::get_list() const { assert(false); } + file_position value_node::get_position() const { UNDEFINED_ERROR(); } + std::string value_node::get_quickbook() const { UNDEFINED_ERROR(); } + std::string value_node::get_boostbook() const { UNDEFINED_ERROR(); } + value_node* value_node::get_list() const { UNDEFINED_ERROR(); } bool value_node::empty() const { return false; } bool value_node::is_list() const { return false; } @@ -52,6 +67,8 @@ namespace quickbook : value_node(t) {} private: + char const* type_name() const { return "empty"; } + virtual value_node* clone() const { return new value_empty_impl(tag_); } @@ -188,6 +205,8 @@ namespace quickbook public: explicit value_string_impl(std::string const&, value::tag_type); private: + char const* type_name() const { return "boostbook"; } + virtual ~value_string_impl(); virtual value_node* clone() const; virtual std::string get_boostbook() const; @@ -206,6 +225,8 @@ namespace quickbook quickbook::iterator begin, quickbook::iterator end, value::tag_type); private: + char const* type_name() const { return "quickbook"; } + virtual ~value_qbk_string_impl(); virtual value_node* clone() const; virtual file_position get_position() const; @@ -222,6 +243,8 @@ namespace quickbook public: explicit value_qbk_ref_impl(quickbook::iterator begin, quickbook::iterator end, value::tag_type); private: + char const* type_name() const { return "quickbook"; } + virtual ~value_qbk_ref_impl(); virtual value_node* clone() const; virtual value_node* store(); @@ -237,6 +260,8 @@ namespace quickbook struct value_qbk_bbk_impl : public value_node { private: + char const* type_name() const { return "quickbook/boostbook"; } + value_qbk_bbk_impl( std::string const& qbk, std::string const& bbk, file_position const&, value::tag_type); @@ -571,6 +596,8 @@ namespace quickbook value_list_impl(value::tag_type); value_list_impl(value_node*, value::tag_type); private: + char const* type_name() const { return "list"; } + virtual ~value_list_impl(); virtual value_node* clone() const; virtual value_node* store(); diff --git a/src/values.hpp b/src/values.hpp index ab1a5ab..337856b 100644 --- a/src/values.hpp +++ b/src/values.hpp @@ -16,12 +16,14 @@ #include #include #include +#include #include "fwd.hpp" namespace quickbook { class value; class value_builder; + class value_error; namespace detail { @@ -42,6 +44,7 @@ namespace quickbook virtual ~value_node(); public: + virtual char const* type_name() const = 0; virtual value_node* clone() const = 0; virtual value_node* store(); @@ -54,7 +57,7 @@ namespace quickbook virtual bool is_string() const; virtual value_node* get_list() const; - + int ref_count_; const tag_type tag_; value_node* next_; @@ -258,6 +261,16 @@ namespace quickbook boost::scoped_ptr saved; }; + //////////////////////////////////////////////////////////////////////////// + // Value Error + // + + class value_error : std::logic_error + { + public: + value_error(std::string const&); + }; + //////////////////////////////////////////////////////////////////////////// // Value Consumer // From e1b241806df306aac348442910483811e00ec4b8 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 26 Feb 2011 11:17:53 +0000 Subject: [PATCH 09/24] Some fixes for windows. [SVN r69300] --- src/actions.cpp | 6 ++++-- src/value_tags.hpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index bec07ac..d3db160 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -184,7 +184,7 @@ namespace quickbook boost::lexical_cast(pos.column)); detail::outerr(actions.filename, pos.line) - << formatted_message << std::endl; + << detail::utf8(formatted_message) << std::endl; ++actions.error_count; } @@ -634,7 +634,9 @@ namespace quickbook if(!attributes.insert(std::make_pair(name.get_quickbook(), value)).second) { detail::outwarn(actions.filename, name.get_position().line) - << "Duplicate image attribute: " << name.get_quickbook() << std::endl; + << "Duplicate image attribute: " + << detail::utf8(name.get_quickbook()) + << std::endl; } } diff --git a/src/value_tags.hpp b/src/value_tags.hpp index 1e34e6d..ec3312c 100644 --- a/src/value_tags.hpp +++ b/src/value_tags.hpp @@ -30,7 +30,7 @@ return "null"; \ BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_CASE, _, values) \ default: \ - assert(false); \ + assert(false); return ""; \ }; \ } \ \ @@ -55,7 +55,7 @@ return "null"; \ BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_NAMED_CASE, _, values) \ default: \ - assert(false); \ + assert(false); return ""; \ }; \ } \ \ From 6d5e10008a5c5f931996a444311d0c0b9daf59e7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 26 Feb 2011 11:19:02 +0000 Subject: [PATCH 10/24] Try using wide streams more widely on windows. [SVN r69301] --- src/input_path.cpp | 2 ++ src/input_path.hpp | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/input_path.cpp b/src/input_path.cpp index 67da796..19d81d4 100644 --- a/src/input_path.cpp +++ b/src/input_path.cpp @@ -161,8 +161,10 @@ namespace detail { void initialise_output() { +# if defined(BOOST_MSVC) && BOOST_MSVC >= 1400 if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT); if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT); +# endif } void write_utf8(ostream& out, std::string const& x) diff --git a/src/input_path.hpp b/src/input_path.hpp index 0ecc6f1..ee13487 100644 --- a/src/input_path.hpp +++ b/src/input_path.hpp @@ -19,9 +19,7 @@ # define QUICKBOOK_CYGWIN_PATHS 1 #elif defined(_WIN32) # define QUICKBOOK_WIDE_PATHS 1 -# if defined(BOOST_MSVC) && BOOST_MSVC >= 1400 -# define QUICKBOOK_WIDE_STREAMS 1 -# endif +# define QUICKBOOK_WIDE_STREAMS 1 #endif #if !defined(QUICKBOOK_WIDE_PATHS) From 33ff714c47f78c90091273b67b49fcc24702f21f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 26 Feb 2011 11:32:11 +0000 Subject: [PATCH 11/24] Implement integer values, and use them for the quickbook version. [SVN r69302] --- src/actions.cpp | 6 ---- src/actions.hpp | 2 -- src/doc_info_actions.cpp | 20 +++++++++---- src/doc_info_grammar.cpp | 9 ++++-- src/doc_info_tags.hpp | 1 + src/values.cpp | 63 ++++++++++++++++++++++++++++++++++++---- src/values.hpp | 10 ++++++- src/values_parse.hpp | 6 ++++ 8 files changed, 94 insertions(+), 23 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index d3db160..c9e2217 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -32,8 +32,6 @@ 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 { @@ -1630,8 +1628,6 @@ namespace quickbook // save the source mode and version info (only restored for 1.6+) std::string source_mode = actions.source_mode; - unsigned qbk_major_version_store = qbk_major_version; - unsigned qbk_minor_version_store = qbk_minor_version; unsigned qbk_version_n_store = qbk_version_n; // scope the macros @@ -1667,8 +1663,6 @@ namespace quickbook { actions.source_mode = source_mode; - qbk_major_version = qbk_major_version_store; - qbk_minor_version = qbk_minor_version_store; qbk_version_n = qbk_version_n_store; } diff --git a/src/actions.hpp b/src/actions.hpp index 0b858bd..42f1522 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -37,8 +37,6 @@ namespace quickbook namespace cl = boost::spirit::classic; namespace fs = boost::filesystem; - 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 { diff --git a/src/doc_info_actions.cpp b/src/doc_info_actions.cpp index 298ff08..1e7359d 100644 --- a/src/doc_info_actions.cpp +++ b/src/doc_info_actions.cpp @@ -79,8 +79,8 @@ namespace quickbook while (values.check(value::default_tag)) values.consume(); - std::vector duplicates; - + value qbk_version = values.optional_consume(doc_info_tags::qbk_version); + value doc_title; if (values.check()) { @@ -89,6 +89,8 @@ namespace quickbook actions.doc_title_qbk = doc_title.get_quickbook(); } + std::vector duplicates; + value id = consume_last_single(values, doc_info_attributes::id, &duplicates); value dirname = consume_last_single(values, doc_info_attributes::dirname, &duplicates); value last_revision = consume_last_single(values, doc_info_attributes::last_revision, &duplicates); @@ -155,22 +157,28 @@ namespace quickbook // Quickbook version - if (qbk_major_version == -1) + int qbk_major_version, qbk_minor_version; + + if (qbk_version.empty()) { // hard code quickbook version to v1.1 qbk_major_version = 1; qbk_minor_version = 1; - qbk_version_n = 101; detail::outwarn(actions.filename,1) << "Warning: Quickbook version undefined. " "Version 1.1 is assumed" << std::endl; } else { - qbk_version_n = ((unsigned) qbk_major_version * 100) + - (unsigned) qbk_minor_version; + value_consumer qbk_version_values(qbk_version); + qbk_major_version = qbk_version_values.consume().get_int(); + qbk_minor_version = qbk_version_values.consume().get_int(); + qbk_version_values.finish(); } + qbk_version_n = ((unsigned) qbk_major_version * 100) + + (unsigned) qbk_minor_version; + if (qbk_version_n == 106) { detail::outwarn(actions.filename,1) diff --git a/src/doc_info_grammar.cpp b/src/doc_info_grammar.cpp index 0fe308e..2671ecf 100644 --- a/src/doc_info_grammar.cpp +++ b/src/doc_info_grammar.cpp @@ -135,11 +135,14 @@ namespace quickbook ; local.quickbook_version = - "quickbook" >> hard_space - >> ( cl::uint_p [cl::assign_a(qbk_major_version)] + actions.values.list(doc_info_tags::qbk_version) + [ "quickbook" + >> hard_space + >> ( cl::uint_p [actions.values.entry(ph::arg1)] >> '.' - >> uint2_t() [cl::assign_a(qbk_minor_version)] + >> uint2_t() [actions.values.entry(ph::arg1)] ) + ] ; // TODO: Clear phrase afterwards? diff --git a/src/doc_info_tags.hpp b/src/doc_info_tags.hpp index bfba342..811a694 100644 --- a/src/doc_info_tags.hpp +++ b/src/doc_info_tags.hpp @@ -14,6 +14,7 @@ namespace quickbook { QUICKBOOK_VALUE_TAGS(doc_info_tags, 0x400, + (qbk_version) (type) (title) (author_surname)(author_first) diff --git a/src/values.cpp b/src/values.cpp index f4b1adf..e17b320 100644 --- a/src/values.cpp +++ b/src/values.cpp @@ -9,6 +9,7 @@ #include "values.hpp" #include #include +#include #define UNDEFINED_ERROR() \ throw value_error( \ @@ -41,6 +42,7 @@ namespace quickbook value_node* value_node::store() { return this; } file_position value_node::get_position() const { UNDEFINED_ERROR(); } + int value_node::get_int() const { UNDEFINED_ERROR(); } std::string value_node::get_quickbook() const { UNDEFINED_ERROR(); } std::string value_node::get_boostbook() const { UNDEFINED_ERROR(); } value_node* value_node::get_list() const { UNDEFINED_ERROR(); } @@ -195,6 +197,62 @@ namespace quickbook return value(detail::value_empty_impl::new_(t)); } + //////////////////////////////////////////////////////////////////////////// + // Integers + + namespace detail + { + struct value_int_impl : public value_node + { + public: + explicit value_int_impl(int, value::tag_type); + private: + char const* type_name() const { return "integer"; } + virtual value_node* clone() const; + virtual int get_int() const; + virtual std::string get_quickbook() const; + virtual std::string get_boostbook() const; + virtual bool empty() const; + + int value_; + }; + + value_int_impl::value_int_impl(int v, value::tag_type t) + : value_node(t) + , value_(v) + {} + + value_node* value_int_impl::clone() const + { + return new value_int_impl(value_, tag_); + } + + int value_int_impl::get_int() const + { + return value_; + } + + std::string value_int_impl::get_quickbook() const + { + return boost::lexical_cast(value_); + } + + std::string value_int_impl::get_boostbook() const + { + return boost::lexical_cast(value_); + } + + bool value_int_impl::empty() const + { + return false; + } + } + + value int_value(int v, value::tag_type t) + { + return value(new detail::value_int_impl(v, t)); + } + //////////////////////////////////////////////////////////////////////////// // Strings @@ -675,11 +733,6 @@ namespace quickbook } } - value list_value(value::tag_type t) - { - return value(new detail::value_list_impl(t)); - } - ////////////////////////////////////////////////////////////////////////// // List builder diff --git a/src/values.hpp b/src/values.hpp index 337856b..6f27844 100644 --- a/src/values.hpp +++ b/src/values.hpp @@ -51,6 +51,7 @@ namespace quickbook virtual file_position get_position() const; virtual std::string get_quickbook() const; virtual std::string get_boostbook() const; + virtual int get_int() const; virtual bool empty() const; virtual bool is_list() const; @@ -110,6 +111,8 @@ namespace quickbook { return value_->get_quickbook(); } std::string get_boostbook() const { return value_->get_boostbook(); } + int get_int() const + { return value_->get_int(); } protected: value_node* value_; @@ -219,8 +222,13 @@ namespace quickbook explicit value(detail::value_node*); }; + // Empty value empty_value(value::tag_type = value::default_tag); - value list_value(value::tag_type = value::default_tag); + + // Integers + value int_value(int, value::tag_type = value::default_tag); + + // Boostbook and quickbook strings value qbk_value(iterator, iterator, value::tag_type = value::default_tag); value qbk_value(std::string const&, file_position = file_position(), diff --git a/src/values_parse.hpp b/src/values_parse.hpp index a4f8902..9897994 100644 --- a/src/values_parse.hpp +++ b/src/values_parse.hpp @@ -74,6 +74,12 @@ namespace quickbook { { b.insert(qbk_value(v, begin.get_position(), tag)); } + + void operator()(int v, + value::tag_type tag = value::default_tag) const + { + b.insert(int_value(v, tag)); + } value_builder& b; }; From cb26921203b820c28988725d013aa432ba63b0cb Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 26 Feb 2011 18:31:17 +0000 Subject: [PATCH 12/24] Don't include escaped boostbook or code in simple markup. [SVN r69308] --- src/main_grammar.cpp | 2 +- test/simple_markup.gold | 3 +++ test/simple_markup.quickbook | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 7bd937a..299bda8 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -420,7 +420,7 @@ namespace quickbook | local.simple_teletype ; - local.simple_phrase_end = '[' | phrase_end; + local.simple_phrase_end = cl::ch_p('[') | "'''" | '`' | phrase_end; simple_markup(local.simple_bold, '*', actions.simple_bold, local.simple_phrase_end); diff --git a/test/simple_markup.gold b/test/simple_markup.gold index 3b912de..cef5e39 100644 --- a/test/simple_markup.gold +++ b/test/simple_markup.gold @@ -28,5 +28,8 @@ not_underlined_ + + _Should not underline escaped markup_. _or this escaped_ markup form. + diff --git a/test/simple_markup.quickbook b/test/simple_markup.quickbook index abbaaa0..3abc7cd 100644 --- a/test/simple_markup.quickbook +++ b/test/simple_markup.quickbook @@ -18,4 +18,7 @@ not__underlined__hopefully not_underlined_ +_Should not underline '''escaped''' markup_. +_or this '''escaped_ markup''' form. + [endsect] \ No newline at end of file From a4b28525513b51a2607abc8fb7988255fbf250c0 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 26 Feb 2011 18:31:58 +0000 Subject: [PATCH 13/24] Fail if boostbook escape isn't closed. [SVN r69309] --- src/main_grammar.cpp | 4 +++- test/Jamfile.v2 | 1 + test/fail-mismatched-boostbook-escape.quickbook | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 test/fail-mismatched-boostbook-escape.quickbook diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 299bda8..47f27d4 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -479,7 +479,9 @@ namespace quickbook | ( ("'''" >> !eol) [actions.escape_pre] >> *(cl::anychar_p - "'''") [actions.raw_char] - >> cl::str_p("'''") [actions.escape_post] + >> ( cl::str_p("'''") [actions.escape_post] + | cl::eps_p [actions.error("Unclosed boostbook escape.")] + ) ) ; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ba97bd7..5529b67 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -79,6 +79,7 @@ test-suite quickbook.test : [ quickbook-error-test fail-unknown-quickbook-1 ] [ quickbook-error-test fail-unknown-quickbook-2 ] [ quickbook-error-test fail-unknown-quickbook-3 ] + [ quickbook-error-test fail-mismatched-boostbook-escape ] [ quickbook-test utf-8 ] [ quickbook-test utf-8-bom ] [ quickbook-test unicode-escape ] diff --git a/test/fail-mismatched-boostbook-escape.quickbook b/test/fail-mismatched-boostbook-escape.quickbook new file mode 100644 index 0000000..1f9d0c0 --- /dev/null +++ b/test/fail-mismatched-boostbook-escape.quickbook @@ -0,0 +1,5 @@ +[article Badly escaped boostbook +[quickbook 1.5] +] + +'''something \ No newline at end of file From c5292a1349655875638a56d0a287b68059d4474d Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 26 Feb 2011 18:32:31 +0000 Subject: [PATCH 14/24] Use a phoenix closure to inline the simple markup parser. [SVN r69310] --- src/actions.cpp | 24 ++++++-- src/actions.hpp | 6 -- src/actions_class.cpp | 6 +- src/actions_class.hpp | 6 +- src/main_grammar.cpp | 106 +++++++++++++++-------------------- test/simple_markup.gold | 2 +- test/simple_markup.quickbook | 2 +- 7 files changed, 68 insertions(+), 84 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index c9e2217..b71ad5d 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "quickbook.hpp" #include "actions.hpp" #include "utils.hpp" @@ -310,18 +311,31 @@ namespace quickbook { if(!actions.output_pre(out)) return; - out << pre; - std::string str(first, last); + char mark = *first; + int tag = + mark == '*' ? phrase_tags::bold : + mark == '/' ? phrase_tags::italic : + mark == '_' ? phrase_tags::underline : + mark == '=' ? phrase_tags::teletype : + 0; + + assert(tag != 0); + detail::markup markup = detail::markups[tag]; + + std::string str( + boost::next(first.base()), + boost::prior(last.base())); + + out << markup.pre; if (std::string const* ptr = find(macro, str.c_str())) { out << *ptr; } else { - while (first != last) - detail::print_char(*first++, out.get()); + detail::print_string(str, out.get()); } - out << post; + out << markup.post; } bool cond_phrase_push::start() diff --git a/src/actions.hpp b/src/actions.hpp index 42f1522..99d7619 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -136,21 +136,15 @@ namespace quickbook simple_phrase_action( collector& out - , std::string const& pre - , std::string const& post , string_symbols const& macro , quickbook::actions& actions) : out(out) - , pre(pre) - , post(post) , macro(macro) , actions(actions) {} void operator()(iterator first, iterator last) const; collector& out; - std::string pre; - std::string post; string_symbols const& macro; quickbook::actions& actions; }; diff --git a/src/actions_class.cpp b/src/actions_class.cpp index 98065c7..2df8482 100644 --- a/src/actions_class.cpp +++ b/src/actions_class.cpp @@ -77,11 +77,7 @@ namespace quickbook , raw_char(phrase, *this) , escape_unicode(phrase, *this) - , simple_bold(phrase, bold_pre_, bold_post_, macro, *this) - , simple_italic(phrase, italic_pre_, italic_post_, macro, *this) - , simple_underline(phrase, underline_pre_, underline_post_, macro, *this) - , simple_teletype(phrase, teletype_pre_, teletype_post_, macro, *this) - , simple_strikethrough(phrase, strikethrough_pre_, strikethrough_post_, macro, *this) + , simple_markup(phrase, macro, *this) , break_(phrase, *this) , do_macro(phrase, *this) diff --git a/src/actions_class.hpp b/src/actions_class.hpp index e3702b1..5182da3 100644 --- a/src/actions_class.hpp +++ b/src/actions_class.hpp @@ -122,11 +122,7 @@ namespace quickbook raw_char_action raw_char; escape_unicode_action escape_unicode; - simple_phrase_action simple_bold; - simple_phrase_action simple_italic; - simple_phrase_action simple_underline; - simple_phrase_action simple_teletype; - simple_phrase_action simple_strikethrough; + simple_phrase_action simple_markup; break_action break_; do_macro_action do_macro; diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 47f27d4..643ea57 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,47 +27,6 @@ namespace quickbook { namespace cl = boost::spirit::classic; - template - inline void - simple_markup( - Rule& simple - , char mark - , Action const& action - , Rule const& close - ) - { - simple = - mark - >> lookback - [ cl::anychar_p - >> ~cl::eps_p(mark) // first mark not be preceeded by - // the same character. - >> (cl::space_p | cl::punct_p | cl::end_p) - // first mark must be preceeded - // by space or punctuation or the - // mark character or a the start. - ] - >> ( cl::graph_p // graph_p must follow first mark - >> *( cl::anychar_p - - ( lookback[cl::graph_p] - // final mark must be preceeded by - // graph_p - >> mark - >> ~cl::eps_p(mark) // final mark not be followed by - // the same character. - >> (cl::space_p | cl::punct_p | cl::end_p) - // final mark must be followed by - // space or punctuation - | close // Make sure that we don't go - // past a single block - ) - ) - >> cl::eps_p(mark) - ) [action] - >> mark - ; - } - struct main_grammar_local { struct assign_element_type { @@ -141,11 +101,9 @@ namespace quickbook top_level, blocks, paragraph_separator, code, code_line, blank_line, hr, list, list_item, element, - simple_phrase_end, escape, - inline_code, simple_format, - simple_bold, simple_italic, simple_underline, - simple_teletype, template_, + inline_code, + template_, code_block, macro, template_args, template_args_1_4, template_arg_1_4, @@ -157,6 +115,15 @@ namespace quickbook dummy_block ; + struct simple_markup_closure + : cl::closure + { + member1 mark; + }; + + cl::rule + simple_markup, simple_markup_end; + element_info::type_enum element_type; cl::rule element_rule; value::tag_type element_tag; @@ -293,7 +260,7 @@ namespace quickbook | local.break_ | local.code_block | local.inline_code - | local.simple_format + | local.simple_markup | local.escape | comment ; @@ -413,23 +380,40 @@ namespace quickbook ) ; - local.simple_format = - local.simple_bold - | local.simple_italic - | local.simple_underline - | local.simple_teletype + local.simple_markup = + ( cl::chset<>("*/_=") [local.simple_markup.mark = ph::arg1] + >> lookback + [ cl::anychar_p + >> ~cl::eps_p(cl::f_ch_p(local.simple_markup.mark)) + // first mark not be preceeded by + // the same character. + >> (cl::space_p | cl::punct_p | cl::end_p) + // first mark must be preceeded + // by space or punctuation or the + // mark character or a the start. + ] + >> cl::graph_p // graph_p must follow first mark + >> *(cl::anychar_p - local.simple_markup_end(local.simple_markup.mark)) + >> cl::f_ch_p(local.simple_markup.mark) + ) [actions.simple_markup] ; - local.simple_phrase_end = cl::ch_p('[') | "'''" | '`' | phrase_end; - - simple_markup(local.simple_bold, - '*', actions.simple_bold, local.simple_phrase_end); - simple_markup(local.simple_italic, - '/', actions.simple_italic, local.simple_phrase_end); - simple_markup(local.simple_underline, - '_', actions.simple_underline, local.simple_phrase_end); - simple_markup(local.simple_teletype, - '=', actions.simple_teletype, local.simple_phrase_end); + local.simple_markup_end + = ( lookback[cl::graph_p] // final mark must be preceeded by + // graph_p + >> cl::f_ch_p(local.simple_markup_end.mark) + >> ~cl::eps_p(cl::f_ch_p(local.simple_markup_end.mark)) + // final mark not be followed by + // the same character. + >> (cl::space_p | cl::punct_p | cl::end_p) + // final mark must be followed by + // space or punctuation + ) + | '[' + | "'''" + | '`' + | phrase_end + ; phrase = actions.scoped_context(element_info::in_phrase) diff --git a/test/simple_markup.gold b/test/simple_markup.gold index cef5e39..9cdca67 100644 --- a/test/simple_markup.gold +++ b/test/simple_markup.gold @@ -17,7 +17,7 @@ not__underlined__hopefully - (bold) + (bold) und/er/lined all/italic * not bold* diff --git a/test/simple_markup.quickbook b/test/simple_markup.quickbook index 3abc7cd..c275d23 100644 --- a/test/simple_markup.quickbook +++ b/test/simple_markup.quickbook @@ -10,7 +10,7 @@ not__underlined__hopefully -(*bold*) +(*bold*) _und/er/lined_ /all/italic/ * not bold* From 14bbbe159a31223d68d7e1507af9fc14f8e8507d Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 27 Feb 2011 10:08:47 +0000 Subject: [PATCH 15/24] Decouple post_process. [SVN r69317] --- src/post_process.cpp | 39 +++++++++------------------------------ src/post_process.hpp | 12 +++++++++--- src/quickbook.cpp | 14 +++++++++++++- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/post_process.cpp b/src/post_process.cpp index d8a8dc1..f1621a5 100644 --- a/src/post_process.cpp +++ b/src/post_process.cpp @@ -7,7 +7,6 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include "post_process.hpp" -#include "input_path.hpp" #include #include #include @@ -419,9 +418,8 @@ namespace quickbook int indent; }; - int post_process( + std::string post_process( std::string const& in - , std::ostream& out , int indent , int linewidth) { @@ -430,36 +428,17 @@ namespace quickbook if (linewidth == -1) linewidth = 80; // set default to 80 - try + std::string tidy; + tidy_compiler state(tidy, linewidth); + tidy_grammar g(state, indent); + cl::parse_info r = parse(in.begin(), in.end(), g, cl::space_p); + if (r.full) { - std::string tidy; - tidy_compiler state(tidy, linewidth); - tidy_grammar g(state, indent); - cl::parse_info r = parse(in.begin(), in.end(), g, cl::space_p); - if (r.full) - { - out << tidy; - return 0; - } - else - { - // fallback! - ::quickbook::detail::outerr() - << "Warning: Post Processing Failed." - << std::endl; - out << in; - return 1; - } + return tidy; } - - catch(...) + else { - // fallback! - ::quickbook::detail::outerr() - << "Post Processing Failed." - << std::endl; - out << in; - return 1; + throw quickbook::post_process_failure("Post Processing Failed."); } } } diff --git a/src/post_process.hpp b/src/post_process.hpp index cfe220f..5893933 100644 --- a/src/post_process.hpp +++ b/src/post_process.hpp @@ -9,16 +9,22 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP) #define BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP -#include #include +#include namespace quickbook { - int post_process( + std::string post_process( std::string const& in - , std::ostream& out , int indent , int linewidth); + + class post_process_failure : std::runtime_error + { + public: + post_process_failure(std::string const& error) + : std::runtime_error(error) {} + }; } #endif // BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP diff --git a/src/quickbook.cpp b/src/quickbook.cpp index a341e03..1146caa 100644 --- a/src/quickbook.cpp +++ b/src/quickbook.cpp @@ -149,7 +149,19 @@ namespace quickbook if (pretty_print) { - result = post_process(buffer.str(), fileout, indent, linewidth); + try + { + fileout << post_process(buffer.str(), indent, linewidth); + } + catch (quickbook::post_process_failure&) + { + // fallback! + ::quickbook::detail::outerr() + << "Post Processing Failed." + << std::endl; + fileout << buffer.str(); + return 1; + } } else { From ab5cc3fb0ccf67291707bc800c4aa4b876ef6c84 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 27 Feb 2011 10:09:53 +0000 Subject: [PATCH 16/24] Make post_process a little less crashy. [SVN r69318] --- src/post_process.cpp | 3 +++ src/post_process.hpp | 4 ++-- test/unit/Jamfile.v2 | 1 + test/unit/post_process_test.cpp | 30 ++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 test/unit/post_process_test.cpp diff --git a/src/post_process.cpp b/src/post_process.cpp index f1621a5..3c77351 100644 --- a/src/post_process.cpp +++ b/src/post_process.cpp @@ -402,6 +402,9 @@ namespace quickbook void do_end_tag(iter_type f, iter_type l) const { + if (state.tags.empty()) + throw quickbook::post_process_failure("Mismatched tags."); + bool is_flow_tag = state.is_flow_tag(state.tags.top()); if (!is_flow_tag) { diff --git a/src/post_process.hpp b/src/post_process.hpp index 5893933..5b63ba2 100644 --- a/src/post_process.hpp +++ b/src/post_process.hpp @@ -16,8 +16,8 @@ namespace quickbook { std::string post_process( std::string const& in - , int indent - , int linewidth); + , int indent = -1 + , int linewidth = -1); class post_process_failure : std::runtime_error { diff --git a/test/unit/Jamfile.v2 b/test/unit/Jamfile.v2 index 310aebc..78a7845 100644 --- a/test/unit/Jamfile.v2 +++ b/test/unit/Jamfile.v2 @@ -5,3 +5,4 @@ project quickbook-unit-tests ; run values_test.cpp ../../src/values.cpp ; +run post_process_test.cpp ../../src/post_process.cpp ; diff --git a/test/unit/post_process_test.cpp b/test/unit/post_process_test.cpp new file mode 100644 index 0000000..737d233 --- /dev/null +++ b/test/unit/post_process_test.cpp @@ -0,0 +1,30 @@ +/*============================================================================= + Copyright (c) 2011 Daniel James + + 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) +=============================================================================*/ + +#include "post_process.hpp" +#include + +#define EXPECT_EXCEPTION(test, msg) \ + try { \ + test; \ + BOOST_ERROR(msg); \ + } \ + catch(quickbook::post_process_failure&) { \ + } + +int main() +{ + EXPECT_EXCEPTION( + quickbook::post_process(""), + "Succeeded with unbalanced tag"); + EXPECT_EXCEPTION( + quickbook::post_process("<"), + "Succeeded with badly formed tag"); + + return boost::report_errors(); +} From 661fd200ae363479fdbee4407c87722d7a3d9c0c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 27 Feb 2011 15:37:47 +0000 Subject: [PATCH 17/24] Support escapes in simple markup. [SVN r69332] --- src/actions.cpp | 13 +++++----- src/actions.hpp | 2 +- src/main_grammar.cpp | 46 ++++++++++++++++++++++++++---------- test/simple_markup.gold | 15 ++++++++++++ test/simple_markup.quickbook | 12 ++++++++++ 5 files changed, 67 insertions(+), 21 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index b71ad5d..1dc31c9 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -307,11 +307,10 @@ namespace quickbook content.get_boostbook(), anchor + "-heading", linkend); } - void simple_phrase_action::operator()(iterator first, iterator last) const + void simple_phrase_action::operator()(char mark) const { if(!actions.output_pre(out)) return; - char mark = *first; int tag = mark == '*' ? phrase_tags::bold : mark == '/' ? phrase_tags::italic : @@ -322,18 +321,18 @@ namespace quickbook assert(tag != 0); detail::markup markup = detail::markups[tag]; - std::string str( - boost::next(first.base()), - boost::prior(last.base())); + value_consumer values = actions.values.get(); + value content = values.consume(); + values.finish(); out << markup.pre; - if (std::string const* ptr = find(macro, str.c_str())) + if (std::string const* ptr = find(macro, content.get_quickbook().c_str())) { out << *ptr; } else { - detail::print_string(str, out.get()); + out << content.get_boostbook(); } out << markup.post; } diff --git a/src/actions.hpp b/src/actions.hpp index 99d7619..7f82f21 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -142,7 +142,7 @@ namespace quickbook , macro(macro) , actions(actions) {} - void operator()(iterator first, iterator last) const; + void operator()(char) const; collector& out; string_symbols const& macro; diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 643ea57..727a91d 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -101,7 +101,7 @@ namespace quickbook top_level, blocks, paragraph_separator, code, code_line, blank_line, hr, list, list_item, element, - escape, + nested_char, escape, inline_code, template_, code_block, macro, @@ -381,7 +381,8 @@ namespace quickbook ; local.simple_markup = - ( cl::chset<>("*/_=") [local.simple_markup.mark = ph::arg1] + cl::chset<>("*/_=") [local.simple_markup.mark = ph::arg1] + >> cl::eps_p(cl::graph_p) // graph_p must follow first mark >> lookback [ cl::anychar_p >> ~cl::eps_p(cl::f_ch_p(local.simple_markup.mark)) @@ -392,10 +393,17 @@ namespace quickbook // by space or punctuation or the // mark character or a the start. ] - >> cl::graph_p // graph_p must follow first mark - >> *(cl::anychar_p - local.simple_markup_end(local.simple_markup.mark)) - >> cl::f_ch_p(local.simple_markup.mark) - ) [actions.simple_markup] + >> actions.values.save() + [ + actions.scoped_output() + [ + (*( ~cl::eps_p(local.simple_markup_end(local.simple_markup.mark)) + >> local.nested_char + )) [actions.docinfo_value(ph::arg1, ph::arg2)] + ] + >> cl::f_ch_p(local.simple_markup.mark) + [actions.simple_markup] + ] ; local.simple_markup_end @@ -452,6 +460,19 @@ namespace quickbook ] ; + local.nested_char = + cl::str_p("\\n") [actions.break_] + | "\\ " // 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] + | cl::anychar_p [actions.plain_char] + ; + local.escape = cl::str_p("\\n") [actions.break_] | cl::str_p("\\ ") // ignore an escaped space @@ -540,13 +561,12 @@ namespace quickbook ; phrase_end = - ']' | - cl::if_p(var(actions.no_eols)) - [ - cl::eol_p >> *cl::blank_p >> cl::eol_p - // Make sure that we don't go - ] // past a single block, except - ; // when preformatted. + ']' + | cl::eps_p(var(actions.no_eols)) + >> cl::eol_p >> *cl::blank_p >> cl::eol_p + ; // Make sure that we don't go + // past a single block, except + // when preformatted. comment = "[/" >> *(local.dummy_block | (cl::anychar_p - ']')) >> ']' diff --git a/test/simple_markup.gold b/test/simple_markup.gold index 9cdca67..2cb0481 100644 --- a/test/simple_markup.gold +++ b/test/simple_markup.gold @@ -31,5 +31,20 @@ _Should not underline escaped markup_. _or this escaped_ markup form. + + Matti Meikäläinen + + + replaced + + + replaced + + + _macro_ + + + /not italic/ + diff --git a/test/simple_markup.quickbook b/test/simple_markup.quickbook index c275d23..9f4268f 100644 --- a/test/simple_markup.quickbook +++ b/test/simple_markup.quickbook @@ -2,6 +2,8 @@ [quickbook 1.5] ] +[def _macro_ replaced] + [section Simple Markup] /italic/ *bold* _underline_ =teletype= @@ -21,4 +23,14 @@ not_underlined_ _Should not underline '''escaped''' markup_. _or this '''escaped_ markup''' form. +=Matti Meik\u00E4l\u00E4inen= + +=_macro_= + +__macro__ + +=_mac\ ro_= + +/not italic\/ + [endsect] \ No newline at end of file From 5abc1f9a69af454e31dbd93bdbe3182331484b3a Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Mar 2011 09:13:06 +0000 Subject: [PATCH 18/24] Slightly simpler simple markup. [SVN r69435] --- src/main_grammar.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 727a91d..168e72f 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -122,7 +122,8 @@ namespace quickbook }; cl::rule - simple_markup, simple_markup_end; + simple_markup; + cl::rule simple_markup_end; element_info::type_enum element_type; cl::rule element_rule; @@ -397,7 +398,7 @@ namespace quickbook [ actions.scoped_output() [ - (*( ~cl::eps_p(local.simple_markup_end(local.simple_markup.mark)) + (*( ~cl::eps_p(local.simple_markup_end) >> local.nested_char )) [actions.docinfo_value(ph::arg1, ph::arg2)] ] @@ -409,8 +410,8 @@ namespace quickbook local.simple_markup_end = ( lookback[cl::graph_p] // final mark must be preceeded by // graph_p - >> cl::f_ch_p(local.simple_markup_end.mark) - >> ~cl::eps_p(cl::f_ch_p(local.simple_markup_end.mark)) + >> cl::f_ch_p(local.simple_markup.mark) + >> ~cl::eps_p(cl::f_ch_p(local.simple_markup.mark)) // final mark not be followed by // the same character. >> (cl::space_p | cl::punct_p | cl::end_p) From 283bc525a128acdb49bfd07ffc33dfe80a25f9fb Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Mar 2011 09:13:55 +0000 Subject: [PATCH 19/24] More use of phoenix. [SVN r69436] --- src/block_element_grammar.cpp | 2 -- src/doc_info_grammar.cpp | 2 +- src/grammar_impl.hpp | 3 ++ src/main_grammar.cpp | 57 ++++++++++++---------------------- src/parsers.hpp | 10 +++--- src/phrase_element_grammar.cpp | 2 -- src/utils.hpp | 19 ------------ 7 files changed, 28 insertions(+), 67 deletions(-) diff --git a/src/block_element_grammar.cpp b/src/block_element_grammar.cpp index 5b31726..8514965 100644 --- a/src/block_element_grammar.cpp +++ b/src/block_element_grammar.cpp @@ -39,8 +39,6 @@ namespace quickbook void quickbook_grammar::impl::init_block_elements() { - using detail::var; - block_element_grammar_local& local = store_.create(); local.element_id = diff --git a/src/doc_info_grammar.cpp b/src/doc_info_grammar.cpp index 2671ecf..56d2975 100644 --- a/src/doc_info_grammar.cpp +++ b/src/doc_info_grammar.cpp @@ -123,7 +123,7 @@ namespace quickbook [actions.error("Unrecognized document attribute: '%s'.")] ) >> hard_space - >> actions.values.list(detail::var(local.attribute_tag)) + >> actions.values.list(ph::var(local.attribute_tag)) [local.attribute_rule] >> space >> ']' diff --git a/src/grammar_impl.hpp b/src/grammar_impl.hpp index ab1b20d..9db35ea 100644 --- a/src/grammar_impl.hpp +++ b/src/grammar_impl.hpp @@ -37,6 +37,9 @@ namespace quickbook phrase = nested_block | in_phrase }; + element_info() + : type(nothing), rule(), tag(0) {} + element_info( type_enum t, cl::rule* r, diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 168e72f..2445475 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -20,8 +20,8 @@ #include #include #include +#include #include -#include namespace quickbook { @@ -29,35 +29,21 @@ namespace quickbook struct main_grammar_local { - struct assign_element_type { - assign_element_type(main_grammar_local& l) : l(l) {} - - void operator()(element_info& t) const { - l.element_type = t.type; - l.element_rule = *t.rule; - l.element_tag = t.tag; - } - - main_grammar_local& l; - }; - struct process_element_impl : scoped_action_base { process_element_impl(main_grammar_local& l) : l(l) {} bool start() { - if (!(l.element_type & l.actions_.context)) + if (!(l.info.type & l.actions_.context)) return false; - // Save the element type because it might - // be overridden by nested markup. - element_type_ = l.element_type; + info_ = l.info; - if (!(element_type_ & element_info::in_phrase)) + if (!(info_.type & element_info::in_phrase)) l.actions_.paragraph(); - l.actions_.values.reset()(); + l.actions_.values.builder.reset(); return true; } @@ -65,18 +51,18 @@ namespace quickbook template bool result(ResultT result, ScannerT const& scan) { - if (result || l.element_type & element_info::in_phrase) + if (result || info_.type & element_info::in_phrase) return result; l.actions_.error(scan.first, scan.first); return true; } - void success() { l.element_type = element_type_; } + void success() { l.element_type = info_.type; } void failure() { l.element_type = element_info::nothing; } main_grammar_local& l; - element_info::type_enum element_type_; + element_info info_; }; struct is_block_type @@ -91,7 +77,7 @@ namespace quickbook bool operator()() const { - return !(l_.element_type & element_info::in_phrase); + return l_.element_type && !(l_.element_type & element_info::in_phrase); } main_grammar_local& l_; @@ -100,7 +86,7 @@ namespace quickbook cl::rule top_level, blocks, paragraph_separator, code, code_line, blank_line, hr, - list, list_item, element, + list, list_item, nested_char, escape, inline_code, template_, @@ -115,28 +101,26 @@ namespace quickbook dummy_block ; + cl::rule element; + struct simple_markup_closure : cl::closure { member1 mark; }; - cl::rule - simple_markup; + cl::rule simple_markup; cl::rule simple_markup_end; + element_info info; element_info::type_enum element_type; - cl::rule element_rule; - value::tag_type element_tag; quickbook::actions& actions_; - assign_element_type assign_element; scoped_parser process_element; is_block_type is_block; main_grammar_local(quickbook::actions& actions) : actions_(actions) - , assign_element(*this) , process_element(*this) , is_block(*this) {} @@ -144,8 +128,6 @@ namespace quickbook void quickbook_grammar::impl::init_main() { - using detail::var; - main_grammar_local& local = store_.add(new main_grammar_local(actions)); block_skip_initial_spaces = @@ -194,13 +176,14 @@ namespace quickbook local.element = '[' >> ( cl::eps_p(cl::punct_p) - >> elements [local.assign_element] - | elements [local.assign_element] + >> elements [ph::var(local.info) = ph::arg1] + | elements [ph::var(local.info) = ph::arg1] >> (cl::eps_p - (cl::alnum_p | '_')) ) >> local.process_element() - [ actions.values.list(detail::var(local.element_tag)) - [ local.element_rule + [ actions.values.list(ph::var(local.info.tag)) + + [ cl::lazy_p(*ph::var(local.info.rule)) >> space >> ']' ] [actions.element] @@ -563,7 +546,7 @@ namespace quickbook phrase_end = ']' - | cl::eps_p(var(actions.no_eols)) + | cl::eps_p(ph::var(actions.no_eols)) >> cl::eol_p >> *cl::blank_p >> cl::eol_p ; // Make sure that we don't go // past a single block, except diff --git a/src/parsers.hpp b/src/parsers.hpp index 87935b1..152771e 100644 --- a/src/parsers.hpp +++ b/src/parsers.hpp @@ -14,7 +14,9 @@ #include #include +#include #include +#include namespace quickbook { namespace cl = boost::spirit::classic; @@ -53,10 +55,6 @@ namespace quickbook { struct scoped { - typedef void result_type; - template - struct result { typedef void type; }; - explicit scoped(Impl const& impl) : impl_(impl) , in_progress_(false) @@ -74,14 +72,14 @@ namespace quickbook { template bool start(phoenix::tuple const& x) { - in_progress_ = impl_.start(x[t0()]); + in_progress_ = phoenix::bind(&Impl::start)(phoenix::var(impl_), x[t0()])(); return in_progress_; } template bool start(phoenix::tuple const& x) { - in_progress_ = impl_.start(x[t0()], x[t1()]); + in_progress_ = phoenix::bind(&Impl::start)(phoenix::var(impl_), x[t0()], x[t1()])(); return in_progress_; } diff --git a/src/phrase_element_grammar.cpp b/src/phrase_element_grammar.cpp index 3946089..0605081 100644 --- a/src/phrase_element_grammar.cpp +++ b/src/phrase_element_grammar.cpp @@ -32,8 +32,6 @@ namespace quickbook void quickbook_grammar::impl::init_phrase_elements() { - using detail::var; - phrase_element_grammar_local& local = store_.create(); elements.add diff --git a/src/utils.hpp b/src/utils.hpp index bee7406..878ba91 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -42,24 +41,6 @@ namespace detail return out_name; } - template - struct var_wrapper - : public ::boost::reference_wrapper - { - typedef ::boost::reference_wrapper parent; - - explicit inline var_wrapper(T& t) : parent(t) {} - - inline T& operator()() const { return parent::get(); } - }; - - template - inline var_wrapper - var(T& t) - { - return var_wrapper(t); - } - // un-indent a code segment void unindent(std::string& program); From 7983810c396b11697d21972463b55ee13763fa9c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Mar 2011 09:14:28 +0000 Subject: [PATCH 20/24] Better anchor support for lists. [SVN r69437] --- src/actions.cpp | 2 +- src/main_grammar.cpp | 5 ++++- test/anchor.gold | 37 +++++++++++++++++++++++++++++++++++++ test/anchor.quickbook | 14 ++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 1dc31c9..5674ec9 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -376,7 +376,7 @@ namespace quickbook void list_action(quickbook::actions& actions, value list) { - if(actions.suppress) return; + if(!actions.output_pre(actions.out)) return; typedef std::pair mark_type; std::stack list_marks; diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index 2445475..d43281e 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -209,7 +209,9 @@ namespace quickbook local.list = cl::eps_p(cl::ch_p('*') | '#') [actions.values.reset()] - >> actions.values.list(block_tags::list) + >> actions.scoped_output() + [ + actions.values.list(block_tags::list) [ +actions.values.list() [ (*cl::blank_p) [actions.values.entry(ph::arg1, ph::arg2, general_tags::list_indent)] >> (cl::ch_p('*') | '#') @@ -217,6 +219,7 @@ namespace quickbook >> *cl::blank_p >> local.list_item [actions.phrase_value] ] + ] ] [actions.element] ; diff --git a/test/anchor.gold b/test/anchor.gold index 59026d9..5f61f34 100644 --- a/test/anchor.gold +++ b/test/anchor.gold @@ -43,4 +43,41 @@
Conditional Section Anchor
+
+ Lists + + + + Item 1 + + + + + Item 2 + + + + + Nested List + + + + Nested Item 1 + + + + + Nested Item 2 + + + + + + + + Item 3 + + + +
diff --git a/test/anchor.quickbook b/test/anchor.quickbook index b5d493e..ff0806d 100644 --- a/test/anchor.quickbook +++ b/test/anchor.quickbook @@ -33,4 +33,18 @@ they appear in the correct place. [#a3] [#a12][?__not_defined__ #a13] [section Conditional Section Anchor] +[endsect] + +[section Lists] + +[#a14] + +* Item 1 +* Item 2 +* Nested List + [#a15] + * Nested Item 1 + * Nested Item 2 +* Item 3 + [endsect] \ No newline at end of file From fddc8c896c432688f3dbff25d945747ae9cf23b4 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Mar 2011 09:15:09 +0000 Subject: [PATCH 21/24] Explicit list markup. Refs #1193 I don't think paragraph markup would be very useful right now, because it wouldn't be usable in a phrase context. These can't be templates because templates are implicitly wrapped in paragraphs. [SVN r69438] --- src/actions.cpp | 21 +++++++++++++++++++++ src/block_element_grammar.cpp | 9 ++++++++- src/block_tags.hpp | 2 +- src/grammar_impl.hpp | 6 ++++-- src/main_grammar.cpp | 3 ++- src/markups.cpp | 2 ++ test/Jamfile.v2 | 2 ++ test/elements_1_5.gold | 12 ++++++++++++ test/elements_1_5.quickbook | 9 +++++++++ test/elements_1_6.gold | 30 ++++++++++++++++++++++++++++++ test/elements_1_6.quickbook | 9 +++++++++ 11 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 test/elements_1_5.gold create mode 100644 test/elements_1_5.quickbook create mode 100644 test/elements_1_6.gold create mode 100644 test/elements_1_6.quickbook diff --git a/src/actions.cpp b/src/actions.cpp index 5674ec9..fb8e0ff 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -50,6 +50,7 @@ namespace quickbook } void list_action(quickbook::actions&, value); + void explicit_list_action(quickbook::actions&, value); void header_action(quickbook::actions&, value); void begin_section_action(quickbook::actions&, value); void end_section_action(quickbook::actions&, value, file_position); @@ -78,6 +79,9 @@ namespace quickbook { case block_tags::list: return list_action(actions, v); + case block_tags::ordered_list: + case block_tags::itemized_list: + return explicit_list_action(actions, v); case block_tags::generic_heading: case block_tags::heading1: case block_tags::heading2: @@ -447,6 +451,23 @@ namespace quickbook } } + void explicit_list_action(quickbook::actions& actions, value list) + { + if(!actions.output_pre(actions.out)) return; + detail::markup markup = detail::markups[list.get_tag()]; + + actions.out << markup.pre; + + BOOST_FOREACH(value item, list) + { + actions.out << ""; + actions.out << item.get_boostbook(); + actions.out << ""; + } + + actions.out << markup.post; + } + // TODO: No need to check suppress since this is only used in the syntax // highlighter. I should moved this or something. void span::operator()(iterator first, iterator last) const diff --git a/src/block_element_grammar.cpp b/src/block_element_grammar.cpp index 8514965..8eacb0a 100644 --- a/src/block_element_grammar.cpp +++ b/src/block_element_grammar.cpp @@ -29,7 +29,7 @@ namespace quickbook cl::rule heading, inner_block, inner_phrase, def_macro, table, table_row, variablelist, - varlistentry, varlistterm, cell, + varlistentry, varlistterm, list, cell, preformatted, begin_section, end_section, xinclude, include, template_, template_id, template_formal_arg, @@ -232,6 +232,13 @@ namespace quickbook ) ; + elements.add + ("ordered_list", element_info(element_info::nested_block, &local.list, block_tags::ordered_list, 106)) + ("itemized_list", element_info(element_info::nested_block, &local.list, block_tags::itemized_list, 106)) + ; + + local.list = *local.cell; + local.cell = space >> cl::ch_p('[') diff --git a/src/block_tags.hpp b/src/block_tags.hpp index 58c67d3..921904c 100644 --- a/src/block_tags.hpp +++ b/src/block_tags.hpp @@ -23,7 +23,7 @@ namespace quickbook (variable_list)(table) (xinclude)(import)(include) (paragraph) - (list) + (list)(ordered_list)(itemized_list) ) QUICKBOOK_VALUE_TAGS(table_tags, 0x250, diff --git a/src/grammar_impl.hpp b/src/grammar_impl.hpp index 9db35ea..b3e7532 100644 --- a/src/grammar_impl.hpp +++ b/src/grammar_impl.hpp @@ -43,12 +43,14 @@ namespace quickbook element_info( type_enum t, cl::rule* r, - value::tag_type tag = value::default_tag) - : type(t), rule(r), tag(tag) {} + value::tag_type tag = value::default_tag, + unsigned int v = 0) + : type(t), rule(r), tag(tag), qbk_version(v) {} type_enum type; cl::rule* rule; value::tag_type tag; + unsigned int qbk_version; }; struct quickbook_grammar::impl diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index d43281e..a284d4f 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -35,7 +35,8 @@ namespace quickbook bool start() { - if (!(l.info.type & l.actions_.context)) + if (!(l.info.type & l.actions_.context) || + qbk_version_n < l.info.qbk_version) return false; info_ = l.info; diff --git a/src/markups.cpp b/src/markups.cpp index 97480ef..0b4c277 100644 --- a/src/markups.cpp +++ b/src/markups.cpp @@ -108,6 +108,8 @@ namespace quickbook { block_tags::important, important_pre, important_post }, { block_tags::note, note_pre, note_post }, { block_tags::tip, tip_pre, tip_post }, + { block_tags::ordered_list, "", "" }, + { block_tags::itemized_list, "", "" }, { phrase_tags::url, url_pre_, url_post_ }, { phrase_tags::link, link_pre_, link_post_ }, { phrase_tags::funcref, funcref_pre_, funcref_post_ }, diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5529b67..1a72763 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -59,6 +59,8 @@ test-suite quickbook.test : [ quickbook-test xml-escape_1_2 ] [ quickbook-test xml-escape_1_5 ] [ quickbook-test blocks ] + [ quickbook-test elements_1_5 ] + [ quickbook-test elements_1_6 ] [ quickbook-test newline ] [ quickbook-test anchor ] [ quickbook-test command_line_macro : : : __macro__=*bold* ] diff --git a/test/elements_1_5.gold b/test/elements_1_5.gold new file mode 100644 index 0000000..acbc81b --- /dev/null +++ b/test/elements_1_5.gold @@ -0,0 +1,12 @@ + + +
+ 1.5 Elements + + [ordered_list [item1][item2]] + + + [itemized_list [item1][item2]] + +
diff --git a/test/elements_1_5.quickbook b/test/elements_1_5.quickbook new file mode 100644 index 0000000..4ad0dee --- /dev/null +++ b/test/elements_1_5.quickbook @@ -0,0 +1,9 @@ +[article 1.5 Elements +[quickbook 1.5] +] + +[/ elements from 1.6] + +[ordered_list [item1][item2]] + +[itemized_list [item1][item2]] diff --git a/test/elements_1_6.gold b/test/elements_1_6.gold new file mode 100644 index 0000000..b678e4f --- /dev/null +++ b/test/elements_1_6.gold @@ -0,0 +1,30 @@ + + +
+ 1.6 Elements + + + + item1 + + + + + item2 + + + + + + + item1 + + + + + item2 + + + +
diff --git a/test/elements_1_6.quickbook b/test/elements_1_6.quickbook new file mode 100644 index 0000000..5282db4 --- /dev/null +++ b/test/elements_1_6.quickbook @@ -0,0 +1,9 @@ +[article 1.6 Elements +[quickbook 1.6] +] + +[/ elements from 1.6] + +[ordered_list [item1][item2]] + +[itemized_list [item1][item2]] From b39e5b1b6688aa7bb3e45200934ba6bf8ab2d401 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 12 Mar 2011 10:07:12 +0000 Subject: [PATCH 22/24] Use spirit to convert years to integers. [SVN r69887] --- src/doc_info_actions.cpp | 6 ++---- src/doc_info_grammar.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/doc_info_actions.cpp b/src/doc_info_actions.cpp index 1e7359d..a7c6214 100644 --- a/src/doc_info_actions.cpp +++ b/src/doc_info_actions.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include "quickbook.hpp" #include "utils.hpp" #include "input_path.hpp" @@ -291,11 +290,10 @@ namespace quickbook while(copyright.check(doc_info_tags::copyright_year)) { - int year_start = - boost::lexical_cast(copyright.consume().get_quickbook()); + int year_start = copyright.consume().get_int(); int year_end = copyright.check(doc_info_tags::copyright_year_end) ? - boost::lexical_cast(copyright.consume().get_quickbook()) : + copyright.consume().get_int() : year_start; if (year_end < year_start) { diff --git a/src/doc_info_grammar.cpp b/src/doc_info_grammar.cpp index 56d2975..064e069 100644 --- a/src/doc_info_grammar.cpp +++ b/src/doc_info_grammar.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace quickbook @@ -65,9 +66,10 @@ namespace quickbook cl::rule doc_title, doc_simple, doc_phrase, doc_fallback, doc_authors, doc_author, - doc_copyright, doc_copyright_year, doc_copyright_holder, + doc_copyright, doc_copyright_holder, doc_source_mode, doc_biblioid, quickbook_version, char_; + cl::uint_parser doc_copyright_year; cl::symbols<> doc_types; cl::symbols doc_attributes; std::map* > attribute_rules; @@ -159,8 +161,6 @@ namespace quickbook local.attribute_rules[doc_info_attributes::last_revision] = &local.doc_simple; local.attribute_rules[doc_info_attributes::lang] = &local.doc_simple; - local.doc_copyright_year = cl::repeat_p(4)[cl::digit_p]; - local.doc_copyright_holder = *( ~cl::eps_p ( ']' @@ -171,12 +171,12 @@ namespace quickbook local.doc_copyright = *( +( local.doc_copyright_year - [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::copyright_year)] + [actions.values.entry(ph::arg1, doc_info_tags::copyright_year)] >> space >> !( '-' >> space >> local.doc_copyright_year - [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::copyright_year_end)] + [actions.values.entry(ph::arg1, doc_info_tags::copyright_year_end)] >> space ) >> !cl::ch_p(',') From 704e3e72177c6866aff79c54ee74dd5922d4faba Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 12 Mar 2011 10:08:00 +0000 Subject: [PATCH 23/24] Don't require newlines at end of grammars. [SVN r69888] --- src/actions.cpp | 28 +++++++--------------------- src/code_snippet.cpp | 6 +++--- src/doc_info_grammar.cpp | 2 +- src/main_grammar.cpp | 7 ++++--- src/utils.cpp | 4 ---- src/utils.hpp | 2 -- test/templates.gold | 18 ++++++++++++++++++ test/templates.quickbook | 20 +++++++++++++++++++- 8 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index fb8e0ff..b5f4357 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -1031,28 +1031,14 @@ namespace quickbook } else { - if (!body.is_block) - { - // do a phrase level parse - actions.filename = body.filename; - iterator first(body.content.begin(), body.position); - iterator last(body.content.end()); + actions.filename = body.filename; + iterator first(body.content.begin(), body.position); + iterator last(body.content.end()); - return cl::parse(first, last, actions.grammar().simple_phrase).full; - } - else - { - // do a block level parse - // ensure that we have enough trailing newlines to eliminate - // the need to check for end of file in the grammar. - - actions.filename = body.filename; - std::string content = body.content + "\n\n"; - iterator first(content.begin(), body.position); - iterator last(content.end()); - - return cl::parse(first, last, actions.grammar().block).full; - } + return cl::parse(first, last, + body.is_block ? actions.grammar().block : + actions.grammar().simple_phrase + ).full; } } } diff --git a/src/code_snippet.cpp b/src/code_snippet.cpp index 19d5e97..82e7129 100644 --- a/src/code_snippet.cpp +++ b/src/code_snippet.cpp @@ -116,7 +116,7 @@ namespace quickbook = cl::confix_p( *cl::blank_p >> "#<-", *cl::anychar_p, - "#->" >> *cl::blank_p >> cl::eol_p + "#->" >> *cl::blank_p >> (cl::eol_p | cl::end_p) ) | cl::confix_p( "\"\"\"<-\"\"\"", @@ -134,7 +134,7 @@ namespace quickbook cl::confix_p( *cl::space_p >> "#`", (*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)], - cl::eol_p + (cl::eol_p | cl::end_p) ) | cl::confix_p( *cl::space_p >> "\"\"\"`", @@ -241,7 +241,7 @@ namespace quickbook = cl::confix_p( *cl::space_p >> "//`", (*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)], - cl::eol_p + (cl::eol_p | cl::end_p) ) | cl::confix_p( *cl::space_p >> "/*`", diff --git a/src/doc_info_grammar.cpp b/src/doc_info_grammar.cpp index 064e069..0c56770 100644 --- a/src/doc_info_grammar.cpp +++ b/src/doc_info_grammar.cpp @@ -133,7 +133,7 @@ namespace quickbook ) >> space [actions.values.sort()] >> ']' - >> +cl::eol_p + >> (+cl::eol_p | cl::end_p) ; local.quickbook_version = diff --git a/src/main_grammar.cpp b/src/main_grammar.cpp index a284d4f..04daf51 100644 --- a/src/main_grammar.cpp +++ b/src/main_grammar.cpp @@ -151,6 +151,7 @@ namespace quickbook | cl::space_p [actions.space_char] | cl::anychar_p [actions.plain_char] ) + >> cl::eps_p [actions.paragraph] ] ; @@ -171,7 +172,7 @@ namespace quickbook local.hr = cl::str_p("----") >> *(cl::anychar_p - eol) - >> +eol + >> (+eol | cl::end_p) ; local.element @@ -200,7 +201,7 @@ namespace quickbook ; local.code_line = - cl::blank_p >> *(cl::anychar_p - cl::eol_p) >> cl::eol_p + cl::blank_p >> *(cl::anychar_p - cl::eol_p) >> (cl::eol_p | cl::end_p) ; local.blank_line = @@ -238,7 +239,7 @@ namespace quickbook ) ] ] - >> +eol + >> (+eol | cl::end_p) ; common = diff --git a/src/utils.cpp b/src/utils.cpp index bf8f064..945f560 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -244,10 +244,6 @@ namespace quickbook { namespace detail return 1; } - // ensure that we have enough trailing newlines to eliminate - // the need to check for end of file in the grammar. - storage.push_back('\n'); - storage.push_back('\n'); return 0; } diff --git a/src/utils.hpp b/src/utils.hpp index 878ba91..bb2e5e3 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -46,8 +46,6 @@ namespace detail std::string escape_uri(std::string uri); - // load file into memory with extra trailing newlines to eliminate - // the need to check for end of file in the grammar. int load(fs::path const& filename, std::string& storage); // given a file extension, return the type of the source file diff --git a/test/templates.gold b/test/templates.gold index 1ddb72d..1c220ad 100644 --- a/test/templates.gold +++ b/test/templates.gold @@ -107,4 +107,22 @@ phrase template. End phrase template.
+
+ <link linkend="templates.block_markup">Block Markup</link> + + + + a + + + + + b + + + + + +int main() {} +
diff --git a/test/templates.quickbook b/test/templates.quickbook index 586caf6..07caa8f 100644 --- a/test/templates.quickbook +++ b/test/templates.quickbook @@ -165,4 +165,22 @@ End block template. [phrase [block Hello!]] [phrase [phrase Hello!]] -[endsect] \ No newline at end of file +[endsect] + +[/----------------------------------- Block Markup ] + +[section Block Markup] + +[template list +* a +* b] + +[template horizontal +----] + +[template codeblock + int main() {}] + +[list][horizontal][codeblock] + +[endsect] From 6500170f496fe601e1d6ad15d05d79ac57aea7e1 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 16 Mar 2011 09:12:01 +0000 Subject: [PATCH 24/24] Pass-thru comments. [SVN r70018] --- src/code_snippet.cpp | 36 ++++++++++++++++++++++++++++--- test/Jamfile.v2 | 1 + test/snippets/Jamfile.v2 | 15 +++++++++++++ test/snippets/pass_thru.cpp | 14 ++++++++++++ test/snippets/pass_thru.gold | 21 ++++++++++++++++++ test/snippets/pass_thru.py | 7 ++++++ test/snippets/pass_thru.quickbook | 10 +++++++++ test/snippets/pass_thru.xml | 21 ++++++++++++++++++ 8 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 test/snippets/Jamfile.v2 create mode 100644 test/snippets/pass_thru.cpp create mode 100644 test/snippets/pass_thru.gold create mode 100644 test/snippets/pass_thru.py create mode 100644 test/snippets/pass_thru.quickbook create mode 100644 test/snippets/pass_thru.xml diff --git a/src/code_snippet.cpp b/src/code_snippet.cpp index 82e7129..ae1f43c 100644 --- a/src/code_snippet.cpp +++ b/src/code_snippet.cpp @@ -99,6 +99,7 @@ namespace quickbook start_snippet [boost::bind(&actions_type::start_snippet, &actions, _1, _2)] | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)] | escaped_comment + | pass_thru_comment | ignore | cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)] ; @@ -142,11 +143,25 @@ namespace quickbook "\"\"\"" ) ; + + // Note: Unlike escaped_comment and ignore, this doesn't + // swallow preceeding whitespace. + pass_thru_comment + = "#=" + >> ( *(cl::anychar_p - cl::eol_p) + >> (cl::eol_p | cl::end_p) + ) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)] + | cl::confix_p( + "\"\"\"=", + (*cl::anychar_p) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)], + "\"\"\"" + ) + ; } cl::rule start_, identifier, code_elements, start_snippet, end_snippet, - escaped_comment, ignore; + escaped_comment, pass_thru_comment, ignore; cl::rule const& start() const { return start_; } @@ -182,6 +197,7 @@ namespace quickbook | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)] | escaped_comment | ignore + | pass_thru_comment | line_callout | inline_callout | cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)] @@ -249,11 +265,25 @@ namespace quickbook "*/" ) ; + + // Note: Unlike escaped_comment and ignore, this doesn't + // swallow preceeding whitespace. + pass_thru_comment + = "//=" + >> ( *(cl::anychar_p - cl::eol_p) + >> (cl::eol_p | cl::end_p) + ) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)] + | cl::confix_p( + "/*`", + (*cl::anychar_p) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)], + "*/" + ) + ; } cl::rule start_, identifier, code_elements, start_snippet, end_snippet, - escaped_comment, inline_callout, line_callout, ignore; + escaped_comment, pass_thru_comment, inline_callout, line_callout, ignore; cl::rule const& start() const { return start_; } @@ -334,7 +364,7 @@ namespace quickbook void code_snippet_actions::pass_thru(iterator first, iterator last) { if(snippet_stack.empty()) return; - code += *first; + code.append(first, last); } void code_snippet_actions::pass_thru_char(char c) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1a72763..3c3ec64 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -15,6 +15,7 @@ project test build-project doc-info ; build-project command-line ; +build-project snippets ; import quickbook-testing : quickbook-test quickbook-error-test ; diff --git a/test/snippets/Jamfile.v2 b/test/snippets/Jamfile.v2 new file mode 100644 index 0000000..89f72dd --- /dev/null +++ b/test/snippets/Jamfile.v2 @@ -0,0 +1,15 @@ +# +# Copyright (c) 2011 Daniel James +# +# 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) +# + +project quickook/tests/snippets ; + +import quickbook-testing : quickbook-test quickbook-error-test ; + +test-suite quickbook.test : + [ quickbook-test pass_thru ] + ; diff --git a/test/snippets/pass_thru.cpp b/test/snippets/pass_thru.cpp new file mode 100644 index 0000000..f85522c --- /dev/null +++ b/test/snippets/pass_thru.cpp @@ -0,0 +1,14 @@ +//[foo_cpp +struct Foo{ + + Foo()//=; +//<- + : x( 10 ) + {} +//-> + +//<- + int x; +//-> +}; +//] \ No newline at end of file diff --git a/test/snippets/pass_thru.gold b/test/snippets/pass_thru.gold new file mode 100644 index 0000000..61b5b00 --- /dev/null +++ b/test/snippets/pass_thru.gold @@ -0,0 +1,21 @@ + + +
+ Pass thru test + + +struct Foo{ + + Foo(); + +}; + + + + +def foo: + print('foo') + + +
diff --git a/test/snippets/pass_thru.py b/test/snippets/pass_thru.py new file mode 100644 index 0000000..d8e847d --- /dev/null +++ b/test/snippets/pass_thru.py @@ -0,0 +1,7 @@ +#[foo_py +def foo: + #=print('foo') + #<- + print('bar') + #-> +#] \ No newline at end of file diff --git a/test/snippets/pass_thru.quickbook b/test/snippets/pass_thru.quickbook new file mode 100644 index 0000000..2f46cd5 --- /dev/null +++ b/test/snippets/pass_thru.quickbook @@ -0,0 +1,10 @@ +[article Pass thru test +[quickbook 1.5] +] + +[import pass_thru.cpp] +[import pass_thru.py] + +[foo_cpp] + +[foo_py] \ No newline at end of file diff --git a/test/snippets/pass_thru.xml b/test/snippets/pass_thru.xml new file mode 100644 index 0000000..c647d11 --- /dev/null +++ b/test/snippets/pass_thru.xml @@ -0,0 +1,21 @@ + + +
+ Pass thru test + + +struct Foo{ + + Foo()//=; + +}; + + + + +def foo: + #= print('foo') + + +