Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59314 - in branches/quickbook-1.5-spirit2: . detail test
From: daniel_james_at_[hidden]
Date: 2010-01-27 17:04:43


Author: danieljames
Date: 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
New Revision: 59314
URL: http://svn.boost.org/trac/boost/changeset/59314

Log:
Make doc_info_grammar produce a synthesized attribute.

It still sets the quickbook version and source mode in action/global
state.
Added:
   branches/quickbook-1.5-spirit2/test/doc-info-1.gold (contents, props changed)
   branches/quickbook-1.5-spirit2/test/doc-info-1.quickbook (contents, props changed)
Text files modified:
   branches/quickbook-1.5-spirit2/block_actions.cpp | 8 -
   branches/quickbook-1.5-spirit2/detail/actions.cpp | 125 +++++++++++-----------------
   branches/quickbook-1.5-spirit2/detail/actions.hpp | 15 --
   branches/quickbook-1.5-spirit2/detail/actions_class.cpp | 16 ---
   branches/quickbook-1.5-spirit2/detail/actions_class.hpp | 17 ----
   branches/quickbook-1.5-spirit2/detail/quickbook.cpp | 7
   branches/quickbook-1.5-spirit2/doc_info.cpp | 167 ++++++++++++++++++++-------------------
   branches/quickbook-1.5-spirit2/grammars.hpp | 25 +++++
   branches/quickbook-1.5-spirit2/parse_utils.hpp | 55 ++++++++++++
   branches/quickbook-1.5-spirit2/test/Jamfile.v2 | 4
   10 files changed, 221 insertions(+), 218 deletions(-)

Modified: branches/quickbook-1.5-spirit2/block_actions.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/block_actions.cpp (original)
+++ branches/quickbook-1.5-spirit2/block_actions.cpp 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -401,16 +401,13 @@
     void process(quickbook::actions& actions, include const& x)
     {
         fs::path filein = include_search(actions.filename.branch_path(), x.path);
- std::string doc_type, doc_id, doc_dirname, doc_last_revision;
+ std::string doc_id;
 
         // swap the filenames
         std::swap(actions.filename, filein);
 
         // save the doc info strings
- actions.doc_type.swap(doc_type);
         actions.doc_id.swap(doc_id);
- actions.doc_dirname.swap(doc_dirname);
- actions.doc_last_revision.swap(doc_last_revision);
 
         // scope the macros
         macro_symbols macro = actions.macro;
@@ -431,10 +428,7 @@
         // restore the values
         std::swap(actions.filename, filein);
 
- actions.doc_type.swap(doc_type);
         actions.doc_id.swap(doc_id);
- actions.doc_dirname.swap(doc_dirname);
- actions.doc_last_revision.swap(doc_last_revision);
 
         // restore the macros
         actions.macro = macro;

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 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -198,22 +198,22 @@
         out << " <year>" << year << "</year>\n";
     }
 
- static void write_document_title(collector& out, quickbook::actions& actions);
- static void write_document_info(collector& out, quickbook::actions& actions);
+ static void write_document_title(collector& out, doc_info& actions);
+ static void write_document_info(collector& out, doc_info& actions);
 
- void pre(collector& out, quickbook::actions& actions, bool ignore_docinfo)
+ void pre(collector& out, quickbook::actions& actions, doc_info& info, bool ignore_docinfo)
     {
         // The doc_info in the file has been parsed. Here's what we'll do
         // *before* anything else.
 
- if (actions.doc_id.empty())
- actions.doc_id = detail::make_identifier(
- actions.doc_title.begin(),actions.doc_title.end());
+ if (info.doc_id.empty())
+ info.doc_id = detail::make_identifier(
+ info.doc_title.begin(),info.doc_title.end());
 
- if (actions.doc_dirname.empty() && actions.doc_type == "library")
- actions.doc_dirname = actions.doc_id;
+ if (info.doc_dirname.empty() && info.doc_type == "library")
+ info.doc_dirname = info.doc_id;
 
- if (actions.doc_last_revision.empty())
+ if (info.doc_last_revision.empty())
         {
             // default value for last-revision is now
 
@@ -225,60 +225,47 @@
                     "$" /* prevent CVS substitution */ "Date: %Y/%m/%d %H:%M:%S $"),
                 current_gm_time
             );
- actions.doc_last_revision = strdate;
+ info.doc_last_revision = strdate;
         }
 
+ if(!info.doc_id.empty()) actions.doc_id = info.doc_id;
+
         // if we're ignoring the document info, we're done.
         if (ignore_docinfo)
         {
             return;
         }
 
- if (qbk_major_version == 0)
- {
- // hard code quickbook version to v1.1
- qbk_major_version = 1;
- qbk_minor_version = 1;
- qbk_version_n = 101;
- detail::outwarn(actions.filename.native_file_string(),1)
- << "Warning: Quickbook version undefined. "
- "Version 1.1 is assumed" << std::endl;
- }
- else
- {
- qbk_version_n = (qbk_major_version * 100) + qbk_minor_version;
- }
-
         out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
             << "<!DOCTYPE library PUBLIC \"-//Boost//DTD BoostBook XML V1.0//EN\"\n"
             << " \"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd\">\n"
- << '<' << actions.doc_type << "\n"
- << " id=\"" << actions.doc_id << "\"\n";
+ << '<' << info.doc_type << "\n"
+ << " id=\"" << info.doc_id << "\"\n";
         
- if(actions.doc_type == "library")
+ if(info.doc_type == "library")
         {
- out << " name=\"" << actions.doc_title << "\"\n";
+ out << " name=\"" << info.doc_title << "\"\n";
         }
 
- if(!actions.doc_dirname.empty())
+ if(!info.doc_dirname.empty())
         {
- out << " dirname=\"" << actions.doc_dirname << "\"\n";
+ out << " dirname=\"" << info.doc_dirname << "\"\n";
         }
 
- out << " last-revision=\"" << actions.doc_last_revision << "\" \n"
+ out << " last-revision=\"" << info.doc_last_revision << "\" \n"
             << " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n";
             
- if(actions.doc_type == "library") {
- write_document_info(out, actions);
- write_document_title(out, actions);
+ if(info.doc_type == "library") {
+ write_document_info(out, info);
+ write_document_title(out, info);
         }
         else {
- write_document_title(out, actions);
- write_document_info(out, actions);
+ write_document_title(out, info);
+ write_document_info(out, info);
         }
     }
     
- void post(collector& out, quickbook::actions& actions, bool ignore_docinfo)
+ void post(collector& out, quickbook::actions& actions, doc_info& info, bool ignore_docinfo)
     {
         // if we're ignoring the document info, do nothing.
         if (ignore_docinfo)
@@ -288,79 +275,72 @@
 
         // We've finished generating our output. Here's what we'll do
         // *after* everything else.
- out << "\n</" << actions.doc_type << ">\n\n";
+ out << "\n</" << info.doc_type << ">\n\n";
     }
 
- void write_document_title(collector& out, quickbook::actions& actions)
+ void write_document_title(collector& out, doc_info& info)
     {
- if (!actions.doc_title.empty())
+ if (!info.doc_title.empty())
         {
- out<< " <title>" << actions.doc_title;
- if (!actions.doc_version.empty())
- out << ' ' << actions.doc_version;
+ out<< " <title>" << info.doc_title;
+ if (!info.doc_version.empty())
+ out << ' ' << info.doc_version;
             out<< "</title>\n\n\n";
         }
     }
 
- void write_document_info(collector& out, quickbook::actions& actions)
+ void write_document_info(collector& out, doc_info& info)
     {
- out << " <" << actions.doc_type << "info>\n";
+ out << " <" << info.doc_type << "info>\n";
 
- if(!actions.doc_authors.empty())
+ if(!info.doc_authors.empty())
         {
             out << " <authorgroup>\n";
             for_each(
- actions.doc_authors.begin()
- , actions.doc_authors.end()
+ info.doc_authors.begin()
+ , info.doc_authors.end()
               , xml_author(out));
             out << " </authorgroup>\n";
         }
 
- if (!actions.doc_copyrights.empty())
+ if (!info.doc_copyrights.empty())
         {
             for_each(
- actions.doc_copyrights.begin()
- , actions.doc_copyrights.end()
+ info.doc_copyrights.begin()
+ , info.doc_copyrights.end()
               , xml_copyright(out));
         }
 
- if (qbk_version_n < 103)
- {
- // version < 1.3 compatibility
- actions.doc_license = actions.doc_license_1_1;
- actions.doc_purpose = actions.doc_purpose_1_1;
- }
-
- if (!actions.doc_license.empty())
+ if (!info.doc_license.empty())
         {
             out << " <legalnotice>\n"
                 << " <para>\n"
- << " " << actions.doc_license << "\n"
+ << " " << info.doc_license << "\n"
                 << " </para>\n"
                 << " </legalnotice>\n"
                 << "\n"
             ;
         }
 
- if (!actions.doc_purpose.empty())
+ if (!info.doc_purpose.empty())
         {
- out << " <" << actions.doc_type << "purpose>\n"
- << " " << actions.doc_purpose
- << " </" << actions.doc_type << "purpose>\n"
+ out << " <" << info.doc_type << "purpose>\n"
+ << " " << info.doc_purpose
+ << " </" << info.doc_type << "purpose>\n"
                 << "\n"
             ;
         }
 
- if (!actions.doc_category.empty())
+ if (!info.doc_category.empty())
         {
- out << " <" << actions.doc_type << "category name=\"category:"
- << actions.doc_category
- << "\"></" << actions.doc_type << "category>\n"
+ out << " <" << info.doc_type << "category name=\"category:"
+ << info.doc_category
+ << "\"></" << info.doc_type << "category>\n"
                 << "\n"
             ;
         }
 
- out << " </" << actions.doc_type << "info>\n"
+ out << " </" << info.doc_type << "info>\n"
             << "\n"
         ;
     }
@@ -377,10 +357,5 @@
         phrase.pop();
         return out;
     }
-
- 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 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -148,9 +148,6 @@
 
         collector& out;
     };
-
- void pre(collector& out, quickbook::actions& actions, bool ignore_docinfo = false);
- void post(collector& out, quickbook::actions& actions, bool ignore_docinfo = false);
     
     struct phrase_push_action
     {
@@ -178,16 +175,10 @@
         collector& phrase;
     };
 
- struct phrase_to_string_action
- {
- phrase_to_string_action(std::string& out, collector& phrase)
- : out(out) , phrase(phrase) {}
-
- void operator()(unused_type, unused_type, unused_type) const;
+ struct doc_info;
 
- std::string& out;
- collector& phrase;
- };
+ void pre(collector& out, quickbook::actions& actions, doc_info& info, bool ignore_docinfo = false);
+ void post(collector& out, quickbook::actions& actions, doc_info& info, bool ignore_docinfo = false);
 
     struct code_snippet_actions
     {

Modified: branches/quickbook-1.5-spirit2/detail/actions_class.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions_class.cpp (original)
+++ branches/quickbook-1.5-spirit2/detail/actions_class.cpp 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -19,19 +19,7 @@
 {
     actions::actions(char const* filein_, fs::path const& outdir_, string_stream& out_)
     // header info
- : doc_type()
- , doc_title()
- , doc_version()
- , doc_id()
- , doc_dirname()
- , doc_copyrights()
- , doc_purpose()
- , doc_category()
- , doc_authors()
- , doc_license()
- , doc_last_revision()
- , doc_license_1_1()
- , doc_purpose_1_1()
+ : doc_id()
 
     // main output stream
         , phrase(out_)
@@ -56,8 +44,6 @@
         , phrase_push(phrase)
         , phrase_pop(phrase)
         , error(error_count)
- , extract_doc_license(doc_license, phrase)
- , extract_doc_purpose(doc_purpose, phrase)
 
         , syntax_p(source_mode, *this)
         , plain_char(phrase)

Modified: branches/quickbook-1.5-spirit2/detail/actions_class.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/detail/actions_class.hpp (original)
+++ branches/quickbook-1.5-spirit2/detail/actions_class.hpp 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -27,25 +27,10 @@
     ///////////////////////////////////////////////////////////////////////////
 
         typedef std::vector<std::string> string_list;
- typedef std::vector<std::pair<std::string, std::string> > author_list;
- typedef std::vector<std::pair<string_list, std::string> > copyright_list;
         typedef std::pair<char, int> mark_type;
         static int const max_template_depth = 100;
 
- // header info
- std::string doc_type;
- std::string doc_title;
- std::string doc_version;
         std::string doc_id;
- std::string doc_dirname;
- copyright_list doc_copyrights;
- std::string doc_purpose;
- std::string doc_category;
- author_list doc_authors;
- std::string doc_license;
- std::string doc_last_revision;
- std::string doc_license_1_1;
- std::string doc_purpose_1_1;
 
     // main output stream
         collector phrase;
@@ -88,8 +73,6 @@
         phrase_push_action phrase_push;
         phrase_pop_action phrase_pop;
         error_action error;
- phrase_to_string_action extract_doc_license;
- phrase_to_string_action extract_doc_purpose;
 
         syntax_highlight syntax_p;
         plain_char_action plain_char;

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 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -62,20 +62,21 @@
         iterator last(storage.end(), storage.end());
         iterator start = first;
 
+ doc_info info;
         doc_info_grammar l(actor);
- bool success = parse(first, last, l);
+ bool success = parse(first, last, l, info);
 
         if (success || ignore_docinfo)
         {
             if(!success) first = start;
 
- pre(actor.phrase, actor, ignore_docinfo);
+ pre(actor.phrase, actor, info, ignore_docinfo);
 
             block_grammar g(actor);
             success = parse(first, last, g);
             if (success && first == last)
             {
- post(actor.phrase, actor, ignore_docinfo);
+ post(actor.phrase, actor, info, ignore_docinfo);
             }
         }
         else {

Modified: branches/quickbook-1.5-spirit2/doc_info.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/doc_info.cpp (original)
+++ branches/quickbook-1.5-spirit2/doc_info.cpp 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -18,14 +18,38 @@
 #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/qi_attr_cast.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_container.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#include <boost/fusion/include/std_pair.hpp>
 
 namespace quickbook
 {
     namespace qi = boost::spirit::qi;
     namespace ph = boost::phoenix;
+
+ void set_quickbook_version(boost::optional<std::pair<unsigned, unsigned> > version)
+ {
+ if (version)
+ {
+ qbk_major_version = version->first;
+ qbk_minor_version = version->second;
+ }
+ else
+ {
+ qbk_major_version = 1;
+ qbk_minor_version = 1;
+
+ // TODO:
+ //detail::outwarn(actions.filename.native_file_string(),1)
+ // << "Warning: Quickbook version undefined. "
+ // "Version 1.1 is assumed" << std::endl;
+ }
+
+ qbk_version_n = (qbk_major_version * 100) + qbk_minor_version;
+ }
 
     struct doc_info_grammar::rules
     {
@@ -33,21 +57,21 @@
 
         quickbook::actions& actions;
         bool unused;
- std::pair<std::string, std::string> name;
- std::pair<std::vector<std::string>, std::string> copyright;
         phrase_grammar 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;
+ qi::rule<iterator, doc_info()> doc_info_details;
+ qi::rule<iterator> comment, space, hard_space;
+ qi::rule<iterator, std::pair<unsigned, unsigned>()> quickbook_version;
+ qi::rule<iterator, std::string()> phrase, doc_version, doc_id, doc_dirname, doc_category, doc_last_revision, doc_source_mode, doc_purpose, doc_license;
+ qi::rule<iterator, std::pair<std::vector<std::string>, std::string>()> doc_copyright;
+ qi::rule<iterator, std::vector<std::pair<std::string, std::string> >()> doc_authors;
+ qi::rule<iterator, std::pair<std::string, std::string>()> doc_author;
     };
 
     doc_info_grammar::doc_info_grammar(quickbook::actions& actions)
             : doc_info_grammar::base_type(start)
             , rules_pimpl(new rules(actions))
- , start(rules_pimpl->doc_info) {}
+ , start(rules_pimpl->doc_info_details) {}
 
     doc_info_grammar::~doc_info_grammar() {}
 
@@ -63,108 +87,89 @@
           , "reference", "set"
         ;
         
- doc_info =
+ doc_info_details =
             space
>> '[' >> space
- >> qi::raw[doc_types] [ph::ref(actions.doc_type) = as_string(qi::_1)]
+ >> qi::raw[doc_types] [member_assign(&doc_info::doc_type)]
>> hard_space
>> ( *(qi::char_ -
                     (qi::char_('[') | ']' | qi::eol)
                     )
- ) [ph::ref(actions.doc_title) = as_string(qi::_1)]
- >> -(
- space >> '[' >>
- quickbook_version
- >> space >> ']'
- )
+ ) [member_assign(&doc_info::doc_title)]
+ >> quickbook_version [set_quickbook_version]
>>
                 *(
                     space >> '[' >>
                     (
- doc_version
- | doc_id
- | doc_dirname
- | doc_copyright [ph::push_back(ph::ref(actions.doc_copyrights), ph::ref(copyright))]
- | doc_purpose [actions.extract_doc_purpose]
- | doc_category
- | doc_authors
- | doc_license [actions.extract_doc_license]
- | doc_last_revision
- | doc_source_mode
+ doc_version [member_assign(&doc_info::doc_version)]
+ | doc_id [member_assign(&doc_info::doc_id)]
+ | doc_dirname [member_assign(&doc_info::doc_dirname)]
+ | doc_copyright [ph::push_back(ph::bind(&doc_info::doc_copyrights, qi::_val), qi::_1)]
+ | doc_purpose [member_assign(&doc_info::doc_purpose)]
+ | doc_category [member_assign(&doc_info::doc_category)]
+ | doc_authors [member_assign(&doc_info::doc_authors)]
+ | doc_license [member_assign(&doc_info::doc_license)]
+ | doc_last_revision [member_assign(&doc_info::doc_last_revision)]
+ // This has to be set in actions so that source code in phrases use the
+ // correct encoding.
+ | doc_source_mode [ph::ref(actions.source_mode) = qi::_1]
                     )
>> space >> ']' >> +qi::eol
                 )
>> space >> ']' >> +qi::eol
             ;
 
- quickbook_version =
- "quickbook" >> hard_space
- >> ( qi::uint_ [ph::ref(qbk_major_version) = qi::_1]
- >> '.'
- >> uint2_t() [ph::ref(qbk_minor_version) = qi::_1]
- )
- ;
-
- doc_version =
- "version" >> hard_space
- >> qi::raw[*(qi::char_ - ']')] [ph::ref(actions.doc_version) = as_string(qi::_1)]
- ;
-
- doc_id =
- "id" >> hard_space
- >> qi::raw[*(qi::char_ - ']')] [ph::ref(actions.doc_id) = as_string(qi::_1)]
- ;
-
- doc_dirname =
- "dirname" >> hard_space
- >> qi::raw[*(qi::char_ - ']')] [ph::ref(actions.doc_dirname) = as_string(qi::_1)]
- ;
+ quickbook_version = -(
+ space >> '['
+ >> "quickbook"
+ >> hard_space
+ >> qi::uint_
+ >> '.'
+ >> uint2_t()
+ >> space >> ']'
+ );
+
+ doc_version = "version" >> hard_space >> *(qi::char_ - ']');
+ doc_id = "id" >> hard_space >> *(qi::char_ - ']');
+ doc_dirname = "dirname" >> hard_space >> *(qi::char_ - ']');
+ doc_category="category" >> hard_space >> *(qi::char_ - ']');
+ doc_last_revision = "last-revision" >> hard_space >> *(qi::char_ - ']');
 
         doc_copyright =
- "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
- >> (*(qi::char_ - ']')) [ph::ref(copyright.second) = as_string(qi::_1)]
+ "copyright"
+ >> hard_space
+ >> +(qi::repeat(4)[qi::digit] >> space)
+ >> qi::raw[(*(qi::char_ - ']'))]
             ;
 
         doc_purpose =
                 "purpose" >> hard_space
- >> qi::raw[phrase] [ph::ref(actions.doc_purpose_1_1) = as_string(qi::_1)]
- ;
-
- doc_category =
- "category" >> hard_space
- >> (*(qi::char_ - ']')) [ph::ref(actions.doc_category) = as_string(qi::_1)]
+ >> (
+ qi::eps(qbk_before(103)) >> qi::raw[phrase] |
+ qi::eps(qbk_since(103)) >> phrase
+ )
             ;
 
         doc_author =
                 space
- >> '[' >> space
- >> (*(qi::char_ - ',')) [ph::ref(name.second) = as_string(qi::_1)] // surname
+ >> '['
+ >> space
+ >> (*(qi::char_ - ',')) [member_assign(&std::pair<std::string, std::string>::second)]
>> ',' >> space
- >> (*(qi::char_ - ']')) [ph::ref(name.first) = as_string(qi::_1)] // firstname
+ >> (*(qi::char_ - ']')) [member_assign(&std::pair<std::string, std::string>::first)]
>> ']'
             ;
 
- doc_authors =
- "authors" >> hard_space
- >> doc_author [ph::push_back(ph::ref(actions.doc_authors), ph::ref(name))]
- >> *( ','
- >> doc_author [ph::push_back(ph::ref(actions.doc_authors), ph::ref(name))]
- )
- ;
+ doc_authors = "authors" >> hard_space >> (doc_author % ',') ;
 
         doc_license =
                 "license" >> hard_space
- >> qi::raw[phrase] [ph::ref(actions.doc_license_1_1) = as_string(qi::_1)]
+ >> (
+ qi::eps(qbk_before(103)) >> qi::raw[phrase] |
+ qi::eps(qbk_since(103)) >> phrase
+ )
             ;
 
- doc_last_revision =
- "last-revision" >> hard_space
- >> (*(qi::char_ - ']')) [ph::ref(actions.doc_last_revision) = as_string(qi::_1)]
- ;
 
         doc_source_mode =
                 "source-mode" >> hard_space
@@ -172,7 +177,7 @@
                    qi::string("c++")
                 | qi::string("python")
                 | qi::string("teletype")
- ) [ph::ref(actions.source_mode) = qi::_1]
+ )
             ;
 
         comment =
@@ -188,10 +193,12 @@
             ; // alpha-numeric or underscore
 
         phrase =
- *( common
- | comment
- | (qi::char_ - ']') [actions.plain_char]
- )
+ qi::eps [actions.phrase_push]
+ >> *( common
+ | comment
+ | (qi::char_ - ']') [actions.plain_char]
+ )
+ >> qi::eps [actions.phrase_pop]
             ;
     }
 }

Modified: branches/quickbook-1.5-spirit2/grammars.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/grammars.hpp (original)
+++ branches/quickbook-1.5-spirit2/grammars.hpp 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -58,14 +58,33 @@
         block_grammar& operator=(block_grammar const&);
     };
 
- struct doc_info_grammar : qi::grammar<iterator>
+ struct doc_info
+ {
+ typedef std::vector<std::string> string_list;
+ typedef std::vector<std::pair<std::string, std::string> > author_list;
+ typedef std::vector<std::pair<string_list, std::string> > copyright_list;
+
+ std::string doc_type;
+ std::string doc_title;
+ std::string doc_version;
+ std::string doc_id;
+ std::string doc_dirname;
+ copyright_list doc_copyrights;
+ std::string doc_purpose;
+ std::string doc_category;
+ author_list doc_authors;
+ std::string doc_license;
+ std::string doc_last_revision;
+ };
+
+ struct doc_info_grammar : qi::grammar<iterator, doc_info()>
     {
         doc_info_grammar(quickbook::actions& actions);
         ~doc_info_grammar();
 
         struct rules;
         boost::scoped_ptr<rules> rules_pimpl;
- qi::rule<iterator> start;
+ qi::rule<iterator, doc_info()> start;
     private:
         doc_info_grammar(doc_info_grammar const&);
         doc_info_grammar& operator=(doc_info_grammar const&);
@@ -109,5 +128,3 @@
 }
 
 #endif // BOOST_SPIRIT_QUICKBOOK_GRAMMARS_HPP
-
-

Modified: branches/quickbook-1.5-spirit2/parse_utils.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/parse_utils.hpp (original)
+++ branches/quickbook-1.5-spirit2/parse_utils.hpp 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -15,10 +15,17 @@
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_function.hpp>
 #include <boost/spirit/include/support_attributes.hpp>
+#include <boost/spirit/include/phoenix_bind.hpp>
+#include <boost/spirit/include/qi_core.hpp>
 #include <string>
 
 namespace quickbook
 {
+ namespace qi = boost::spirit::qi;
+ namespace ph = boost::phoenix;
+
+ // as_string - converts a char range to a string.
+
     struct as_string_impl
     {
         template <typename Arg>
@@ -39,12 +46,56 @@
         }
     };
 
- namespace ph = boost::phoenix;
-
     namespace {
         get_position_impl get_position;
         ph::function<as_string_impl> as_string;
     }
+
+ // member_assign - action to assign the attribute to a member of the
+ // rule's attributte.
+
+ template <typename Struct, typename Member>
+ struct member_assign_type {
+ member_assign_type(Member Struct::*mem_ptr) : mem_ptr_(mem_ptr) {}
+
+ template <typename Context>
+ void operator()(Member& attrib, Context& context, bool& pass) const {
+ namespace qi = boost::spirit::qi;
+ namespace ph = boost::phoenix;
+
+ (ph::bind(mem_ptr_, qi::_val) = attrib)(attrib, context, pass);
+ }
+
+ Member Struct::*mem_ptr_;
+ };
+
+ template <typename Struct>
+ struct member_assign_type<Struct, std::string> {
+ member_assign_type(std::string Struct::*mem_ptr) : mem_ptr_(mem_ptr) {}
+
+ template <typename Context>
+ void operator()(std::string& attrib, Context& context, bool& pass) const {
+ namespace qi = boost::spirit::qi;
+ namespace ph = boost::phoenix;
+
+ (ph::bind(mem_ptr_, qi::_val) = attrib)(attrib, context, pass);
+ }
+
+ template <typename Attrib, typename Context>
+ void operator()(Attrib& attrib, Context& context, bool& pass) const {
+ namespace qi = boost::spirit::qi;
+ namespace ph = boost::phoenix;
+
+ (ph::bind(mem_ptr_, qi::_val) = std::string(attrib.begin(), attrib.end()))(attrib, context, pass);
+ }
+
+ std::string Struct::*mem_ptr_;
+ };
+
+ template <typename Struct, typename Member>
+ member_assign_type<Struct, Member> member_assign(Member Struct::*mem_ptr) {
+ return member_assign_type<Struct, Member>(mem_ptr);
+ }
 }
 
 #endif

Modified: branches/quickbook-1.5-spirit2/test/Jamfile.v2
==============================================================================
--- branches/quickbook-1.5-spirit2/test/Jamfile.v2 (original)
+++ branches/quickbook-1.5-spirit2/test/Jamfile.v2 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -32,6 +32,7 @@
     [ quickbook-test image_1_5 ]
     [ quickbook-test list_test ]
     [ quickbook-test cond_phrase ]
+ [ quickbook-test doc-info-1 ]
     [ quickbook-fail-test fail-include ]
     [ quickbook-fail-test fail-import ]
     [ quickbook-fail-test fail-template-arguments1 ]
@@ -45,6 +46,3 @@
     [ quickbook-fail-test fail-template-lookup1 ]
     [ quickbook-fail-test fail-image_1_5 ]
     ;
-
-
-

Added: branches/quickbook-1.5-spirit2/test/doc-info-1.gold
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/test/doc-info-1.gold 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<article id="document_information_1" last-revision="DEBUG MODE Date: 2000/12/20 12:00:00 $"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Document Information 1</title>
+ <articleinfo>
+ <articlepurpose>
+ Inline code test: <code>1 + 2</code>
+ </articlepurpose>
+ </articleinfo>
+ <para>
+ The body is largely irrelevant.
+ </para>
+</article>

Added: branches/quickbook-1.5-spirit2/test/doc-info-1.quickbook
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/test/doc-info-1.quickbook 2010-01-27 17:04:42 EST (Wed, 27 Jan 2010)
@@ -0,0 +1,7 @@
+[article Document Information 1
+[quickbook 1.5]
+[source-mode teletype]
+[purpose Inline code test: `1 + 2`]
+]
+
+The body is largely irrelevant.
\ No newline at end of file


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