Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r59569 - branches/quickbook-1.5-spirit2
From: daniel_james_at_[hidden]
Date: 2010-02-07 09:48:29


Author: danieljames
Date: 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
New Revision: 59569
URL: http://svn.boost.org/trac/boost/changeset/59569

Log:
Create an abstract interface for encoding the output. Sort of.
Added:
   branches/quickbook-1.5-spirit2/encoder.hpp (contents, props changed)
Removed:
   branches/quickbook-1.5-spirit2/boostbook.hpp
Text files modified:
   branches/quickbook-1.5-spirit2/boostbook.cpp | 102 ++++++++++++++++++++++++---------------
   branches/quickbook-1.5-spirit2/fwd.hpp | 7 ++
   branches/quickbook-1.5-spirit2/phrase_actions.cpp | 12 ++-
   branches/quickbook-1.5-spirit2/process.cpp | 8 +-
   branches/quickbook-1.5-spirit2/quickbook.cpp | 2
   branches/quickbook-1.5-spirit2/state.cpp | 4 +
   branches/quickbook-1.5-spirit2/state.hpp | 4 +
   7 files changed, 87 insertions(+), 52 deletions(-)

Modified: branches/quickbook-1.5-spirit2/boostbook.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/boostbook.cpp (original)
+++ branches/quickbook-1.5-spirit2/boostbook.cpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -1,25 +1,49 @@
 #include <algorithm>
 #include <boost/foreach.hpp>
 #include "fwd.hpp"
-#include "boostbook.hpp"
+#include "encoder.hpp"
 #include "phrase.hpp"
 #include "state.hpp"
 
 namespace quickbook
 {
- struct output_action
- {
- output_action(quickbook::state& state) : state(state) {}
- quickbook::state& state;
-
- template <typename T>
- void operator()(T const& x) const {
- output(state, x);
- }
+ struct boostbook_encoder : encoder {
+ virtual void operator()(quickbook::state&, doc_info const&) const;
+ virtual void operator()(quickbook::state&, doc_info_post const&) const;
+
+ // Note: char is a plain quickbook character, string is an encoded
+ // boostbook string. Oops.
+ virtual void operator()(quickbook::state&, char) const;
+ virtual void operator()(quickbook::state&, std::string const&) const;
+ virtual void operator()(quickbook::state&, anchor const&) const;
+ virtual void operator()(quickbook::state&, link const&) const;
+ virtual void operator()(quickbook::state&, formatted const&) const;
+ virtual void operator()(quickbook::state&, break_ const&) const;
+ virtual void operator()(quickbook::state&, image2 const&) const;
+
+ virtual void operator()(quickbook::state&, hr) const;
+ virtual void operator()(quickbook::state&, begin_section2 const&) const;
+ virtual void operator()(quickbook::state&, end_section2 const&) const;
+ virtual void operator()(quickbook::state&, heading2 const&) const;
+ virtual void operator()(quickbook::state&, variablelist const&) const;
+ virtual void operator()(quickbook::state&, table2 const&) const;
+ virtual void operator()(quickbook::state&, xinclude2 const&) const;
+ virtual void operator()(quickbook::state&, list2 const&) const;
+
+ virtual void operator()(quickbook::state&, code_token const&) const;
+
+ virtual std::string encode(std::string const&) const;
+ virtual std::string encode(char) const;
+ virtual std::string encode(char const*) const;
     };
+
+ encoder_ptr create_encoder(std::string const&)
+ {
+ return boost::shared_ptr<encoder>(new boostbook_encoder());
+ }
 
     template <typename Iter>
- std::string encode(Iter first, Iter last)
+ std::string encode_impl(Iter first, Iter last)
     {
         std::string r;
         
@@ -37,18 +61,18 @@
         return r;
     }
 
- std::string encode(std::string const& x) {
- return encode(x.begin(), x.end());
+ std::string boostbook_encoder::encode(std::string const& x) const {
+ return encode_impl(x.begin(), x.end());
     }
 
- std::string encode(char const* x) {
+ std::string boostbook_encoder::encode(char const* x) const {
         char const* end = x;
         while(*end) ++end;
- return encode(x, end);
+ return encode_impl(x, end);
     }
 
- std::string encode(char c) {
- return encode(&c, &c + 1);
+ std::string boostbook_encoder::encode(char c) const {
+ return encode_impl(&c, &c + 1);
     }
 
     namespace {
@@ -119,23 +143,23 @@
         } initialize_instance;
     }
 
- void output(quickbook::state& state, std::string const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, std::string const& x) const
     {
         state.phrase << x;
     }
 
- void output(quickbook::state& state, char x)
+ void boostbook_encoder::operator()(quickbook::state& state, char x) const
     {
         state.phrase << encode(x);
     }
 
- void output(quickbook::state& state, anchor const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, anchor const& x) const {
         state.phrase << "<anchor id=\"";
         state.phrase << encode(x.id);
         state.phrase << "\"/>\n";
     }
 
- void output(quickbook::state& state, link const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, link const& x) const {
         boostbook_markup m = markup_map.at(x.type);
         state.phrase << m.pre;
         state.phrase << encode(x.destination);
@@ -144,17 +168,17 @@
         state.phrase << m.post;
     }
 
- void output(quickbook::state& state, formatted const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, formatted const& x) const {
         boostbook_markup m = markup_map.at(x.type);
         state.phrase << m.pre << x.content << m.post;
     }
 
- void output(quickbook::state& state, break_ const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, break_ const& x) const {
         boostbook_markup m = markup_map.at("break");
         state.phrase << m.pre;
     }
 
- void output(quickbook::state& state, image2 const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, image2 const& x) const {
         state.phrase << "<inlinemediaobject>";
 
         state.phrase << "<imageobject><imagedata";
@@ -187,11 +211,11 @@
         state.phrase << "</inlinemediaobject>";
     }
 
- void output(quickbook::state& state, hr) {
+ void boostbook_encoder::operator()(quickbook::state& state, hr) const {
         state.phrase << markup_map.at("hr").pre;
     }
 
- void output(quickbook::state& state, begin_section2 const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, begin_section2 const& x) const {
         state.phrase << "\n<section id=\"" << x.id << "\">\n";
         if(x.linkend.empty()) {
             state.phrase
@@ -213,11 +237,11 @@
         }
     }
 
- void output(quickbook::state& state, end_section2 const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, end_section2 const& x) const {
         state.phrase << "</section>";
     }
 
- void output(quickbook::state& state, heading2 const& x) {
+ void boostbook_encoder::operator()(quickbook::state& state, heading2 const& x) const {
         state.phrase
             << "<anchor id=\"" << x.id << "\"/>"
             << "<bridgehead renderas=\"sect" << x.level << "\">";
@@ -234,7 +258,7 @@
         state.phrase << "</bridgehead>";
     }
 
- void output(quickbook::state& state, variablelist const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, variablelist const& x) const
     {
         state.phrase << "<variablelist>\n";
 
@@ -248,14 +272,14 @@
             it = x.entries.begin(); it != x.entries.end(); ++it)
         {
             state.phrase << m.pre;
- std::for_each(it->begin(), it->end(), output_action(state));
+ std::for_each(it->begin(), it->end(), encode_action(state, *this));
             state.phrase << m.post;
         }
 
         state.phrase << "</variablelist>\n";
     }
 
- void output(quickbook::state& state, table2 const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, table2 const& x) const
     {
         if (x.title)
         {
@@ -285,7 +309,7 @@
         {
             state.phrase << "<thead>";
             state.phrase << m.pre;
- std::for_each(x.head->begin(), x.head->end(), output_action(state));
+ std::for_each(x.head->begin(), x.head->end(), encode_action(state, *this));
             state.phrase << m.post;
             state.phrase << "</thead>\n";
         }
@@ -296,7 +320,7 @@
             it = x.rows.begin(); it != x.rows.end(); ++it)
         {
             state.phrase << m.pre;
- std::for_each(it->begin(), it->end(), output_action(state));
+ std::for_each(it->begin(), it->end(), encode_action(state, *this));
             state.phrase << m.post;
         }
 
@@ -312,12 +336,12 @@
         }
     }
 
- void output(quickbook::state& state, xinclude2 const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, xinclude2 const& x) const
     {
         state.phrase << "\n<xi:include href=\"" << x.path << "\" />\n";
     }
 
- void output(quickbook::state& state, list2 const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, list2 const& x) const
     {
         state.phrase << std::string(x.mark == '#' ? "<orderedlist>\n" : "<itemizedlist>\n");
 
@@ -325,14 +349,14 @@
             it = x.items.begin(), end = x.items.end(); it != end; ++it)
         {
             state.phrase << "<listitem>\n" << it->content;
- if(!it->sublist.items.empty()) output(state, it->sublist);
+ if(!it->sublist.items.empty()) (*this)(state, it->sublist);
             state.phrase << std::string("\n</listitem>");
         }
 
         state.phrase << std::string(x.mark == '#' ? "\n</orderedlist>" : "\n</itemizedlist>");
     }
 
- void output(quickbook::state& state, code_token const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, code_token const& x) const
     {
         std::string type = x.type;
         if(type == "space") {
@@ -346,7 +370,7 @@
         }
     }
 
- void output(quickbook::state& state, doc_info const& info)
+ void boostbook_encoder::operator()(quickbook::state& state, doc_info const& info) const
     {
         // if we're ignoring the document info, we're done.
         if (info.ignore) return;
@@ -463,7 +487,7 @@
         if(info.doc_type == "library") state.phrase << title;
     }
 
- void output(quickbook::state& state, doc_info_post const& x)
+ void boostbook_encoder::operator()(quickbook::state& state, doc_info_post const& x) const
     {
         // if we're ignoring the document info, do nothing.
         if (x.info.ignore) return;

Deleted: branches/quickbook-1.5-spirit2/boostbook.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/boostbook.hpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
+++ (empty file)
@@ -1,61 +0,0 @@
-/*=============================================================================
- Copyright (c) 2002 2004 2006 Joel de Guzman
- Copyright (c) 2004 Eric Niebler
- Copyright (c) 2010 Daniel James
- 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_BOOSTBOOK_HPP)
-#define BOOST_SPIRIT_QUICKBOOK_BOOSTBOOK_HPP
-
-#include "fwd.hpp"
-#include "phrase.hpp"
-#include "block.hpp"
-#include "syntax_highlight.hpp"
-#include "doc_info.hpp"
-#include "gen_types.hpp"
-
-namespace quickbook
-{
- // TODO: Sort this out:
-
- // Output function for boostbook, these should eventually become an
- // interface with implementations for boostbook and html.
- // They probably shouldn't use quickbook::state, instead they
- // should either take a stream/collector to write to, or return their
- // output by value.
-
- void output(quickbook::state&, doc_info const&);
- void output(quickbook::state&, doc_info_post const&);
-
- // Note: char is a plain quickbook character, string is an encoded
- // boostbook string. Oops.
- void output(quickbook::state&, char);
- void output(quickbook::state&, std::string const&);
- void output(quickbook::state&, anchor const&);
- void output(quickbook::state&, link const&);
- void output(quickbook::state&, formatted const&);
- void output(quickbook::state&, break_ const&);
- void output(quickbook::state&, image2 const&);
-
- void output(quickbook::state&, hr);
- void output(quickbook::state&, begin_section2 const&);
- void output(quickbook::state&, end_section2 const&);
- void output(quickbook::state&, heading2 const&);
- void output(quickbook::state&, variablelist const&);
- void output(quickbook::state&, table2 const&);
- void output(quickbook::state&, xinclude2 const&);
- void output(quickbook::state&, list2 const&);
-
- void output(quickbook::state&, code_token const&);
-
- std::string encode(std::string const&);
- std::string encode(char);
- std::string encode(char const*);
-}
-
-#endif

Added: branches/quickbook-1.5-spirit2/encoder.hpp
==============================================================================
--- (empty file)
+++ branches/quickbook-1.5-spirit2/encoder.hpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -0,0 +1,81 @@
+/*=============================================================================
+ Copyright (c) 2002 2004 2006 Joel de Guzman
+ Copyright (c) 2004 Eric Niebler
+ Copyright (c) 2010 Daniel James
+ 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_OUTPUT_HPP)
+#define BOOST_SPIRIT_QUICKBOOK_OUTPUT_HPP
+
+#include <boost/shared_ptr.hpp>
+#include "fwd.hpp"
+#include "phrase.hpp"
+#include "block.hpp"
+#include "syntax_highlight.hpp"
+#include "doc_info.hpp"
+#include "gen_types.hpp"
+
+namespace quickbook
+{
+ // Base class for encoders.
+ //
+ // The methods in this class possibly shouldn't be const, as it might be
+ // useful to store some state eg. in case anything needs to rearranged in
+ // order to create a valid document. Maybe this should act more like a
+ // stream? It could have something like the collector interface, with
+ // push and pop methods.
+
+ struct encoder {
+ void operator()(quickbook::state&, nothing) {}
+
+ virtual void operator()(quickbook::state&, doc_info const&) const = 0;
+ virtual void operator()(quickbook::state&, doc_info_post const&) const = 0;
+
+ // Note: char is a plain quickbook character, string is an encoded
+ // boostbook string. Oops.
+ virtual void operator()(quickbook::state&, char) const = 0;
+ virtual void operator()(quickbook::state&, std::string const&) const = 0;
+ virtual void operator()(quickbook::state&, anchor const&) const = 0;
+ virtual void operator()(quickbook::state&, link const&) const = 0;
+ virtual void operator()(quickbook::state&, formatted const&) const = 0;
+ virtual void operator()(quickbook::state&, break_ const&) const = 0;
+ virtual void operator()(quickbook::state&, image2 const&) const = 0;
+
+ virtual void operator()(quickbook::state&, hr) const = 0;
+ virtual void operator()(quickbook::state&, begin_section2 const&) const = 0;
+ virtual void operator()(quickbook::state&, end_section2 const&) const = 0;
+ virtual void operator()(quickbook::state&, heading2 const&) const = 0;
+ virtual void operator()(quickbook::state&, variablelist const&) const = 0;
+ virtual void operator()(quickbook::state&, table2 const&) const = 0;
+ virtual void operator()(quickbook::state&, xinclude2 const&) const = 0;
+ virtual void operator()(quickbook::state&, list2 const&) const = 0;
+
+ virtual void operator()(quickbook::state&, code_token const&) const = 0;
+
+ virtual std::string encode(std::string const&) const = 0;
+ virtual std::string encode(char) const = 0;
+ virtual std::string encode(char const*) const = 0;
+ };
+
+ struct encode_action
+ {
+ encode_action(quickbook::state& state,
+ quickbook::encoder const& encoder)
+ : state(state), encoder(encoder) {}
+
+ template <typename T>
+ void operator()(T const& x) const {
+ encoder(state, x);
+ }
+
+ quickbook::state& state;
+ quickbook::encoder const& encoder;
+ };
+}
+
+#endif

Modified: branches/quickbook-1.5-spirit2/fwd.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/fwd.hpp (original)
+++ branches/quickbook-1.5-spirit2/fwd.hpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -12,6 +12,7 @@
 
 #include <boost/spirit/include/classic_iterator.hpp>
 #include <boost/range.hpp>
+#include <boost/shared_ptr.hpp>
 
 namespace quickbook
 {
@@ -38,6 +39,12 @@
     struct call_template;
     struct define_template;
     struct template_symbol;
+
+ // encoder
+
+ struct encoder;
+ typedef boost::shared_ptr<encoder> encoder_ptr;
+ encoder_ptr create_encoder(std::string const&);
 }
 
 #endif
\ No newline at end of file

Modified: branches/quickbook-1.5-spirit2/phrase_actions.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase_actions.cpp (original)
+++ branches/quickbook-1.5-spirit2/phrase_actions.cpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -14,7 +14,7 @@
 #include "state.hpp"
 #include "utils.hpp"
 #include "code.hpp"
-#include "boostbook.hpp"
+#include "encoder.hpp"
 #include "quickbook.hpp"
 
 namespace quickbook
@@ -24,18 +24,20 @@
         return nothing();
     }
 
+ // TODO: If I used a different types for quickbook and the generated
+ // output, I could possibly do something smarter here.
     std::string process(quickbook::state& state, macro const& x) {
         if (x.raw_markup == quickbook_get_date)
         {
             char strdate[64];
             strftime(strdate, sizeof(strdate), "%Y-%b-%d", current_time);
- return encode(strdate);
+ return state.encoder->encode(strdate);
         }
         else if (x.raw_markup == quickbook_get_time)
         {
             char strdate[64];
             strftime(strdate, sizeof(strdate), "%I:%M:%S %p", current_time);
- return encode(strdate);
+ return state.encoder->encode(strdate);
         }
         else
         {
@@ -46,7 +48,7 @@
     link process(quickbook::state& state, link const& x) {
         link r = x;
         if(r.content.empty()) {
- r.content = encode(x.destination);
+ r.content = state.encoder->encode(x.destination);
         }
         return r;
     }
@@ -61,7 +63,7 @@
             default: BOOST_ASSERT(false);
         }
 
- r.content = encode(x.raw_content);
+ r.content = state.encoder->encode(x.raw_content);
 
         return r;
     }

Modified: branches/quickbook-1.5-spirit2/process.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/process.cpp (original)
+++ branches/quickbook-1.5-spirit2/process.cpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -13,19 +13,20 @@
 #include "phrase_actions.hpp"
 #include "block_actions.hpp"
 #include "actions.hpp"
+#include "state.hpp"
 #include "parse_types.hpp"
 #include "code.hpp"
 #include "syntax_highlight.hpp"
 #include "template.hpp"
 #include "doc_info_actions.hpp"
-#include "boostbook.hpp"
+#include "encoder.hpp"
 
 namespace quickbook
 {
     template <typename T>
     void process_action::operator()(T const& x) const
     {
- output(actions.state_, process(actions.state_, x));
+ (*actions.state_.encoder)(actions.state_, process(actions.state_, x));
     }
 
     template <typename T>
@@ -34,9 +35,6 @@
         return x;
     }
 
- void output(quickbook::state&, nothing) {
- }
-
     template void process_action::operator()<formatted>(formatted const&) const;
     template void process_action::operator()<source_mode>(source_mode const&) const;
     template void process_action::operator()<macro>(macro const&) const;

Modified: branches/quickbook-1.5-spirit2/quickbook.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/quickbook.cpp (original)
+++ branches/quickbook-1.5-spirit2/quickbook.cpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -111,7 +111,7 @@
     static int
     parse(char const* filein_, fs::path const& outdir, string_stream& out, bool ignore_docinfo = false)
     {
- quickbook::state state(filein_, outdir, out);
+ quickbook::state state(filein_, outdir, out, create_encoder("boostbook"));
         bool r = parse(filein_, state);
         if (state.section_level != 0)
             detail::outwarn(filein_)

Modified: branches/quickbook-1.5-spirit2/state.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/state.cpp (original)
+++ branches/quickbook-1.5-spirit2/state.cpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -22,13 +22,15 @@
 {
     namespace fs = boost::filesystem;
 
- state::state(char const* filein_, fs::path const& outdir_, string_stream& out_)
+ state::state(char const* filein_, fs::path const& outdir_, string_stream& out_,
+ encoder_ptr const& encoder)
     // header info
         : doc_id()
         , doc_title()
 
     // main output stream
         , phrase(out_)
+ , encoder(encoder)
 
     // state
         , filename(fs::complete(fs::path(filein_, fs::native)))

Modified: branches/quickbook-1.5-spirit2/state.hpp
==============================================================================
--- branches/quickbook-1.5-spirit2/state.hpp (original)
+++ branches/quickbook-1.5-spirit2/state.hpp 2010-02-07 09:48:28 EST (Sun, 07 Feb 2010)
@@ -25,7 +25,8 @@
 
     struct state
     {
- state(char const* filein_, fs::path const& outdir, string_stream& out_);
+ state(char const* filein_, fs::path const& outdir, string_stream& out_,
+ encoder_ptr const&);
 
     ///////////////////////////////////////////////////////////////////////////
     // State
@@ -38,6 +39,7 @@
 
     // main output stream
         collector phrase;
+ encoder_ptr encoder;
 
     // state
         fs::path filename;


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