Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r70528 - trunk/tools/quickbook/src
From: dnljms_at_[hidden]
Date: 2011-03-24 17:25:19


Author: danieljames
Date: 2011-03-24 17:25:18 EDT (Thu, 24 Mar 2011)
New Revision: 70528
URL: http://svn.boost.org/trac/boost/changeset/70528

Log:
Quickbook: Use values for templates and snippets.
Text files modified:
   trunk/tools/quickbook/src/actions.cpp | 70 +++++++++++++-----------------
   trunk/tools/quickbook/src/code_snippet.cpp | 92 ++++++++++++++++++++++++---------------
   trunk/tools/quickbook/src/template_stack.cpp | 19 ++++++++
   trunk/tools/quickbook/src/template_stack.hpp | 30 +++---------
   trunk/tools/quickbook/src/values.cpp | 38 +++++++++++++---
   trunk/tools/quickbook/src/values.hpp | 11 ++++
   6 files changed, 154 insertions(+), 106 deletions(-)

Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp (original)
+++ trunk/tools/quickbook/src/actions.cpp 2011-03-24 17:25:18 EDT (Thu, 24 Mar 2011)
@@ -27,7 +27,6 @@
 #include "actions_class.hpp"
 #include "grammar.hpp"
 #include "input_path.hpp"
-#include "template_tags.hpp"
 #include "block_tags.hpp"
 #include "phrase_tags.hpp"
 
@@ -883,10 +882,8 @@
             template_symbol(
                 identifier,
                 template_values,
- body.get_quickbook(),
+ body,
                 actions.filename,
- body.get_position(),
- body.get_tag() == template_tags::block,
                 &actions.templates.top_scope())))
         {
             file_position const pos = body.get_position();
@@ -991,18 +988,18 @@
                     // arguments, or if there are no more spaces left.
 
                     template_body& body = args.back();
- iterator begin(body.content.begin(), body.position);
- iterator end(body.content.end());
+ iterator begin = body.content.get_quickbook_range().begin();
+ iterator end = body.content.get_quickbook_range().end();
                     
                     std::pair<iterator, iterator> pos =
                         find_seperator(begin, end);
                     if (pos.second == end) break;
                     template_body second(
- std::string(pos.second, end),
- body.filename,
- pos.second.get_position(),
- false);
- body.content = std::string(begin, pos.first);
+ qbk_value(pos.second, end, template_tags::phrase),
+ body.filename);
+
+ body.content = qbk_value(begin, pos.first,
+ body.content.get_tag()).store();
                     args.push_back(second);
                 }
             }
@@ -1040,7 +1037,7 @@
             {
                 if (!actions.templates.add(
                         template_symbol(*tpl, empty_params, arg->content,
- arg->filename, arg->position, arg->is_block, &scope)))
+ arg->filename, &scope)))
                 {
                     detail::outerr(actions.filename, pos.line)
                         << "Duplicate Symbol Found" << std::endl;
@@ -1069,17 +1066,17 @@
             {
                 // escape the body of the template
                 // we just copy out the literal body
- (body.is_block ? actions.out : actions.phrase) << body.content;
+ (body.is_block() ? actions.out : actions.phrase) << body.content.get_quickbook();
                 return true;
             }
             else
             {
- if (!body.is_block)
+ if (!body.is_block())
                 {
                     // do a phrase level parse
                     actions.filename = body.filename;
- iterator first(body.content.begin(), body.position);
- iterator last(body.content.end());
+ iterator first = body.content.get_quickbook_range().begin();
+ iterator last = body.content.get_quickbook_range().end();
                     
                     return cl::parse(first, last, actions.grammar().simple_phrase).full;
                 }
@@ -1090,8 +1087,8 @@
                     // the need to check for end of file in the grammar.
                     
                     actions.filename = body.filename;
- std::string content = body.content + "\n\n";
- iterator first(content.begin(), body.position);
+ std::string content = body.content.get_quickbook() + "\n\n";
+ iterator first(content.begin(), body.content.get_position());
                     iterator last(content.end());
 
                     return cl::parse(first, last, actions.grammar().block).full;
@@ -1123,17 +1120,7 @@
 
         BOOST_FOREACH(value arg, values)
         {
- BOOST_ASSERT(
- arg.get_tag() == template_tags::block ||
- arg.get_tag() == template_tags::phrase);
-
- args.push_back(
- template_body(
- arg.get_quickbook(),
- actions.filename,
- arg.get_position(),
- arg.get_tag() == template_tags::block
- ));
+ args.push_back(template_body(arg, actions.filename));
         }
         
         values.finish();
@@ -1177,7 +1164,7 @@
             ///////////////////////////////////
             // Initialise the arguments
             
- if (!symbol->callout)
+ if (!symbol->callouts.check())
             {
                 // Break the arguments for a template
             
@@ -1214,7 +1201,9 @@
                     code += "linkends=\"" + callout_id + "\" />";
                     code += "'''";
 
- args.push_back(template_body(code, actions.filename, pos, false));
+ args.push_back(template_body(
+ qbk_value(code, pos, template_tags::phrase),
+ actions.filename));
                 }
             }
 
@@ -1241,11 +1230,11 @@
                 file_position const pos = first.get_position();
                 detail::outerr(actions.filename, pos.line)
                     << "Expanding "
- << (symbol->body.is_block ? "block" : "phrase")
+ << (symbol->body.is_block() ? "block" : "phrase")
                     << " template: " << detail::utf8(symbol->identifier) << std::endl
                     << std::endl
                     << "------------------begin------------------" << std::endl
- << detail::utf8(symbol->body.content)
+ << detail::utf8(symbol->body.content.get_quickbook())
                     << "------------------end--------------------" << std::endl
                     << std::endl;
                 actions.pop(); // restore the actions' states
@@ -1270,27 +1259,28 @@
         actions.phrase.swap(phrase);
         actions.pop(); // restore the actions' states
 
- if(symbol->callout && symbol->callouts.size() > 0)
+ if(!symbol->callouts.empty())
         {
             BOOST_ASSERT(phrase.empty());
             block += "<calloutlist>";
- BOOST_FOREACH(template_body const& c, symbol->callouts)
+ BOOST_FOREACH(value c, symbol->callouts)
             {
                 std::string callout_id = actions.doc_id +
                     boost::lexical_cast<std::string>(detail::callout_id++);
 
                 std::string callout_value;
                 actions.push();
- bool r = parse_template(c, false, actions);
+ bool r = parse_template(
+ template_body(c, symbol->body.filename), false, actions);
                 actions.out.swap(callout_value);
                 actions.pop();
 
                 if(!r)
                 {
- detail::outerr(c.filename, c.position.line)
+ detail::outerr(symbol->body.filename, c.get_position().line)
                         << "Expanding callout." << std::endl
                         << "------------------begin------------------" << std::endl
- << detail::utf8(c.content)
+ << detail::utf8(c.get_quickbook())
                         << std::endl
                         << "------------------end--------------------" << std::endl
                         ;
@@ -1306,7 +1296,7 @@
             block += "</calloutlist>";
         }
 
- if(symbol->body.is_block || !block.empty()) {
+ if(symbol->body.is_block() || !block.empty()) {
             actions.paragraph(); // For paragraphs before the template call.
             actions.out << block;
             actions.phrase << phrase;
@@ -1749,7 +1739,7 @@
             ts.parent = &actions.templates.top_scope();
             if (!actions.templates.add(ts))
             {
- detail::outerr(ts.body.filename, ts.body.position.line)
+ detail::outerr(ts.body.filename, ts.body.content.get_position().line)
                     << "Template Redefinition: " << detail::utf8(tname) << std::endl;
                 ++actions.error_count;
             }

Modified: trunk/tools/quickbook/src/code_snippet.cpp
==============================================================================
--- trunk/tools/quickbook/src/code_snippet.cpp (original)
+++ trunk/tools/quickbook/src/code_snippet.cpp 2011-03-24 17:25:18 EDT (Thu, 24 Mar 2011)
@@ -7,14 +7,15 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
-#include <stack>
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_actor.hpp>
 #include <boost/spirit/include/classic_confix.hpp>
+#include <boost/shared_ptr.hpp>
 #include <boost/bind.hpp>
 #include <boost/lexical_cast.hpp>
 #include "template_stack.hpp"
 #include "actions.hpp"
+#include "values.hpp"
 
 namespace quickbook
 {
@@ -52,17 +53,34 @@
                 , start_code(false)
                 , end_code(false)
             {}
-
+
             std::string id;
             int callout_base_id;
             std::string content;
             bool start_code;
             bool end_code;
- std::vector<template_body> callouts;
+ value_builder callouts;
+ boost::shared_ptr<snippet_data> next;
         };
         
+ void push_snippet_data(std::string const& id, int callout_base_id)
+ {
+ boost::shared_ptr<snippet_data> new_snippet(
+ new snippet_data(id, callout_base_id));
+ new_snippet->next = snippet_stack;
+ snippet_stack = new_snippet;
+ }
+
+ boost::shared_ptr<snippet_data> pop_snippet_data()
+ {
+ boost::shared_ptr<snippet_data> snippet(snippet_stack);
+ snippet_stack = snippet->next;
+ snippet->next.reset();
+ return snippet;
+ }
+
         int callout_id;
- std::stack<snippet_data> snippet_stack;
+ boost::shared_ptr<snippet_data> snippet_stack;
         std::string code;
         std::string id;
         std::vector<template_symbol>& storage;
@@ -323,8 +341,8 @@
 
     void code_snippet_actions::append_code()
     {
- if(snippet_stack.empty()) return;
- snippet_data& snippet = snippet_stack.top();
+ if(!snippet_stack) return;
+ snippet_data& snippet = *snippet_stack;
     
         if (!code.empty())
         {
@@ -350,8 +368,8 @@
 
     void code_snippet_actions::close_code()
     {
- if(snippet_stack.empty()) return;
- snippet_data& snippet = snippet_stack.top();
+ if(!snippet_stack) return;
+ snippet_data& snippet = *snippet_stack;
     
         if(snippet.end_code)
         {
@@ -362,30 +380,29 @@
 
     void code_snippet_actions::pass_thru(iterator first, iterator last)
     {
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
         code.append(first, last);
     }
 
     void code_snippet_actions::pass_thru_char(char c)
     {
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
         code += c;
     }
 
     void code_snippet_actions::callout(iterator first, iterator last)
     {
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
         code += "``[[callout" + boost::lexical_cast<std::string>(callout_id) + "]]``";
     
- snippet_stack.top().callouts.push_back(
- template_body(std::string(first, last), filename, first.get_position(), true));
+ snippet_stack->callouts.insert(qbk_value(first, last, template_tags::block).store());
         ++callout_id;
     }
 
     void code_snippet_actions::escaped_comment(iterator first, iterator last)
     {
- if(snippet_stack.empty()) return;
- snippet_data& snippet = snippet_stack.top();
+ if(!snippet_stack) return;
+ snippet_data& snippet = *snippet_stack;
         append_code();
         close_code();
 
@@ -400,50 +417,53 @@
     void code_snippet_actions::start_snippet(iterator, iterator)
     {
         append_code();
- snippet_stack.push(snippet_data(id, callout_id));
+ push_snippet_data(id, callout_id);
         id.clear();
     }
 
     void code_snippet_actions::end_snippet(iterator first, iterator)
     {
         // TODO: Error?
- if(snippet_stack.empty()) return;
+ if(!snippet_stack) return;
 
         append_code();
 
- snippet_data snippet = snippet_stack.top();
- snippet_stack.pop();
+ boost::shared_ptr<snippet_data> snippet = pop_snippet_data();
+ value callouts = snippet->callouts.get();
 
         std::string body;
- if(snippet.start_code) {
+ if(snippet->start_code) {
             body += "\n\n";
             body += source_type;
             body += "```\n";
         }
- body += snippet.content;
- if(snippet.end_code) {
+ body += snippet->content;
+ if(snippet->end_code) {
             body += "```\n\n";
         }
-
+
         std::vector<std::string> params;
- for (size_t i = 0; i < snippet.callouts.size(); ++i)
+ int i = 0;
+ for(value::iterator it = callouts.begin(); it != callouts.end(); ++it)
         {
- params.push_back("[callout" + boost::lexical_cast<std::string>(snippet.callout_base_id + i) + "]");
+ params.push_back("[callout" + boost::lexical_cast<std::string>(snippet->callout_base_id + i) + "]");
+ ++i;
         }
         
         // TODO: Save position in start_snippet
- template_symbol symbol(snippet.id, params, body, filename, first.get_position(), true);
- symbol.callout = true;
- symbol.callouts = snippet.callouts;
+ template_symbol symbol(snippet->id, params,
+ qbk_value(body, first.get_position(), template_tags::block),
+ filename);
+ symbol.callouts = callouts;
         storage.push_back(symbol);
 
         // Merge the snippet into its parent
 
- if(!snippet_stack.empty())
+ if(snippet_stack)
         {
- snippet_data& next = snippet_stack.top();
- if(!snippet.content.empty()) {
- if(!snippet.start_code) {
+ snippet_data& next = *snippet_stack;
+ if(!snippet->content.empty()) {
+ if(!snippet->start_code) {
                     close_code();
                 }
                 else if(!next.end_code) {
@@ -452,11 +472,11 @@
                     next.content += "```\n";
                 }
                 
- next.content += snippet.content;
- next.end_code = snippet.end_code;
+ next.content += snippet->content;
+ next.end_code = snippet->end_code;
             }
-
- next.callouts.insert(next.callouts.end(), snippet.callouts.begin(), snippet.callouts.end());
+
+ next.callouts.extend(callouts);
         }
     }
 }

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

Modified: trunk/tools/quickbook/src/template_stack.hpp
==============================================================================
--- trunk/tools/quickbook/src/template_stack.hpp (original)
+++ trunk/tools/quickbook/src/template_stack.hpp 2011-03-24 17:25:18 EDT (Thu, 24 Mar 2011)
@@ -19,6 +19,8 @@
 #include <boost/next_prior.hpp>
 #include <boost/filesystem/path.hpp>
 #include "fwd.hpp"
+#include "values.hpp"
+#include "template_tags.hpp"
 
 namespace quickbook
 {
@@ -26,23 +28,11 @@
 
     struct template_body
     {
- template_body(
- std::string const& content,
- fs::path const& filename,
- file_position const& position,
- bool is_block
- )
- : content(content)
- , filename(filename)
- , position(position)
- , is_block(is_block)
- {
- }
+ template_body(value const&, fs::path const&);
+ bool is_block() const;
 
- std::string content;
+ value content;
         fs::path filename;
- file_position position;
- bool is_block;
     };
 
     struct template_scope;
@@ -52,16 +42,13 @@
         template_symbol(
                 std::string const& identifier,
                 std::vector<std::string> const& params,
- std::string const& body,
+ value const& content,
                 fs::path const& filename,
- file_position const& position,
- bool is_block,
                 template_scope const* parent = 0)
            : identifier(identifier)
            , params(params)
- , body(body, filename, position, is_block)
+ , body(content, filename)
            , parent(parent)
- , callout(false)
            , callouts() {}
 
         std::string identifier;
@@ -73,8 +60,7 @@
         // or static_parent for clarity.
         template_scope const* parent;
 
- bool callout;
- std::vector<template_body> callouts;
+ value callouts;
     };
 
     typedef boost::spirit::classic::symbols<template_symbol> template_symbols;

Modified: trunk/tools/quickbook/src/values.cpp
==============================================================================
--- trunk/tools/quickbook/src/values.cpp (original)
+++ trunk/tools/quickbook/src/values.cpp 2011-03-24 17:25:18 EDT (Thu, 24 Mar 2011)
@@ -44,10 +44,12 @@
         file_position value_node::get_position() const { UNDEFINED_ERROR(); }
         int value_node::get_int() const { UNDEFINED_ERROR(); }
         std::string value_node::get_quickbook() const { UNDEFINED_ERROR(); }
+ value_node::qbk_range value_node::get_quickbook_range() const { UNDEFINED_ERROR(); }
         std::string value_node::get_boostbook() const { UNDEFINED_ERROR(); }
         value_node* value_node::get_list() const { UNDEFINED_ERROR(); }
 
         bool value_node::empty() const { return false; }
+ bool value_node::check() const { return true; }
         bool value_node::is_list() const { return false; }
         bool value_node::is_string() const { return false; }
     }
@@ -76,6 +78,9 @@
 
             virtual bool empty() const
                 { return true; }
+
+ virtual bool check() const
+ { return false; }
             
             friend value quickbook::empty_value(value::tag_type);
         };
@@ -151,12 +156,9 @@
             intrusive_ptr_release(value_);
         }
 
- void value_counted::store()
+ value value_counted::store() const
         {
- value_node* new_value = value_->store();
- intrusive_ptr_add_ref(new_value);
- intrusive_ptr_release(value_);
- value_ = new_value;
+ return value(value_->store());
         }
     }
     
@@ -289,6 +291,7 @@
             virtual value_node* clone() const;
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
+ qbk_range get_quickbook_range() const;
             virtual bool is_string() const;
             virtual bool empty() const;
     
@@ -308,6 +311,7 @@
             virtual value_node* store();
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
+ qbk_range get_quickbook_range() const;
             virtual bool is_string() const;
             virtual bool empty() const;
     
@@ -332,6 +336,7 @@
             virtual value_node* clone() const;
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
+ qbk_range get_quickbook_range() const;
             virtual std::string get_boostbook() const;
             virtual bool is_string() const;
             virtual bool empty() const;
@@ -408,6 +413,11 @@
         std::string value_qbk_string_impl::get_quickbook() const
             { return value_; }
 
+ value::qbk_range value_qbk_string_impl::get_quickbook_range() const
+ { return qbk_range(
+ iterator(value_.begin(), position_),
+ iterator(value_.end())); }
+
         bool value_qbk_string_impl::is_string() const
             { return true; }
 
@@ -443,6 +453,9 @@
         std::string value_qbk_ref_impl::get_quickbook() const
             { return std::string(begin_.base(), end_.base()); }
 
+ value::qbk_range value_qbk_ref_impl::get_quickbook_range() const
+ { return qbk_range(begin_, end_); }
+
         bool value_qbk_ref_impl::is_string() const
             { return true; }
 
@@ -503,6 +516,11 @@
         std::string value_qbk_bbk_impl::get_quickbook() const
             { return qbk_value_; }
 
+ value::qbk_range value_qbk_bbk_impl::get_quickbook_range() const
+ { return qbk_range(
+ iterator(qbk_value_.begin(), position_),
+ iterator(qbk_value_.end())); }
+
         std::string value_qbk_bbk_impl::get_boostbook() const
             { return bbk_value_; }
 
@@ -687,7 +705,6 @@
             return new value_list_impl(head_, tag_);
         }
 
- // TODO: Could reuse nodes is any node has a reference count of 1.
         value_node* value_list_impl::store()
         {
             value_node* pos = head_;
@@ -762,7 +779,6 @@
             if(other.back_ == &head_) other.back_ = &other.head_;
         }
 
- // TODO: Multiple list refs are incompatible with 'store'
         value_node* value_list_builder::get() const {
             return head_;
         }
@@ -825,6 +841,14 @@
         current.append(item.value_);
     }
 
+ void value_builder::extend(value const& list) {
+ for (value::iterator begin = list.begin(), end = list.end();
+ begin != end; ++begin)
+ {
+ insert(*begin);
+ }
+ }
+
     void value_builder::start_list(value::tag_type tag) {
         value::tag_type saved_tag = tag;
         save();

Modified: trunk/tools/quickbook/src/values.hpp
==============================================================================
--- trunk/tools/quickbook/src/values.hpp (original)
+++ trunk/tools/quickbook/src/values.hpp 2011-03-24 17:25:18 EDT (Thu, 24 Mar 2011)
@@ -16,6 +16,7 @@
 #include <cassert>
 #include <boost/scoped_ptr.hpp>
 #include <boost/iterator/iterator_traits.hpp>
+#include <boost/range/iterator_range.hpp>
 #include <stdexcept>
 #include "fwd.hpp"
 
@@ -38,6 +39,7 @@
 
         public:
             typedef int tag_type;
+ typedef boost::iterator_range<quickbook::iterator> qbk_range;
 
         protected:
             explicit value_node(tag_type);
@@ -51,8 +53,10 @@
             virtual file_position get_position() const;
             virtual std::string get_quickbook() const;
             virtual std::string get_boostbook() const;
+ virtual qbk_range get_quickbook_range() const;
             virtual int get_int() const;
 
+ virtual bool check() const;
             virtual bool empty() const;
             virtual bool is_list() const;
             virtual bool is_string() const;
@@ -83,6 +87,7 @@
             typedef iterator const_iterator;
             typedef value_node::tag_type tag_type;
             enum { default_tag = 0 };
+ typedef boost::iterator_range<quickbook::iterator> qbk_range;
 
         protected:
             explicit value_base(value_node* base)
@@ -96,6 +101,7 @@
         public:
             void swap(value_base& x) { std::swap(value_, x.value_); }
 
+ bool check() const { return value_->check(); }
             bool empty() const { return value_->empty(); }
             bool is_list() const { return value_->is_list(); }
             bool is_string() const { return value_->is_string(); }
@@ -109,6 +115,8 @@
             { return value_->get_position(); }
             std::string get_quickbook() const
             { return value_->get_quickbook(); }
+ qbk_range get_quickbook_range() const
+ { return value_->get_quickbook_range(); }
             std::string get_boostbook() const
             { return value_->get_boostbook(); }
             int get_int() const
@@ -181,7 +189,7 @@
             value_counted& operator=(value_counted);
             ~value_counted();
 
- void store();
+ value store() const;
         };
 
         ////////////////////////////////////////////////////////////////////////
@@ -257,6 +265,7 @@
         void reset();
         void set_tag(value::tag_type);
         void insert(value const&);
+ void extend(value const&);
 
         void start_list(value::tag_type = value::default_tag);
         void finish_list();


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