Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r70930 - in branches/release/tools/quickbook: . doc src test test/command-line test/doc-info test/include test/include/sub test/snippets test/src test/unit
From: dnljms_at_[hidden]
Date: 2011-04-03 07:51:00


Author: danieljames
Date: 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
New Revision: 70930
URL: http://svn.boost.org/trac/boost/changeset/70930

Log:
Quickbook: merge quickbook 1.5.5
Added:
   branches/release/tools/quickbook/src/block_tags.hpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/block_tags.hpp
   branches/release/tools/quickbook/src/cleanup.hpp
      - copied unchanged from r70569, /trunk/tools/quickbook/src/cleanup.hpp
   branches/release/tools/quickbook/src/doc_info_tags.hpp
      - copied unchanged from r70210, /trunk/tools/quickbook/src/doc_info_tags.hpp
   branches/release/tools/quickbook/src/iterator.hpp
      - copied, changed from r70044, /trunk/tools/quickbook/src/iterator.hpp
   branches/release/tools/quickbook/src/parsers.hpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/parsers.hpp
   branches/release/tools/quickbook/src/phrase_tags.hpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/phrase_tags.hpp
   branches/release/tools/quickbook/src/scoped.hpp
      - copied unchanged from r70210, /trunk/tools/quickbook/src/scoped.hpp
   branches/release/tools/quickbook/src/template_tags.hpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/template_tags.hpp
   branches/release/tools/quickbook/src/value_tags.hpp
      - copied unchanged from r70210, /trunk/tools/quickbook/src/value_tags.hpp
   branches/release/tools/quickbook/src/values.cpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/values.cpp
   branches/release/tools/quickbook/src/values.hpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/values.hpp
   branches/release/tools/quickbook/src/values_parse.hpp
      - copied, changed from r70210, /trunk/tools/quickbook/src/values_parse.hpp
   branches/release/tools/quickbook/test/command-line/
      - copied from r70210, /trunk/tools/quickbook/test/command-line/
   branches/release/tools/quickbook/test/command-line/Jamfile.v2
      - copied unchanged from r70210, /trunk/tools/quickbook/test/command-line/Jamfile.v2
   branches/release/tools/quickbook/test/command-line/error-fail.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/command-line/error-fail.quickbook
   branches/release/tools/quickbook/test/command-line/error1.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/command-line/error1.quickbook
   branches/release/tools/quickbook/test/command-line/error2.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/command-line/error2.quickbook
   branches/release/tools/quickbook/test/doc-info/
      - copied from r70210, /trunk/tools/quickbook/test/doc-info/
   branches/release/tools/quickbook/test/doc-info/Jamfile.v2
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/Jamfile.v2
   branches/release/tools/quickbook/test/doc-info/author1.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/author1.gold
   branches/release/tools/quickbook/test/doc-info/author1.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/author1.quickbook
   branches/release/tools/quickbook/test/doc-info/author2.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/author2.gold
   branches/release/tools/quickbook/test/doc-info/author2.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/author2.quickbook
   branches/release/tools/quickbook/test/doc-info/copyright-fail1.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/copyright-fail1.quickbook
   branches/release/tools/quickbook/test/doc-info/copyright-fail2.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/copyright-fail2.quickbook
   branches/release/tools/quickbook/test/doc-info/copyright1.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/copyright1.gold
   branches/release/tools/quickbook/test/doc-info/copyright1.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/copyright1.quickbook
   branches/release/tools/quickbook/test/doc-info/duplicates-1.1.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/duplicates-1.1.gold
   branches/release/tools/quickbook/test/doc-info/duplicates-1.1.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/duplicates-1.1.quickbook
   branches/release/tools/quickbook/test/doc-info/duplicates-1.5.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/duplicates-1.5.gold
   branches/release/tools/quickbook/test/doc-info/duplicates-1.5.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/duplicates-1.5.quickbook
   branches/release/tools/quickbook/test/doc-info/empty-attributes.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/empty-attributes.gold
   branches/release/tools/quickbook/test/doc-info/empty-attributes.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/empty-attributes.quickbook
   branches/release/tools/quickbook/test/doc-info/encode-1.5.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/encode-1.5.gold
   branches/release/tools/quickbook/test/doc-info/encode-1.5.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/encode-1.5.quickbook
   branches/release/tools/quickbook/test/doc-info/escape-1.6.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/escape-1.6.gold
   branches/release/tools/quickbook/test/doc-info/escape-1.6.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/escape-1.6.quickbook
   branches/release/tools/quickbook/test/doc-info/source-mode-1.4.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-1.4.gold
   branches/release/tools/quickbook/test/doc-info/source-mode-1.4.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-1.4.quickbook
   branches/release/tools/quickbook/test/doc-info/source-mode-1.5.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-1.5.gold
   branches/release/tools/quickbook/test/doc-info/source-mode-1.5.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-1.5.quickbook
   branches/release/tools/quickbook/test/doc-info/source-mode-1.6.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-1.6.gold
   branches/release/tools/quickbook/test/doc-info/source-mode-1.6.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-1.6.quickbook
   branches/release/tools/quickbook/test/doc-info/source-mode-cpp-include.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-cpp-include.quickbook
   branches/release/tools/quickbook/test/doc-info/source-mode-python-include.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-python-include.quickbook
   branches/release/tools/quickbook/test/doc-info/source-mode-teletype-include.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/doc-info/source-mode-teletype-include.quickbook
   branches/release/tools/quickbook/test/elements_1_5.gold
      - copied unchanged from r70301, /trunk/tools/quickbook/test/elements_1_5.gold
   branches/release/tools/quickbook/test/elements_1_5.quickbook
      - copied unchanged from r70301, /trunk/tools/quickbook/test/elements_1_5.quickbook
   branches/release/tools/quickbook/test/elements_1_6.gold
      - copied unchanged from r70301, /trunk/tools/quickbook/test/elements_1_6.gold
   branches/release/tools/quickbook/test/elements_1_6.quickbook
      - copied unchanged from r70301, /trunk/tools/quickbook/test/elements_1_6.quickbook
   branches/release/tools/quickbook/test/fail-mismatched-boostbook-escape.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/fail-mismatched-boostbook-escape.quickbook
   branches/release/tools/quickbook/test/include/
      - copied from r70301, /trunk/tools/quickbook/test/include/
   branches/release/tools/quickbook/test/include/Jamfile.v2
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/Jamfile.v2
   branches/release/tools/quickbook/test/include/filename-path.gold
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/filename-path.gold
   branches/release/tools/quickbook/test/include/filename-path.quickbook
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/filename-path.quickbook
   branches/release/tools/quickbook/test/include/filename.gold
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/filename.gold
   branches/release/tools/quickbook/test/include/filename.quickbook
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/filename.quickbook
   branches/release/tools/quickbook/test/include/filename_include2.quickbook
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/filename_include2.quickbook
   branches/release/tools/quickbook/test/include/sub/
      - copied from r70301, /trunk/tools/quickbook/test/include/sub/
   branches/release/tools/quickbook/test/include/sub/filename_include1.quickbook
      - copied unchanged from r70301, /trunk/tools/quickbook/test/include/sub/filename_include1.quickbook
   branches/release/tools/quickbook/test/snippets/
      - copied from r70210, /trunk/tools/quickbook/test/snippets/
   branches/release/tools/quickbook/test/snippets/Jamfile.v2
      - copied unchanged from r70210, /trunk/tools/quickbook/test/snippets/Jamfile.v2
   branches/release/tools/quickbook/test/snippets/pass_thru.cpp
      - copied, changed from r70210, /trunk/tools/quickbook/test/snippets/pass_thru.cpp
   branches/release/tools/quickbook/test/snippets/pass_thru.gold
      - copied unchanged from r70210, /trunk/tools/quickbook/test/snippets/pass_thru.gold
   branches/release/tools/quickbook/test/snippets/pass_thru.py
      - copied, changed from r70210, /trunk/tools/quickbook/test/snippets/pass_thru.py
   branches/release/tools/quickbook/test/snippets/pass_thru.quickbook
      - copied unchanged from r70210, /trunk/tools/quickbook/test/snippets/pass_thru.quickbook
   branches/release/tools/quickbook/test/src/Jamfile.v2
      - copied, changed from r69832, /trunk/tools/quickbook/test/src/Jamfile.v2
   branches/release/tools/quickbook/test/unit/
      - copied from r70210, /trunk/tools/quickbook/test/unit/
   branches/release/tools/quickbook/test/unit/Jamfile.v2
      - copied, changed from r70210, /trunk/tools/quickbook/test/unit/Jamfile.v2
   branches/release/tools/quickbook/test/unit/iterator_tests.cpp
      - copied unchanged from r70569, /trunk/tools/quickbook/test/unit/iterator_tests.cpp
   branches/release/tools/quickbook/test/unit/post_process_test.cpp
      - copied unchanged from r70210, /trunk/tools/quickbook/test/unit/post_process_test.cpp
   branches/release/tools/quickbook/test/unit/values_test.cpp
      - copied, changed from r70210, /trunk/tools/quickbook/test/unit/values_test.cpp
Removed:
   branches/release/tools/quickbook/src/rule_store.hpp
   branches/release/tools/quickbook/src/scoped_parser.hpp
   branches/release/tools/quickbook/test/doc-info-1.gold
   branches/release/tools/quickbook/test/doc-info-1.quickbook
   branches/release/tools/quickbook/test/doc-info-2.gold
   branches/release/tools/quickbook/test/doc-info-2.quickbook
   branches/release/tools/quickbook/test/doc-info-3.gold
   branches/release/tools/quickbook/test/doc-info-3.quickbook
   branches/release/tools/quickbook/test/doc-info-4.gold
   branches/release/tools/quickbook/test/doc-info-4.quickbook
Properties modified:
   branches/release/tools/quickbook/ (props changed)
   branches/release/tools/quickbook/doc/ (props changed)
   branches/release/tools/quickbook/src/ (props changed)
   branches/release/tools/quickbook/test/ (props changed)
Text files modified:
   branches/release/tools/quickbook/doc/quickbook.qbk | 56 +
   branches/release/tools/quickbook/src/Jamfile.v2 | 9
   branches/release/tools/quickbook/src/actions.cpp | 1626 ++++++++++++++++++++++++---------------
   branches/release/tools/quickbook/src/actions.hpp | 716 +---------------
   branches/release/tools/quickbook/src/actions_class.cpp | 181 ---
   branches/release/tools/quickbook/src/actions_class.hpp | 187 ---
   branches/release/tools/quickbook/src/block_element_grammar.cpp | 261 ++---
   branches/release/tools/quickbook/src/block_tags.hpp | 3
   branches/release/tools/quickbook/src/code_snippet.cpp | 144 ++-
   branches/release/tools/quickbook/src/doc_info_actions.cpp | 344 +++++--
   branches/release/tools/quickbook/src/doc_info_grammar.cpp | 259 +++--
   branches/release/tools/quickbook/src/fwd.hpp | 11
   branches/release/tools/quickbook/src/grammar.cpp | 2
   branches/release/tools/quickbook/src/grammar.hpp | 2
   branches/release/tools/quickbook/src/grammar_impl.hpp | 27
   branches/release/tools/quickbook/src/input_path.cpp | 256 +++++-
   branches/release/tools/quickbook/src/input_path.hpp | 127 ++
   branches/release/tools/quickbook/src/iterator.hpp | 15
   branches/release/tools/quickbook/src/main_grammar.cpp | 527 +++++++-----
   branches/release/tools/quickbook/src/markups.cpp | 149 +--
   branches/release/tools/quickbook/src/markups.hpp | 100 --
   branches/release/tools/quickbook/src/parsers.hpp | 7
   branches/release/tools/quickbook/src/phrase_element_grammar.cpp | 220 +----
   branches/release/tools/quickbook/src/phrase_tags.hpp | 2
   branches/release/tools/quickbook/src/post_process.cpp | 44
   branches/release/tools/quickbook/src/post_process.hpp | 16
   branches/release/tools/quickbook/src/quickbook.cpp | 229 ++++-
   branches/release/tools/quickbook/src/quickbook.hpp | 15
   branches/release/tools/quickbook/src/syntax_highlight.hpp | 31
   branches/release/tools/quickbook/src/template_stack.cpp | 19
   branches/release/tools/quickbook/src/template_stack.hpp | 62 -
   branches/release/tools/quickbook/src/template_tags.hpp | 1
   branches/release/tools/quickbook/src/utils.cpp | 63 -
   branches/release/tools/quickbook/src/utils.hpp | 50
   branches/release/tools/quickbook/src/values.cpp | 309 +++++-
   branches/release/tools/quickbook/src/values.hpp | 70 +
   branches/release/tools/quickbook/src/values_parse.hpp | 2
   branches/release/tools/quickbook/test/Jamfile.v2 | 62
   branches/release/tools/quickbook/test/anchor.gold | 53 +
   branches/release/tools/quickbook/test/anchor.quickbook | 14
   branches/release/tools/quickbook/test/blocks.gold | 8
   branches/release/tools/quickbook/test/code-block.gold | 2
   branches/release/tools/quickbook/test/heading.gold | 6
   branches/release/tools/quickbook/test/heading_1_6.gold | 6
   branches/release/tools/quickbook/test/identifier_1_5.gold | 2
   branches/release/tools/quickbook/test/identifier_1_6.gold | 2
   branches/release/tools/quickbook/test/link.quickbook | 2
   branches/release/tools/quickbook/test/list_test.gold | 265 +++--
   branches/release/tools/quickbook/test/list_test.quickbook | 7
   branches/release/tools/quickbook/test/quickbook-manual.gold | 256 +++---
   branches/release/tools/quickbook/test/quickbook-testing.jam | 46
   branches/release/tools/quickbook/test/simple_markup.gold | 33
   branches/release/tools/quickbook/test/simple_markup.quickbook | 23
   branches/release/tools/quickbook/test/snippets/pass_thru.cpp | 8
   branches/release/tools/quickbook/test/snippets/pass_thru.py | 6
   branches/release/tools/quickbook/test/src/Jamfile.v2 | 8
   branches/release/tools/quickbook/test/table_1_5.gold | 89 ++
   branches/release/tools/quickbook/test/table_1_5.quickbook | 31
   branches/release/tools/quickbook/test/template-section.gold | 2
   branches/release/tools/quickbook/test/unicode-escape.gold | 2
   branches/release/tools/quickbook/test/unit/Jamfile.v2 | 9
   branches/release/tools/quickbook/test/unit/values_test.cpp | 53 +
   branches/release/tools/quickbook/test/utf-8-bom.gold | 2
   branches/release/tools/quickbook/test/utf-8.gold | 2
   branches/release/tools/quickbook/test/variablelist.gold | 12
   branches/release/tools/quickbook/test/variablelist.quickbook | 11
   branches/release/tools/quickbook/test/xinclude.gold | 2
   67 files changed, 3870 insertions(+), 3296 deletions(-)

Modified: branches/release/tools/quickbook/doc/quickbook.qbk
==============================================================================
--- branches/release/tools/quickbook/doc/quickbook.qbk (original)
+++ branches/release/tools/quickbook/doc/quickbook.qbk 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -239,7 +239,9 @@
   * XML escape documentation fields, with escapes to allow encoding unicode
     in ASCII.
 
-[heading Version 1.5.4 - Boost 1.46.0]
+[heading Version 1.5.4 - Boost 1.46.1]
+
+Boost 1.46.0:
 
 * Add support for `lang` attribute in documentation info.
 * Improved anchor implementation. Especially for using an anchor
@@ -251,6 +253,46 @@
 * Rearrange the structure of the grammar.
 * Use filesystem 3. Remove cygwin support.
 
+Boost 1.46.1:
+
+* Work around optimization bug in g++ 4.4 on 64 bit linux.
+
+[heading Version 1.5.5 - Boost 1.47]
+
+* Tweak anchor placement for titles.
+* Hard code the quickbook path into the quickbook testing tools. This
+ means that they can be used from multiple locations.
+* Generate an id for boostbook `bridgehead` elements. This results in
+ more consistent html, since docbook generates a random id if they
+ don't have one.
+* Improved unicode support on windows. Unicode can now be used from the
+ command line, and unicode filenames are supported. Unicode output is
+ a bit weak.
+* Check for windows paths, and warn about them.
+* Fix relative path detection on windows.
+* Reverse deprecation of `[br]`, printing a single warning about
+ generating invalid boostbook.
+* Fix handling empty category attributes.
+* Store data from the parser in a dynamic data structure.
+ This simplifies the implementation and makes it easier to parse
+ more complicated data structures.
+* Improved error messages for unknown doc info attributes.
+* Richer copyright syntax. Now understands:
+ `[copyright 2001-2006, 2010 One person, 2008 Another person]`.
+* Fix delimeter checking for simple markup.
+* Allow more block elements to be nested.
+* Go back to using invalid markup for lists. It generates better html.
+* Better anchor placement for lists.
+* Pass-thru comments in code snippets.
+* Use relative paths for `__FILENAME__` macro.
+* Rewrite xinclude path generator so that it doesn't use deprecated
+ filesystem functions.
+* Quickbook 1.6:
+ * Scope source mode changes to the file they're made in.
+ * Explicit markup for lists. e.g.
+ `[ordered_list [item1][item2]]` or
+ `[itemized_list [item1][item2]]`.
+
 [endsect] [/Change log]
 
 [section:syntax Syntax Summary]
@@ -1902,6 +1944,18 @@
 can be used to inhibit code from passing through to quickbook. All text between
 the delimeters will simply be ignored.
 
+Comments of this form:
+
+ //=int main() {}
+
+or
+
+ /*=foo()*/
+
+will be displayed as code that isn't in comments. This allows you to
+include some code in the snippet but not actually use it when
+compiling your example.
+
 [heading Callouts]
 
 Special comments of the form:

Modified: branches/release/tools/quickbook/src/Jamfile.v2
==============================================================================
--- branches/release/tools/quickbook/src/Jamfile.v2 (original)
+++ branches/release/tools/quickbook/src/Jamfile.v2 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -14,8 +14,12 @@
         <toolset>darwin:<c++-template-depth>300
         <toolset>gcc:<cflags>-g0
         <toolset>darwin:<cflags>-g0
+ <warnings>all
+ <toolset>msvc:<cflags>/wd4709
     ;
 
+lib shell32 ;
+
 exe quickbook
     :
     quickbook.cpp
@@ -24,6 +28,7 @@
     actions_class.cpp
     utils.cpp
     input_path.cpp
+ values.cpp
     post_process.cpp
     collector.cpp
     template_stack.cpp
@@ -38,8 +43,7 @@
     /boost//program_options
     /boost//filesystem
     : #<define>QUICKBOOK_NO_DATES
- # Still using 'normalize' which has been deprecated.
- #<define>BOOST_FILESYSTEM_NO_DEPRECATED
+ <define>BOOST_FILESYSTEM_NO_DEPRECATED
       <toolset>msvc:<cxxflags>/wd4355
       <toolset>msvc:<cxxflags>/wd4511
       <toolset>msvc:<cxxflags>/wd4512
@@ -50,4 +54,5 @@
       <toolset>msvc:<cxxflags>/wd4800
       <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
       <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
+ <target-os>windows:<library>shell32
     ;

Modified: branches/release/tools/quickbook/src/actions.cpp
==============================================================================
--- branches/release/tools/quickbook/src/actions.cpp (original)
+++ branches/release/tools/quickbook/src/actions.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,28 +10,33 @@
 =============================================================================*/
 #include <numeric>
 #include <functional>
-#include <algorithm>
+#include <vector>
+#include <map>
 #include <boost/filesystem/v3/convenience.hpp>
 #include <boost/filesystem/v3/fstream.hpp>
+#include <boost/range/distance.hpp>
+#include <boost/range/algorithm/replace.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/foreach.hpp>
 #include "quickbook.hpp"
 #include "actions.hpp"
 #include "utils.hpp"
 #include "markups.hpp"
 #include "actions_class.hpp"
 #include "grammar.hpp"
+#include "input_path.hpp"
+#include "block_tags.hpp"
+#include "phrase_tags.hpp"
 
 namespace quickbook
 {
     char const* quickbook_get_date = "__quickbook_get_date__";
     char const* quickbook_get_time = "__quickbook_get_time__";
 
- int qbk_major_version = -1;
- int qbk_minor_version = -1;
     unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version
 
- void assign_qbk_version::operator()(int value) const { v_ = value; }
-
     namespace {
         std::string fully_qualified_id(std::string const& library_id,
             std::string const& qualified_section_id,
@@ -44,281 +49,478 @@
             id += section_id;
             return id;
         }
+
+ void write_anchors(quickbook::actions& actions, collector& tgt)
+ {
+ for(quickbook::actions::string_list::iterator
+ it = actions.anchors.begin(),
+ end = actions.anchors.end();
+ it != end; ++it)
+ {
+ tgt << "<anchor id=\"";
+ detail::print_string(*it, tgt.get());
+ tgt << "\"/>\n";
+ }
+
+ actions.anchors.clear();
+ }
+ }
+
+ void list_action(quickbook::actions&, value);
+ void explicit_list_action(quickbook::actions&, value);
+ void header_action(quickbook::actions&, value);
+ void begin_section_action(quickbook::actions&, value);
+ void end_section_action(quickbook::actions&, value, file_position);
+ void block_action(quickbook::actions&, value);
+ void block_empty_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 raw_phrase_action(quickbook::actions&, value);
+ void source_mode_action(quickbook::actions&, value);
+ void do_template_action(quickbook::actions&, value, file_position);
+
+ void element_action::operator()(iterator first, iterator) const
+ {
+ value_consumer values = actions.values.release();
+ if(!values.check()) return;
+ value v = values.consume();
+ if(values.check()) return;
+
+ switch(v.get_tag())
+ {
+ case block_tags::list:
+ return list_action(actions, v);
+ case block_tags::ordered_list:
+ case block_tags::itemized_list:
+ return explicit_list_action(actions, v);
+ case block_tags::generic_heading:
+ case block_tags::heading1:
+ case block_tags::heading2:
+ 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::hr:
+ return block_empty_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 phrase_tags::escape:
+ return raw_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);
+ case template_tags::template_:
+ return do_template_action(actions, v, first.get_position());
+ default:
+ break;
+ }
     }
 
     // Handles line-breaks (DEPRECATED!!!)
     void break_action::operator()(iterator first, iterator) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
+
+ file_position const pos = first.get_position();
+ if(*first == '\\')
+ {
+ detail::outwarn(actions.filename, pos.line)
+ << "in column:" << pos.column << ", "
+ << "'\\n' is deprecated, pleases use '[br]' instead" << ".\n";
+ }
+
+ if(!actions.warned_about_breaks)
+ {
+ detail::outwarn(actions.filename, pos.line)
+ << "line breaks generate invalid boostbook"
+ << " (will only note first occurrence)."
+ << "\n";
+
+ actions.warned_about_breaks = true;
+ }
+
+ phrase << detail::get_markup(phrase_tags::break_mark).pre;
+ }
+
+ void error_message_action::operator()(iterator first, iterator last) const
+ {
+ file_position const pos = first.get_position();
+
+ std::string value(first, last);
+ std::string formatted_message = message;
+ boost::replace_all(formatted_message, "%s", value);
+ boost::replace_all(formatted_message, "%c",
+ boost::lexical_cast<std::string>(pos.column));
 
- position const pos = first.get_position();
- detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", "
- << "[br] and \\n are deprecated" << ".\n";
- phrase << break_mark;
+ detail::outerr(actions.filename, pos.line)
+ << detail::utf8(formatted_message) << std::endl;
+ ++actions.error_count;
     }
 
     void error_action::operator()(iterator first, iterator /*last*/) const
     {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const pos = first.get_position();
+ detail::outerr(actions.filename, pos.line)
             << "Syntax Error near column " << pos.column << ".\n";
- ++error_count;
+ ++actions.error_count;
     }
 
- void tagged_action::operator()(std::string const& str) const
+ void block_action(quickbook::actions& actions, value block)
     {
- if(!actions.output_pre(out)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, actions.out);
 
- out << pre << str << post;
+ detail::markup markup = detail::get_markup(block.get_tag());
+
+ value_consumer values = block;
+ actions.out << markup.pre << values.consume().get_boostbook() << markup.post;
+ values.finish();
     }
 
- void phrase_action::operator()() const
+ void block_empty_action(quickbook::actions& actions, value block)
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, actions.out);
 
- std::string str;
- phrase.swap(str);
- out << pre << str << post;
+ detail::markup markup = detail::get_markup(block.get_tag());
+ actions.out << markup.pre;
+ }
+
+ void phrase_action(quickbook::actions& actions, value phrase)
+ {
+ if (actions.suppress) return;
+ write_anchors(actions, actions.phrase);
+
+ detail::markup markup = detail::get_markup(phrase.get_tag());
+
+ value_consumer values = phrase;
+ actions.phrase << markup.pre << values.consume().get_boostbook() << markup.post;
+ values.finish();
     }
 
- void implicit_paragraph_action::operator()() const
+ void raw_phrase_action(quickbook::actions& actions, value phrase)
+ {
+ if (actions.suppress) return;
+ write_anchors(actions, actions.phrase);
+
+ detail::markup markup = detail::get_markup(phrase.get_tag());
+ actions.phrase << markup.pre << phrase.get_quickbook() << markup.post;
+ }
+
+ 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::get_markup(block_tags::paragraph);
+ actions.out << markup.pre << str;
+ write_anchors(actions, actions.out);
+ actions.out << markup.post;
+ }
+ }
+
+ namespace {
+ void write_bridgehead(collector& out, int level,
+ std::string const& str, std::string const& id, std::string const& linkend)
+ {
+ out << "<bridgehead renderas=\"sect" << level << "\"";
+ if(!id.empty()) out << " id=\"" << id << "\"";
+ out << ">";
+ if(!linkend.empty()) out << "<link linkend=\"" << linkend << "\">";
+ out << str;
+ if(!linkend.empty()) out << "</link>";
+ out << "</bridgehead>";
         }
     }
 
- 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 = 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();
+ values.finish();
+
+ 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 =
- !element_id.empty() ? element_id :
- qbk_version_n >= 106 ? detail::make_identifier(first, last) :
- detail::make_identifier(str.begin(), str.end());
+ !element_id.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);
+ write_anchors(actions, actions.out);
         
- if (qbk_version_n < 103)
- {
- out << pre << str << post
- ;
- }
- else // version 1.3 and above
- {
- out << pre
- << "<link linkend=\"" << anchor << "\">"
- << str
- << "</link>"
- << post
- ;
- }
+ write_bridgehead(actions.out, level,
+ content.get_boostbook(), anchor + "-heading", linkend);
     }
 
- void generic_header_action::operator()(iterator first, iterator last) const
+ void simple_phrase_action::operator()(char mark) 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);
-
- std::string id =
- !element_id.empty() ? element_id :
- 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);
+ if (actions.suppress) return;
+ write_anchors(actions, out);
 
- out
- << "<bridgehead renderas=\"sect" << level_ << "\">"
- << "<link linkend=\"" << anchor << "\">"
- << str
- << "</link>"
- << "</bridgehead>"
- ;
- }
+ int tag =
+ mark == '*' ? phrase_tags::bold :
+ mark == '/' ? phrase_tags::italic :
+ mark == '_' ? phrase_tags::underline :
+ mark == '=' ? phrase_tags::teletype :
+ 0;
+
+ assert(tag != 0);
+ detail::markup markup = detail::get_markup(tag);
 
- void simple_phrase_action::operator()(iterator first, iterator last) const
- {
- if(!actions.output_pre(out)) return;
+ value_consumer values = actions.values.release();
+ value content = values.consume();
+ values.finish();
 
- out << pre;
- std::string str(first, last);
- if (std::string const* ptr = find(macro, str.c_str()))
+ out << markup.pre;
+ if (std::string const* ptr = find(macro, content.get_quickbook().c_str()))
         {
             out << *ptr;
         }
         else
         {
- while (first != last)
- detail::print_char(*first++, out.get());
+ out << content.get_boostbook();
         }
- out << post;
+ out << markup.post;
     }
 
- void cond_phrase_action_pre::operator()(iterator first, iterator last) const
+ bool cond_phrase_push::start()
     {
- std::string str(first, last);
- condition = find(macro, str.c_str());
- }
+ saved_suppress = actions.suppress;
+
+ value_consumer values = actions.values.release();
+ bool condition = find(actions.macro,
+ values.consume().get_quickbook().c_str());
+
+ actions.suppress = actions.suppress || !condition;
 
- cond_phrase_push::cond_phrase_push(quickbook::actions& actions)
- : actions(actions)
- , saved_suppress(actions.suppress)
- {
- actions.suppress = actions.suppress || !actions.condition;
+ return true;
     }
     
- 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;
+ write_anchors(actions, actions.out);
 
- 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();
+ values.finish();
 
- 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 << "</simpara></listitem>";
+ actions.out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
+ }
+ actions.out << "</simpara></listitem>";
+ }
+ else
+ {
+ actions.out << "</simpara></listitem>";
+ }
 
- while (!list_marks.empty() && (list_indent < list_marks.top().second))
+ if (mark != list_marks.top().first) // new_indent == list_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>";
+ 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><simpara>";
+ actions.out << content;
         }
 
- if (mark != list_marks.top().first) // new_indent == list_indent
+ assert(!list_marks.empty());
+ while (!list_marks.empty())
         {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
- << "Illegal change of list style near column " << pos.column << ".\n";
- detail::outwarn(pos.file,pos.line)
- << "Ignoring change of list style" << std::endl;
- ++error_count;
+ char mark = list_marks.top().first;
+ list_marks.pop();
+ actions.out << "</simpara></listitem>";
+ actions.out << ((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");
         }
     }
 
+ void explicit_list_action(quickbook::actions& actions, value list)
+ {
+ if (actions.suppress) return;
+ write_anchors(actions, actions.out);
+
+ detail::markup markup = detail::get_markup(list.get_tag());
+
+ actions.out << markup.pre;
+
+ BOOST_FOREACH(value item, list)
+ {
+ actions.out << "<listitem>";
+ actions.out << item.get_boostbook();
+ actions.out << "</listitem>";
+ }
+
+ actions.out << markup.post;
+ }
+
     // TODO: No need to check suppress since this is only used in the syntax
     // highlighter. I should moved this or something.
     void span::operator()(iterator first, iterator last) const
@@ -331,11 +533,11 @@
 
     void unexpected_char::operator()(iterator first, iterator last) const
     {
- position const pos = first.get_position();
+ file_position const pos = first.get_position();
 
- detail::outwarn(pos.file, pos.line)
+ detail::outwarn(actions.filename, pos.line)
             << "in column:" << pos.column
- << ", unexpected character: " << std::string(first, last)
+ << ", unexpected character: " << detail::utf8(first, last)
             << "\n";
 
         // print out an unexpected character
@@ -345,15 +547,19 @@
         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());
+ values.finish();
     }
 
     void do_macro_action::operator()(std::string const& str) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
 
         if (str == quickbook_get_date)
         {
@@ -384,21 +590,27 @@
             detail::print_space(*first++, out.get());
     }
 
- void pre_escape_back::operator()(iterator first, iterator last) const
+ void pre_escape_back::operator()(iterator, iterator) const
     {
         escape_actions.phrase.push(); // save the stream
     }
 
- void post_escape_back::operator()(iterator first, iterator last) const
+ void post_escape_back::operator()(iterator, iterator) const
     {
- escape_actions.output_pre(escape_actions.phrase);
+ write_anchors(escape_actions, escape_actions.phrase);
         out << escape_actions.phrase.str();
         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;
+ if (actions.suppress) return;
+ write_anchors(actions, out);
 
         // preprocess the code section to remove the initial indentation
         std::string program(first, last);
@@ -406,9 +618,8 @@
         if (program.size() == 0)
             return; // Nothing left to do here. The program is empty.
 
- iterator first_(program.begin(), program.end());
- iterator last_(program.end(), program.end());
- first_.set_position(first.get_position());
+ iterator first_(program.begin(), first.get_position());
+ iterator last_(program.end());
 
         // TODO: Shouldn't phrase be empty here? Why would it be output
         // after the code block?
@@ -431,7 +642,8 @@
 
     void inline_code_action::operator()(iterator first, iterator last) const
     {
- if(!actions.output_pre(out)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, out);
 
         std::string save;
         out.swap(save);
@@ -448,31 +660,40 @@
 
     void raw_char_action::operator()(char ch) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
+
         phrase << ch;
     }
 
     void raw_char_action::operator()(iterator first, iterator /*last*/) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
+
         phrase << *first;
     }
 
     void plain_char_action::operator()(char ch) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
+
         detail::print_char(ch, phrase.get());
     }
 
     void plain_char_action::operator()(iterator first, iterator /*last*/) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
+
         detail::print_char(*first, phrase.get());
     }
 
     void escape_unicode_action::operator()(iterator first, iterator last) const
     {
- if(!actions.output_pre(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, phrase);
 
         while(first != last && *first == '0') ++first;
 
@@ -491,34 +712,86 @@
         }
     }
 
- void attribute_action::operator()(iterator first, iterator last) const
+ void image_action(quickbook::actions& actions, value image)
     {
- position const pos = first.get_position();
+ if (actions.suppress) return;
+ write_anchors(actions, actions.phrase);
+
+ typedef std::map<std::string, value> attribute_map;
+ attribute_map attributes;
 
- if (!attributes.insert(
- attribute_map::value_type(attribute_name, std::string(first, last))
- ).second)
+ value_consumer values = image;
+ attributes["fileref"] = values.consume();
+
+ BOOST_FOREACH(value pair_, values)
         {
- detail::outwarn(pos.file,pos.line)
- << "Repeated attribute: " << attribute_name << ".\n";
+ value_consumer pair = pair_;
+ value name = pair.consume();
+ value value = pair.consume();
+ pair.finish();
+ if(!attributes.insert(std::make_pair(name.get_quickbook(), value)).second)
+ {
+ detail::outwarn(actions.filename, name.get_position().line)
+ << "Duplicate image attribute: "
+ << detail::utf8(name.get_quickbook())
+ << std::endl;
+ }
         }
- }
-
- void image_action::operator()(iterator, iterator) const
- {
- if(!actions.output_pre(phrase)) return;
+
+ values.finish();
 
- fs::path const img_path(image_fileref);
+ // Find the file basename and extension.
+ //
+ // Not using Boost.Filesystem because I want to stay in UTF-8.
+ // Need to think about uri encoding.
         
- attribute_map::iterator it = attributes.find("alt");
- std::string alt_text = it != attributes.end() ?
- it->second :
- img_path.stem().generic_string();
- attributes.erase("alt");
+ std::string fileref = attributes["fileref"].get_quickbook();
+
+ // Check for windows paths, then convert.
+ // A bit crude, but there you go.
+
+ if(fileref.find('\\') != std::string::npos)
+ {
+ detail::outwarn(actions.filename, attributes["fileref"].get_position().line)
+ << "Image path isn't portable: '"
+ << detail::utf8(fileref)
+ << "'"
+ << std::endl;
+ }
+
+ boost::replace(fileref, '\\', '/');
 
- attributes.insert(attribute_map::value_type("fileref", image_fileref));
+ // Find the file basename and extension.
+ //
+ // Not using Boost.Filesystem because I want to stay in UTF-8.
+ // Need to think about uri encoding.
+
+ std::string::size_type pos;
+ std::string stem,extension;
+
+ pos = fileref.rfind('/');
+ stem = pos == std::string::npos ?
+ fileref :
+ fileref.substr(pos + 1);
 
- if(img_path.extension() == ".svg")
+ pos = stem.rfind('.');
+ if (pos != std::string::npos)
+ {
+ extension = stem.substr(pos + 1);
+ stem = stem.substr(0, pos);
+ }
+
+ // Extract the alt tag, to use as a text description.
+ // Or if there isn't one, use the stem of the file name.
+ // TODO: IMO if there isn't an alt tag, then the description should
+ // be empty or missing.
+
+ attribute_map::iterator alt_pos = attributes.find("alt");
+ std::string alt_text = alt_pos != attributes.end() ?
+ alt_pos->second.get_quickbook() : stem;
+ attributes.erase("alt");
+
+ if(extension == ".svg")
         {
            //
            // SVG's need special handling:
@@ -531,15 +804,18 @@
            // a tiny box with scrollbars (Firefox), or else cropped to
            // fit in a tiny box (IE7).
            //
- attributes.insert(attribute_map::value_type("format", "SVG"));
+
+ attributes.insert(attribute_map::value_type("format", qbk_value("SVG")));
+
            //
            // Image paths are relative to the html subdirectory:
            //
- fs::path img;
- if(img_path.root_path().empty())
- img = "html" / img_path; // relative path
- else
- img = img_path; // absolute path
+ // TODO: This seems wrong to me.
+ //
+ fs::path img = detail::generic_to_path(fileref);
+ if(img.root_path().empty())
+ img = "html" / img; // relative path
+
            //
            // Now load the SVG file:
            //
@@ -565,8 +841,10 @@
            b = svg_text.find('\"', a + 1);
            if(a != std::string::npos)
            {
- attributes.insert(attribute_map::value_type("contentwidth",
- std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
+ attributes.insert(std::make_pair(
+ "contentwidth", qbk_value(std::string(
+ svg_text.begin() + a + 1, svg_text.begin() + b))
+ ));
            }
            a = svg_text.find("height");
            a = svg_text.find('=', a);
@@ -574,141 +852,166 @@
            b = svg_text.find('\"', a + 1);
            if(a != std::string::npos)
            {
- attributes.insert(attribute_map::value_type("contentdepth",
- std::string(svg_text.begin() + a + 1, svg_text.begin() + b)));
+ attributes.insert(std::make_pair(
+ "contentdepth", qbk_value(std::string(
+ svg_text.begin() + a + 1, svg_text.begin() + b))
+ ));
            }
         }
 
- phrase << "<inlinemediaobject>";
+ actions.phrase << "<inlinemediaobject>";
 
- phrase << "<imageobject><imagedata";
+ actions.phrase << "<imageobject><imagedata";
         
- for(attribute_map::const_iterator
- attr_first = attributes.begin(), attr_last = attributes.end();
- attr_first != attr_last; ++attr_first)
+ BOOST_FOREACH(attribute_map::value_type const& attr, attributes)
         {
- phrase << " " << attr_first->first << "=\"";
+ actions.phrase << " " << attr.first << "=\"";
 
+ std::string value = attr.second.get_quickbook();
             for(std::string::const_iterator
- first = attr_first->second.begin(),
- last = attr_first->second.end();
+ first = value.begin(), last = value.end();
                 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>";
 
- // Also add a textobject -- use the basename of the image file.
- // This will mean we get "alt" attributes of the HTML img.
- phrase << "<textobject><phrase>";
- detail::print_string(alt_text, phrase.get());
- phrase << "</phrase></textobject>";
+ // Add a textobject containing the alt tag from earlier.
+ // This will be used for the alt tag in html.
+ 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();
+ values.finish();
+
         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 first, iterator last) const
+ void template_body_action(quickbook::actions& actions, quickbook::value template_definition)
     {
         if(actions.suppress) return;
+
+ value_consumer values = template_definition;
+ std::string identifier = values.consume().get_quickbook();
+
+ std::vector<std::string> template_values;
+ BOOST_FOREACH(value const& p, values.consume()) {
+ template_values.push_back(p.get_quickbook());
+ }
+
+ BOOST_ASSERT(values.check(template_tags::block) || values.check(template_tags::phrase));
+ value body = values.consume();
+ BOOST_ASSERT(!values.check());
+
         if (!actions.templates.add(
- template_symbol(actions.template_identifier, actions.template_info,
- std::string(first, last), first.get_position(),
- actions.template_block, &actions.templates.top_scope())))
- {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
- << "Template Redefinition: " << actions.template_identifier << std::endl;
+ template_symbol(
+ identifier,
+ template_values,
+ body,
+ actions.filename,
+ &actions.templates.top_scope())))
+ {
+ file_position const pos = body.get_position();
+ detail::outerr(actions.filename, pos.line)
+ << "Template Redefinition: " << detail::utf8(identifier) << std::endl;
             ++actions.error_count;
         }
-
- actions.template_identifier.clear();
- actions.template_info.clear();
     }
 
     namespace
     {
- iterator find_bracket_end(iterator begin, iterator const& end)
+ iterator find_first_seperator(iterator begin, iterator end)
         {
- unsigned int depth = 1;
-
- while(depth > 0) {
- char const* search_chars = "[]\\";
- begin = std::find_first_of(begin, end, search_chars, search_chars + 3);
- if(begin == end) return begin;
-
- if(*begin == '\\')
- {
- if(++begin == end) return begin;
- ++begin;
- }
- else
+ if(qbk_version_n < 105) {
+ for(;begin != end; ++begin)
                 {
- depth += (*begin == '[') ? 1 : -1;
- ++begin;
+ switch(*begin)
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ return begin;
+ default:
+ break;
+ }
                 }
             }
-
- return begin;
- }
-
- iterator find_first_seperator(iterator const& begin, iterator const& end)
- {
- if(qbk_version_n < 105) {
- char const* whitespace = " \t\r\n";
- return std::find_first_of(begin, end, whitespace, whitespace + 4);
- }
             else {
- iterator pos = begin;
+ unsigned int depth = 0;
 
- while(true)
+ for(;begin != end; ++begin)
                 {
- char const* search_chars = " \t\r\n\\[";
- pos = std::find_first_of(pos, end, search_chars, search_chars + 6);
- if(pos == end) return pos;
-
- switch(*pos)
+ switch(*begin)
                     {
                     case '[':
- pos = find_bracket_end(++pos, end);
+ ++depth;
                         break;
                     case '\\':
- if(++pos == end) return pos;
- ++pos;
+ if(++begin == end) return begin;
                         break;
+ case ']':
+ if (depth > 0) --depth;
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ if (depth == 0) return begin;
                     default:
- return pos;
+ break;
                     }
                 }
             }
+
+ return begin;
+ }
+
+ std::pair<iterator, iterator> find_seperator(iterator begin, iterator end)
+ {
+ iterator first = begin = find_first_seperator(begin, end);
+
+ for(;begin != end; ++begin)
+ {
+ switch(*begin)
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ default:
+ return std::make_pair(first, begin);
+ }
+ }
+
+ return std::make_pair(first, begin);
         }
     
         bool break_arguments(
             std::vector<template_body>& args
           , std::vector<std::string> const& params
- , position const& pos
+ , fs::path const& filename
+ , file_position const& pos
         )
         {
             // Quickbook 1.4-: If there aren't enough parameters seperated by
@@ -729,28 +1032,25 @@
                     // arguments, or if there are no more spaces left.
 
                     template_body& body = args.back();
- iterator begin(body.content.begin(), body.content.end(),
- position(body.position.file.c_str(), body.position.line, body.position.column));
- iterator end(body.content.end(), body.content.end());
+ iterator begin = body.content.get_quickbook_range().begin();
+ iterator end = body.content.get_quickbook_range().end();
                     
- iterator l_pos = find_first_seperator(begin, end);
- if (l_pos == end)
- break;
- char const* whitespace = " \t\r\n";
- char const* whitespace_end = whitespace + 4;
- iterator r_pos = l_pos;
- while(r_pos != end && std::find(whitespace, whitespace_end, *r_pos) != whitespace_end) ++r_pos;
- if (r_pos == end)
- break;
- template_body second(std::string(r_pos, end), r_pos.get_position(), false);
- body.content = std::string(begin, l_pos);
+ std::pair<iterator, iterator> pos =
+ find_seperator(begin, end);
+ if (pos.second == end) break;
+ template_body second(
+ qbk_value(pos.second, end, template_tags::phrase),
+ body.filename);
+
+ body.content = qbk_value(begin, pos.first,
+ body.content.get_tag());
                     args.push_back(second);
                 }
             }
 
             if (args.size() != params.size())
             {
- detail::outerr(pos.file, pos.line)
+ detail::outerr(filename, pos.line)
                     << "Invalid number of arguments passed. Expecting: "
                     << params.size()
                     << " argument(s), got: "
@@ -767,7 +1067,7 @@
             std::vector<template_body>& args
           , std::vector<std::string> const& params
           , template_scope const& scope
- , position const& pos
+ , file_position const& pos
           , quickbook::actions& actions
         )
         {
@@ -781,9 +1081,9 @@
             {
                 if (!actions.templates.add(
                         template_symbol(*tpl, empty_params, arg->content,
- arg->position, arg->is_block, &scope)))
+ arg->filename, &scope)))
                 {
- detail::outerr(pos.file,pos.line)
+ detail::outerr(actions.filename, pos.line)
                         << "Duplicate Symbol Found" << std::endl;
                     ++actions.error_count;
                     return std::make_pair(false, tpl);
@@ -810,17 +1110,18 @@
             {
                 // escape the body of the template
                 // we just copy out the literal body
- (body.is_block ? actions.out : actions.phrase) << body.content;
+ (body.is_block() ? actions.out : actions.phrase) << body.content.get_quickbook();
                 return true;
             }
             else
             {
- if (!body.is_block)
+ if (!body.is_block())
                 {
                     // do a phrase level parse
- iterator first(body.content.begin(), body.content.end(),
- position(body.position.file.c_str(), body.position.line, body.position.column));
- iterator last(body.content.end(), body.content.end());
+ actions.filename = body.filename;
+ iterator first = body.content.get_quickbook_range().begin();
+ iterator last = body.content.get_quickbook_range().end();
+
                     return cl::parse(first, last, actions.grammar().simple_phrase).full;
                 }
                 else
@@ -829,10 +1130,11 @@
                     // ensure that we have enough trailing newlines to eliminate
                     // the need to check for end of file in the grammar.
                     
- std::string content = body.content + "\n\n";
- iterator first(content.begin(), content.end(),
- position(body.position.file.c_str(), body.position.line, body.position.column));
- iterator last(content.end(), content.end());
+ actions.filename = body.filename;
+ std::string content = body.content.get_quickbook() + "\n\n";
+ iterator first(content.begin(), body.content.get_position());
+ iterator last(content.end());
+
                     return cl::parse(first, last, actions.grammar().block).full;
                 }
             }
@@ -844,33 +1146,32 @@
         int callout_id = 0;
     }
 
- void template_arg_action::operator()(iterator first, iterator last) const
+ void do_template_action(quickbook::actions& actions, value template_list,
+ file_position pos)
     {
         if(actions.suppress) return;
 
- actions.template_args.push_back(
- template_body(
- std::string(first, last),
- first.get_position(),
- actions.template_block));
- }
+ // Get the arguments
+ value_consumer values = template_list;
 
- void do_template_action::operator()(iterator first, iterator) const
- {
- if(actions.suppress) return;
+ bool template_escape = values.check(template_tags::escape);
+ if(template_escape) values.consume();
 
- // Get the arguments and clear values stored in action.
+ std::string identifier = values.consume(template_tags::identifier).get_quickbook();
 
         std::vector<template_body> args;
- std::string identifier;
- std::swap(args, actions.template_args);
- std::swap(identifier, actions.template_identifier);
- position const pos = first.get_position();
+
+ BOOST_FOREACH(value arg, values)
+ {
+ args.push_back(template_body(arg, actions.filename));
+ }
+
+ values.finish();
 
         ++actions.template_depth;
         if (actions.template_depth > actions.max_template_depth)
         {
- detail::outerr(pos.file,pos.line)
+ detail::outerr(actions.filename, pos.line)
                 << "Infinite loop detected" << std::endl;
             --actions.template_depth;
             ++actions.error_count;
@@ -906,11 +1207,11 @@
             ///////////////////////////////////
             // Initialise the arguments
             
- if (!symbol->callout)
+ if (!symbol->callouts.check())
             {
                 // Break the arguments for a template
             
- if (!break_arguments(args, symbol->params, pos))
+ if (!break_arguments(args, symbol->params, actions.filename, pos))
                 {
                     actions.pop(); // restore the actions' states
                     --actions.template_depth;
@@ -922,7 +1223,7 @@
             {
                 if (!args.empty())
                 {
- detail::outerr(pos.file, pos.line)
+ detail::outerr(actions.filename, pos.line)
                         << "Arguments for code snippet."
                         <<std::endl;
                     ++actions.error_count;
@@ -943,7 +1244,9 @@
                     code += "linkends=\"" + callout_id + "\" />";
                     code += "'''";
 
- args.push_back(template_body(code, first.get_position(), false));
+ args.push_back(template_body(
+ qbk_value(code, pos, template_tags::phrase),
+ actions.filename));
                 }
             }
 
@@ -965,16 +1268,15 @@
             ///////////////////////////////////
             // parse the template body:
 
- if (!parse_template(symbol->body, actions.template_escape, actions))
+ if (!parse_template(symbol->body, template_escape, actions))
             {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ detail::outerr(actions.filename, pos.line)
                     << "Expanding "
- << (symbol->body.is_block ? "block" : "phrase")
- << " template: " << symbol->identifier << std::endl
+ << (symbol->body.is_block() ? "block" : "phrase")
+ << " template: " << detail::utf8(symbol->identifier) << std::endl
                     << std::endl
                     << "------------------begin------------------" << std::endl
- << symbol->body.content
+ << detail::utf8(symbol->body.content.get_quickbook())
                     << "------------------end--------------------" << std::endl
                     << std::endl;
                 actions.pop(); // restore the actions' states
@@ -985,9 +1287,8 @@
 
             if (actions.section_level != actions.min_section_level)
             {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
- << "Mismatched sections in template " << identifier << std::endl;
+ detail::outerr(actions.filename, pos.line)
+ << "Mismatched sections in template " << detail::utf8(identifier) << std::endl;
                 actions.pop(); // restore the actions' states
                 --actions.template_depth;
                 ++actions.error_count;
@@ -999,27 +1300,28 @@
         actions.phrase.swap(phrase);
         actions.pop(); // restore the actions' states
 
- if(symbol->callout && symbol->callouts.size() > 0)
+ if(!symbol->callouts.empty())
         {
             BOOST_ASSERT(phrase.empty());
             block += "<calloutlist>";
- BOOST_FOREACH(template_body const& c, symbol->callouts)
+ BOOST_FOREACH(value c, symbol->callouts)
             {
                 std::string callout_id = actions.doc_id +
                     boost::lexical_cast<std::string>(detail::callout_id++);
 
                 std::string callout_value;
                 actions.push();
- bool r = parse_template(c, false, actions);
+ bool r = parse_template(
+ template_body(c, symbol->body.filename), false, actions);
                 actions.out.swap(callout_value);
                 actions.pop();
 
                 if(!r)
                 {
- detail::outerr(c.position.file, c.position.line)
+ detail::outerr(symbol->body.filename, c.get_position().line)
                         << "Expanding callout." << std::endl
                         << "------------------begin------------------" << std::endl
- << c.content
+ << detail::utf8(c.get_quickbook())
                         << std::endl
                         << "------------------end--------------------" << std::endl
                         ;
@@ -1035,8 +1337,8 @@
             block += "</calloutlist>";
         }
 
- if(symbol->body.is_block || !block.empty()) {
- actions.inside_paragraph();
+ if(symbol->body.is_block() || !block.empty()) {
+ actions.paragraph(); // For paragraphs before the template call.
             actions.out << block;
             actions.phrase << phrase;
         }
@@ -1046,73 +1348,106 @@
         --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.suppress) return;
+ write_anchors(actions, actions.phrase);
 
- iterator save = first;
- phrase << tag;
- while (first != last)
- detail::print_char(*first++, phrase.get());
- phrase << "\">";
+ detail::markup markup = detail::get_markup(link.get_tag());
 
- // 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/]
+ value_consumer values = link;
+ value dst = values.consume();
+ value content = values.consume();
+ values.finish();
+
+ actions.phrase << markup.pre;
+ detail::print_string(dst.get_quickbook(), actions.phrase.get());
+ actions.phrase << "\">";
 
- if (*last == ']')
- {
- first = save;
- while (first != last)
- detail::print_char(*first++, phrase.get());
- }
+ if (content.empty())
+ detail::print_string(dst.get_quickbook(), actions.phrase.get());
+ else
+ actions.phrase << content.get_boostbook();
+
+ 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;
+ write_anchors(actions, actions.out);
+
+ value_consumer values = variable_list;
+ std::string title = values.consume(table_tags::title).get_quickbook();
 
         actions.out << "<variablelist>\n";
 
         actions.out << "<title>";
- std::string::iterator first = actions.table_title.begin();
- std::string::iterator last = actions.table_title.end();
- while (first != last)
- detail::print_char(*first++, actions.out.get());
+ detail::print_string(title, actions.out.get());
         actions.out << "</title>\n";
 
- std::string str;
- actions.phrase.swap(str);
- actions.out << str;
+ BOOST_FOREACH(value_consumer entry, values) {
+ actions.out << "<varlistentry>";
+
+ if(entry.check()) {
+ actions.out << "<term>";
+ actions.out << entry.consume().get_boostbook();
+ actions.out << "</term>";
+ }
+
+ if(entry.check()) {
+ actions.out << "<listitem>";
+ BOOST_FOREACH(value phrase, entry) actions.out << phrase.get_boostbook();
+ actions.out << "</listitem>";
+ }
+
+ actions.out << "</varlistentry>\n";
+ }
 
         actions.out << "</variablelist>\n";
- actions.table_span = 0;
- actions.table_header.clear();
- actions.table_title.clear();
+
+ values.finish();
     }
 
- void table_action::operator()(iterator, iterator) const
+ void table_action(quickbook::actions& actions, value table)
     {
         if(actions.suppress) return;
+ write_anchors(actions, actions.out);
+
+ value_consumer values = table;
+
+ std::string element_id;
+ if(values.check(general_tags::element_id))
+ element_id = values.consume().get_quickbook();
 
- std::string::iterator first = actions.table_title.begin();
- std::string::iterator last = actions.table_title.end();
- bool has_title = first != last;
+ std::string title = values.consume(table_tags::title).get_quickbook();
+ bool has_title = !title.empty();
         
         std::string table_id;
         if(qbk_version_n >= 105) {
- if(!actions.element_id.empty()) {
+ if(!element_id.empty()) {
                 table_id = fully_qualified_id(actions.doc_id,
- actions.qualified_section_id, actions.element_id);
+ actions.qualified_section_id, element_id);
             }
             else if(has_title) {
                 table_id = fully_qualified_id(actions.doc_id,
                     actions.qualified_section_id,
- detail::make_identifier(first, last));
+ detail::make_identifier(title));
             }
         }
 
+ // Emulating the old behaviour which used the width of the final
+ // row for span_count.
+ int row_count = 0;
+ int span_count = 0;
+
+ value_consumer lookahead = values;
+ BOOST_FOREACH(value row, lookahead) {
+ ++row_count;
+ span_count = boost::distance(row);
+ }
+ lookahead.finish();
+
         if (has_title)
         {
             actions.out << "<table frame=\"all\"";
@@ -1120,8 +1455,7 @@
                 actions.out << " id=\"" << table_id << "\"";
             actions.out << ">\n";
             actions.out << "<title>";
- while (first != last)
- detail::print_char(*first++, actions.out.get());
+ detail::print_string(title, actions.out.get());
             actions.out << "</title>";
         }
         else
@@ -1132,18 +1466,28 @@
             actions.out << ">\n";
         }
 
- actions.out << "<tgroup cols=\"" << actions.table_span << "\">\n";
+ actions.out << "<tgroup cols=\"" << span_count << "\">\n";
 
- if (!actions.table_header.empty())
+ if (row_count > 1)
         {
- actions.out << "<thead>" << actions.table_header << "</thead>\n";
+ actions.out << "<thead>" << "<row>";
+ BOOST_FOREACH(value cell, values.consume()) {
+ actions.out << "<entry>" << cell.get_boostbook() << "</entry>";
+ }
+ actions.out << "</row>\n" << "</thead>\n";
         }
 
         actions.out << "<tbody>\n";
 
- std::string str;
- actions.phrase.swap(str);
- actions.out << str;
+ BOOST_FOREACH(value row, values) {
+ actions.out << "<row>";
+ BOOST_FOREACH(value cell, row) {
+ actions.out << "<entry>" << cell.get_boostbook() << "</entry>";
+ }
+ actions.out << "</row>\n";
+ }
+
+ values.finish();
 
         actions.out << "</tbody>\n"
                      << "</tgroup>\n";
@@ -1156,206 +1500,284 @@
         {
             actions.out << "</informaltable>\n";
         }
-
- actions.table_span = 0;
- actions.table_header.clear();
- actions.table_title.clear();
     }
 
- void start_row_action::operator()(char) const
- {
- if (actions.suppress) return;
-
- // the first row is the header
- if (header.empty() && !phrase.str().empty())
- {
- phrase.swap(header);
- }
-
- phrase << start_row_;
- span = 0;
- }
-
- void start_row_action::operator()(iterator f, iterator) const
- {
- (*this)(*f);
- }
-
- void col_action::operator()(std::string const& contents) const
- {
- if(actions.suppress) return;
- phrase << start_cell_ << contents << end_cell_;
- ++span;
- }
-
- 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;
 
- section_id = element_id.empty() ?
- detail::make_identifier(first, last) :
- element_id;
+ value_consumer values = begin_section_list;
+
+ value element_id = values.optional_consume(general_tags::element_id);
+ value content = values.consume();
+ values.finish();
+
+ actions.section_id = !element_id.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);
 
         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);
 
- actions.anchors.swap(actions.saved_anchors);
- actions.output_pre(out);
+ actions.out << "<title>";
+
+ actions.anchors.swap(saved_anchors);
+ write_anchors(actions, actions.out);
 
         if (qbk_version_n < 103) // version 1.2 and below
         {
- out << "<title>" << str << "</title>\n";
+ actions.out << content.get_boostbook();
         }
         else // version 1.3 and above
         {
- out << "<title>"
- << "<link linkend=\"" << library_id
- << "." << qualified_section_id << "\">"
- << str
+ actions.out << "<link linkend=\"" << actions.doc_id
+ << "." << actions.qualified_section_id << "\">"
+ << content.get_boostbook()
                 << "</link>"
- << "</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.suppress) return;
+ write_anchors(actions, actions.out);
 
- if (section_level <= min_section_level)
+ if (actions.section_level <= actions.min_section_level)
         {
- position const pos = first.get_position();
- detail::outerr(pos.file,pos.line)
+ 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);
         }
     }
     
     void element_id_warning_action::operator()(iterator first, iterator) const
     {
- position const pos = first.get_position();
- detail::outwarn(pos.file,pos.line) << "Empty id.\n";
+ file_position const pos = first.get_position();
+ detail::outwarn(actions.filename, pos.line) << "Empty id.\n";
     }
 
- fs::path path_difference(fs::path const& outdir, fs::path const& path)
+ // Not a general purpose normalization function, just
+ // from paths from the root directory. It strips the excess
+ // ".." parts from a path like: "x/../../y", leaving "y".
+ std::vector<fs::path> normalize_path_from_root(fs::path const& path)
     {
- fs::path outtmp, temp;
- fs::path::iterator out = outdir.begin(), file = path.begin();
- for(; out != outdir.end() && file != path.end(); ++out, ++file)
+ assert(!path.has_root_directory() && !path.has_root_name());
+
+ std::vector<fs::path> parts;
+
+ BOOST_FOREACH(fs::path const& part, path)
         {
- if(!fs::equivalent(outtmp /= *out, temp /= *file))
- break;
+ if (part.empty() || part == ".") {
+ }
+ else if (part == "..") {
+ if (!parts.empty()) parts.pop_back();
+ }
+ else {
+ parts.push_back(part);
+ }
         }
- out = (out == outdir.begin()) ? outdir.end() : out;
+
+ return parts;
+ }
+
+ // The relative path from base to path
+ fs::path path_difference(fs::path const& base, fs::path const& path)
+ {
+ fs::path
+ absolute_base = fs::absolute(base),
+ absolute_path = fs::absolute(path);
 
- fs::path result = fs::path();
- for(; out != outdir.end(); ++out)
- if(*out != ".") result /= "..";
- std::divides<fs::path> concat;
- return std::accumulate(file, path.end(), result, concat);
+ // Remove '.', '..' and empty parts from the remaining path
+ std::vector<fs::path>
+ base_parts = normalize_path_from_root(absolute_base.relative_path()),
+ path_parts = normalize_path_from_root(absolute_path.relative_path());
+
+ std::vector<fs::path>::iterator
+ base_it = base_parts.begin(),
+ base_end = base_parts.end(),
+ path_it = path_parts.begin(),
+ path_end = path_parts.end();
+
+ // Build up the two paths in these variables, checking for the first
+ // difference.
+ fs::path
+ base_tmp = absolute_base.root_path(),
+ path_tmp = absolute_path.root_path();
+
+ fs::path result;
+
+ // If they have different roots then there's no relative path so
+ // just build an absolute path.
+ if (!fs::equivalent(base_tmp, path_tmp))
+ {
+ result = path_tmp;
+ }
+ else
+ {
+ // Find the point at which the paths differ
+ for(; base_it != base_end && path_it != path_end; ++base_it, ++path_it)
+ {
+ if(!fs::equivalent(base_tmp /= *base_it, path_tmp /= *path_it))
+ break;
+ }
+
+ // Build a relative path to that point
+ for(; base_it != base_end; ++base_it) result /= "..";
+ }
+
+ // Build the rest of our path
+ for(; path_it != path_end; ++path_it) result /= *path_it;
+
+ return result;
     }
 
- fs::path calculate_relative_path(
- iterator first, iterator last, quickbook::actions& actions)
+ std::string check_path(value const& path, quickbook::actions& actions)
+ {
+ std::string path_text = path.get_quickbook();
+
+ if(path_text.find('\\') != std::string::npos)
+ {
+ detail::outwarn(actions.filename, path.get_position().line)
+ << "Path isn't portable: "
+ << detail::utf8(path_text)
+ << std::endl;
+ }
+
+ boost::replace(path_text, '\\', '/');
+
+ return path_text;
+ }
+
+ fs::path calculate_relative_path(std::string const& name, quickbook::actions& actions)
     {
         // Given a source file and the current filename, calculate the
         // path to the source file relative to the output directory.
- fs::path path(std::string(first, last));
- if (!path.is_complete())
+
+ fs::path path = detail::generic_to_path(name);
+ if (path.has_root_directory())
         {
- fs::path infile = fs::absolute(actions.filename).normalize();
- path = (infile.parent_path() / path).normalize();
- fs::path outdir = fs::absolute(actions.outdir).normalize();
- path = path_difference(outdir, path);
+ return path;
+ }
+ else
+ {
+ return path_difference(
+ actions.xinclude_base,
+ actions.filename.parent_path() / path);
+
         }
- 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.suppress) return;
+ write_anchors(actions, actions.out);
 
- fs::path path = calculate_relative_path(first, last, 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);
+ values.finish();
+
+ actions.out << "\n<xi:include href=\"";
+ detail::print_string(detail::escape_uri(path.generic_string()), actions.out.get());
+ actions.out << "\" />\n";
     }
 
     namespace
     {
- fs::path include_search(fs::path const & current, std::string const & name)
+ struct include_search_return
         {
+ include_search_return(fs::path const& x, fs::path const& y)
+ : filename(x), filename_relative(y) {}
+
+ fs::path filename;
+ fs::path filename_relative;
+ };
+
+ include_search_return include_search(std::string const & name,
+ quickbook::actions const& actions)
+ {
+ fs::path current = actions.filename.parent_path();
             fs::path path(name);
 
             // If the path is relative, try and resolve it.
- if (!path.is_complete())
+ if (!path.has_root_directory() && !path.has_root_name())
             {
                 // See if it can be found locally first.
                 if (fs::exists(current / path))
                 {
- return current / path;
+ return include_search_return(
+ current / path,
+ actions.filename_relative.parent_path() / path);
                 }
 
                 // Search in each of the include path locations.
- BOOST_FOREACH(std::string const & p, include_path)
+ BOOST_FOREACH(fs::path full, include_path)
                 {
- fs::path full(p);
                     full /= path;
                     if (fs::exists(full))
                     {
- return full;
+ return include_search_return(full, path);
                     }
                 }
             }
 
- return path;
+ return include_search_return(path,
+ actions.filename_relative.parent_path() / path);
         }
     }
 
- void import_action::operator()(iterator first, iterator last) const
+ void import_action(quickbook::actions& actions, value import)
     {
- if(!actions.output_pre(actions.out)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, actions.out);
+
+ value_consumer values = import;
+ include_search_return paths = include_search(
+ check_path(values.consume(), actions), actions);
+ values.finish();
 
- fs::path path = include_search(actions.filename.parent_path(), std::string(first,last));
- std::string ext = path.extension().generic_string();
+ std::string ext = paths.filename.extension().generic_string();
         std::vector<template_symbol> storage;
         actions.error_count +=
- load_snippets(path.string(), storage, ext, actions.doc_id);
+ load_snippets(paths.filename.string(), storage, ext, actions.doc_id);
 
         BOOST_FOREACH(template_symbol& ts, storage)
         {
@@ -1363,42 +1785,42 @@
             ts.parent = &actions.templates.top_scope();
             if (!actions.templates.add(ts))
             {
- cl::file_position const pos = ts.body.position;
- detail::outerr(pos.file, pos.line)
- << "Template Redefinition: " << tname << std::endl;
+ detail::outerr(ts.body.filename, ts.body.content.get_position().line)
+ << "Template Redefinition: " << detail::utf8(tname) << std::endl;
                 ++actions.error_count;
             }
         }
     }
 
- void include_action::operator()(iterator first, iterator last) const
+ void include_action(quickbook::actions& actions, value include)
     {
- if(!actions.output_pre(actions.out)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, actions.out);
+
+ value_consumer values = include;
+ value include_doc_id = values.optional_consume(general_tags::include_id);
+ include_search_return filein = include_search(
+ check_path(values.consume(), actions), actions);
+ values.finish();
 
- fs::path filein = include_search(actions.filename.parent_path(), std::string(first,last));
         std::string doc_type, doc_id;
- docinfo_string doc_dirname, doc_last_revision;
 
         // swap the filenames
- std::swap(actions.filename, filein);
+ std::swap(actions.filename, filein.filename);
+ std::swap(actions.filename_relative, filein.filename_relative);
 
- // save the doc info strings
+ // save the doc info strings and source mode
         if(qbk_version_n >= 106) {
             doc_type = actions.doc_type;
             doc_id = actions.doc_id;
- doc_dirname = actions.doc_dirname;
- doc_last_revision = actions.doc_last_revision;
         }
         else {
             actions.doc_type.swap(doc_type);
             actions.doc_id.swap(doc_id);
- actions.doc_dirname.swap(doc_dirname);
- actions.doc_last_revision.swap(doc_last_revision);
         }
         
- // save the version info
- unsigned qbk_major_version_store = qbk_major_version;
- unsigned qbk_minor_version_store = qbk_minor_version;
+ // save the source mode and version info (only restored for 1.6+)
+ std::string source_mode = actions.source_mode;
         unsigned qbk_version_n_store = qbk_version_n;
 
         // scope the macros
@@ -1409,30 +1831,32 @@
 
         // 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.empty())
+ actions.doc_id = include_doc_id.get_quickbook();
 
         // update the __FILENAME__ macro
- *boost::spirit::classic::find(actions.macro, "__FILENAME__") = actions.filename.string();
+ *boost::spirit::classic::find(actions.macro, "__FILENAME__")
+ = detail::path_to_generic(actions.filename_relative);
+
+ // save values
+ actions.values.builder.save();
 
         // parse the file
         quickbook::parse_file(actions.filename.string().c_str(), actions, true);
 
         // restore the values
- std::swap(actions.filename, filein);
+ actions.values.builder.restore();
+
+ std::swap(actions.filename, filein.filename);
+ std::swap(actions.filename_relative, filein.filename_relative);
 
         actions.doc_type.swap(doc_type);
         actions.doc_id.swap(doc_id);
- actions.doc_dirname.swap(doc_dirname);
- actions.doc_last_revision.swap(doc_last_revision);
         
         if(qbk_version_n >= 106 || qbk_version_n_store >= 106)
         {
- qbk_major_version = qbk_major_version_store;
- qbk_minor_version = qbk_minor_version_store;
+ actions.source_mode = source_mode;
+
             qbk_version_n = qbk_version_n_store;
         }
 
@@ -1443,92 +1867,72 @@
         //~ actions.templates = templates; $$$ fixme $$$
     }
 
- void phrase_to_string_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(phrase)) return;
+ if (actions.suppress) return;
+ write_anchors(actions, actions.phrase);
 
- out.clear();
- phrase.swap(out);
+ std::string encoded;
+ actions.phrase.swap(encoded);
+ actions.values.builder.insert(
+ qbk_bbk_value(first, last, encoded, tag));
     }
 
- void phrase_to_docinfo_action::operator()(iterator first, iterator last) const
+ void phrase_to_docinfo_action_impl::operator()(iterator first, iterator last) const
     {
- if(!actions.output_pre(phrase)) return;
-
- out.encoded.clear();
- phrase.swap(out.encoded);
- out.raw = std::string(first, last);
+ return (*this)(first, last, value::default_tag);
     }
     
- void inner_phrase_action_pre::operator()(iterator, iterator) const
- {
- // TODO: Really?
- if(actions.suppress) return;
-
- actions.saved_anchors.clear();
- actions.saved_anchors.swap(actions.anchors);
- }
-
- void inner_phrase_action_post::operator()(iterator, iterator) const
+ void collector_to_value_action::operator()(iterator, iterator) const
     {
- if(actions.suppress) return;
-
- actions.output_pre(actions.phrase);
- }
-
- bool pre_output_action::operator()(collector& tgt) const
- {
- if(actions.suppress) return false;
-
- for(quickbook::actions::string_list::iterator
- it = actions.anchors.begin(),
- end = actions.anchors.end();
- it != end; ++it)
- {
- tgt << "<anchor id=\"";
- detail::print_string(*it, tgt.get());
- tgt << "\"/>\n";
- }
-
- actions.anchors.clear();
+ if (actions.suppress) return;
+ write_anchors(actions, output);
 
- return true;
+ std::string value;
+ output.swap(value);
+ actions.values.builder.insert(bbk_value(value, value::default_tag));
     }
     
- bool pre_output_action::operator()(iterator, iterator) const
- {
- return (*this)(actions.out);
- }
-
- scoped_block_push::scoped_block_push(quickbook::actions& actions)
- : actions(actions)
+ bool scoped_output_push::start()
     {
         actions.out.push();
         actions.phrase.push();
+ actions.anchors.swap(saved_anchors);
+
+ return true;
     }
     
- scoped_block_push::~scoped_block_push()
+ void scoped_output_push::cleanup()
     {
         actions.phrase.pop();
         actions.out.pop();
+ actions.anchors.swap(saved_anchors);
     }
 
- std::string const& scoped_block_push::success_impl()
+ bool set_no_eols_scoped::start()
     {
- // TODO: This should probably return an empty string
- // if actions.suppress is true.
- actions.inside_paragraph();
- return actions.out.str();
+ saved_no_eols = actions.no_eols;
+ actions.no_eols = false;
+
+ return true;
     }
 
- set_no_eols_scoped::set_no_eols_scoped(quickbook::actions& actions)
- : actions(actions), saved_no_eols(actions.no_eols)
+ void set_no_eols_scoped::cleanup()
     {
- actions.no_eols = false;
+ actions.no_eols = saved_no_eols;
     }
 
- set_no_eols_scoped::~set_no_eols_scoped()
+ bool scoped_context_impl::start(int new_context)
     {
- actions.no_eols = saved_no_eols;
+ saved_context_ = actions_.context;
+ actions_.context = new_context;
+
+ return true;
+ }
+
+ void scoped_context_impl::cleanup()
+ {
+ actions_.context = saved_context_;
     }
 }

Modified: branches/release/tools/quickbook/src/actions.hpp
==============================================================================
--- branches/release/tools/quickbook/src/actions.hpp (original)
+++ branches/release/tools/quickbook/src/actions.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,41 +10,21 @@
 #if !defined(BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP)
 #define BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP
 
-#include <map>
 #include <string>
 #include <vector>
-#include <stack>
-#include <algorithm>
-#include <boost/filesystem/v3/operations.hpp>
-#include <boost/foreach.hpp>
-#include <boost/tuple/tuple.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/classic_symbols_fwd.hpp>
 #include "fwd.hpp"
-#include "collector.hpp"
 #include "template_stack.hpp"
 #include "utils.hpp"
-
-#ifdef BOOST_MSVC
-// disable copy/assignment could not be generated, unreferenced formal params
-#pragma warning (push)
-#pragma warning(disable : 4511 4512 4100)
-#endif
+#include "values.hpp"
+#include "scoped.hpp"
 
 namespace quickbook
 {
     namespace cl = boost::spirit::classic;
- namespace fs = boost::filesystem;
 
- extern int qbk_major_version;
- extern int qbk_minor_version;
     extern unsigned qbk_version_n; // qbk_major_version * 100 + qbk_minor_version
-
- // This struct is used to avoid an optimization bug
- // in g++ 4.4 on 64-bit linux.
- struct assign_qbk_version {
- assign_qbk_version(int& v) : v_(v) {}
- void operator()(int value) const;
- int& v_;
- };
 
     struct quickbook_range {
         template <typename Arg>
@@ -72,7 +52,6 @@
     }
 
     typedef cl::symbols<std::string> string_symbols;
- typedef std::map<std::string, std::string> attribute_map;
 
     int load_snippets(std::string const& file, std::vector<template_symbol>& storage,
         std::string const& extension, std::string const& doc_id);
@@ -81,203 +60,60 @@
         actions& escape_actions,
         std::string const& source_mode);
 
- template <typename Derived, typename DataT = void>
- struct scoped_action_base
+ struct error_message_action
     {
- typedef quickbook::actions data_type;
-
- template <typename T>
- struct result
- {
- typedef cl::match<DataT> type;
- };
+ // Prints an error message to std::cerr
 
- template <typename T>
- DataT success(T const&)
- {
- return static_cast<Derived*>(this)->success_impl();
- }
-
- void failure() {
- return static_cast<Derived*>(this)->failure_impl();
- }
-
- void failure_impl() {}
- };
+ error_message_action(quickbook::actions& actions, std::string const& m)
+ : actions(actions)
+ , message(m)
+ {}
 
- struct void_type {};
+ void operator()(iterator, iterator) const;
 
- template <typename Derived>
- struct scoped_action_base<Derived, void>
- : scoped_action_base<Derived, void_type>
- {
- template <typename T>
- void_type success(T const&)
- {
- static_cast<Derived*>(this)->success_impl();
- return void_type();
- }
-
- void success_impl() {}
+ quickbook::actions& actions;
+ std::string message;
     };
 
     struct error_action
     {
         // Prints an error message to std::cerr
 
- error_action(
- int& error_count)
- : error_count(error_count) {}
+ error_action(quickbook::actions& actions)
+ : actions(actions) {}
 
         void operator()(iterator first, iterator /*last*/) const;
 
- int& error_count;
- };
-
- struct tagged_action
- {
- tagged_action(
- collector& out,
- std::string const& pre,
- std::string const& post,
- quickbook::actions& actions)
- : out(out)
- , pre(pre)
- , post(post)
- , actions(actions) {}
-
- void operator()(std::string const&) const;
+ error_message_action operator()(std::string const& message)
+ {
+ return error_message_action(actions, message);
+ }
 
- collector& out;
- std::string pre;
- std::string post;
         quickbook::actions& actions;
     };
 
- struct phrase_action
+ struct element_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) {}
+ element_action(quickbook::actions& actions)
+ : actions(actions) {}
 
- void operator()(iterator first, iterator last) const { return (*this)(); }
- template <typename T>
- void operator()(T const&) const { return (*this)(); }
- void operator()() const;
+ void operator()(iterator, iterator) 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)(); }
+ void operator()(iterator, iterator) 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& element_id,
- std::string const& library_id,
- std::string const& section_id,
- std::string const& qualified_section_id,
- std::string const& pre,
- std::string const& post,
- quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , element_id(element_id)
- , library_id(library_id)
- , section_id(section_id)
- , qualified_section_id(qualified_section_id)
- , pre(pre)
- , post(post)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& out;
- collector& phrase;
- std::string const& element_id;
- std::string const& library_id;
- std::string const& section_id;
- std::string const& qualified_section_id;
- std::string pre;
- std::string post;
- quickbook::actions& actions;
- };
-
- struct generic_header_action
- {
- // Handles h
-
- generic_header_action(
- collector& out,
- collector& phrase,
- std::string const& element_id,
- 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)
- , element_id(element_id)
- , 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& element_id;
- std::string const& library_id;
- std::string const& section_id;
- std::string const& qualified_section_id;
- int const& section_level;
         quickbook::actions& actions;
     };
 
@@ -287,102 +123,31 @@
 
         simple_phrase_action(
             collector& out
- , std::string const& pre
- , std::string const& post
           , string_symbols const& macro
           , quickbook::actions& actions)
         : out(out)
- , pre(pre)
- , post(post)
         , macro(macro)
         , actions(actions) {}
 
- void operator()(iterator first, iterator last) const;
+ void operator()(char) const;
 
         collector& out;
- std::string pre;
- std::string post;
         string_symbols const& macro;
         quickbook::actions& actions;
     };
 
- struct cond_phrase_action_pre
+ struct cond_phrase_push : scoped_action_base
     {
- // 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;
- };
+ cond_phrase_push(quickbook::actions& x)
+ : actions(x) {}
 
- struct cond_phrase_push : scoped_action_base<cond_phrase_push>
- {
- cond_phrase_push(quickbook::actions&);
- ~cond_phrase_push();
+ bool start();
+ void cleanup();
 
         quickbook::actions& actions;
         bool saved_suppress;
     };
 
- struct list_action
- {
- // Handles lists
-
- 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;
-
- 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;
- };
-
     struct span
     {
         // Decorates c++ code fragments
@@ -400,23 +165,15 @@
     {
         // Handles unexpected chars in c++ syntax
 
- unexpected_char(collector& out)
- : out(out) {}
+ unexpected_char(
+ collector& out
+ , quickbook::actions& actions)
+ : out(out)
+ , actions(actions) {}
 
         void operator()(iterator first, iterator last) const;
 
         collector& out;
- };
-
- struct anchor_action
- {
- // Handles anchors
-
- anchor_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
         quickbook::actions& actions;
     };
 
@@ -519,74 +276,6 @@
         quickbook::actions& actions;
     };
 
- struct attribute_action
- {
- // Handle image attributes
-
- attribute_action(
- attribute_map& attributes
- , std::string& attribute_name
- , int& error_count)
- : attributes(attributes)
- , attribute_name(attribute_name)
- , error_count(error_count) {}
-
- void operator()(iterator first, iterator last) const;
-
- attribute_map& attributes;
- std::string& attribute_name;
- int& error_count;
- };
-
- struct image_action
- {
- // Handles inline images
-
- image_action(
- collector& phrase
- , attribute_map& attributes
- , std::string& image_fileref
- , quickbook::actions& actions)
- : phrase(phrase)
- , attributes(attributes)
- , image_fileref(image_fileref)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- collector& phrase;
- attribute_map& attributes;
- std::string& image_fileref;
- quickbook::actions& actions;
- };
-
- struct markup_action
- {
- // A generic markup action
-
- markup_action(
- collector& phrase,
- std::string const& str,
- quickbook::actions& actions)
- : phrase(phrase), str(str), actions(actions) {}
-
- template <typename T>
- void operator()(T const&) const
- {
- phrase << str;
- }
-
- template <typename T>
- void operator()(T const&, T const&) const
- {
- phrase << str;
- }
-
- collector& phrase;
- std::string str;
- quickbook::actions& actions;
- };
-
     struct code_action
     {
         // Does the actual syntax highlighing of code
@@ -638,341 +327,82 @@
         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 template_arg_action
- {
- // Handles a template argument
-
- template_arg_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- quickbook::actions& actions;
- };
-
- struct do_template_action
- {
- // Handles template substitutions
-
- do_template_action(quickbook::actions& actions)
- : actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
-
- 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 start_row_action
- {
- // Handles table rows
-
- start_row_action(collector& phrase, unsigned& span, std::string& header, quickbook::actions& actions)
- : phrase(phrase), span(span), header(header), actions(actions) {}
-
- void operator()(char) const;
- void operator()(iterator f, iterator) const;
-
- collector& phrase;
- unsigned& span;
- std::string& header;
- quickbook::actions& actions;
- };
-
- struct col_action
- {
- col_action(collector& phrase, unsigned& span, quickbook::actions& actions)
- : phrase(phrase), span(span), actions(actions) {}
-
- void operator()(std::string const&) const;
-
- collector& phrase;
- unsigned& span;
- 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
- , std::string& element_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)
- , element_id(element_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;
- std::string& element_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
    {
- void operator()(iterator first, iterator last) const;
- };
-
- 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_)
+ element_id_warning_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;
- };
-
- struct docinfo_string {
- std::string raw;
- std::string encoded;
-
- docinfo_string() : raw(), encoded() {}
-
- void swap(docinfo_string& x) {
- raw.swap(x.raw);
- encoded.swap(x.encoded);
- }
-
- void clear() {
- raw.clear();
- encoded.clear();
- }
-
- bool empty() const {
- return raw.empty();
- }
-
- std::string const& get(unsigned version) const;
- };
+ };
 
     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
+ struct phrase_to_docinfo_action_impl
     {
- phrase_to_string_action(std::string& out, collector& phrase, quickbook::actions& actions)
- : out(out) , phrase(phrase), 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;
 
- std::string& out;
- collector& phrase;
         quickbook::actions& actions;
     };
+
+ typedef phoenix::function<phrase_to_docinfo_action_impl> phrase_to_docinfo_action;
 
- struct phrase_to_docinfo_action
+ struct collector_to_value_action
     {
- phrase_to_docinfo_action(docinfo_string& out, collector& phrase, quickbook::actions& actions)
- : out(out)
- , phrase(phrase)
- , actions(actions) {}
+ collector_to_value_action(quickbook::actions& actions, collector& output)
+ : actions(actions), output(output) {}
 
         void operator()(iterator first, iterator last) const;
 
- docinfo_string& out;
- collector& phrase;
         quickbook::actions& actions;
+ collector& output;
     };
 
- struct inner_phrase_action_pre
+ struct scoped_output_push : scoped_action_base
     {
- inner_phrase_action_pre(quickbook::actions& actions)
+ scoped_output_push(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) {}
+ bool start();
+ void cleanup();
 
- void operator()(iterator, iterator) const;
-
         quickbook::actions& actions;
+ std::vector<std::string> saved_anchors;
     };
 
- struct pre_output_action
+ struct set_no_eols_scoped : scoped_action_base
     {
- pre_output_action(quickbook::actions& actions)
+ set_no_eols_scoped(quickbook::actions& actions)
             : actions(actions) {}
-
- bool operator()(collector& tgt) const;
- bool operator()(iterator, iterator) const;
-
- quickbook::actions& actions;
- };
 
- struct scoped_block_push : scoped_action_base<scoped_block_push, std::string>
- {
- scoped_block_push(quickbook::actions&);
- ~scoped_block_push();
- std::string const& success_impl();
+ bool start();
+ void cleanup();
 
         quickbook::actions& actions;
+ bool saved_no_eols;
     };
-
- struct set_no_eols_scoped : scoped_action_base<set_no_eols_scoped>
+
+ struct scoped_context_impl : scoped_action_base
     {
- set_no_eols_scoped(quickbook::actions&);
- ~set_no_eols_scoped();
+ scoped_context_impl(quickbook::actions& actions)
+ : actions_(actions) {}
 
- quickbook::actions& actions;
- bool saved_no_eols;
+ bool start(int);
+ void cleanup();
+
+ private:
+ quickbook::actions& actions_;
+ int saved_context_;
     };
 }
 
-#ifdef BOOST_MSVC
-#pragma warning (pop)
-#endif
-
 #endif // BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP
-

Modified: branches/release/tools/quickbook/src/actions_class.cpp
==============================================================================
--- branches/release/tools/quickbook/src/actions_class.cpp (original)
+++ branches/release/tools/quickbook/src/actions_class.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -9,9 +9,9 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 #include "actions_class.hpp"
-#include "markups.hpp"
 #include "quickbook.hpp"
 #include "grammar.hpp"
+#include "input_path.hpp"
 
 #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
 #pragma warning(disable:4355)
@@ -19,33 +19,34 @@
 
 namespace quickbook
 {
- actions::actions(char const* filein_, fs::path const& outdir_, string_stream& out_)
+ actions::actions(fs::path const& filein_, fs::path const& xinclude_base_, string_stream& out_)
         : grammar_()
 
     // header info
         , doc_type()
- , doc_title()
- , doc_version()
+ , doc_title_qbk()
         , doc_id()
- , doc_dirname()
- , doc_copyrights()
- , doc_purpose()
- , doc_categories()
- , doc_authors()
- , doc_license()
- , doc_last_revision()
- , 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)
+ , scoped_context(*this)
 
     // state
- , filename(fs::absolute(fs::path(filein_)))
- , outdir(outdir_)
+ , filename(filein_)
+ , filename_relative(filein_.filename())
+ , xinclude_base(xinclude_base_)
         , macro_change_depth(0)
         , macro()
         , section_level(0)
@@ -55,164 +56,38 @@
         , source_mode("c++")
 
     // temporary or global state
- , element_id()
- , table_title()
- , table_span(0)
- , table_header()
- , macro_id()
- , list_marks()
- , list_indent(-1)
- , template_identifier()
- , template_info()
         , template_depth(0)
- , template_escape(false)
         , templates()
         , error_count(0)
- , image_fileref()
- , attribute_name()
- , attributes()
         , anchors()
- , saved_anchors()
         , no_eols(true)
         , suppress(false)
+ , warned_about_breaks(false)
 
     // actions
- , error(error_count)
- , extract_doc_title(doc_title, phrase, *this)
- , extract_doc_license(doc_license, phrase, *this)
- , extract_doc_purpose(doc_purpose, phrase, *this)
- , extract_doc_version(doc_version, phrase, *this)
- , extract_doc_id(doc_id_tmp, phrase, *this)
- , extract_doc_dirname(doc_dirname, phrase, *this)
- , extract_copyright_second(copyright.second, phrase, *this)
- , extract_name_second(name.second, phrase, *this)
- , extract_name_first(name.first, phrase, *this)
- , extract_doc_last_revision(doc_last_revision, phrase, *this)
- , extract_doc_category(doc_category, phrase, *this)
- , extract_doc_biblioid(doc_biblioid.second, phrase, *this)
- , extract_doc_lang(doc_lang, phrase, *this)
- , scoped_block(*this)
+ , element(*this)
+ , error(*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, element_id, doc_id, section_id, qualified_section_id, section_level, *this)
- , h1(out, phrase, element_id, doc_id, section_id, qualified_section_id, h1_pre, h1_post, *this)
- , h2(out, phrase, element_id, doc_id, section_id, qualified_section_id, h2_pre, h2_post, *this)
- , h3(out, phrase, element_id, doc_id, section_id, qualified_section_id, h3_pre, h3_post, *this)
- , h4(out, phrase, element_id, doc_id, section_id, qualified_section_id, h4_pre, h4_post, *this)
- , h5(out, phrase, element_id, doc_id, section_id, qualified_section_id, h5_pre, h5_post, *this)
- , h6(out, phrase, element_id, doc_id, section_id, qualified_section_id, h6_pre, h6_post, *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)
+ , paragraph(*this)
         , space_char(phrase)
         , plain_char(phrase, *this)
         , raw_char(phrase, *this)
         , escape_unicode(phrase, *this)
- , attribute(attributes, attribute_name, error_count)
- , image(phrase, attributes, image_fileref, *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)
- , simple_underline(phrase, underline_pre_, underline_post_, macro, *this)
- , simple_teletype(phrase, teletype_pre_, teletype_post_, macro, *this)
- , simple_strikethrough(phrase, strikethrough_pre_, strikethrough_post_, macro, *this)
-
- , variablelist(*this)
- , start_varlistentry(phrase, start_varlistentry_, *this)
- , end_varlistentry(phrase, end_varlistentry_, *this)
- , start_varlistterm(phrase, start_varlistterm_, *this)
- , end_varlistterm(phrase, end_varlistterm_, *this)
- , varlistitem(phrase, start_varlistitem_, end_varlistitem_, *this)
+ , simple_markup(phrase, macro, *this)
 
         , break_(phrase, *this)
- , macro_identifier(*this)
- , macro_definition(*this)
         , do_macro(phrase, *this)
- , template_body(*this)
- , template_arg(*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)
- , start_row(phrase, table_span, table_header, *this)
- , end_row(phrase, end_row_, *this)
- , cell(phrase, table_span, *this)
- , anchor(*this)
-
- , begin_section(out, phrase, doc_id, section_id, section_level, qualified_section_id, element_id, *this)
- , end_section(out, section_level, min_section_level, qualified_section_id, error_count, *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)
+ , element_id_warning(*this)
     {
- // turn off __FILENAME__ macro on debug mode = true
- std::string filename_str = debug_mode ?
- std::string("NO_FILENAME_MACRO_GENERATED_IN_DEBUG_MODE") :
- filename.string();
-
         // add the predefined macros
         macro.add
             ("__DATE__", std::string(quickbook_get_date))
             ("__TIME__", std::string(quickbook_get_time))
- ("__FILENAME__", filename_str)
+ ("__FILENAME__", detail::path_to_generic(filename_relative))
         ;
         
         boost::scoped_ptr<quickbook_grammar> g(
@@ -225,7 +100,7 @@
         state_stack.push(
             boost::make_tuple(
                 filename
- , outdir
+ , xinclude_base
               , macro_change_depth
               , section_level
               , min_section_level
@@ -237,8 +112,8 @@
 
         out.push();
         phrase.push();
- list_buffer.push();
- templates.push();
+ templates.push();
+ values.builder.save();
     }
     
     // Pushing and popping the macro symbol table is pretty expensive, so
@@ -265,7 +140,7 @@
     
         boost::tie(
             filename
- , outdir
+ , xinclude_base
           , macro_change_depth
           , section_level
           , min_section_level
@@ -277,8 +152,8 @@
 
         out.pop();
         phrase.pop();
- list_buffer.pop();
         templates.pop();
+ values.builder.restore();
     }
     
     quickbook_grammar& actions::grammar() const {

Modified: branches/release/tools/quickbook/src/actions_class.hpp
==============================================================================
--- branches/release/tools/quickbook/src/actions_class.hpp (original)
+++ branches/release/tools/quickbook/src/actions_class.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,10 +10,12 @@
 #if !defined(BOOST_SPIRIT_ACTIONS_CLASS_HPP)
 #define BOOST_SPIRIT_ACTIONS_CLASS_HPP
 
-#include "actions.hpp"
-#include "scoped_parser.hpp"
 #include <boost/tuple/tuple.hpp>
 #include <boost/scoped_ptr.hpp>
+#include "actions.hpp"
+#include "parsers.hpp"
+#include "values_parse.hpp"
+#include "collector.hpp"
 
 namespace quickbook
 {
@@ -22,7 +24,7 @@
 
     struct actions
     {
- actions(char const* filein_, fs::path const& outdir, string_stream& out_);
+ actions(fs::path const& filein_, fs::path const& xinclude_base, string_stream& out_);
 
     private:
         boost::scoped_ptr<quickbook_grammar> grammar_;
@@ -34,49 +36,40 @@
 
         typedef std::vector<std::string> string_list;
 
- typedef std::vector<docinfo_string> docinfo_list;
- typedef std::pair<docinfo_string, docinfo_string> author;
- typedef std::vector<author> author_list;
- typedef std::pair<string_list, docinfo_string> copyright_item;
- typedef std::vector<copyright_item> copyright_list;
- typedef std::pair<std::string, docinfo_string> biblioid_item;
- typedef std::vector<biblioid_item> biblioid_list;
- typedef std::pair<char, int> mark_type;
         static int const max_template_depth = 100;
 
     // header info
         std::string doc_type;
- docinfo_string doc_title;
- docinfo_string doc_version;
+ std::string doc_title_qbk;
         std::string doc_id;
- docinfo_string doc_dirname;
- copyright_list doc_copyrights;
- docinfo_string doc_purpose;
- docinfo_list doc_categories;
- author_list doc_authors;
- docinfo_string doc_license;
- docinfo_string doc_last_revision;
- biblioid_list doc_biblioid_items;
- docinfo_string doc_lang;
- std::string include_doc_id;
- //temporary state
- biblioid_item doc_biblioid;
- docinfo_string doc_id_tmp;
- author name;
- copyright_item copyright;
- docinfo_string doc_category;
-
 
     // 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;
+ scoped_parser<scoped_context_impl>
+ scoped_context;
 
     // state
         fs::path filename;
- fs::path outdir;
+ fs::path filename_relative; // for the __FILENAME__ macro.
+ // (relative to the original file
+ // or include path).
+ fs::path xinclude_base;
         std::size_t macro_change_depth;
         string_symbols macro;
         int section_level;
@@ -101,30 +94,14 @@
         std::stack<string_symbols> macro_stack;
 
     // temporary or global state
- std::string element_id;
- std::string table_title;
- unsigned table_span;
- std::string table_header;
- std::string macro_id;
- std::stack<mark_type> list_marks;
- int list_indent;
- bool condition;
- std::string template_identifier;
- string_list template_info;
         int template_depth;
- bool template_escape;
- bool template_block;
- std::vector<quickbook::template_body>
- template_args;
         template_stack templates;
         int error_count;
- std::string image_fileref;
- std::string attribute_name;
- attribute_map attributes;
         string_list anchors;
- string_list saved_anchors;
         bool no_eols;
         bool suppress;
+ bool warned_about_breaks;
+ int context;
 
     // push/pop the states and the streams
         void copy_macros_for_write();
@@ -135,127 +112,25 @@
     ///////////////////////////////////////////////////////////////////////////
     // actions
     ///////////////////////////////////////////////////////////////////////////
- error_action error;
- phrase_to_docinfo_action extract_doc_title;
- phrase_to_docinfo_action extract_doc_license;
- phrase_to_docinfo_action extract_doc_purpose;
- phrase_to_docinfo_action extract_doc_version;
- phrase_to_docinfo_action extract_doc_id;
- phrase_to_docinfo_action extract_doc_dirname;
- phrase_to_docinfo_action extract_copyright_second;
- phrase_to_docinfo_action extract_name_second;
- phrase_to_docinfo_action extract_name_first;
- phrase_to_docinfo_action extract_doc_last_revision;
- phrase_to_docinfo_action extract_doc_category;
- phrase_to_docinfo_action extract_doc_biblioid;
- phrase_to_docinfo_action extract_doc_lang;
 
- 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;
- 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;
+ paragraph_action paragraph;
         space space_char;
         plain_char_action plain_char;
         raw_char_action raw_char;
         escape_unicode_action escape_unicode;
- attribute_action attribute;
- 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;
- simple_phrase_action simple_underline;
- simple_phrase_action simple_teletype;
- simple_phrase_action simple_strikethrough;
-
- variablelist_action variablelist;
- markup_action start_varlistentry;
- markup_action end_varlistentry;
- markup_action start_varlistterm;
- markup_action end_varlistterm;
- tagged_action varlistitem;
+ simple_phrase_action simple_markup;
 
         break_action break_;
- macro_identifier_action macro_identifier;
- macro_definition_action macro_definition;
         do_macro_action do_macro;
- template_body_action template_body;
- template_arg_action template_arg;
- do_template_action do_template;
- link_action url_pre;
- markup_action url_post;
- link_action link_pre;
- markup_action link_post;
- table_action table;
- start_row_action start_row;
- markup_action end_row;
- col_action cell;
- 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: branches/release/tools/quickbook/src/block_element_grammar.cpp
==============================================================================
--- branches/release/tools/quickbook/src/block_element_grammar.cpp (original)
+++ branches/release/tools/quickbook/src/block_element_grammar.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,22 +11,25 @@
 #include "utils.hpp"
 #include "actions_class.hpp"
 #include "grammar_impl.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,
+ varlistentry, varlistterm, list, cell,
                         preformatted, begin_section, end_section,
                         xinclude, include,
                         template_, template_id, template_formal_arg,
@@ -36,144 +39,94 @@
 
     void quickbook_grammar::impl::init_block_elements()
     {
- using detail::var;
-
- block_element_grammar_local& local = store_.create();
+ block_element_grammar_local& local = cleanup_.add(
+ new block_element_grammar_local);
 
         local.element_id =
- ':'
- >>
- (
- cl::if_p(qbk_since(105u)) [space]
- >> (+(cl::alnum_p | '_')) [cl::assign_a(actions.element_id)]
+ !( ':'
+ >> ( cl::if_p(qbk_since(105u)) [space]
+ >> (+(cl::alnum_p | '_')) [actions.values.entry(ph::arg1, ph::arg2, general_tags::element_id)]
                 | cl::eps_p [actions.element_id_warning]
- [cl::assign_a(actions.element_id)]
                 )
- | cl::eps_p [cl::assign_a(actions.element_id)]
+ )
             ;
         
         local.element_id_1_5 =
                 cl::if_p(qbk_since(105u)) [
                     local.element_id
                 ]
- .else_p [
- cl::eps_p [cl::assign_a(actions.element_id)]
- ]
                 ;
 
         local.element_id_1_6 =
                 cl::if_p(qbk_since(106u)) [
                     local.element_id
                 ]
- .else_p [
- cl::eps_p [cl::assign_a(actions.element_id)]
- ]
                 ;
 
         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];
-
- static const bool true_ = true;
- static const bool false_ = false;
-
- elements.add("blurb", element_info(element_info::block, &local.blurb));
-
- local.blurb =
- actions.scoped_block[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 >> actions.scoped_block[inside_paragraph]
- [actions.blockquote]
+ ("heading", element_info(element_info::conditional_or_block, &local.heading, block_tags::generic_heading))
+ ("h1", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading1))
+ ("h2", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading2))
+ ("h3", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading3))
+ ("h4", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading4))
+ ("h5", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading5))
+ ("h6", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading6))
             ;
 
         elements.add
- ("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 =
- actions.scoped_block[inside_paragraph]
- [actions.warning]
- ;
-
- local.caution =
- actions.scoped_block[inside_paragraph]
- [actions.caution]
- ;
-
- local.important =
- actions.scoped_block[inside_paragraph]
- [actions.important]
- ;
-
- local.note =
- actions.scoped_block[inside_paragraph]
- [actions.note]
- ;
-
- local.tip =
- actions.scoped_block[inside_paragraph]
- [actions.tip]
+ ("blurb", element_info(element_info::nested_block, &local.inner_block, block_tags::blurb))
+ (":", element_info(element_info::nested_block, &local.inner_block, block_tags::blockquote))
+ ("warning", element_info(element_info::nested_block, &local.inner_block, block_tags::warning))
+ ("caution", element_info(element_info::nested_block, &local.inner_block, block_tags::caution))
+ ("important", element_info(element_info::nested_block, &local.inner_block, block_tags::important))
+ ("note", element_info(element_info::nested_block, &local.inner_block, block_tags::note))
+ ("tip", element_info(element_info::nested_block, &local.inner_block, block_tags::tip))
             ;
 
         elements.add
- ("pre", element_info(element_info::block, &local.preformatted))
+ ("pre", element_info(element_info::nested_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::conditional_or_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 =
@@ -185,27 +138,26 @@
             ;
 
         elements.add
- ("template", element_info(element_info::block, &local.template_))
+ ("template", element_info(element_info::conditional_or_block, &local.template_, block_tags::template_definition))
             ;
 
         local.template_ =
                space
- >> local.template_id [cl::assign_a(actions.template_identifier)]
- [cl::clear_a(actions.template_info)]
- >>
+ >> local.template_id [actions.values.entry(ph::arg1, ph::arg2)]
+ >> actions.values.list()[
             !(
                 space >> '['
>> *(
                         space
- >> local.template_id [cl::push_back_a(actions.template_info)]
+ >> local.template_id [actions.values.entry(ph::arg1, ph::arg2)]
                     )
>> space >> ']'
             )
+ ]
>> ( cl::eps_p(*cl::blank_p >> cl::eol_p)
- [cl::assign_a(actions.template_block, true_)]
- | cl::eps_p [cl::assign_a(actions.template_block, false_)]
+ >> 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 [actions.template_body]
             ;
 
         local.template_body =
@@ -215,119 +167,103 @@
             ;
 
         elements.add
- ("variablelist", element_info(element_info::block, &local.variablelist))
+ ("variablelist", element_info(element_info::nested_block, &local.variablelist, block_tags::variable_list))
             ;
 
         local.variablelist =
                 (cl::eps_p(*cl::blank_p >> cl::eol_p) | space)
- >> (*(cl::anychar_p - eol)) [cl::assign_a(actions.table_title)]
- >> (+eol) [actions.output_pre]
+ >> (*(cl::anychar_p - eol)) [actions.values.entry(ph::arg1, ph::arg2, table_tags::title)]
+ >> (+eol)
>> *local.varlistentry
- >> cl::eps_p [actions.variablelist]
             ;
 
         local.varlistentry =
             space
- >> cl::ch_p('[') [actions.start_varlistentry]
- >>
- (
+ >> cl::ch_p('[')
+ >> actions.values.list()
+ [
                 (
                     local.varlistterm
- >> ( actions.scoped_block [+local.varlistitem]
- [actions.varlistitem]
+ >> ( +local.cell
                         | cl::eps_p [actions.error]
                         )
- >> cl::ch_p(']') [actions.end_varlistentry]
+ >> cl::ch_p(']')
>> space
                 )
                 | cl::eps_p [actions.error]
- )
+ ]
             ;
 
         local.varlistterm =
             space
- >> cl::ch_p('[') [actions.start_varlistterm]
- >>
- (
- (
- phrase
- >> cl::ch_p(']') [actions.end_varlistterm]
- >> space
- )
- | cl::eps_p [actions.error]
- )
- ;
-
- local.varlistitem =
- space
>> cl::ch_p('[')
- >>
- (
- (
- inside_paragraph
- >> cl::ch_p(']')
- >> space
+ >> local.inner_phrase
+ >> ( cl::ch_p(']')
+ >> space
+ | cl::eps_p [actions.error]
                 )
- | cl::eps_p [actions.error]
- )
             ;
 
         elements.add
- ("table", element_info(element_info::block, &local.table))
+ ("table", element_info(element_info::nested_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)) [cl::assign_a(actions.table_title)]
- >> (+eol) [actions.output_pre]
+ >> (*(cl::anychar_p - eol)) [actions.values.entry(ph::arg1, ph::arg2, table_tags::title)]
+ >> (+eol)
>> *local.table_row
- >> cl::eps_p [actions.table]
             ;
 
         local.table_row =
             space
- >> cl::ch_p('[') [actions.start_row]
+ >> cl::ch_p('[')
>>
             (
                 (
- *local.table_cell
- >> cl::ch_p(']') [actions.end_row]
+ actions.values.list(table_tags::row)
+ [ *local.cell
+ ]
+ >> cl::ch_p(']')
>> space
                 )
                 | cl::eps_p [actions.error]
             )
             ;
 
- local.table_cell =
+ elements.add
+ ("ordered_list", element_info(element_info::nested_block, &local.list, block_tags::ordered_list, 106))
+ ("itemized_list", element_info(element_info::nested_block, &local.list, block_tags::itemized_list, 106))
+ ;
+
+ local.list = *local.cell;
+
+ local.cell =
                 space
>> cl::ch_p('[')
- >> ( actions.scoped_block [
- inside_paragraph
- >> cl::ch_p(']')
- >> space
- ] [actions.cell]
- | cl::eps_p [actions.error]
+ >> ( local.inner_block
+ >> cl::ch_p(']')
+ >> space
+ | cl::eps_p [actions.error]
                 )
             ;
 
         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 =
@@ -336,17 +272,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)]
+ ]
             ;
     }
 }

Copied: branches/release/tools/quickbook/src/block_tags.hpp (from r70210, /trunk/tools/quickbook/src/block_tags.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/block_tags.hpp (original)
+++ branches/release/tools/quickbook/src/block_tags.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -23,7 +23,8 @@
         (variable_list)(table)
         (xinclude)(import)(include)
         (paragraph)
- (list)
+ (list)(ordered_list)(itemized_list)
+ (hr)
     )
 
     QUICKBOOK_VALUE_TAGS(table_tags, 0x250,

Modified: branches/release/tools/quickbook/src/code_snippet.cpp
==============================================================================
--- branches/release/tools/quickbook/src/code_snippet.cpp (original)
+++ branches/release/tools/quickbook/src/code_snippet.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,10 +10,12 @@
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_actor.hpp>
 #include <boost/spirit/include/classic_confix.hpp>
+#include <boost/shared_ptr.hpp>
 #include <boost/bind.hpp>
 #include <boost/lexical_cast.hpp>
 #include "template_stack.hpp"
 #include "actions.hpp"
+#include "values.hpp"
 
 namespace quickbook
 {
@@ -22,10 +24,12 @@
     struct code_snippet_actions
     {
         code_snippet_actions(std::vector<template_symbol>& storage,
+ std::string const& filename,
                                  std::string const& doc_id,
                                  char const* source_type)
             : callout_id(0)
             , storage(storage)
+ , filename(filename)
             , doc_id(doc_id)
             , source_type(source_type)
         {}
@@ -49,20 +53,38 @@
                 , start_code(false)
                 , end_code(false)
             {}
-
+
             std::string id;
             int callout_base_id;
             std::string content;
             bool start_code;
             bool end_code;
- std::vector<template_body> callouts;
+ value_builder callouts;
+ boost::shared_ptr<snippet_data> next;
         };
         
+ void push_snippet_data(std::string const& id, int callout_base_id)
+ {
+ boost::shared_ptr<snippet_data> new_snippet(
+ new snippet_data(id, callout_base_id));
+ new_snippet->next = snippet_stack;
+ snippet_stack = new_snippet;
+ }
+
+ boost::shared_ptr<snippet_data> pop_snippet_data()
+ {
+ boost::shared_ptr<snippet_data> snippet(snippet_stack);
+ snippet_stack = snippet->next;
+ snippet->next.reset();
+ return snippet;
+ }
+
         int callout_id;
- std::stack<snippet_data> snippet_stack;
+ boost::shared_ptr<snippet_data> snippet_stack;
         std::string code;
         std::string id;
         std::vector<template_symbol>& storage;
+ fs::path filename;
         std::string const doc_id;
         char const* const source_type;
     };
@@ -96,6 +118,7 @@
                         start_snippet [boost::bind(&actions_type::start_snippet, &actions, _1, _2)]
                     | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)]
                     | escaped_comment
+ | pass_thru_comment
                     | ignore
                     | cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
                     ;
@@ -139,11 +162,25 @@
                             "\"\"\""
                         )
                     ;
+
+ // Note: Unlike escaped_comment and ignore, this doesn't
+ // swallow preceeding whitespace.
+ pass_thru_comment
+ = "#="
+ >> ( *(cl::anychar_p - cl::eol_p)
+ >> (cl::eol_p | cl::end_p)
+ ) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)]
+ | cl::confix_p(
+ "\"\"\"=",
+ (*cl::anychar_p) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)],
+ "\"\"\""
+ )
+ ;
             }
 
             cl::rule<Scanner>
                 start_, identifier, code_elements, start_snippet, end_snippet,
- escaped_comment, ignore;
+ escaped_comment, pass_thru_comment, ignore;
 
             cl::rule<Scanner> const&
             start() const { return start_; }
@@ -179,6 +216,7 @@
                     | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)]
                     | escaped_comment
                     | ignore
+ | pass_thru_comment
                     | line_callout
                     | inline_callout
                     | cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
@@ -246,11 +284,25 @@
                             "*/"
                         )
                     ;
+
+ // Note: Unlike escaped_comment and ignore, this doesn't
+ // swallow preceeding whitespace.
+ pass_thru_comment
+ = "//="
+ >> ( *(cl::anychar_p - cl::eol_p)
+ >> (cl::eol_p | cl::end_p)
+ ) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)]
+ | cl::confix_p(
+ "/*`",
+ (*cl::anychar_p) [boost::bind(&actions_type::pass_thru, &actions, _1, _2)],
+ "*/"
+ )
+ ;
             }
 
             cl::rule<Scanner>
             start_, identifier, code_elements, start_snippet, end_snippet,
- escaped_comment, inline_callout, line_callout, ignore;
+ escaped_comment, pass_thru_comment, inline_callout, line_callout, ignore;
 
             cl::rule<Scanner> const&
             start() const { return start_; }
@@ -271,13 +323,11 @@
         if (err != 0)
             return err; // return early on error
 
- iterator first(code.begin(), code.end(), file.c_str());
- iterator last(code.end(), code.end());
+ iterator first(code.begin());
+ iterator last(code.end());
 
- size_t fname_len = file.size();
- bool is_python = fname_len >= 3
- && file[--fname_len]=='y' && file[--fname_len]=='p' && file[--fname_len]=='.';
- code_snippet_actions a(storage, doc_id, is_python ? "[python]" : "[c++]");
+ bool is_python = extension == ".py";
+ code_snippet_actions a(storage, file, doc_id, is_python ? "[python]" : "[c++]");
         // TODO: Should I check that parse succeeded?
         if(is_python) {
             boost::spirit::classic::parse(first, last, python_code_snippet_grammar(a));
@@ -291,8 +341,8 @@
 
     void code_snippet_actions::append_code()
     {
- if(snippet_stack.empty()) return;
- snippet_data& snippet = snippet_stack.top();
+ if(!snippet_stack) return;
+ snippet_data& snippet = *snippet_stack;
     
         if (!code.empty())
         {
@@ -318,8 +368,8 @@
 
     void code_snippet_actions::close_code()
     {
- if(snippet_stack.empty()) return;
- snippet_data& snippet = snippet_stack.top();
+ if(!snippet_stack) return;
+ snippet_data& snippet = *snippet_stack;
     
         if(snippet.end_code)
         {
@@ -330,30 +380,29 @@
 
     void code_snippet_actions::pass_thru(iterator first, iterator last)
     {
- if(snippet_stack.empty()) return;
- code += *first;
+ if(!snippet_stack) return;
+ code.append(first, last);
     }
 
     void code_snippet_actions::pass_thru_char(char c)
     {
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
         code += c;
     }
 
     void code_snippet_actions::callout(iterator first, iterator last)
     {
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
         code += "``[[callout" + boost::lexical_cast<std::string>(callout_id) + "]]``";
     
- snippet_stack.top().callouts.push_back(
- template_body(std::string(first, last), first.get_position(), true));
+ snippet_stack->callouts.insert(qbk_value(first, last, template_tags::block));
         ++callout_id;
     }
 
     void code_snippet_actions::escaped_comment(iterator first, iterator last)
     {
- if(snippet_stack.empty()) return;
- snippet_data& snippet = snippet_stack.top();
+ if(!snippet_stack) return;
+ snippet_data& snippet = *snippet_stack;
         append_code();
         close_code();
 
@@ -365,53 +414,56 @@
         }
     }
 
- void code_snippet_actions::start_snippet(iterator first, iterator last)
+ void code_snippet_actions::start_snippet(iterator, iterator)
     {
         append_code();
- snippet_stack.push(snippet_data(id, callout_id));
+ push_snippet_data(id, callout_id);
         id.clear();
     }
 
- void code_snippet_actions::end_snippet(iterator first, iterator last)
+ void code_snippet_actions::end_snippet(iterator first, iterator)
     {
         // TODO: Error?
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
 
         append_code();
 
- snippet_data snippet = snippet_stack.top();
- snippet_stack.pop();
+ boost::shared_ptr<snippet_data> snippet = pop_snippet_data();
+ value callouts = snippet->callouts.release();
 
         std::string body;
- if(snippet.start_code) {
+ if(snippet->start_code) {
             body += "\n\n";
             body += source_type;
             body += "```\n";
         }
- body += snippet.content;
- if(snippet.end_code) {
+ body += snippet->content;
+ if(snippet->end_code) {
             body += "```\n\n";
         }
-
+
         std::vector<std::string> params;
- for (size_t i = 0; i < snippet.callouts.size(); ++i)
+ int i = 0;
+ for(value::iterator it = callouts.begin(); it != callouts.end(); ++it)
         {
- params.push_back("[callout" + boost::lexical_cast<std::string>(snippet.callout_base_id + i) + "]");
+ params.push_back("[callout" + boost::lexical_cast<std::string>(snippet->callout_base_id + i) + "]");
+ ++i;
         }
         
         // TODO: Save position in start_snippet
- template_symbol symbol(snippet.id, params, body, first.get_position(), true);
- symbol.callout = true;
- symbol.callouts = snippet.callouts;
+ template_symbol symbol(snippet->id, params,
+ qbk_value(body, first.get_position(), template_tags::block),
+ filename);
+ symbol.callouts = callouts;
         storage.push_back(symbol);
 
         // Merge the snippet into its parent
 
- if(!snippet_stack.empty())
+ if(snippet_stack)
         {
- snippet_data& next = snippet_stack.top();
- if(!snippet.content.empty()) {
- if(!snippet.start_code) {
+ snippet_data& next = *snippet_stack;
+ if(!snippet->content.empty()) {
+ if(!snippet->start_code) {
                     close_code();
                 }
                 else if(!next.end_code) {
@@ -420,11 +472,11 @@
                     next.content += "```\n";
                 }
                 
- next.content += snippet.content;
- next.end_code = snippet.end_code;
+ next.content += snippet->content;
+ next.end_code = snippet->end_code;
             }
-
- next.callouts.insert(next.callouts.end(), snippet.callouts.begin(), snippet.callouts.end());
+
+ next.callouts.extend(callouts);
         }
     }
 }

Modified: branches/release/tools/quickbook/src/doc_info_actions.cpp
==============================================================================
--- branches/release/tools/quickbook/src/doc_info_actions.cpp (original)
+++ branches/release/tools/quickbook/src/doc_info_actions.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,44 +11,130 @@
 #include <sstream>
 #include <boost/bind.hpp>
 #include <boost/algorithm/string/join.hpp>
+#include <boost/foreach.hpp>
 #include "quickbook.hpp"
 #include "utils.hpp"
+#include "input_path.hpp"
 #include "actions_class.hpp"
+#include "doc_info_tags.hpp"
 
 namespace quickbook
 {
- std::string const& docinfo_string::get(unsigned version) const
+ static void write_document_title(collector& out, value const& title, value const& version);
+
+ static std::string doc_info_output(value const& p, unsigned version)
+ {
+ return (qbk_version_n < version) ? p.get_quickbook() : p.get_boostbook();
+ }
+
+ value consume_last(value_consumer& c, value::tag_type tag,
+ std::vector<std::string>* duplicates)
     {
- return (qbk_version_n < version) ? raw : encoded;
+ value p;
+
+ int count = 0;
+ while(c.check(tag)) {
+ p = c.consume();
+ ++count;
+ }
+
+ if(count > 1) duplicates->push_back(doc_info_attributes::name(tag));
+
+ 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.empty()) return l;
+
+ assert(l.is_list());
+ value_consumer c2 = l;
+ value p = c2.consume();
+ c2.finish();
+
+ return p;
     }
 
- static void write_document_title(collector& out, quickbook::actions& actions);
- static void write_document_info(collector& out, quickbook::actions& actions);
+ std::vector<value> consume_multiple(value_consumer& c, value::tag_type tag)
+ {
+ std::vector<value> values;
+
+ while(c.check(tag)) {
+ values.push_back(c.consume());
+ }
+
+ return values;
+ }
 
     void pre(collector& out, quickbook::actions& actions, bool ignore_docinfo)
     {
         // The doc_info in the file has been parsed. Here's what we'll do
         // *before* anything else.
 
- if (!actions.doc_id_tmp.empty())
- actions.doc_id = actions.doc_id_tmp.get(106);
+ value_consumer values = actions.values.release();
 
- if (actions.doc_id.empty())
- actions.doc_id = detail::make_identifier(
- actions.doc_title.raw.begin(),actions.doc_title.raw.end());
+ // Skip over invalid attributes
+
+ while (values.check(value::default_tag)) values.consume();
+
+ value qbk_version = values.optional_consume(doc_info_tags::qbk_version);
+
+ value doc_title;
+ if (values.check())
+ {
+ actions.doc_type = values.consume(doc_info_tags::type).get_quickbook();
+ doc_title = values.consume(doc_info_tags::title);
+ actions.doc_title_qbk = doc_title.get_quickbook();
+ }
+
+ std::vector<std::string> 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_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_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.check(doc_info_attributes::source_mode)) values.consume();
+
+ values.finish();
 
- if (actions.doc_dirname.empty() && actions.doc_type == "library") {
- if (!actions.doc_id_tmp.empty()) {
- actions.doc_dirname = actions.doc_id_tmp;
+ if(!duplicates.empty())
+ {
+ detail::outwarn(actions.filename,1)
+ << (duplicates.size() > 1 ?
+ "Duplicate attributes" : "Duplicate attribute")
+ << ":" << detail::utf8(boost::algorithm::join(duplicates, ", "))
+ << "\n"
+ ;
+ }
+
+ if (!id.empty())
+ actions.doc_id = id.get_quickbook();
+
+ if (actions.doc_id.empty())
+ actions.doc_id = detail::make_identifier(actions.doc_title_qbk);
+
+ if (dirname.empty() && actions.doc_type == "library") {
+ if (!id.empty()) {
+ dirname = id;
             }
             else {
- actions.doc_dirname.raw = actions.doc_dirname.encoded = actions.doc_id;
+ dirname = qbk_bbk_value(actions.doc_id, doc_info_attributes::dirname);
             }
         }
 
- actions.doc_id_tmp.clear();
-
- if (actions.doc_last_revision.empty())
+ if (last_revision.empty())
         {
             // default value for last-revision is now
 
@@ -60,7 +146,7 @@
                     "$" /* prevent CVS substitution */ "Date: %Y/%m/%d %H:%M:%S $"),
                 current_gm_time
             );
- actions.doc_last_revision.raw = actions.doc_last_revision.encoded = strdate;
+ last_revision = qbk_bbk_value(strdate, doc_info_attributes::last_revision);
         }
 
         // if we're ignoring the document info, we're done.
@@ -71,31 +157,37 @@
 
         // Quickbook version
 
- if (qbk_major_version == -1)
+ int qbk_major_version, qbk_minor_version;
+
+ if (qbk_version.empty())
         {
             // hard code quickbook version to v1.1
             qbk_major_version = 1;
             qbk_minor_version = 1;
- qbk_version_n = 101;
- detail::outwarn(actions.filename.string(),1)
+ detail::outwarn(actions.filename,1)
                 << "Warning: Quickbook version undefined. "
                 "Version 1.1 is assumed" << std::endl;
         }
         else
         {
- qbk_version_n = ((unsigned) qbk_major_version * 100) +
- (unsigned) qbk_minor_version;
+ value_consumer qbk_version_values(qbk_version);
+ qbk_major_version = qbk_version_values.consume().get_int();
+ qbk_minor_version = qbk_version_values.consume().get_int();
+ qbk_version_values.finish();
         }
         
+ qbk_version_n = ((unsigned) qbk_major_version * 100) +
+ (unsigned) qbk_minor_version;
+
         if (qbk_version_n == 106)
         {
- detail::outwarn(actions.filename.string(),1)
+ detail::outwarn(actions.filename,1)
                 << "Quickbook 1.6 is still under development and is "
                 "likely to change in the future." << std::endl;
         }
         else if(qbk_version_n < 100 || qbk_version_n > 106)
         {
- detail::outerr(actions.filename.string(),1)
+ detail::outerr(actions.filename,1)
                 << "Unknown version of quickbook: quickbook "
                 << qbk_major_version
                 << "."
@@ -110,22 +202,22 @@
         {
             std::vector<std::string> invalid_attributes;
 
- if (!actions.doc_purpose.empty())
+ if (!purpose.empty())
                 invalid_attributes.push_back("purpose");
 
- if (!actions.doc_categories.empty())
+ if (!categories.empty())
                 invalid_attributes.push_back("category");
 
- if (!actions.doc_dirname.empty())
+ if (!dirname.empty())
                 invalid_attributes.push_back("dirname");
 
             if(!invalid_attributes.empty())
             {
- detail::outwarn(actions.filename.string(),1)
+ detail::outwarn(actions.filename,1)
                     << (invalid_attributes.size() > 1 ?
                         "Invalid attributes" : "Invalid attribute")
- << " for '" << actions.doc_type << " document info': "
- << boost::algorithm::join(invalid_attributes, ", ")
+ << " for '" << detail::utf8(actions.doc_type) << " document info': "
+ << detail::utf8(boost::algorithm::join(invalid_attributes, ", "))
                     << "\n"
                     ;
             }
@@ -143,109 +235,87 @@
             << actions.doc_id
             << "\"\n";
         
- if(!actions.doc_lang.empty())
+ if(!lang.empty())
         {
             out << " lang=\""
- << actions.doc_lang.get(106)
+ << doc_info_output(lang, 106)
                 << "\"\n";
         }
 
         if(actions.doc_type == "library")
         {
- out << " name=\"" << actions.doc_title.get(106) << "\"\n";
+ out << " name=\"" << doc_info_output(doc_title, 106) << "\"\n";
         }
 
- if(!actions.doc_dirname.empty())
+ if(!dirname.empty())
         {
             out << " dirname=\""
- << actions.doc_dirname.get(106)
+ << doc_info_output(dirname, 106)
                 << "\"\n";
         }
 
         out << " last-revision=\""
- << actions.doc_last_revision.get(106)
+ << doc_info_output(last_revision, 106)
             << "\" \n"
             << " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n";
-
- if(actions.doc_type == "library") {
- write_document_info(out, actions);
- write_document_title(out, actions);
- }
- else {
- write_document_title(out, actions);
- write_document_info(out, actions);
- }
- }
-
- void post(collector& out, quickbook::actions& actions, bool ignore_docinfo)
- {
- // if we're ignoring the document info, do nothing.
- if (ignore_docinfo)
- {
- return;
- }
 
- // We've finished generating our output. Here's what we'll do
- // *after* everything else.
- out << "\n</" << actions.doc_type << ">\n\n";
- }
-
- void write_document_title(collector& out, quickbook::actions& actions)
- {
- if (!actions.doc_title.empty())
- {
- out << " <title>"
- << actions.doc_title.get(106);
- if (!actions.doc_version.empty()) {
- out << ' ' << actions.doc_version.get(106);
- }
- out<< "</title>\n\n\n";
- }
- }
-
- void write_document_info(collector& out, quickbook::actions& actions)
- {
         std::ostringstream tmp;
 
- if(!actions.doc_authors.empty())
+ if(!authors.empty())
         {
             tmp << " <authorgroup>\n";
- for(actions::author_list::const_iterator
- it = actions.doc_authors.begin(),
- end = actions.doc_authors.end();
- it != end; ++it)
+ BOOST_FOREACH(value_consumer author_values, authors)
             {
- tmp << " <author>\n"
- << " <firstname>"
- << it->first.get(106)
- << "</firstname>\n"
- << " <surname>"
- << it->second.get(106)
- << "</surname>\n"
- << " </author>\n";
+ while (author_values.check()) {
+ value surname = author_values.consume(doc_info_tags::author_surname);
+ value first = author_values.consume(doc_info_tags::author_first);
+
+ tmp << " <author>\n"
+ << " <firstname>"
+ << doc_info_output(first, 106)
+ << "</firstname>\n"
+ << " <surname>"
+ << doc_info_output(surname, 106)
+ << "</surname>\n"
+ << " </author>\n";
+ }
             }
             tmp << " </authorgroup>\n";
         }
 
- if (!actions.doc_copyrights.empty())
+ BOOST_FOREACH(value_consumer copyright, copyrights)
         {
- for(actions::copyright_list::const_iterator
- it = actions.doc_copyrights.begin(),
- end = actions.doc_copyrights.end();
- it != end; ++it)
+ while(copyright.check())
             {
                 tmp << "\n" << " <copyright>\n";
-
- for(actions::string_list::const_iterator
- it2 = it->first.begin(),
- end = it->first.end();
- it2 != end; ++it2)
+
+ while(copyright.check(doc_info_tags::copyright_year))
                 {
- tmp << " <year>" << *it2 << "</year>\n";
+ int year_start = copyright.consume().get_int();
+ int year_end =
+ copyright.check(doc_info_tags::copyright_year_end) ?
+ copyright.consume().get_int() :
+ 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";
                 }
-
+
                 tmp << " <holder>"
- << it->second.get(106)
+ << doc_info_output(copyright.consume(doc_info_tags::copyright_name), 106)
                     << "</holder>\n"
                     << " </copyright>\n"
                     << "\n"
@@ -253,63 +323,95 @@
             }
         }
 
- if (!actions.doc_license.empty())
+ if (!license.empty())
         {
             tmp << " <legalnotice>\n"
                 << " <para>\n"
- << " " << actions.doc_license.get(103) << "\n"
+ << " " << doc_info_output(license, 103) << "\n"
                 << " </para>\n"
                 << " </legalnotice>\n"
                 << "\n"
             ;
         }
 
- if (!actions.doc_purpose.empty())
+ if (!purpose.empty())
         {
             tmp << " <" << actions.doc_type << "purpose>\n"
- << " " << actions.doc_purpose.get(103)
+ << " " << doc_info_output(purpose, 103)
                 << " </" << actions.doc_type << "purpose>\n"
                 << "\n"
                 ;
         }
 
- if (!actions.doc_categories.empty())
- {
- for(actions::docinfo_list::const_iterator
- it = actions.doc_categories.begin(),
- end = actions.doc_categories.end();
- it != end; ++it)
- {
+ BOOST_FOREACH(value_consumer values, categories) {
+ value category = values.optional_consume();
+ if(!category.empty()) {
                 tmp << " <" << actions.doc_type << "category name=\"category:"
- << it->get(106)
+ << doc_info_output(category, 106)
                     << "\"></" << actions.doc_type << "category>\n"
                     << "\n"
                 ;
             }
+ values.finish();
         }
 
- for (actions::biblioid_list::const_iterator
- it = actions.doc_biblioid_items.begin(),
- end = actions.doc_biblioid_items.end();
- it != end; ++it)
+ BOOST_FOREACH(value_consumer biblioid, biblioids)
         {
+ value class_ = biblioid.consume(doc_info_tags::biblioid_class);
+ value value_ = biblioid.consume(doc_info_tags::biblioid_value);
+
             tmp << " <biblioid class=\""
- << it->first
+ << class_.get_quickbook()
                 << "\">"
- << it->second.get(103)
+ << doc_info_output(value_, 106)
                 << "</biblioid>"
                 << "\n"
                 ;
+ biblioid.finish();
         }
 
- std::string value = tmp.str();
- if(!value.empty())
+ if(actions.doc_type != "library") {
+ write_document_title(out, doc_title, version);
+ }
+
+ std::string docinfo = tmp.str();
+ if(!docinfo.empty())
         {
             out << " <" << actions.doc_type << "info>\n"
- << value
+ << docinfo
                 << " </" << actions.doc_type << "info>\n"
                 << "\n"
             ;
         }
+
+ if(actions.doc_type == "library") {
+ write_document_title(out, doc_title, version);
+ }
+ }
+
+ void post(collector& out, quickbook::actions& actions, bool ignore_docinfo)
+ {
+ // if we're ignoring the document info, do nothing.
+ if (ignore_docinfo)
+ {
+ return;
+ }
+
+ // We've finished generating our output. Here's what we'll do
+ // *after* everything else.
+ out << "\n</" << actions.doc_type << ">\n\n";
+ }
+
+ static void write_document_title(collector& out, value const& title, value const& version)
+ {
+ if (!title.empty())
+ {
+ out << " <title>"
+ << doc_info_output(title, 106);
+ if (!version.empty()) {
+ out << ' ' << doc_info_output(version, 106);
+ }
+ out<< "</title>\n\n\n";
+ }
     }
 }

Modified: branches/release/tools/quickbook/src/doc_info_grammar.cpp
==============================================================================
--- branches/release/tools/quickbook/src/doc_info_grammar.cpp (original)
+++ branches/release/tools/quickbook/src/doc_info_grammar.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -8,32 +8,89 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
-#include "grammar_impl.hpp"
-#include "actions_class.hpp"
+#include <map>
+#include <boost/foreach.hpp>
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_actor.hpp>
 #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/classic_numerics.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include "grammar_impl.hpp"
+#include "actions_class.hpp"
+#include "doc_info_tags.hpp"
+#include "phrase_tags.hpp"
 
 namespace quickbook
 {
     namespace cl = boost::spirit::classic;
 
+ struct attribute_info
+ {
+ attribute_info(value::tag_type t, cl::rule<scanner>* r)
+ : tag(t), rule(r)
+ {}
+
+ value::tag_type tag;
+ cl::rule<scanner>* rule;
+ };
+
     struct doc_info_grammar_local
     {
+ struct assign_attribute_type
+ {
+ assign_attribute_type(doc_info_grammar_local& l)
+ : l(l)
+ {}
+
+ void operator()(value::tag_type& t) const {
+ l.attribute_rule = *l.attribute_rules[t];
+ l.attribute_tag = t;
+ }
+
+ doc_info_grammar_local& l;
+ };
+
+ struct fallback_attribute_type
+ {
+ fallback_attribute_type(doc_info_grammar_local& l)
+ : l(l)
+ {}
+
+ void operator()(iterator, iterator) const {
+ l.attribute_rule = l.doc_fallback;
+ l.attribute_tag = value::default_tag;
+ }
+
+ doc_info_grammar_local& l;
+ };
+
         cl::rule<scanner>
- doc_title, doc_version, doc_id, doc_dirname,
- doc_copyright, doc_purpose, doc_category, doc_authors,
- doc_author, doc_license,
- doc_last_revision, doc_source_mode, doc_biblioid, doc_lang,
+ doc_title, doc_simple, doc_phrase, doc_fallback,
+ doc_authors, doc_author,
+ doc_copyright, doc_copyright_holder,
+ doc_source_mode, doc_biblioid,
                         quickbook_version, char_;
+ cl::uint_parser<int, 10, 4, 4> doc_copyright_year;
         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;
+
+ doc_info_grammar_local()
+ : assign_attribute(*this)
+ , fallback_attribute(*this)
+ {}
     };
 
     void quickbook_grammar::impl::init_doc_info()
     {
- doc_info_grammar_local& local = store_.create();
+ doc_info_grammar_local& local = cleanup_.add(
+ new doc_info_grammar_local);
 
         typedef cl::uint_parser<int, 10, 1, 2> uint2_t;
 
@@ -42,150 +99,143 @@
           , "appendix", "preface", "qandadiv", "qandaset"
           , "reference", "set"
         ;
+
+ BOOST_FOREACH(value::tag_type t, doc_info_attributes::tags()) {
+ local.doc_attributes.add(doc_info_attributes::name(t), t);
+ }
         
         doc_info_details =
             space
>> '[' >> space
>> (local.doc_types >> cl::eps_p)
- [cl::assign_a(actions.doc_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.extract_doc_title]
+ ) [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::title)]
>> !(
                     space >> '[' >>
                         local.quickbook_version
>> space >> ']'
                 )
- >>
- *(
- space >> '[' >>
- (
- local.doc_version
- | local.doc_id
- | local.doc_dirname
- | local.doc_copyright [cl::push_back_a(actions.doc_copyrights, actions.copyright)]
- | local.doc_purpose
- | local.doc_category
- | local.doc_authors
- | local.doc_license
- | local.doc_last_revision
- | local.doc_source_mode
- | local.doc_biblioid
- | local.doc_lang
+ >> *(
+ space
+ >> '['
+ >> space
+ >> ( local.doc_attributes
+ [local.assign_attribute]
+ | (+(cl::alnum_p | '_' | '-'))
+ [local.fallback_attribute]
+ [actions.error("Unrecognized document attribute: '%s'.")]
                     )
- >> space >> ']' >> +cl::eol_p
+ >> hard_space
+ >> actions.values.list(ph::var(local.attribute_tag))
+ [local.attribute_rule]
+ >> space
+ >> ']'
+ >> +cl::eol_p
                 )
- >> space >> ']' >> +cl::eol_p
+ >> space [actions.values.sort()]
+ >> ']'
+ >> +cl::eol_p
             ;
 
         local.quickbook_version =
- "quickbook" >> hard_space
- >> ( cl::uint_p [assign_qbk_version(qbk_major_version)]
+ actions.values.list(doc_info_tags::qbk_version)
+ [ "quickbook"
+ >> hard_space
+ >> ( cl::uint_p [actions.values.entry(ph::arg1)]
>> '.'
- >> uint2_t() [assign_qbk_version(qbk_minor_version)]
+ >> uint2_t() [actions.values.entry(ph::arg1)]
                 )
+ ]
             ;
 
- local.doc_version =
- "version" >> hard_space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_version]
- ;
-
- // TODO: Restrictions on doc_id?
- local.doc_id =
- "id" >> hard_space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_id]
- ;
-
- // TODO: Restrictions on doc_dirname?
- local.doc_dirname =
- "dirname" >> hard_space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_dirname]
- ;
+ // TODO: Clear phrase afterwards?
+
+ local.doc_fallback = (*(~cl::eps_p(']') >> local.char_));
+
+ // TODO: Restrictions on doc_id and doc_dirname?
+
+ 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;
+ local.attribute_rules[doc_info_attributes::category] = &local.doc_simple;
+ local.attribute_rules[doc_info_attributes::last_revision] = &local.doc_simple;
+ local.attribute_rules[doc_info_attributes::lang] = &local.doc_simple;
+
+ local.doc_copyright_holder
+ = *( ~cl::eps_p
+ ( ']'
+ | ',' >> space >> local.doc_copyright_year
+ )
+ >> local.char_
+ );
 
         local.doc_copyright =
- "copyright"
- >> hard_space [cl::clear_a(actions.copyright.first)]
- >> +( cl::repeat_p(4)[cl::digit_p]
- [cl::push_back_a(actions.copyright.first)]
- >> space
+ *( +( local.doc_copyright_year
+ [actions.values.entry(ph::arg1, doc_info_tags::copyright_year)]
+ >> space
+ >> !( '-'
+ >> space
+ >> local.doc_copyright_year
+ [actions.values.entry(ph::arg1, doc_info_tags::copyright_year_end)]
+ >> space
+ )
+ >> !cl::ch_p(',')
+ >> space
                 )
- >> space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_copyright_second]
+ >> local.doc_copyright_holder [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::copyright_name)]
+ >> !cl::ch_p(',')
+ >> space
+ )
             ;
 
- local.doc_purpose =
- "purpose" >> hard_space
- >> simple_phrase [actions.extract_doc_purpose]
- ;
+ local.attribute_rules[doc_info_attributes::copyright] = &local.doc_copyright;
 
- local.doc_category =
- "category" >> hard_space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_category]
- [cl::push_back_a(actions.doc_categories, actions.doc_category)]
- ;
+ 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;
 
         local.doc_author =
- '[' >> space
+ '['
+ >> space
>> (*(~cl::eps_p(',') >> local.char_))
- [actions.extract_name_second]
+ [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::author_surname)]
>> ',' >> space
>> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_name_first]
+ [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::author_first)]
>> ']'
             ;
 
         local.doc_authors =
- "authors"
- >> hard_space
- >> local.doc_author [cl::push_back_a(actions.doc_authors, actions.name)]
+ *( local.doc_author
>> space
- >> *( !(cl::ch_p(',') >> space)
- >> local.doc_author [cl::push_back_a(actions.doc_authors, actions.name)]
- >> space
- )
+ >> !(cl::ch_p(',') >> space)
+ )
             ;
 
- local.doc_license =
- "license" >> hard_space
- >> simple_phrase [actions.extract_doc_license]
- ;
-
- local.doc_last_revision =
- "last-revision" >> hard_space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_last_revision]
- ;
+ local.attribute_rules[doc_info_attributes::authors] = &local.doc_authors;
 
         local.doc_source_mode =
- "source-mode" >> hard_space
- >> (
+ (
                    cl::str_p("c++")
                 | "python"
                 | "teletype"
                 ) [cl::assign_a(actions.source_mode)]
             ;
 
+ local.attribute_rules[doc_info_attributes::source_mode] = &local.doc_source_mode;
+
         local.doc_biblioid =
- "biblioid"
- >> hard_space
- >> (+cl::alnum_p) [cl::assign_a(actions.doc_biblioid.first)]
+ (+cl::alnum_p) [actions.values.entry(ph::arg1, ph::arg2, doc_info_tags::biblioid_class)]
>> hard_space
>> (+(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_biblioid]
- [cl::push_back_a(actions.doc_biblioid_items, actions.doc_biblioid)]
+ [actions.docinfo_value(ph::arg1, ph::arg2, doc_info_tags::biblioid_value)]
             ;
 
- local.doc_lang =
- "lang" >> hard_space
- >> (*(~cl::eps_p(']') >> local.char_))
- [actions.extract_doc_lang]
- ;
+ local.attribute_rules[doc_info_attributes::biblioid] = &local.doc_biblioid;
 
         local.char_ =
                 cl::str_p("\\n") [actions.break_]
@@ -197,11 +247,12 @@
             | "\\U" >> cl::repeat_p(8)
                     [cl::chset<>("0-9a-fA-F")]
                                             [actions.escape_unicode]
- | (
- ("'''" >> !cl::eol_p) [actions.escape_pre]
- >> *(cl::anychar_p - "'''")[actions.raw_char]
- >> cl::str_p("'''") [actions.escape_post]
- )
+ | ("'''" >> !eol)
+ >> actions.values.save()
+ [ (*(cl::anychar_p - "'''"))
+ [actions.values.entry(ph::arg1, ph::arg2, phrase_tags::escape)]
+ >> cl::str_p("'''") [actions.element]
+ ]
             | cl::anychar_p [actions.plain_char]
             ;
     }

Modified: branches/release/tools/quickbook/src/fwd.hpp
==============================================================================
--- branches/release/tools/quickbook/src/fwd.hpp (original)
+++ branches/release/tools/quickbook/src/fwd.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,18 +11,17 @@
 #if !defined(BOOST_SPIRIT_FWD_HPP)
 #define BOOST_SPIRIT_FWD_HPP
 
-#include <boost/spirit/include/classic_iterator.hpp>
-#include <boost/range.hpp>
-#include <boost/shared_ptr.hpp>
+#include "iterator.hpp"
 
 namespace quickbook
 {
     struct actions;
     struct quickbook_grammar;
+ struct collector;
 
- typedef boost::spirit::classic::file_position_base<char const*> position;
- typedef boost::spirit::classic::position_iterator<
- std::string::const_iterator, position> iterator;
+ typedef position_iterator<std::string::const_iterator> iterator;
+
+ inline void ignore_variable(void const*) {}
 }
 
 #endif

Modified: branches/release/tools/quickbook/src/grammar.cpp
==============================================================================
--- branches/release/tools/quickbook/src/grammar.cpp (original)
+++ branches/release/tools/quickbook/src/grammar.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -30,7 +30,7 @@
 
     quickbook_grammar::impl::impl(quickbook::actions& a)
         : actions(a)
- , store_()
+ , cleanup_()
     {
         init_main();
         init_block_elements();

Modified: branches/release/tools/quickbook/src/grammar.hpp
==============================================================================
--- branches/release/tools/quickbook/src/grammar.hpp (original)
+++ branches/release/tools/quickbook/src/grammar.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -44,7 +44,7 @@
         cl::rule<scanner> const& start_rule;
     };
 
- class quickbook_grammar
+ struct quickbook_grammar
     {
     public:
         struct impl;

Modified: branches/release/tools/quickbook/src/grammar_impl.hpp
==============================================================================
--- branches/release/tools/quickbook/src/grammar_impl.hpp (original)
+++ branches/release/tools/quickbook/src/grammar_impl.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -12,7 +12,8 @@
 #define BOOST_SPIRIT_QUICKBOOK_GRAMMARS_IMPL_HPP
 
 #include "grammar.hpp"
-#include "rule_store.hpp"
+#include "cleanup.hpp"
+#include "values.hpp"
 #include <boost/spirit/include/classic_symbols.hpp>
 
 namespace quickbook
@@ -25,25 +26,37 @@
             in_block = 1,
             in_phrase = 2,
             in_conditional = 4,
+ in_nested_block = 8
         };
 
         enum type_enum {
- block = 1,
- phrase = 2,
- conditional_or_block = 5
+ nothing = 0,
+ block = in_block,
+ conditional_or_block = block | in_conditional,
+ nested_block = conditional_or_block | in_nested_block,
+ phrase = nested_block | in_phrase
         };
 
- element_info(type_enum t, cl::rule<scanner>* r)
- : type(t), rule(r) {}
+ element_info()
+ : type(nothing), rule(), tag(0) {}
+
+ element_info(
+ type_enum t,
+ cl::rule<scanner>* r,
+ value::tag_type tag = value::default_tag,
+ unsigned int v = 0)
+ : type(t), rule(r), tag(tag), qbk_version(v) {}
 
         type_enum type;
         cl::rule<scanner>* rule;
+ value::tag_type tag;
+ unsigned int qbk_version;
     };
 
     struct quickbook_grammar::impl
     {
         quickbook::actions& actions;
- rule_store store_;
+ cleanup cleanup_;
 
         // Main Grammar
         cl::rule<scanner> block_start;

Modified: branches/release/tools/quickbook/src/input_path.cpp
==============================================================================
--- branches/release/tools/quickbook/src/input_path.cpp (original)
+++ branches/release/tools/quickbook/src/input_path.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -7,68 +7,240 @@
 =============================================================================*/
 
 #include <boost/program_options.hpp>
+#include <iostream>
 #include "input_path.hpp"
+#include "utils.hpp"
 
-#if !(defined(__cygwin__) || defined(__CYGWIN__))
+#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
+#include <boost/scoped_ptr.hpp>
+#include <windows.h>
+#include <io.h>
+#include <fcntl.h>
+#endif
 
-// Everything but cygwin
+#if QUICKBOOK_CYGWIN_PATHS
+#include <boost/scoped_array.hpp>
+#include <boost/program_options/errors.hpp>
+#include <sys/cygwin.h>
+#endif
 
-namespace quickbook { namespace detail
-{
- void validate(boost::any& v,
- const std::vector<std::string>& values,
- input_path*, int)
- {
- std::string path
- = boost::program_options::validators::get_single_string(values);
+namespace quickbook {
+ extern bool ms_errors;
+}
+
+namespace quickbook {
+namespace detail {
+
+// This is used for converting paths to UTF-8 on cygin.
+// Might be better not to use a windows
+#if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS
+ namespace {
+ std::string to_utf8(std::wstring const& x)
+ {
+ int buffer_count = WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, 0, 0, 0, 0);
+
+ if (!buffer_count)
+ throw conversion_error("Error converting wide string to utf-8.");
+
+ boost::scoped_ptr<char> buffer(new char[buffer_count]);
+
+ if (!WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count, 0, 0))
+ throw conversion_error("Error converting wide string to utf-8.");
+
+ return std::string(buffer.get());
+ }
 
- v = input_path(path);
+ std::wstring from_utf8(std::string const& x)
+ {
+ int buffer_count = MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, 0, 0);
+
+ if (!buffer_count)
+ throw conversion_error("Error converting utf-8 to wide string.");
+
+ boost::scoped_ptr<wchar_t> buffer(new wchar_t[buffer_count]);
+
+ if (!MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count))
+ throw conversion_error("Error converting utf-8 to wide string.");
+
+ return std::wstring(buffer.get());
+ }
     }
-}}
+#endif
 
+#if QUICKBOOK_WIDE_PATHS
+ std::string input_to_utf8(input_string const& x)
+ {
+ return to_utf8(x);
+ }
 #else
+ std::string input_to_utf8(input_string const& x)
+ {
+ return x;
+ }
+#endif
 
-// Cygwin 1.7.x
-
-#include <boost/filesystem/v3/config.hpp>
-#include <boost/scoped_array.hpp>
-#include <boost/program_options/errors.hpp>
-#include <windows.h>
-#include <sys/cygwin.h>
+#if QUICKBOOK_WIDE_PATHS
+ fs::path generic_to_path(std::string const& x)
+ {
+ return fs::path(from_utf8(x));
+ }
 
-namespace quickbook { namespace detail
-{
- void validate(boost::any& v,
- const std::vector<std::string>& values,
- input_path*, int)
- {
- std::string path
- = boost::program_options::validators::get_single_string(values);
-
-#if defined(BOOST_WINDOWS_PATH)
- cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
-#elif defined(BOOST_POSIX_PATH)
- cygwin_conv_path_t flags = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
+ std::string path_to_generic(fs::path const& x)
+ {
+ return to_utf8(x.generic_wstring());
+ }
 #else
-# error "Boost filesystem path type doesn't seem to be set."
+ fs::path generic_to_path(std::string const& x)
+ {
+ return fs::path(x);
+ }
+
+ std::string path_to_generic(fs::path const& x)
+ {
+ return x.generic_string();
+ }
+
 #endif
 
+#if QUICKBOOK_CYGWIN_PATHS
+ fs::path input_to_path(input_string const& path)
+ {
+ cygwin_conv_path_t flags = CCP_POSIX_TO_WIN_W | CCP_RELATIVE;
+
         ssize_t size = cygwin_conv_path(flags, path.c_str(), NULL, 0);
         
- if (size < 0) {
- throw boost::program_options::validation_error(
- boost::program_options::validation_error::invalid_option_value);
- }
+ if (size < 0)
+ throw conversion_error("Error converting cygwin path to windows.");
+
+ // TODO: size is in bytes.
+ boost::scoped_array<wchar_t> result(new wchar_t[size]);
+
+ if(cygwin_conv_path(flags, path.c_str(), result.get(), size))
+ throw conversion_error("Error converting cygwin path to windows.");
+
+ return fs::path(result.get());
+ }
+
+ stream_string path_to_stream(fs::path const& path)
+ {
+ cygwin_conv_path_t flags = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
+
+ ssize_t size = cygwin_conv_path(flags, path.native().c_str(), NULL, 0);
+
+ if (size < 0)
+ throw conversion_error("Error converting windows path to cygwin.");
 
         boost::scoped_array<char> result(new char[size]);
 
- if(cygwin_conv_path(flags, path.c_str(), result.get(), size)) {
- throw boost::program_options::validation_error(
- boost::program_options::validation_error::invalid_option_value);
+ if(cygwin_conv_path(flags, path.native().c_str(), result.get(), size))
+ throw conversion_error("Error converting windows path to cygwin.");
+
+ return std::string(result.get());
+ }
+#else
+ fs::path input_to_path(input_string const& path)
+ {
+ return fs::path(path);
+ }
+
+#if QUICKBOOK_WIDE_PATHS && !QUICKBOOK_WIDE_STREAMS
+ stream_string path_to_stream(fs::path const& path)
+ {
+ return path.string();
+ }
+#else
+ stream_string path_to_stream(fs::path const& path)
+ {
+ return path.native();
+ }
+#endif
+
+#endif // QUICKBOOK_CYGWIN_PATHS
+
+#if QUICKBOOK_WIDE_STREAMS
+
+ void initialise_output()
+ {
+ if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT);
+ if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT);
+ }
+
+ void write_utf8(ostream& out, std::string const& x)
+ {
+ out << from_utf8(x);
+ }
+
+ ostream& out()
+ {
+ return std::wcout;
+ }
+
+ namespace
+ {
+ inline ostream& error_stream()
+ {
+ return std::wcerr;
         }
+ }
 
- v = input_path(result.get());
+#else
+
+ void initialise_output()
+ {
+ }
+
+ void write_utf8(ostream& out, std::string const& x)
+ {
+ out << x;
+ }
+
+ ostream& out()
+ {
+ return std::cout;
+ }
+
+ namespace
+ {
+ inline ostream& error_stream()
+ {
+ return std::clog;
+ }
     }
-}}
 
 #endif
+
+ ostream& outerr()
+ {
+ return error_stream() << "Error: ";
+ }
+
+ ostream& outerr(fs::path const& file, int line)
+ {
+ if (line >= 0)
+ {
+ if (ms_errors)
+ return error_stream() << path_to_stream(file) << "(" << line << "): error: ";
+ else
+ return error_stream() << path_to_stream(file) << ":" << line << ": error: ";
+ }
+ else
+ {
+ return error_stream() << path_to_stream(file) << ": error: ";
+ }
+ }
+
+ ostream& outwarn(fs::path const& file, int line)
+ {
+ if (line >= 0)
+ {
+ if (ms_errors)
+ return error_stream() << path_to_stream(file) << "(" << line << "): warning: ";
+ else
+ return error_stream() << path_to_stream(file) << ":" << line << ": warning: ";
+ }
+ else
+ {
+ return error_stream() << path_to_stream(file) << ": warning: ";
+ }
+ }
+}}

Modified: branches/release/tools/quickbook/src/input_path.hpp
==============================================================================
--- branches/release/tools/quickbook/src/input_path.hpp (original)
+++ branches/release/tools/quickbook/src/input_path.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -9,31 +9,112 @@
 #if !defined(BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP)
 #define BOOST_QUICKBOOK_DETAIL_INPUT_PATH_HPP
 
-#include <vector>
-#include <boost/any.hpp>
+#include <boost/config.hpp>
+#include <boost/filesystem/v3/path.hpp>
 #include <string>
+#include <stdexcept>
+#include <iostream>
 
-namespace quickbook { namespace detail
+#if defined(__cygwin__) || defined(__CYGWIN__)
+# define QUICKBOOK_CYGWIN_PATHS 1
+#elif defined(_WIN32)
+# define QUICKBOOK_WIDE_PATHS 1
+# if defined(BOOST_MSVC) && BOOST_MSVC >= 1400
+# define QUICKBOOK_WIDE_STREAMS 1
+# endif
+#endif
+
+#if !defined(QUICKBOOK_WIDE_PATHS)
+#define QUICKBOOK_WIDE_PATHS 0
+#endif
+
+#if !defined(QUICKBOOK_WIDE_STREAMS)
+#define QUICKBOOK_WIDE_STREAMS 0
+#endif
+
+#if !defined(QUICKBOOK_CYGWIN_PATHS)
+#define QUICKBOOK_CYGWIN_PATHS 0
+#endif
+
+namespace quickbook
 {
- // Use this class with Boost.Program Options to convert paths to the format
- // the Boost.Filesystem expects. This is needed on cygwin to convert cygwin
- // paths to windows paths (or vice versa, depending on how filesystem is set
- // up).
- //
- // Note that we don't want to convert paths in quickbook files, as they
- // should be platform independent, and aren't necessarily relative to the
- // current directory.
-
- class input_path {
- std::string path_;
- public:
- explicit input_path(char const* c) : path_(c) {}
- explicit input_path(std::string const& c) : path_(c) {}
- operator std::string() const { return path_; }
-
- friend void validate(boost::any&, const std::vector<std::string>&,
- input_path*, int);
- };
-}}
+ namespace fs = boost::filesystem;
+
+ namespace detail
+ {
+ struct conversion_error : std::runtime_error
+ {
+ conversion_error(char const* m) : std::runtime_error(m) {}
+ };
+
+ // 'generic': Paths in quickbook source and the generated boostbook.
+ // Always UTF-8.
+ // 'input': Paths (or other parameters) from the command line and
+ // possibly other sources in the future. Wide strings on
+ // normal windows, UTF-8 for cygwin and other platforms
+ // (hopefully).
+ // 'stream': Strings to be written to a stream.
+ // 'path': Stored as a boost::filesystem::path. Since
+ // Boost.Filesystem doesn't support cygwin, this
+ // is always wide on windows. UTF-8 on other
+ // platforms (again, hopefully).
+
+#if QUICKBOOK_WIDE_PATHS
+ typedef std::wstring input_string;
+#else
+ typedef std::string input_string;
+#endif
+
+#if QUICKBOOK_WIDE_STREAMS
+ typedef std::wostream ostream;
+ typedef std::wstring stream_string;
+#else
+ typedef std::ostream ostream;
+ typedef std::string stream_string;
+#endif
+
+ std::string input_to_utf8(input_string const&);
+ fs::path input_to_path(input_string const&);
+ stream_string path_to_stream(fs::path const&);
+
+ std::string path_to_generic(fs::path const&);
+ fs::path generic_to_path(std::string const&);
+
+ void initialise_output();
+
+ ostream& out();
+
+ // Preformats an error/warning message so that it can be parsed by
+ // common IDEs. Uses the ms_errors global to determine if VS format
+ // or GCC format. Returns the stream to continue ouput of the verbose
+ // error message.
+ ostream& outerr();
+ ostream& outerr(fs::path const& file, int line = -1);
+ ostream& outwarn(fs::path const& file, int line = -1);
+
+ struct utf8_proxy
+ {
+ std::string value;
+
+ explicit utf8_proxy(std::string const& v) : value(v) {}
+ };
+
+ void write_utf8(ostream& out, std::string const&);
+
+ inline ostream& operator<<(ostream& out, utf8_proxy const& p) {
+ write_utf8(out, p.value);
+ return out;
+ }
+
+ inline utf8_proxy utf8(std::string const& value) {
+ return utf8_proxy(value);
+ }
+
+ template <typename It>
+ inline utf8_proxy utf8(It begin, It end) {
+ return utf8_proxy(std::string(begin, end));
+ }
+ }
+}
 
 #endif

Copied: branches/release/tools/quickbook/src/iterator.hpp (from r70044, /trunk/tools/quickbook/src/iterator.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/iterator.hpp (original)
+++ branches/release/tools/quickbook/src/iterator.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,6 +11,8 @@
 
 #include <boost/operators.hpp>
 #include <boost/iterator/iterator_traits.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <iterator>
 
 namespace quickbook
 {
@@ -35,9 +37,9 @@
     {
         position_iterator() {}
         explicit position_iterator(Iterator base)
- : base_(base), previous_('\0'), position_() {}
+ : original_(base), base_(base), previous_('\0'), position_() {}
         explicit position_iterator(Iterator base, file_position const& position)
- : base_(base), previous_('\0'), position_(position) {}
+ : original_(base), base_(base), previous_('\0'), position_(position) {}
     
         friend bool operator==(
             position_iterator const& x,
@@ -82,8 +84,17 @@
         Iterator base() const {
             return base_;
         }
+
+ typedef boost::iterator_range<std::reverse_iterator<Iterator> >
+ lookback_range;
+
+ lookback_range lookback() const
+ {
+ return lookback_range(base_, original_);
+ }
     
     private:
+ Iterator original_;
         Iterator base_;
         char previous_;
         file_position position_;

Modified: branches/release/tools/quickbook/src/main_grammar.cpp
==============================================================================
--- branches/release/tools/quickbook/src/main_grammar.cpp (original)
+++ branches/release/tools/quickbook/src/main_grammar.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,114 +11,127 @@
 #include "grammar_impl.hpp"
 #include "actions_class.hpp"
 #include "utils.hpp"
+#include "template_tags.hpp"
+#include "block_tags.hpp"
+#include "phrase_tags.hpp"
+#include "parsers.hpp"
+#include "scoped.hpp"
 #include <boost/spirit/include/classic_core.hpp>
-#include <boost/spirit/include/classic_confix.hpp>
 #include <boost/spirit/include/classic_chset.hpp>
-#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/classic_attribute.hpp>
+#include <boost/spirit/include/classic_lazy.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
 
 namespace quickbook
 {
     namespace cl = boost::spirit::classic;
 
- template <typename Rule, typename Action>
- inline void
- simple_markup(
- Rule& simple
- , char mark
- , Action const& action
- , Rule const& close
- )
- {
- simple =
- mark >>
- (
- (
- cl::graph_p // A single char. e.g. *c*
- >> cl::eps_p(mark
- >> (cl::space_p | cl::punct_p | cl::end_p))
- // space_p, punct_p or end_p
- ) // must follow mark
- |
- ( cl::graph_p >> // graph_p must follow mark
- *(cl::anychar_p -
- ( (cl::graph_p >> mark) // Make sure that we don't go
- | close // past a single block
- )
- ) >> cl::graph_p // graph_p must precede mark
- >> cl::eps_p(mark
- >> (cl::space_p | cl::punct_p | cl::end_p))
- // space_p, punct_p or end_p
- ) // must follow mark
- ) [action]
- >> mark
- ;
- }
-
     struct main_grammar_local
     {
+ struct process_element_impl : scoped_action_base {
+ process_element_impl(main_grammar_local& l)
+ : l(l) {}
+
+ bool start()
+ {
+ if (!(l.info.type & l.actions_.context) ||
+ qbk_version_n < l.info.qbk_version)
+ return false;
+
+ info_ = l.info;
+
+ if (!(info_.type & element_info::in_phrase))
+ l.actions_.paragraph();
+
+ l.actions_.values.builder.reset();
+
+ return true;
+ }
+
+ template <typename ResultT, typename ScannerT>
+ bool result(ResultT result, ScannerT const& scan)
+ {
+ if (result || info_.type & element_info::in_phrase)
+ return result;
+
+ l.actions_.error(scan.first, scan.first);
+ return true;
+ }
+
+ void success() { l.element_type = info_.type; }
+ void failure() { l.element_type = element_info::nothing; }
+
+ main_grammar_local& l;
+ element_info info_;
+ };
+
+ struct is_block_type
+ {
+ typedef bool result_type;
+ template <typename Arg1 = void>
+ struct result { typedef bool type; };
+
+ is_block_type(main_grammar_local& l)
+ : l_(l)
+ {}
+
+ bool operator()() const
+ {
+ return l_.element_type && !(l_.element_type & element_info::in_phrase);
+ }
+
+ main_grammar_local& l_;
+ };
+
         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_,
+ list, list_item,
+ nested_char, escape,
+ inline_code,
+ 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_args_1_5, template_arg_1_5, template_arg_1_5_content,
                         template_inner_arg_1_5, brackets_1_5,
+ break_,
                         command_line_macro_identifier, command_line_phrase,
                         dummy_block
                         ;
 
- struct assign_element_type {
- assign_element_type(main_grammar_local& l) : l(l) {}
+ cl::rule<scanner> element;
 
- void operator()(element_info& t) const {
- l.element_type = t.type;
- l.element_rule = *t.rule;
- }
-
- main_grammar_local& l;
+ struct simple_markup_closure
+ : cl::closure<simple_markup_closure, char>
+ {
+ member1 mark;
         };
 
- struct check_element_type {
- check_element_type(main_grammar_local const& l, element_info::context t)
- : l(l), t(t) {}
-
- bool operator()() const {
- return l.element_type & t;
- }
-
- main_grammar_local const& l;
- element_info::context t;
- };
+ cl::rule<scanner, simple_markup_closure::context_t> simple_markup;
+ cl::rule<scanner> simple_markup_end;
 
+ element_info info;
         element_info::type_enum element_type;
- cl::rule<scanner> element_rule;
- assign_element_type assign_element;
 
- main_grammar_local()
- : assign_element(*this) {}
-
- check_element_type check_element(element_info::context t) const {
- return check_element_type(*this, t);
- }
+ quickbook::actions& actions_;
+ scoped_parser<process_element_impl> process_element;
+ is_block_type is_block;
+
+ main_grammar_local(quickbook::actions& actions)
+ : actions_(actions)
+ , process_element(*this)
+ , is_block(*this)
+ {}
     };
 
     void quickbook_grammar::impl::init_main()
     {
- using detail::var;
-
- main_grammar_local& local = store_.create();
+ main_grammar_local& local = cleanup_.add(
+ new main_grammar_local(actions));
 
         block_skip_initial_spaces =
             *(cl::blank_p | comment) >> block_start
@@ -128,20 +141,25 @@
             local.top_level >> blank
             ;
 
- local.top_level
- = local.blocks
- >> *(
- local.block_element >> !(+eol >> local.blocks)
+ local.top_level =
+ actions.scoped_context(element_info::in_block)
+ [ local.blocks
+ >> *( local.element
+ >> cl::if_p(local.is_block)
+ [ !(+eol >> local.blocks)
+ ]
                 | local.paragraph_separator >> local.blocks
                 | common
                 | cl::space_p [actions.space_char]
                 | cl::anychar_p [actions.plain_char]
- );
+ )
+ ]
+ ;
 
         local.blocks =
            *( local.code
- | local.list [actions.list]
- | local.hr [actions.hr]
+ | local.list
+ | local.hr
             | +eol
             )
             ;
@@ -149,28 +167,33 @@
         local.paragraph_separator
             = cl::eol_p
>> *cl::blank_p
- >> cl::eol_p [actions.inside_paragraph]
+ >> cl::eol_p [actions.paragraph]
             ;
 
         local.hr =
- cl::str_p("----")
- >> *(cl::anychar_p - eol)
- >> +eol
+ cl::str_p("----")
+ >> actions.values.list(block_tags::hr)
+ [ *(cl::anychar_p - eol)
+ >> +eol
+ ] [actions.element]
             ;
 
- local.block_element
- = '[' >> space
- >> local.element
- >> cl::eps_p(local.check_element(element_info::in_block))
- [actions.inside_paragraph]
- >> ( local.element_rule
- >> ( (space >> ']')
- | cl::eps_p [actions.error]
- )
- | cl::eps_p [actions.error]
+ local.element
+ = '['
+ >> ( cl::eps_p(cl::punct_p)
+ >> elements [ph::var(local.info) = ph::arg1]
+ | elements [ph::var(local.info) = ph::arg1]
+ >> (cl::eps_p - (cl::alnum_p | '_'))
                 )
+ >> local.process_element()
+ [ actions.values.list(ph::var(local.info.tag))
+ [ cl::lazy_p(*ph::var(local.info.rule))
+ >> space
+ >> ']'
+ ] [actions.element]
+ ]
             ;
-
+
         local.code =
             (
                 local.code_line
@@ -188,32 +211,47 @@
             ;
 
         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.scoped_output()
+ [
+ actions.values.list(block_tags::list)
+ [ +actions.values.list()
+ [ (*cl::blank_p) [actions.values.entry(ph::arg1, ph::arg2, general_tags::list_indent)]
+ >> (cl::ch_p('*') | '#')
+ [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.scoped_context(element_info::in_phrase)
+ [
+ actions.values.save()
+ [
+ *( common
+ | (cl::anychar_p -
+ ( cl::eol_p >> *cl::blank_p
+ >> (cl::ch_p('*') | '#' | cl::eol_p)
+ )
+ ) [actions.plain_char]
+ )
+ ]
+ ]
>> +eol
             ;
 
         common =
                 local.macro
- | local.phrase_element
+ | local.element
+ | local.template_
+ | local.break_
             | local.code_block
             | local.inline_code
- | local.simple_format
+ | local.simple_markup
             | local.escape
             | comment
             ;
@@ -225,31 +263,21 @@
>> actions.macro [actions.do_macro]
             ;
 
- static const bool true_ = true;
- static const bool false_ = false;
-
         local.template_ =
- (
- cl::ch_p('`') [cl::assign_a(actions.template_escape,true_)]
- |
- cl::eps_p [cl::assign_a(actions.template_escape,false_)]
- )
- >>
- ( (
- (cl::eps_p(cl::punct_p)
- >> actions.templates.scope
- ) [cl::assign_a(actions.template_identifier)]
- [cl::clear_a(actions.template_args)]
- >> !local.template_args
- ) | (
- (actions.templates.scope
- >> cl::eps_p(hard_space)
- ) [cl::assign_a(actions.template_identifier)]
- [cl::clear_a(actions.template_args)]
- >> space
- >> !local.template_args
- ) )
- >> cl::eps_p(']')
+ ( '['
+ >> space
+ >> actions.values.list(template_tags::template_)
+ [ !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(ph::arg1, ph::arg2, template_tags::identifier)]
+ | actions.templates.scope [actions.values.entry(ph::arg1, ph::arg2, template_tags::identifier)]
+ >> cl::eps_p(hard_space)
+ )
+ >> space
+ >> !local.template_args
+ >> ']'
+ ]
+ ) [actions.element]
             ;
 
         local.template_args =
@@ -263,11 +291,10 @@
         local.template_args_1_4 = local.template_arg_1_4 >> *(".." >> local.template_arg_1_4);
 
         local.template_arg_1_4 =
- ( cl::eps_p(*cl::blank_p >> cl::eol_p)
- [cl::assign_a(actions.template_block, true_)]
- | cl::eps_p [cl::assign_a(actions.template_block, false_)]
- )
- >> local.template_inner_arg_1_4 [actions.template_arg]
+ ( cl::eps_p(*cl::blank_p >> cl::eol_p)
+ >> 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)]
+ )
             ;
 
         local.template_inner_arg_1_4 =
@@ -281,12 +308,14 @@
         local.template_args_1_5 = local.template_arg_1_5 >> *(".." >> local.template_arg_1_5);
 
         local.template_arg_1_5 =
- ( cl::eps_p(*cl::blank_p >> cl::eol_p)
- [cl::assign_a(actions.template_block, true_)]
- | cl::eps_p [cl::assign_a(actions.template_block, false_)]
- )
- >> (+(local.brackets_1_5 | ('\\' >> cl::anychar_p) | (cl::anychar_p - (cl::str_p("..") | '[' | ']'))))
- [actions.template_arg]
+ ( cl::eps_p(*cl::blank_p >> cl::eol_p)
+ >> 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)]
+ )
+ ;
+
+ local.template_arg_1_5_content =
+ +(local.brackets_1_5 | ('\\' >> cl::anychar_p) | (cl::anychar_p - (cl::str_p("..") | '[' | ']')))
             ;
 
         local.template_inner_arg_1_5 =
@@ -297,6 +326,15 @@
             '[' >> local.template_inner_arg_1_5 >> ']'
             ;
 
+ local.break_
+ = ( '['
+ >> space
+ >> "br"
+ >> space
+ >> ']'
+ ) [actions.break_]
+ ;
+
         local.inline_code =
             '`' >>
             (
@@ -329,75 +367,97 @@
                 )
             ;
 
- local.simple_format =
- local.simple_bold
- | local.simple_italic
- | local.simple_underline
- | local.simple_teletype
- ;
-
- local.simple_phrase_end = '[' | phrase_end;
-
- simple_markup(local.simple_bold,
- '*', actions.simple_bold, local.simple_phrase_end);
- simple_markup(local.simple_italic,
- '/', actions.simple_italic, local.simple_phrase_end);
- simple_markup(local.simple_underline,
- '_', actions.simple_underline, local.simple_phrase_end);
- simple_markup(local.simple_teletype,
- '=', actions.simple_teletype, local.simple_phrase_end);
+ local.simple_markup =
+ cl::chset<>("*/_=") [local.simple_markup.mark = ph::arg1]
+ >> cl::eps_p(cl::graph_p) // graph_p must follow first mark
+ >> lookback
+ [ cl::anychar_p
+ >> ~cl::eps_p(cl::f_ch_p(local.simple_markup.mark))
+ // first mark not be preceeded by
+ // the same character.
+ >> (cl::space_p | cl::punct_p | cl::end_p)
+ // first mark must be preceeded
+ // by space or punctuation or the
+ // mark character or a the start.
+ ]
+ >> actions.values.save()
+ [
+ actions.scoped_output()
+ [
+ (*( ~cl::eps_p(local.simple_markup_end)
+ >> local.nested_char
+ )) [actions.docinfo_value(ph::arg1, ph::arg2)]
+ ]
+ >> cl::f_ch_p(local.simple_markup.mark)
+ [actions.simple_markup]
+ ]
+ ;
+
+ local.simple_markup_end
+ = ( lookback[cl::graph_p] // final mark must be preceeded by
+ // graph_p
+ >> cl::f_ch_p(local.simple_markup.mark)
+ >> ~cl::eps_p(cl::f_ch_p(local.simple_markup.mark))
+ // final mark not be followed by
+ // the same character.
+ >> (cl::space_p | cl::punct_p | cl::end_p)
+ // final mark must be followed by
+ // space or punctuation
+ )
+ | '['
+ | "'''"
+ | '`'
+ | phrase_end
+ ;
 
         phrase =
- *( common
- | (cl::anychar_p - phrase_end) [actions.plain_char]
- )
+ actions.scoped_context(element_info::in_phrase)
+ [
+ actions.values.save()
+ [ *( common
+ | (cl::anychar_p - phrase_end)
+ [actions.plain_char]
+ )
+ ]
+ ]
             ;
 
         extended_phrase =
- *( local.extended_phrase_element
- | common
- | (cl::anychar_p - phrase_end) [actions.plain_char]
- )
- ;
-
- inside_paragraph =
- (*( common
- | (cl::anychar_p - phrase_end) [actions.plain_char]
- | (+eol) [actions.inside_paragraph]
- )) [actions.inside_paragraph]
- ;
-
- local.phrase_element
- = '['
- >> space
- >> ( local.element
- >> cl::eps_p(local.check_element(element_info::in_phrase))
- >> local.element_rule
- | local.template_ [actions.do_template]
- | cl::str_p("br") [actions.break_]
+ actions.scoped_context(element_info::in_conditional)
+ [
+ actions.values.save()
+ [ *( common
+ | (cl::anychar_p - phrase_end)
+ [actions.plain_char]
                 )
- >> ']'
+ ]
+ ]
             ;
 
- local.extended_phrase_element
- = '[' >> space
- >> local.element
- >> cl::eps_p(local.check_element(element_info::in_conditional))
- [actions.inside_paragraph]
- >> ( local.element_rule
- >> ( (space >> ']')
- | cl::eps_p [actions.error]
- )
- | cl::eps_p [actions.error]
+ inside_paragraph =
+ actions.scoped_context(element_info::in_nested_block)
+ [
+ actions.values.save()
+ [ *( local.paragraph_separator [actions.paragraph]
+ | common
+ | (cl::anychar_p - phrase_end)
+ [actions.plain_char]
                 )
+ ] [actions.paragraph]
+ ]
             ;
 
-
- local.element
- = cl::eps_p(cl::punct_p)
- >> elements [local.assign_element]
- | elements [local.assign_element]
- >> (cl::eps_p - (cl::alnum_p | '_'))
+ local.nested_char =
+ cl::str_p("\\n") [actions.break_]
+ | "\\ " // ignore an escaped space
+ | '\\' >> cl::punct_p [actions.raw_char]
+ | "\\u" >> cl::repeat_p(4)
+ [cl::chset<>("0-9a-fA-F")]
+ [actions.escape_unicode]
+ | "\\U" >> cl::repeat_p(8)
+ [cl::chset<>("0-9a-fA-F")]
+ [actions.escape_unicode]
+ | cl::anychar_p [actions.plain_char]
             ;
 
         local.escape =
@@ -408,11 +468,13 @@
                                                 [actions.escape_unicode]
             | "\\U" >> cl::repeat_p(8) [cl::chset<>("0-9a-fA-F")]
                                                 [actions.escape_unicode]
- | (
- ("'''" >> !eol) [actions.escape_pre]
- >> *(cl::anychar_p - "'''") [actions.raw_char]
- >> cl::str_p("'''") [actions.escape_post]
- )
+ | ("'''" >> !eol)
+ >> actions.values.save()
+ [ (*(cl::anychar_p - "'''")) [actions.values.entry(ph::arg1, ph::arg2, phrase_tags::escape)]
+ >> ( cl::str_p("'''")
+ | cl::eps_p [actions.error("Unclosed boostbook escape.")]
+ ) [actions.element]
+ ]
             ;
 
         //
@@ -420,9 +482,15 @@
         //
 
         simple_phrase =
+ actions.scoped_context(element_info::in_phrase)
+ [
+ actions.values.save()
+ [
            *( common
- | (cl::anychar_p - ']') [actions.plain_char]
+ | (cl::anychar_p - ']') [actions.plain_char]
             )
+ ]
+ ]
             ;
 
         //
@@ -430,17 +498,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 =
@@ -449,9 +518,14 @@
 
 
         local.command_line_phrase =
- *( common
- | (cl::anychar_p - ']') [actions.plain_char]
- )
+ actions.scoped_context(element_info::in_phrase)
+ [
+ actions.values.save()
+ [ *( common
+ | (cl::anychar_p - ']') [actions.plain_char]
+ )
+ ]
+ ]
             ;
 
         // Miscellaneous stuff
@@ -474,13 +548,12 @@
             ;
 
         phrase_end =
- ']' |
- cl::if_p(var(actions.no_eols))
- [
- cl::eol_p >> *cl::blank_p >> cl::eol_p
- // Make sure that we don't go
- ] // past a single block, except
- ; // when preformatted.
+ ']'
+ | cl::eps_p(ph::var(actions.no_eols))
+ >> cl::eol_p >> *cl::blank_p >> cl::eol_p
+ ; // Make sure that we don't go
+ // past a single block, except
+ // when preformatted.
 
         comment =
             "[/" >> *(local.dummy_block | (cl::anychar_p - ']')) >> ']'

Modified: branches/release/tools/quickbook/src/markups.cpp
==============================================================================
--- branches/release/tools/quickbook/src/markups.cpp (original)
+++ branches/release/tools/quickbook/src/markups.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -8,94 +8,71 @@
     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>
+#include <map>
 
 namespace quickbook
 {
- const char* comment_pre = "<!--";
- const char* comment_post = "-->";
- const char* paragraph_pre = "<para>\n";
- const char* paragraph_post = "</para>\n";
- const char* h1_pre = "<bridgehead renderas=\"sect1\">";
- const char* h1_post = "</bridgehead>";
- const char* h2_pre = "<bridgehead renderas=\"sect2\">";
- const char* h2_post = "</bridgehead>";
- const char* h3_pre = "<bridgehead renderas=\"sect3\">";
- const char* h3_post = "</bridgehead>";
- const char* h4_pre = "<bridgehead renderas=\"sect4\">";
- const char* h4_post = "</bridgehead>";
- const char* h5_pre = "<bridgehead renderas=\"sect5\">";
- const char* h5_post = "</bridgehead>";
- const char* h6_pre = "<bridgehead renderas=\"sect6\">";
- const char* h6_post = "</bridgehead>";
- const char* hr_ = "<para/>";
- const char* blurb_pre = "<sidebar role=\"blurb\">\n";
- const char* blurb_post = "</sidebar>\n";
- const char* blockquote_pre = "<blockquote>";
- const char* blockquote_post = "</blockquote>";
- const char* preformatted_pre = "<programlisting>";
- const char* preformatted_post = "</programlisting>";
- const char* warning_pre = "<warning>";
- const char* warning_post = "</warning>";
- const char* caution_pre = "<caution>";
- const char* caution_post = "</caution>";
- const char* important_pre = "<important>";
- const char* important_post = "</important>";
- const char* note_pre = "<note>";
- const char* note_post = "</note>";
- const char* tip_pre = "<tip>";
- const char* tip_post = "</tip>";
- const char* list_item_pre = "<listitem><simpara>\n";
- const char* list_item_post = "\n</simpara></listitem>";
- const char* bold_pre_ = "<emphasis role=\"bold\">";
- const char* bold_post_ = "</emphasis>";
- const char* italic_pre_ = "<emphasis>";
- const char* italic_post_ = "</emphasis>";
- const char* underline_pre_ = "<emphasis role=\"underline\">";
- const char* underline_post_ = "</emphasis>";
- const char* teletype_pre_ = "<literal>";
- const char* teletype_post_ = "</literal>";
- const char* strikethrough_pre_ = "<emphasis role=\"strikethrough\">";
- const char* strikethrough_post_ = "</emphasis>";
- const char* quote_pre_ = "<quote>";
- const char* quote_post_ = "</quote>";
- const char* break_mark = "<sbr/>\n";
- const char* url_pre_ = "<ulink url=\"";
- const char* url_post_ = "</ulink>";
- const char* link_pre_ = "<link linkend=\"";
- const char* link_post_ = "</link>";
- const char* start_varlistentry_ = "<varlistentry>";
- const char* end_varlistentry_ = "</varlistentry>\n";
- const char* start_varlistterm_ = "<term>";
- const char* end_varlistterm_ = "</term>";
- const char* start_varlistitem_ = "<listitem>";
- const char* end_varlistitem_ = "</listitem>";
- const char* start_header_ = "<thead>";
- const char* end_header_ = "</thead>\n";
- const char* start_row_ = "<row>";
- const char* end_row_ = "</row>\n";
- const char* start_cell_ = "<entry>";
- const char* end_cell_ = "</entry>";
- const char* funcref_pre_ = "<functionname alt=\"";
- const char* funcref_post_ = "</functionname>";
- const char* classref_pre_ = "<classname alt=\"";
- const char* classref_post_ = "</classname>";
- const char* memberref_pre_ = "<methodname alt=\"";
- const char* memberref_post_ = "</methodname>";
- const char* enumref_pre_ = "<enumname alt=\"";
- const char* enumref_post_ = "</enumname>";
- const char* macroref_pre_ = "<macroname alt=\"";
- const char* macroref_post_ = "</macroname>";
- const char* headerref_pre_ = "<headername alt=\"";
- const char* headerref_post_ = "</headername>";
- const char* conceptref_pre_ = "<conceptname alt=\"";
- const char* conceptref_post_ = "</conceptname>";
- const char* globalref_pre_ = "<globalname alt=\"";
- const char* globalref_post_ = "</globalname>";
- const char* footnote_pre_ = "<footnote><para>";
- const char* footnote_post_ = "</para></footnote>";
- const char* escape_pre_ = "<!--quickbook-escape-prefix-->";
- 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, "<para>\n", "</para>\n" },
+ { block_tags::blurb, "<sidebar role=\"blurb\">\n", "</sidebar>\n" },
+ { block_tags::blockquote, "<blockquote>", "</blockquote>" },
+ { block_tags::preformatted, "<programlisting>", "</programlisting>" },
+ { block_tags::warning, "<warning>", "</warning>" },
+ { block_tags::caution, "<caution>", "</caution>" },
+ { block_tags::important, "<important>", "</important>" },
+ { block_tags::note, "<note>", "</note>" },
+ { block_tags::tip, "<tip>", "</tip>" },
+ { block_tags::ordered_list, "<orderedlist>", "</orderedlist>" },
+ { block_tags::itemized_list, "<itemizedlist>", "</itemizedlist>" },
+ { block_tags::hr, "<para/>", 0 },
+ { phrase_tags::url, "<ulink url=\"", "</ulink>" },
+ { phrase_tags::link, "<link linkend=\"", "</link>" },
+ { phrase_tags::funcref, "<functionname alt=\"", "</functionname>" },
+ { phrase_tags::classref, "<classname alt=\"", "</classname>" },
+ { phrase_tags::memberref, "<methodname alt=\"", "</methodname>" },
+ { phrase_tags::enumref, "<enumname alt=\"", "</enumname>" },
+ { phrase_tags::macroref, "<macroname alt=\"", "</macroname>" },
+ { phrase_tags::headerref, "<headername alt=\"", "</headername>" },
+ { phrase_tags::conceptref, "<conceptname alt=\"", "</conceptname>" },
+ { phrase_tags::globalref, "<globalname alt=\"", "</globalname>" },
+ { phrase_tags::bold, "<emphasis role=\"bold\">", "</emphasis>" },
+ { phrase_tags::italic, "<emphasis>", "</emphasis>" },
+ { phrase_tags::underline, "<emphasis role=\"underline\">", "</emphasis>" },
+ { phrase_tags::teletype, "<literal>", "</literal>" },
+ { phrase_tags::strikethrough, "<emphasis role=\"strikethrough\">", "</emphasis>" },
+ { phrase_tags::quote, "<quote>", "</quote>" },
+ { phrase_tags::replaceable, "<replaceable>", "</replaceable>" },
+ { phrase_tags::footnote, "<footnote><para>", "</para></footnote>" },
+ { phrase_tags::escape, "<!--quickbook-escape-prefix-->", "<!--quickbook-escape-postfix-->" },
+ { phrase_tags::break_mark, "<sbr/>\n", 0 }
+ };
+
+ BOOST_FOREACH(markup m, init_markups)
+ {
+ markups[m.tag] = m;
+ }
+ }
+
+ markup const& get_markup(value::tag_type t)
+ {
+ return markups[t];
+ }
+
+ std::ostream& operator<<(std::ostream& out, markup const& m)
+ {
+ return out<<"{"<<m.tag<<": \""<<m.pre<<"\", \""<<m.post<<"\"}";
+ }
+ }
 }

Modified: branches/release/tools/quickbook/src/markups.hpp
==============================================================================
--- branches/release/tools/quickbook/src/markups.hpp (original)
+++ branches/release/tools/quickbook/src/markups.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,94 +10,22 @@
 #if !defined(BOOST_SPIRIT_MARKUPS_HPP)
 #define BOOST_SPIRIT_MARKUPS_HPP
 
+#include <iosfwd>
+#include "values.hpp"
+
 namespace quickbook
 {
- extern const char* comment_pre;
- extern const char* comment_post;
- extern const char* paragraph_pre;
- extern const char* paragraph_post;
- extern const char* h1_pre;
- extern const char* h1_post;
- extern const char* h2_pre;
- extern const char* h2_post;
- extern const char* h3_pre;
- extern const char* h3_post;
- extern const char* h4_pre;
- extern const char* h4_post;
- extern const char* h5_pre;
- extern const char* h5_post;
- extern const char* h6_pre;
- extern const char* h6_post;
- extern const char* hr_;
- extern const char* blurb_pre;
- extern const char* blurb_post;
- extern const char* blockquote_pre;
- extern const char* blockquote_post;
- extern const char* preformatted_pre;
- extern const char* preformatted_post;
- extern const char* warning_pre;
- extern const char* warning_post;
- extern const char* caution_pre;
- extern const char* caution_post;
- extern const char* important_pre;
- extern const char* important_post;
- extern const char* note_pre;
- extern const char* note_post;
- extern const char* tip_pre;
- extern const char* tip_post;
- extern const char* list_item_pre;
- extern const char* list_item_post;
- extern const char* bold_pre_;
- extern const char* bold_post_;
- extern const char* italic_pre_;
- extern const char* italic_post_;
- extern const char* underline_pre_;
- extern const char* underline_post_;
- extern const char* teletype_pre_;
- extern const char* teletype_post_;
- extern const char* strikethrough_pre_;
- extern const char* strikethrough_post_;
- extern const char* quote_pre_;
- extern const char* quote_post_;
- extern const char* break_mark;
- extern const char* url_pre_;
- extern const char* url_post_;
- extern const char* link_pre_;
- extern const char* link_post_;
- extern const char* start_varlistentry_;
- extern const char* end_varlistentry_;
- extern const char* start_varlistterm_;
- extern const char* end_varlistterm_;
- extern const char* start_varlistitem_;
- extern const char* end_varlistitem_;
- extern const char* start_header_;
- extern const char* end_header_;
- extern const char* start_row_;
- extern const char* end_row_;
- extern const char* start_cell_;
- extern const char* end_cell_;
- extern const char* funcref_pre_;
- extern const char* funcref_post_;
- extern const char* classref_pre_;
- extern const char* classref_post_;
- extern const char* memberref_pre_;
- extern const char* memberref_post_;
- extern const char* enumref_pre_;
- extern const char* enumref_post_;
- extern const char* macroref_pre_;
- extern const char* macroref_post_;
- extern const char* headerref_pre_;
- extern const char* headerref_post_;
- extern const char* conceptref_pre_;
- extern const char* conceptref_post_;
- extern const char* globalref_pre_;
- extern const char* globalref_post_;
- extern const char* footnote_pre_;
- extern const char* footnote_post_;
- extern const char* escape_pre_;
- 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;
+ };
+
+ markup const& get_markup(value::tag_type);
+ std::ostream& operator<<(std::ostream&, markup const&);
+ }
 }
 
 #endif // BOOST_SPIRIT_MARKUPS_HPP

Copied: branches/release/tools/quickbook/src/parsers.hpp (from r70210, /trunk/tools/quickbook/src/parsers.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/parsers.hpp (original)
+++ branches/release/tools/quickbook/src/parsers.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -176,7 +176,7 @@
         {
             typedef phoenix::tuple<> tuple;
             return scoped_parser_gen<Impl, tuple>(impl_, tuple());
- };
+ }
 
         template <typename Arg1>
         scoped_parser_gen<Impl, phoenix::tuple<Arg1> >
@@ -184,7 +184,7 @@
         {
             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> >
@@ -192,7 +192,7 @@
         {
             typedef phoenix::tuple<Arg1, Arg2> tuple;
             return scoped_parser_gen<Impl, tuple>(impl_, tuple(x1, x2));
- };
+ }
         
         Impl impl_;
     };
@@ -252,4 +252,5 @@
     
     lookback_gen const lookback = lookback_gen();
 }
+
 #endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP

Modified: branches/release/tools/quickbook/src/phrase_element_grammar.cpp
==============================================================================
--- branches/release/tools/quickbook/src/phrase_element_grammar.cpp (original)
+++ branches/release/tools/quickbook/src/phrase_element_grammar.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 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,22 +26,14 @@
     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
                         ;
     };
 
     void quickbook_grammar::impl::init_phrase_elements()
     {
- using detail::var;
-
- phrase_element_grammar_local& local = store_.create();
+ phrase_element_grammar_local& local = cleanup_.add(
+ new phrase_element_grammar_local);
 
         elements.add
             ("?", element_info(element_info::phrase, &local.cond_phrase))
@@ -46,207 +41,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 [cl::clear_a(actions.attributes)]
+ blank
>> cl::if_p(qbk_since(105u)) [
                         (+(
                             *cl::space_p
>> +(cl::anychar_p - (cl::space_p | phrase_end | '['))
- )) [cl::assign_a(actions.image_fileref)]
+ )) [actions.values.entry(ph::arg1, ph::arg2)]
>> hard_space
- >> *(
- '['
- >> (*(cl::alnum_p | '_')) [cl::assign_a(actions.attribute_name)]
+ >> *actions.values.list()
+ [ '['
+ >> (*(cl::alnum_p | '_'))
+ [actions.values.entry(ph::arg1, ph::arg2)]
>> space
>> (*(cl::anychar_p - (phrase_end | '[')))
- [actions.attribute]
+ [actions.values.entry(ph::arg1, ph::arg2)]
>> ']'
>> space
- )
+ ]
                 ].else_p [
                         (*(cl::anychar_p - phrase_end))
- [cl::assign_a(actions.image_fileref)]
+ [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]
- ;
-
- 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]
+ >> (*(cl::anychar_p - phrase_end)) [actions.values.entry(ph::arg1, ph::arg2)]
             ;
 
         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]
+ ]
             ;
     }
 }

Copied: branches/release/tools/quickbook/src/phrase_tags.hpp (from r70210, /trunk/tools/quickbook/src/phrase_tags.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/phrase_tags.hpp (original)
+++ branches/release/tools/quickbook/src/phrase_tags.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -20,6 +20,8 @@
         (macroref)(headerref)(conceptref)(globalref)
         (bold)(italic)(underline)(teletype)(strikethrough)(quote)(replaceable)
         (footnote)
+ (escape)
+ (break_mark)
     )
     
     QUICKBOOK_VALUE_NAMED_TAGS(source_mode_tags, 0x550,

Modified: branches/release/tools/quickbook/src/post_process.cpp
==============================================================================
--- branches/release/tools/quickbook/src/post_process.cpp (original)
+++ branches/release/tools/quickbook/src/post_process.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -7,7 +7,6 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 #include "post_process.hpp"
-#include "utils.hpp"
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/bind.hpp>
 #include <set>
@@ -403,6 +402,9 @@
 
         void do_end_tag(iter_type f, iter_type l) const
         {
+ if (state.tags.empty())
+ throw quickbook::post_process_failure("Mismatched tags.");
+
             bool is_flow_tag = state.is_flow_tag(state.tags.top());
             if (!is_flow_tag)
             {
@@ -419,9 +421,8 @@
         int indent;
     };
 
- int post_process(
+ std::string post_process(
         std::string const& in
- , std::ostream& out
       , int indent
       , int linewidth)
     {
@@ -430,36 +431,17 @@
         if (linewidth == -1)
             linewidth = 80; // set default to 80
 
- try
+ std::string tidy;
+ tidy_compiler state(tidy, linewidth);
+ tidy_grammar g(state, indent);
+ cl::parse_info<iter_type> r = parse(in.begin(), in.end(), g, cl::space_p);
+ if (r.full)
         {
- std::string tidy;
- tidy_compiler state(tidy, linewidth);
- tidy_grammar g(state, indent);
- cl::parse_info<iter_type> r = parse(in.begin(), in.end(), g, cl::space_p);
- if (r.full)
- {
- out << tidy;
- return 0;
- }
- else
- {
- // fallback!
- ::quickbook::detail::outerr("")
- << "Warning: Post Processing Failed."
- << std::endl;
- out << in;
- return 1;
- }
+ return tidy;
         }
-
- catch(...)
- {
- // fallback!
- ::quickbook::detail::outerr("")
- << "Post Processing Failed."
- << std::endl;
- out << in;
- return 1;
+ else
+ {
+ throw quickbook::post_process_failure("Post Processing Failed.");
         }
     }
 }

Modified: branches/release/tools/quickbook/src/post_process.hpp
==============================================================================
--- branches/release/tools/quickbook/src/post_process.hpp (original)
+++ branches/release/tools/quickbook/src/post_process.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -9,16 +9,22 @@
 #if !defined(BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP)
 #define BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP
 
-#include <iostream>
 #include <string>
+#include <stdexcept>
 
 namespace quickbook
 {
- int post_process(
+ std::string post_process(
         std::string const& in
- , std::ostream& out
- , int indent
- , int linewidth);
+ , int indent = -1
+ , int linewidth = -1);
+
+ class post_process_failure : public std::runtime_error
+ {
+ public:
+ explicit post_process_failure(std::string const& error)
+ : std::runtime_error(error) {}
+ };
 }
 
 #endif // BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP

Modified: branches/release/tools/quickbook/src/quickbook.cpp
==============================================================================
--- branches/release/tools/quickbook/src/quickbook.cpp (original)
+++ branches/release/tools/quickbook/src/quickbook.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -13,22 +13,28 @@
 #include "post_process.hpp"
 #include "utils.hpp"
 #include "input_path.hpp"
-#include <boost/spirit/include/classic_iterator.hpp>
 #include <boost/program_options.hpp>
 #include <boost/filesystem/v3/path.hpp>
 #include <boost/filesystem/v3/operations.hpp>
+#include <boost/filesystem/v3/fstream.hpp>
+#include <boost/range/algorithm.hpp>
 #include <boost/ref.hpp>
+#include <boost/version.hpp>
 
 #include <stdexcept>
-#include <fstream>
-#include <iostream>
 #include <vector>
+#include <iterator>
+
+#if defined(_WIN32)
+#include <windows.h>
+#include <shellapi.h>
+#endif
 
 #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
 #pragma warning(disable:4355)
 #endif
 
-#define QUICKBOOK_VERSION "Quickbook Version 1.5.4"
+#define QUICKBOOK_VERSION "Quickbook Version 1.5.5"
 
 namespace quickbook
 {
@@ -39,7 +45,7 @@
     tm* current_gm_time; // the current UTC time
     bool debug_mode; // for quickbook developers only
     bool ms_errors = false; // output errors/warnings as if for VS
- std::vector<std::string> include_path;
+ std::vector<fs::path> include_path;
     std::vector<std::string> preset_defines;
 
     static void set_macros(actions& actor)
@@ -49,8 +55,9 @@
                 end = preset_defines.end();
                 it != end; ++it)
         {
- iterator first(it->begin(), it->end(), "command line parameter");
- iterator last(it->end(), it->end());
+ // TODO: Set filename in actor???
+ iterator first(it->begin());
+ iterator last(it->end());
 
             cl::parse(first, last, actor.grammar().command_line_macro);
             // TODO: Check result?
@@ -63,9 +70,8 @@
     //
     ///////////////////////////////////////////////////////////////////////////
     int
- parse_file(char const* filein_, actions& actor, bool ignore_docinfo)
+ parse_file(fs::path const& filein_, actions& actor, bool ignore_docinfo)
     {
- using std::cerr;
         using std::vector;
         using std::string;
 
@@ -76,8 +82,8 @@
             return err;
         }
 
- iterator first(storage.begin(), storage.end(), filein_);
- iterator last(storage.end(), storage.end());
+ iterator first(storage.begin());
+ iterator last(storage.end());
 
         cl::parse_info<iterator> info = cl::parse(first, last, actor.grammar().doc_info);
 
@@ -94,8 +100,8 @@
 
         if (!info.full)
         {
- position const pos = info.stop.get_position();
- detail::outerr(pos.file,pos.line)
+ file_position const& pos = info.stop.get_position();
+ detail::outerr(actor.filename, pos.line)
                 << "Syntax Error near column " << pos.column << ".\n";
             ++actor.error_count;
         }
@@ -104,9 +110,12 @@
     }
 
     static int
- parse_document(char const* filein_, fs::path const& outdir, string_stream& out, bool ignore_docinfo = false)
+ parse_document(
+ fs::path const& filein_,
+ fs::path const& xinclude_base,
+ string_stream& out)
     {
- actions actor(filein_, outdir, out);
+ actions actor(filein_, xinclude_base, out);
 
         set_macros(actor);
         bool r = parse_file(filein_, actor);
@@ -117,7 +126,7 @@
 
         if(actor.error_count)
         {
- detail::outerr(filein_)
+ detail::outerr()
                 << "Error count: " << actor.error_count << ".\n";
         }
 
@@ -126,26 +135,36 @@
 
     static int
     parse_document(
- char const* filein_
- , char const* fileout_
+ fs::path const& filein_
+ , fs::path const& fileout_
+ , fs::path const& xinclude_base_
       , int indent
       , int linewidth
       , bool pretty_print)
     {
         int result = 0;
- fs::path outdir = fs::path(fileout_).parent_path();
- if (outdir.empty())
- outdir = ".";
         string_stream buffer;
- result = parse_document(filein_, outdir, buffer);
+ result = parse_document(filein_, xinclude_base_, buffer);
 
         if (result == 0)
         {
- std::ofstream fileout(fileout_);
+ fs::ofstream fileout(fileout_);
 
             if (pretty_print)
             {
- result = post_process(buffer.str(), fileout, indent, linewidth);
+ try
+ {
+ fileout << post_process(buffer.str(), indent, linewidth);
+ }
+ catch (quickbook::post_process_failure&)
+ {
+ // fallback!
+ ::quickbook::detail::outerr()
+ << "Post Processing Failed."
+ << std::endl;
+ fileout << buffer.str();
+ return 1;
+ }
             }
             else
             {
@@ -166,33 +185,62 @@
 {
     try
     {
+ namespace fs = boost::filesystem;
+ namespace po = boost::program_options;
+
         using boost::program_options::options_description;
         using boost::program_options::variables_map;
         using boost::program_options::store;
         using boost::program_options::parse_command_line;
+ using boost::program_options::wcommand_line_parser;
         using boost::program_options::command_line_parser;
         using boost::program_options::notify;
- using boost::program_options::value;
         using boost::program_options::positional_options_description;
+
+ using quickbook::detail::input_string;
 
         // First thing, the filesystem should record the current working directory.
- boost::filesystem::initial_path<boost::filesystem::path>();
+ fs::initial_path<fs::path>();
+
+ // Various initialisation methods
+ quickbook::detail::initialise_output();
+ quickbook::detail::initialise_markups();
 
         options_description desc("Allowed options");
+ options_description hidden("Hidden options");
+ options_description all("All options");
+
+#if QUICKBOOK_WIDE_PATHS
+#define PO_VALUE po::wvalue
+#else
+#define PO_VALUE po::value
+#endif
+
         desc.add_options()
             ("help", "produce help message")
             ("version", "print version string")
             ("no-pretty-print", "disable XML pretty printing")
- ("indent", value<int>(), "indent spaces")
- ("linewidth", value<int>(), "line width")
- ("input-file", value<quickbook::detail::input_path>(), "input file")
- ("output-file", value<quickbook::detail::input_path>(), "output file")
+ ("indent", PO_VALUE<int>(), "indent spaces")
+ ("linewidth", PO_VALUE<int>(), "line width")
+ ("input-file", PO_VALUE<input_string>(), "input file")
+ ("output-file", PO_VALUE<input_string>(), "output file")
             ("debug", "debug mode (for developers)")
             ("ms-errors", "use Microsoft Visual Studio style error & warn message format")
- ("include-path,I", value< std::vector<quickbook::detail::input_path> >(), "include path")
- ("define,D", value< std::vector<std::string> >(), "define macro")
+ ("include-path,I", PO_VALUE< std::vector<input_string> >(), "include path")
+ ("define,D", PO_VALUE< std::vector<input_string> >(), "define macro")
         ;
 
+ hidden.add_options()
+ ("expect-errors",
+ "Succeed if the input file contains a correctly handled "
+ "error, fail otherwise.")
+ ("xinclude-base", PO_VALUE<input_string>(),
+ "Generate xincludes as if generating for this target "
+ "directory.")
+ ;
+
+ all.add(desc).add(hidden);
+
         positional_options_description p;
         p.add("input-file", -1);
 
@@ -200,18 +248,59 @@
         int indent = -1;
         int linewidth = -1;
         bool pretty_print = true;
- store(command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+
+#if QUICKBOOK_WIDE_PATHS
+ quickbook::ignore_variable(&argc);
+ quickbook::ignore_variable(&argv);
+
+ int wide_argc;
+ LPWSTR* wide_argv = CommandLineToArgvW(GetCommandLineW(), &wide_argc);
+ if (!wide_argv)
+ {
+ quickbook::detail::outerr() << "Error getting argument values." << std::endl;
+ return 1;
+ }
+
+ store(
+ wcommand_line_parser(wide_argc, wide_argv)
+ .options(all)
+ .positional(p)
+ .run(), vm);
+
+ LocalFree(wide_argv);
+#else
+ store(command_line_parser(argc, argv)
+ .options(all)
+ .positional(p)
+ .run(), vm);
+#endif
+
         notify(vm);
 
+ bool expect_errors = vm.count("expect-errors");
+
         if (vm.count("help"))
         {
- std::cout << desc << "\n";
+ std::ostringstream description_text;
+ description_text << desc;
+
+ quickbook::detail::out()
+ << quickbook::detail::utf8(description_text.str()) << "\n";
+
             return 0;
         }
 
         if (vm.count("version"))
         {
- std::cout << QUICKBOOK_VERSION << std::endl;
+ std::string boost_version = BOOST_LIB_VERSION;
+ boost::replace(boost_version, '_', '.');
+
+ quickbook::detail::out()
+ << QUICKBOOK_VERSION
+ << " (Boost "
+ << quickbook::detail::utf8(boost_version)
+ << ")"
+ << std::endl;
             return 0;
         }
 
@@ -252,60 +341,90 @@
             quickbook::debug_mode = false;
         }
         
+ quickbook::include_path.clear();
         if (vm.count("include-path"))
         {
- std::vector<quickbook::detail::input_path> paths
- = vm["include-path"].as<
- std::vector<quickbook::detail::input_path> >();
- quickbook::include_path
- = std::vector<std::string>(paths.begin(), paths.end());
+ boost::transform(
+ vm["include-path"].as<std::vector<input_string> >(),
+ std::back_inserter(quickbook::include_path),
+ quickbook::detail::input_to_path);
         }
 
+ quickbook::preset_defines.clear();
         if (vm.count("define"))
         {
- quickbook::preset_defines
- = vm["define"].as<std::vector<std::string> >();
+ boost::transform(
+ vm["define"].as<std::vector<input_string> >(),
+ std::back_inserter(quickbook::preset_defines),
+ quickbook::detail::input_to_utf8);
         }
 
         if (vm.count("input-file"))
         {
- std::string filein
- = vm["input-file"].as<quickbook::detail::input_path>();
- std::string fileout;
+ fs::path filein = quickbook::detail::input_to_path(
+ vm["input-file"].as<input_string>());
+ fs::path fileout;
 
             if (vm.count("output-file"))
             {
- fileout = vm["output-file"].as<quickbook::detail::input_path>();
+ fileout = quickbook::detail::input_to_path(
+ vm["output-file"].as<input_string>());
+ }
+ else
+ {
+ fileout = filein;
+ fileout.replace_extension(".xml");
+ }
+
+ fs::path xinclude_base;
+ if (vm.count("xinclude-base"))
+ {
+ xinclude_base = quickbook::detail::input_to_path(
+ vm["xinclude-base"].as<input_string>());
             }
             else
             {
- fileout = quickbook::detail::remove_extension(filein.c_str());
- fileout += ".xml";
+ xinclude_base = fileout.parent_path();
+ if (xinclude_base.empty())
+ xinclude_base = ".";
             }
 
- std::cout << "Generating Output File: "
- << fileout
+ quickbook::detail::out() << "Generating Output File: "
+ << quickbook::detail::path_to_stream(fileout)
                 << std::endl;
 
- return quickbook::parse_document(filein.c_str(), fileout.c_str(), indent, linewidth, pretty_print);
+ int r = quickbook::parse_document(filein, fileout, xinclude_base, indent, linewidth, pretty_print);
+
+ if (expect_errors)
+ {
+ if (!r) quickbook::detail::outerr() << "No errors detected for --expect-errors." << std::endl;
+ return !r;
+ }
+ else
+ {
+ return r;
+ }
         }
         else
         {
- quickbook::detail::outerr("") << "Error: No filename given\n\n"
- << desc << std::endl;
+ std::ostringstream description_text;
+ description_text << desc;
+
+ quickbook::detail::outerr() << "No filename given\n\n"
+ << quickbook::detail::utf8(description_text.str()) << std::endl;
             return 1;
         }
     }
 
     catch(std::exception& e)
     {
- quickbook::detail::outerr("") << "Error: " << e.what() << "\n";
+ quickbook::detail::outerr() << quickbook::detail::utf8(e.what()) << "\n";
         return 1;
     }
 
     catch(...)
     {
- quickbook::detail::outerr("") << "Error: Exception of unknown type caught\n";
+ quickbook::detail::outerr() << "Exception of unknown type caught\n";
         return 1;
     }
 

Modified: branches/release/tools/quickbook/src/quickbook.hpp
==============================================================================
--- branches/release/tools/quickbook/src/quickbook.hpp (original)
+++ branches/release/tools/quickbook/src/quickbook.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -15,17 +15,28 @@
 #include <time.h>
 #include <vector>
 #include <string>
+#include <boost/filesystem/v3/path.hpp>
 #include "fwd.hpp"
 
 namespace quickbook
 {
+ namespace fs = boost::filesystem;
+
     extern tm* current_time; // the current time
     extern tm* current_gm_time; // the current UTC time
     extern bool debug_mode;
- extern std::vector<std::string> include_path;
+ extern std::vector<fs::path> include_path;
     extern std::vector<std::string> preset_defines;
 
- int parse_file(char const* filein_, actions& actor, bool ignore_docinfo = false);
+ 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: branches/release/tools/quickbook/src/rule_store.hpp
==============================================================================
--- branches/release/tools/quickbook/src/rule_store.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,83 +0,0 @@
-/*=============================================================================
- Copyright (c) 2010 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)
-=============================================================================*/
-
-// This header defines a class which can will manage quickbook rules for a
-// grammar class so that it doesn't have to declare every rule it'll use.
-//
-// TODO: Noncopyable, but some sort of reference counting scheme would work.
-
-#if !defined(BOOST_SPIRIT_QUICKBOOK_RULE_STORE_HPP)
-#define BOOST_SPIRIT_QUICKBOOK_RULE_STORE_HPP
-
-#include <deque>
-#include <boost/assert.hpp>
-#include <utility>
-
-namespace quickbook
-{
- namespace detail
- {
- template <typename T>
- void delete_impl(void* ptr) {
- delete static_cast<T*>(ptr);
- }
-
- struct scoped_void
- {
- void* ptr_;
- void (*del_)(void*);
-
- scoped_void() : ptr_(0), del_(0) {}
- scoped_void(scoped_void const& src) : ptr_(0), del_(0) {
- BOOST_ASSERT(!src.ptr_);
- }
- ~scoped_void() {
- if(ptr_) del_(ptr_);
- }
-
- void store(void* ptr, void (*del)(void* x)) {
- ptr = ptr_;
- del = del_;
- }
- private:
- scoped_void& operator=(scoped_void const&);
- };
- }
-
- struct rule_store
- {
- struct instantiate
- {
- rule_store& s;
- instantiate(rule_store& s) : s(s) {}
-
- template <typename T>
- operator T&() {
- std::auto_ptr<T> obj(new T());
- T& ref = *obj;
- s.store_.push_back(detail::scoped_void());
- s.store_.back().store(obj.release(), &detail::delete_impl<T>);
- return ref;
- }
- };
-
- rule_store() {}
-
- instantiate create() {
- instantiate i(*this);
- return i;
- }
-
- std::deque<detail::scoped_void> store_;
- private:
- rule_store& operator=(rule_store const&);
- rule_store(rule_store const&);
- };
-}
-
-#endif

Deleted: branches/release/tools/quickbook/src/scoped_parser.hpp
==============================================================================
--- branches/release/tools/quickbook/src/scoped_parser.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,97 +0,0 @@
-/*=============================================================================
- Copyright (c) 2010 Daniel James
- Copyright (c) 2003 Martin Wille
- http://spirit.sourceforge.net/
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
-
-// Used to store variables/state while parsing
-
-#ifndef BOOST_QUICKBOOK_SCOPED_PARSER_HPP
-#define BOOST_QUICKBOOK_SCOPED_PARSER_HPP
-
-#include <boost/spirit/include/classic_core.hpp>
-
-namespace quickbook {
- namespace cl = boost::spirit::classic;
-
- template <typename ScopeT, typename DataT, typename ParserT>
- struct scoped_parser_impl
- : public cl::unary< ParserT, cl::parser< scoped_parser_impl<ScopeT, DataT, ParserT> > >
- {
- typedef scoped_parser_impl<ScopeT, DataT, ParserT> self_t;
- typedef cl::unary< ParserT, cl::parser< scoped_parser_impl<ScopeT, DataT, ParserT> > > base_t;
-
- template <typename ScannerT>
- struct result :
- ScopeT::template result<
- typename cl::parser_result<ParserT, ScannerT>::type
- >
- {
- };
-
- scoped_parser_impl(DataT& actions, ParserT const &p)
- : base_t(p)
- , actions(actions)
- {}
-
- 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);
- typename cl::parser_result<ParserT, ScannerT>::type result
- = this->subject().parse(scan);
-
- if (result) {
- return scan.create_match(result.length(), scope.success(result), save, scan.first);
- }
- else {
- scope.failure();
- return scan.no_match();
- }
- }
-
- DataT& actions;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // 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 ParserT>
- scoped_parser_impl
- <
- ScopeT,
- data_type,
- typename cl::as_parser<ParserT>::type
- >
- operator[](ParserT const &p) const
- {
- 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));
- }
-
- data_type& actions;
- };
-}
-#endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP

Modified: branches/release/tools/quickbook/src/syntax_highlight.hpp
==============================================================================
--- branches/release/tools/quickbook/src/syntax_highlight.hpp (original)
+++ branches/release/tools/quickbook/src/syntax_highlight.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -16,6 +16,7 @@
 #include <boost/spirit/include/classic_symbols.hpp>
 #include <boost/spirit/include/classic_loops.hpp>
 #include "grammar.hpp"
+#include "grammar_impl.hpp" // Just for context stuff. Should move?
 
 namespace quickbook
 {
@@ -57,7 +58,7 @@
                     | char_ [Process("char", self.out)]
                     | number [Process("number", self.out)]
                     | cl::repeat_p(1)[cl::anychar_p]
- [Unexpected(self.out)]
+ [Unexpected(self.out, self.escape_actions)]
                     )
                     ;
 
@@ -69,10 +70,12 @@
                     ;
 
                 qbk_phrase =
- *( g.common
- | (cl::anychar_p - cl::str_p("``"))
+ self.escape_actions.scoped_context(element_info::in_phrase)
+ [ *( g.common
+ | (cl::anychar_p - cl::str_p("``"))
                                         [self.escape_actions.plain_char]
- )
+ )
+ ]
                     ;
 
                 escape =
@@ -206,7 +209,7 @@
                     | string_ [Process("string", self.out)]
                     | number [Process("number", self.out)]
                     | cl::repeat_p(1)[cl::anychar_p]
- [Unexpected(self.out)]
+ [Unexpected(self.out, self.escape_actions)]
                     )
                     ;
 
@@ -218,10 +221,13 @@
                     ;
 
                 qbk_phrase =
- *( g.common
- | (cl::anychar_p - cl::str_p("``"))
+ self.escape_actions.scoped_context(element_info::in_phrase)
+ [
+ *( g.common
+ | (cl::anychar_p - cl::str_p("``"))
                                         [self.escape_actions.plain_char]
- )
+ )
+ ]
                     ;
 
                 escape =
@@ -362,10 +368,13 @@
                     ;
 
                 qbk_phrase =
- *( g.common
- | (cl::anychar_p - cl::str_p("``"))
+ self.escape_actions.scoped_context(element_info::in_phrase)
+ [
+ *( g.common
+ | (cl::anychar_p - cl::str_p("``"))
                                         [self.escape_actions.plain_char]
- )
+ )
+ ]
                     ;
 
                 escape =

Modified: branches/release/tools/quickbook/src/template_stack.cpp
==============================================================================
--- branches/release/tools/quickbook/src/template_stack.cpp (original)
+++ branches/release/tools/quickbook/src/template_stack.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -6,6 +6,8 @@
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
+
+#include <cassert>
 #include "template_stack.hpp"
 
 #ifdef BOOST_MSVC
@@ -14,6 +16,23 @@
 
 namespace quickbook
 {
+ template_body::template_body(
+ value const& content,
+ fs::path const& filename
+ )
+ : content(content)
+ , filename(filename)
+ {
+ assert(content.get_tag() == template_tags::block ||
+ content.get_tag() == template_tags::phrase);
+ }
+
+ bool template_body::is_block() const
+ {
+ return content.get_tag() == template_tags::block;
+ }
+
+
     template_stack::template_stack()
         : scope(template_stack::parser(*this))
         , scopes()

Modified: branches/release/tools/quickbook/src/template_stack.hpp
==============================================================================
--- branches/release/tools/quickbook/src/template_stack.hpp (original)
+++ branches/release/tools/quickbook/src/template_stack.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -14,42 +14,25 @@
 #include <vector>
 #include <boost/tuple/tuple.hpp>
 #include <boost/assert.hpp>
-#include <boost/spirit/include/classic_position_iterator.hpp>
 #include <boost/spirit/include/classic_functor_parser.hpp>
 #include <boost/spirit/include/classic_symbols.hpp>
 #include <boost/next_prior.hpp>
+#include <boost/filesystem/path.hpp>
+#include "fwd.hpp"
+#include "values.hpp"
+#include "template_tags.hpp"
 
 namespace quickbook
 {
+ namespace fs = boost::filesystem;
+
     struct template_body
     {
- template_body(
- std::string const& content,
- boost::spirit::classic::file_position const& position,
- bool is_block
- )
- : content(content)
- , position(position)
- , is_block(is_block)
- {
- }
+ template_body(value const&, fs::path const&);
+ bool is_block() const;
 
- template_body(
- std::string const& content,
- boost::spirit::classic::file_position_base<char const*> const& position,
- bool is_block
- )
- : content(content)
- , position(position.file, position.line, position.column)
- , is_block(is_block)
- {
- }
-
- std::string content;
- // Note: Using file_position to store the filename after the file
- // has been closed.
- boost::spirit::classic::file_position position;
- bool is_block;
+ stored_value content;
+ fs::path filename;
     };
 
     struct template_scope;
@@ -59,29 +42,13 @@
         template_symbol(
                 std::string const& identifier,
                 std::vector<std::string> const& params,
- std::string const& body,
- boost::spirit::classic::file_position const& position,
- bool is_block,
- template_scope const* parent = 0)
- : identifier(identifier)
- , params(params)
- , body(body, position, is_block)
- , parent(parent)
- , callout(false)
- , callouts() {}
-
- template_symbol(
- std::string const& identifier,
- std::vector<std::string> const& params,
- std::string const& body,
- boost::spirit::classic::file_position_base<char const*> const& position,
- bool is_block,
+ value const& content,
+ fs::path const& filename,
                 template_scope const* parent = 0)
            : identifier(identifier)
            , params(params)
- , body(body, position, is_block)
+ , body(content, filename)
            , parent(parent)
- , callout(false)
            , callouts() {}
 
         std::string identifier;
@@ -93,8 +60,7 @@
         // or static_parent for clarity.
         template_scope const* parent;
 
- bool callout;
- std::vector<template_body> callouts;
+ stored_value callouts;
     };
 
     typedef boost::spirit::classic::symbols<template_symbol> template_symbols;

Copied: branches/release/tools/quickbook/src/template_tags.hpp (from r70210, /trunk/tools/quickbook/src/template_tags.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/template_tags.hpp (original)
+++ branches/release/tools/quickbook/src/template_tags.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -14,6 +14,7 @@
 namespace quickbook
 {
     QUICKBOOK_VALUE_TAGS(template_tags, 0x100,
+ (template_)
         (escape)
         (identifier)
         (block)

Modified: branches/release/tools/quickbook/src/utils.cpp
==============================================================================
--- branches/release/tools/quickbook/src/utils.cpp (original)
+++ branches/release/tools/quickbook/src/utils.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -8,19 +8,17 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 #include "utils.hpp"
+#include "input_path.hpp"
 #include <boost/spirit/include/classic_core.hpp>
+#include <boost/filesystem/v3/fstream.hpp>
 
 #include <cctype>
 #include <cstring>
 #include <stdexcept>
 #include <fstream>
-#include <iostream>
+#include <ostream>
 #include <map>
 
-namespace quickbook {
- extern bool ms_errors;
-}
-
 namespace quickbook { namespace detail
 {
     void print_char(char ch, std::ostream& out)
@@ -118,21 +116,6 @@
         }
     }
 
- // remove the extension from a filename
- std::string
- remove_extension(std::string const& filename)
- {
- std::string::size_type const n = filename.find_last_of('.');
- if(std::string::npos == n)
- {
- return filename;
- }
- else
- {
- return std::string(filename.begin(), filename.begin()+n);
- }
- }
-
     std::string escape_uri(std::string uri)
     {
         for (std::string::size_type n = 0; n < uri.size(); ++n)
@@ -151,36 +134,6 @@
         return uri;
     }
 
- std::ostream& outerr(std::string const& file, int line)
- {
- if (line >= 0)
- {
- if (ms_errors)
- return std::clog << file << "(" << line << "): error: ";
- else
- return std::clog << file << ":" << line << ": error: ";
- }
- else
- {
- return std::clog << file << ": error: ";
- }
- }
-
- std::ostream& outwarn(std::string const& file, int line)
- {
- if (line >= 0)
- {
- if (ms_errors)
- return std::clog << file << "(" << line << "): warning: ";
- else
- return std::clog << file << ":" << line << ": warning: ";
- }
- else
- {
- return std::clog << file << ": warning: ";
- }
- }
-
     // Read the first few bytes in a file to see it starts with a byte order
     // mark. If it doesn't, then write the characters we've already read in.
     // Although, given how UTF-8 works, if we've read anything in, the files
@@ -238,12 +191,13 @@
 
     template <class InputIterator, class OutputIterator>
     bool normalize(InputIterator begin, InputIterator end,
- OutputIterator out, std::string const& filename)
+ OutputIterator out, fs::path const& filename)
     {
         std::string encoding = read_bom(begin, end, out);
 
         if(encoding != "UTF-8" && encoding != "") {
- outerr(filename) << encoding << " is not supported. Please use UTF-8."
+ outerr(filename) << encoding.c_str()
+ << " is not supported. Please use UTF-8."
                 << std::endl;
 
             return false;
@@ -263,15 +217,14 @@
         return true;
     }
 
- int load(std::string const& filename, std::string& storage)
+ int load(fs::path const& filename, std::string& storage)
     {
- using std::cerr;
         using std::endl;
         using std::ios;
         using std::ifstream;
         using std::istream_iterator;
 
- ifstream in(filename.c_str(), std::ios_base::in);
+ fs::ifstream in(filename, std::ios_base::in);
 
         if (!in)
         {

Modified: branches/release/tools/quickbook/src/utils.hpp
==============================================================================
--- branches/release/tools/quickbook/src/utils.hpp (original)
+++ branches/release/tools/quickbook/src/utils.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,64 +11,44 @@
 #define BOOST_SPIRIT_QUICKBOOK_UTILS_HPP
 
 #include <string>
-#include <iostream>
 #include <cctype>
-#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 { namespace detail
+
+namespace quickbook {
+
+ namespace fs = boost::filesystem;
+
+namespace detail
 {
     void print_char(char ch, std::ostream& out);
     void print_string(std::basic_string<char> const& str, std::ostream& out);
     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);
- return out_name;
- }
-
- template <typename T>
- struct var_wrapper
- : public ::boost::reference_wrapper<T>
- {
- typedef ::boost::reference_wrapper<T> parent;
 
- explicit inline var_wrapper(T& t) : parent(t) {}
+ boost::push_back(out_name,
+ range | boost::adaptors::transformed(filter_identifier_char));
 
- inline T& operator()() const { return parent::get(); }
- };
-
- template <typename T>
- inline var_wrapper<T>
- var(T& t)
- {
- return var_wrapper<T>(t);
+ return out_name;
     }
 
     // un-indent a code segment
     void unindent(std::string& program);
 
- // remove the extension from a filename
- std::string remove_extension(std::string const& filename);
-
     std::string escape_uri(std::string uri);
 
- // Preformats an error/warning message so that it can be parsed by
- // common IDEs. Uses the ms_errors global to determine if VS format
- // or GCC format. Returns the stream to continue ouput of the verbose
- // error message.
- std::ostream & outerr(std::string const& file, int line = -1);
- std::ostream & outwarn(std::string const& file, int line = -1);
-
     // load file into memory with extra trailing newlines to eliminate
     // the need to check for end of file in the grammar.
- int load(std::string const& filename, std::string& storage);
+ int load(fs::path const& filename, std::string& storage);
 
     // given a file extension, return the type of the source file
     // we'll have an internal database for known file types.

Copied: branches/release/tools/quickbook/src/values.cpp (from r70210, /trunk/tools/quickbook/src/values.cpp)
==============================================================================
--- /trunk/tools/quickbook/src/values.cpp (original)
+++ branches/release/tools/quickbook/src/values.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -12,7 +12,7 @@
 #include <boost/lexical_cast.hpp>
 
 #define UNDEFINED_ERROR() \
- throw value_error( \
+ throw value_undefined_method( \
         std::string(BOOST_CURRENT_FUNCTION) +\
         " not defined for " + \
         this->type_name() + \
@@ -24,9 +24,17 @@
     ////////////////////////////////////////////////////////////////////////////
     // Value Error
     
+ struct value_undefined_method : value_error
+ {
+ value_undefined_method(std::string const&);
+ };
+
     value_error::value_error(std::string const& x)
         : std::logic_error(x) {}
-
+
+ value_undefined_method::value_undefined_method(std::string const& x)
+ : value_error(x) {}
+
     ////////////////////////////////////////////////////////////////////////////
     // Node
 
@@ -44,15 +52,51 @@
         file_position value_node::get_position() const { UNDEFINED_ERROR(); }
         int value_node::get_int() const { UNDEFINED_ERROR(); }
         std::string value_node::get_quickbook() const { UNDEFINED_ERROR(); }
- std::string value_node::get_boostbook() const { UNDEFINED_ERROR(); }
- value_node* value_node::get_list() const { UNDEFINED_ERROR(); }
+ value_node::qbk_range value_node::get_quickbook_range() const { UNDEFINED_ERROR(); }
+ std::string value_node::get_boostbook() const { UNDEFINED_ERROR(); }
+ value_node* value_node::get_list() const { UNDEFINED_ERROR(); }
 
         bool value_node::empty() const { return false; }
+ bool value_node::check() const { return true; }
         bool value_node::is_list() const { return false; }
         bool value_node::is_string() const { return false; }
+ bool value_node::equals(value_node*) const { UNDEFINED_ERROR(); }
     }
 
     ////////////////////////////////////////////////////////////////////////////
+ // List end value
+ //
+ // A special value for marking the end of lists.
+
+ namespace detail
+ {
+ struct value_list_end_impl : public value_node
+ {
+ static value_list_end_impl instance;
+ private:
+ value_list_end_impl()
+ : value_node(value::default_tag)
+ {
+ intrusive_ptr_add_ref(&instance);
+ next_ = this;
+ }
+
+ virtual char const* type_name() const { return "list end"; }
+ virtual value_node* clone() const { UNDEFINED_ERROR(); }
+
+ virtual bool equals(value_node* other) const
+ { return this == other; }
+
+ bool empty() const { UNDEFINED_ERROR(); }
+ bool check() const { UNDEFINED_ERROR(); }
+ bool is_list() const { UNDEFINED_ERROR(); }
+ bool is_string() const { UNDEFINED_ERROR(); }
+ };
+
+ value_list_end_impl value_list_end_impl::instance;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
     // Empty/nil values
     //
     // (nil is just a special case of empty, don't be mislead by the name
@@ -76,6 +120,12 @@
 
             virtual bool empty() const
                 { return true; }
+
+ virtual bool check() const
+ { return false; }
+
+ virtual bool equals(value_node* other) const
+ { return !other->check(); }
             
             friend value quickbook::empty_value(value::tag_type);
         };
@@ -88,9 +138,10 @@
                 : value_empty_impl(value::default_tag)
             {
                 intrusive_ptr_add_ref(&instance);
+ next_ = &value_list_end_impl::instance;
             }
         };
-
+
         value_nil_impl value_nil_impl::instance;
 
         value_node* value_empty_impl::new_(value::tag_type t) {
@@ -107,6 +158,11 @@
         }
     }
 
+ value empty_value(value::tag_type t)
+ {
+ return value(detail::value_empty_impl::new_(t));
+ }
+
     ////////////////////////////////////////////////////////////////////////////
     // value_counted
 
@@ -140,24 +196,10 @@
             intrusive_ptr_add_ref(value_);
         }
     
- value_counted& value_counted::operator=(value_counted x)
- {
- swap(x);
- return *this;
- }
-
         value_counted::~value_counted()
         {
             intrusive_ptr_release(value_);
         }
-
- void value_counted::store()
- {
- value_node* new_value = value_->store();
- intrusive_ptr_add_ref(new_value);
- intrusive_ptr_release(value_);
- value_ = new_value;
- }
     }
     
     ////////////////////////////////////////////////////////////////////////////
@@ -173,7 +215,7 @@
     {
     }
 
- value::value(detail::value_ref x)
+ value::value(detail::value_base const& x)
         : detail::value_counted(x)
     {
     }
@@ -182,19 +224,35 @@
         : detail::value_counted(x)
     {
     }
-
+
+ value& value::operator=(value x)
+ {
+ swap(x);
+ return *this;
+ }
+
     ////////////////////////////////////////////////////////////////////////////
- // Iterator
+ // stored_value
 
- namespace detail
+ stored_value::stored_value()
+ : detail::value_counted()
     {
- value::iterator::iterator()
- : ptr_(&value_nil_impl::instance) {}
     }
 
- value empty_value(value::tag_type t)
+ stored_value::stored_value(stored_value const& x)
+ : detail::value_counted(x)
+ {
+ }
+
+ stored_value::stored_value(detail::value_base const& x)
+ : detail::value_counted(x.value_->store())
     {
- return value(detail::value_empty_impl::new_(t));
+ }
+
+ stored_value& stored_value::operator=(stored_value x)
+ {
+ swap(x);
+ return *this;
     }
 
     ////////////////////////////////////////////////////////////////////////////
@@ -213,7 +271,8 @@
             virtual std::string get_quickbook() const;
             virtual std::string get_boostbook() const;
             virtual bool empty() const;
-
+ virtual bool equals(value_node*) const;
+
             int value_;
         };
 
@@ -246,6 +305,15 @@
         {
             return false;
         }
+
+ bool value_int_impl::equals(value_node* other) const {
+ try {
+ return value_ == other->get_int();
+ }
+ catch(value_undefined_method&) {
+ return false;
+ }
+ }
     }
 
     value int_value(int v, value::tag_type t)
@@ -270,7 +338,8 @@
             virtual std::string get_boostbook() const;
             virtual bool is_string() const;
             virtual bool empty() const;
-
+ virtual bool equals(value_node*) const;
+
             std::string value_;
         };
     
@@ -289,8 +358,10 @@
             virtual value_node* clone() const;
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
+ qbk_range get_quickbook_range() const;
             virtual bool is_string() const;
             virtual bool empty() const;
+ virtual bool equals(value_node*) const;
     
             std::string value_;
             file_position position_;
@@ -308,9 +379,11 @@
             virtual value_node* store();
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
+ qbk_range get_quickbook_range() const;
             virtual bool is_string() const;
             virtual bool empty() const;
-
+ virtual bool equals(value_node*) const;
+
             quickbook::iterator begin_;
             quickbook::iterator end_;
         };
@@ -332,9 +405,11 @@
             virtual value_node* clone() const;
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
+ qbk_range get_quickbook_range() const;
             virtual std::string get_boostbook() const;
             virtual bool is_string() const;
             virtual bool empty() const;
+ virtual bool equals(value_node*) const;
 
             std::string qbk_value_;
             std::string bbk_value_;
@@ -375,6 +450,15 @@
         bool value_string_impl::empty() const
             { return value_.empty(); }
 
+ bool value_string_impl::equals(value_node* other) const {
+ try {
+ return value_ == other->get_boostbook();
+ }
+ catch(value_undefined_method&) {
+ return false;
+ }
+ }
+
         // value_qbk_string_impl
     
         value_qbk_string_impl::value_qbk_string_impl(
@@ -408,12 +492,26 @@
         std::string value_qbk_string_impl::get_quickbook() const
             { return value_; }
 
+ value::qbk_range value_qbk_string_impl::get_quickbook_range() const
+ { return qbk_range(
+ iterator(value_.begin(), position_),
+ iterator(value_.end())); }
+
         bool value_qbk_string_impl::is_string() const
             { return true; }
 
         bool value_qbk_string_impl::empty() const
             { return value_.empty(); }
-
+
+ bool value_qbk_string_impl::equals(value_node* other) const {
+ try {
+ return value_ == other->get_quickbook();
+ }
+ catch(value_undefined_method&) {
+ return false;
+ }
+ }
+
         // value_qbk_ref_impl
     
         value_qbk_ref_impl::value_qbk_ref_impl(
@@ -443,12 +541,24 @@
         std::string value_qbk_ref_impl::get_quickbook() const
             { return std::string(begin_.base(), end_.base()); }
 
+ value::qbk_range value_qbk_ref_impl::get_quickbook_range() const
+ { return qbk_range(begin_, end_); }
+
         bool value_qbk_ref_impl::is_string() const
             { return true; }
 
         bool value_qbk_ref_impl::empty() const
             { return begin_ == end_; }
     
+ bool value_qbk_ref_impl::equals(value_node* other) const {
+ try {
+ return this->get_quickbook() == other->get_quickbook();
+ }
+ catch(value_undefined_method&) {
+ return false;
+ }
+ }
+
         // value_qbk_bbk_impl
     
         value_qbk_bbk_impl::value_qbk_bbk_impl(
@@ -503,6 +613,11 @@
         std::string value_qbk_bbk_impl::get_quickbook() const
             { return qbk_value_; }
 
+ value::qbk_range value_qbk_bbk_impl::get_quickbook_range() const
+ { return qbk_range(
+ iterator(qbk_value_.begin(), position_),
+ iterator(qbk_value_.end())); }
+
         std::string value_qbk_bbk_impl::get_boostbook() const
             { return bbk_value_; }
 
@@ -512,6 +627,20 @@
         // Should this test the quickbook, the boostbook or both?
         bool value_qbk_bbk_impl::empty() const
             { return bbk_value_.empty(); }
+
+ bool value_qbk_bbk_impl::equals(value_node* other) const {
+ try {
+ return this->get_quickbook() == other->get_quickbook();
+ }
+ catch(value_undefined_method&) {}
+
+ try {
+ return this->get_boostbook() == other->get_boostbook();
+ }
+ catch(value_undefined_method&) {}
+
+ return false;
+ }
     }
 
     value qbk_value(iterator x, iterator y, value::tag_type t)
@@ -557,7 +686,7 @@
 
         value_node** list_ref_back(value_node** back)
         {
- while(*back != &value_nil_impl::instance) {
+ while(*back != &value_list_end_impl::instance) {
                 intrusive_ptr_add_ref(*back);
                 back = &(*back)->next_;
             }
@@ -567,7 +696,7 @@
 
         void list_ref(value_node* ptr)
         {
- while(ptr != &value_nil_impl::instance) {
+ while(ptr != &value_list_end_impl::instance) {
                 intrusive_ptr_add_ref(ptr);
                 ptr = ptr->next_;
             }
@@ -575,7 +704,7 @@
 
         void list_unref(value_node* ptr)
         {
- while(ptr != &value_nil_impl::instance) {
+ while(ptr != &value_list_end_impl::instance) {
                 value_node* next = ptr->next_;
                 intrusive_ptr_release(ptr);
                 ptr = next;
@@ -584,7 +713,7 @@
 
         value_node** merge_sort(value_node** l)
         {
- if(*l == &value_nil_impl::instance)
+ if(*l == &value_list_end_impl::instance)
                 return l;
             else
                 return merge_sort(l, 9999);
@@ -594,7 +723,7 @@
         {
             value_node** p = &(*l)->next_;
             for(int count = 0;
- count < recurse_limit && *p != &value_nil_impl::instance;
+ count < recurse_limit && *p != &value_list_end_impl::instance;
                 ++count)
             {
                 p = merge(l, p, merge_sort(p, count));
@@ -639,7 +768,7 @@
             *first = *second;
             *second = *third;
             *third = tmp;
- //if(*second != &value_nil_impl::instance) back = second;
+ //if(*second != &value_list_end_impl::instance) back = second;
         }
     }
     }
@@ -652,27 +781,36 @@
         struct value_list_impl : public value_node
         {
             value_list_impl(value::tag_type);
- value_list_impl(value_node*, value::tag_type);
+ value_list_impl(value_list_builder&, value::tag_type);
         private:
+ value_list_impl(value_list_impl const&);
+
             char const* type_name() const { return "list"; }
 
             virtual ~value_list_impl();
             virtual value_node* clone() const;
             virtual value_node* store();
             virtual bool empty() const;
+ virtual bool equals(value_node*) const;
+
             virtual bool is_list() const;
-
             virtual value_node* get_list() const;
     
             value_node* head_;
         };
-
+
         value_list_impl::value_list_impl(value::tag_type tag)
- : value_node(tag), head_(&value_nil_impl::instance)
+ : value_node(tag), head_(&value_list_end_impl::instance)
         {}
     
- value_list_impl::value_list_impl(value_node* ptr, value::tag_type tag)
- : value_node(tag), head_(ptr)
+ value_list_impl::value_list_impl(value_list_builder& builder,
+ value::tag_type tag)
+ : value_node(tag), head_(builder.release())
+ {
+ }
+
+ value_list_impl::value_list_impl(value_list_impl const& x)
+ : value_node(x.tag_), head_(x.head_)
         {
             list_ref(head_);
         }
@@ -684,17 +822,16 @@
 
         value_node* value_list_impl::clone() const
         {
- return new value_list_impl(head_, tag_);
+ return new value_list_impl(*this);
         }
 
- // TODO: Could reuse nodes is any node has a reference count of 1.
         value_node* value_list_impl::store()
         {
             value_node* pos = head_;
             boost::intrusive_ptr<value_node> new_node;
 
- while(true) {
- if(pos == &value_nil_impl::instance)
+ for(;;) {
+ if(pos == &value_list_end_impl::instance)
                     return this;
                 new_node = pos->store();
                 if(new_node.get() != pos) break;
@@ -703,23 +840,23 @@
 
             value_list_builder build;
 
- for(value_node* pos2 = head_;
- pos2 != &value_nil_impl::instance;
- pos2 = pos2->next_)
- {
- if(pos2 == pos)
- build.append(new_node.get());
- else
- build.append(pos2);
- }
+ value_node* pos2 = head_;
 
- return new value_list_impl(build.get(), tag_);
- }
+ for(;pos2 != pos; pos2 = pos2->next_)
+ build.append(pos2);
+
+ build.append(new_node.get());
+ pos2 = pos2->next_;
+
+ for(;pos2 != &value_list_end_impl::instance; pos2 = pos2->next_)
+ build.append(pos2->store());
 
+ return new value_list_impl(build, tag_);
+ }
 
         bool value_list_impl::empty() const
         {
- return head_ == &value_nil_impl::instance;
+ return head_ == &value_list_end_impl::instance;
         }
     
         bool value_list_impl::is_list() const
@@ -731,6 +868,25 @@
         {
             return head_;
         }
+
+ bool value_list_impl::equals(value_node* other) const {
+ value_node* x1;
+
+ try {
+ x1 = other->get_list();
+ }
+ catch(value_undefined_method&) {
+ return false;
+ }
+
+ for(value_node *x2 = head_; x1 != x2; x1 = x1->next_, x2 = x2->next_)
+ {
+ if (x2 == &value_list_end_impl::instance ||
+ !x1->equals(x2)) return false;
+ }
+
+ return true;
+ }
     }
 
     //////////////////////////////////////////////////////////////////////////
@@ -741,7 +897,7 @@
         // value_list_builder
     
         value_list_builder::value_list_builder()
- : head_(&value_nil_impl::instance)
+ : head_(&value_list_end_impl::instance)
             , back_(&head_)
         {}
 
@@ -762,9 +918,11 @@
             if(other.back_ == &head_) other.back_ = &other.head_;
         }
 
- // TODO: Multiple list refs are incompatible with 'store'
- value_node* value_list_builder::get() const {
- return head_;
+ value_node* value_list_builder::release() {
+ value_node* r = head_;
+ head_ = &value_list_end_impl::instance;
+ back_ = &head_;
+ return r;
         }
     
         void value_list_builder::append(value_node* item)
@@ -779,7 +937,7 @@
         void value_list_builder::sort()
         {
             back_ = merge_sort(&head_);
- assert(*back_ == &value_nil_impl::instance);
+ assert(*back_ == &value_list_end_impl::instance);
         }
     }
 
@@ -811,8 +969,8 @@
         swap(*store);
     }
 
- value value_builder::get() {
- return value(new detail::value_list_impl(current.get(), list_tag));
+ value value_builder::release() {
+ return value(new detail::value_list_impl(current, list_tag));
     }
 
     void value_builder::reset() {
@@ -825,6 +983,14 @@
         current.append(item.value_);
     }
 
+ void value_builder::extend(value const& list) {
+ for (value::iterator begin = list.begin(), end = list.end();
+ begin != end; ++begin)
+ {
+ insert(*begin);
+ }
+ }
+
     void value_builder::start_list(value::tag_type tag) {
         value::tag_type saved_tag = tag;
         save();
@@ -832,7 +998,7 @@
     }
 
     void value_builder::finish_list() {
- value list = get();
+ value list = release();
         restore();
         insert(list);
     }
@@ -845,4 +1011,13 @@
     {
         current.sort();
     }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Iterator
+
+ namespace detail
+ {
+ value::iterator::iterator()
+ : ptr_(&value_list_end_impl::instance) {}
+ }
 }

Copied: branches/release/tools/quickbook/src/values.hpp (from r70210, /trunk/tools/quickbook/src/values.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/values.hpp (original)
+++ branches/release/tools/quickbook/src/values.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -16,12 +16,14 @@
 #include <cassert>
 #include <boost/scoped_ptr.hpp>
 #include <boost/iterator/iterator_traits.hpp>
+#include <boost/range/iterator_range.hpp>
 #include <stdexcept>
 #include "fwd.hpp"
 
 namespace quickbook
 {
     class value;
+ class stored_value;
     class value_builder;
     class value_error;
 
@@ -38,6 +40,7 @@
 
         public:
             typedef int tag_type;
+ typedef boost::iterator_range<quickbook::iterator> qbk_range;
 
         protected:
             explicit value_node(tag_type);
@@ -51,11 +54,14 @@
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
             virtual std::string get_boostbook() const;
+ virtual qbk_range get_quickbook_range() const;
             virtual int get_int() const;
 
+ virtual bool check() const;
             virtual bool empty() const;
             virtual bool is_list() const;
             virtual bool is_string() const;
+ virtual bool equals(value_node*) const;
 
             virtual value_node* get_list() const;
             
@@ -83,6 +89,7 @@
             typedef iterator const_iterator;
             typedef value_node::tag_type tag_type;
             enum { default_tag = 0 };
+ typedef boost::iterator_range<quickbook::iterator> qbk_range;
 
         protected:
             explicit value_base(value_node* base)
@@ -93,9 +100,9 @@
 
             ~value_base() {}
 
- public:
             void swap(value_base& x) { std::swap(value_, x.value_); }
-
+ public:
+ bool check() const { return value_->check(); }
             bool empty() const { return value_->empty(); }
             bool is_list() const { return value_->is_list(); }
             bool is_string() const { return value_->is_string(); }
@@ -109,17 +116,25 @@
             { return value_->get_position(); }
             std::string get_quickbook() const
             { return value_->get_quickbook(); }
+ qbk_range get_quickbook_range() const
+ { return value_->get_quickbook_range(); }
             std::string get_boostbook() const
             { return value_->get_boostbook(); }
             int get_int() const
             { return value_->get_int(); }
 
+ // Equality is pretty inefficient. Not really designed for anything
+ // more than testing purposes.
+ friend bool operator==(value_base const& x, value_base const& y)
+ { return x.value_->equals(y.value_); }
+
         protected:
             value_node* value_;
 
             // value_builder needs to access 'value_' to get the node
             // from a value.
             friend class quickbook::value_builder;
+ friend class quickbook::stored_value;
         };
         
         ////////////////////////////////////////////////////////////////////////
@@ -173,15 +188,13 @@
 
         class value_counted : public value_base
         {
- public:
+ value_counted& operator=(value_counted const&);
+ protected:
             value_counted();
             value_counted(value_counted const&);
             value_counted(value_base const&);
             value_counted(value_node*);
- value_counted& operator=(value_counted);
             ~value_counted();
-
- void store();
         };
 
         ////////////////////////////////////////////////////////////////////////
@@ -198,7 +211,7 @@
             value_list_builder(value_node*);
             ~value_list_builder();
             void swap(value_list_builder& b);
- value_node* get() const;
+ value_node* release();
 
             void append(value_node*);
             void sort();
@@ -218,8 +231,20 @@
     public:
         value();
         value(value const&);
- value(detail::value_ref);
+ value(detail::value_base const&);
         explicit value(detail::value_node*);
+ value& operator=(value);
+ void swap(value& x) { detail::value_counted::swap(x); }
+ };
+
+ class stored_value : public detail::value_counted
+ {
+ public:
+ stored_value();
+ stored_value(stored_value const&);
+ stored_value(detail::value_base const&);
+ stored_value& operator=(stored_value);
+ void swap(stored_value& x) { detail::value_counted::swap(x); }
     };
 
     // Empty
@@ -252,11 +277,12 @@
         void save();
         void restore();
 
- value get();
+ value release();
 
         void reset();
         void set_tag(value::tag_type);
         void insert(value const&);
+ void extend(value const&);
 
         void start_list(value::tag_type = value::default_tag);
         void finish_list();
@@ -273,10 +299,10 @@
     // Value Error
     //
     
- class value_error : std::logic_error
+ class value_error : public std::logic_error
     {
     public:
- value_error(std::string const&);
+ explicit value_error(std::string const&);
     };
 
     ////////////////////////////////////////////////////////////////////////////
@@ -305,7 +331,6 @@
             value::iterator* ptr_;
         };
 
-
         typedef iterator const_iterator;
         typedef iterator::reference reference;
     
@@ -323,13 +348,13 @@
 
         reference consume()
         {
- assert(check());
+ assert_check();
             return *pos_++;
         }
 
         reference consume(value::tag_type t)
         {
- assert(check(t));
+ assert_check(t);
             return *pos_++;
         }
 
@@ -365,12 +390,27 @@
         
         void finish() const
         {
- assert(pos_ == end_);
+ if (pos_ != end_)
+ throw value_error("Not all values handled.");
         }
 
         iterator begin() { return iterator(&pos_); }
         iterator end() { return iterator(&end_); }
     private:
+
+ void assert_check() const
+ {
+ if (pos_ == end_)
+ throw value_error("Attempt to read past end of value list.");
+ }
+
+ void assert_check(value::tag_type t) const
+ {
+ assert_check();
+ if (t != pos_->get_tag())
+ throw value_error("Incorrect value tag.");
+ }
+
         value list_;
         value::iterator pos_, end_;
     };

Copied: branches/release/tools/quickbook/src/values_parse.hpp (from r70210, /trunk/tools/quickbook/src/values_parse.hpp)
==============================================================================
--- /trunk/tools/quickbook/src/values_parse.hpp (original)
+++ branches/release/tools/quickbook/src/values_parse.hpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -123,7 +123,7 @@
             , sort(builder)
             {}
     
- value get() { return builder.get(); }
+ value release() { return builder.release(); }
 
         value_builder builder;
         scoped_parser<value_builder_save> save;

Modified: branches/release/tools/quickbook/test/Jamfile.v2
==============================================================================
--- branches/release/tools/quickbook/test/Jamfile.v2 (original)
+++ branches/release/tools/quickbook/test/Jamfile.v2 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -6,9 +6,18 @@
 # http://www.boost.org/LICENSE_1_0.txt)
 #
 
-project test ;
+project test
+ : requirements
+ <toolset>msvc:<debug-symbols>off
+ ;
+
+build-project doc-info ;
+build-project unit ;
+build-project command-line ;
+build-project snippets ;
+build-project "include" ;
 
-import quickbook-testing : quickbook-test quickbook-fail-test ;
+import quickbook-testing : quickbook-test quickbook-error-test ;
 
 test-suite quickbook.test :
     [ quickbook-test quickbook-manual ]
@@ -27,8 +36,8 @@
     [ quickbook-test template-section ]
     [ quickbook-test mismatched-brackets-1 ]
     [ quickbook-test mismatched-brackets-2 ]
- [ quickbook-fail-test mismatched-brackets-3 ]
- #[ quickbook-test xinclude ]
+ [ quickbook-error-test mismatched-brackets-3 ]
+ [ quickbook-test xinclude : : : <quickbook-xinclude-base>../src ]
     [ quickbook-test import ]
     [ quickbook-test include_1_5 ]
     [ quickbook-test include_1_6 ]
@@ -46,38 +55,37 @@
     [ quickbook-test list_test ]
     [ quickbook-test cond_phrase ]
     [ quickbook-test macro ]
- [ quickbook-test doc-info-1 ]
- [ quickbook-test doc-info-2 ]
- [ quickbook-test doc-info-3 ]
- [ quickbook-test doc-info-4 ]
     [ quickbook-test callouts ]
     [ quickbook-test simple_markup ]
     [ quickbook-test xml-escape_1_2 ]
     [ quickbook-test xml-escape_1_5 ]
     [ quickbook-test blocks ]
+ [ quickbook-test elements_1_5 ]
+ [ quickbook-test elements_1_6 ]
     [ quickbook-test newline ]
     [ quickbook-test anchor ]
     [ quickbook-test command_line_macro : : : <quickbook-test-define>__macro__=*bold* ]
- [ quickbook-fail-test fail-include ]
- [ quickbook-fail-test fail-import ]
- [ quickbook-fail-test fail-template-arguments1 ]
- [ quickbook-fail-test fail-template-arguments2 ]
- [ quickbook-fail-test fail-template-arguments3 ]
- [ quickbook-fail-test fail-cpp-mismatched-escape ]
- [ quickbook-fail-test fail-python-mismatched-escape ]
- [ quickbook-fail-test fail-post-process ]
- [ quickbook-fail-test fail-parse-error1 ]
- [ quickbook-fail-test fail-parse-error2 ]
- [ quickbook-fail-test fail-template-lookup1 ]
- [ quickbook-fail-test fail-template-section-1 ]
- [ quickbook-fail-test fail-template-section-2 ]
- [ quickbook-fail-test fail-template-section-3 ]
- [ quickbook-fail-test fail-unknown-quickbook-1 ]
- [ quickbook-fail-test fail-unknown-quickbook-2 ]
- [ quickbook-fail-test fail-unknown-quickbook-3 ]
+ [ quickbook-error-test fail-include ]
+ [ quickbook-error-test fail-import ]
+ [ quickbook-error-test fail-template-arguments1 ]
+ [ quickbook-error-test fail-template-arguments2 ]
+ [ quickbook-error-test fail-template-arguments3 ]
+ [ quickbook-error-test fail-cpp-mismatched-escape ]
+ [ quickbook-error-test fail-python-mismatched-escape ]
+ [ quickbook-error-test fail-post-process ]
+ [ quickbook-error-test fail-parse-error1 ]
+ [ quickbook-error-test fail-parse-error2 ]
+ [ quickbook-error-test fail-template-lookup1 ]
+ [ quickbook-error-test fail-template-section-1 ]
+ [ quickbook-error-test fail-template-section-2 ]
+ [ quickbook-error-test fail-template-section-3 ]
+ [ quickbook-error-test fail-unknown-quickbook-1 ]
+ [ quickbook-error-test fail-unknown-quickbook-2 ]
+ [ quickbook-error-test fail-unknown-quickbook-3 ]
+ [ quickbook-error-test fail-mismatched-boostbook-escape ]
     [ quickbook-test utf-8 ]
     [ quickbook-test utf-8-bom ]
     [ quickbook-test unicode-escape ]
- [ quickbook-fail-test utf-16be-bom ]
- [ quickbook-fail-test utf-16le-bom ]
+ [ quickbook-error-test utf-16be-bom ]
+ [ quickbook-error-test utf-16le-bom ]
     ;

Modified: branches/release/tools/quickbook/test/anchor.gold
==============================================================================
--- branches/release/tools/quickbook/test/anchor.gold (original)
+++ branches/release/tools/quickbook/test/anchor.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,37 +10,74 @@
       We want to make sure they appear in the correct place. <anchor id="a3"/>
     </para>
     <anchor id="anchor_test.anchors.this_heading_shouldn_t_pick_up_the_previous_anchor"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="anchor_test.anchors.this_heading_shouldn_t_pick_up_the_previous_anchor-heading">
       <link linkend="anchor_test.anchors.this_heading_shouldn_t_pick_up_the_previous_anchor">This
       heading shouldn't pick up the previous anchor</link>
     </bridgehead>
     <anchor id="a4"/> <anchor id="anchor_test.anchors.this_heading_should_pick_up_the_previous_anchor"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="anchor_test.anchors.this_heading_should_pick_up_the_previous_anchor-heading">
       <link linkend="anchor_test.anchors.this_heading_should_pick_up_the_previous_anchor">This
       heading should pick up the previous anchor</link>
     </bridgehead>
     <anchor id="a5"/> <anchor id="anchor_test.anchors.and_this_one"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="anchor_test.anchors.and_this_one-heading">
       <link linkend="anchor_test.anchors.and_this_one">And this one</link>
     </bridgehead>
     <anchor id="a6"/> <anchor id="anchor_test.anchors.also_this_one"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="anchor_test.anchors.also_this_one-heading">
       <link linkend="anchor_test.anchors.also_this_one">Also this one</link>
     </bridgehead>
     <anchor id="a7"/> <anchor id="anchors.finally_this"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="anchors.finally_this-heading">
       Finally this
     </bridgehead>
     <anchor id="a8"/>
   </section>
   <section id="anchor_test.section_anchor">
- <anchor id="a9"/> <title>Section Anchor</title>
+ <title><anchor id="a9"/> Section Anchor</title>
     <section id="anchor_test.nested_section">
- <anchor id="a10"/> <title>Nested Section</title>
+ <title><anchor id="a10"/> Nested Section</title>
     </section>
     <anchor id="a11"/>
   </section>
   <section id="anchor_test.conditional_section_anchor">
- <anchor id="a12"/> <title>Conditional Section Anchor</title>
+ <title><anchor id="a12"/> Conditional Section Anchor</title>
+ </section>
+ <section id="anchor_test.lists">
+ <title>Lists</title> <anchor id="a14"/>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Item 1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Item 2
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Nested List <anchor id="a15"/>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Nested Item 1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Nested Item 2
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Item 3
+ </simpara>
+ </listitem>
+ </itemizedlist>
   </section>
 </article>

Modified: branches/release/tools/quickbook/test/anchor.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/anchor.quickbook (original)
+++ branches/release/tools/quickbook/test/anchor.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -33,4 +33,18 @@
 
 [#a12][?__not_defined__ #a13]
 [section Conditional Section Anchor]
+[endsect]
+
+[section Lists]
+
+[#a14]
+
+* Item 1
+* Item 2
+* Nested List
+ [#a15]
+ * Nested Item 1
+ * Nested Item 2
+* Item 3
+
 [endsect]
\ No newline at end of file

Modified: branches/release/tools/quickbook/test/blocks.gold
==============================================================================
--- branches/release/tools/quickbook/test/blocks.gold (original)
+++ branches/release/tools/quickbook/test/blocks.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -3,7 +3,7 @@
 <article id="various_blocks" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
  xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>Various blocks</title> <anchor id="various_blocks.blockquotes"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="various_blocks.blockquotes-heading">
     <link linkend="various_blocks.blockquotes">Blockquotes</link>
   </bridgehead>
   <para>
@@ -26,7 +26,7 @@
     </para>
   </blockquote>
   <anchor id="various_blocks.admonitions"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="various_blocks.admonitions-heading">
     <link linkend="various_blocks.admonitions">Admonitions</link>
   </bridgehead>
   <warning>
@@ -63,7 +63,7 @@
     </para>
   </warning>
   <anchor id="various_blocks.blurb"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="various_blocks.blurb-heading">
     <link linkend="various_blocks.blurb">Blurb</link>
   </bridgehead>
   <sidebar role="blurb">
@@ -71,7 +71,7 @@
     Blurb
   </para>
   </sidebar> <anchor id="various_blocks.inline_blocks"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="various_blocks.inline_blocks-heading">
     <link linkend="various_blocks.inline_blocks">Inline blocks</link>
   </bridgehead>
   <blockquote>

Modified: branches/release/tools/quickbook/test/code-block.gold
==============================================================================
--- branches/release/tools/quickbook/test/code-block.gold (original)
+++ branches/release/tools/quickbook/test/code-block.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -27,7 +27,7 @@
     Paragraph.
   </para>
   <anchor id="indented_code_blocks.code_blocks_separated_by_comment"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="indented_code_blocks.code_blocks_separated_by_comment-heading">
     <link linkend="indented_code_blocks.code_blocks_separated_by_comment">Code blocks
     separated by comment</link>
   </bridgehead>

Deleted: branches/release/tools/quickbook/test/doc-info-1.gold
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-1.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
-<article id="karel_vom_u00e1_u010dka_and_tom_u00e1_u0161_martin_u00edk" lang="en"
-last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
- <title>Karel Vom&#xE1;&#x10D;ka and Tom&#xE1;&#x161; Martin&#xED;k</title>
- <articleinfo>
- <authorgroup>
- <author>
- <firstname>Matti</firstname> <surname>Meik&#xE4;l&#xE4;inen</surname>
- </author>
- <author>
- <firstname>Pero</firstname> <surname>Peri&#x107;</surname>
- </author>
- </authorgroup>
- <copyright>
- <year>2010</year> <holder>Me&#xF0;al-J&#xF3;n and J&#xF3;na J&#xF3;nsd&#xF3;ttir</holder>
- </copyright>
- <articlepurpose>
- Inline code test: <code>1 + 2</code>
- </articlepurpose>
- <articlecategory name="category:tests"></articlecategory> <articlecategory name="category:irrelevance"></articlecategory>
- <biblioid class="uri">http://www.boost.org/tools/quickbook/test/doc-info-1.quickbook>
- </articleinfo>
-</article>

Deleted: branches/release/tools/quickbook/test/doc-info-1.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-1.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,12 +0,0 @@
-[article Karel Vom\u00E1\u010Dka and Tom\u00E1\u0161 Martin\u00EDk
-[quickbook 1.6]
-[authors [Meik\u00E4l\u00E4inen, Matti][Peri\u0107, Pero]]
-[copyright 2010 Me\u00F0al-J\u00F3n and J\u00F3na J\u00F3nsd\u00F3ttir]
-[source-mode teletype]
-[purpose Inline code test: `1 + 2`]
-[category tests]
-[category irrelevance]
-[/ [category commented out] ]
-[biblioid uri
http://www.boost.org/tools/quickbook/test/doc-info-1.quickbook]
-[lang en]
-]

Deleted: branches/release/tools/quickbook/test/doc-info-2.gold
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-2.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
-<library id="karel_vom__xe1___x10d_ka_and_tom__xe1___x161__martin__xed_k" name="Karel Vom&#xE1;&#x10D;ka and Tom&#xE1;&#x161; Martin&#xED;k"
-dirname="karel_vom__xe1___x10d_ka_and_tom__xe1___x161__martin__xed_k" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
- xmlns:xi="http://www.w3.org/2001/XInclude">
- <libraryinfo>
- <authorgroup>
- <author>
- <firstname>Matti</firstname> <surname>Meik&#xE4;l&#xE4;inen</surname>
- </author>
- <author>
- <firstname>Pero</firstname> <surname>Peri&#x107;</surname>
- </author>
- </authorgroup>
- <copyright>
- <year>2010</year> <holder>Me&#xF0;al-J&#xF3;n and J&#xF3;na J&#xF3;nsd&#xF3;ttir</holder>
- </copyright>
- <librarypurpose>
- Inline code test: <code>1 + 2</code>
- </librarypurpose>
- <librarycategory name="category:tests"></librarycategory> <librarycategory name="category:irrelevance"></librarycategory>
- <biblioid class="uri">http://www.boost.org/tools/quickbook/test/doc-info-2.quickbook>
- <biblioid class="isbn">0-937383-18-X</biblioid>
- </libraryinfo>
- <title>Karel Vom&#xE1;&#x10D;ka and Tom&#xE1;&#x161; Martin&#xED;k</title>
-</library>

Deleted: branches/release/tools/quickbook/test/doc-info-2.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-2.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,14 +0,0 @@
-[library Karel Vom&#xE1;&#x10D;ka and Tom&#xE1;&#x161; Martin&#xED;k
-[quickbook 1.5]
-[authors [Meik&#xE4;l&#xE4;inen, Matti],[Peri&#x107;, Pero]]
-[copyright 2010 Me&#xF0;al-J&#xF3;n and J&#xF3;na J&#xF3;nsd&#xF3;ttir]
-[source-mode teletype]
-[purpose Inline code test: `1 + 2`]
-[category tests]
-[category irrelevance]
-[/ [category commented out] ]
-[biblioid uri
http://www.boost.org/tools/quickbook/test/doc-info-2.quickbook]
-[biblioid isbn 0-937383-18-X]
-]
-
-[/ Some comment]

Deleted: branches/release/tools/quickbook/test/doc-info-3.gold
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-3.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE appendix PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
-<appendix id="document_information_4" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
- xmlns:xi="http://www.w3.org/2001/XInclude">
- <title>Document Information 4</title>
- <appendixinfo>
- <authorgroup>
- <author>
- <firstname>Joe</firstname> <surname>Blow</surname>
- </author>
- </authorgroup>
- </appendixinfo>
-</appendix>

Deleted: branches/release/tools/quickbook/test/doc-info-3.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-3.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,5 +0,0 @@
-[appendix Document Information 4
-[quickbook 1.5]
-[authors [Blow, Joe]]
-]
-[/ Some comment]
\ No newline at end of file

Deleted: branches/release/tools/quickbook/test/doc-info-4.gold
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-4.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
-<chapter id="document_information_4" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
- xmlns:xi="http://www.w3.org/2001/XInclude">
- <title>Document Information 4</title>
- <chapterinfo>
- <authorgroup>
- <author>
- <firstname>Joe</firstname> <surname>Blow</surname>
- </author>
- <author>
- <firstname>Jane</firstname> <surname>Doe</surname>
- </author>
- <author>
- <firstname>John</firstname> <surname>Coe</surname>
- </author>
- </authorgroup>
- </chapterinfo>
-</chapter>

Deleted: branches/release/tools/quickbook/test/doc-info-4.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/doc-info-4.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
+++ (empty file)
@@ -1,4 +0,0 @@
-[chapter Document Information 4
-[quickbook 1.5]
-[authors [Blow, Joe], [Doe, Jane] [Coe, John]]
-]
\ No newline at end of file

Modified: branches/release/tools/quickbook/test/heading.gold
==============================================================================
--- branches/release/tools/quickbook/test/heading.gold (original)
+++ branches/release/tools/quickbook/test/heading.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,21 +2,21 @@
 <!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
 <article id="header" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>Header</title> <anchor id="header.header_test"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="header.header_test-heading">
     <link linkend="header.header_test">Header Test</link>
   </bridgehead>
   <para>
     Testing headers without sections.
   </para>
   <anchor id="header._not_an_id"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="header._not_an_id-heading">
     <link linkend="header._not_an_id">:Not an Id</link>
   </bridgehead>
   <para>
     Paragraph.
   </para>
   <anchor id="header._not_an_id_again"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="header._not_an_id_again-heading">
     <link linkend="header._not_an_id_again">:Not an Id again</link>
   </bridgehead>
   <para>

Modified: branches/release/tools/quickbook/test/heading_1_6.gold
==============================================================================
--- branches/release/tools/quickbook/test/heading_1_6.gold (original)
+++ branches/release/tools/quickbook/test/heading_1_6.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,21 +2,21 @@
 <!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
 <article id="header" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>Header</title> <anchor id="header.header_test"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="header.header_test-heading">
     <link linkend="header.header_test">Header Test</link>
   </bridgehead>
   <para>
     Paragraph.
   </para>
   <anchor id="header.heading_id"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="header.heading_id-heading">
     <link linkend="header.heading_id">Heading with an id</link>
   </bridgehead>
   <para>
     Paragraph.
   </para>
   <anchor id="header.heading_id2"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="header.heading_id2-heading">
     <link linkend="header.heading_id2">Heading with an id</link>
   </bridgehead>
   <para>

Modified: branches/release/tools/quickbook/test/identifier_1_5.gold
==============================================================================
--- branches/release/tools/quickbook/test/identifier_1_5.gold (original)
+++ branches/release/tools/quickbook/test/identifier_1_5.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -3,7 +3,7 @@
 <article id="identifiers_in_quickbook_1_5" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
  xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>Identifiers in quickbook 1.5</title> <anchor id="identifiers_in_quickbook_1_5.test_heading_with__code__phrase_role__identifier__code__phrase___code_"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="identifiers_in_quickbook_1_5.test_heading_with__code__phrase_role__identifier__code__phrase___code_-heading">
     <link linkend="identifiers_in_quickbook_1_5.test_heading_with__code__phrase_role__identifier__code__phrase___code_">Test
     heading with <code><phrase role="identifier">code</phrase></code></link>
   </bridgehead>

Modified: branches/release/tools/quickbook/test/identifier_1_6.gold
==============================================================================
--- branches/release/tools/quickbook/test/identifier_1_6.gold (original)
+++ branches/release/tools/quickbook/test/identifier_1_6.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -3,7 +3,7 @@
 <article id="identifiers_in_quickbook_1_6" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
  xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>Identifiers in quickbook 1.6</title> <anchor id="identifiers_in_quickbook_1_6.test_heading_with__code_"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="identifiers_in_quickbook_1_6.test_heading_with__code_-heading">
     <link linkend="identifiers_in_quickbook_1_6.test_heading_with__code_">Test heading
     with <code><phrase role="identifier">code</phrase></code></link>
   </bridgehead>

Modified: branches/release/tools/quickbook/test/link.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/link.quickbook (original)
+++ branches/release/tools/quickbook/test/link.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 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: branches/release/tools/quickbook/test/list_test.gold
==============================================================================
--- branches/release/tools/quickbook/test/list_test.gold (original)
+++ branches/release/tools/quickbook/test/list_test.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -39,36 +39,36 @@
     <listitem>
       <simpara>
         A
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B
+ </simpara>
+ </listitem>
+ </itemizedlist>
       </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- A
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- B
- </simpara>
- </listitem>
- </itemizedlist>
     </listitem>
     <listitem>
       <simpara>
         B
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B
+ </simpara>
+ </listitem>
+ </itemizedlist>
       </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- A
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- B
- </simpara>
- </listitem>
- </itemizedlist>
     </listitem>
   </itemizedlist>
   <para>
@@ -78,36 +78,36 @@
     <listitem>
       <simpara>
         A
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B
+ </simpara>
+ </listitem>
+ </itemizedlist>
       </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- A
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- B
- </simpara>
- </listitem>
- </itemizedlist>
     </listitem>
     <listitem>
       <simpara>
         B
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B
+ </simpara>
+ </listitem>
+ </itemizedlist>
       </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- A
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- B
- </simpara>
- </listitem>
- </itemizedlist>
     </listitem>
   </orderedlist>
   <para>
@@ -117,53 +117,53 @@
     <listitem>
       <simpara>
         A
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ C
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ D
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ E
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ F
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ G
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ H
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
+ </listitem>
+ </itemizedlist>
       </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- A
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- B
- </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- C
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- D
- </simpara>
- </listitem>
- </itemizedlist>
- </listitem>
- <listitem>
- <simpara>
- E
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- F
- </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- G
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- H
- </simpara>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
     </listitem>
   </orderedlist>
   <para>
@@ -173,31 +173,31 @@
     <listitem>
       <simpara>
         A
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ A
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ B
+ <orderedlist>
+ <listitem>
+ <simpara>
+ C
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ D
+ </simpara>
+ </listitem>
+ </orderedlist>
+ </simpara>
+ </listitem>
+ </itemizedlist>
       </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- A
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- B
- </simpara>
- <orderedlist>
- <listitem>
- <simpara>
- C
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- D
- </simpara>
- </listitem>
- </orderedlist>
- </listitem>
- </itemizedlist>
     </listitem>
     <listitem>
       <simpara>
@@ -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: branches/release/tools/quickbook/test/list_test.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/list_test.quickbook (original)
+++ branches/release/tools/quickbook/test/list_test.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -52,6 +52,13 @@
 # G
 # H
 
+Markup in list:
+
+* *Bold*
+* [*Bold]
+* ["Quoted]
+* [footnote Footnote]
+
 [section List immediately following markup]
 * One
 * Two

Modified: branches/release/tools/quickbook/test/quickbook-manual.gold
==============================================================================
--- branches/release/tools/quickbook/test/quickbook-manual.gold (original)
+++ branches/release/tools/quickbook/test/quickbook-manual.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -104,7 +104,7 @@
   <section id="quickbook.change_log">
     <title><link linkend="quickbook.change_log">Change Log</link></title> <anchor
     id="quickbook.change_log.version_1_3"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="quickbook.change_log.version_1_3-heading">
       <link linkend="quickbook.change_log.version_1_3">Version 1.3</link>
     </bridgehead>
     <itemizedlist>
@@ -1272,48 +1272,48 @@
             <listitem>
               <simpara>
                 Three
+ <orderedlist>
+ <listitem>
+ <simpara>
+ Three.a
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Three.b
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Three.c
+ </simpara>
+ </listitem>
+ </orderedlist>
               </simpara>
- <orderedlist>
- <listitem>
- <simpara>
- Three.a
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- Three.b
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- Three.c
- </simpara>
- </listitem>
- </orderedlist>
             </listitem>
             <listitem>
               <simpara>
                 Fourth
+ <orderedlist>
+ <listitem>
+ <simpara>
+ Four.a
+ <orderedlist>
+ <listitem>
+ <simpara>
+ Four.a.i
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Four.a.ii
+ </simpara>
+ </listitem>
+ </orderedlist>
+ </simpara>
+ </listitem>
+ </orderedlist>
               </simpara>
- <orderedlist>
- <listitem>
- <simpara>
- Four.a
- </simpara>
- <orderedlist>
- <listitem>
- <simpara>
- Four.a.i
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- Four.a.ii
- </simpara>
- </listitem>
- </orderedlist>
- </listitem>
- </orderedlist>
             </listitem>
             <listitem>
               <simpara>
@@ -1418,24 +1418,24 @@
             <listitem>
               <simpara>
                 Three
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Three.a
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Three.b
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Three.c
+ </simpara>
+ </listitem>
+ </itemizedlist>
               </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- Three.a
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- Three.b
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- Three.c
- </simpara>
- </listitem>
- </itemizedlist>
             </listitem>
             <listitem>
               <simpara>
@@ -1467,72 +1467,72 @@
             <listitem>
               <simpara>
                 1
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ 1.a
+ <orderedlist>
+ <listitem>
+ <simpara>
+ 1.a.1
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ 1.a.2
+ </simpara>
+ </listitem>
+ </orderedlist>
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ 1.b
+ </simpara>
+ </listitem>
+ </itemizedlist>
               </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- 1.a
- </simpara>
- <orderedlist>
- <listitem>
- <simpara>
- 1.a.1
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- 1.a.2
- </simpara>
- </listitem>
- </orderedlist>
- </listitem>
- <listitem>
- <simpara>
- 1.b
- </simpara>
- </listitem>
- </itemizedlist>
             </listitem>
             <listitem>
               <simpara>
                 2
- </simpara>
- <itemizedlist>
- <listitem>
- <simpara>
- 2.a
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- 2.b
- </simpara>
- <orderedlist>
- <listitem>
- <simpara>
- 2.b.1
- </simpara>
- </listitem>
- <listitem>
- <simpara>
- 2.b.2
- </simpara>
- <itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ 2.a
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ 2.b
+ <orderedlist>
                         <listitem>
                           <simpara>
- 2.b.2.a
+ 2.b.1
                           </simpara>
                         </listitem>
                         <listitem>
                           <simpara>
- 2.b.2.b
+ 2.b.2
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ 2.b.2.a
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ 2.b.2.b
+ </simpara>
+ </listitem>
+ </itemizedlist>
                           </simpara>
                         </listitem>
- </itemizedlist>
- </listitem>
- </orderedlist>
- </listitem>
- </itemizedlist>
+ </orderedlist>
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </simpara>
             </listitem>
           </orderedlist>
         </section>
@@ -1707,27 +1707,27 @@
 [h6 Heading 6]
 <!--quickbook-escape-postfix--></programlisting>
         <anchor id="quickbook.syntax.block.headings.heading_1"/>
- <bridgehead renderas="sect1">
+ <bridgehead renderas="sect1" id="quickbook.syntax.block.headings.heading_1-heading">
           <link linkend="quickbook.syntax.block.headings.heading_1">Heading 1</link>
         </bridgehead>
         <anchor id="quickbook.syntax.block.headings.heading_2"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="quickbook.syntax.block.headings.heading_2-heading">
           <link linkend="quickbook.syntax.block.headings.heading_2">Heading 2</link>
         </bridgehead>
         <anchor id="quickbook.syntax.block.headings.heading_3"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="quickbook.syntax.block.headings.heading_3-heading">
           <link linkend="quickbook.syntax.block.headings.heading_3">Heading 3</link>
         </bridgehead>
         <anchor id="quickbook.syntax.block.headings.heading_4"/>
- <bridgehead renderas="sect4">
+ <bridgehead renderas="sect4" id="quickbook.syntax.block.headings.heading_4-heading">
           <link linkend="quickbook.syntax.block.headings.heading_4">Heading 4</link>
         </bridgehead>
         <anchor id="quickbook.syntax.block.headings.heading_5"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.headings.heading_5-heading">
           <link linkend="quickbook.syntax.block.headings.heading_5">Heading 5</link>
         </bridgehead>
         <anchor id="quickbook.syntax.block.headings.heading_6"/>
- <bridgehead renderas="sect6">
+ <bridgehead renderas="sect6" id="quickbook.syntax.block.headings.heading_6-heading">
           <link linkend="quickbook.syntax.block.headings.heading_6">Heading 6</link>
         </bridgehead>
         <para>
@@ -1943,7 +1943,7 @@
                 </entry>
                 <entry>
                   <para>
- NO_FILENAME_MACRO_GENERATED_IN_DEBUG_MODE
+ quickbook-manual.quickbook
                   </para>
                 </entry>
               </row>
@@ -1972,7 +1972,7 @@
 ]
 <!--quickbook-escape-postfix--></programlisting>
         <anchor id="quickbook.syntax.block.templates.template_identifier"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.template_identifier-heading">
           <link linkend="quickbook.syntax.block.templates.template_identifier">Template
           Identifier</link>
         </bridgehead>
@@ -1994,7 +1994,7 @@
           </listitem>
         </itemizedlist>
         <anchor id="quickbook.syntax.block.templates.formal_template_arguments"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.formal_template_arguments-heading">
           <link linkend="quickbook.syntax.block.templates.formal_template_arguments">Formal
           Template Arguments</link>
         </bridgehead>
@@ -2014,7 +2014,7 @@
           of the template call.
         </para>
         <anchor id="quickbook.syntax.block.templates.template_body"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.template_body-heading">
           <link linkend="quickbook.syntax.block.templates.template_body">Template
           Body</link>
         </bridgehead>
@@ -2041,7 +2041,7 @@
           block level elements are not allowed in phrase templates.
         </para>
         <anchor id="quickbook.syntax.block.templates.template_expansion"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.template_expansion-heading">
           <link linkend="quickbook.syntax.block.templates.template_expansion">Template
           Expansion</link>
         </bridgehead>
@@ -2084,7 +2084,7 @@
           by the close parenthesis.
         </para>
         <anchor id="quickbook.syntax.block.templates.nullary_templates"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.nullary_templates-heading">
           <link linkend="quickbook.syntax.block.templates.nullary_templates">Nullary
           Templates</link>
         </bridgehead>
@@ -2177,7 +2177,7 @@
           brackets, though.
         </para>
         <anchor id="quickbook.syntax.block.templates.simple_arguments"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.simple_arguments-heading">
           <link linkend="quickbook.syntax.block.templates.simple_arguments">Simple
           Arguments</link>
         </bridgehead>
@@ -2252,7 +2252,7 @@
           what do you think man?
         </para>
         <anchor id="quickbook.syntax.block.templates.punctuation_templates"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.templates.punctuation_templates-heading">
           <link linkend="quickbook.syntax.block.templates.punctuation_templates">Punctuation
           Templates</link>
         </bridgehead>
@@ -2656,7 +2656,7 @@
           QuickBook's import facility provides a nice solution.
         </para>
         <anchor id="quickbook.syntax.block.import.example"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.import.example-heading">
           <link linkend="quickbook.syntax.block.import.example">Example</link>
         </bridgehead>
         <para>
@@ -2734,7 +2734,7 @@
           Some trailing text here
         </para>
         <anchor id="quickbook.syntax.block.import.code_snippet_markup"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.import.code_snippet_markup-heading">
           <link linkend="quickbook.syntax.block.import.code_snippet_markup">Code
           Snippet Markup</link>
         </bridgehead>
@@ -2756,7 +2756,7 @@
           This too will not be visible in quickbook.
         </para>
         <anchor id="quickbook.syntax.block.import.special_comments"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.import.special_comments-heading">
           <link linkend="quickbook.syntax.block.import.special_comments">Special
           Comments</link>
         </bridgehead>
@@ -2779,7 +2779,7 @@
           initial slash-star-tick and the final star-slash shall be ignored.
         </para>
         <anchor id="quickbook.syntax.block.import.callouts"/>
- <bridgehead renderas="sect5">
+ <bridgehead renderas="sect5" id="quickbook.syntax.block.import.callouts-heading">
           <link linkend="quickbook.syntax.block.import.callouts">Callouts</link>
         </bridgehead>
         <para>
@@ -3147,7 +3147,7 @@
   <section id="quickbook.faq">
     <title><link linkend="quickbook.faq">Frequently Asked Questions</link></title>
     <anchor id="quickbook.faq.can_i_use_quickbook_for_non_boost_documentation_"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="quickbook.faq.can_i_use_quickbook_for_non_boost_documentation_-heading">
       <link linkend="quickbook.faq.can_i_use_quickbook_for_non_boost_documentation_">Can
       I use QuickBook for non-Boost documentation?</link>
     </bridgehead>
@@ -3178,8 +3178,8 @@
     :
         my_doc
     :
- &lt;xsl:param&gt;boost.image.src<literal>images/my_project_logo.png
- &lt;xsl:param&gt;boost.image.alt</literal>&quot;\&quot;My Project\&quot;&quot;
+ &lt;xsl:param&gt;boost.image.src=images/my_project_logo.png
+ &lt;xsl:param&gt;boost.image.alt=&quot;\&quot;My Project\&quot;&quot;
         &lt;xsl:param&gt;boost.image.w=100
         &lt;xsl:param&gt;boost.image.h=50
         &lt;xsl:param&gt;nav.layout=none

Modified: branches/release/tools/quickbook/test/quickbook-testing.jam
==============================================================================
--- branches/release/tools/quickbook/test/quickbook-testing.jam (original)
+++ branches/release/tools/quickbook/test/quickbook-testing.jam 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -17,6 +17,8 @@
 
 feature.feature quickbook-testing.quickbook-command : : free dependency ;
 feature.feature <quickbook-test-define> : : free ;
+feature.feature <quickbook-test-include> : : free path ;
+feature.feature <quickbook-xinclude-base> : : free ;
 
 type.register QUICKBOOK_INPUT : quickbook ;
 type.register QUICKBOOK_OUTPUT ;
@@ -24,8 +26,6 @@
 generators.register-standard quickbook-testing.process-quickbook : QUICKBOOK_INPUT : QUICKBOOK_OUTPUT ;
 
 ################################################################################
-exe line-compare-tool : src/text_diff.cpp ;
-
 #
 # quickbook-test - generates a test for quickbook itself. A quickbook-test is
 # actually made up of two tests:
@@ -43,6 +43,8 @@
 
     local project = [ project.current ] ;
 
+ local boost-root = [ modules.peek : BOOST_ROOT ] ;
+
     local t =
         [ targets.create-typed-target QUICKBOOK_OUTPUT
             : $(project)
@@ -50,13 +52,13 @@
             : $(input)
             : $(requirements)
                 <location-prefix>$(target-name).test
- <quickbook-testing.quickbook-command>../src//quickbook
+ <quickbook-testing.quickbook-command>$(boost-root)/tools/quickbook/src//quickbook
         ]
 
         [ targets.create-typed-target RUN
             : $(project)
             : $(target-name)
- : .//line-compare-tool
+ : $(boost-root)/tools/quickbook/test/src//line-compare-tool
             : $(requirements)
                 <location-prefix>$(target-name).test
                 <testing.input-file>$(reference-output)
@@ -75,14 +77,42 @@
     input ?= $(target-name).quickbook ;
 
     local project = [ project.current ] ;
- requirements += <testing.arg>$(input:J=" ") ;
+
+ local boost-root = [ modules.peek : BOOST_ROOT ] ;
 
     local t =
         [ targets.create-typed-target RUN_FAIL
             : $(project)
             : $(target-name)
- : ../src//quickbook
+ : $(boost-root)/tools/quickbook/src//quickbook
+ : $(requirements)
+ <testing.input-file>$(input)
+ <preserve-test-targets>on
+ <dependency>$(input)
+ ]
+ ;
+
+ modules.poke testing : .all-tests : \$\(all-tests\) $(t) ;
+
+ return $(t) ;
+}
+
+rule quickbook-error-test ( target-name : input ? : requirements * )
+{
+ input ?= $(target-name).quickbook ;
+
+ local project = [ project.current ] ;
+
+ local boost-root = [ modules.peek : BOOST_ROOT ] ;
+
+ local t =
+ [ targets.create-typed-target RUN
+ : $(project)
+ : $(target-name)
+ : $(boost-root)/tools/quickbook/src//quickbook
             : $(requirements)
+ <testing.input-file>$(input)
+ <testing.arg>--expect-errors
               <preserve-test-targets>on
               <dependency>$(input)
         ]
@@ -96,6 +126,8 @@
 ################################################################################
 toolset.flags quickbook-testing.process-quickbook quickbook-command <quickbook-testing.quickbook-command> ;
 toolset.flags quickbook-testing.process-quickbook QB-DEFINES <quickbook-test-define> ;
+toolset.flags quickbook-testing.process-quickbook XINCLUDE <quickbook-xinclude-base> ;
+toolset.flags quickbook-testing.process-quickbook INCLUDES <quickbook-test-include> ;
 
 rule process-quickbook ( target : source : properties * )
 {
@@ -104,6 +136,6 @@
 
 actions process-quickbook bind quickbook-command
 {
- $(quickbook-command) $(>) --output-file=$(<) --debug -D"$(QB-DEFINES)"
+ $(quickbook-command) $(>) --output-file=$(<) --debug -D"$(QB-DEFINES)" -I"$(INCLUDES)" --xinclude-base="$(XINCLUDE)"
 }
 

Modified: branches/release/tools/quickbook/test/simple_markup.gold
==============================================================================
--- branches/release/tools/quickbook/test/simple_markup.gold (original)
+++ branches/release/tools/quickbook/test/simple_markup.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -10,10 +10,41 @@
       role="underline">underline</emphasis> <literal>teletype</literal>
     </para>
     <para>
- /all<emphasis>italic</emphasis> * not bold*
+ <emphasis>/italic/</emphasis> <emphasis role="bold">*bold*</emphasis> <emphasis
+ role="underline">_underline_</emphasis> <literal>=teletype=</literal>
+ </para>
+ <para>
+ not__underlined__hopefully
+ </para>
+ <para>
+ (<emphasis role="bold">bold</emphasis>) <emphasis role="underline">und/er/lined</emphasis>
+ </para>
+ <para>
+ <emphasis>all/italic</emphasis> * not bold*
     </para>
     <para>
       /not italic <ulink url="http://www.boost.org/"><emphasis role="bold">bold</emphasis></ulink>
     </para>
+ <para>
+ not_underlined_
+ </para>
+ <para>
+ _Should not underline escaped markup_. _or this escaped_ markup form.
+ </para>
+ <para>
+ <literal>Matti Meik&#xE4;l&#xE4;inen</literal>
+ </para>
+ <para>
+ <literal>replaced</literal>
+ </para>
+ <para>
+ <emphasis role="underline">replaced</emphasis>
+ </para>
+ <para>
+ <literal>_macro_</literal>
+ </para>
+ <para>
+ /not italic/
+ </para>
   </section>
 </article>

Modified: branches/release/tools/quickbook/test/simple_markup.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/simple_markup.quickbook (original)
+++ branches/release/tools/quickbook/test/simple_markup.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,12 +2,35 @@
 [quickbook 1.5]
 ]
 
+[def _macro_ replaced]
+
 [section Simple Markup]
 
 /italic/ *bold* _underline_ =teletype=
 
+//italic// **bold** __underline__ ==teletype==
+
+not__underlined__hopefully
+
+(*bold*) _und/er/lined_
+
 /all/italic/ * not bold*
 
 /not italic [@http://www.boost.org/ *bold*]
 
+not_underlined_
+
+_Should not underline '''escaped''' markup_.
+_or this '''escaped_ markup''' form.
+
+=Matti Meik\u00E4l\u00E4inen=
+
+=_macro_=
+
+__macro__
+
+=_mac\ ro_=
+
+/not italic\/
+
 [endsect]
\ No newline at end of file

Copied: branches/release/tools/quickbook/test/snippets/pass_thru.cpp (from r70210, /trunk/tools/quickbook/test/snippets/pass_thru.cpp)
==============================================================================
--- /trunk/tools/quickbook/test/snippets/pass_thru.cpp (original)
+++ branches/release/tools/quickbook/test/snippets/pass_thru.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -1,3 +1,11 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+
 //[foo_cpp
 struct Foo{
 

Copied: branches/release/tools/quickbook/test/snippets/pass_thru.py (from r70210, /trunk/tools/quickbook/test/snippets/pass_thru.py)
==============================================================================
--- /trunk/tools/quickbook/test/snippets/pass_thru.py (original)
+++ branches/release/tools/quickbook/test/snippets/pass_thru.py 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -1,3 +1,9 @@
+# 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)
+
 #[foo_py
 def foo:
     #=print('foo')

Copied: branches/release/tools/quickbook/test/src/Jamfile.v2 (from r69832, /trunk/tools/quickbook/test/src/Jamfile.v2)
==============================================================================
--- /trunk/tools/quickbook/test/src/Jamfile.v2 (original)
+++ branches/release/tools/quickbook/test/src/Jamfile.v2 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -1 +1,9 @@
+#
+# Copyright (c) 2011 Daniel James
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
 exe line-compare-tool : text_diff.cpp ;

Modified: branches/release/tools/quickbook/test/table_1_5.gold
==============================================================================
--- branches/release/tools/quickbook/test/table_1_5.gold (original)
+++ branches/release/tools/quickbook/test/table_1_5.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -233,5 +233,94 @@
         </tbody>
       </tgroup>
     </table>
+ <table frame="all" id="table_1_5.section1.nested_tables">
+ <title>Nested Tables</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry>
+ <para>
+ Header 1
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Header 2
+ </para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <table frame="all" id="table_1_5.section1.inner_table">
+ <title>Inner Table</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>
+ <para>
+ 1.1
+ </para>
+ </entry>
+ <entry>
+ <para>
+ 1.2
+ </para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ 2.1
+ </para>
+ </entry>
+ <entry>
+ <para>
+ 2.2
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ Something.
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <anchor id="id1"/>
+ <table frame="all" id="table_1_5.section1.table_with_anchors">
+ <title>Table with anchors</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry>
+ <para>
+ <anchor id="id2"/> a<anchor id="id3"/>
+ </para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ b
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
   </section>
 </article>

Modified: branches/release/tools/quickbook/test/table_1_5.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/table_1_5.quickbook (original)
+++ branches/release/tools/quickbook/test/table_1_5.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -69,4 +69,33 @@
   ]
 ]
 
-[endsect]
\ No newline at end of file
+[table Nested Tables
+ [
+ [
+ Header 1
+ ]
+ [
+ Header 2
+ ]
+ ]
+ [
+ [
+ [table Inner Table
+ [[1.1][1.2]]
+ [[2.1][2.2]]
+ ]
+ ]
+ ]
+ [
+ [
+ Something.
+ ]
+ ]
+]
+
+[#id1]
+[table Table with anchors
+[[[#id2]a[#id3]]][[b]]
+]
+
+[endsect]

Modified: branches/release/tools/quickbook/test/template-section.gold
==============================================================================
--- branches/release/tools/quickbook/test/template-section.gold (original)
+++ branches/release/tools/quickbook/test/template-section.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -12,7 +12,7 @@
       Hello.
     </para>
     <anchor id="section_in_a_template.test.just_to_test_id_generation"/>
- <bridgehead renderas="sect3">
+ <bridgehead renderas="sect3" id="section_in_a_template.test.just_to_test_id_generation-heading">
       <link linkend="section_in_a_template.test.just_to_test_id_generation">Just
       to test id generation</link>
     </bridgehead>

Modified: branches/release/tools/quickbook/test/unicode-escape.gold
==============================================================================
--- branches/release/tools/quickbook/test/unicode-escape.gold (original)
+++ branches/release/tools/quickbook/test/unicode-escape.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,7 +2,7 @@
 <!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
 <article id="utf_8_test" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>UTF-8 test</title> <anchor id="utf_8_test.i__xf1_t__xeb_rn__xe2_ti__xf4_n__xe0_liz__xe6_ti__xf8_n"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="utf_8_test.i__xf1_t__xeb_rn__xe2_ti__xf4_n__xe0_liz__xe6_ti__xf8_n-heading">
     <link linkend="utf_8_test.i__xf1_t__xeb_rn__xe2_ti__xf4_n__xe0_liz__xe6_ti__xf8_n">I&#xF1;t&#xEB;rn&#xE2;ti&#xF4;n&#xE0;liz&#xE6;ti&#xF8;n</link>
   </bridgehead>
   <itemizedlist>

Copied: branches/release/tools/quickbook/test/unit/Jamfile.v2 (from r70210, /trunk/tools/quickbook/test/unit/Jamfile.v2)
==============================================================================
--- /trunk/tools/quickbook/test/unit/Jamfile.v2 (original)
+++ branches/release/tools/quickbook/test/unit/Jamfile.v2 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -1,3 +1,11 @@
+#
+# Copyright (c) 2011 Daniel James
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
 import testing ;
 
 project quickbook-unit-tests
@@ -6,3 +14,4 @@
 
 run values_test.cpp ../../src/values.cpp ;
 run post_process_test.cpp ../../src/post_process.cpp ;
+run iterator_tests.cpp ../../src/values.cpp ;

Copied: branches/release/tools/quickbook/test/unit/values_test.cpp (from r70210, /trunk/tools/quickbook/test/unit/values_test.cpp)
==============================================================================
--- /trunk/tools/quickbook/test/unit/values_test.cpp (original)
+++ branches/release/tools/quickbook/test/unit/values_test.cpp 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -11,6 +11,7 @@
 
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/range/algorithm/equal.hpp>
+#include <vector>
 #include "values.hpp"
 
 void empty_tests()
@@ -39,7 +40,7 @@
     b.insert(quickbook::bbk_value("d", 8));
     b.sort_list();
     
- quickbook::value_consumer c = b.get();
+ quickbook::value_consumer c = b.release();
     BOOST_TEST(c.check(2)); BOOST_TEST_EQ(c.consume(2).get_boostbook(), "b");
     BOOST_TEST(c.check(5)); c.consume(5);
     BOOST_TEST(c.check(8)); c.consume(8);
@@ -62,8 +63,8 @@
 
     list2.insert(quickbook::bbk_value("c", 3));
 
- quickbook::value_consumer l1 = list1.get(); list1.reset();
- quickbook::value_consumer l2 = list2.get(); list2.reset();
+ quickbook::value_consumer l1 = list1.release();
+ quickbook::value_consumer l2 = list2.release();
 
     BOOST_TEST(l1.check(10));
     BOOST_TEST_EQ(l1.consume(10).get_boostbook(), "b");
@@ -80,18 +81,19 @@
 
 void store_test1()
 {
- quickbook::value q;
+ quickbook::stored_value q;
     
     {
         std::string src = "Hello";
- q = quickbook::qbk_value(
+ quickbook::value q1 = quickbook::qbk_value(
             quickbook::iterator(src.begin()),
             quickbook::iterator(src.end()),
             5);
 
+ BOOST_TEST_EQ(q1.get_quickbook(), "Hello");
+ q = q1;
         BOOST_TEST_EQ(q.get_quickbook(), "Hello");
- q.store();
- BOOST_TEST_EQ(q.get_quickbook(), "Hello");
+ BOOST_TEST_EQ(q1.get_quickbook(), "Hello");
     }
 
     BOOST_TEST_EQ(q.get_quickbook(), "Hello");
@@ -109,7 +111,7 @@
 
 void store_test2()
 {
- quickbook::value q;
+ quickbook::stored_value q;
     
     {
         quickbook::value_builder list1;
@@ -120,15 +122,43 @@
             5));
         list1.insert(quickbook::bbk_value("World", 10));
         
- q = list1.get();
+ quickbook::value q2 = list1.release();
 
+ store_test2_check(q2);
+ q = q2;
         store_test2_check(q);
- q.store();
- store_test2_check(q);
+ store_test2_check(q2);
     }
     store_test2_check(q);
 }
 
+void equality_tests()
+{
+ std::vector<quickbook::value> distinct_values;
+
+ quickbook::value_builder builder;
+ quickbook::value nil;
+
+ // 0: nil
+ distinct_values.push_back(nil);
+
+ // 1: []
+ distinct_values.push_back(builder.release());
+
+ // 2: [nil]
+ builder.insert(nil);
+ distinct_values.push_back(builder.release());
+
+ for(int i = 0; i < distinct_values.size(); ++i)
+ for(int j = 0; j < distinct_values.size(); ++j)
+ if ((i == j) != (distinct_values[i] == distinct_values[j]))
+ {
+ BOOST_ERROR("Value mismatch.");
+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
+ << "\tat " << i << ", " << j << std::endl;
+ }
+}
+
 int main()
 {
     empty_tests();
@@ -137,6 +167,7 @@
     multiple_list_test();
     store_test1();
     store_test2();
+ equality_tests();
 
     return boost::report_errors();
 }

Modified: branches/release/tools/quickbook/test/utf-8-bom.gold
==============================================================================
--- branches/release/tools/quickbook/test/utf-8-bom.gold (original)
+++ branches/release/tools/quickbook/test/utf-8-bom.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,7 +2,7 @@
 <!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
 <article id="utf_8_test" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>UTF-8 test</title> <anchor id="utf_8_test.i__t__rn__ti__n__liz__ti__n"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="utf_8_test.i__t__rn__ti__n__liz__ti__n-heading">
     <link linkend="utf_8_test.i__t__rn__ti__n__liz__ti__n">Iñtërnâtiônàlizætiøn</link>
   </bridgehead>
   <itemizedlist>

Modified: branches/release/tools/quickbook/test/utf-8.gold
==============================================================================
--- branches/release/tools/quickbook/test/utf-8.gold (original)
+++ branches/release/tools/quickbook/test/utf-8.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,7 +2,7 @@
 <!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
 <article id="utf_8_test" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>UTF-8 test</title> <anchor id="utf_8_test.i__t__rn__ti__n__liz__ti__n"/>
- <bridgehead renderas="sect2">
+ <bridgehead renderas="sect2" id="utf_8_test.i__t__rn__ti__n__liz__ti__n-heading">
     <link linkend="utf_8_test.i__t__rn__ti__n__liz__ti__n">Iñtërnâtiônàlizætiøn</link>
   </bridgehead>
   <itemizedlist>

Modified: branches/release/tools/quickbook/test/variablelist.gold
==============================================================================
--- branches/release/tools/quickbook/test/variablelist.gold (original)
+++ branches/release/tools/quickbook/test/variablelist.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -92,4 +92,16 @@
       </listitem>
     </varlistentry>
   </variablelist>
+ <anchor id="id1"/>
+ <variablelist>
+ <title>Variable List with anchors</title>
+ <varlistentry>
+ <term><anchor id="id2"/> a<anchor id="id3"/> </term>
+ <listitem>
+ <para>
+ <anchor id="id4"/> b<anchor id="id5"/>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
 </article>

Modified: branches/release/tools/quickbook/test/variablelist.quickbook
==============================================================================
--- branches/release/tools/quickbook/test/variablelist.quickbook (original)
+++ branches/release/tools/quickbook/test/variablelist.quickbook 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -19,4 +19,13 @@
     [[a][b][c][d]]
     [[a][b][c][d][e]]
     [[a][b]]
-]
\ No newline at end of file
+]
+
+[#id1]
+[variablelist Variable List with anchors
+ [
+ [[#id2]a[#id3]]
+ [[#id4]b[#id5]]
+ ]
+]
+

Modified: branches/release/tools/quickbook/test/xinclude.gold
==============================================================================
--- branches/release/tools/quickbook/test/xinclude.gold (original)
+++ branches/release/tools/quickbook/test/xinclude.gold 2011-04-03 07:50:51 EDT (Sun, 03 Apr 2011)
@@ -2,5 +2,5 @@
 <!DOCTYPE article PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
 <article id="include" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $" xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>Include</title>
- <xi:include href="../../../../../../../../../tools/quickbook/test/stub.xml" />
+ <xi:include href="../test/stub.xml" />
 </article>


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