$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r57777 - in branches/quickbook-1.5-spirit2: . detail
From: daniel_james_at_[hidden]
Date: 2009-11-18 18:20:11
Author: danieljames
Date: 2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
New Revision: 57777
URL: http://svn.boost.org/trac/boost/changeset/57777
Log:
Use Spirit 2 for the main parser.
Text files modified: 
   branches/quickbook-1.5-spirit2/block.hpp                   |   225 +++++++-------                          
   branches/quickbook-1.5-spirit2/detail/actions.cpp          |   165 +++++-----                              
   branches/quickbook-1.5-spirit2/detail/actions.hpp          |   114 +++----                                 
   branches/quickbook-1.5-spirit2/detail/block.cpp            |     7                                         
   branches/quickbook-1.5-spirit2/detail/doc_info.cpp         |     6                                         
   branches/quickbook-1.5-spirit2/detail/phrase.cpp           |    10                                         
   branches/quickbook-1.5-spirit2/detail/quickbook.cpp        |    24 +                                       
   branches/quickbook-1.5-spirit2/detail/syntax_highlight.cpp |     9                                         
   branches/quickbook-1.5-spirit2/detail/template_stack.cpp   |    10                                         
   branches/quickbook-1.5-spirit2/detail/template_stack.hpp   |    52 ++-                                     
   branches/quickbook-1.5-spirit2/doc_info.hpp                |   100 +++---                                  
   branches/quickbook-1.5-spirit2/grammars.hpp                |   183 ++++-------                             
   branches/quickbook-1.5-spirit2/phrase.hpp                  |   364 +++++++++++------------                 
   branches/quickbook-1.5-spirit2/syntax_highlight.hpp        |   598 +++++++++++++++++++-------------------- 
   14 files changed, 892 insertions(+), 975 deletions(-)
Modified: branches/quickbook-1.5-spirit2/block.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/block.hpp	(original)
+++ branches/quickbook-1.5-spirit2/block.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -10,34 +10,33 @@
 #if !defined(BOOST_SPIRIT_QUICKBOOK_BLOCK_HPP)
 #define BOOST_SPIRIT_QUICKBOOK_BLOCK_HPP
 
+#include "./grammars.hpp"
 #include "./detail/quickbook.hpp"
 #include "./detail/utils.hpp"
-#include "./grammars.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_assign_actor.hpp>
-#include <boost/spirit/include/classic_if.hpp>
-#include <boost/spirit/include/classic_symbols.hpp>
+#include "./parse_utils.hpp"
+#include <boost/spirit/include/qi_core.hpp>
+#include <boost/spirit/include/qi_eol.hpp>
+#include <boost/spirit/include/qi_eps.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
 
 namespace quickbook
 {
     using namespace boost::spirit;
+    namespace ph = boost::phoenix;
 
-    template <typename Actions, bool skip_initial_spaces>
-    template <typename Scanner>
-    block_grammar<Actions, skip_initial_spaces>::
-        definition<Scanner>::definition(block_grammar const& self)
-        : no_eols(true)
-        , common(self.actions, no_eols)
+    template <typename Iterator, typename Actions, bool skip_initial_spaces>
+    block_grammar<Iterator, Actions, skip_initial_spaces>::block_grammar(Actions& actions_)
+        : block_grammar::base_type(start_, "block")
+        , actions(actions_)
+        , no_eols(true)
+        , common(actions, no_eols)
     {
-        using detail::var;
-        Actions& actions = self.actions;
-
         if (skip_initial_spaces)
         {
             start_ =
-                *(classic::space_p | comment) >> blocks >> blank
+                *(qi::space | comment) >> blocks >> blank
                 ;
         }
         else
@@ -46,7 +45,7 @@
                 blocks >> blank
                 ;
         }
-        
+
         blocks =
            +(   block_markup
             |   code
@@ -59,40 +58,38 @@
             ;
 
         space =
-            *(classic::space_p | comment)
+            *(qi::space | comment)
             ;
 
         blank =
-            *(classic::blank_p | comment)
+            *(qi::blank | comment)
             ;
 
-        eol = blank >> classic::eol_p
+        eol = blank >> qi::eol
             ;
 
         phrase_end =
             ']' |
-            classic::if_p(var(no_eols))
-            [
+            qi::eps(ph::ref(no_eols)) >>
                 eol >> eol                      // Make sure that we don't go
-            ]                                   // past a single block, except
+                                                // past a single block, except
             ;                                   // when preformatted.
 
         hard_space =
-            (classic::eps_p - (classic::alnum_p | '_')) >> space
-                                                // must not be preceded by
-            ;                                   // alpha-numeric or underscore
+            (qi::eps - (qi::alnum | '_')) >> space  // must not be preceded by
+            ;                                      // alpha-numeric or underscore
 
         comment =
-            "[/" >> *(dummy_block | (classic::anychar_p - ']')) >> ']'
+            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
 
         dummy_block =
-            '[' >> *(dummy_block | (classic::anychar_p - ']')) >> ']'
+            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
 
         hr =
-            classic::str_p("----")
-            >> *(classic::anychar_p - eol)
+            qi::lit("----")
+            >> *(qi::char_ - eol)
             >> +eol
             ;
 
@@ -114,7 +111,7 @@
                 |   template_
                 )
             >>  (   (space >> ']' >> +eol)
-                |   classic::eps_p              [actions.error]
+                |   qi::raw[qi::eps]            [actions.error]
                 )
             ;
         
@@ -122,46 +119,46 @@
                 ':'
             >>
                 (
-                    classic::if_p(qbk_since(105u))
-                                                [space]
-                >>  (+(classic::alnum_p | '_')) [classic::assign_a(actions.element_id)]
-                |   classic::eps_p              [actions.element_id_warning]
-                                                [classic::assign_a(actions.element_id)]
+                    (
+                        qi::eps(ph::ref(qbk_version_n) >= 105u) >> space
+                    |   qi::eps(ph::ref(qbk_version_n) < 105u)
+                    )
+                >>  qi::raw[+(qi::alnum | '_')] [ph::ref(actions.element_id) = as_string(qi::_1)]
+                |   qi::raw[qi::eps]            [actions.element_id_warning]
+                                                [ph::clear(ph::ref(actions.element_id))]
                 )
-            | classic::eps_p                    [classic::assign_a(actions.element_id)]
+            | qi::eps                           [ph::clear(ph::ref(actions.element_id))]
             ;
         
         element_id_1_5 =
-                classic::if_p(qbk_since(105u)) [
-                    element_id
-                ]
-                .else_p [
-                    classic::eps_p              [classic::assign_a(actions.element_id)]
-                ]
+                qi::eps(ph::ref(qbk_version_n) >= 105u) >> element_id
+            |
+                qi::eps(ph::ref(qbk_version_n) < 105u)
+                                                [ph::clear(ph::ref(actions.element_id))]
                 ;
 
         begin_section =
                "section"
             >> hard_space
             >> element_id
-            >> phrase                           [actions.begin_section]
+            >> qi::raw[phrase]                  [actions.begin_section]
             ;
 
         end_section =
-            classic::str_p("endsect")           [actions.end_section]
+            qi::raw["endsect"]                  [actions.end_section]
             ;
 
         headings =
             h1 | h2 | h3 | h4 | h5 | h6 | h
             ;
 
-        h = "heading" >> hard_space >> phrase   [actions.h];
-        h1 = "h1" >> hard_space >> phrase       [actions.h1];
-        h2 = "h2" >> hard_space >> phrase       [actions.h2];
-        h3 = "h3" >> hard_space >> phrase       [actions.h3];
-        h4 = "h4" >> hard_space >> phrase       [actions.h4];
-        h5 = "h5" >> hard_space >> phrase       [actions.h5];
-        h6 = "h6" >> hard_space >> phrase       [actions.h6];
+        h = "heading" >> hard_space >> qi::raw[phrase]   [actions.h];
+        h1 = "h1" >> hard_space >> qi::raw[phrase]       [actions.h1];
+        h2 = "h2" >> hard_space >> qi::raw[phrase]       [actions.h2];
+        h3 = "h3" >> hard_space >> qi::raw[phrase]       [actions.h3];
+        h4 = "h4" >> hard_space >> qi::raw[phrase]       [actions.h4];
+        h5 = "h5" >> hard_space >> qi::raw[phrase]       [actions.h5];
+        h6 = "h6" >> hard_space >> qi::raw[phrase]       [actions.h6];
 
         static const bool true_ = true;
         static const bool false_ = false;
@@ -176,7 +173,7 @@
         blurb =
             "blurb" >> hard_space
             >> inside_paragraph                 [actions.blurb]
-            >> classic::eps_p
+            >> qi::eps
             ;
 
         blockquote =
@@ -202,193 +199,197 @@
             ;
 
         preformatted =
-            "pre" >> hard_space                 [classic::assign_a(no_eols, false_)]
-            >> !eol >> phrase                   [actions.preformatted]
-            >> classic::eps_p                   [classic::assign_a(no_eols, true_)]
+            "pre" >> hard_space                 [ph::ref(no_eols) = false_]
+            >> -eol >> phrase                   [actions.preformatted]
+            >> qi::eps                          [ph::ref(no_eols) = true_]
             ;
 
         macro_identifier =
-            +(classic::anychar_p - (classic::space_p | ']'))
+            +(qi::char_ - (qi::space | ']'))
             ;
 
         def_macro =
             "def" >> hard_space
-            >> macro_identifier                 [actions.macro_identifier]
+            >> qi::raw[macro_identifier]        [actions.macro_identifier]
             >> blank >> phrase                  [actions.macro_definition]
             ;
 
         identifier =
-            (classic::alpha_p | '_') >> *(classic::alnum_p | '_')
+            (qi::alpha | '_') >> *(qi::alnum | '_')
             ;
 
         template_id =
-            identifier | (classic::punct_p - (classic::ch_p('[') | ']'))
+            identifier | (qi::punct - (qi::char_('[') | ']'))
             ;
 
         template_ =
             "template"
-            >> hard_space >> template_id        [classic::push_back_a(actions.template_info)]
+            >> hard_space >> qi::raw[template_id]
+                                                [ph::push_back(ph::ref(actions.template_info), as_string(qi::_1))]
             >>
-            !(
+            -(
                 space >> '['
                 >> *(
-                        space >> template_id    [classic::push_back_a(actions.template_info)]
+                        space >> qi::raw[template_id]
+                                                [ph::push_back(ph::ref(actions.template_info), as_string(qi::_1))]
                     )
                 >> space >> ']'
             )
-            >> template_body                    [actions.template_body]
+            >> qi::raw[template_body]           [actions.template_body]
             ;
 
         template_body =
-           *(('[' >> template_body >> ']') | (classic::anychar_p - ']'))
-            >> space >> classic::eps_p(']')
+           *(('[' >> template_body >> ']') | (qi::char_ - ']'))
+            >> space >> &qi::lit(']')
             ;
 
         variablelist =
             "variablelist"
-            >>  (classic::eps_p(*classic::blank_p >> classic::eol_p) | hard_space)
-            >>  (*(classic::anychar_p - eol))   [classic::assign_a(actions.table_title)]
+            >>  (&(*qi::blank >> qi::eol) | hard_space)
+            >>  (*(qi::char_ - eol))            [ph::ref(actions.table_title) = as_string(qi::_1)]
             >>  +eol
             >>  *varlistentry
-            >>  classic::eps_p                  [actions.variablelist]
+            >>  qi::eps                         [actions.variablelist]
             ;
 
         varlistentry =
             space
-            >>  classic::ch_p('[')              [actions.start_varlistentry]
+            >>  qi::char_('[')                  [actions.start_varlistentry]
             >>
             (
                 (
                     varlistterm
                     >> +varlistitem
-                    >>  classic::ch_p(']')      [actions.end_varlistentry]
+                    >>  qi::char_(']')          [actions.end_varlistentry]
                     >>  space
                 )
-                | classic::eps_p                [actions.error]
+                | qi::raw[qi::eps]              [actions.error]
             )
             ;
 
         varlistterm =
             space
-            >>  classic::ch_p('[')              [actions.start_varlistterm]
+            >>  qi::char_('[')                  [actions.start_varlistterm]
             >>
             (
                 (
                     phrase
-                    >>  classic::ch_p(']')      [actions.end_varlistterm]
+                    >>  qi::char_(']')          [actions.end_varlistterm]
                     >>  space
                 )
-                | classic::eps_p                [actions.error]
+                | qi::raw[qi::eps]              [actions.error]
             )
             ;
 
         varlistitem =
             space
-            >>  classic::ch_p('[')              [actions.start_varlistitem]
+            >>  qi::char_('[')                  [actions.start_varlistitem]
             >>
             (
                 (
                     inside_paragraph
-                    >>  classic::ch_p(']')      [actions.end_varlistitem]
+                    >>  qi::char_(']')          [actions.end_varlistitem]
                     >>  space
                 )
-                | classic::eps_p                [actions.error]
+                | qi::raw[qi::eps]              [actions.error]
             )
             ;
 
         table =
             "table"
-            >>  (classic::eps_p(*classic::blank_p >> classic::eol_p) | hard_space)
+            >>  (&(*qi::blank >> qi::eol) | hard_space)
             >> element_id_1_5
-            >>  (classic::eps_p(*classic::blank_p >> classic::eol_p) | space)
-            >>  (*(classic::anychar_p - eol))   [classic::assign_a(actions.table_title)]
+            >>  (&(*qi::blank >> qi::eol) | space)
+            >>  (*(qi::char_ - eol))            [ph::ref(actions.table_title) = as_string(qi::_1)]
             >>  +eol
             >>  *table_row
-            >>  classic::eps_p                  [actions.table]
+            >>  qi::eps                         [actions.table]
             ;
 
         table_row =
             space
-            >>  classic::ch_p('[')              [actions.start_row]
+            >>  qi::char_('[')                  [actions.start_row]
             >>
             (
                 (
                     *table_cell
-                    >>  classic::ch_p(']')      [actions.end_row]
+                    >>  qi::char_(']')          [actions.end_row]
                     >>  space
                 )
-                | classic::eps_p                [actions.error]
+                | qi::raw[qi::eps]              [actions.error]
             )
             ;
 
         table_cell =
             space
-            >>  classic::ch_p('[')              [actions.start_cell]
+            >>  qi::char_('[')                  [actions.start_cell]
             >>
             (
                 (
                     inside_paragraph
-                    >>  classic::ch_p(']')      [actions.end_cell]
+                    >>  qi::char_(']')          [actions.end_cell]
                     >>  space
                 )
-                | classic::eps_p                [actions.error]
+                | qi::raw[qi::eps]              [actions.error]
             )
             ;
 
         xinclude =
                "xinclude"
             >> hard_space
-            >> (*(classic::anychar_p -
-                    phrase_end))                [actions.xinclude]
+            >> qi::raw[*(qi::char_ -
+                    phrase_end)]                [actions.xinclude]
             ;
 
         import =
                "import"
             >> hard_space
-            >> (*(classic::anychar_p -
-                    phrase_end))                [actions.import]
+            >> qi::raw[*(qi::char_ -
+                    phrase_end)]                [actions.import]
             ;
 
         include =
                "include"
             >> hard_space
             >>
-           !(
+           -(
                 ':'
-                >> (*((classic::alnum_p | '_') - classic::space_p))[classic::assign_a(actions.include_doc_id)]
+                >> qi::raw[*((qi::alnum | '_') - qi::space)]
+                                                [ph::ref(actions.include_doc_id) = as_string(qi::_1)]
                 >> space
             )
-            >> (*(classic::anychar_p -
-                    phrase_end))                [actions.include]
+            >> qi::raw[*(qi::char_ -
+                    phrase_end)]                [actions.include]
             ;
 
         code =
-            (
+            qi::raw[
                 code_line
                 >> *(*eol >> code_line)
-            )                                   [actions.code]
+            ]                                   [actions.code]
             >> +eol
             ;
 
         code_line =
-            ((classic::ch_p(' ') | '\t'))
-            >> *(classic::anychar_p - eol) >> eol
+            ((qi::char_(' ') | '\t'))
+            >> *(qi::char_ - eol) >> eol
             ;
 
         list =
-            classic::eps_p(classic::ch_p('*') | '#') >>
-           +(
-                (*classic::blank_p
-                >> (classic::ch_p('*') | '#'))  [actions.list_format]
-                >> *classic::blank_p
+            &(qi::char_('*') | '#') >>
+           +qi::raw[
+                qi::raw[*qi::blank
+                >> (qi::char_('*') | '#')]
+                                                [actions.list_format]
+                >> *qi::blank
                 >> list_item
-            )                                   [actions.list_item]
+            ]                                   [actions.list_item]
             ;
 
         list_item =
            *(   common
-            |   (classic::anychar_p -
-                    (   classic::eol_p >> *classic::blank_p >> classic::eps_p(classic::ch_p('*') | '#')
+            |   (qi::char_ -
+                    (   qi::eol >> *qi::blank >> &(qi::char_('*') | '#')
                     |   (eol >> eol)
                     )
                 )                               [actions.plain_char]
@@ -409,17 +410,17 @@
 
         paragraph =
            *(   common
-            |   (classic::anychar_p -           // Make sure we don't go past
+            |   (qi::char_ -                    // Make sure we don't go past
                     paragraph_end               // a single block.
                 )                               [actions.plain_char]
             )
-            >> (classic::eps_p('[') | +eol)
+            >> (&qi::lit('[') | +eol)
             ;
 
         phrase =
            *(   common
             |   comment
-            |   (classic::anychar_p -
+            |   (qi::char_ -
                     phrase_end)                 [actions.plain_char]
             )
             ;
Modified: branches/quickbook-1.5-spirit2/detail/actions.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/actions.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -13,6 +13,7 @@
 #include <boost/filesystem/convenience.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/lexical_cast.hpp>
+#include <boost/spirit/include/support_unused.hpp>
 #include "./quickbook.hpp"
 #include "./actions.hpp"
 #include "./utils.hpp"
@@ -44,30 +45,30 @@
     }
 
     // Handles line-breaks (DEPRECATED!!!)
-    void break_action::operator()(iterator first, iterator) const
+    void break_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        boost::spirit::classic::file_position const pos = first.get_position();
+        boost::spirit::classic::file_position const pos = x.begin().get_position();
         detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", "
             << "[br] and \\n are deprecated" << ".\n";
         phrase << break_mark;
     }
 
-    void error_action::operator()(iterator first, iterator /*last*/) const
+    void error_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        boost::spirit::classic::file_position const pos = first.get_position();
+        boost::spirit::classic::file_position const pos = x.begin().get_position();
         detail::outerr(pos.file,pos.line)
             << "Syntax Error near column " << pos.column << ".\n";
         ++error_count;
     }
 
-    void phrase_action::operator()(iterator first, iterator last) const
+    void phrase_action::operator()(unused_type, unused_type, unused_type) const
     {
         std::string str;
         phrase.swap(str);
         out << pre << str << post;
     }
 
-    void header_action::operator()(iterator first, iterator last) const
+    void header_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         std::string str;
         phrase.swap(str);
@@ -96,7 +97,7 @@
         }
     }
 
-    void generic_header_action::operator()(iterator first, iterator last) const
+    void generic_header_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         int level_ = section_level + 2;     // section_level is zero-based. We need to use a
                                             // 0ne-based heading which is one greater
@@ -119,35 +120,35 @@
             ;
     }
 
-    void simple_phrase_action::operator()(iterator first, iterator last) const
+    void simple_phrase_action::operator()(iterator_range const& x, unused_type, unused_type) const
     {
         out << pre;
-        std::string str(first, last);
-        if (std::string const* ptr = find(macro, str.c_str()))
+        if (std::string const* ptr = macro.find(x))
         {
             out << *ptr;
         }
         else
         {
+            iterator first = x.begin(), last = x.end();
             while (first != last)
                 detail::print_char(*first++, out.get());
         }
         out << post;
     }
 
-    void cond_phrase_action_pre::operator()(iterator first, iterator last) const
+    void cond_phrase_action_pre::operator()(iterator_range x, unused_type, unused_type) const
     {
-        std::string str(first, last);
-        conditions.push_back(find(macro, str.c_str()));
+        std::string str(x.begin(), x.end());
+        conditions.push_back(macro.find(str.c_str()));
         out.push(); // save the stream
     }
 
-    void cond_phrase_action_post::operator()(iterator first, iterator last) const
+    void cond_phrase_action_post::operator()(iterator_range x, unused_type, unused_type) const
     {
         bool symbol_found = conditions.back();
         conditions.pop_back();
 
-        if (first == last || !symbol_found)
+        if (x.begin() == x.end() || !symbol_found)
         {
             out.pop(); // restore the stream
         }
@@ -160,7 +161,7 @@
         }
     }
 
-    void list_action::operator()(iterator first, iterator last) const
+    void list_action::operator()(unused_type, unused_type, unused_type) const
     {
         BOOST_ASSERT(!list_marks.empty()); // there must be at least one item in the stack
         out << list_buffer.str();
@@ -178,9 +179,10 @@
         list_indent = -1; // reset
     }
 
-    void list_format_action::operator()(iterator first, iterator last) const
+    void list_format_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         int new_indent = 0;
+        iterator first = x.begin(), last = x.end();
         while (first != last && (*first == ' ' || *first == '\t'))
         {
             char mark = *first++;
@@ -251,16 +253,18 @@
         }
     }
 
-    void span::operator()(iterator first, iterator last) const
+    void span::operator()(iterator_range x, unused_type, unused_type) const
     {
+        iterator first = x.begin(), last = x.end();
         out << "<phrase role=\"" << name << "\">";
         while (first != last)
             detail::print_char(*first++, out.get());
         out << "</phrase>";
     }
 
-    void unexpected_char::operator()(iterator first, iterator last) const
+    void unexpected_char::operator()(iterator_range x, unused_type, unused_type) const
     {
+        iterator first = x.begin(), last = x.end();
         boost::spirit::classic::file_position const pos = first.get_position();
 
         detail::outwarn(pos.file, pos.line)
@@ -275,15 +279,16 @@
         out << "</phrase>";
     }
 
-    void anchor_action::operator()(iterator first, iterator last) const
+    void anchor_action::operator()(iterator_range x, unused_type, unused_type) const
     {
+        iterator first = x.begin(), last = x.end();
         out << "<anchor id=\"";
         while (first != last)
             detail::print_char(*first++, out.get());
         out << "\" />\n";
     }
 
-    void do_macro_action::operator()(std::string const& str) const
+    void do_macro_action::operator()(std::string const& str, unused_type, unused_type) const
     {
         if (str == quickbook_get_date)
         {
@@ -303,40 +308,40 @@
         }
     }
 
-    void space::operator()(char ch) const
+    void space::operator()(char ch, unused_type, unused_type) const
     {
-
         detail::print_space(ch, out.get());
     }
 
-    void space::operator()(iterator first, iterator last) const
+    void space::operator()(iterator_range x, unused_type, unused_type) const
     {
+        iterator first = x.begin(), last = x.end();
         while (first != last)
             detail::print_space(*first++, out.get());
     }
 
-    void pre_escape_back::operator()(iterator first, iterator last) const
+    void pre_escape_back::operator()(unused_type, unused_type, unused_type) const
     {
         escape_actions.phrase.push(); // save the stream
     }
 
-    void post_escape_back::operator()(iterator first, iterator last) const
+    void post_escape_back::operator()(unused_type, unused_type, unused_type) const
     {
         out << escape_actions.phrase.str();
         escape_actions.phrase.pop(); // restore the stream
     }
 
-    void code_action::operator()(iterator first, iterator last) const
+    void code_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         // preprocess the code section to remove the initial indentation
-        std::string program(first, last);
+        std::string program(x.begin(), x.end());
         detail::unindent(program);
         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());
+        first_.set_position(x.begin().get_position());
 
         std::string save;
         phrase.swap(save);
@@ -355,13 +360,13 @@
         out << "</programlisting>\n";
     }
 
-    void inline_code_action::operator()(iterator first, iterator last) const
+    void inline_code_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         std::string save;
         out.swap(save);
 
         // print the code with syntax coloring
-        std::string str = syntax_p(first, last);
+        std::string str = syntax_p(x.begin(), x.end());
 
         out.swap(save);
 
@@ -370,32 +375,32 @@
         out << "</code>";
     }
 
-    void raw_char_action::operator()(char ch) const
+    void raw_char_action::operator()(char ch, unused_type, unused_type) const
     {
         phrase << ch;
     }
 
-    void raw_char_action::operator()(iterator first, iterator /*last*/) const
+    void raw_char_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        phrase << *first;
+        phrase << *x.begin();
     }
 
-    void plain_char_action::operator()(char ch) const
+    void plain_char_action::operator()(char ch, unused_type, unused_type) const
     {
         detail::print_char(ch, phrase.get());
     }
 
-    void plain_char_action::operator()(iterator first, iterator /*last*/) const
+    void plain_char_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        detail::print_char(*first, phrase.get());
+        detail::print_char(*x.begin(), phrase.get());
     }
 
-    void attribute_action::operator()(iterator first, iterator last) const
+    void attribute_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        boost::spirit::classic::file_position const pos = first.get_position();
+        boost::spirit::classic::file_position const pos = x.begin().get_position();
 
         if (!attributes.insert(
-                attribute_map::value_type(attribute_name, std::string(first, last))
+                attribute_map::value_type(attribute_name, std::string(x.begin(), x.end()))
             ).second)
         {
             detail::outerr(pos.file,pos.line)
@@ -403,7 +408,7 @@
         }
     }
 
-    void image_action::operator()(iterator, iterator) const
+    void image_action::operator()(unused_type, unused_type, unused_type) const
     {
         fs::path const img_path(image_fileref);
         
@@ -507,13 +512,13 @@
         phrase << "</inlinemediaobject>";
     }
 
-    void macro_identifier_action::operator()(iterator first, iterator last) const
+    void macro_identifier_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        actions.macro_id.assign(first, last);
+        actions.macro_id.assign(x.begin(), x.end());
         actions.phrase.push(); // save the phrase
     }
 
-    void macro_definition_action::operator()(iterator first, iterator last) const
+    void macro_definition_action::operator()(unused_type, unused_type, unused_type) const
     {
         actions.macro.add(
             actions.macro_id.begin()
@@ -522,21 +527,21 @@
         actions.phrase.pop(); // restore the phrase
     }
 
-    void template_body_action::operator()(iterator first, iterator last) const
+    void template_body_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         BOOST_ASSERT(actions.template_info.size());
         if (actions.templates.find_top_scope(actions.template_info[0]))
         {
-            boost::spirit::classic::file_position const pos = first.get_position();
+            boost::spirit::classic::file_position const pos = x.begin().get_position();
             detail::outerr(pos.file,pos.line)
                 << "Template Redefinition: " << actions.template_info[0] << std::endl;
             ++actions.error_count;
         }
 
-        actions.template_info.push_back(std::string(first, last));
+        actions.template_info.push_back(std::string(x.begin(), x.end()));
         actions.templates.add(
             actions.template_info[0]
-          , template_symbol(actions.template_info, first.get_position()));
+          , template_symbol(actions.template_info, x.begin().get_position()));
         actions.template_info.clear();
     }
 
@@ -686,8 +691,8 @@
           , quickbook::actions& actions
         )
         {
-            simple_phrase_grammar<quickbook::actions> phrase_p(actions);
-            block_grammar<quickbook::actions, true> block_p(actions);
+            simple_phrase_grammar<iterator, quickbook::actions> phrase_p(actions);
+            block_grammar<iterator, quickbook::actions, false> block_p(actions);
 
             // How do we know if we are to parse the template as a block or
             // a phrase? We apply a simple heuristic: if the body starts with
@@ -713,7 +718,7 @@
                 iterator first(body.begin(), body.end(), actions.filename.native_file_string().c_str());
                 first.set_position(template_pos);
                 iterator last(body.end(), body.end());
-                r = boost::spirit::classic::parse(first, last, phrase_p).full;
+                r = boost::spirit::qi::parse(first, last, phrase_p) && first == last;
                 actions.phrase.swap(result);
             }
             else
@@ -728,16 +733,16 @@
                 iterator first(iter, body.end(), actions.filename.native_file_string().c_str());
                 first.set_position(template_pos);
                 iterator last(body.end(), body.end());
-                r = boost::spirit::classic::parse(first, last, block_p).full;
+                r = boost::spirit::qi::parse(first, last, block_p) && first == last;
                 actions.out.swap(result);
             }
             return r;
         }
     }
 
-    void do_template_action::operator()(iterator first, iterator) const
+    void do_template_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        boost::spirit::classic::file_position const pos = first.get_position();
+        boost::spirit::classic::file_position const pos = x.begin().get_position();
         ++actions.template_depth;
         if (actions.template_depth > actions.max_template_depth)
         {
@@ -812,7 +817,7 @@
 
             if (!parse_template(body, result, template_pos, actions))
             {
-                boost::spirit::classic::file_position const pos = first.get_position();
+                boost::spirit::classic::file_position const pos = x.begin().get_position();
                 detail::outerr(pos.file,pos.line)
                     << "Expanding template:" << template_info[0] << std::endl
                     << "------------------begin------------------" << std::endl
@@ -831,8 +836,9 @@
         --actions.template_depth;
     }
 
-    void link_action::operator()(iterator first, iterator last) const
+    void link_action::operator()(iterator_range x, unused_type, unused_type) const
     {
+        iterator first = x.begin(), last = x.end();
         iterator save = first;
         phrase << tag;
         while (first != last)
@@ -852,7 +858,7 @@
         }
     }
 
-    void variablelist_action::operator()(iterator, iterator) const
+    void variablelist_action::operator()(unused_type, unused_type, unused_type) const
     {
         actions.out << "<variablelist>\n";
 
@@ -873,13 +879,13 @@
         actions.table_title.clear();
     }
 
-    void start_varlistitem_action::operator()(char) const
+    void start_varlistitem_action::operator()(unused_type, unused_type, unused_type) const
     {
         phrase << start_varlistitem_;
         phrase.push();
     }
 
-    void end_varlistitem_action::operator()(char) const
+    void end_varlistitem_action::operator()(unused_type, unused_type, unused_type) const
     {
         std::string str;
         temp_para.swap(str);
@@ -887,7 +893,7 @@
         phrase << str << end_varlistitem_;
     }
 
-    void table_action::operator()(iterator, iterator) const
+    void table_action::operator()(unused_type, unused_type, unused_type) const
     {
         std::string::iterator first = actions.table_title.begin();
         std::string::iterator last = actions.table_title.end();
@@ -955,7 +961,7 @@
         actions.table_title.clear();
     }
 
-    void start_row_action::operator()(char) const
+    void start_row_action::operator()(unused_type, unused_type, unused_type) const
     {
         // the first row is the header
         if (header.empty() && !phrase.str().empty())
@@ -967,19 +973,14 @@
         span = 0;
     }
 
-    void start_row_action::operator()(iterator f, iterator) const
-    {
-        (*this)(*f);
-    }
-
-    void start_col_action::operator()(char) const
+    void start_col_action::operator()(unused_type, unused_type, unused_type) const
     {
         phrase << start_cell_;
         phrase.push();
         ++span;
     }
 
-    void end_col_action::operator()(char) const
+    void end_col_action::operator()(unused_type, unused_type, unused_type) const
     {
         std::string str;
         temp_para.swap(str);
@@ -987,10 +988,10 @@
         phrase << str << end_cell_;
     }
 
-    void begin_section_action::operator()(iterator first, iterator last) const
+    void begin_section_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         section_id = element_id.empty() ?
-            detail::make_identifier(first, last) :
+            detail::make_identifier(x.begin(), x.end()) :
             element_id;
 
         if (section_level != 0)
@@ -1029,14 +1030,14 @@
         }
     }
 
-    void end_section_action::operator()(iterator first, iterator last) const
+    void end_section_action::operator()(iterator_range x, unused_type, unused_type) const
     {
         out << "</section>";
 
         --section_level;
         if (section_level < 0)
         {
-            boost::spirit::classic::file_position const pos = first.get_position();
+            boost::spirit::classic::file_position const pos = x.begin().get_position();
             detail::outerr(pos.file,pos.line)
                 << "Mismatched [endsect] near column " << pos.column << ".\n";
             ++error_count;
@@ -1057,9 +1058,9 @@
         }
     }
     
-    void element_id_warning_action::operator()(iterator first, iterator) const
+    void element_id_warning_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        boost::spirit::classic::file_position const pos = first.get_position();
+        boost::spirit::classic::file_position const pos = x.begin().get_position();
         detail::outwarn(pos.file,pos.line) << "Empty id.\n";        
     }
 
@@ -1097,9 +1098,9 @@
         return path;
     }
 
-    void xinclude_action::operator()(iterator first, iterator last) const
+    void xinclude_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        fs::path path = calculate_relative_path(first, last, actions);
+        fs::path path = calculate_relative_path(x.begin(), x.end(), actions);
         out << "\n<xi:include href=\"";
         detail::print_string(detail::escape_uri(path.string()), out.get());
         out << "\" />\n";
@@ -1268,9 +1269,9 @@
         }
     }
 
-    void import_action::operator()(iterator first, iterator last) const
+    void import_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        fs::path path = include_search(actions.filename.branch_path(), std::string(first,last));
+        fs::path path = include_search(actions.filename.branch_path(), std::string(x.begin(), x.end()));
         std::string ext = fs::extension(path);
         std::vector<template_symbol> storage;
         actions.error_count +=
@@ -1293,9 +1294,9 @@
         }
     }
 
-    void include_action::operator()(iterator first, iterator last) const
+    void include_action::operator()(iterator_range x, unused_type, unused_type) const
     {
-        fs::path filein = include_search(actions.filename.branch_path(), std::string(first,last));
+        fs::path filein = include_search(actions.filename.branch_path(), std::string(x.begin(), x.end()));
         std::string doc_type, doc_id, doc_dirname, doc_last_revision;
 
         // swap the filenames
@@ -1321,7 +1322,7 @@
         }
 
         // update the __FILENAME__ macro
-        *boost::spirit::classic::find(actions.macro, "__FILENAME__") = actions.filename.native_file_string();
+        *actions.macro.find("__FILENAME__") = actions.filename.native_file_string();
 
         // parse the file
         quickbook::parse(actions.filename.native_file_string().c_str(), actions, true);
@@ -1535,7 +1536,7 @@
         ;
     }
 
-    void phrase_to_string_action::operator()(iterator first, iterator last) const
+    void phrase_to_string_action::operator()(unused_type, unused_type, unused_type) const
     {
         phrase.swap(out);
     }
Modified: branches/quickbook-1.5-spirit2/detail/actions.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions.hpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/actions.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -17,7 +17,6 @@
 #include <stack>
 #include <algorithm>
 #include <boost/spirit/include/classic_iterator.hpp>
-#include <boost/spirit/include/qi_core.hpp>
 #include <boost/filesystem/operations.hpp>
 #include <boost/foreach.hpp>
 #include <boost/tuple/tuple.hpp>
@@ -34,10 +33,14 @@
 namespace quickbook
 {
         using namespace boost::spirit;
-
     namespace fs = boost::filesystem;
+
+	// TODO: This is defined in two places.    	
+	typedef qi::symbols<char, std::string> string_symbols;    
+
     typedef classic::position_iterator<std::string::const_iterator> iterator;
-    typedef classic::symbols<std::string> string_symbols;
+    typedef boost::iterator_range<iterator> iterator_range;
+    typedef qi::symbols<char, std::string> string_symbols;
     typedef std::map<std::string, std::string> attribute_map;
 
     struct actions;
@@ -58,7 +61,7 @@
             int& error_count)
         : error_count(error_count) {}
 
-        void operator()(iterator first, iterator /*last*/) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         int& error_count;
     };
@@ -78,7 +81,7 @@
         , pre(pre)
         , post(post) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& out;
         collector& phrase;
@@ -106,7 +109,7 @@
         , pre(pre)
         , post(post) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         collector& phrase;
@@ -135,7 +138,7 @@
         , qualified_section_id(qualified_section_id)
         , section_level(section_level) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         collector& phrase;
@@ -159,7 +162,7 @@
         , post(post)
         , macro(macro) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range const&, unused_type, unused_type) const;
 
         collector& out;
         std::string pre;
@@ -179,7 +182,7 @@
         , conditions(conditions)
         , macro(macro) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         std::vector<bool>& conditions;
@@ -198,7 +201,7 @@
         , conditions(conditions)
         , macro(macro) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         std::vector<bool>& conditions;
@@ -220,7 +223,7 @@
         , list_indent(list_indent)
         , list_marks(list_marks) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& out;
         collector& list_buffer;
@@ -243,7 +246,7 @@
         , list_marks(list_marks)
         , error_count(error_count) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         int& list_indent;
@@ -258,7 +261,7 @@
         span(char const* name, collector& out)
         : name(name), out(out) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         char const* name;
         collector& out;
@@ -271,7 +274,7 @@
         unexpected_char(collector& out)
         : out(out) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
     };
@@ -283,7 +286,7 @@
         anchor_action(collector& out)
             : out(out) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
     };
@@ -294,11 +297,11 @@
     struct do_macro_action
     {
         // Handles macro substitutions
-
+        
         do_macro_action(collector& phrase)
             : phrase(phrase) {}
 
-        void operator()(std::string const& str) const;
+        void operator()(std::string const& str, unused_type, unused_type) const;
         collector& phrase;
     };
 
@@ -309,8 +312,8 @@
         space(collector& out)
             : out(out) {}
 
-        void operator()(iterator first, iterator last) const;
-        void operator()(char ch) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
+        void operator()(char ch, unused_type, unused_type) const;
 
         collector& out;
     };
@@ -322,7 +325,7 @@
         pre_escape_back(actions& escape_actions, std::string& save)
             : escape_actions(escape_actions), save(save) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         actions& escape_actions;
         std::string& save;
@@ -335,7 +338,7 @@
         post_escape_back(collector& out, actions& escape_actions, std::string& save)
             : out(out), escape_actions(escape_actions), save(save) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& out;
         actions& escape_actions;
@@ -350,8 +353,8 @@
         raw_char_action(collector& phrase)
         : phrase(phrase) {}
 
-        void operator()(char ch) const;
-        void operator()(iterator first, iterator /*last*/) const;
+        void operator()(char ch, unused_type, unused_type) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& phrase;
     };
@@ -364,8 +367,8 @@
         plain_char_action(collector& phrase)
         : phrase(phrase) {}
 
-        void operator()(char ch) const;
-        void operator()(iterator first, iterator /*last*/) const;
+        void operator()(char ch, unused_type, unused_type) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& phrase;
     };
@@ -380,7 +383,7 @@
         : attributes(attributes)
         , attribute_name(attribute_name) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         attribute_map& attributes;
         std::string& attribute_name;
@@ -398,7 +401,7 @@
         , attributes(attributes)
         , image_fileref(image_fileref) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& phrase;
         attribute_map& attributes;
@@ -412,14 +415,7 @@
         markup_action(collector& phrase, std::string const& str)
         : phrase(phrase), str(str) {}
 
-        template <typename T>
-        void operator()(T const&) const
-        {
-            phrase << str;
-        }
-
-        template <typename T>
-        void operator()(T const&, T const&) const
+        void operator()(unused_type, unused_type, unused_type) const
         {
             phrase << str;
         }
@@ -427,7 +423,7 @@
         collector& phrase;
         std::string str;
     };
-    
+
     struct syntax_highlight
     {
         syntax_highlight(
@@ -450,7 +446,6 @@
         actions& escape_actions;
     };
 
-
     struct code_action
     {
         // Does the actual syntax highlighing of code
@@ -465,7 +460,7 @@
         {
         }
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         collector& phrase;
@@ -483,7 +478,7 @@
         , syntax_p(syntax_p)
         {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         syntax_highlight& syntax_p;
@@ -494,7 +489,7 @@
         start_varlistitem_action(collector& phrase)
         : phrase(phrase) {}
 
-        void operator()(char) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& phrase;
     };
@@ -504,7 +499,7 @@
         end_varlistitem_action(collector& phrase, collector& temp_para)
         : phrase(phrase), temp_para(temp_para) {}
 
-        void operator()(char) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& phrase;
         collector& temp_para;
@@ -517,7 +512,7 @@
         break_action(collector& phrase)
         : phrase(phrase) {}
 
-        void operator()(iterator f, iterator) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& phrase;
     };
@@ -529,7 +524,7 @@
         macro_identifier_action(quickbook::actions& actions)
         : actions(actions) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -541,7 +536,7 @@
         macro_definition_action(quickbook::actions& actions)
         : actions(actions) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -553,7 +548,7 @@
         template_body_action(quickbook::actions& actions)
         : actions(actions) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -565,7 +560,7 @@
         do_template_action(quickbook::actions& actions)
         : actions(actions) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -577,7 +572,7 @@
         link_action(collector& phrase, char const* tag)
         : phrase(phrase), tag(tag) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& phrase;
         char const* tag;
@@ -590,7 +585,7 @@
         variablelist_action(quickbook::actions& actions)
         : actions(actions) {}
 
-        void operator()(iterator, iterator) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -602,7 +597,7 @@
         table_action(quickbook::actions& actions)
         : actions(actions) {}
 
-        void operator()(iterator, iterator) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -614,8 +609,7 @@
         start_row_action(collector& phrase, unsigned& span, std::string& header)
             : phrase(phrase), span(span), header(header) {}
 
-        void operator()(char) const;
-        void operator()(iterator f, iterator) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& phrase;
         unsigned& span;
@@ -629,7 +623,7 @@
         start_col_action(collector& phrase, unsigned& span)
         : phrase(phrase), span(span) {}
 
-        void operator()(char) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& phrase;
         unsigned& span;
@@ -640,7 +634,7 @@
         end_col_action(collector& phrase, collector& temp_para)
         : phrase(phrase), temp_para(temp_para) {}
 
-        void operator()(char) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         collector& phrase;
         collector& temp_para;
@@ -666,7 +660,7 @@
         , qualified_section_id(qualified_section_id)
         , element_id(element_id) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         collector& phrase;
@@ -689,7 +683,7 @@
         , qualified_section_id(qualified_section_id)
         , error_count(error_count) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         int& section_level;
@@ -699,7 +693,7 @@
    
    struct element_id_warning_action
    {
-       void operator()(iterator first, iterator last) const;
+       void operator()(iterator_range, unused_type, unused_type) const;
    };
 
     struct xinclude_action
@@ -708,7 +702,7 @@
         xinclude_action(collector& out_, quickbook::actions& actions_)
             : out(out_), actions(actions_) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         quickbook::actions& actions;
@@ -721,7 +715,7 @@
         include_action(quickbook::actions& actions_)
             : actions(actions_) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         quickbook::actions& actions;
     };
@@ -732,7 +726,7 @@
         import_action(collector& out_, quickbook::actions& actions_)
             : out(out_), actions(actions_) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(iterator_range, unused_type, unused_type) const;
 
         collector& out;
         quickbook::actions& actions;
@@ -782,7 +776,7 @@
         phrase_to_string_action(std::string& out, collector& phrase)
             : out(out) , phrase(phrase) {}
 
-        void operator()(iterator first, iterator last) const;
+        void operator()(unused_type, unused_type, unused_type) const;
 
         std::string& out;
         collector& phrase;
Modified: branches/quickbook-1.5-spirit2/detail/block.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/block.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/block.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -3,10 +3,9 @@
 
 namespace quickbook
 {
-    typedef boost::spirit::classic::scanner<iterator> scanner;
-
-    void instantiate_phrase(block_grammar<quickbook::actions>& self)
+    void instantiate_phrase(actions& a)
     {
-        block_grammar<quickbook::actions>::definition<scanner> definition(self);
+        block_grammar<iterator, quickbook::actions, false> bg1(a);
+        block_grammar<iterator, quickbook::actions, true> bg2(a);
     }
 }
\ No newline at end of file
Modified: branches/quickbook-1.5-spirit2/detail/doc_info.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/doc_info.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/doc_info.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -3,10 +3,8 @@
 
 namespace quickbook
 {
-    typedef boost::spirit::classic::scanner<iterator> scanner;
-
-    void instantiate_phrase(doc_info_grammar<quickbook::actions>& self)
+    void instantiate_doc_info(quickbook::actions& a)
     {
-        doc_info_grammar<quickbook::actions>::definition<scanner> definition(self);
+        doc_info_grammar<iterator, quickbook::actions> grammar(a);
     }
 }
\ No newline at end of file
Modified: branches/quickbook-1.5-spirit2/detail/phrase.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/phrase.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/phrase.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -3,15 +3,13 @@
 
 namespace quickbook
 {
-    typedef boost::spirit::classic::scanner<iterator> scanner;
-
-    void instantiate_simple_phrase(simple_phrase_grammar<quickbook::actions>& self)
+    void instantiate_simple_phrase(actions& a)
     {
-        simple_phrase_grammar<quickbook::actions>::definition<scanner> spgd(self);
+        simple_phrase_grammar<iterator, actions> spgd(a);
     }
 
-    void instantiate_phrase(phrase_grammar<quickbook::actions>& self)
+    void instantiate_phrase(actions& a, bool& b)
     {
-        phrase_grammar<quickbook::actions>::definition<scanner> pgd(self);
+        phrase_grammar<iterator, actions> pgd(a, b);
     }
 }
\ No newline at end of file
Modified: branches/quickbook-1.5-spirit2/detail/quickbook.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/quickbook.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/quickbook.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -61,25 +61,33 @@
         typedef classic::position_iterator<std::string::const_iterator> iterator_type;
         iterator_type first(storage.begin(), storage.end(), filein_);
         iterator_type last(storage.end(), storage.end());
+        iterator_type start = first;
 
-        doc_info_grammar<actions> l(actor);
-        classic::parse_info<iterator_type> info = parse(first, last, l);
+        doc_info_grammar<iterator, actions> l(actor);
+        bool success = parse(first, last, l);
 
-        if (info.hit || ignore_docinfo)
+        if (success || ignore_docinfo)
         {
+            if(!success) first = start;
+
             pre(actor.out, actor, ignore_docinfo);
 
-            block_grammar<actions> g(actor);
-            info = parse(info.hit ? info.stop : first, last, g);
-            if (info.full)
+            block_grammar<iterator, actions> g(actor);
+            success = parse(first, last, g);
+            if (success && first == last)
             {
                 post(actor.out, actor, ignore_docinfo);
             }
         }
+        else {
+            classic::file_position const pos = first.get_position();
+            detail::outerr(pos.file,pos.line)
+                << "Doc Info error near column " << pos.column << ".\n";
+        }
 
-        if (!info.full)
+        if (!success || first != last)
         {
-            classic::file_position const pos = info.stop.get_position();
+            classic::file_position const pos = first.get_position();
             detail::outerr(pos.file,pos.line)
                 << "Syntax Error near column " << pos.column << ".\n";
             ++actor.error_count;
Modified: branches/quickbook-1.5-spirit2/detail/syntax_highlight.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/syntax_highlight.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/syntax_highlight.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -12,7 +12,8 @@
       , post_escape_back
       , actions
       , unexpected_char
-      , collector>
+      , collector
+      , iterator>
     cpp_p_type;
 
     typedef python_highlight<
@@ -24,7 +25,8 @@
       , post_escape_back
       , actions
       , unexpected_char
-      , collector>
+      , collector
+      , iterator>
     python_p_type;
     
     typedef teletype_highlight<
@@ -34,7 +36,8 @@
       , pre_escape_back
       , post_escape_back
       , actions
-      , collector>
+      , collector
+      , iterator>
     teletype_p_type;
     
     std::string syntax_highlight::operator()(iterator first, iterator last) const
Modified: branches/quickbook-1.5-spirit2/detail/template_stack.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/template_stack.cpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/template_stack.cpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -21,19 +21,19 @@
         scopes.push_front(template_scope());
     }
     
-    template_symbol* template_stack::find(std::string const& symbol) const
+    template_symbol const* template_stack::find(std::string const& symbol) const
     {
         for (template_scope const* i = &*scopes.begin(); i; i = i->parent_scope)
         {
-            if (template_symbol* ts = boost::spirit::classic::find(i->symbols, symbol.c_str()))
+            if (template_symbol const* ts = i->symbols.find(symbol.c_str()))
                 return ts;
         }
         return 0;
     }
 
-    template_symbol* template_stack::find_top_scope(std::string const& symbol) const
+    template_symbol const* template_stack::find_top_scope(std::string const& symbol) const
     {
-        return boost::spirit::classic::find(scopes.front().symbols, symbol.c_str());
+        return scopes.front().symbols.find(symbol.c_str());
     }
 
     template_symbols const& template_stack::top() const
@@ -52,7 +52,7 @@
     void template_stack::add(std::string const& symbol, template_symbol const& ts)
     {
         BOOST_ASSERT(!scopes.empty());
-        boost::spirit::classic::add(scopes.front().symbols, symbol.c_str(),
+        scopes.front().symbols.add(symbol.c_str(),
             boost::get<2>(ts) ? ts :
             template_symbol(boost::get<0>(ts), boost::get<1>(ts), &top_scope()));
     }    
Modified: branches/quickbook-1.5-spirit2/detail/template_stack.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/template_stack.hpp	(original)
+++ branches/quickbook-1.5-spirit2/detail/template_stack.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -15,8 +15,9 @@
 #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/spirit/include/qi_symbols.hpp>
+#include <boost/spirit/include/qi_parse.hpp>
+#include <boost/spirit/include/support_attributes.hpp>
 #include <boost/next_prior.hpp>
 
 namespace quickbook
@@ -41,7 +42,7 @@
           , template_scope const*>
     template_symbol;
 
-    typedef boost::spirit::classic::symbols<template_symbol> template_symbols;
+    typedef boost::spirit::qi::symbols<char, template_symbol> template_symbols;
     
     // template scope
     //
@@ -65,38 +66,49 @@
     {
         typedef std::deque<template_scope> deque;
 
-        struct parser
+        struct parser : boost::spirit::qi::primitive_parser<parser>
         {
-            typedef boost::spirit::classic::nil_t result_t;
-
+            template <typename Ctx, typename Itr>
+            struct attribute {
+                typedef template_scope type;
+            };
+        
             parser(template_stack& ts)
                 : ts(ts) {}
 
-            template <typename Scanner>
-            std::ptrdiff_t
-            operator()(Scanner const& scan, result_t) const
+            template <typename Iterator, typename Context, typename Skipper, typename Attribute>
+            bool parse(Iterator& first, Iterator const& last
+              , Context& context, Skipper const& skipper, Attribute& attr) const
             {
+                boost::spirit::qi::skip_over(first, last, skipper);
+            
+                // TODO: Is this right?
+                Attribute result_attr;
+
                 // search all scopes for the longest matching symbol.
-                typename Scanner::iterator_t f = scan.first;
+                Iterator f = first;
                 std::ptrdiff_t len = -1;
                 for (template_scope const* i = &*ts.scopes.begin(); i; i = i->parent_scope)
-                {
-                    boost::spirit::classic::match<> m = i->symbols.parse(scan);
-                    if (m.length() > len)
-                        len = m.length();
-                    scan.first = f;
+                {                    
+                    // TODO: Implement this without calling 'base'.
+                    if(i->symbols.parse(first, last, context, skipper, result_attr) && first.base() - f.base() > len)
+                    {
+                        boost::spirit::traits::assign_to(result_attr, attr);
+                        len = first.base() - f.base();
+                    }
+                    first = f;
                 }
                 if (len >= 0)
-                    scan.first = boost::next(f, len);
-                return len;
+                    first = boost::next(f, len);
+                return len > 0;
             }
 
             template_stack& ts;
         };
 
         template_stack();
-        template_symbol* find(std::string const& symbol) const;
-        template_symbol* find_top_scope(std::string const& symbol) const;
+        template_symbol const* find(std::string const& symbol) const;
+        template_symbol const* find_top_scope(std::string const& symbol) const;
         template_symbols const& top() const;
         template_scope const& top_scope() const;
         // Add the given template symbol to the current scope.
@@ -108,7 +120,7 @@
         // Set the current scope's parent.
         void set_parent_scope(template_scope const&);
 
-        boost::spirit::classic::functor_parser<parser> scope;
+        parser scope;
 
     private:
 
Modified: branches/quickbook-1.5-spirit2/doc_info.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/doc_info.hpp	(original)
+++ branches/quickbook-1.5-spirit2/doc_info.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -12,22 +12,26 @@
 
 #include "./grammars.hpp"
 #include "./detail/quickbook.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 "./parse_utils.hpp"
+#include <boost/spirit/include/qi_core.hpp>
+#include <boost/spirit/include/qi_uint.hpp>
+#include <boost/spirit/include/qi_eol.hpp>
+#include <boost/spirit/include/qi_eps.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
 
 namespace quickbook
 {
     using namespace boost::spirit;
+    namespace ph = boost::phoenix;
 
-    template <typename Actions>
-    template <typename Scanner>
-    doc_info_grammar<Actions>::
-        definition<Scanner>::definition(doc_info_grammar const& self)
-        : unused(false), common(self.actions, unused)
+    template <typename Iterator, typename Actions>
+    doc_info_grammar<Iterator, Actions>::doc_info_grammar(Actions& actions)
+            : doc_info_grammar::base_type(doc_info), actions(actions)
+            , unused(false), common(actions, unused)
     {
-        Actions& actions = self.actions;
+        typedef qi::uint_parser<int, 10, 1, 2>  uint2_t;
 
         doc_types =
             "book", "article", "library", "chapter", "part"
@@ -38,14 +42,13 @@
         doc_info =
             space
             >> '[' >> space
-            >> (doc_types >> classic::eps_p)
-                                            [classic::assign_a(actions.doc_type)]
+            >> qi::raw[doc_types]           [ph::ref(actions.doc_type) = as_string(qi::_1)]
             >> hard_space
-            >>  (  *(classic::anychar_p -
-                    (classic::ch_p('[') | ']' | classic::eol_p)
+            >>  (  *(qi::char_ -
+                    (qi::char_('[') | ']' | qi::eol)
                     )
-                )                           [classic::assign_a(actions.doc_title)]
-            >>  !(
+                )                           [ph::ref(actions.doc_title) = as_string(qi::_1)]
+            >>  -(
                     space >> '[' >>
                         quickbook_version
                     >> space >> ']'
@@ -57,7 +60,7 @@
                       doc_version
                     | doc_id
                     | doc_dirname
-                    | doc_copyright         [classic::push_back_a(actions.doc_copyrights, copyright)]
+                    | doc_copyright         [ph::push_back(ph::ref(actions.doc_copyrights), ph::ref(copyright))]
                     | doc_purpose           [actions.extract_doc_purpose]
                     | doc_category
                     | doc_authors
@@ -65,114 +68,105 @@
                     | doc_last_revision
                     | doc_source_mode
                     )
-                    >> space >> ']' >> +classic::eol_p
+                    >> space >> ']' >> +qi::eol
                 )
-            >> space >> ']' >> +classic::eol_p
+            >> space >> ']' >> +qi::eol
             ;
 
         quickbook_version =
                 "quickbook" >> hard_space
-            >>  (   classic::uint_p         [classic::assign_a(qbk_major_version)]
+            >>  (   qi::uint_               [ph::ref(qbk_major_version) = qi::_1]
                     >> '.' 
-                    >>  uint2_t()           [classic::assign_a(qbk_minor_version)]
+                    >>  uint2_t()           [ph::ref(qbk_minor_version) = qi::_1]
                 )
             ;
 
         doc_version =
                 "version" >> hard_space
-            >> (*(classic::anychar_p - ']'))
-                                            [classic::assign_a(actions.doc_version)]
+            >> qi::raw[*(qi::char_ - ']')]  [ph::ref(actions.doc_version) = as_string(qi::_1)]
             ;
 
         doc_id =
                 "id" >> hard_space
-            >> (*(classic::anychar_p - ']'))
-                                            [classic::assign_a(actions.doc_id)]
+            >> qi::raw[*(qi::char_ - ']')]  [ph::ref(actions.doc_id) = as_string(qi::_1)]
             ;
 
         doc_dirname =
                 "dirname" >> hard_space
-            >> (*(classic::anychar_p - ']'))
-                                            [classic::assign_a(actions.doc_dirname)]
+            >> qi::raw[*(qi::char_ - ']')]  [ph::ref(actions.doc_dirname) = as_string(qi::_1)]
             ;
 
         doc_copyright =
-                "copyright" >> hard_space   [classic::clear_a(copyright.first)]
-            >> +( classic::repeat_p(4)[classic::digit_p]
-                                            [classic::push_back_a(copyright.first)]
+                "copyright" >> hard_space   [ph::clear(ph::ref(copyright.first))]
+            >> +( qi::repeat(4)[qi::digit]  [ph::push_back(ph::ref(copyright.first), as_string(qi::_1))]
                   >> space
                 )
             >> space
-            >> (*(classic::anychar_p - ']'))
-                                            [classic::assign_a(copyright.second)]
+            >> (*(qi::char_ - ']'))         [ph::ref(copyright.second) = as_string(qi::_1)]
             ;
 
         doc_purpose =
                 "purpose" >> hard_space
-            >> phrase                       [classic::assign_a(actions.doc_purpose_1_1)]
+            >> qi::raw[phrase]              [ph::ref(actions.doc_purpose_1_1) = as_string(qi::_1)]
             ;
 
         doc_category =
                 "category" >> hard_space
-            >> (*(classic::anychar_p - ']'))
-                                            [classic::assign_a(actions.doc_category)]
+            >> (*(qi::char_ - ']'))         [ph::ref(actions.doc_category) = as_string(qi::_1)]
             ;
 
         doc_author =
                 space
             >>  '[' >> space
-            >>  (*(classic::anychar_p - ','))
-                                            [classic::assign_a(name.second)] // surname
+            >>  (*(qi::char_ - ','))        [ph::ref(name.second) = as_string(qi::_1)] // surname
             >>  ',' >> space
-            >>  (*(classic::anychar_p - ']'))
-                                            [classic::assign_a(name.first)] // firstname
+            >>  (*(qi::char_ - ']'))        [ph::ref(name.first) = as_string(qi::_1)] // firstname
             >>  ']'
             ;
 
         doc_authors =
                 "authors" >> hard_space
-            >> doc_author                   [classic::push_back_a(actions.doc_authors, name)]
+            >> doc_author                   [ph::push_back(ph::ref(actions.doc_authors), ph::ref(name))]
             >> *(   ','
-                    >>  doc_author          [classic::push_back_a(actions.doc_authors, name)]
+                    >>  doc_author          [ph::push_back(ph::ref(actions.doc_authors), ph::ref(name))]
                 )
             ;
 
         doc_license =
                 "license" >> hard_space
-            >> phrase                       [classic::assign_a(actions.doc_license_1_1)]
+            >> qi::raw[phrase]              [ph::ref(actions.doc_license_1_1) = as_string(qi::_1)]
             ;
 
         doc_last_revision =
                 "last-revision" >> hard_space
-            >> (*(classic::anychar_p - ']'))[classic::assign_a(actions.doc_last_revision)]
+            >> (*(qi::char_ - ']'))         [ph::ref(actions.doc_last_revision) = as_string(qi::_1)]
             ;
 
         doc_source_mode =
                 "source-mode" >> hard_space
             >>  (
-                   classic::str_p("c++") 
-                |  "python"
-                |  "teletype"
-                )                           [classic::assign_a(actions.source_mode)]
+                   qi::string("c++") 
+                |  qi::string("python")
+                |  qi::string("teletype")
+                )                           [ph::ref(actions.source_mode) = qi::_1]
             ;
 
         comment =
-            "[/" >> *(classic::anychar_p - ']') >> ']'
+            "[/" >> *(qi::char_ - ']') >> ']'
             ;
 
         space =
-            *(classic::space_p | comment)
+            *(qi::space | comment)
             ;
 
         hard_space =
-            (classic::eps_p - (classic::alnum_p | '_')) >> space
-                                                // must not be preceded by
-            ;                                   // alpha-numeric or underscore
+            (qi::eps - (qi::alnum | '_')) >> space  // must not be preceded by
+            ;                                       // alpha-numeric or underscore
 
         phrase =
            *(   common
             |   comment
-            |   (classic::anychar_p - ']')  [actions.plain_char]
+            |   (qi::char_ - ']')           [actions.plain_char]
             )
             ;
     }
Modified: branches/quickbook-1.5-spirit2/grammars.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/grammars.hpp	(original)
+++ branches/quickbook-1.5-spirit2/grammars.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -10,140 +10,89 @@
 #if !defined(BOOST_SPIRIT_QUICKBOOK_GRAMMARS_HPP)
 #define BOOST_SPIRIT_QUICKBOOK_GRAMMARS_HPP
 
-#include <boost/spirit/include/classic_core.hpp>
-#include <boost/spirit/include/classic_symbols.hpp>
-#include <boost/spirit/include/classic_numerics.hpp>
-#include <boost/spirit/include/classic_iterator.hpp>
 #include <boost/spirit/include/qi_core.hpp>
+#include <boost/spirit/include/qi_symbols.hpp>
 
 namespace quickbook
 {
     using namespace boost::spirit;
 
-    template <typename Actions>
-    struct phrase_grammar : classic::grammar<phrase_grammar<Actions> >
+    template <typename Iterator, typename Actions>
+    struct phrase_grammar : qi::grammar<Iterator>
     {
-        phrase_grammar(Actions& actions, bool& no_eols)
-            : no_eols(no_eols), actions(actions) {}
+        phrase_grammar(Actions& actions, bool& no_eols);
 
-        template <typename Scanner>
-        struct definition
-        {
-            definition(phrase_grammar const& self);
-
-            classic::rule<Scanner>
-                            space, blank, comment, phrase, phrase_markup, image,
-                            phrase_end, bold, italic, underline, teletype,
-                            strikethrough, escape, url, common, funcref, classref,
-                            memberref, enumref, macroref, headerref, conceptref, globalref,
-                            anchor, link, hard_space, eol, inline_code, simple_format,
-                            simple_bold, simple_italic, simple_underline,
-                            simple_teletype, source_mode, template_,
-                            quote, code_block, footnote, replaceable, macro,
-                            dummy_block, cond_phrase, macro_identifier, template_args,
-                            template_args_1_4, template_arg_1_4, brackets_1_4,
-                            template_args_1_5, template_arg_1_5,
-                            template_inner_arg_1_5, brackets_1_5
-                            ;
-
-            classic::rule<Scanner> const&
-            start() const { return common; }
-        };
-
-        bool& no_eols;
         Actions& actions;
+        bool& no_eols;
+
+        qi::rule<Iterator>
+                        space, blank, comment, phrase, phrase_markup, image,
+                        phrase_end, bold, italic, underline, teletype,
+                        strikethrough, escape, url, common, funcref, classref,
+                        memberref, enumref, macroref, headerref, conceptref, globalref,
+                        anchor, link, hard_space, eol, inline_code, simple_format,
+                        simple_bold, simple_italic, simple_underline,
+                        simple_teletype, source_mode, template_,
+                        quote, code_block, footnote, replaceable, macro,
+                        dummy_block, cond_phrase, macro_identifier, template_args,
+                        template_args_1_4, template_arg_1_4, brackets_1_4,
+                        template_args_1_5, template_arg_1_5,
+                        template_inner_arg_1_5, brackets_1_5
+                        ;
+
+        qi::rule<Iterator, std::string()> image_filename;
     };
 
-    template <typename Actions>
-    struct simple_phrase_grammar
-    : public classic::grammar<simple_phrase_grammar<Actions> >
-    {
-        simple_phrase_grammar(Actions& actions)
-            : actions(actions) {}
-
-        template <typename Scanner>
-        struct definition
-        {
-            definition(simple_phrase_grammar const& self);
-
-            bool unused;
-            classic::rule<Scanner> phrase, comment, dummy_block;
-            phrase_grammar<Actions> common;
-
-            classic::rule<Scanner> const&
-            start() const { return phrase; }
-        };
+    template <typename Iterator, typename Actions>
+    struct simple_phrase_grammar : qi::grammar<Iterator>
+    {
+        simple_phrase_grammar(Actions& actions);
 
         Actions& actions;
+        bool unused;
+        phrase_grammar<Iterator, Actions> common;
+        qi::rule<Iterator> phrase, comment, dummy_block;
     };
 
-    template <typename Actions, bool skip_initial_spaces = false>
-    struct block_grammar : classic::grammar<block_grammar<Actions> >
+    template <typename Iterator, typename Actions, bool skip_initial_spaces = false>
+    struct block_grammar : qi::grammar<Iterator>
     {
-        block_grammar(Actions& actions_)
-            : actions(actions_) {}
-
-        template <typename Scanner>
-        struct definition
-        {
-            definition(block_grammar const& self);
-
-            bool no_eols;
-
-            classic::rule<Scanner>
-                            start_, blocks, block_markup, code, code_line,
-                            paragraph, space, blank, comment, headings, h, h1, h2,
-                            h3, h4, h5, h6, hr, blurb, blockquote, admonition,
-                            phrase, list, phrase_end, ordered_list, def_macro,
-                            macro_identifier, table, table_row, variablelist,
-                            varlistentry, varlistterm, varlistitem, table_cell,
-                            preformatted, list_item, begin_section, end_section,
-                            xinclude, include, hard_space, eol, paragraph_end,
-                            template_, template_id, template_formal_arg,
-                            template_body, identifier, dummy_block, import,
-                            inside_paragraph, element_id, element_id_1_5;
-
-            classic::symbols<>
-                            paragraph_end_markups;
-
-            phrase_grammar<Actions> common;
-
-            classic::rule<Scanner> const&
-            start() const { return start_; }
-        };
+        block_grammar(Actions& actions_);
 
-        Actions&   actions;
+        Actions& actions;
+        bool no_eols;
+        phrase_grammar<Iterator, Actions> common;
+        qi::symbols<>   paragraph_end_markups;
+        qi::rule<Iterator>
+                        start_, blocks, block_markup, code, code_line,
+                        paragraph, space, blank, comment, headings, h, h1, h2,
+                        h3, h4, h5, h6, hr, blurb, blockquote, admonition,
+                        phrase, list, phrase_end, ordered_list, def_macro,
+                        macro_identifier, table, table_row, variablelist,
+                        varlistentry, varlistterm, varlistitem, table_cell,
+                        preformatted, list_item, begin_section, end_section,
+                        xinclude, include, hard_space, eol, paragraph_end,
+                        template_, template_id, template_formal_arg,
+                        template_body, identifier, dummy_block, import,
+                        inside_paragraph, element_id, element_id_1_5;
     };
 
-    template <typename Actions>
-    struct doc_info_grammar
-    : public classic::grammar<doc_info_grammar<Actions> >
-    {
-        doc_info_grammar(Actions& actions)
-            : actions(actions) {}
-
-        template <typename Scanner>
-        struct definition
-        {
-            typedef classic::uint_parser<int, 10, 1, 2>  uint2_t;
-
-            definition(doc_info_grammar const& self);
-            bool unused;
-            std::pair<std::string, std::string> name;
-            std::pair<std::vector<std::string>, std::string> copyright;
-            classic::rule<Scanner>
-                            doc_info, doc_title, doc_version, doc_id, doc_dirname,
-                            doc_copyright, doc_purpose,doc_category, doc_authors,
-                            doc_author, comment, space, hard_space, doc_license,
-                            doc_last_revision, doc_source_mode, phrase, quickbook_version;
-            phrase_grammar<Actions> common;
-            classic::symbols<> doc_types;
-
-            classic::rule<Scanner> const&
-            start() const { return doc_info; }
-        };
+    template <typename Iterator, typename Actions>
+    struct doc_info_grammar : qi::grammar<Iterator>
+    {
+        doc_info_grammar(Actions& actions);
 
         Actions& actions;
+        bool unused;
+        std::pair<std::string, std::string> name;
+        std::pair<std::vector<std::string>, std::string> copyright;
+        phrase_grammar<Iterator, Actions> common;
+        qi::symbols<char> doc_types;
+        qi::rule<Iterator>
+                        doc_info, doc_title, doc_version, doc_id, doc_dirname,
+                        doc_copyright, doc_purpose,doc_category, doc_authors,
+                        doc_author, comment, space, hard_space, doc_license,
+                        doc_last_revision, doc_source_mode, phrase, quickbook_version;
     };
 
     // TODO: Duplicate definition:
@@ -158,13 +107,13 @@
   
         python_code_snippet_grammar(actions_type & actions);
 
+        actions_type& actions;
+
         qi::rule<Iterator>
             start_, snippet, code_elements, escaped_comment,
             inline_callout, line_callout, ignore;
         qi::rule<Iterator, std::string()>
             identifier;
-
-        actions_type& actions;
     };  
 
     template <typename Iterator>
@@ -175,13 +124,13 @@
   
         cpp_code_snippet_grammar(actions_type & actions);
 
+        actions_type& actions;
+
         qi::rule<Iterator>
             start_, snippet, code_elements, escaped_comment,
             inline_callout, line_callout, ignore;
         qi::rule<Iterator, std::string()>
             identifier;
-
-        actions_type& actions;
     };
 }
 
Modified: branches/quickbook-1.5-spirit2/phrase.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.hpp	(original)
+++ branches/quickbook-1.5-spirit2/phrase.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -13,16 +13,18 @@
 #include "./grammars.hpp"
 #include "./detail/quickbook.hpp"
 #include "./detail/utils.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_assign_actor.hpp>
-#include <boost/spirit/include/classic_clear_actor.hpp>
-#include <boost/spirit/include/classic_if.hpp>
+#include "./parse_utils.hpp"
+#include <boost/spirit/include/qi_core.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/repository/include/qi_confix.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
 
 namespace quickbook
 {
     using namespace boost::spirit;
+    namespace ph = boost::phoenix;
 
     template <typename Rule, typename Action>
     inline void
@@ -34,69 +36,65 @@
     )
     {
         simple =
-            mark >>
-            (
+            mark >> 
+            qi::raw[
                 (
-                    classic::graph_p             // A single char. e.g. *c*
-                    >> classic::eps_p(mark
-                        >> (classic::space_p | classic::punct_p | classic::end_p))
-                                                // space_p, punct_p or end_p
+                    qi::graph                   // A single char. e.g. *c*
+                    >> &(mark
+                        >> (qi::space | qi::punct | qi::eoi))
+                                                // space, punct or end
                 )                               // must follow mark
             |
-                (   classic::graph_p >>         // graph_p must follow mark
-                    *(classic::anychar_p -
-                        (   (classic::graph_p >> mark) 
-                                                // Make sure that we don't go
+                (   qi::graph >>                // qi::graph must follow mark
+                    *(qi::char_ -
+                        (   (qi::graph >> mark) // Make sure that we don't go
                         |   close               // past a single block
                         )
-                    ) >> classic::graph_p       // graph_p must precede mark
-                    >> classic::eps_p(mark
-                        >> (classic::space_p | classic::punct_p | classic::end_p))
-                                                // space_p, punct_p or end_p
+                    ) >> qi::graph              // qi::graph must precede mark
+                    >> &(mark
+                        >> (qi::space | qi::punct | qi::eoi))
+                                                // space, punct or end
                 )                               // must follow mark
-            )                                   [action]
+            ]                                   [action]
             >> mark
             ;
     }
 
-    template <typename Actions>
-    template <typename Scanner>
-    phrase_grammar<Actions>::definition<Scanner>::definition(
-        phrase_grammar const& self)
+    template <typename Iterator, typename Actions>
+    phrase_grammar<Iterator, Actions>::phrase_grammar(Actions& actions, bool& no_eols)
+        : phrase_grammar::base_type(common, "phrase"),
+        actions(actions),
+        no_eols(no_eols)
     {
-        using detail::var;
-        Actions& actions = self.actions;
-
         space =
-            *(classic::space_p | comment)
+            *(qi::space | comment)
             ;
 
         blank =
-            *(classic::blank_p | comment)
+            *(qi::blank | comment)
             ;
 
-        eol = blank >> classic::eol_p
+        eol = blank >> qi::eol
             ;
 
         phrase_end =
             ']' |
-            classic::if_p(var(self.no_eols))
-            [
+            qi::eps(ph::ref(no_eols)) >>
                 eol >> eol                      // Make sure that we don't go
-            ]                                   // past a single block, except
-            ;                                   // when preformatted.
+            ;                                   // past a single block, except
+                                                // when preformatted.
 
         hard_space =
-            (classic::eps_p - (classic::alnum_p | '_')) >> space
-                                                // must not be preceded by
-            ;                                   // alpha-numeric or underscore
+            (qi::eps - (qi::alnum | '_')) >> space
+            ;                                   // must not be preceded by
+                                                // alpha-numeric or underscore
 
         comment =
-            "[/" >> *(dummy_block | (classic::anychar_p - ']')) >> ']'
+            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
 
         dummy_block =
-            '[' >> *(dummy_block | (classic::anychar_p - ']')) >> ']'
+            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
 
         common =
@@ -110,10 +108,9 @@
             ;
 
         macro =
-            classic::eps_p(actions.macro        // must not be followed by
-                                                // alpha or underscore
-                >> (classic::eps_p - (classic::alpha_p | '_')))
-            >> actions.macro                    [actions.do_macro]
+            &(actions.macro                         // must not be followed by
+                >> (qi::eps - (qi::alpha | '_')))   // alpha or underscore
+            >> actions.macro                        [actions.do_macro]
             ;
 
         static const bool true_ = true;
@@ -121,43 +118,35 @@
 
         template_ =
             (
-                classic::ch_p('`')              [classic::assign_a(actions.template_escape,true_)]
+                qi::char_('`')                      [ph::ref(actions.template_escape) = true_]
                 |
-                classic::eps_p                  [classic::assign_a(actions.template_escape,false_)]
+                qi::eps                             [ph::ref(actions.template_escape) = false_]
             )
             >>
             ( (
-                (classic::eps_p(classic::punct_p)
-                    >> actions.templates.scope
-                )                               [classic::push_back_a(actions.template_info)]
-                >> !template_args
+                qi::raw[&qi::punct >> actions.templates.scope]
+                                                    [ph::push_back(ph::ref(actions.template_info), as_string(qi::_1))]
+                >> -template_args
             ) | (
-                (actions.templates.scope
-                    >> classic::eps_p
-                )                               [classic::push_back_a(actions.template_info)]
-                >> !(hard_space
-                    >> template_args)
+                qi::raw[actions.templates.scope]    [ph::push_back(ph::ref(actions.template_info), as_string(qi::_1))]
+                >> -(hard_space >> template_args)
             ) )
-            >> classic::eps_p(']')
+            >> &qi::lit(']')
             ;
 
         template_args =
-            classic::if_p(qbk_since(105u)) [
-                template_args_1_5
-            ].else_p [
-                template_args_1_4
-            ]
+            qi::eps(qbk_before(105u)) >> template_args_1_4
+            |
+            qi::eps(qbk_since(105u)) >> template_args_1_5
             ;
 
         template_args_1_4 =
-            template_arg_1_4                    [classic::push_back_a(actions.template_info)]
-            >> *(
-                    ".." >> template_arg_1_4    [classic::push_back_a(actions.template_info)]
-                )
+            qi::raw[template_arg_1_4]               [ph::push_back(ph::ref(actions.template_info), as_string(qi::_1))]
+            % ".."
             ;
 
         template_arg_1_4 =
-            +(brackets_1_4 | (classic::anychar_p - (classic::str_p("..") | ']')))
+            +(brackets_1_4 | (qi::char_ - (qi::lit("..") | ']')))
             ;
 
         brackets_1_4 =
@@ -165,18 +154,16 @@
             ;
 
         template_args_1_5 =
-            template_arg_1_5                    [classic::push_back_a(actions.template_info)]
-            >> *(
-                    ".." >> template_arg_1_5    [classic::push_back_a(actions.template_info)]
-                )
+            qi::raw[template_arg_1_5]               [ph::push_back(ph::ref(actions.template_info), as_string(qi::_1))]
+            % ".."
             ;
 
         template_arg_1_5 =
-            +(brackets_1_5 | ('\\' >> classic::anychar_p) | (classic::anychar_p - (classic::str_p("..") | '[' | ']')))
+            +(brackets_1_5 | ('\\' >> qi::char_) | (qi::char_ - (qi::lit("..") | '[' | ']')))
             ;
 
         template_inner_arg_1_5 =
-            +(brackets_1_5 | ('\\' >> classic::anychar_p) | (classic::anychar_p - (classic::str_p('[') | ']')))
+            +(brackets_1_5 | ('\\' >> qi::char_) | (qi::char_ - (qi::lit('[') | ']')))
             ;
 
         brackets_1_5 =
@@ -185,31 +172,31 @@
 
         inline_code =
             '`' >>
-            (
-               *(classic::anychar_p -
+            qi::raw[
+               *(qi::char_ -
                     (   '`'
-                    |   (eol >> eol)            // Make sure that we don't go
-                    )                           // past a single block
-                ) >> classic::eps_p('`')
-            )                                   [actions.inline_code]
+                    |   (eol >> eol)                // Make sure that we don't go
+                    )                               // past a single block
+                ) >> &qi::lit('`')
+            ]                                       [actions.inline_code]
             >>  '`'
             ;
 
         code_block =
                 (
                     "```" >>
-                    (
-                       *(classic::anychar_p - "```")
-                            >> classic::eps_p("```")
-                    )                           [actions.code_block]
+                    qi::raw[
+                       *(qi::char_ - "```")
+                            >> &qi::lit("```")
+                    ]                               [actions.code_block]
                     >>  "```"
                 )
             |   (
                     "``" >>
-                    (
-                       *(classic::anychar_p - "``")
-                            >> classic::eps_p("``")
-                    )                           [actions.code_block]
+                    qi::raw[
+                       *(qi::char_ - "``")
+                            >> &qi::lit("``")
+                    ]                               [actions.code_block]
                     >>  "``"
                 )
             ;
@@ -233,8 +220,7 @@
         phrase =
            *(   common
             |   comment
-            |   (classic::anychar_p - phrase_end)
-                                                [actions.plain_char]
+            |   (qi::char_ - phrase_end)            [actions.plain_char]
             )
             ;
 
@@ -262,226 +248,228 @@
                 |   quote
                 |   replaceable
                 |   footnote
-                |   template_                   [actions.do_template]
-                |   classic::str_p("br")        [actions.break_]
+                |   qi::raw[template_]              [actions.do_template]
+                |   qi::raw["br"]                   [actions.break_]
                 )
             >>  ']'
             ;
 
         escape =
-                classic::str_p("\\n")           [actions.break_]
-            |   "\\ "                           // ignore an escaped char
-            |   '\\' >> classic::punct_p        [actions.raw_char]
+                qi::raw["\\n"]                      [actions.break_]
+            |   "\\ "                               // ignore an escaped char
+            |   '\\' >> qi::punct                   [actions.raw_char]
             |   (
-                    ("'''" >> !eol)             [actions.escape_pre]
-                >>  *(classic::anychar_p - "'''")
-                                                [actions.raw_char]
-                >>  classic::str_p("'''")       [actions.escape_post]
+                    ("'''" >> -eol)                 [actions.escape_pre]
+                >>  *(qi::char_ - "'''")            [actions.raw_char]
+                >>  qi::lit("'''")                  [actions.escape_post]
                 )
             ;
 
         macro_identifier =
-            +(classic::anychar_p - (classic::space_p | ']'))
+            +(qi::char_ - (qi::space | ']'))
             ;
 
         cond_phrase =
                 '?' >> blank
-            >>  macro_identifier                [actions.cond_phrase_pre]
-            >>  (!phrase)                       [actions.cond_phrase_post]
+            >>  qi::raw[macro_identifier]           [actions.cond_phrase_pre]
+            >>  qi::raw[-phrase]                    [actions.cond_phrase_post]
             ;
 
         image =
-                '$' >> blank                    [classic::clear_a(actions.attributes)]
-            >>  classic::if_p(qbk_since(105u)) [
-                        (+(
-                            *classic::space_p
-                        >>  +(classic::anychar_p - (classic::space_p | phrase_end | '['))
-                        ))                       [classic::assign_a(actions.image_fileref)]
+                '$' >> blank                        [ph::clear(ph::ref(actions.attributes))]
+            >> (
+                qi::eps(qbk_since(105u)) >> (
+                        image_filename              [ph::ref(actions.image_fileref) = qi::_1]
                     >>  hard_space
                     >>  *(
                             '['
-                        >>  (*(classic::alnum_p | '_'))  [classic::assign_a(actions.attribute_name)]
+                        >>  qi::raw[*(qi::alnum | '_')]
+                                                    [ph::ref(actions.attribute_name) = as_string(qi::_1)]
                         >>  space
-                        >>  (*(classic::anychar_p - (phrase_end | '[')))
-                                                [actions.attribute]
+                        >>  qi::raw[*(qi::char_ - (phrase_end | '['))]
+                                                    [actions.attribute]
                         >>  ']'
                         >>  space
                         )
-                ].else_p [
-                        (*(classic::anychar_p -
-                            phrase_end))        [classic::assign_a(actions.image_fileref)]
-                ]
-            >>  classic::eps_p(']')             [actions.image]
+                ) |
+                qi::eps(qbk_before(105u)) >> (
+                        (*(qi::char_ -
+                            phrase_end))            [ph::ref(actions.image_fileref) = as_string(qi::_1)]
+                )
+            )
+            >>  &qi::lit(']')                       [actions.image]
             ;
-            
+
+        image_filename = qi::raw[
+            +(
+                *qi::space
+            >>  +(qi::char_ - (qi::space | phrase_end | '['))
+            )];
+
         url =
                 '@'
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.url_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | qi::space))]             [actions.url_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.url_post]
+                )                                   [actions.url_post]
             ;
 
         link =
                 "link" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.link_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | qi::space))]             [actions.link_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.link_post]
+                )                                   [actions.link_post]
             ;
 
         anchor =
                 '#'
             >>  blank
-            >>  (   *(classic::anychar_p -
-                        phrase_end)
-                )                               [actions.anchor]
+            >>  qi::raw[*(qi::char_ - phrase_end)]  [actions.anchor]
             ;
 
         funcref =
             "funcref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.funcref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.funcref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.funcref_post]
+                )                                   [actions.funcref_post]
             ;
 
         classref =
             "classref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.classref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.classref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.classref_post]
+                )                                   [actions.classref_post]
             ;
 
         memberref =
             "memberref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.memberref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.memberref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.memberref_post]
+                )                                   [actions.memberref_post]
             ;
 
         enumref =
             "enumref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.enumref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.enumref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.enumref_post]
+                )                                   [actions.enumref_post]
             ;
 
         macroref =
             "macroref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.macroref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.macroref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.macroref_post]
+                )                                   [actions.macroref_post]
             ;
 
         headerref =
             "headerref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.headerref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.headerref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.headerref_post]
+                )                                   [actions.headerref_post]
             ;
 
         conceptref =
             "conceptref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.conceptref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.conceptref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.conceptref_post]
+                )                                   [actions.conceptref_post]
             ;
 
         globalref =
             "globalref" >> hard_space
-            >>  (*(classic::anychar_p -
-                    (']' | hard_space)))        [actions.globalref_pre]
-            >>  (   classic::eps_p(']')
+            >>  qi::raw[*(qi::char_ -
+                    (']' | hard_space))]            [actions.globalref_pre]
+            >>  (   &qi::lit(']')
                 |   (hard_space >> phrase)
-                )                               [actions.globalref_post]
+                )                                   [actions.globalref_post]
             ;
 
         bold =
-                classic::ch_p('*')              [actions.bold_pre]
-            >>  blank >> phrase                 [actions.bold_post]
+                qi::char_('*')                      [actions.bold_pre]
+            >>  blank >> phrase                     [actions.bold_post]
             ;
 
         italic =
-                classic::ch_p('\'')             [actions.italic_pre]
-            >>  blank >> phrase                 [actions.italic_post]
+                qi::char_('\'')                     [actions.italic_pre]
+            >>  blank >> phrase                     [actions.italic_post]
             ;
 
         underline =
-                classic::ch_p('_')              [actions.underline_pre]
-            >>  blank >> phrase                 [actions.underline_post]
+                qi::char_('_')                      [actions.underline_pre]
+            >>  blank >> phrase                     [actions.underline_post]
             ;
 
         teletype =
-                classic::ch_p('^')              [actions.teletype_pre]
-            >>  blank >> phrase                 [actions.teletype_post]
+                qi::char_('^')                      [actions.teletype_pre]
+            >>  blank >> phrase                     [actions.teletype_post]
             ;
 
         strikethrough =
-                classic::ch_p('-')              [actions.strikethrough_pre]
-            >>  blank >> phrase                 [actions.strikethrough_post]
+                qi::char_('-')                      [actions.strikethrough_pre]
+            >>  blank >> phrase                     [actions.strikethrough_post]
             ;
 
         quote =
-                classic::ch_p('"')              [actions.quote_pre]
-            >>  blank >> phrase                 [actions.quote_post]
+                qi::char_('"')                      [actions.quote_pre]
+            >>  blank >> phrase                     [actions.quote_post]
             ;
 
         replaceable =
-                classic::ch_p('~')              [actions.replaceable_pre]
-            >>  blank >> phrase                 [actions.replaceable_post]
+                qi::char_('~')                      [actions.replaceable_pre]
+            >>  blank >> phrase                     [actions.replaceable_post]
             ;
 
         source_mode =
             (
-                classic::str_p("c++")
-            |   "python"
-            |   "teletype"
-            )                                   [classic::assign_a(actions.source_mode)]
+                qi::string("c++")
+            |   qi::string("python")
+            |   qi::string("teletype")
+            )                                       [ph::ref(actions.source_mode) = qi::_1]
             ;
 
         footnote =
-                classic::str_p("footnote")      [actions.footnote_pre]
-            >>  blank >> phrase                 [actions.footnote_post]
+                qi::lit("footnote")                 [actions.footnote_pre]
+            >>  blank >> phrase                     [actions.footnote_post]
             ;
     }
 
-    template <typename Actions>
-    template <typename Scanner>
-    simple_phrase_grammar<Actions>::definition<Scanner>::definition(
-        simple_phrase_grammar const& self)
-        : unused(false), common(self.actions, unused)
+    template <typename Iterator, typename Actions>
+    simple_phrase_grammar<Iterator, Actions>::simple_phrase_grammar(Actions& actions)
+        : simple_phrase_grammar::base_type(phrase, "simple_phrase")
+        , actions(actions), unused(false), common(actions, unused),
+        phrase("phrase"), comment("comment"), dummy_block("dummy_block")
     {
-        Actions& actions = self.actions;
-
         phrase =
            *(   common
             |   comment
-            |   (classic::anychar_p - ']')      [actions.plain_char]
+            |   (qi::char_ - ']')               [actions.plain_char]
             )
             ;
 
         comment =
-            "[/" >> *(dummy_block | (classic::anychar_p - ']')) >> ']'
+            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
 
         dummy_block =
-            '[' >> *(dummy_block | (classic::anychar_p - ']')) >> ']'
+            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
     }
 }
Modified: branches/quickbook-1.5-spirit2/syntax_highlight.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/syntax_highlight.hpp	(original)
+++ branches/quickbook-1.5-spirit2/syntax_highlight.hpp	2009-11-18 18:20:08 EST (Wed, 18 Nov 2009)
@@ -10,17 +10,37 @@
 #if !defined(BOOST_SPIRIT_QUICKBOOK_SYNTAX_HIGHLIGHT_HPP)
 #define BOOST_SPIRIT_QUICKBOOK_SYNTAX_HIGHLIGHT_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_symbols.hpp>
-#include <boost/spirit/include/classic_loops.hpp>
+#include <boost/spirit/include/qi_core.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_directive.hpp>
 #include "./grammars.hpp"
 
 namespace quickbook
 {
     using namespace boost::spirit;
 
+    template <class Iterator, class EscapeActions>
+    struct parse_escaped_impl
+    {
+        parse_escaped_impl(EscapeActions& escape_actions)
+            : actions(escape_actions) {}
+
+        void operator()(boost::iterator_range<Iterator> escaped, unused_type, unused_type) const {
+            bool unused;
+            phrase_grammar<Iterator, EscapeActions> common(actions, unused);   
+            Iterator first = escaped.begin(), last = escaped.end();
+            while(first != last) {
+                if(!qi::parse(first, last, common)) {
+                    actions.plain_char(*first, 0, 0);
+                    ++first;
+                }
+            }
+        }
+        
+        EscapeActions& actions;
+    };
+
     // Grammar for C++ highlighting
     template <
         typename Process
@@ -31,143 +51,129 @@
       , typename PostEscape
       , typename EscapeActions
       , typename Unexpected
-      , typename Out>
+      , typename Out
+      , typename Iterator>
     struct cpp_highlight
-    : public classic::grammar<cpp_highlight<Process, Space, Macro, DoMacro, PreEscape, PostEscape, EscapeActions, Unexpected, Out> >
+    : public qi::grammar<Iterator>
     {
-        cpp_highlight(Out& out, Macro const& macro, DoMacro do_macro, EscapeActions& escape_actions)
-        : out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {}
-
-        template <typename Scanner>
-        struct definition
+        cpp_highlight(Out& out, Macro const& macro_symbols, DoMacro do_macro, EscapeActions& escape_actions)
+        : cpp_highlight::base_type(program), out(out), macro_symbols(macro_symbols), do_macro(do_macro), escape_actions(escape_actions)
+        , parse_escaped(escape_actions)
         {
-            definition(cpp_highlight const& self)
-                : common(self.escape_actions, unused)
-                , unused(false)
-            {
-                program
-                    =
-                    *(  (+classic::space_p)      [Space(self.out)]
-                    |   macro
-                    |   escape
-                    |   preprocessor    [Process("preprocessor", self.out)]
-                    |   comment         [Process("comment", self.out)]
-                    |   keyword         [Process("keyword", self.out)]
-                    |   identifier      [Process("identifier", self.out)]
-                    |   special         [Process("special", self.out)]
-                    |   string_         [Process("string", self.out)]
-                    |   char_           [Process("char", self.out)]
-                    |   number          [Process("number", self.out)]
-                    |   classic::repeat_p(1)[classic::anychar_p] [Unexpected(self.out)]
-                    )
-                    ;
-
-                macro = 
-                    classic::eps_p(self.macro                    // must not be followed by
-                        >> (classic::eps_p - (classic::alpha_p | '_')))   // alpha or underscore
-                    >> self.macro                       [self.do_macro]
-                    ;
-
-                qbk_phrase =
-                   *(   common
-                    |   (classic::anychar_p - classic::str_p("``"))   [self.escape_actions.plain_char]
-                    )
-                    ;
-
-                escape =
-                    classic::str_p("``")         [PreEscape(self.escape_actions, save)]
-                    >>
+            program
+                =
+                *(  qi::raw[+qi::space]     [Space(out)]
+                |   macro
+                |   escape
+                |   qi::raw[preprocessor]   [Process("preprocessor", out)]
+                |   qi::raw[comment]        [Process("comment", out)]
+                |   qi::raw[keyword]        [Process("keyword", out)]
+                |   qi::raw[identifier]     [Process("identifier", out)]
+                |   qi::raw[special]        [Process("special", out)]
+                |   qi::raw[string_]        [Process("string", out)]
+                |   qi::raw[char_]          [Process("char", out)]
+                |   qi::raw[number]         [Process("number", out)]
+                |   qi::raw[qi::char_]      [Unexpected(out)]
+                )
+                ;
+
+            macro = 
+                &(macro_symbols                         // must not be followed by
+                    >> (qi::eps - (qi::alpha | '_')))   // alpha or underscore
+                >> macro_symbols            [do_macro]
+                ;
+
+            escape =
+                qi::string("``")            [PreEscape(escape_actions, save)]
+                >>
+                (
                     (
                         (
-                            (
-                                (+(classic::anychar_p - "``") >> classic::eps_p("``"))
-                                & qbk_phrase
-                            )
-                            >>  classic::str_p("``")
-                        )
-                        |
-                        (
-                            classic::eps_p       [self.escape_actions.error]
-                            >> *classic::anychar_p
-                        )
-                    )                   [PostEscape(self.out, self.escape_actions, save)]
-                    ;
-
-                preprocessor
-                    =   '#' >> *classic::space_p >> ((classic::alpha_p | '_') >> *(classic::alnum_p | '_'))
-                    ;
-
-                comment
-                    =   classic::comment_p("//") | classic::comment_p("/*", "*/")
-                    ;
-
-                keyword
-                    =   keyword_ >> (classic::eps_p - (classic::alnum_p | '_'))
-                    ;   // make sure we recognize whole words only
-
-                keyword_
-                    =   "and_eq", "and", "asm", "auto", "bitand", "bitor",
-                        "bool", "break", "case", "catch", "char", "class",
-                        "compl", "const_cast", "const", "continue", "default",
-                        "delete", "do", "double", "dynamic_cast",  "else",
-                        "enum", "explicit", "export", "extern", "false",
-                        "float", "for", "friend", "goto", "if", "inline",
-                        "int", "long", "mutable", "namespace", "new", "not_eq",
-                        "not", "operator", "or_eq", "or", "private",
-                        "protected", "public", "register", "reinterpret_cast",
-                        "return", "short", "signed", "sizeof", "static",
-                        "static_cast", "struct", "switch", "template", "this",
-                        "throw", "true", "try", "typedef", "typeid",
-                        "typename", "union", "unsigned", "using", "virtual",
-                        "void", "volatile", "wchar_t", "while", "xor_eq", "xor"
-                    ;
-
-                special
-                    =   +classic::chset_p("~!%^&*()+={[}]:;,<.>?/|\\-")
-                    ;
-
-                string_char = ('\\' >> classic::anychar_p) | (classic::anychar_p - '\\');
-
-                string_
-                    =   !classic::as_lower_d['l'] >> classic::confix_p('"', *string_char, '"')
-                    ;
-
-                char_
-                    =   !classic::as_lower_d['l'] >> classic::confix_p('\'', *string_char, '\'')
-                    ;
-
-                number
-                    =   (
-                            classic::as_lower_d["0x"] >> classic::hex_p
-                        |   '0' >> classic::oct_p
-                        |   classic::real_p
+                            // TODO: Is this right?
+                            qi::raw[+(qi::char_ - "``") >> &qi::lit("``")]
+                                [parse_escaped]
                         )
-                        >>  *classic::as_lower_d[classic::chset_p("ldfu")]
-                    ;
-
-                identifier
-                    =   (classic::alpha_p | '_') >> *(classic::alnum_p | '_')
-                    ;
-            }
+                        >>  qi::string("``")
+                    )
+                    |
+                    (
+                        qi::raw[qi::eps]    [escape_actions.error]
+                        >> *qi::char_
+                    )
+                )                           [PostEscape(out, escape_actions, save)]
+                ;
 
-            classic::rule<Scanner>
-                            program, macro, preprocessor, comment, special, string_, 
-                            char_, number, identifier, keyword, qbk_phrase, escape,
-                            string_char;
-
-            classic::symbols<> keyword_;
-            phrase_grammar<EscapeActions> common;
-            std::string save;
-            bool unused;
+            preprocessor
+                =   '#' >> *qi::space >> ((qi::alpha | '_') >> *(qi::alnum | '_'))
+                ;
+
+            comment
+                =   qi::lit("//") >> *(qi::char_ - qi::eol) >> -qi::eol
+                |   qi::lit("/*") >> *(qi::char_ - "*/") >> -qi::lit("*/")
+                ;
+
+            keyword
+                =   keyword_ >> (qi::eps - (qi::alnum | '_'))
+                ;   // make sure we recognize whole words only
+
+            keyword_
+                =   "and_eq", "and", "asm", "auto", "bitand", "bitor",
+                    "bool", "break", "case", "catch", "char", "class",
+                    "compl", "const_cast", "const", "continue", "default",
+                    "delete", "do", "double", "dynamic_cast",  "else",
+                    "enum", "explicit", "export", "extern", "false",
+                    "float", "for", "friend", "goto", "if", "inline",
+                    "int", "long", "mutable", "namespace", "new", "not_eq",
+                    "not", "operator", "or_eq", "or", "private",
+                    "protected", "public", "register", "reinterpret_cast",
+                    "return", "short", "signed", "sizeof", "static",
+                    "static_cast", "struct", "switch", "template", "this",
+                    "throw", "true", "try", "typedef", "typeid",
+                    "typename", "union", "unsigned", "using", "virtual",
+                    "void", "volatile", "wchar_t", "while", "xor_eq", "xor"
+                ;
+
+            special
+                =   +qi::char_("~!%^&*()+={[}]:;,<.>?/|\\-")
+                ;
+
+            string_char = ('\\' >> qi::char_) | (qi::char_ - '\\');
+
+            string_
+                =   -qi::no_case['l'] >> '"' >> *(string_char - '"') >> -qi::lit('"');
+                ;
+
+            char_
+                =   -qi::no_case['l'] >> '\'' >> *(string_char - '\'') >> -qi::lit('\'');
+                ;
+
+            number
+                =   (
+                        qi::no_case["0x"] >> qi::hex
+                    |   '0' >> qi::oct
+                    |   qi::long_double
+                    )
+                    >>  *qi::no_case[qi::char_("ldfu")]
+                ;
 
-            classic::rule<Scanner> const&
-            start() const { return program; }
-        };
+            identifier
+                =   (qi::alpha | '_') >> *(qi::alnum | '_')
+                ;
+        }
+
+        qi::rule<Iterator>
+                        program, macro, preprocessor, comment, special, string_, 
+                        char_, number, identifier, keyword, escape,
+                        string_char;
 
         Out& out;
-        Macro const& macro;
+        Macro const& macro_symbols;
         DoMacro do_macro;
         EscapeActions& escape_actions;
+
+        qi::symbols<> keyword_;
+        parse_escaped_impl<Iterator, EscapeActions> parse_escaped;
+        std::string save;
     };
 
     // Grammar for Python highlighting
@@ -182,148 +188,130 @@
       , typename PostEscape
       , typename EscapeActions
       , typename Unexpected
-      , typename Out>
+      , typename Out
+      , typename Iterator>
     struct python_highlight
-    : public classic::grammar<python_highlight<Process, Space, Macro, DoMacro, PreEscape, PostEscape, EscapeActions, Unexpected, Out> >
+    : public qi::grammar<Iterator>
     {
-        python_highlight(Out& out, Macro const& macro, DoMacro do_macro, EscapeActions& escape_actions)
-        : out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {}
-
-        template <typename Scanner>
-        struct definition
+        python_highlight(Out& out, Macro const& macro_symbols, DoMacro do_macro, EscapeActions& escape_actions)
+        : python_highlight::base_type(program), out(out), macro_symbols(macro_symbols), do_macro(do_macro), escape_actions(escape_actions)
+        , parse_escaped(escape_actions)
         {
-            definition(python_highlight const& self)
-                : common(self.escape_actions, unused)
-                , unused(false)
-            {
-                program
-                    =
-                    *(  (+classic::space_p)      [Space(self.out)]
-                    |   macro
-                    |   escape          
-                    |   comment         [Process("comment", self.out)]
-                    |   keyword         [Process("keyword", self.out)]
-                    |   identifier      [Process("identifier", self.out)]
-                    |   special         [Process("special", self.out)]
-                    |   string_         [Process("string", self.out)]
-                    |   number          [Process("number", self.out)]
-                    |   classic::repeat_p(1)[classic::anychar_p] [Unexpected(self.out)]
-                    )
-                    ;
-
-                macro = 
-                    classic::eps_p(self.macro                    // must not be followed by
-                        >> (classic::eps_p - (classic::alpha_p | '_')))   // alpha or underscore
-                    >> self.macro                       [self.do_macro]
-                    ;
-
-                qbk_phrase =
-                   *(   common
-                    |   (classic::anychar_p - classic::str_p("``"))   [self.escape_actions.plain_char]
-                    )
-                    ;
-
-                escape =
-                    classic::str_p("``")         [PreEscape(self.escape_actions, save)]
-                    >>
+            program
+                =
+                *(  qi::raw[+qi::space]     [Space(out)]
+                |   macro
+                |   escape          
+                |   qi::raw[comment]        [Process("comment", out)]
+                |   qi::raw[keyword]        [Process("keyword", out)]
+                |   qi::raw[identifier]     [Process("identifier", out)]
+                |   qi::raw[special]        [Process("special", out)]
+                |   qi::raw[string_]        [Process("string", out)]
+                |   qi::raw[number]         [Process("number", out)]
+                |   qi::raw[qi::char_]      [Unexpected(out)]
+                )
+                ;
+
+            macro = 
+                &(macro_symbols                         // must not be followed by
+                    >> (qi::eps - (qi::alpha | '_')))   // alpha or underscore
+                >> macro_symbols            [do_macro]
+                ;
+
+            escape =
+                qi::string("``")            [PreEscape(escape_actions, save)]
+                >>
+                (
                     (
                         (
-                            (
-                                (+(classic::anychar_p - "``") >> classic::eps_p("``"))
-                                & qbk_phrase
-                            )
-                            >>  classic::str_p("``")
+                            qi::raw[+(qi::char_ - "``") >> &qi::lit("``")]
+                                [parse_escaped]
                         )
-                        |
-                        (
-                            classic::eps_p       [self.escape_actions.error]
-                            >> *classic::anychar_p
-                        )
-                    )                   [PostEscape(self.out, self.escape_actions, save)]
-                    ;
+                        >>  qi::string("``")
+                    )
+                    |
+                    (
+                        qi::raw[qi::eps]    [escape_actions.error]
+                    >>  *qi::char_
+                    )
+                )                           [PostEscape(out, escape_actions, save)]
+                ;
 
-                comment
-                    =   classic::comment_p("#")
-                    ;
-
-                keyword
-                    =   keyword_ >> (classic::eps_p - (classic::alnum_p | '_'))
-                    ;   // make sure we recognize whole words only
-
-                keyword_
-                    =
-                    "and",       "del",       "for",       "is",        "raise",    
-                    "assert",    "elif",      "from",      "lambda",    "return",   
-                    "break",     "else",      "global",    "not",       "try",  
-                    "class",     "except",    "if",        "or",        "while",    
-                    "continue",  "exec",      "import",    "pass",      "yield",   
-                    "def",       "finally",   "in",        "print",
-
-                    // Technically "as" and "None" are not yet keywords (at Python
-                    // 2.4). They are destined to become keywords, and we treat them 
-                    // as such for syntax highlighting purposes.
-                    
-                    "as", "None"
-                    ;
-
-                special
-                    =   +classic::chset_p("~!%^&*()+={[}]:;,<.>/|\\-")
-                    ;
-
-                string_prefix
-                    =    classic::as_lower_d[classic::str_p("u") >> ! classic::str_p("r")]
-                    ;
+            comment
+                = qi::lit('#') >> *(qi::char_ - qi::eol) >> -qi::eol;
+                ;
+
+            keyword
+                =   keyword_ >> (qi::eps - (qi::alnum | '_'))
+                ;   // make sure we recognize whole words only
+
+            keyword_
+                =
+                "and",       "del",       "for",       "is",        "raise",    
+                "assert",    "elif",      "from",      "lambda",    "return",   
+                "break",     "else",      "global",    "not",       "try",  
+                "class",     "except",    "if",        "or",        "while",    
+                "continue",  "exec",      "import",    "pass",      "yield",   
+                "def",       "finally",   "in",        "print",
+
+                // Technically "as" and "None" are not yet keywords (at Python
+                // 2.4). They are destined to become keywords, and we treat them 
+                // as such for syntax highlighting purposes.
                 
-                string_
-                    =   ! string_prefix >> (long_string | short_string)
-                    ;
+                "as", "None"
+                ;
 
-                string_char = ('\\' >> classic::anychar_p) | (classic::anychar_p - '\\');
+            special
+                =   +qi::char_("~!%^&*()+={[}]:;,<.>/|\\-")
+                ;
+
+            string_prefix
+                =    qi::no_case[qi::string("u") >> - qi::string("r")]
+                ;
             
-                short_string
-                    =   classic::confix_p('\'', * string_char, '\'') |
-                        classic::confix_p('"', * string_char, '"')
-                    ;
+            string_
+                =   - string_prefix >> (long_string | short_string)
+                ;
+
+            string_char = ('\\' >> qi::char_) | (qi::char_ - '\\');
+        
+            short_string
+                =   qi::lit('\'') >> *(string_char - '\'') >> -qi::lit('\'') |
+                    qi::lit('"') >> *(string_char - '"') >> -qi::lit('"')
+                ;
+        
+            long_string
+                =   qi::lit("'''") >> *(string_char - "'''") >> -qi::lit("'''") |
+                    qi::lit("\"\"\"") >> *(string_char - "\"\"\"") >> -qi::lit("\"\"\"")
+                ;
             
-                long_string
-                    // Note: the "str_p" on the next two lines work around
-                    // an INTERNAL COMPILER ERROR when using VC7.1
-                    =   classic::confix_p(classic::str_p("'''"), * string_char, "'''") |
-                        classic::confix_p(classic::str_p("\"\"\""), * string_char, "\"\"\"")
-                    ;
-                
-                number
-                    =   (
-                            classic::as_lower_d["0x"] >> classic::hex_p
-                        |   '0' >> classic::oct_p
-                        |   classic::real_p
-                        )
-                        >>  *classic::as_lower_d[classic::chset_p("lj")]
-                    ;
-
-                identifier
-                    =   (classic::alpha_p | '_') >> *(classic::alnum_p | '_')
-                    ;
-            }
-
-            classic::rule<Scanner>
-                            program, macro, comment, special, string_, string_prefix, 
-                            short_string, long_string, number, identifier, keyword, 
-                            qbk_phrase, escape, string_char;
-
-            classic::symbols<> keyword_;
-            phrase_grammar<EscapeActions> common;
-            std::string save;
-            bool unused;
+            number
+                =   (
+                        qi::no_case["0x"] >> qi::hex
+                    |   '0' >> qi::oct
+                    |   qi::long_double
+                    )
+                    >>  *qi::no_case[qi::char_("lj")]
+                ;
 
-            classic::rule<Scanner> const&
-            start() const { return program; }
-        };
+            identifier
+                =   (qi::alpha | '_') >> *(qi::alnum | '_')
+                ;
+        }
+
+        qi::rule<Iterator>
+                        program, macro, comment, special, string_, string_prefix, 
+                        short_string, long_string, number, identifier, keyword, 
+                        escape, string_char;
 
         Out& out;
-        Macro const& macro;
+        Macro const& macro_symbols;
         DoMacro do_macro;
         EscapeActions& escape_actions;
+
+        qi::symbols<> keyword_;
+        parse_escaped_impl<Iterator, EscapeActions> parse_escaped;
+        std::string save;
     };
 
     // Grammar for plain text (no actual highlighting)
@@ -334,74 +322,58 @@
       , typename PreEscape
       , typename PostEscape
       , typename EscapeActions
-      , typename Out>
+      , typename Out
+      , typename Iterator>
     struct teletype_highlight
-    : public classic::grammar<teletype_highlight<CharProcess, Macro, DoMacro, PreEscape, PostEscape, EscapeActions, Out> >
+    : public qi::grammar<Iterator>
     {
-        teletype_highlight(Out& out, Macro const& macro, DoMacro do_macro, EscapeActions& escape_actions)
-        : out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {}
-
-        template <typename Scanner>
-        struct definition
+        teletype_highlight(Out& out, Macro const& macro_symbols, DoMacro do_macro, EscapeActions& escape_actions)
+        : teletype_highlight::base_type(program), out(out), macro_symbols(macro_symbols), do_macro(do_macro), escape_actions(escape_actions)
+        , parse_escaped(escape_actions)
         {
-            definition(teletype_highlight const& self)
-                : common(self.escape_actions, unused)
-                , unused(false)
-            {
-                program
-                    =
-                    *(  macro
-                    |   escape          
-                    |   classic::repeat_p(1)[classic::anychar_p]          [CharProcess(self.out)]
-                    )
-                    ;
-
-                macro = 
-                    classic::eps_p(self.macro                    // must not be followed by
-                        >> (classic::eps_p - (classic::alpha_p | '_')))   // alpha or underscore
-                    >> self.macro                       [self.do_macro]
-                    ;
-
-                qbk_phrase =
-                   *(   common
-                    |   (classic::anychar_p - classic::str_p("``"))   [self.escape_actions.plain_char]
-                    )
-                    ;
-
-                escape =
-                    classic::str_p("``")         [PreEscape(self.escape_actions, save)]
-                    >>
+            program
+                =
+                *(  macro
+                |   escape          
+                |   qi::char_                           [CharProcess(out)]
+                )
+                ;
+
+            macro = 
+                &(macro_symbols                         // must not be followed by
+                    >> (qi::eps - (qi::alpha | '_')))   // alpha or underscore
+                >> macro_symbols            [do_macro]
+                ;
+
+            escape =
+                qi::lit("``")                           [PreEscape(escape_actions, save)]
+                >>
+                (
                     (
                         (
-                            (
-                                (+(classic::anychar_p - "``") >> classic::eps_p("``"))
-                                & qbk_phrase
-                            )
-                            >>  classic::str_p("``")
+                            qi::raw[+(qi::char_ - "``") >> &qi::lit("``")]
+                                [parse_escaped]
                         )
-                        |
-                        (
-                            classic::eps_p       [self.escape_actions.error]
-                            >> *classic::anychar_p
-                        )
-                    )                   [PostEscape(self.out, self.escape_actions, save)]
-                    ;
-            }
-
-            classic::rule<Scanner> program, macro, qbk_phrase, escape;
-
-            phrase_grammar<EscapeActions> common;
-            std::string save;
-            bool unused;
+                        >>  qi::string("``")
+                    )
+                    |
+                    (
+                        qi::raw[qi::eps]                [escape_actions.error]
+                        >> *qi::char_
+                    )
+                )                                       [PostEscape(out, escape_actions, save)]
+                ;
+        }
 
-            classic::rule<Scanner> const&
-            start() const { return program; }
-        };
+        qi::rule<Iterator> program, macro, escape;
 
         Out& out;
-        Macro const& macro;
+        Macro const& macro_symbols;
         DoMacro do_macro;
         EscapeActions& escape_actions;
+
+        parse_escaped_impl<Iterator, EscapeActions> parse_escaped;
+        std::string save;
     };
 
 }