Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59295 - in branches/quickbook-1.5-spirit2: . detail
From: daniel_james_at_[hidden]
Date: 2010-01-27 17:00:56


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

Log:
Convert links, urls and source mode to use synthesized attributes and
symbol tables. And use a generic visitor to process them.
Added:
   branches/quickbook-1.5-spirit2/phrase.hpp (contents, props changed)
   branches/quickbook-1.5-spirit2/phrase_actions.cpp (contents, props changed)
Text files modified:
   branches/quickbook-1.5-spirit2/Jamfile.v2 | 1
   branches/quickbook-1.5-spirit2/detail/actions.cpp | 35 ++++--------
   branches/quickbook-1.5-spirit2/detail/actions.hpp | 93 ++++++++++++++++++++++-----------
   branches/quickbook-1.5-spirit2/detail/actions_class.cpp | 5 +
   branches/quickbook-1.5-spirit2/detail/actions_class.hpp | 5 +
   branches/quickbook-1.5-spirit2/phrase.cpp | 110 +++++++++++++++++++++------------------
   6 files changed, 141 insertions(+), 108 deletions(-)

Modified: branches/quickbook-1.5-spirit2/Jamfile.v2
==============================================================================
--- branches/quickbook-1.5-spirit2/Jamfile.v2 (original)
+++ branches/quickbook-1.5-spirit2/Jamfile.v2 2010-01-27 17:00:54 EST (Wed, 27 Jan 2010)
@@ -28,6 +28,7 @@
     detail/template_stack.cpp
     detail/markups.cpp
     phrase.cpp
+ phrase_actions.cpp
     block.cpp
     doc_info.cpp
     detail/syntax_highlight.cpp

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:00:54 EST (Wed, 27 Jan 2010)
@@ -844,28 +844,6 @@
         --actions.template_depth;
     }
 
- void generic_link_action::operator()(char const* tag, iterator_range x) const
- {
- iterator first = x.begin(), last = x.end();
- iterator save = first;
- phrase << tag;
- while (first != last)
- detail::print_char(*first++, phrase.get());
- phrase << "\">";
-
- // Yes, it is safe to dereference last here. When we
- // reach here, *last is certainly valid. We test if
- // *last == ']'. In which case, the url is the text.
- // Example: [@http://spirit.sourceforge.net/]
-
- if (*last == ']')
- {
- first = save;
- while (first != last)
- detail::print_char(*first++, phrase.get());
- }
- }
-
     void variablelist_action::operator()(std::string const& title) const
     {
         actions.out << "<variablelist>\n";
@@ -1542,6 +1520,19 @@
         ;
     }
 
+ void phrase_push_action::operator()(unused_type, unused_type, unused_type) const
+ {
+ phrase.push();
+ }
+
+ std::string phrase_pop_action::operator()() const
+ {
+ std::string out;
+ phrase.swap(out);
+ 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:00:54 EST (Wed, 27 Jan 2010)
@@ -395,23 +395,6 @@
         int& error_count;
     };
 
- struct generic_markup_action
- {
- template <typename Arg1> struct result { typedef void type; };
-
- // Handles links (URL, XML refentry, function, class, member)
-
- generic_markup_action(collector& phrase)
- : phrase(phrase) {}
-
- void operator()(char const* str) const
- {
- phrase << str;
- }
-
- collector& phrase;
- };
-
     struct markup_action
     {
         template <typename T = void> struct result { typedef void type; };
@@ -581,20 +564,6 @@
         quickbook::actions& actions;
     };
 
- struct generic_link_action
- {
- template <typename Arg1, typename Arg2> struct result { typedef void type; };
-
- // Handles links (URL, XML refentry, function, class, member)
-
- generic_link_action(collector& phrase)
- : phrase(phrase) {}
-
- void operator()(char const*, iterator_range) const;
-
- collector& phrase;
- };
-
     struct variablelist_action
     {
         // Handles variable lists
@@ -793,6 +762,32 @@
 
     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
+ {
+ phrase_push_action(collector& phrase)
+ : phrase(phrase) {}
+
+ void operator()(unused_type, unused_type, unused_type) const;
+
+ collector& phrase;
+ };
+
+ struct phrase_pop_action
+ {
+ phrase_pop_action(collector& phrase)
+ : phrase(phrase) {}
+
+ template <typename Context>
+ void operator()(unused_type x1, Context& c, unused_type x2) const
+ {
+ boost::spirit::_val(x1, c, x2) = (*this)();
+ }
+
+ std::string operator()() const;
+
+ collector& phrase;
+ };
 
     struct phrase_to_string_action
     {
@@ -830,6 +825,42 @@
         std::string const doc_id;
         char const* const source_type;
     };
+
+ struct process_action
+ {
+ process_action(quickbook::actions& actions)
+ : actions(actions) {}
+
+ typedef void result_type;
+
+ template <typename Arg1, typename Arg2 = void, typename Arg3 = void>
+ struct result { typedef void type; };
+
+ template <typename Attrib, typename Context>
+ void operator()(Attrib& a, Context& c, bool& pass) const {
+ (*this)(a);
+ }
+
+ template <typename T>
+ void operator()(boost::optional<T> const& x) const {
+ if(x) (*this)(*x);
+ }
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ void operator()(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& x) const {
+ return boost::apply_visitor(*this, x);
+ }
+
+ void operator()(unused_type) const {
+ }
+
+ template <typename T>
+ void operator()(T const& x) const {
+ process(actions, x);
+ }
+
+ quickbook::actions& actions;
+ };
 }
 
 #ifdef BOOST_MSVC

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:00:54 EST (Wed, 27 Jan 2010)
@@ -63,6 +63,9 @@
         , error_count(0)
 
     // actions
+ , process(*this)
+ , phrase_push(phrase)
+ , phrase_pop(phrase)
         , error(error_count)
         , extract_doc_license(doc_license, phrase)
         , extract_doc_purpose(doc_purpose, phrase)
@@ -136,8 +139,6 @@
         , do_macro(phrase)
         , template_body(*this)
         , do_template(*this)
- , generic_link_pre(phrase)
- , generic_link_post(phrase)
         , url_pre(url_pre_)
         , url_post(url_post_)
         , link_pre(link_pre_)

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:00:54 EST (Wed, 27 Jan 2010)
@@ -97,6 +97,9 @@
     ///////////////////////////////////////////////////////////////////////////
     // actions
     ///////////////////////////////////////////////////////////////////////////
+ process_action process;
+ 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;
@@ -159,8 +162,6 @@
         do_macro_action do_macro;
         template_body_action template_body;
         do_template_action do_template;
- generic_link_action generic_link_pre;
- generic_markup_action generic_link_post;
         char const* url_pre;
         char const* url_post;
         char const* link_pre;

Modified: branches/quickbook-1.5-spirit2/phrase.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.cpp (original)
+++ branches/quickbook-1.5-spirit2/phrase.cpp 2010-01-27 17:00:54 EST (Wed, 27 Jan 2010)
@@ -7,9 +7,8 @@
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
-#if !defined(BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP)
-#define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
 
+#include "./phrase.hpp"
 #include "./grammars.hpp"
 #include "./detail/quickbook.hpp"
 #include "./detail/utils.hpp"
@@ -19,6 +18,8 @@
 #include <map>
 #include <boost/spirit/include/qi_core.hpp>
 #include <boost/spirit/include/qi_auxiliary.hpp>
+#include <boost/spirit/include/qi_attr.hpp>
+#include <boost/spirit/include/qi_symbols.hpp>
 #include <boost/spirit/repository/include/qi_confix.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
@@ -27,6 +28,14 @@
 #include <boost/spirit/include/phoenix_bind.hpp>
 #include <boost/spirit/include/phoenix_function.hpp>
 #include <boost/fusion/include/std_pair.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+
+BOOST_FUSION_ADAPT_STRUCT(
+ quickbook::link,
+ (quickbook::link_type, type)
+ (std::string, destination)
+ (std::string, content)
+)
 
 namespace quickbook
 {
@@ -43,10 +52,9 @@
         qi::rule<iterator>
                         space, blank, comment, phrase, phrase_markup,
                         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,
- source_mode, template_,
+ strikethrough, escape, common,
+ anchor, hard_space, eol, inline_code, simple_format,
+ template_,
                         quote, code_block, footnote, replaceable, macro,
                         dummy_block, cond_phrase, macro_identifier,
                         brackets_1_4, template_inner_arg_1_5, brackets_1_5
@@ -55,13 +63,18 @@
         qi::rule<iterator, std::string()> template_arg_1_4, template_arg_1_5;
         qi::rule<iterator, std::vector<std::string>() > template_args;
 
+ qi::rule<iterator, std::string()> phrase_attr;
+
         qi::rule<iterator> image, image_1_4, image_1_5;
         qi::rule<iterator, std::string()> image_filename, image_attribute_key, image_attribute_value;
         qi::rule<iterator, std::multimap<std::string, std::string>()> image_attributes;
         qi::rule<iterator, std::pair<std::string, std::string>()> image_attribute;
         
         qi::rule<iterator, boost::iterator_range<iterator>(char)> simple_markup;
- qi::rule<iterator, void(char const*, char const*, char const*)> generic_link;
+ qi::symbols<char, link_type> link_symbol;
+ qi::rule<iterator, quickbook::link()> link, url;
+
+ qi::symbols<char, quickbook::source_mode> source_mode;
     };
 
     phrase_grammar::phrase_grammar(quickbook::actions& actions, bool& no_eols)
@@ -231,22 +244,21 @@
             )
             ;
 
+ phrase_attr =
+ qi::eps [actions.phrase_push]
+ >> ( phrase
+ | qi::eps
+ ) [actions.phrase_pop]
+ ;
+
         phrase_markup =
                 '['
>> ( cond_phrase
                 | image
- | url
- | link
+ | url [actions.process]
+ | link [actions.process]
                 | anchor
- | source_mode
- | funcref
- | classref
- | memberref
- | enumref
- | macroref
- | headerref
- | conceptref
- | globalref
+ | source_mode [actions.process]
                 | bold
                 | italic
                 | underline
@@ -324,40 +336,41 @@
         image_attribute_key = *(qi::alnum | '_');
         image_attribute_value = *(qi::char_ - (phrase_end | '['));
 
- url =
- '@'
- >> qi::raw[*(qi::char_ -
- (']' | qi::space))] [ph::bind(actions.generic_link_pre, actions.url_pre, qi::_1)]
- >> ( &qi::lit(']')
- | (hard_space >> phrase)
- ) [ph::bind(actions.generic_link_post, actions.url_post)]
- ;
-
         anchor =
                 '#'
>> blank
>> qi::raw[*(qi::char_ - phrase_end)] [actions.anchor]
             ;
 
- generic_link =
- qi::string(qi::_r1)
+ link_symbol.add
+ ("link", link_type(link_pre_, link_post_))
+ ("funcref", link_type(funcref_pre_, funcref_post_))
+ ("classref", link_type(classref_pre_, classref_post_))
+ ("memberref", link_type(memberref_pre_, memberref_post_))
+ ("enumref", link_type(enumref_pre_, enumref_post_))
+ ("macroref", link_type(macroref_pre_, macroref_post_))
+ ("headerref", link_type(headerref_pre_, headerref_post_))
+ ("conceptref", link_type(conceptref_pre_, conceptref_post_))
+ ("globalref", link_type(globalref_pre_, globalref_post_))
+ ;
+
+ link =
+ link_symbol
>> hard_space
- >> qi::raw[*(qi::char_ -
- (']' | qi::space))] [ph::bind(actions.generic_link_pre, qi::_r2, qi::_1)]
+ >> *(qi::char_ - (']' | qi::space))
>> ( &qi::lit(']')
- | (hard_space >> phrase)
- ) [ph::bind(actions.generic_link_post, qi::_r3)]
+ | (hard_space >> phrase_attr)
+ )
             ;
 
- link = generic_link((char const*)"link", link_pre_, link_post_);
- funcref = generic_link((char const*)"funcref", funcref_pre_, funcref_post_);
- classref = generic_link((char const*)"classref", classref_pre_, classref_post_);
- memberref = generic_link((char const*)"memberref", memberref_pre_, memberref_post_);
- enumref = generic_link((char const*)"enumref", enumref_pre_, enumref_post_);
- macroref = generic_link((char const*)"macroref", macroref_pre_, macroref_post_);
- headerref = generic_link((char const*)"headerref", headerref_pre_, headerref_post_);
- conceptref = generic_link((char const*)"conceptref", conceptref_pre_, conceptref_post_);
- globalref = generic_link((char const*)"globalref", globalref_pre_, globalref_post_);
+ url =
+ '@'
+ >> qi::attr(link_type(url_pre_, url_post_))
+ >> *(qi::char_ - (']' | qi::space))
+ >> ( &qi::lit(']')
+ | (hard_space >> phrase_attr)
+ )
+ ;
 
         bold =
                 qi::char_('*') [actions.bold_pre]
@@ -394,12 +407,10 @@
>> blank >> phrase [actions.replaceable_post]
             ;
 
- source_mode =
- (
- qi::string("c++")
- | qi::string("python")
- | qi::string("teletype")
- ) [ph::ref(actions.source_mode) = qi::_1]
+ source_mode.add
+ ("c++", quickbook::source_mode("c++"))
+ ("python", quickbook::source_mode("python"))
+ ("teletype", quickbook::source_mode("teletype"))
             ;
 
         footnote =
@@ -444,6 +455,3 @@
             ;
     }
 }
-
-#endif // BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
-

Added: branches/quickbook-1.5-spirit2/phrase.hpp
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/phrase.hpp 2010-01-27 17:00:54 EST (Wed, 27 Jan 2010)
@@ -0,0 +1,48 @@
+/*=============================================================================
+ Copyright (c) 2002 2004 2006 Joel de Guzman
+ Copyright (c) 2004 Eric Niebler
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP)
+#define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
+
+#include <string>
+
+namespace quickbook
+{
+ // TODO: Add to a forward header somewhere.
+ class actions;
+
+ struct source_mode {
+ source_mode() {}
+ source_mode(std::string const& m) : mode(m) {}
+
+ std::string mode;
+ };
+
+ struct link_type {
+ link_type()
+ : pre(""), post("") {}
+ link_type(char const* pre, char const* post)
+ : pre(pre), post(post) {}
+
+ char const* pre;
+ char const* post;
+ };
+
+ struct link {
+ link_type type;
+ std::string destination;
+ std::string content;
+ };
+
+ void process(quickbook::actions& actions, source_mode const& s);
+ void process(quickbook::actions& actions, link const& x);
+}
+
+#endif // BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
+

Added: branches/quickbook-1.5-spirit2/phrase_actions.cpp
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/phrase_actions.cpp 2010-01-27 17:00:54 EST (Wed, 27 Jan 2010)
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2002 2004 2006 Joel de Guzman
+ Copyright (c) 2004 Eric Niebler
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+#include "./phrase.hpp"
+#include "./detail/actions_class.hpp"
+
+namespace quickbook
+{
+ void process(quickbook::actions& actions, source_mode const& s) {
+ actions.source_mode = s.mode;
+ }
+
+ void process(quickbook::actions& actions, link const& x) {
+ actions.phrase << x.type.pre;
+ detail::print_string(x.destination, actions.phrase.get());
+ actions.phrase << "\">";
+ if(x.content.empty())
+ detail::print_string(x.destination, actions.phrase.get());
+ else
+ actions.phrase << x.content;
+ actions.phrase << x.type.post;
+ }
+}


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