Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r70185 - in trunk/tools/quickbook: . src test
From: dnljms_at_[hidden]
Date: 2011-03-19 10:43:15


Author: danieljames
Date: 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
New Revision: 70185
URL: http://svn.boost.org/trac/boost/changeset/70185

Log:
Quickbook: merge further 'value' development.

Added:
   trunk/tools/quickbook/src/block_tags.hpp
      - copied unchanged from r69178, /branches/quickbook-filenames/tools/quickbook/src/block_tags.hpp
   trunk/tools/quickbook/src/phrase_tags.hpp
      - copied unchanged from r69178, /branches/quickbook-filenames/tools/quickbook/src/phrase_tags.hpp
   trunk/tools/quickbook/src/scoped.hpp
      - copied unchanged from r69178, /branches/quickbook-filenames/tools/quickbook/src/scoped.hpp
Removed:
   trunk/tools/quickbook/src/table_tags.hpp
Properties modified:
   trunk/tools/quickbook/ (props changed)
Text files modified:
   trunk/tools/quickbook/src/actions.cpp | 693 ++++++++++++++++++++++-----------------
   trunk/tools/quickbook/src/actions.hpp | 478 ++-------------------------
   trunk/tools/quickbook/src/actions_class.cpp | 99 -----
   trunk/tools/quickbook/src/actions_class.hpp | 98 ----
   trunk/tools/quickbook/src/block_element_grammar.cpp | 177 ++++-----
   trunk/tools/quickbook/src/doc_info_actions.cpp | 112 ++++--
   trunk/tools/quickbook/src/doc_info_grammar.cpp | 70 +--
   trunk/tools/quickbook/src/grammar_impl.hpp | 9
   trunk/tools/quickbook/src/main_grammar.cpp | 189 ++++++----
   trunk/tools/quickbook/src/markups.cpp | 53 +++
   trunk/tools/quickbook/src/markups.hpp | 17
   trunk/tools/quickbook/src/parsers.hpp | 166 +++++++-
   trunk/tools/quickbook/src/phrase_element_grammar.cpp | 212 ++---------
   trunk/tools/quickbook/src/quickbook.cpp | 3
   trunk/tools/quickbook/src/quickbook.hpp | 8
   trunk/tools/quickbook/src/utils.hpp | 13
   trunk/tools/quickbook/src/value_tags.hpp | 4
   trunk/tools/quickbook/src/values.cpp | 19
   trunk/tools/quickbook/src/values.hpp | 37 +
   trunk/tools/quickbook/src/values_parse.hpp | 252 ++-----------
   trunk/tools/quickbook/test/link.quickbook | 2
   trunk/tools/quickbook/test/list_test.gold | 29 +
   trunk/tools/quickbook/test/list_test.quickbook | 7
   23 files changed, 1132 insertions(+), 1615 deletions(-)

Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp (original)
+++ trunk/tools/quickbook/src/actions.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -25,7 +25,8 @@
 #include "grammar.hpp"
 #include "input_path.hpp"
 #include "template_tags.hpp"
-#include "table_tags.hpp"
+#include "block_tags.hpp"
+#include "phrase_tags.hpp"
 
 namespace quickbook
 {
@@ -52,6 +53,103 @@
         }
     }
 
+ void 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);
+ void block_action(quickbook::actions&, value);
+ void macro_definition_action(quickbook::actions&, value);
+ void template_body_action(quickbook::actions&, value);
+ void variable_list_action(quickbook::actions&, value);
+ void table_action(quickbook::actions&, value);
+ void xinclude_action(quickbook::actions&, value);
+ void import_action(quickbook::actions&, value);
+ void include_action(quickbook::actions&, value);
+ void image_action(quickbook::actions&, value);
+ void anchor_action(quickbook::actions&, value);
+ void link_action(quickbook::actions&, value);
+ void phrase_action_(quickbook::actions&, value);
+ void source_mode_action(quickbook::actions&, value);
+
+ void element_action::operator()(iterator first, iterator) const
+ {
+ value_consumer values = actions.values.get();
+ if(!values.is()) return;
+ value v = values.consume();
+ if(values.is()) return;
+
+ switch(v.get_tag())
+ {
+ case block_tags::list:
+ return list_action(actions, v);
+ case block_tags::generic_heading:
+ case block_tags::heading1:
+ case block_tags::heading2:
+ case block_tags::heading3:
+ case block_tags::heading4:
+ case block_tags::heading5:
+ case block_tags::heading6:
+ return header_action(actions, v);
+ case block_tags::begin_section:
+ return begin_section_action(actions, v);
+ case block_tags::end_section:
+ return end_section_action(actions, v, first.get_position());
+ case block_tags::blurb:
+ case block_tags::preformatted:
+ case block_tags::blockquote:
+ case block_tags::warning:
+ case block_tags::caution:
+ case block_tags::important:
+ case block_tags::note:
+ case block_tags::tip:
+ return block_action(actions,v);
+ case block_tags::macro_definition:
+ return macro_definition_action(actions,v);
+ case block_tags::template_definition:
+ return template_body_action(actions,v);
+ case block_tags::variable_list:
+ return variable_list_action(actions, v);
+ case block_tags::table:
+ return table_action(actions, v);
+ case block_tags::xinclude:
+ return xinclude_action(actions, v);
+ case block_tags::import:
+ return import_action(actions, v);
+ case block_tags::include:
+ return include_action(actions, v);
+ case phrase_tags::image:
+ return image_action(actions, v);
+ case phrase_tags::anchor:
+ return anchor_action(actions, v);
+ case phrase_tags::url:
+ case phrase_tags::link:
+ case phrase_tags::funcref:
+ case phrase_tags::classref:
+ case phrase_tags::memberref:
+ case phrase_tags::enumref:
+ case phrase_tags::macroref:
+ case phrase_tags::headerref:
+ case phrase_tags::conceptref:
+ case phrase_tags::globalref:
+ return link_action(actions, v);
+ case phrase_tags::bold:
+ case phrase_tags::italic:
+ case phrase_tags::underline:
+ case phrase_tags::teletype:
+ case phrase_tags::strikethrough:
+ case phrase_tags::quote:
+ case phrase_tags::replaceable:
+ case phrase_tags::footnote:
+ return phrase_action_(actions, v);
+ case source_mode_tags::cpp:
+ case source_mode_tags::python:
+ case source_mode_tags::teletype:
+ return source_mode_action(actions, v);
+ default:
+ break;
+ }
+ }
+
     // Handles line-breaks (DEPRECATED!!!)
     void break_action::operator()(iterator first, iterator) const
     {
@@ -101,47 +199,44 @@
         ++actions.error_count;
     }
 
- void tagged_action::operator()(iterator, iterator) const
+ void block_action(quickbook::actions& actions, value block)
     {
- if(!actions.output_pre(out)) return;
+ if(!actions.output_pre(actions.out)) return;
+ detail::markup markup = detail::markups[block.get_tag()];
 
- value_consumer values = actions.values.get();
- out << pre << values.consume().get_boostbook() << post;
+ value_consumer values = block;
+ actions.out << markup.pre << values.consume().get_boostbook() << markup.post;
+ assert(!values.is());
     }
 
- void phrase_action::operator()() const
+ void phrase_action_(quickbook::actions& actions, value phrase)
     {
- if(!actions.output_pre(phrase)) return;
+ if(!actions.output_pre(actions.phrase)) return;
+ detail::markup markup = detail::markups[phrase.get_tag()];
 
- std::string str;
- phrase.swap(str);
- out << pre << str << post;
+ value_consumer values = phrase;
+ actions.phrase << markup.pre << values.consume().get_boostbook() << markup.post;
+ assert(!values.is());
     }
 
- void implicit_paragraph_action::operator()() const
+ void paragraph_action::operator()() const
     {
         if(actions.suppress) return;
     
         std::string str;
- phrase.swap(str);
-
- // TODO: Use spirit to do this?
+ actions.phrase.swap(str);
 
         std::string::const_iterator
             pos = str.begin(),
             end = str.end();
 
- while(pos != end && (
- *pos == ' ' || *pos == '\t' || *pos == '\n' || *pos == '\r'))
- {
- ++pos;
- }
+ while(pos != end && cl::space_p.test(*pos)) ++pos;
 
         if(pos != end) {
- out << pre << str;
- // TODO: Is this right place?
- actions.output_pre(out);
- out << post;
+ detail::markup markup = detail::markups[block_tags::paragraph];
+ actions.out << markup.pre << str;
+ actions.output_pre(actions.out);
+ actions.out << markup.post;
         }
     }
     
@@ -159,70 +254,61 @@
         }
     }
 
- void header_action::operator()(iterator first, iterator last) const
+ void header_action(quickbook::actions& actions, value heading_list)
     {
         if(actions.suppress) return;
 
- std::string str;
- phrase.swap(str);
-
- value_consumer values = actions.values.get();
+ value_consumer values = heading_list;
+
+ 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());
+
+ int level;
+
+ if (generic)
+ {
+ level = actions.section_level + 2;
+ // section_level is zero-based. We need to use a
+ // one-based heading which is one greater
+ // than the current. Thus: section_level + 2.
+ if (level > 6 ) // The max is h6, clip it if it goes
+ level = 6; // further than that
+ }
+ else
+ {
+ level = heading_list.get_tag() - block_tags::heading1 + 1;
+ }
 
         std::string anchor;
+ std::string linkend;
 
- if (qbk_version_n < 103) // version 1.2 and below
+ if (!generic && qbk_version_n < 103) // version 1.2 and below
         {
- anchor = section_id + '.' +
- detail::make_identifier(str.begin(), str.end());
+ anchor = actions.section_id + '.' +
+ detail::make_identifier(content.get_boostbook());
         }
         else
         {
             std::string id =
- values.is(general_tags::element_id) ? values.consume().get_quickbook() :
- qbk_version_n >= 106 ? detail::make_identifier(first, last) :
- detail::make_identifier(str.begin(), str.end());
+ !element_id.is_empty() ?
+ element_id.get_quickbook() :
+ detail::make_identifier(
+ qbk_version_n >= 106 ?
+ content.get_quickbook() :
+ content.get_boostbook()
+ );
 
- anchor =
- fully_qualified_id(library_id, qualified_section_id, id);
+ linkend = anchor =
+ fully_qualified_id(actions.doc_id, actions.qualified_section_id, id);
         }
 
- actions.output_pre(out);
- actions.anchors.swap(actions.saved_anchors);
         actions.anchors.push_back(anchor);
- actions.output_pre(out);
+ actions.output_pre(actions.out);
         
- std::string linkend = qbk_version_n < 103 ? std::string() : anchor;
- write_bridgehead(out, level, str, anchor + "-heading", linkend);
- }
-
- void generic_header_action::operator()(iterator first, iterator last) const
- {
- if(actions.suppress) return;
-
- int level_ = section_level + 2; // section_level is zero-based. We need to use a
- // one-based heading which is one greater
- // than the current. Thus: section_level + 2.
- if (level_ > 6) // The max is h6, clip it if it goes
- level_ = 6; // further than that
- std::string str;
- phrase.swap(str);
-
- value_consumer values = actions.values.get();
-
- std::string id =
- values.is(general_tags::element_id) ? values.consume().get_quickbook() :
- qbk_version_n >= 106 ? detail::make_identifier(first, last) :
- detail::make_identifier(str.begin(), str.end());
-
- std::string anchor =
- fully_qualified_id(library_id, qualified_section_id, id);
-
- actions.output_pre(out);
- actions.anchors.swap(actions.saved_anchors);
- actions.anchors.push_back(anchor);
- actions.output_pre(out);
-
- write_bridgehead(out, level_, str, anchor + "-heading", anchor);
+ write_bridgehead(actions.out, level,
+ content.get_boostbook(), anchor + "-heading", linkend);
     }
 
     void simple_phrase_action::operator()(iterator first, iterator last) const
@@ -243,116 +329,114 @@
         out << post;
     }
 
- void cond_phrase_action_pre::operator()(iterator first, iterator last) const
+ void cond_phrase_push::start()
     {
- std::string str(first, last);
- condition = find(macro, str.c_str());
- }
-
- cond_phrase_push::cond_phrase_push(quickbook::actions& actions)
- : actions(actions)
- , saved_suppress(actions.suppress)
- {
- actions.suppress = actions.suppress || !actions.condition;
+ saved_suppress = actions.suppress;
+
+ value_consumer values = actions.values.get();
+ bool condition = find(actions.macro,
+ values.consume().get_quickbook().c_str());
+
+ actions.suppress = actions.suppress || !condition;
     }
     
- cond_phrase_push::~cond_phrase_push()
+ void cond_phrase_push::cleanup()
     {
         actions.suppress = saved_suppress;
     }
 
- void list_action::operator()(iterator first, iterator last) const
- {
- if(actions.suppress) return;
-
- BOOST_ASSERT(!list_marks.empty()); // there must be at least one item in the stack
- out << list_buffer.str();
- list_buffer.clear();
-
- while (!list_marks.empty())
+ namespace {
+ int indent_length(std::string const& indent)
         {
- char mark = list_marks.top().first;
- list_marks.pop();
- out << std::string((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
- if (list_marks.size() >= 1)
- out << "</listitem>";
+ int length = 0;
+ for(std::string::const_iterator
+ first = indent.begin(), end = indent.end(); first != end; ++first)
+ {
+ switch(*first) {
+ case ' ': ++length; break;
+ // hardcoded tab to 4 for now
+ case '\t': length = ((length + 4) / 4) * 4; break;
+ default: BOOST_ASSERT(false);
+ }
+ }
+
+ return length;
         }
-
- list_indent = -1; // reset
     }
 
- void list_format_action::operator()(iterator first, iterator last) const
+ void list_action(quickbook::actions& actions, value list)
     {
- if(!actions.output_pre(out)) return;
-
- int new_indent = 0;
- while (first != last && (*first == ' ' || *first == '\t'))
- {
- char mark = *first++;
- if (mark == ' ')
- {
- ++new_indent;
- }
- else // must be a tab
- {
- BOOST_ASSERT(mark == '\t');
- // hardcoded tab to 4 for now
- new_indent = ((new_indent + 4) / 4) * 4;
- }
- }
+ if(actions.suppress) return;
 
- char mark = *first;
- BOOST_ASSERT(mark == '#' || mark == '*'); // expecting a mark
+ typedef std::pair<char, int> mark_type;
+ std::stack<mark_type> list_marks;
+ int list_indent = -1;
 
- if (list_indent == -1) // the very start
+ BOOST_FOREACH(value_consumer values, list)
         {
- BOOST_ASSERT(new_indent == 0);
- }
+ int new_indent = indent_length(
+ 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());
 
- if (new_indent > list_indent)
- {
- list_indent = new_indent;
- list_marks.push(mark_type(mark, list_indent));
- if (list_marks.size() > 1)
+ char mark = mark_value.get_quickbook()[0];
+ assert(mark == '*' || mark == '#');
+
+ if(list_indent == -1) {
+ assert(new_indent == 0);
+ }
+
+ if(new_indent > list_indent)
             {
- // Make this new list a child of the previous list.
- // The previous listelem has already ended so we erase
- // "</listitem>" to accomodate this sub-list. We'll close
- // the listelem later.
+ list_indent = new_indent;
+ list_marks.push(mark_type(mark, list_indent));
 
- std::string str;
- out.swap(str);
- std::string::size_type pos = str.rfind("</listitem>");
- BOOST_ASSERT(pos <= str.size());
- str.erase(str.begin()+pos, str.end());
- out << str;
+ actions.out << ((mark == '#') ? "<orderedlist>\n" : "<itemizedlist>\n");
             }
- out << std::string((mark == '#') ? "<orderedlist>\n" : "<itemizedlist>\n");
- }
+ else if (new_indent < list_indent)
+ {
+ BOOST_ASSERT(!list_marks.empty());
+ list_indent = new_indent;
 
- else if (new_indent < list_indent)
- {
- BOOST_ASSERT(!list_marks.empty());
- list_indent = new_indent;
+ while (!list_marks.empty() && (list_indent < list_marks.top().second))
+ {
+ char mark = list_marks.top().first;
+ list_marks.pop();
+ actions.out << "</listitem>";
+ actions.out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
+ }
 
- while (!list_marks.empty() && (list_indent < list_marks.top().second))
+ actions.out << "</listitem>";
+ }
+ else
             {
- char mark = list_marks.top().first;
- list_marks.pop();
- out << std::string((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
- if (list_marks.size() >= 1)
- out << "</listitem>";
+ actions.out << "</listitem>";
+ }
+
+ if (mark != list_marks.top().first) // new_indent == list_indent
+ {
+ file_position const pos = mark_value.get_position();
+ detail::outerr(actions.filename, pos.line)
+ << "Illegal change of list style near column " << pos.column << ".\n";
+ detail::outwarn(actions.filename, pos.line)
+ << "Ignoring change of list style" << std::endl;
+ ++actions.error_count;
             }
+
+ actions.out << "<listitem>";
+ actions.out << "<simpara>\n";
+ actions.out << content;
+ actions.out << "\n</simpara>";
         }
 
- if (mark != list_marks.top().first) // new_indent == list_indent
+ assert(!list_marks.empty());
+ while (!list_marks.empty())
         {
- file_position const pos = first.get_position();
- detail::outerr(actions.filename, pos.line)
- << "Illegal change of list style near column " << pos.column << ".\n";
- detail::outwarn(actions.filename, pos.line)
- << "Ignoring change of list style" << std::endl;
- ++error_count;
+ char mark = list_marks.top().first;
+ list_marks.pop();
+ actions.out << "</listitem>";
+ actions.out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
         }
     }
 
@@ -382,10 +466,13 @@
         out << "</phrase>";
     }
 
- void anchor_action::operator()(iterator first, iterator last) const
+ void anchor_action(quickbook::actions& actions, value anchor)
     {
- if(!actions.suppress)
- actions.anchors.push_back(std::string(first, last));
+ if(actions.suppress) return;
+
+ value_consumer values = anchor;
+ actions.anchors.push_back(values.consume().get_quickbook());
+ assert(!values.is());
     }
 
     void do_macro_action::operator()(std::string const& str) const
@@ -433,6 +520,11 @@
         escape_actions.phrase.pop(); // restore the stream
     }
 
+ void source_mode_action(quickbook::actions& actions, value source_mode)
+ {
+ actions.source_mode = source_mode_tags::name(source_mode.get_tag());
+ }
+
     void code_action::operator()(iterator first, iterator last) const
     {
         if(!actions.output_pre(out)) return;
@@ -527,14 +619,14 @@
         }
     }
 
- void image_action::operator()(iterator, iterator) const
+ void image_action(quickbook::actions& actions, value image)
     {
- if(!actions.output_pre(phrase)) return;
+ if(!actions.output_pre(actions.phrase)) return;
 
         typedef std::map<std::string, value> attribute_map;
         attribute_map attributes;
 
- value_consumer values = actions.values.get();
+ value_consumer values = image;
         attributes["fileref"] = values.consume();
 
         BOOST_FOREACH(value pair_, values)
@@ -669,13 +761,13 @@
            }
         }
 
- phrase << "<inlinemediaobject>";
+ actions.phrase << "<inlinemediaobject>";
 
- phrase << "<imageobject><imagedata";
+ actions.phrase << "<imageobject><imagedata";
         
         BOOST_FOREACH(attribute_map::value_type const& attr, attributes)
         {
- phrase << " " << attr.first << "=\"";
+ actions.phrase << " " << attr.first << "=\"";
 
             std::string value = attr.second.get_quickbook();
             for(std::string::const_iterator
@@ -683,46 +775,44 @@
                 first != last; ++first)
             {
                 if (*first == '\\' && ++first == last) break;
- detail::print_char(*first, phrase.get());
+ detail::print_char(*first, actions.phrase.get());
             }
 
- phrase << "\"";
+ actions.phrase << "\"";
         }
 
- phrase << "></imagedata></imageobject>";
+ actions.phrase << "></imagedata></imageobject>";
 
         // Add a textobject containing the alt tag from earlier.
         // This will be used for the alt tag in html.
- phrase << "<textobject><phrase>";
- detail::print_string(alt_text, phrase.get());
- phrase << "</phrase></textobject>";
+ actions.phrase << "<textobject><phrase>";
+ detail::print_string(alt_text, actions.phrase.get());
+ actions.phrase << "</phrase></textobject>";
 
- phrase << "</inlinemediaobject>";
+ actions.phrase << "</inlinemediaobject>";
     }
 
- void macro_identifier_action::operator()(iterator first, iterator last) const
+ void macro_definition_action(quickbook::actions& actions, quickbook::value macro_definition)
     {
         if(actions.suppress) return;
- actions.macro_id.assign(first, last);
- actions.phrase.push(); // save the phrase
- }
 
- void macro_definition_action::operator()(iterator first, iterator last) const
- {
- if(actions.suppress) return;
+ value_consumer values = macro_definition;
+ std::string macro_id = values.consume().get_quickbook();
+ std::string phrase = values.consume().get_boostbook();
+ assert(!values.is());
+
         actions.copy_macros_for_write();
         actions.macro.add(
- actions.macro_id.begin()
- , actions.macro_id.end()
- , actions.phrase.str());
- actions.phrase.pop(); // restore the phrase
+ macro_id.begin()
+ , macro_id.end()
+ , phrase);
     }
 
- void template_body_action::operator()(iterator, iterator) const
+ void template_body_action(quickbook::actions& actions, quickbook::value template_definition)
     {
         if(actions.suppress) return;
 
- value_consumer values = actions.values.get();
+ value_consumer values = template_definition;
         std::string identifier = values.consume().get_quickbook();
 
         std::vector<std::string> template_values;
@@ -1149,7 +1239,7 @@
         }
 
         if(symbol->body.is_block || !block.empty()) {
- actions.inside_paragraph();
+ actions.paragraph(); // For paragraphs before the template call.
             actions.out << block;
             actions.phrase << phrase;
         }
@@ -1159,34 +1249,33 @@
         --actions.template_depth;
     }
 
- void link_action::operator()(iterator first, iterator last) const
+ void link_action(quickbook::actions& actions, value link)
     {
- if(!actions.output_pre(phrase)) return;
+ if(!actions.output_pre(actions.phrase)) return;
+ detail::markup markup = detail::markups[link.get_tag()];
 
- iterator save = first;
- phrase << tag;
- while (first != last)
- detail::print_char(*first++, phrase.get());
- phrase << "\">";
+ value_consumer values = link;
+ value dst = values.consume();
+ value content = values.consume();
+ assert(!values.is());
+
+ actions.phrase << markup.pre;
+ detail::print_string(dst.get_quickbook(), actions.phrase.get());
+ actions.phrase << "\">";
 
- // Yes, it is safe to dereference last here. When we
- // reach here, *last is certainly valid. We test if
- // *last == ']'. In which case, the url is the text.
- // Example: [@http://spirit.sourceforge.net/]
+ if (content.is_empty())
+ detail::print_string(dst.get_quickbook(), actions.phrase.get());
+ else
+ actions.phrase << content.get_boostbook();
 
- if (*last == ']')
- {
- first = save;
- while (first != last)
- detail::print_char(*first++, phrase.get());
- }
+ actions.phrase << markup.post;
     }
 
- void variablelist_action::operator()(iterator, iterator) const
+ void variable_list_action(quickbook::actions& actions, value variable_list)
     {
         if(actions.suppress) return;
 
- value_consumer values = actions.values.get();
+ value_consumer values = variable_list;
         std::string title = values.consume(table_tags::title).get_quickbook();
 
         actions.out << "<variablelist>\n";
@@ -1216,11 +1305,11 @@
         actions.out << "</variablelist>\n";
     }
 
- void table_action::operator()(iterator, iterator) const
+ void table_action(quickbook::actions& actions, value table)
     {
         if(actions.suppress) return;
 
- value_consumer values = actions.values.get();
+ value_consumer values = table;
 
         std::string element_id;
         if(values.is(general_tags::element_id))
@@ -1238,7 +1327,7 @@
             else if(has_title) {
                 table_id = fully_qualified_id(actions.doc_id,
                     actions.qualified_section_id,
- detail::make_identifier(title.begin(), title.end()));
+ detail::make_identifier(title));
             }
         }
 
@@ -1304,85 +1393,90 @@
         }
     }
 
- void begin_section_action::operator()(iterator first, iterator last) const
+ void begin_section_action(quickbook::actions& actions, value begin_section_list)
     {
         if(actions.suppress) return;
 
- value_consumer values = actions.values.get();
+ value_consumer values = begin_section_list;
 
- section_id = values.is(general_tags::element_id) ?
- values.consume().get_quickbook() :
- detail::make_identifier(first, last);
+ value element_id = values.optional_consume(general_tags::element_id);
+ value content = values.consume();
+ assert(!values.is());
+
+ actions.section_id = !element_id.is_empty() ?
+ element_id.get_quickbook() :
+ detail::make_identifier(content.get_quickbook());
 
- if (section_level != 0)
- qualified_section_id += '.';
+ if (actions.section_level != 0)
+ actions.qualified_section_id += '.';
         else
- BOOST_ASSERT(qualified_section_id.empty());
- qualified_section_id += section_id;
- ++section_level;
+ BOOST_ASSERT(actions.qualified_section_id.empty());
 
- actions.output_pre(out);
+ actions.qualified_section_id += actions.section_id;
+ ++actions.section_level;
+
+ actions::string_list saved_anchors;
+ saved_anchors.swap(actions.anchors);
+
+ actions.output_pre(actions.out);
 
         if (qbk_version_n < 103) // version 1.2 and below
         {
- out << "\n<section id=\""
- << library_id << "." << section_id << "\">\n";
+ actions.out << "\n<section id=\""
+ << actions.doc_id << "." << actions.section_id << "\">\n";
         }
         else // version 1.3 and above
         {
- out << "\n<section id=\"" << library_id
- << "." << qualified_section_id << "\">\n";
+ actions.out << "\n<section id=\"" << actions.doc_id
+ << "." << actions.qualified_section_id << "\">\n";
         }
- std::string str;
- phrase.swap(str);
 
- out << "<title>";
+ actions.out << "<title>";
 
- actions.anchors.swap(actions.saved_anchors);
- actions.output_pre(out);
+ actions.anchors.swap(saved_anchors);
+ actions.output_pre(actions.out);
 
         if (qbk_version_n < 103) // version 1.2 and below
         {
- out << str;
+ actions.out << content.get_boostbook();
         }
         else // version 1.3 and above
         {
- out << "<link linkend=\"" << library_id
- << "." << qualified_section_id << "\">"
- << str
+ actions.out << "<link linkend=\"" << actions.doc_id
+ << "." << actions.qualified_section_id << "\">"
+ << content.get_boostbook()
                 << "</link>"
                 ;
         }
         
- out << "</title>\n";
+ actions.out << "</title>\n";
     }
 
- void end_section_action::operator()(iterator first, iterator last) const
+ void end_section_action(quickbook::actions& actions, value end_section, file_position pos)
     {
- if(!actions.output_pre(out)) return;
+ if(!actions.output_pre(actions.out)) return;
 
- if (section_level <= min_section_level)
+ if (actions.section_level <= actions.min_section_level)
         {
- file_position const pos = first.get_position();
             detail::outerr(actions.filename, pos.line)
                 << "Mismatched [endsect] near column " << pos.column << ".\n";
- ++error_count;
+ ++actions.error_count;
             
             return;
         }
 
- --section_level;
- out << "</section>";
+ --actions.section_level;
+ actions.out << "</section>";
 
- if (section_level == 0)
+ if (actions.section_level == 0)
         {
- qualified_section_id.clear();
+ actions.qualified_section_id.clear();
         }
         else
         {
             std::string::size_type const n =
- qualified_section_id.find_last_of('.');
- qualified_section_id.erase(n, std::string::npos);
+ actions.qualified_section_id.find_last_of('.');
+ actions.qualified_section_id.erase(n, std::string::npos);
         }
     }
     
@@ -1410,14 +1504,13 @@
         return std::accumulate(file, path.end(), result, concat);
     }
 
- std::string check_path(iterator first, iterator last,
- quickbook::actions& actions)
+ std::string check_path(value const& path, quickbook::actions& actions)
     {
- std::string path_text(first, last);
+ std::string path_text = path.get_quickbook();
 
         if(path_text.find('\\') != std::string::npos)
         {
- detail::outwarn(actions.filename, first.get_position().line)
+ detail::outwarn(actions.filename, path.get_position().line)
                 << "Path isn't portable: "
                 << detail::utf8(path_text)
                 << std::endl;
@@ -1444,14 +1537,18 @@
         return path;
     }
 
- void xinclude_action::operator()(iterator first, iterator last) const
+ void xinclude_action(quickbook::actions& actions, value xinclude)
     {
- if(!actions.output_pre(out)) return;
+ if(!actions.output_pre(actions.out)) return;
 
- fs::path path = calculate_relative_path(check_path(first, last, actions), actions);
- out << "\n<xi:include href=\"";
- detail::print_string(detail::escape_uri(path.generic_string()), out.get());
- out << "\" />\n";
+ value_consumer values = xinclude;
+ fs::path path = calculate_relative_path(
+ check_path(values.consume(), actions), actions);
+ assert(!values.is());
+
+ actions.out << "\n<xi:include href=\"";
+ detail::print_string(detail::escape_uri(path.generic_string()), actions.out.get());
+ actions.out << "\" />\n";
     }
 
     namespace
@@ -1484,12 +1581,15 @@
         }
     }
 
- void import_action::operator()(iterator first, iterator last) const
+ void import_action(quickbook::actions& actions, value import)
     {
         if(!actions.output_pre(actions.out)) return;
 
+ value_consumer values = import;
         fs::path path = include_search(actions.filename.parent_path(),
- check_path(first, last, actions));
+ check_path(values.consume(), actions));
+ assert(!values.is());
+
         std::string ext = path.extension().generic_string();
         std::vector<template_symbol> storage;
         actions.error_count +=
@@ -1508,12 +1608,16 @@
         }
     }
 
- void include_action::operator()(iterator first, iterator last) const
+ void include_action(quickbook::actions& actions, value include)
     {
         if(!actions.output_pre(actions.out)) return;
 
+ value_consumer values = include;
+ value include_doc_id = values.optional_consume(general_tags::include_id);
         fs::path filein = include_search(actions.filename.parent_path(),
- check_path(first, last, actions));
+ check_path(values.consume(), actions));
+ assert(!values.is());
+
         std::string doc_type, doc_id;
 
         // swap the filenames
@@ -1543,20 +1647,22 @@
 
         // if an id is specified in this include (as in [include:id foo.qbk])
         // then use it as the doc_id.
- if (!actions.include_doc_id.empty())
- {
- actions.doc_id = actions.include_doc_id;
- actions.include_doc_id.clear();
- }
+ if (!include_doc_id.is_empty())
+ actions.doc_id = include_doc_id.get_quickbook();
 
         // update the __FILENAME__ macro
         *boost::spirit::classic::find(actions.macro, "__FILENAME__")
             = detail::path_to_generic(actions.filename);
 
+ // save values
+ actions.values.builder.save();
+
         // parse the file
         quickbook::parse_file(actions.filename.string().c_str(), actions, true);
 
         // restore the values
+ actions.values.builder.restore();
+
         std::swap(actions.filename, filein);
 
         actions.doc_type.swap(doc_type);
@@ -1578,50 +1684,31 @@
         //~ actions.templates = templates; $$$ fixme $$$
     }
 
- void phrase_to_string_action::operator()(iterator first, iterator last) const
- {
- if(!actions.output_pre(phrase)) return;
-
- out.clear();
- phrase.swap(out);
- }
-
- void phrase_to_docinfo_action::operator()(iterator first, iterator last) const
+ void phrase_to_docinfo_action_impl::operator()(iterator first, iterator last,
+ value::tag_type tag) const
     {
         if(!actions.output_pre(actions.phrase)) return;
 
         std::string encoded;
         actions.phrase.swap(encoded);
         actions.values.builder.insert(
- qbk_bbk_value(first, last, encoded, actions.values.builder.release_tag()));
+ qbk_bbk_value(first, last, encoded, tag));
     }
-
- void phrase_to_value_action::operator()(iterator first, iterator last) const
- {
- if(!actions.output_pre(actions.phrase)) return;
 
- std::string value;
- actions.phrase.swap(value);
- actions.values.builder.insert(
- bbk_value(value, actions.values.builder.release_tag()));
- }
-
- void inner_phrase_action_pre::operator()(iterator, iterator) const
+ void phrase_to_docinfo_action_impl::operator()(iterator first, iterator last) const
     {
- // TODO: Really?
- if(actions.suppress) return;
-
- actions.saved_anchors.clear();
- actions.saved_anchors.swap(actions.anchors);
+ return (*this)(first, last, value::default_tag);
     }
-
- void inner_phrase_action_post::operator()(iterator, iterator) const
+
+ void collector_to_value_action::operator()(iterator first, iterator last) const
     {
- if(actions.suppress) return;
+ if(!actions.output_pre(output)) return;
 
- actions.output_pre(actions.phrase);
+ std::string value;
+ output.swap(value);
+ actions.values.builder.insert(bbk_value(value, value::default_tag));
     }
-
+
     bool pre_output_action::operator()(collector& tgt) const
     {
         if(actions.suppress) return false;
@@ -1646,33 +1733,27 @@
         return (*this)(actions.out);
     }
 
- scoped_block_push::scoped_block_push(quickbook::actions& actions)
- : actions(actions)
+ void scoped_output_push::start()
     {
         actions.out.push();
         actions.phrase.push();
+ actions.anchors.swap(saved_anchors);
     }
     
- scoped_block_push::~scoped_block_push()
+ void scoped_output_push::cleanup()
     {
         actions.phrase.pop();
         actions.out.pop();
+ actions.anchors.swap(saved_anchors);
     }
 
- void scoped_block_push::success_impl()
- {
- actions.inside_paragraph();
- actions.values.builder.insert(
- bbk_value(actions.out.str(), actions.values.builder.release_tag()));
- }
-
- set_no_eols_scoped::set_no_eols_scoped(quickbook::actions& actions)
- : actions(actions), saved_no_eols(actions.no_eols)
+ void set_no_eols_scoped::start()
     {
+ saved_no_eols = actions.no_eols;
         actions.no_eols = false;
     }
 
- set_no_eols_scoped::~set_no_eols_scoped()
+ void set_no_eols_scoped::cleanup()
     {
         actions.no_eols = saved_no_eols;
     }

Modified: trunk/tools/quickbook/src/actions.hpp
==============================================================================
--- trunk/tools/quickbook/src/actions.hpp (original)
+++ trunk/tools/quickbook/src/actions.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -16,12 +16,15 @@
 #include <stack>
 #include <algorithm>
 #include <boost/filesystem/v3/operations.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
 #include <boost/foreach.hpp>
 #include <boost/tuple/tuple.hpp>
 #include "fwd.hpp"
 #include "collector.hpp"
 #include "template_stack.hpp"
 #include "utils.hpp"
+#include "values.hpp"
+#include "scoped.hpp"
 
 #ifdef BOOST_MSVC
 // disable copy/assignment could not be generated, unreferenced formal params
@@ -80,14 +83,6 @@
         actions& escape_actions,
         std::string const& source_mode);
 
- struct scoped_action_base
- {
- typedef quickbook::actions data_type;
-
- template <typename T> void success(T const&) {}
- void failure() {}
- };
-
     struct error_message_action
     {
         // Prints an error message to std::cerr
@@ -120,141 +115,28 @@
         quickbook::actions& actions;
     };
 
- struct tagged_action
+ struct element_action
     {
- tagged_action(
- collector& out,
- std::string const& pre,
- std::string const& post,
- quickbook::actions& actions)
- : out(out)
- , pre(pre)
- , post(post)
- , actions(actions) {}
+ element_action(quickbook::actions& actions)
+ : actions(actions) {}
 
         void operator()(iterator, iterator) const;
 
- collector& out;
- std::string pre;
- std::string post;
- quickbook::actions& actions;
- };
-
- struct phrase_action
- {
- // blurb, blockquote, preformatted, list_item,
- // unordered_list, ordered_list
-
- phrase_action(
- collector& out,
- collector& phrase,
- std::string const& pre,
- std::string const& post,
- quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , pre(pre)
- , post(post)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const { return (*this)(); }
- template <typename T>
- void operator()(T const&) const { return (*this)(); }
- void operator()() const;
-
- collector& out;
- collector& phrase;
- std::string pre;
- std::string post;
         quickbook::actions& actions;
     };
 
- struct implicit_paragraph_action
+ struct paragraph_action
     {
         // implicit paragraphs
         // doesn't output the paragraph if it's only whitespace.
 
- implicit_paragraph_action(
- collector& out,
- collector& phrase,
- std::string const& pre,
- std::string const& post,
+ paragraph_action(
             quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , pre(pre)
- , post(post)
- , actions(actions) {}
+ : actions(actions) {}
 
         void operator()() const;
         void operator()(iterator first, iterator last) const { (*this)(); }
 
- collector& out;
- collector& phrase;
- std::string pre;
- std::string post;
- quickbook::actions& actions;
- };
-
- struct header_action
- {
- // Handles paragraph, h1, h2, h3, h4, h5, h6,
-
- header_action(
- collector& out,
- collector& phrase,
- std::string const& library_id,
- std::string const& section_id,
- std::string const& qualified_section_id,
- int level,
- quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , library_id(library_id)
- , section_id(section_id)
- , qualified_section_id(qualified_section_id)
- , level(level)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- collector& phrase;
- std::string const& library_id;
- std::string const& section_id;
- std::string const& qualified_section_id;
- int level;
- quickbook::actions& actions;
- };
-
- struct generic_header_action
- {
- // Handles h
-
- generic_header_action(
- collector& out,
- collector& phrase,
- std::string const& library_id,
- std::string const& section_id,
- std::string const& qualified_section_id,
- int const& section_level,
- quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , library_id(library_id)
- , section_id(section_id)
- , qualified_section_id(qualified_section_id)
- , section_level(section_level)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- collector& phrase;
- std::string const& library_id;
- std::string const& section_id;
- std::string const& qualified_section_id;
- int const& section_level;
         quickbook::actions& actions;
     };
 
@@ -283,81 +165,16 @@
         quickbook::actions& actions;
     };
 
- struct cond_phrase_action_pre
- {
- // Handles conditional phrases
-
- cond_phrase_action_pre(
- bool& condition
- , string_symbols const& macro)
- : condition(condition)
- , macro(macro) {}
-
- void operator()(iterator first, iterator last) const;
-
- bool& condition;
- string_symbols const& macro;
- };
-
     struct cond_phrase_push : scoped_action_base
     {
- cond_phrase_push(quickbook::actions&);
- ~cond_phrase_push();
-
- quickbook::actions& actions;
- bool saved_suppress;
- };
-
- struct list_action
- {
- // Handles lists
+ cond_phrase_push(quickbook::actions& x)
+ : actions(x) {}
 
- typedef std::pair<char, int> mark_type;
- list_action(
- collector& out
- , collector& list_buffer
- , int& list_indent
- , std::stack<mark_type>& list_marks
- , quickbook::actions& actions)
- : out(out)
- , list_buffer(list_buffer)
- , list_indent(list_indent)
- , list_marks(list_marks)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
+ void start();
+ void cleanup();
 
- collector& out;
- collector& list_buffer;
- int& list_indent;
- std::stack<mark_type>& list_marks;
- quickbook::actions& actions;
- };
-
- struct list_format_action
- {
- // Handles list formatting and hierarchy
-
- typedef std::pair<char, int> mark_type;
- list_format_action(
- collector& out
- , int& list_indent
- , std::stack<mark_type>& list_marks
- , int& error_count
- , quickbook::actions& actions)
- : out(out)
- , list_indent(list_indent)
- , list_marks(list_marks)
- , error_count(error_count)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- int& list_indent;
- std::stack<mark_type>& list_marks;
- int& error_count;
         quickbook::actions& actions;
+ bool saved_suppress;
     };
 
     struct span
@@ -389,18 +206,6 @@
         quickbook::actions& actions;
     };
 
- struct anchor_action
- {
- // Handles anchors
-
- anchor_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- quickbook::actions& actions;
- };
-
     extern char const* quickbook_get_date;
     extern char const* quickbook_get_time;
 
@@ -500,22 +305,6 @@
         quickbook::actions& actions;
     };
 
- struct image_action
- {
- // Handles inline images
-
- image_action(
- collector& phrase
- , quickbook::actions& actions)
- : phrase(phrase)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& phrase;
- quickbook::actions& actions;
- };
-
     struct markup_action
     {
         // A generic markup action
@@ -594,42 +383,6 @@
         quickbook::actions& actions;
     };
 
- struct macro_identifier_action
- {
- // Handles macro identifiers
-
- macro_identifier_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- quickbook::actions& actions;
- };
-
- struct macro_definition_action
- {
- // Handles macro definitions
-
- macro_definition_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- quickbook::actions& actions;
- };
-
- struct template_body_action
- {
- // Handles template definitions
-
- template_body_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- quickbook::actions& actions;
- };
-
     struct do_template_action
     {
         // Handles template substitutions
@@ -642,104 +395,6 @@
         quickbook::actions& actions;
     };
 
- struct link_action
- {
- // Handles links (URL, XML refentry, function, class, member)
-
- link_action(
- collector& phrase,
- char const* tag,
- quickbook::actions& actions)
- : phrase(phrase), tag(tag), actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& phrase;
- char const* tag;
- quickbook::actions& actions;
- };
-
- struct variablelist_action
- {
- // Handles variable lists
-
- variablelist_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator, iterator) const;
-
- quickbook::actions& actions;
- };
-
- struct table_action
- {
- // Handles tables
-
- table_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator, iterator) const;
-
- quickbook::actions& actions;
- };
-
- struct begin_section_action
- {
- // Handles begin page
-
- begin_section_action(
- collector& out
- , collector& phrase
- , std::string& library_id
- , std::string& section_id
- , int& section_level
- , std::string& qualified_section_id
- , quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , library_id(library_id)
- , section_id(section_id)
- , section_level(section_level)
- , qualified_section_id(qualified_section_id)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- collector& phrase;
- std::string& library_id;
- std::string& section_id;
- int& section_level;
- std::string& qualified_section_id;
- quickbook::actions& actions;
- };
-
- struct end_section_action
- {
- end_section_action(
- collector& out
- , int& section_level
- , int& min_section_level
- , std::string& qualified_section_id
- , int& error_count
- , quickbook::actions& actions)
- : out(out)
- , section_level(section_level)
- , min_section_level(min_section_level)
- , qualified_section_id(qualified_section_id)
- , error_count(error_count)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- int& section_level;
- int& min_section_level;
- std::string& qualified_section_id;
- int& error_count;
- quickbook::actions& actions;
- };
-
    struct element_id_warning_action
    {
         element_id_warning_action(quickbook::actions& actions_)
@@ -750,95 +405,34 @@
         quickbook::actions& actions;
    };
 
- struct xinclude_action
- {
- // Handles XML includes
- xinclude_action(collector& out_, quickbook::actions& actions_)
- : out(out_), actions(actions_) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- quickbook::actions& actions;
- };
-
- struct include_action
- {
- // Handles QBK includes
-
- include_action(quickbook::actions& actions_)
- : actions(actions_) {}
-
- void operator()(iterator first, iterator last) const;
-
- quickbook::actions& actions;
- };
-
- struct import_action
- {
- // Handles import of source code files (e.g. *.cpp *.py)
- import_action(collector& out_, quickbook::actions& actions_)
- : out(out_), actions(actions_) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- quickbook::actions& actions;
- };
-
     void pre(collector& out, quickbook::actions& actions, bool ignore_docinfo = false);
     void post(collector& out, quickbook::actions& actions, bool ignore_docinfo = false);
 
- struct phrase_to_string_action
- {
- phrase_to_string_action(std::string& out, collector& phrase, quickbook::actions& actions)
- : out(out) , phrase(phrase), actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- std::string& out;
- collector& phrase;
- quickbook::actions& actions;
- };
-
- struct phrase_to_docinfo_action
+ struct phrase_to_docinfo_action_impl
     {
- phrase_to_docinfo_action(quickbook::actions& actions)
+ template <typename Arg1, typename Arg2, typename Arg3 = void>
+ struct result { typedef void type; };
+
+ phrase_to_docinfo_action_impl(quickbook::actions& actions)
             : actions(actions) {}
 
         void operator()(iterator first, iterator last) const;
+ void operator()(iterator first, iterator last, value::tag_type) const;
 
         quickbook::actions& actions;
     };
+
+ typedef phoenix::function<phrase_to_docinfo_action_impl> phrase_to_docinfo_action;
 
- struct phrase_to_value_action
+ struct collector_to_value_action
     {
- phrase_to_value_action(quickbook::actions& actions)
- : actions(actions) {}
+ collector_to_value_action(quickbook::actions& actions, collector& output)
+ : actions(actions), output(output) {}
 
         void operator()(iterator first, iterator last) const;
 
         quickbook::actions& actions;
- };
-
- struct inner_phrase_action_pre
- {
- inner_phrase_action_pre(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator, iterator) const;
-
- quickbook::actions& actions;
- };
-
- struct inner_phrase_action_post
- {
- inner_phrase_action_post(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator, iterator) const;
-
- quickbook::actions& actions;
+ collector& output;
     };
 
     struct pre_output_action
@@ -852,20 +446,25 @@
         quickbook::actions& actions;
     };
 
- struct scoped_block_push : scoped_action_base
+ struct scoped_output_push : scoped_action_base
     {
- scoped_block_push(quickbook::actions&);
- ~scoped_block_push();
- template <typename T> void success(T const&) { this->success_impl(); }
- void success_impl();
+ scoped_output_push(quickbook::actions& actions)
+ : actions(actions) {}
+
+ void start();
+ void cleanup();
 
         quickbook::actions& actions;
+ std::vector<std::string> saved_anchors;
     };
 
     struct set_no_eols_scoped : scoped_action_base
     {
- set_no_eols_scoped(quickbook::actions&);
- ~set_no_eols_scoped();
+ set_no_eols_scoped(quickbook::actions& actions)
+ : actions(actions) {}
+
+ void start();
+ void cleanup();
 
         quickbook::actions& actions;
         bool saved_no_eols;
@@ -877,4 +476,3 @@
 #endif
 
 #endif // BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP
-

Modified: trunk/tools/quickbook/src/actions_class.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions_class.cpp (original)
+++ trunk/tools/quickbook/src/actions_class.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -23,22 +23,25 @@
     actions::actions(fs::path const& filein_, fs::path const& outdir_, string_stream& out_)
         : grammar_()
 
- , values()
- , phrase_value(*this)
- , docinfo_value(*this)
-
     // header info
         , doc_type()
         , doc_title_qbk()
         , doc_id()
- , include_doc_id()
 
     // main output stream
         , out(out_)
 
     // auxilliary streams
         , phrase()
- , list_buffer()
+
+ // value actions
+ , values()
+ , phrase_value(*this, phrase)
+ , out_value(*this, out)
+ , docinfo_value(*this)
+ , scoped_cond_phrase(*this)
+ , scoped_output(*this)
+ , scoped_no_eols(*this)
 
     // state
         , filename(fs::absolute(filein_))
@@ -53,86 +56,26 @@
 
     // temporary or global state
         , macro_id()
- , list_marks()
- , list_indent(-1)
         , template_depth(0)
         , templates()
         , error_count(0)
         , anchors()
- , saved_anchors()
         , no_eols(true)
         , suppress(false)
         , warned_about_breaks(false)
 
     // actions
+ , element(*this)
         , error(*this)
- , scoped_block(*this)
         , code(out, phrase, *this)
         , code_block(phrase, phrase, *this)
         , inline_code(phrase, *this)
- , inside_paragraph(out, phrase, paragraph_pre, paragraph_post, *this)
- , h(out, phrase, doc_id, section_id, qualified_section_id, section_level, *this)
- , h1(out, phrase, doc_id, section_id, qualified_section_id, 1, *this)
- , h2(out, phrase, doc_id, section_id, qualified_section_id, 2, *this)
- , h3(out, phrase, doc_id, section_id, qualified_section_id, 3, *this)
- , h4(out, phrase, doc_id, section_id, qualified_section_id, 4, *this)
- , h5(out, phrase, doc_id, section_id, qualified_section_id, 5, *this)
- , h6(out, phrase, doc_id, section_id, qualified_section_id, 6, *this)
+ , paragraph(*this)
         , hr(out, hr_, *this)
- , blurb(out, blurb_pre, blurb_post, *this)
- , blockquote(out, blockquote_pre, blockquote_post, *this)
- , set_no_eols(*this)
- , preformatted(out, phrase, preformatted_pre, preformatted_post, *this)
- , warning(out, warning_pre, warning_post, *this)
- , caution(out, caution_pre, caution_post, *this)
- , important(out, important_pre, important_post, *this)
- , note(out, note_pre, note_post, *this)
- , tip(out, tip_pre, tip_post, *this)
         , space_char(phrase)
         , plain_char(phrase, *this)
         , raw_char(phrase, *this)
         , escape_unicode(phrase, *this)
- , image(phrase, *this)
- , cond_phrase_pre(condition, macro)
- , scoped_cond_phrase(*this)
-
- , list(out, list_buffer, list_indent, list_marks, *this)
- , list_format(list_buffer, list_indent, list_marks, error_count, *this)
- , list_item(list_buffer, phrase, list_item_pre, list_item_post, *this)
-
- , funcref_pre(phrase, funcref_pre_, *this)
- , funcref_post(phrase, funcref_post_, *this)
- , classref_pre(phrase, classref_pre_, *this)
- , classref_post(phrase, classref_post_, *this)
- , memberref_pre(phrase, memberref_pre_, *this)
- , memberref_post(phrase, memberref_post_, *this)
- , enumref_pre(phrase, enumref_pre_, *this)
- , enumref_post(phrase, enumref_post_, *this)
- , macroref_pre(phrase, macroref_pre_, *this)
- , macroref_post(phrase, macroref_post_, *this)
- , headerref_pre(phrase, headerref_pre_, *this)
- , headerref_post(phrase, headerref_post_, *this)
- , conceptref_pre(phrase, conceptref_pre_, *this)
- , conceptref_post(phrase, conceptref_post_, *this)
- , globalref_pre(phrase, globalref_pre_, *this)
- , globalref_post(phrase, globalref_post_, *this)
-
- , bold_pre(phrase, bold_pre_, *this)
- , bold_post(phrase, bold_post_, *this)
- , italic_pre(phrase, italic_pre_, *this)
- , italic_post(phrase, italic_post_, *this)
- , underline_pre(phrase, underline_pre_, *this)
- , underline_post(phrase, underline_post_, *this)
- , teletype_pre(phrase, teletype_pre_, *this)
- , teletype_post(phrase, teletype_post_, *this)
- , strikethrough_pre(phrase, strikethrough_pre_, *this)
- , strikethrough_post(phrase, strikethrough_post_, *this)
- , quote_pre(phrase, quote_pre_, *this)
- , quote_post(phrase, quote_post_, *this)
- , replaceable_pre(phrase, replaceable_pre_, *this)
- , replaceable_post(phrase, replaceable_post_, *this)
- , footnote_pre(phrase, footnote_pre_, *this)
- , footnote_post(phrase, footnote_post_, *this)
 
         , simple_bold(phrase, bold_pre_, bold_post_, macro, *this)
         , simple_italic(phrase, italic_pre_, italic_post_, macro, *this)
@@ -140,33 +83,15 @@
         , simple_teletype(phrase, teletype_pre_, teletype_post_, macro, *this)
         , simple_strikethrough(phrase, strikethrough_pre_, strikethrough_post_, macro, *this)
 
- , variablelist(*this)
-
         , break_(phrase, *this)
- , macro_identifier(*this)
- , macro_definition(*this)
         , do_macro(phrase, *this)
- , template_body(*this)
         , do_template(*this)
- , url_pre(phrase, url_pre_, *this)
- , url_post(phrase, url_post_, *this)
- , link_pre(phrase, link_pre_, *this)
- , link_post(phrase, link_post_, *this)
- , table(*this)
- , anchor(*this)
 
- , begin_section(out, phrase, doc_id, section_id, section_level, qualified_section_id, *this)
- , end_section(out, section_level, min_section_level, qualified_section_id, error_count, *this)
         , element_id_warning(*this)
- , xinclude(out, *this)
- , include(*this)
- , import(out, *this)
 
         , escape_pre(phrase, escape_pre_, *this)
         , escape_post(phrase, escape_post_, *this)
         
- , inner_phrase_pre(*this)
- , inner_phrase_post(*this)
         , output_pre(*this)
     {
         // turn off __FILENAME__ macro on debug mode = true
@@ -203,7 +128,6 @@
 
         out.push();
         phrase.push();
- list_buffer.push();
         templates.push();
         values.builder.save();
     }
@@ -244,7 +168,6 @@
 
         out.pop();
         phrase.pop();
- list_buffer.pop();
         templates.pop();
         values.builder.restore();
     }

Modified: trunk/tools/quickbook/src/actions_class.hpp
==============================================================================
--- trunk/tools/quickbook/src/actions_class.hpp (original)
+++ trunk/tools/quickbook/src/actions_class.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -35,25 +35,31 @@
 
         typedef std::vector<std::string> string_list;
 
- typedef std::pair<char, int> mark_type;
         static int const max_template_depth = 100;
 
- value_parser values;
- phrase_to_value_action phrase_value;
- phrase_to_docinfo_action docinfo_value;
-
     // header info
         std::string doc_type;
         std::string doc_title_qbk;
         std::string doc_id;
- std::string include_doc_id;
 
     // main output stream
         collector out;
 
     // auxilliary streams
         collector phrase;
- collector list_buffer;
+
+ // value actions
+ value_parser values;
+ collector_to_value_action phrase_value;
+ collector_to_value_action out_value;
+ phrase_to_docinfo_action docinfo_value;
+
+ scoped_parser<cond_phrase_push>
+ scoped_cond_phrase;
+ scoped_parser<scoped_output_push>
+ scoped_output;
+ scoped_parser<set_no_eols_scoped>
+ scoped_no_eols;
 
     // state
         fs::path filename;
@@ -83,14 +89,10 @@
 
     // temporary or global state
         std::string macro_id;
- std::stack<mark_type> list_marks;
- int list_indent;
- bool condition;
         int template_depth;
         template_stack templates;
         int error_count;
         string_list anchors;
- string_list saved_anchors;
         bool no_eols;
         bool suppress;
         bool warned_about_breaks;
@@ -104,69 +106,19 @@
     ///////////////////////////////////////////////////////////////////////////
     // actions
     ///////////////////////////////////////////////////////////////////////////
- error_action error;
 
- scoped_parser<scoped_block_push>
- scoped_block;
+ element_action element;
+ error_action error;
 
         code_action code;
         code_action code_block;
         inline_code_action inline_code;
- implicit_paragraph_action inside_paragraph;
- generic_header_action h;
- header_action h1, h2, h3, h4, h5, h6;
+ paragraph_action paragraph;
         markup_action hr;
- tagged_action blurb, blockquote;
- scoped_parser<set_no_eols_scoped>
- set_no_eols;
- phrase_action preformatted;
- tagged_action warning, caution, important, note, tip;
         space space_char;
         plain_char_action plain_char;
         raw_char_action raw_char;
         escape_unicode_action escape_unicode;
- image_action image;
- cond_phrase_action_pre cond_phrase_pre;
- scoped_parser<cond_phrase_push>
- scoped_cond_phrase;
-
- list_action list;
- list_format_action list_format;
- phrase_action list_item;
-
- link_action funcref_pre;
- markup_action funcref_post;
- link_action classref_pre;
- markup_action classref_post;
- link_action memberref_pre;
- markup_action memberref_post;
- link_action enumref_pre;
- markup_action enumref_post;
- link_action macroref_pre;
- markup_action macroref_post;
- link_action headerref_pre;
- markup_action headerref_post;
- link_action conceptref_pre;
- markup_action conceptref_post;
- link_action globalref_pre;
- markup_action globalref_post;
-
- markup_action bold_pre;
- markup_action bold_post;
- markup_action italic_pre;
- markup_action italic_post;
- markup_action underline_pre;
- markup_action underline_post;
- markup_action teletype_pre;
- markup_action teletype_post;
- markup_action strikethrough_pre;
- markup_action strikethrough_post;
- markup_action quote_pre;
- markup_action quote_post;
- markup_action replaceable_pre;
- markup_action replaceable_post;
- markup_action footnote_pre;
- markup_action footnote_post;
 
         simple_phrase_action simple_bold;
         simple_phrase_action simple_italic;
@@ -174,33 +126,15 @@
         simple_phrase_action simple_teletype;
         simple_phrase_action simple_strikethrough;
 
- variablelist_action variablelist;
-
         break_action break_;
- macro_identifier_action macro_identifier;
- macro_definition_action macro_definition;
         do_macro_action do_macro;
- template_body_action template_body;
         do_template_action do_template;
- link_action url_pre;
- markup_action url_post;
- link_action link_pre;
- markup_action link_post;
- table_action table;
- anchor_action anchor;
 
- begin_section_action begin_section;
- end_section_action end_section;
         element_id_warning_action element_id_warning;
- xinclude_action xinclude;
- include_action include;
- import_action import;
 
         markup_action escape_pre;
         markup_action escape_post;
 
- inner_phrase_action_pre inner_phrase_pre;
- inner_phrase_action_post inner_phrase_post;
         pre_output_action output_pre;
     };
 }

Modified: trunk/tools/quickbook/src/block_element_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/block_element_grammar.cpp (original)
+++ trunk/tools/quickbook/src/block_element_grammar.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -11,22 +11,23 @@
 #include "utils.hpp"
 #include "actions_class.hpp"
 #include "grammar_impl.hpp"
-#include "table_tags.hpp"
+#include "block_tags.hpp"
 #include "template_tags.hpp"
 #include <boost/spirit/include/classic_assign_actor.hpp>
 #include <boost/spirit/include/classic_if.hpp>
 #include <boost/spirit/include/classic_clear_actor.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_casts.hpp>
 
 namespace quickbook
 {
     namespace cl = boost::spirit::classic;
+ namespace ph = phoenix;
 
     struct block_element_grammar_local
     {
         cl::rule<scanner>
- h, h1, h2, h3, h4, h5, h6, blurb, blockquote,
- warning, caution, important, note, tip,
- inner_phrase, def_macro,
+ heading, inner_block, inner_phrase, def_macro,
                         table, table_row, variablelist,
                         varlistentry, varlistterm, varlistitem, table_cell,
                         preformatted, begin_section, end_section,
@@ -45,7 +46,7 @@
         local.element_id =
             !( ':'
>> ( cl::if_p(qbk_since(105u)) [space]
- >> (+(cl::alnum_p | '_')) [actions.values.entry(general_tags::element_id)]
+ >> (+(cl::alnum_p | '_')) [actions.values.entry(ph::arg1, ph::arg2, general_tags::element_id)]
                 | cl::eps_p [actions.element_id_warning]
                 )
             )
@@ -64,99 +65,69 @@
                 ;
 
         elements.add
- ("section", element_info(element_info::block, &local.begin_section))
- ("endsect", element_info(element_info::block, &local.end_section))
+ ("section", element_info(element_info::block, &local.begin_section, block_tags::begin_section))
+ ("endsect", element_info(element_info::block, &local.end_section, block_tags::end_section))
             ;
 
         local.begin_section =
                 space
>> local.element_id
>> space
- >> local.inner_phrase [actions.begin_section]
+ >> local.inner_phrase
             ;
 
         local.end_section =
- cl::eps_p [actions.end_section]
+ cl::eps_p
             ;
 
- elements.add
- ("heading", element_info(element_info::block, &local.h))
- ("h1", element_info(element_info::block, &local.h1))
- ("h2", element_info(element_info::block, &local.h2))
- ("h3", element_info(element_info::block, &local.h3))
- ("h4", element_info(element_info::block, &local.h4))
- ("h5", element_info(element_info::block, &local.h5))
- ("h6", element_info(element_info::block, &local.h6))
- ;
-
- local.h = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h];
- local.h1 = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h1];
- local.h2 = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h2];
- local.h3 = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h3];
- local.h4 = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h4];
- local.h5 = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h5];
- local.h6 = space >> local.element_id_1_6 >> space >> local.inner_phrase [actions.h6];
-
- elements.add("blurb", element_info(element_info::block, &local.blurb));
-
- local.blurb =
- inside_paragraph [actions.blurb]
+ local.heading
+ = space
+ >> local.element_id_1_6
+ >> space
+ >> local.inner_phrase
             ;
 
         elements.add
- (":", element_info(element_info::block, &local.blockquote))
- ;
-
- local.blockquote =
- blank >> inside_paragraph [actions.blockquote]
+ ("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))
             ;
 
         elements.add
- ("warning", element_info(element_info::block, &local.warning))
- ("caution", element_info(element_info::block, &local.caution))
- ("important", element_info(element_info::block, &local.important))
- ("note", element_info(element_info::block, &local.note))
- ("tip", element_info(element_info::block, &local.tip))
- ;
-
- local.warning =
- inside_paragraph [actions.warning]
- ;
-
- local.caution =
- inside_paragraph [actions.caution]
- ;
-
- local.important =
- inside_paragraph [actions.important]
- ;
-
- local.note =
- inside_paragraph [actions.note]
- ;
-
- local.tip =
- inside_paragraph [actions.tip]
+ ("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))
             ;
 
         elements.add
- ("pre", element_info(element_info::block, &local.preformatted))
+ ("pre", element_info(element_info::block, &local.preformatted, block_tags::preformatted))
             ;
 
         local.preformatted =
                 space
>> !eol
- >> actions.set_no_eols[phrase] [actions.preformatted]
+ >> actions.scoped_no_eols()
+ [ local.inner_phrase
+ ]
             ;
 
         elements.add
- ("def", element_info(element_info::block, &local.def_macro))
+ ("def", element_info(element_info::block, &local.def_macro, block_tags::macro_definition))
             ;
 
         local.def_macro =
                space
- >> macro_identifier [actions.macro_identifier]
- >> blank >> phrase [actions.macro_definition]
+ >> macro_identifier [actions.values.entry(ph::arg1, ph::arg2)]
+ >> blank
+ >> local.inner_phrase
             ;
 
         local.identifier =
@@ -168,26 +139,26 @@
             ;
 
         elements.add
- ("template", element_info(element_info::block, &local.template_))
+ ("template", element_info(element_info::block, &local.template_, block_tags::template_definition))
             ;
 
         local.template_ =
                space
- >> local.template_id [actions.values.reset][actions.values.entry]
- >> actions.values.scoped[
+ >> local.template_id [actions.values.entry(ph::arg1, ph::arg2)]
+ >> actions.values.list()[
             !(
                 space >> '['
>> *(
                         space
- >> local.template_id [actions.values.entry]
+ >> local.template_id [actions.values.entry(ph::arg1, ph::arg2)]
                     )
>> space >> ']'
             )
             ]
>> ( cl::eps_p(*cl::blank_p >> cl::eol_p)
- >> local.template_body [actions.values.entry(template_tags::block)]
- | local.template_body [actions.values.entry(template_tags::phrase)]
- ) [actions.template_body]
+ >> local.template_body [actions.values.entry(ph::arg1, ph::arg2, template_tags::block)]
+ | local.template_body [actions.values.entry(ph::arg1, ph::arg2, template_tags::phrase)]
+ )
             ;
 
         local.template_body =
@@ -197,21 +168,20 @@
             ;
 
         elements.add
- ("variablelist", element_info(element_info::block, &local.variablelist))
+ ("variablelist", element_info(element_info::block, &local.variablelist, block_tags::variable_list))
             ;
 
         local.variablelist =
                 (cl::eps_p(*cl::blank_p >> cl::eol_p) | space)
- >> (*(cl::anychar_p - eol)) [actions.values.entry(table_tags::title)]
+ >> (*(cl::anychar_p - eol)) [actions.values.entry(ph::arg1, ph::arg2, table_tags::title)]
>> (+eol) [actions.output_pre]
>> *local.varlistentry
- >> cl::eps_p [actions.variablelist]
             ;
 
         local.varlistentry =
             space
>> cl::ch_p('[')
- >> actions.values.scoped
+ >> actions.values.list()
             [
                 (
                     local.varlistterm
@@ -228,18 +198,17 @@
         local.varlistterm =
             space
>> cl::ch_p('[')
- >> actions.values.save
- [ phrase
- >> cl::ch_p(']')
+ >> local.inner_phrase
+ >> ( cl::ch_p(']')
>> space
                 | cl::eps_p [actions.error]
- ] [actions.phrase_value]
+ )
             ;
 
         local.varlistitem =
             space
>> cl::ch_p('[')
- >> ( inside_paragraph
+ >> ( local.inner_block
>> cl::ch_p(']')
>> space
                 | cl::eps_p [actions.error]
@@ -247,17 +216,16 @@
             ;
 
         elements.add
- ("table", element_info(element_info::block, &local.table))
+ ("table", element_info(element_info::block, &local.table, block_tags::table))
             ;
 
         local.table =
                 (cl::eps_p(*cl::blank_p >> cl::eol_p) | space)
>> local.element_id_1_5
>> (cl::eps_p(*cl::blank_p >> cl::eol_p) | space)
- >> (*(cl::anychar_p - eol)) [actions.values.entry(table_tags::title)]
+ >> (*(cl::anychar_p - eol)) [actions.values.entry(ph::arg1, ph::arg2, table_tags::title)]
>> (+eol) [actions.output_pre]
>> *local.table_row
- >> cl::eps_p [actions.table]
             ;
 
         local.table_row =
@@ -266,7 +234,9 @@
>>
             (
                 (
- actions.values.scoped(table_tags::row)[*local.table_cell]
+ actions.values.list(table_tags::row)
+ [ *local.table_cell
+ ]
>> cl::ch_p(']')
>> space
                 )
@@ -277,8 +247,8 @@
         local.table_cell =
                 space
>> cl::ch_p('[')
- >> ( cl::eps_p [actions.values.tag(table_tags::cell)]
- >> inside_paragraph
+ >> ( cl::eps_p
+ >> local.inner_block
>> cl::ch_p(']')
>> space
                 | cl::eps_p [actions.error]
@@ -286,21 +256,19 @@
             ;
 
         elements.add
- ("xinclude", element_info(element_info::conditional_or_block, &local.xinclude))
- ("import", element_info(element_info::conditional_or_block, &local.import))
- ("include", element_info(element_info::conditional_or_block, &local.include))
+ ("xinclude", element_info(element_info::conditional_or_block, &local.xinclude, block_tags::xinclude))
+ ("import", element_info(element_info::conditional_or_block, &local.import, block_tags::import))
+ ("include", element_info(element_info::conditional_or_block, &local.include, block_tags::include))
             ;
 
         local.xinclude =
                space
- >> (*(cl::anychar_p - phrase_end))
- [actions.xinclude]
+ >> (*(cl::anychar_p - phrase_end)) [actions.values.entry(ph::arg1, ph::arg2)]
             ;
 
         local.import =
                space
- >> (*(cl::anychar_p - phrase_end))
- [actions.import]
+ >> (*(cl::anychar_p - phrase_end)) [actions.values.entry(ph::arg1, ph::arg2)]
             ;
 
         local.include =
@@ -309,17 +277,24 @@
            !(
                 ':'
>> (*((cl::alnum_p | '_') - cl::space_p))
- [cl::assign_a(actions.include_doc_id)]
+ [actions.values.entry(ph::arg1, ph::arg2, general_tags::include_id)]
>> space
             )
- >> (*(cl::anychar_p - phrase_end))
- [actions.include]
+ >> (*(cl::anychar_p - phrase_end)) [actions.values.entry(ph::arg1, ph::arg2)]
+ ;
+
+ local.inner_block =
+ actions.scoped_output()
+ [
+ inside_paragraph [actions.out_value]
+ ]
             ;
 
         local.inner_phrase =
- cl::eps_p [actions.inner_phrase_pre]
- >> phrase
- >> cl::eps_p [actions.inner_phrase_post]
+ actions.scoped_output()
+ [
+ phrase [actions.docinfo_value(ph::arg1, ph::arg2)]
+ ]
             ;
     }
 }

Modified: trunk/tools/quickbook/src/doc_info_actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/doc_info_actions.cpp (original)
+++ trunk/tools/quickbook/src/doc_info_actions.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -43,6 +43,20 @@
         return p;
     }
 
+ value consume_last_single(value_consumer& c, value::tag_type tag,
+ std::vector<std::string>* duplicates)
+ {
+ value l = consume_last(c, tag, duplicates);
+ if(l.is_empty()) return l;
+
+ assert(l.is_list());
+ value_consumer c2 = l;
+ value p = c2.consume();
+ assert(!c2.is());
+
+ return p;
+ }
+
     std::vector<value> consume_multiple(value_consumer& c, value::tag_type tag)
     {
         std::vector<value> values;
@@ -60,6 +74,11 @@
         // *before* anything else.
 
         value_consumer values = actions.values.get();
+
+ // Skip over invalid attributes
+
+ while (values.is(value::default_tag)) values.consume();
+
         std::vector<std::string> duplicates;
 
         value doc_title;
@@ -70,17 +89,22 @@
             actions.doc_title_qbk = doc_title.get_quickbook();
         }
 
- value id = consume_last(values, doc_info_attributes::id, &duplicates);
- value dirname = consume_last(values, doc_info_attributes::dirname, &duplicates);
- value last_revision = consume_last(values, doc_info_attributes::last_revision, &duplicates);
- value purpose = consume_last(values, doc_info_attributes::purpose, &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);
+ value purpose = consume_last_single(values, doc_info_attributes::purpose, &duplicates);
         std::vector<value> categories = consume_multiple(values, doc_info_attributes::category);
- value lang = consume_last(values, doc_info_attributes::lang, &duplicates);
- value version = consume_last(values, doc_info_attributes::version, &duplicates);
+ value lang = consume_last_single(values, doc_info_attributes::lang, &duplicates);
+ value version = consume_last_single(values, doc_info_attributes::version, &duplicates);
         std::vector<value> authors = consume_multiple(values, doc_info_attributes::authors);
         std::vector<value> copyrights = consume_multiple(values, doc_info_attributes::copyright);
- value license = consume_last(values, doc_info_attributes::license, &duplicates);
+ value license = consume_last_single(values, doc_info_attributes::license, &duplicates);
         std::vector<value> biblioids = consume_multiple(values, doc_info_attributes::biblioid);
+
+ // Skip over source-mode tags (already dealt with)
+
+ while (values.is(doc_info_attributes::source_mode)) values.consume();
+
 
         BOOST_ASSERT(!values.is());
 
@@ -98,8 +122,7 @@
             actions.doc_id = id.get_quickbook();
 
         if (actions.doc_id.empty())
- actions.doc_id = detail::make_identifier(
- actions.doc_title_qbk.begin(),actions.doc_title_qbk.end());
+ actions.doc_id = detail::make_identifier(actions.doc_title_qbk);
         
         if (dirname.is_empty() && actions.doc_type == "library") {
             if (!id.is_empty()) {
@@ -110,7 +133,6 @@
             }
         }
 
-
         if (last_revision.is_empty())
         {
             // default value for last-revision is now
@@ -256,40 +278,43 @@
 
         BOOST_FOREACH(value_consumer copyright, copyrights)
         {
- tmp << "\n" << " <copyright>\n";
-
- while(copyright.is(doc_info_tags::copyright_year))
+ while(copyright.is())
             {
- int year_start =
- boost::lexical_cast<int>(copyright.consume().get_quickbook());
- int year_end =
- copyright.is(doc_info_tags::copyright_year_end) ?
- boost::lexical_cast<int>(copyright.consume().get_quickbook()) :
- year_start;
-
- if (year_end < year_start) {
- ++actions.error_count;
-
- detail::outerr(actions.filename,
- copyright.begin()->get_position().line)
- << "Invalid year range: "
- << year_start
- << "-"
- << year_end
- << "."
- << std::endl;
+ tmp << "\n" << " <copyright>\n";
+
+ while(copyright.is(doc_info_tags::copyright_year))
+ {
+ int year_start =
+ boost::lexical_cast<int>(copyright.consume().get_quickbook());
+ int year_end =
+ copyright.is(doc_info_tags::copyright_year_end) ?
+ boost::lexical_cast<int>(copyright.consume().get_quickbook()) :
+ year_start;
+
+ if (year_end < year_start) {
+ ++actions.error_count;
+
+ detail::outerr(actions.filename,
+ copyright.begin()->get_position().line)
+ << "Invalid year range: "
+ << year_start
+ << "-"
+ << year_end
+ << "."
+ << std::endl;
+ }
+
+ for(; year_start <= year_end; ++year_start)
+ tmp << " <year>" << year_start << "</year>\n";
                 }
-
- for(; year_start <= year_end; ++year_start)
- tmp << " <year>" << year_start << "</year>\n";
+
+ tmp << " <holder>"
+ << doc_info_output(copyright.consume(doc_info_tags::copyright_name), 106)
+ << "</holder>\n"
+ << " </copyright>\n"
+ << "\n"
+ ;
             }
-
- tmp << " <holder>"
- << doc_info_output(copyright.consume(doc_info_tags::copyright_name), 106)
- << "</holder>\n"
- << " </copyright>\n"
- << "\n"
- ;
         }
 
         if (!license.is_empty())
@@ -312,7 +337,8 @@
                 ;
         }
 
- BOOST_FOREACH(value const& category, categories) {
+ BOOST_FOREACH(value_consumer values, categories) {
+ value category = values.optional_consume();
             if(!category.is_empty()) {
                 tmp << " <" << actions.doc_type << "category name=\"category:"
                     << doc_info_output(category, 106)
@@ -320,6 +346,7 @@
                     << "\n"
                 ;
             }
+ assert(!values.is());
         }
 
         BOOST_FOREACH(value_consumer biblioid, biblioids)
@@ -334,6 +361,7 @@
                 << "</biblioid>"
                 << "\n"
                 ;
+ assert(!biblioid.is());
         }
 
         if(actions.doc_type != "library") {

Modified: trunk/tools/quickbook/src/doc_info_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/doc_info_grammar.cpp (original)
+++ trunk/tools/quickbook/src/doc_info_grammar.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -16,6 +16,7 @@
 #include <boost/spirit/include/classic_loops.hpp>
 #include <boost/spirit/include/classic_symbols.hpp>
 #include <boost/spirit/include/classic_chset.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
 
 namespace quickbook
 {
@@ -41,6 +42,7 @@
 
             void operator()(value::tag_type& t) const {
                 l.attribute_rule = *l.attribute_rules[t];
+ l.attribute_tag = t;
             }
             
             doc_info_grammar_local& l;
@@ -54,6 +56,7 @@
 
             void operator()(iterator, iterator) const {
                 l.attribute_rule = l.doc_fallback;
+ l.attribute_tag = value::default_tag;
             }
             
             doc_info_grammar_local& l;
@@ -68,6 +71,7 @@
         cl::symbols<> doc_types;
         cl::symbols<value::tag_type> doc_attributes;
         std::map<value::tag_type, cl::rule<scanner>* > attribute_rules;
+ value::tag_type attribute_tag;
         cl::rule<scanner> attribute_rule;
         assign_attribute_type assign_attribute;
         fallback_attribute_type fallback_attribute;
@@ -98,12 +102,11 @@
             space
>> '[' >> space
>> (local.doc_types >> cl::eps_p)
- [actions.values.reset]
- [actions.values.entry(doc_info_tags::type)]
+ [actions.values.reset()]
+ [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::type)]
>> hard_space
>> ( *(~cl::eps_p(cl::ch_p('[') | ']' | cl::eol_p) >> local.char_)
- ) [actions.values.tag(doc_info_tags::title)]
- [actions.docinfo_value]
+ ) [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::title)]
>> !(
                     space >> '[' >>
                         local.quickbook_version
@@ -115,18 +118,18 @@
>> space
>> ( local.doc_attributes
                                             [local.assign_attribute]
- [actions.values.tag]
                     | (+(cl::alnum_p | '_' | '-'))
                                             [local.fallback_attribute]
                                             [actions.error("Unrecognized document attribute: '%s'.")]
                     )
>> hard_space
- >> local.attribute_rule
+ >> actions.values.list(detail::var(local.attribute_tag))
+ [local.attribute_rule]
>> space
>> ']'
>> +cl::eol_p
                 )
- >> space [actions.values.sort]
+ >> space [actions.values.sort()]
>> ']'
>> +cl::eol_p
             ;
@@ -145,7 +148,7 @@
 
         // TODO: Restrictions on doc_id and doc_dirname?
 
- local.doc_simple = (*(~cl::eps_p(']') >> local.char_)) [actions.docinfo_value];
+ local.doc_simple = (*(~cl::eps_p(']') >> local.char_)) [actions.docinfo_value(ph::arg1, ph::arg2)];
         local.attribute_rules[doc_info_attributes::version] = &local.doc_simple;
         local.attribute_rules[doc_info_attributes::id] = &local.doc_simple;
         local.attribute_rules[doc_info_attributes::dirname] = &local.doc_simple;
@@ -154,6 +157,7 @@
         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
                     ( ']'
@@ -163,30 +167,27 @@
                 );
 
         local.doc_copyright =
- *actions.values.scoped(doc_info_attributes::copyright)
- [
- +( local.doc_copyright_year
- [actions.values.entry(doc_info_tags::copyright_year)]
+ +( +( local.doc_copyright_year
+ [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::copyright_year)]
>> space
>> !( '-'
>> space
>> local.doc_copyright_year
- [actions.values.entry(doc_info_tags::copyright_year_end)]
+ [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::copyright_year_end)]
+ >> space
                     )
>> !cl::ch_p(',')
+ >> space
                 )
- >> space
- >> local.doc_copyright_holder
- [actions.values.tag(doc_info_tags::copyright_name)]
- [actions.docinfo_value]
+ >> local.doc_copyright_holder [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::copyright_name)]
>> !cl::ch_p(',')
>> space
- ]
+ )
             ;
 
         local.attribute_rules[doc_info_attributes::copyright] = &local.doc_copyright;
 
- local.doc_phrase = simple_phrase[actions.docinfo_value];
+ local.doc_phrase = simple_phrase [actions.docinfo_value(ph::arg1, ph::arg2)];
         local.attribute_rules[doc_info_attributes::purpose] = &local.doc_phrase;
         local.attribute_rules[doc_info_attributes::license] = &local.doc_phrase;
 
@@ -194,25 +195,20 @@
                 '['
>> space
>> (*(~cl::eps_p(',') >> local.char_))
- [actions.values.tag(doc_info_tags::author_surname)]
- [actions.docinfo_value]
+ [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::author_surname)]
>> ',' >> space
>> (*(~cl::eps_p(']') >> local.char_))
- [actions.values.tag(doc_info_tags::author_first)]
- [actions.docinfo_value]
+ [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::author_first)]
>> ']'
             ;
 
         local.doc_authors =
- actions.values.scoped(doc_info_attributes::authors)
- [
- local.doc_author
+ local.doc_author
+ >> space
+ >> *( !(cl::ch_p(',') >> space)
+ >> local.doc_author
>> space
- >> *( !(cl::ch_p(',') >> space)
- >> local.doc_author
- >> space
- )
- ]
+ )
             ;
 
         local.attribute_rules[doc_info_attributes::authors] = &local.doc_authors;
@@ -228,14 +224,10 @@
         local.attribute_rules[doc_info_attributes::source_mode] = &local.doc_source_mode;
 
         local.doc_biblioid =
- actions.values.scoped(doc_info_attributes::biblioid)
- [
- (+cl::alnum_p) [actions.values.entry(doc_info_tags::biblioid_class)]
- >> hard_space
- >> (+(~cl::eps_p(']') >> local.char_))
- [actions.values.tag(doc_info_tags::biblioid_value)]
- [actions.docinfo_value]
- ]
+ (+cl::alnum_p) [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::biblioid_class)]
+ >> hard_space
+ >> (+(~cl::eps_p(']') >> local.char_))
+ [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::biblioid_value)]
             ;
 
         local.attribute_rules[doc_info_attributes::biblioid] = &local.doc_biblioid;

Modified: trunk/tools/quickbook/src/grammar_impl.hpp
==============================================================================
--- trunk/tools/quickbook/src/grammar_impl.hpp (original)
+++ trunk/tools/quickbook/src/grammar_impl.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -13,6 +13,7 @@
 
 #include "grammar.hpp"
 #include "rule_store.hpp"
+#include "values.hpp"
 #include <boost/spirit/include/classic_symbols.hpp>
 
 namespace quickbook
@@ -33,11 +34,15 @@
             conditional_or_block = 5
         };
 
- element_info(type_enum t, cl::rule<scanner>* r)
- : type(t), rule(r) {}
+ element_info(
+ type_enum t,
+ cl::rule<scanner>* r,
+ value::tag_type tag = value::default_tag)
+ : type(t), rule(r), tag(tag) {}
 
         type_enum type;
         cl::rule<scanner>* rule;
+ value::tag_type tag;
     };
 
     struct quickbook_grammar::impl

Modified: trunk/tools/quickbook/src/main_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/main_grammar.cpp (original)
+++ trunk/tools/quickbook/src/main_grammar.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -12,6 +12,7 @@
 #include "actions_class.hpp"
 #include "utils.hpp"
 #include "template_tags.hpp"
+#include "block_tags.hpp"
 #include "parsers.hpp"
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_confix.hpp>
@@ -19,11 +20,13 @@
 #include <boost/spirit/include/classic_clear_actor.hpp>
 #include <boost/spirit/include/classic_if.hpp>
 #include <boost/spirit/include/classic_loops.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_casts.hpp>
 
 namespace quickbook
 {
     namespace cl = boost::spirit::classic;
-
+
     template <typename Rule, typename Action>
     inline void
     simple_markup(
@@ -67,33 +70,13 @@
 
     struct main_grammar_local
     {
- cl::rule<scanner>
- top_level, blocks, paragraph_separator,
- block_element,
- code, code_line, blank_line, hr,
- list, ordered_list, list_item,
- phrase_element, extended_phrase_element, element,
- simple_phrase_end,
- escape,
- inline_code, simple_format,
- simple_bold, simple_italic, simple_underline,
- simple_teletype, template_,
- code_block, macro,
- template_args,
- template_args_1_4, template_arg_1_4,
- 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,
- command_line_macro_identifier, command_line_phrase,
- dummy_block
- ;
-
         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;
@@ -111,8 +94,30 @@
             element_info::context t;
         };
 
+ cl::rule<scanner>
+ top_level, blocks, paragraph_separator,
+ block_element,
+ code, code_line, blank_line, hr,
+ list, ordered_list, list_item,
+ phrase_element, extended_phrase_element, element,
+ simple_phrase_end,
+ escape,
+ inline_code, simple_format,
+ simple_bold, simple_italic, simple_underline,
+ simple_teletype, template_,
+ code_block, macro,
+ template_args,
+ template_args_1_4, template_arg_1_4,
+ 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,
+ command_line_macro_identifier, command_line_phrase,
+ dummy_block
+ ;
+
         element_info::type_enum element_type;
         cl::rule<scanner> element_rule;
+ value::tag_type element_tag;
         assign_element_type assign_element;
 
         main_grammar_local()
@@ -149,7 +154,7 @@
 
         local.blocks =
            *( local.code
- | local.list [actions.list]
+ | local.list
             | local.hr [actions.hr]
             | +eol
             )
@@ -158,7 +163,7 @@
         local.paragraph_separator
             = cl::eol_p
>> *cl::blank_p
- >> cl::eol_p [actions.inside_paragraph]
+ >> cl::eol_p [actions.paragraph]
             ;
 
         local.hr =
@@ -171,16 +176,18 @@
             = '[' >> space
>> local.element
>> cl::eps_p(local.check_element(element_info::in_block))
- [actions.inside_paragraph]
- [actions.values.reset]
- >> ( local.element_rule
- >> ( (space >> ']')
- | cl::eps_p [actions.error]
- )
+ [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.code =
             (
                 local.code_line
@@ -198,23 +205,30 @@
             ;
 
         local.list =
- cl::eps_p(cl::ch_p('*') | '#') >>
- +(
- (*cl::blank_p
- >> (cl::ch_p('*') | '#')) [actions.list_format]
- >> *cl::blank_p
- >> local.list_item
- ) [actions.list_item]
+ cl::eps_p(cl::ch_p('*') | '#')
+ [actions.values.reset()]
+ >> 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('*') | '#')
+ [actions.values.entry(ph::arg1, ph::arg2, general_tags::list_mark)]
+ >> *cl::blank_p
+ >> local.list_item [actions.phrase_value]
+ ]
+ ] [actions.element]
             ;
 
         local.list_item =
- *( common
- | (cl::anychar_p -
- ( cl::eol_p >> *cl::blank_p
- >> (cl::ch_p('*') | '#' | cl::eol_p)
- )
- ) [actions.plain_char]
- )
+ actions.values.save()
+ [
+ *( common
+ | (cl::anychar_p -
+ ( cl::eol_p >> *cl::blank_p
+ >> (cl::ch_p('*') | '#' | cl::eol_p)
+ )
+ ) [actions.plain_char]
+ )
+ ]
>> +eol
             ;
 
@@ -236,18 +250,18 @@
             ;
 
         local.template_ =
- cl::eps_p [actions.values.reset]
- >> !cl::str_p("`") [actions.values.entry(template_tags::escape)]
+ cl::eps_p [actions.values.reset()]
+ >> !cl::str_p("`") [actions.values.entry(ph::arg1, ph::arg2, template_tags::escape)]
>>
             ( (
                 (cl::eps_p(cl::punct_p)
>> actions.templates.scope
- ) [actions.values.entry(template_tags::identifier)]
+ ) [actions.values.entry(ph::arg1, ph::arg2, template_tags::identifier)]
>> !local.template_args
             ) | (
                 (actions.templates.scope
>> cl::eps_p(hard_space)
- ) [actions.values.entry(template_tags::identifier)]
+ ) [actions.values.entry(ph::arg1, ph::arg2, template_tags::identifier)]
>> space
>> !local.template_args
             ) )
@@ -267,8 +281,8 @@
 
         local.template_arg_1_4 =
             ( cl::eps_p(*cl::blank_p >> cl::eol_p)
- >> local.template_inner_arg_1_4 [actions.values.entry(template_tags::block)]
- | local.template_inner_arg_1_4 [actions.values.entry(template_tags::phrase)]
+ >> local.template_inner_arg_1_4 [actions.values.entry(ph::arg1, ph::arg2, template_tags::block)]
+ | local.template_inner_arg_1_4 [actions.values.entry(ph::arg1, ph::arg2, template_tags::phrase)]
             )
             ;
 
@@ -284,8 +298,8 @@
 
         local.template_arg_1_5 =
             ( cl::eps_p(*cl::blank_p >> cl::eol_p)
- >> local.template_arg_1_5_content [actions.values.entry(template_tags::block)]
- | local.template_arg_1_5_content [actions.values.entry(template_tags::phrase)]
+ >> local.template_arg_1_5_content [actions.values.entry(ph::arg1, ph::arg2, template_tags::block)]
+ | local.template_arg_1_5_content [actions.values.entry(ph::arg1, ph::arg2, template_tags::phrase)]
             )
             ;
 
@@ -351,28 +365,29 @@
         simple_markup(local.simple_teletype,
             '=', actions.simple_teletype, local.simple_phrase_end);
 
- phrase =
+ phrase = actions.values.save()[
            *( common
             | (cl::anychar_p - phrase_end) [actions.plain_char]
             )
+ ]
             ;
 
- extended_phrase =
+ extended_phrase = actions.values.save()[
            *( local.extended_phrase_element
             | common
             | (cl::anychar_p - phrase_end) [actions.plain_char]
             )
+ ]
             ;
 
         inside_paragraph =
- actions.scoped_block[
- actions.values.save[
- (*( common
- | (cl::anychar_p - phrase_end) [actions.plain_char]
- | (+eol) [actions.inside_paragraph]
- )) [actions.inside_paragraph]
- ]
- ]
+ actions.values.save()
+ [ *( local.paragraph_separator [actions.paragraph]
+ | common
+ | (cl::anychar_p - phrase_end)
+ [actions.plain_char]
+ )
+ ] [actions.paragraph]
             ;
 
         local.phrase_element
@@ -380,7 +395,11 @@
>> space
>> ( local.element
>> cl::eps_p(local.check_element(element_info::in_phrase))
- >> local.element_rule
+ [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_]
                 )
@@ -391,20 +410,22 @@
             = '[' >> space
>> local.element
>> cl::eps_p(local.check_element(element_info::in_conditional))
- [actions.inside_paragraph]
- >> ( local.element_rule
- >> ( (space >> ']')
+ [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]
- )
- | cl::eps_p [actions.error]
                 )
             ;
 
-
         local.element
             = cl::eps_p(cl::punct_p)
- >> elements [local.assign_element]
- | elements [local.assign_element]
+ >> elements [local.assign_element]
+ | elements [local.assign_element]
>> (cl::eps_p - (cl::alnum_p | '_'))
             ;
 
@@ -427,10 +448,11 @@
         // Simple phrase grammar
         //
 
- simple_phrase =
+ simple_phrase = actions.values.save()[
            *( common
- | (cl::anychar_p - ']') [actions.plain_char]
+ | (cl::anychar_p - ']') [actions.plain_char]
             )
+ ]
             ;
 
         //
@@ -438,17 +460,18 @@
         //
 
         command_line =
- *cl::space_p
+ actions.values.list(block_tags::macro_definition)
+ [ *cl::space_p
>> local.command_line_macro_identifier
- [actions.macro_identifier]
+ [actions.values.entry(ph::arg1, ph::arg2)]
>> *cl::space_p
>> ( '='
>> *cl::space_p
>> local.command_line_phrase
- [actions.macro_definition]
>> *cl::space_p
- )
- | cl::eps_p [actions.macro_definition]
+ | cl::eps_p
+ ) [actions.phrase_value]
+ ] [actions.element]
             ;
 
         local.command_line_macro_identifier =
@@ -457,9 +480,11 @@
 
 
         local.command_line_phrase =
- *( common
- | (cl::anychar_p - ']') [actions.plain_char]
- )
+ actions.values.save()
+ [ *( common
+ | (cl::anychar_p - ']') [actions.plain_char]
+ )
+ ]
             ;
 
         // Miscellaneous stuff

Modified: trunk/tools/quickbook/src/markups.cpp
==============================================================================
--- trunk/tools/quickbook/src/markups.cpp (original)
+++ trunk/tools/quickbook/src/markups.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -8,7 +8,12 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
+#include "quickbook.hpp"
 #include "markups.hpp"
+#include "block_tags.hpp"
+#include "phrase_tags.hpp"
+#include <boost/foreach.hpp>
+#include <ostream>
 
 namespace quickbook
 {
@@ -86,4 +91,52 @@
     const char* escape_post_ = "<!--quickbook-escape-postfix-->";
     const char* replaceable_pre_ = "<replaceable>";
     const char* replaceable_post_ = "</replaceable>";
+
+ namespace detail
+ {
+ std::map<value::tag_type, markup> markups;
+
+ void initialise_markups()
+ {
+ markup init_markups[] = {
+ { block_tags::paragraph, paragraph_pre, paragraph_post },
+ { block_tags::blurb, blurb_pre, blurb_post },
+ { block_tags::blockquote, blockquote_pre, blockquote_post },
+ { block_tags::preformatted, preformatted_pre, preformatted_post },
+ { block_tags::warning, warning_pre, warning_post },
+ { block_tags::caution, caution_pre, caution_post },
+ { block_tags::important, important_pre, important_post },
+ { block_tags::note, note_pre, note_post },
+ { block_tags::tip, tip_pre, tip_post },
+ { phrase_tags::url, url_pre_, url_post_ },
+ { phrase_tags::link, link_pre_, link_post_ },
+ { phrase_tags::funcref, funcref_pre_, funcref_post_ },
+ { phrase_tags::classref, classref_pre_, classref_post_ },
+ { phrase_tags::memberref, memberref_pre_, memberref_post_ },
+ { phrase_tags::enumref, enumref_pre_, enumref_post_ },
+ { phrase_tags::macroref, macroref_pre_, macroref_post_ },
+ { phrase_tags::headerref, headerref_pre_, headerref_post_ },
+ { phrase_tags::conceptref, conceptref_pre_, conceptref_post_ },
+ { phrase_tags::globalref, globalref_pre_, globalref_post_ },
+ { phrase_tags::bold, bold_pre_, bold_post_ },
+ { phrase_tags::italic, italic_pre_, italic_post_ },
+ { phrase_tags::underline, underline_pre_, underline_post_ },
+ { phrase_tags::teletype, teletype_pre_, teletype_post_ },
+ { phrase_tags::strikethrough, strikethrough_pre_, strikethrough_post_ },
+ { phrase_tags::quote, quote_pre_, quote_post_ },
+ { phrase_tags::replaceable, replaceable_pre_, replaceable_post_ },
+ { phrase_tags::footnote, footnote_pre_, footnote_post_ }
+ };
+
+ BOOST_FOREACH(markup m, init_markups)
+ {
+ markups[m.tag] = m;
+ }
+ }
+
+ std::ostream& operator<<(std::ostream& out, markup const& m)
+ {
+ return out<<"{"<<m.tag<<": \""<<m.pre<<"\", \""<<m.post<<"\"}";
+ }
+ }
 }

Modified: trunk/tools/quickbook/src/markups.hpp
==============================================================================
--- trunk/tools/quickbook/src/markups.hpp (original)
+++ trunk/tools/quickbook/src/markups.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -10,6 +10,10 @@
 #if !defined(BOOST_SPIRIT_MARKUPS_HPP)
 #define BOOST_SPIRIT_MARKUPS_HPP
 
+#include <map>
+#include <iosfwd>
+#include "values.hpp"
+
 namespace quickbook
 {
     extern const char* comment_pre;
@@ -98,6 +102,19 @@
     extern const char* escape_post_;
     extern const char* replaceable_pre_;
     extern const char* replaceable_post_;
+
+ namespace detail
+ {
+ struct markup {
+ value::tag_type tag;
+ char const* pre;
+ char const* post;
+ };
+
+ extern std::map<value::tag_type, markup> markups;
+
+ std::ostream& operator<<(std::ostream&, markup const&);
+ }
 }
 
 #endif // BOOST_SPIRIT_MARKUPS_HPP

Modified: trunk/tools/quickbook/src/parsers.hpp
==============================================================================
--- trunk/tools/quickbook/src/parsers.hpp (original)
+++ trunk/tools/quickbook/src/parsers.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -14,39 +14,115 @@
 
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_nil.hpp>
+#include <boost/spirit/include/phoenix1_tuples.hpp>
 
 namespace quickbook {
     namespace cl = boost::spirit::classic;
     
- // Used to store variables/state while parsing
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // scoped_parser<Impl>
+ //
+ // Impl is a struct with the methods:
+ //
+ // void start();
+ // void success();
+ // void failure();
+ // void cleanup();
+ //
+ ///////////////////////////////////////////////////////////////////////////
 
- template <typename ScopeT, typename DataT, typename ParserT>
+ template <typename Impl, typename Arguments, typename ParserT>
     struct scoped_parser_impl
- : public cl::unary< ParserT, cl::parser< scoped_parser_impl<ScopeT, DataT, ParserT> > >
+ : public cl::unary< ParserT, cl::parser< scoped_parser_impl<Impl, Arguments, ParserT> > >
     {
- typedef scoped_parser_impl<ScopeT, DataT, ParserT> self_t;
- typedef cl::unary< ParserT, cl::parser< scoped_parser_impl<ScopeT, DataT, ParserT> > > base_t;
+ typedef scoped_parser_impl<Impl, Arguments, ParserT> self_t;
+ typedef cl::unary< ParserT, cl::parser< scoped_parser_impl<Impl, Arguments, ParserT> > > base_t;
 
         template <typename ScannerT>
         struct result { typedef cl::match<> type; };
 
- scoped_parser_impl(DataT& actions, ParserT const &p)
+ scoped_parser_impl(
+ Impl const& impl,
+ Arguments const& arguments,
+ ParserT const &p)
             : base_t(p)
- , actions(actions)
+ , impl_(impl)
+ , arguments_(arguments)
         {}
 
+ struct scoped
+ {
+ typedef void result_type;
+ template <typename Arg1 = void, typename Arg2 = void>
+ struct result { typedef void type; };
+
+ explicit scoped(Impl const& impl)
+ : impl_(impl)
+ , in_progress_(false)
+ {}
+
+ typedef phoenix::tuple_index<0> t0;
+ typedef phoenix::tuple_index<1> t1;
+
+ void start(phoenix::tuple<> const&)
+ {
+ impl_.start();
+ in_progress_ = true;
+ }
+
+ template <typename Arg1>
+ void start(phoenix::tuple<Arg1> const& x)
+ {
+ impl_.start(x[t0()]);
+ in_progress_ = true;
+ }
+
+ template <typename Arg1, typename Arg2>
+ void start(phoenix::tuple<Arg1, Arg2> const& x)
+ {
+ impl_.start(x[t0()], x[t1()]);
+ in_progress_ = true;
+ }
+
+ void success()
+ {
+ in_progress_ = false;
+ impl_.success();
+ }
+
+ void failure()
+ {
+ in_progress_ = false;
+ impl_.failure();
+ }
+
+ ~scoped()
+ {
+ if (in_progress_) impl_.failure();
+ impl_.cleanup();
+ }
+
+ Impl impl_;
+ bool in_progress_;
+ };
+
         template <typename ScannerT>
         typename result<ScannerT>::type parse(ScannerT const &scan) const
         {
             typedef typename ScannerT::iterator_t iterator_t;
             iterator_t save = scan.first;
 
- ScopeT scope(actions);
+ scoped scope(impl_);
+ scope.start(arguments_);
+
             typename cl::parser_result<ParserT, ScannerT>::type result
                 = this->subject().parse(scan);
 
+ //result = scope.match(result);
+
             if (result) {
- scope.success(result);
+ scope.success();
                 return scan.create_match(result.length(), cl::nil_t(), save, scan.first);
             }
             else {
@@ -55,30 +131,21 @@
             }
         }
         
- DataT& actions;
+ Impl impl_;
+ Arguments arguments_;
     };
 
- ///////////////////////////////////////////////////////////////////////////
- //
- // scoped_parser
- //
- // generator for scoped_parser_impl objects
- // operator[] returns scoped_parser_impl according to its argument
- //
- ///////////////////////////////////////////////////////////////////////////
- template <typename ScopeT>
- struct scoped_parser
- {
- typedef typename ScopeT::data_type data_type;
-
- explicit scoped_parser(data_type& actions)
- : actions(actions) {}
+ template <typename Impl, typename Arguments>
+ struct scoped_parser_gen
+ {
+ explicit scoped_parser_gen(Impl impl, Arguments const& arguments)
+ : impl_(impl), arguments_(arguments) {}
 
         template<typename ParserT>
         scoped_parser_impl
         <
- ScopeT,
- data_type,
+ Impl,
+ Arguments,
             typename cl::as_parser<ParserT>::type
>
         operator[](ParserT const &p) const
@@ -86,17 +153,56 @@
             typedef cl::as_parser<ParserT> as_parser_t;
             typedef typename as_parser_t::type parser_t;
 
- return scoped_parser_impl<ScopeT, data_type, parser_t>
- (actions, as_parser_t::convert(p));
+ return scoped_parser_impl<Impl, Arguments, parser_t>
+ (impl_, arguments_, p);
         }
+
+ Impl impl_;
+ Arguments arguments_;
+ };
+
+ template <typename Impl>
+ struct scoped_parser
+ {
+ scoped_parser(Impl const& impl)
+ : impl_(impl) {}
+
+ scoped_parser_gen<Impl, phoenix::tuple<> >
+ operator()() const
+ {
+ typedef phoenix::tuple<> tuple;
+ return scoped_parser_gen<Impl, tuple>(impl_, tuple());
+ };
+
+ template <typename Arg1>
+ scoped_parser_gen<Impl, phoenix::tuple<Arg1> >
+ operator()(Arg1 x1) const
+ {
+ typedef phoenix::tuple<Arg1> tuple;
+ return scoped_parser_gen<Impl, tuple>(impl_, tuple(x1));
+ };
+
+ template <typename Arg1, typename Arg2>
+ scoped_parser_gen<Impl, phoenix::tuple<Arg1, Arg2> >
+ operator()(Arg1 x1, Arg2 x2) const
+ {
+ typedef phoenix::tuple<Arg1, Arg2> tuple;
+ return scoped_parser_gen<Impl, tuple>(impl_, tuple(x1, x2));
+ };
         
- data_type& actions;
+ Impl impl_;
     };
     
+ ///////////////////////////////////////////////////////////////////////////
+ //
     // Lookback parser
     //
+ // usage: lookback[body]
+ //
     // Requires that iterator has typedef 'lookback_range' and function
     // 'lookback' returning a 'lookback_range'.
+ //
+ ///////////////////////////////////////////////////////////////////////////
 
     template <typename ParserT>
     struct lookback_parser

Modified: trunk/tools/quickbook/src/phrase_element_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/phrase_element_grammar.cpp (original)
+++ trunk/tools/quickbook/src/phrase_element_grammar.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -11,10 +11,13 @@
 #include "grammar_impl.hpp"
 #include "actions_class.hpp"
 #include "utils.hpp"
+#include "phrase_tags.hpp"
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_assign_actor.hpp>
 #include <boost/spirit/include/classic_clear_actor.hpp>
 #include <boost/spirit/include/classic_if.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_casts.hpp>
 
 namespace quickbook
 {
@@ -23,14 +26,7 @@
     struct phrase_element_grammar_local
     {
         cl::rule<scanner>
- image,
- bold, italic, underline, teletype,
- strikethrough, url, funcref, classref,
- memberref, enumref, macroref, headerref, conceptref, globalref,
- anchor, link,
- source_mode_cpp, source_mode_python, source_mode_teletype,
- quote, footnote, replaceable,
- cond_phrase
+ image, anchor, link, empty, cond_phrase, inner_phrase
                         ;
     };
 
@@ -46,208 +42,94 @@
 
         local.cond_phrase =
                 blank
- >> macro_identifier [actions.cond_phrase_pre]
- >> actions.scoped_cond_phrase[extended_phrase]
+ >> macro_identifier [actions.values.entry(ph::arg1, ph::arg2)]
+ >> actions.scoped_cond_phrase()
+ [extended_phrase]
             ;
 
         elements.add
- ("$", element_info(element_info::phrase, &local.image))
+ ("$", element_info(element_info::phrase, &local.image, phrase_tags::image))
             ;
 
         local.image =
- blank [actions.values.reset]
+ blank
>> cl::if_p(qbk_since(105u)) [
                         (+(
                             *cl::space_p
>> +(cl::anychar_p - (cl::space_p | phrase_end | '['))
- )) [actions.values.entry]
+ )) [actions.values.entry(ph::arg1, ph::arg2)]
>> hard_space
- >> *actions.values.scoped[
- '['
+ >> *actions.values.list()
+ [ '['
>> (*(cl::alnum_p | '_'))
- [actions.values.entry]
+ [actions.values.entry(ph::arg1, ph::arg2)]
>> space
>> (*(cl::anychar_p - (phrase_end | '[')))
- [actions.values.entry]
+ [actions.values.entry(ph::arg1, ph::arg2)]
>> ']'
>> space
                         ]
                 ].else_p [
                         (*(cl::anychar_p - phrase_end))
- [actions.values.entry]
+ [actions.values.entry(ph::arg1, ph::arg2)]
                 ]
- >> cl::eps_p(']') [actions.image]
+ >> cl::eps_p(']')
             ;
             
         elements.add
- ("@", element_info(element_info::phrase, &local.url))
- ;
-
- local.url =
- (*(cl::anychar_p -
- (']' | hard_space))) [actions.url_pre]
- >> hard_space
- >> phrase [actions.url_post]
- ;
-
- elements.add
- ("link", element_info(element_info::phrase, &local.link))
+ ("@", element_info(element_info::phrase, &local.link, phrase_tags::url))
+ ("link", element_info(element_info::phrase, &local.link, phrase_tags::link))
+ ("funcref", element_info(element_info::phrase, &local.link, phrase_tags::funcref))
+ ("classref", element_info(element_info::phrase, &local.link, phrase_tags::classref))
+ ("memberref", element_info(element_info::phrase, &local.link, phrase_tags::memberref))
+ ("enumref", element_info(element_info::phrase, &local.link, phrase_tags::enumref))
+ ("macroref", element_info(element_info::phrase, &local.link, phrase_tags::macroref))
+ ("headerref", element_info(element_info::phrase, &local.link, phrase_tags::headerref))
+ ("conceptref", element_info(element_info::phrase, &local.link, phrase_tags::conceptref))
+ ("globalref", element_info(element_info::phrase, &local.link, phrase_tags::globalref))
             ;
 
         local.link =
                 space
>> (*(cl::anychar_p - (']' | hard_space)))
- [actions.link_pre]
+ [actions.values.entry(ph::arg1, ph::arg2)]
>> hard_space
- >> phrase [actions.link_post]
+ >> local.inner_phrase
             ;
 
         elements.add
- ("#", element_info(element_info::phrase, &local.anchor))
+ ("#", element_info(element_info::phrase, &local.anchor, phrase_tags::anchor))
             ;
 
         local.anchor =
                 blank
- >> (*(cl::anychar_p - phrase_end)) [actions.anchor]
+ >> (*(cl::anychar_p - phrase_end)) [actions.values.entry(ph::arg1, ph::arg2)]
             ;
 
         elements.add
- ("funcref", element_info(element_info::phrase, &local.funcref))
- ("classref", element_info(element_info::phrase, &local.classref))
- ("memberref", element_info(element_info::phrase, &local.memberref))
- ("enumref", element_info(element_info::phrase, &local.enumref))
- ("macroref", element_info(element_info::phrase, &local.macroref))
- ("headerref", element_info(element_info::phrase, &local.headerref))
- ("conceptref", element_info(element_info::phrase, &local.conceptref))
- ("globalref", element_info(element_info::phrase, &local.globalref))
- ;
-
- local.funcref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.funcref_pre]
- >> hard_space
- >> phrase [actions.funcref_post]
- ;
-
- local.classref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.classref_pre]
- >> hard_space
- >> phrase [actions.classref_post]
- ;
-
- local.memberref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.memberref_pre]
- >> hard_space
- >> phrase [actions.memberref_post]
- ;
-
- local.enumref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.enumref_pre]
- >> hard_space
- >> phrase [actions.enumref_post]
- ;
-
- local.macroref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.macroref_pre]
- >> hard_space
- >> phrase [actions.macroref_post]
- ;
-
- local.headerref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.headerref_pre]
- >> hard_space
- >> phrase [actions.headerref_post]
- ;
-
- local.conceptref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.conceptref_pre]
- >> hard_space
- >> phrase [actions.conceptref_post]
- ;
-
- local.globalref =
- space
- >> (*(cl::anychar_p -
- (']' | hard_space))) [actions.globalref_pre]
- >> hard_space
- >> phrase [actions.globalref_post]
- ;
-
- elements.add
- ("*", element_info(element_info::phrase, &local.bold))
- ("'", element_info(element_info::phrase, &local.italic))
- ("_", element_info(element_info::phrase, &local.underline))
- ("^", element_info(element_info::phrase, &local.teletype))
- ("-", element_info(element_info::phrase, &local.strikethrough))
- ("\"", element_info(element_info::phrase, &local.quote))
- ("~", element_info(element_info::phrase, &local.replaceable))
- ;
-
- local.bold =
- blank [actions.bold_pre]
- >> phrase [actions.bold_post]
- ;
-
- local.italic =
- blank [actions.italic_pre]
- >> phrase [actions.italic_post]
- ;
-
- local.underline =
- blank [actions.underline_pre]
- >> phrase [actions.underline_post]
- ;
-
- local.teletype =
- blank [actions.teletype_pre]
- >> phrase [actions.teletype_post]
- ;
-
- local.strikethrough =
- blank [actions.strikethrough_pre]
- >> phrase [actions.strikethrough_post]
- ;
-
- local.quote =
- blank [actions.quote_pre]
- >> phrase [actions.quote_post]
- ;
-
- local.replaceable =
- blank [actions.replaceable_pre]
- >> phrase [actions.replaceable_post]
+ ("*", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::bold))
+ ("'", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::italic))
+ ("_", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::underline))
+ ("^", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::teletype))
+ ("-", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::strikethrough))
+ ("\"", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::quote))
+ ("~", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::replaceable))
+ ("footnote", element_info(element_info::phrase, &local.inner_phrase, phrase_tags::footnote))
             ;
 
         elements.add
- ("c++", element_info(element_info::phrase, &local.source_mode_cpp))
- ("python", element_info(element_info::phrase, &local.source_mode_python))
- ("teletype", element_info(element_info::phrase, &local.source_mode_teletype))
+ ("c++", element_info(element_info::phrase, &local.empty, source_mode_tags::cpp))
+ ("python", element_info(element_info::phrase, &local.empty, source_mode_tags::python))
+ ("teletype", element_info(element_info::phrase, &local.empty, source_mode_tags::teletype))
             ;
         
- local.source_mode_cpp = cl::eps_p [cl::assign_a(actions.source_mode, "c++")];
- local.source_mode_python = cl::eps_p [cl::assign_a(actions.source_mode, "python")];
- local.source_mode_teletype = cl::eps_p [cl::assign_a(actions.source_mode, "teletype")];
+ local.empty = cl::eps_p;
 
- elements.add
- ("footnote", element_info(element_info::phrase, &local.footnote))
- ;
-
- local.footnote =
- blank [actions.footnote_pre]
- >> phrase [actions.footnote_post]
+ local.inner_phrase =
+ blank
+ >> actions.scoped_output()
+ [ phrase [actions.phrase_value]
+ ]
             ;
     }
 }

Modified: trunk/tools/quickbook/src/quickbook.cpp
==============================================================================
--- trunk/tools/quickbook/src/quickbook.cpp (original)
+++ trunk/tools/quickbook/src/quickbook.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -189,8 +189,9 @@
         // First thing, the filesystem should record the current working directory.
         fs::initial_path<fs::path>();
         
- // Setup out output stream.
+ // Various initialisation methods
         quickbook::detail::initialise_output();
+ quickbook::detail::initialise_markups();
 
         options_description desc("Allowed options");
 

Modified: trunk/tools/quickbook/src/quickbook.hpp
==============================================================================
--- trunk/tools/quickbook/src/quickbook.hpp (original)
+++ trunk/tools/quickbook/src/quickbook.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -29,6 +29,14 @@
     extern std::vector<std::string> preset_defines;
 
     int parse_file(fs::path const& filein_, actions& actor, bool ignore_docinfo = false);
+
+ // Some initialisation methods
+ //
+ // Declared here to avoid including other headers
+ namespace detail
+ {
+ void initialise_markups();
+ }
 }
 
 #endif

Deleted: trunk/tools/quickbook/src/table_tags.hpp
==============================================================================
--- trunk/tools/quickbook/src/table_tags.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
+++ (empty file)
@@ -1,26 +0,0 @@
-/*=============================================================================
- 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)
-=============================================================================*/
-
-#if !defined(BOOST_SPIRIT_QUICKBOOK_TABLE_TAGS_HPP)
-#define BOOST_SPIRIT_QUICKBOOK_TABLE_TAGS_HPP
-
-#include "value_tags.hpp"
-
-namespace quickbook
-{
- QUICKBOOK_VALUE_TAGS(table_tags, 0x200,
- (title)(row)(cell)
- )
-
- QUICKBOOK_VALUE_TAGS(general_tags, 0x300,
- (element_id)
- )
-
-}
-
-#endif
\ No newline at end of file

Modified: trunk/tools/quickbook/src/utils.hpp
==============================================================================
--- trunk/tools/quickbook/src/utils.hpp (original)
+++ trunk/tools/quickbook/src/utils.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -15,6 +15,9 @@
 #include <boost/ref.hpp>
 #include <boost/assert.hpp>
 #include <boost/filesystem/v3/path.hpp>
+#include <boost/range/algorithm_ext/push_back.hpp>
+#include <boost/range/adaptor/transformed.hpp>
+
 
 namespace quickbook {
 
@@ -27,13 +30,15 @@
     void print_space(char ch, std::ostream& out);
     char filter_identifier_char(char ch);
 
- template <typename Iterator>
+ template <typename Range>
     inline std::string
- make_identifier(Iterator const& first, Iterator const& last)
+ make_identifier(Range const& range)
     {
         std::string out_name;
- for (Iterator i = first; i != last; ++i)
- out_name += filter_identifier_char(*i);
+
+ boost::push_back(out_name,
+ range | boost::adaptors::transformed(filter_identifier_char));
+
         return out_name;
     }
 

Modified: trunk/tools/quickbook/src/value_tags.hpp
==============================================================================
--- trunk/tools/quickbook/src/value_tags.hpp (original)
+++ trunk/tools/quickbook/src/value_tags.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -18,7 +18,7 @@
 
 #define QUICKBOOK_VALUE_TAGS(tags_name, start_index, values) \
     struct tags_name { \
- enum { \
+ enum tags_name##_enum { \
             previous_index = start_index - 1, \
             BOOST_PP_SEQ_ENUM(values), \
             end_index \
@@ -43,7 +43,7 @@
 
 #define QUICKBOOK_VALUE_NAMED_TAGS(tags_name, start_index, values) \
     struct tags_name { \
- enum { \
+ enum tags_name##_enum { \
             previous_index = start_index - 1 \
             BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_NAMED_ENUM, _, values), \
             end_index \

Modified: trunk/tools/quickbook/src/values.cpp
==============================================================================
--- trunk/tools/quickbook/src/values.cpp (original)
+++ trunk/tools/quickbook/src/values.cpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -710,8 +710,7 @@
     
     value_builder::value_builder()
         : current()
- , list_tag(value::no_tag)
- , next_tag(value::default_tag)
+ , list_tag(value::default_tag)
         , saved()
     {
     }
@@ -719,7 +718,6 @@
     void value_builder::swap(value_builder& other) {
         current.swap(other.current);
         std::swap(list_tag, other.list_tag);
- std::swap(next_tag, other.next_tag);
         saved.swap(other.saved);
     }
     
@@ -742,18 +740,7 @@
     void value_builder::reset() {
         detail::value_list_builder new_builder;
         current.swap(new_builder);
- list_tag = value::no_tag;
- next_tag = value::default_tag;
- }
-
- void value_builder::set_tag(value::tag_type tag) {
- next_tag = tag;
- }
-
- value::tag_type value_builder::release_tag(value::tag_type t) {
- value::tag_type r = t != value::no_tag ? t : next_tag;
- next_tag = value::default_tag;
- return r;
+ list_tag = value::default_tag;
     }
 
     void value_builder::insert(value const& item) {
@@ -761,7 +748,7 @@
     }
 
     void value_builder::start_list(value::tag_type tag) {
- value::tag_type saved_tag = release_tag(tag);
+ value::tag_type saved_tag = tag;
         save();
         list_tag = saved_tag;
     }

Modified: trunk/tools/quickbook/src/values.hpp
==============================================================================
--- trunk/tools/quickbook/src/values.hpp (original)
+++ trunk/tools/quickbook/src/values.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -77,7 +77,7 @@
 
             typedef iterator const_iterator;
             typedef value_node::tag_type tag_type;
- enum { no_tag = -1, default_tag = 0 };
+ enum { default_tag = 0 };
 
         protected:
             explicit value_base(value_node* base)
@@ -243,17 +243,16 @@
 
         void reset();
         void set_tag(value::tag_type);
- value::tag_type release_tag(value::tag_type = value::no_tag);
         void insert(value const&);
 
- void start_list(value::tag_type);
+ void start_list(value::tag_type = value::default_tag);
         void finish_list();
         void clear_list();
         void sort_list();
 
     private:
         detail::value_list_builder current;
- value::tag_type list_tag, next_tag;
+ value::tag_type list_tag;
         boost::scoped_ptr<value_builder> saved;
     };
 
@@ -280,13 +279,29 @@
             , end_(x.end())
         {}
 
- reference consume(value::tag_type t = value::no_tag)
+ reference consume()
+ {
+ assert(is());
+ return *pos_++;
+ }
+
+ reference consume(value::tag_type t)
         {
             assert(is(t));
             return *pos_++;
         }
 
- value optional_consume(value::tag_type t = value::no_tag)
+ value optional_consume()
+ {
+ if(is()) {
+ return *pos_++;
+ }
+ else {
+ return value();
+ }
+ }
+
+ value optional_consume(value::tag_type t)
         {
             if(is(t)) {
                 return *pos_++;
@@ -296,10 +311,14 @@
             }
         }
 
- bool is(value::tag_type t = value::no_tag)
+ bool is()
+ {
+ return pos_ != end_;
+ }
+
+ bool is(value::tag_type t)
         {
- return (pos_ != end_ &&
- (t == value::no_tag || t == pos_->get_tag()));
+ return pos_ != end_ && t == pos_->get_tag();
         }
 
         iterator begin() const { return pos_; }

Modified: trunk/tools/quickbook/src/values_parse.hpp
==============================================================================
--- trunk/tools/quickbook/src/values_parse.hpp (original)
+++ trunk/tools/quickbook/src/values_parse.hpp 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -10,221 +10,63 @@
 #define BOOST_SPIRIT_QUICKBOOK_VALUES_PARSE_HPP
 
 #include "values.hpp"
-#include <boost/spirit/include/classic_core.hpp>
+#include "parsers.hpp"
+#include <boost/spirit/include/phoenix1_functions.hpp>
+
+#include <iostream>
 
 namespace quickbook {
- namespace cl = boost::spirit::classic;
+ namespace ph = phoenix;
 
     struct value_builder_save
     {
- value_builder_save(value_builder& a) : a(a) { a.save(); }
- ~value_builder_save() { a.restore(); }
- value_builder& a;
- };
-
- template <typename ParserT>
- struct value_save_parser
- : public cl::unary< ParserT, cl::parser< value_save_parser<ParserT> > >
- {
- typedef value_save_parser<ParserT> self_t;
- typedef cl::unary< ParserT, cl::parser< value_save_parser<ParserT> > > base_t;
-
- template <typename ScannerT>
- struct result
- {
- typedef typename cl::parser_result<ParserT, ScannerT>::type type;
- };
-
- value_save_parser(value_builder& a, ParserT const &p)
- : base_t(p)
- , builder_(a)
- {}
-
- template <typename ScannerT>
- typename result<ScannerT>::type parse(ScannerT const &scan) const
- {
- typedef typename ScannerT::iterator_t iterator_t;
- iterator_t save = scan.first;
+ value_builder_save(value_builder& builder) : builder(builder) {}
 
- value_builder_save saver(builder_);
+ void start() { builder.save(); }
+ void success() {}
+ void failure() {}
+ void cleanup() { builder.restore(); }
 
- typename cl::parser_result<ParserT, ScannerT>::type result
- = this->subject().parse(scan);
-
- if (result) {
- return scan.create_match(result.length(), cl::nil_t(), save, scan.first);
- }
- else {
- return scan.no_match();
- }
- }
-
- value_builder& builder_;
- };
-
- struct value_save_gen
- {
- explicit value_save_gen(value_builder& b)
- : builder_(b) {}
-
- template<typename ParserT>
- value_save_parser<typename cl::as_parser<ParserT>::type>
- operator[](ParserT const& p) const
- {
- typedef typename cl::as_parser<ParserT> as_parser_t;
- typedef typename as_parser_t::type parser_t;
-
- return value_save_parser<parser_t>
- (builder_, as_parser_t::convert(p));
- }
-
- value_builder& builder_;
+ value_builder& builder;
     };
 
     struct value_builder_list
     {
- value_builder_list(value_builder& a, value::tag_type t)
- : a(a), finished(false) { a.start_list(t); }
- void finish() { a.finish_list(); finished = true; }
- ~value_builder_list() { if(!finished) a.clear_list(); }
- value_builder& a;
- bool finished;
- };
+ value_builder_list(value_builder& builder) : builder(builder) {}
 
- template <typename ParserT>
- struct value_scoped_list_parser
- : public cl::unary< ParserT, cl::parser< value_scoped_list_parser<ParserT> > >
- {
- typedef value_scoped_list_parser<ParserT> self_t;
- typedef cl::unary< ParserT, cl::parser< value_scoped_list_parser<ParserT> > > base_t;
-
- template <typename ScannerT>
- struct result
- {
- typedef typename cl::parser_result<ParserT, ScannerT>::type type;
- };
-
- value_scoped_list_parser(value_builder& a, value::tag_type k, ParserT const &p)
- : base_t(p)
- , builder_(a)
- , tag_(k)
- {}
+ void start(value::tag_type tag = value::default_tag)
+ { builder.start_list(tag); }
 
- template <typename ScannerT>
- typename result<ScannerT>::type parse(ScannerT const &scan) const
- {
- typedef typename ScannerT::iterator_t iterator_t;
- iterator_t save = scan.first;
-
- value_builder_list list(builder_, tag_);
- typename cl::parser_result<ParserT, ScannerT>::type result
- = this->subject().parse(scan);
-
- if (result) {
- list.finish();
- return scan.create_match(result.length(), cl::nil_t(), save, scan.first);
- }
- else {
- return scan.no_match();
- }
- }
-
- value_builder& builder_;
- value::tag_type tag_;
- };
-
- struct value_scoped_list_gen
- {
- explicit value_scoped_list_gen(value_builder& b, value::tag_type t = value::no_tag)
- : b(b), tag_(t) {}
+ void success() { builder.finish_list(); }
+ void failure() { builder.clear_list(); }
+ void cleanup() {}
 
- template<typename ParserT>
- value_scoped_list_parser<typename cl::as_parser<ParserT>::type>
- operator[](ParserT const& p) const
- {
- typedef typename cl::as_parser<ParserT> as_parser_t;
- typedef typename as_parser_t::type parser_t;
-
- return value_scoped_list_parser<parser_t>
- (b, tag_, as_parser_t::convert(p));
- }
-
- value_scoped_list_gen operator()(value::tag_type const& tag) const
- {
- return value_scoped_list_gen(b, tag);
- }
-
- value_builder& b;
- value::tag_type tag_;
- };
-
- /* value_scoped_list_gen
- */
-
- struct value_string_entry {
- value_string_entry(value_builder& b, std::string const& v, value::tag_type t = value::no_tag)
- : b(b), v(v), tag_(t) {}
-
- template <typename Iterator>
- void operator()(Iterator, Iterator) const {
- b.insert(bbk_value(v, tag_));
- }
-
- value_builder& b;
- std::string v;
- value::tag_type tag_;
+ value_builder& builder;
     };
 
     struct value_entry
     {
- value_entry(value_builder& b, value::tag_type t = value::no_tag)
- : b(b), tag_(t) {}
-
- template <typename Iterator>
- void operator()(Iterator begin, Iterator end) const {
- b.insert(qbk_value(begin, end, tag_));
- }
-
- value_string_entry operator()(std::string const& value) {
- return value_string_entry(b, value, tag_);
- }
-
- value_string_entry operator()(value::tag_type tag, std::string const& value) {
- return value_string_entry(b, value, tag);
- }
-
- value_entry operator()(value::tag_type const& value) {
- return value_entry(b, value);
- }
-
- value_builder& b;
- value::tag_type tag_;
- };
-
- struct value_fixed_tag {
- value_fixed_tag(value_builder& b, value::tag_type v)
- : b(b), v(v) {}
-
- template <typename Iterator>
- void operator()(Iterator, Iterator) const {
- b.set_tag(v);
- }
-
- value_builder& b;
- value::tag_type v;
- };
+ template <typename Arg1, typename Arg2 = void, typename Arg3 = void, typename Arg4 = void>
+ struct result {
+ typedef void type;
+ };
 
- struct value_tag
- {
- value_tag(value_builder& b)
+ value_entry(value_builder& b)
             : b(b) {}
 
- void operator()(value::tag_type value) const {
- b.set_tag(value);
+ template <typename Iterator>
+ void operator()(Iterator begin, Iterator end,
+ value::tag_type tag = value::default_tag) const
+ {
+ b.insert(qbk_value(begin, end, tag));
         }
 
- value_fixed_tag operator()(value::tag_type value) {
- return value_fixed_tag(b, value);
+ template <typename Iterator>
+ void operator()(Iterator begin, Iterator,
+ std::string const& v,
+ value::tag_type tag = value::default_tag) const
+ {
+ b.insert(qbk_value(v, begin.get_position(), tag));
         }
 
         value_builder& b;
@@ -232,11 +74,12 @@
 
     struct value_reset
     {
+ typedef void result_type;
+
         value_reset(value_builder& b)
             : b(b) {}
 
- template <typename Iterator>
- void operator()(Iterator, Iterator) const {
+ void operator()() const {
             b.reset();
         }
 
@@ -245,11 +88,12 @@
     
     struct value_sort
     {
+ typedef void result_type;
+
         value_sort(value_builder& b)
             : b(b) {}
 
- template <typename Iterator>
- void operator()(Iterator, Iterator) const {
+ void operator()() const {
             b.sort_list();
         }
 
@@ -261,22 +105,20 @@
         value_parser()
             : builder()
             , save(builder)
- , reset(builder)
- , scoped(builder)
- , tag(builder)
+ , list(builder)
             , entry(builder)
+ , reset(builder)
             , sort(builder)
             {}
     
         value get() { return builder.get(); }
 
         value_builder builder;
- value_save_gen save;
- value_reset reset;
- value_scoped_list_gen scoped;
- value_tag tag;
- value_entry entry;
- value_sort sort;
+ scoped_parser<value_builder_save> save;
+ scoped_parser<value_builder_list> list;
+ ph::function<value_entry> entry;
+ ph::function<value_reset> reset;
+ ph::function<value_sort> sort;
     };
 }
 

Modified: trunk/tools/quickbook/test/link.quickbook
==============================================================================
--- trunk/tools/quickbook/test/link.quickbook (original)
+++ trunk/tools/quickbook/test/link.quickbook 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -4,7 +4,7 @@
 [section Different types of links]
 
 [@http://www.boost.org/]
-[@http://www.boost.org/ Boost]
+[@ http://www.boost.org/ Boost]
 [link link-id]
 [link link-id Link Text]
 [#link-id]

Modified: trunk/tools/quickbook/test/list_test.gold
==============================================================================
--- trunk/tools/quickbook/test/list_test.gold (original)
+++ trunk/tools/quickbook/test/list_test.gold 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -210,6 +210,35 @@
       </simpara>
     </listitem>
   </orderedlist>
+ <para>
+ Markup in list:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ <emphasis role="bold">Bold</emphasis>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ <emphasis role="bold">Bold</emphasis>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ <quote>Quoted</quote>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ <footnote>
+ <para>
+ Footnote
+ </para>
+ </footnote>
+ </simpara>
+ </listitem>
+ </itemizedlist>
   <section id="list_test.list_immediately_following_markup">
     <title><link linkend="list_test.list_immediately_following_markup">List immediately
     following markup</link></title>

Modified: trunk/tools/quickbook/test/list_test.quickbook
==============================================================================
--- trunk/tools/quickbook/test/list_test.quickbook (original)
+++ trunk/tools/quickbook/test/list_test.quickbook 2011-03-19 10:43:12 EDT (Sat, 19 Mar 2011)
@@ -52,6 +52,13 @@
 # G
 # H
 
+Markup in list:
+
+* *Bold*
+* [*Bold]
+* ["Quoted]
+* [footnote Footnote]
+
 [section List immediately following markup]
 * One
 * Two


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk