Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64976 - in trunk/tools/quickbook: . detail doc test
From: dnljms_at_[hidden]
Date: 2010-08-23 17:51:54


Author: danieljames
Date: 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
New Revision: 64976
URL: http://svn.boost.org/trac/boost/changeset/64976

Log:
Nested code snippets.
Text files modified:
   trunk/tools/quickbook/code_snippet.hpp | 101 ++++++++++++++++----------
   trunk/tools/quickbook/detail/actions.cpp | 147 ++++++++++++++++++++++++++++++---------
   trunk/tools/quickbook/doc/quickbook.qbk | 1
   trunk/tools/quickbook/test/callouts.cpp | 13 +++
   trunk/tools/quickbook/test/callouts.gold | 46 ++++++++++++
   trunk/tools/quickbook/test/callouts.quickbook | 5 +
   6 files changed, 237 insertions(+), 76 deletions(-)

Modified: trunk/tools/quickbook/code_snippet.hpp
==============================================================================
--- trunk/tools/quickbook/code_snippet.hpp (original)
+++ trunk/tools/quickbook/code_snippet.hpp 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
@@ -22,20 +22,44 @@
         code_snippet_actions(std::vector<template_symbol>& storage,
                                  std::string const& doc_id,
                                  char const* source_type)
- : storage(storage)
+ : callout_id(0)
+ , storage(storage)
             , doc_id(doc_id)
             , source_type(source_type)
         {}
 
+ void pass_thru_char(char);
         void pass_thru(iterator first, iterator last);
         void escaped_comment(iterator first, iterator last);
- void compile(iterator first, iterator last);
+ void start_snippet(iterator first, iterator last);
+ void end_snippet(iterator first, iterator last);
         void callout(iterator first, iterator last);
+
+ void append_code();
+ void close_code();
 
+ struct snippet_data
+ {
+ snippet_data(std::string const& id, int callout_base_id)
+ : id(id)
+ , callout_base_id(callout_base_id)
+ , content()
+ , 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;
+ };
+
+ int callout_id;
+ std::stack<snippet_data> snippet_stack;
         std::string code;
- std::string snippet;
         std::string id;
- std::vector<template_body> callouts;
         std::vector<template_symbol>& storage;
         std::string const doc_id;
         char const* const source_type;
@@ -57,30 +81,30 @@
             
             definition(python_code_snippet_grammar const& self)
             {
+
                 actions_type& actions = self.actions;
             
- start_ =
- +(
- snippet [boost::bind(&actions_type::compile, &actions, _1, _2)]
- | anychar_p
- )
- ;
+ start_ = *code_elements;
 
                 identifier =
                     (alpha_p | '_') >> *(alnum_p | '_')
                     ;
 
- snippet =
+ code_elements =
+ start_snippet [boost::bind(&actions_type::start_snippet, &actions, _1, _2)]
+ | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)]
+ | escaped_comment
+ | ignore
+ | anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
+ ;
+
+ start_snippet =
                     "#[" >> *space_p
>> identifier [assign_a(actions.id)]
- >> (*(code_elements - "#]"))
- >> "#]"
                     ;
 
- code_elements =
- escaped_comment
- | ignore
- | (anychar_p - "#]") [boost::bind(&actions_type::pass_thru, &actions, _1, _2)]
+ end_snippet =
+ str_p("#]")
                     ;
 
                 ignore =
@@ -106,8 +130,8 @@
             }
 
             rule<Scanner>
- start_, snippet, identifier, code_elements, escaped_comment,
- ignore;
+ start_, identifier, code_elements, start_snippet, end_snippet,
+ escaped_comment, ignore;
 
             rule<Scanner> const&
             start() const { return start_; }
@@ -132,36 +156,33 @@
             {
                 actions_type& actions = self.actions;
             
- start_ =
- +(
- snippet [boost::bind(&actions_type::compile, &actions, _1, _2)]
- | anychar_p
- )
- ;
+ start_ = *code_elements;
 
                 identifier =
                     (alpha_p | '_') >> *(alnum_p | '_')
                     ;
 
- snippet =
+ code_elements =
+ start_snippet [boost::bind(&actions_type::start_snippet, &actions, _1, _2)]
+ | end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)]
+ | escaped_comment
+ | ignore
+ | line_callout
+ | inline_callout
+ | anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
+ ;
+
+ start_snippet =
                         "//[" >> *space_p
- >> identifier [assign_a(actions.id)]
- >> (*(code_elements - "//]"))
- >> "//]"
+ >> identifier [assign_a(actions.id)]
                     |
                         "/*[" >> *space_p
- >> identifier [assign_a(actions.id)]
+ >> identifier [assign_a(actions.id)]
>> *space_p >> "*/"
- >> (*(code_elements - "/*]*"))
- >> "/*]*/"
                     ;
 
- code_elements =
- escaped_comment
- | ignore
- | line_callout
- | inline_callout
- | (anychar_p - "//]" - "/*]*/") [boost::bind(&actions_type::pass_thru, &actions, _1, _2)]
+ end_snippet =
+ str_p("//]") | "/*]*/"
                     ;
 
                 inline_callout =
@@ -202,8 +223,8 @@
             }
 
             rule<Scanner>
- start_, snippet, identifier, code_elements, escaped_comment,
- inline_callout, line_callout, ignore;
+ start_, identifier, code_elements, start_snippet, end_snippet,
+ escaped_comment, inline_callout, line_callout, ignore;
 
             rule<Scanner> const&
             start() const { return start_; }

Modified: trunk/tools/quickbook/detail/actions.cpp
==============================================================================
--- trunk/tools/quickbook/detail/actions.cpp (original)
+++ trunk/tools/quickbook/detail/actions.cpp 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
@@ -1276,68 +1276,143 @@
         out << "\" />\n";
     }
 
+ void code_snippet_actions::append_code()
+ {
+ if(snippet_stack.empty()) return;
+ snippet_data& snippet = snippet_stack.top();
+
+ if (!code.empty())
+ {
+ detail::unindent(code); // remove all indents
+
+ if(snippet.content.empty())
+ {
+ snippet.start_code = true;
+ }
+ else if(!snippet.end_code)
+ {
+ snippet.content += "\n\n";
+ snippet.content += source_type;
+ snippet.content += "```\n";
+ }
+
+ snippet.content += code;
+ snippet.end_code = true;
+
+ code.clear();
+ }
+ }
+
+ void code_snippet_actions::close_code()
+ {
+ if(snippet_stack.empty()) return;
+ snippet_data& snippet = snippet_stack.top();
+
+ if(snippet.end_code)
+ {
+ snippet.content += "```\n\n";
+ snippet.end_code = false;
+ }
+ }
+
     void code_snippet_actions::pass_thru(iterator first, iterator last)
     {
+ if(snippet_stack.empty()) return;
         code += *first;
     }
 
+ void code_snippet_actions::pass_thru_char(char c)
+ {
+ if(snippet_stack.empty()) return;
+ code += c;
+ }
+
     void code_snippet_actions::callout(iterator first, iterator last)
     {
- code += "``[[callout" + boost::lexical_cast<std::string>(callouts.size()) + "]]``";
+ if(snippet_stack.empty()) return;
+ code += "``[[callout" + boost::lexical_cast<std::string>(callout_id) + "]]``";
     
- callouts.push_back(template_body(std::string(first, last), first.get_position(), true));
+ snippet_stack.top().callouts.push_back(
+ template_body(std::string(first, last), first.get_position(), true));
+ ++callout_id;
     }
 
     void code_snippet_actions::escaped_comment(iterator first, iterator last)
     {
- if (!code.empty())
- {
- detail::unindent(code); // remove all indents
- if (code.size() != 0)
- {
- snippet += "\n\n";
- snippet += source_type;
- snippet += "``\n" + code + "``\n\n";
- code.clear();
- }
- }
+ if(snippet_stack.empty()) return;
+ snippet_data& snippet = snippet_stack.top();
+ append_code();
+ close_code();
+
         std::string temp(first, last);
         detail::unindent(temp); // remove all indents
         if (temp.size() != 0)
         {
- snippet += "\n" + temp; // add a linebreak to allow block marskups
+ snippet.content += "\n" + temp; // add a linebreak to allow block markups
         }
     }
 
- void code_snippet_actions::compile(iterator first, iterator last)
+ void code_snippet_actions::start_snippet(iterator first, iterator last)
+ {
+ append_code();
+ snippet_stack.push(snippet_data(id, callout_id));
+ id.clear();
+ }
+
+ void code_snippet_actions::end_snippet(iterator first, iterator last)
     {
+ // TODO: Error?
+ if(snippet_stack.empty()) return;
+
+ append_code();
+
+ snippet_data snippet = snippet_stack.top();
+ snippet_stack.pop();
+
+ std::string body;
+ if(snippet.start_code) {
+ body += "\n\n";
+ body += source_type;
+ body += "```\n";
+ }
+ body += snippet.content;
+ if(snippet.end_code) {
+ body += "```\n\n";
+ }
+
         std::vector<std::string> params;
-
- if (!code.empty())
+ for (size_t i = 0; i < snippet.callouts.size(); ++i)
         {
- detail::unindent(code); // remove all indents
- if (code.size() != 0)
- {
- snippet += "\n\n";
- snippet += source_type;
- snippet += "```\n" + code + "```\n\n";
- }
-
- for (size_t i = 0; i < callouts.size(); ++i)
- {
- params.push_back("[callout" + boost::lexical_cast<std::string>(i) + "]");
- }
+ params.push_back("[callout" + boost::lexical_cast<std::string>(snippet.callout_base_id + i) + "]");
         }
-
- template_symbol symbol(id, params, snippet, first.get_position(), true);
+
+ // TODO: Save position in start_snippet
+ template_symbol symbol(snippet.id, params, body, first.get_position(), true);
         symbol.callout = true;
- symbol.callouts = callouts;
+ symbol.callouts = snippet.callouts;
         storage.push_back(symbol);
 
- callouts.clear();
- code.clear();
- snippet.clear();
- id.clear();
+ // Merge the snippet into its parent
+
+ if(!snippet_stack.empty())
+ {
+ snippet_data& next = snippet_stack.top();
+ if(!snippet.content.empty()) {
+ if(!snippet.start_code) {
+ close_code();
+ }
+ else if(!next.end_code) {
+ next.content += "\n\n";
+ next.content += source_type;
+ next.content += "```\n";
+ }
+
+ next.content += snippet.content;
+ next.end_code = snippet.end_code;
+ }
+
+ next.callouts.insert(next.callouts.end(), snippet.callouts.begin(), snippet.callouts.end());
+ }
     }
 
     int load_snippets(

Modified: trunk/tools/quickbook/doc/quickbook.qbk
==============================================================================
--- trunk/tools/quickbook/doc/quickbook.qbk (original)
+++ trunk/tools/quickbook/doc/quickbook.qbk 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
@@ -229,6 +229,7 @@
 * Better generated markup for callout lists.
 * In docbook, variable list entries can only have one `listitem`, so if an
   entry has multiple values, merge them into one `listitem`.
+* Support nested code snippets.
 * Further work on quickbook 1.6, still not stable.
   * Allow heading to have ids, using the syntax: `[heading:id title]`.
 

Modified: trunk/tools/quickbook/test/callouts.cpp
==============================================================================
--- trunk/tools/quickbook/test/callouts.cpp (original)
+++ trunk/tools/quickbook/test/callouts.cpp 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
@@ -33,3 +33,16 @@
 }
 
 //]
+
+//[ example4
+
+int roll_die() {
+ /*<< callout 1 >>*/
+ boost::variate_generator<boost::mt19937&, boost::uniform_int<> > die(gen, dist);
+//[ example4a
+ /*<< callout 2 >>*/
+ boost::uniform_int<> dist(1, 6); /*< create a uniform_int distribution >*/
+//]
+}
+
+//]

Modified: trunk/tools/quickbook/test/callouts.gold
==============================================================================
--- trunk/tools/quickbook/test/callouts.gold (original)
+++ trunk/tools/quickbook/test/callouts.gold 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
@@ -86,4 +86,50 @@
       </important>
     </callout>
   </calloutlist>
+ <para>
+ Example 4:
+ </para>
+ <para>
+
+<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">roll_die</phrase><phrase role="special">()</phrase> <phrase role="special">{</phrase>
+ <!--quickbook-escape-prefix--><co id="callout_tests4co" linkends="callout_tests4" /><!--quickbook-escape-postfix--><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variate_generator</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">mt19937</phrase><phrase role="special">&amp;,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">uniform_int</phrase><phrase role="special">&lt;&gt;</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">die</phrase><phrase role="special">(</phrase><phrase role="identifier">gen</phrase><phrase role="special">,</phrase> <phrase role="identifier">dist</phrase><phrase role="special">);</phrase>
+<!--quickbook-escape-prefix--><co id="callout_tests5co" linkends="callout_tests5" /><!--quickbook-escape-postfix--><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">uniform_int</phrase><phrase role="special">&lt;&gt;</phrase> <phrase role="identifier">dist</phrase><phrase role="special">(</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase> <phrase role="number">6</phrase><phrase role="special">);</phrase> <!--quickbook-escape-prefix--><co id="callout_tests6co" linkends="callout_tests6" /><!--quickbook-escape-postfix-->
+<phrase role="special">}</phrase>
+
+</programlisting>
+ </para>
+ <calloutlist>
+ <callout arearefs="callout_tests4co" id="callout_tests4">
+ <para>
+ callout 1
+ </para>
+ </callout>
+ <callout arearefs="callout_tests5co" id="callout_tests5">
+ <para>
+ callout 2
+ </para>
+ </callout>
+ <callout arearefs="callout_tests6co" id="callout_tests6">
+ <para>
+ create a uniform_int distribution
+ </para>
+ </callout>
+ </calloutlist>
+ <para>
+
+<programlisting><!--quickbook-escape-prefix--><co id="callout_tests7co" linkends="callout_tests7" /><!--quickbook-escape-postfix--><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">uniform_int</phrase><phrase role="special">&lt;&gt;</phrase> <phrase role="identifier">dist</phrase><phrase role="special">(</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase> <phrase role="number">6</phrase><phrase role="special">);</phrase> <!--quickbook-escape-prefix--><co id="callout_tests8co" linkends="callout_tests8" /><!--quickbook-escape-postfix-->
+</programlisting>
+ </para>
+ <calloutlist>
+ <callout arearefs="callout_tests7co" id="callout_tests7">
+ <para>
+ callout 2
+ </para>
+ </callout>
+ <callout arearefs="callout_tests8co" id="callout_tests8">
+ <para>
+ create a uniform_int distribution
+ </para>
+ </callout>
+ </calloutlist>
 </article>

Modified: trunk/tools/quickbook/test/callouts.quickbook
==============================================================================
--- trunk/tools/quickbook/test/callouts.quickbook (original)
+++ trunk/tools/quickbook/test/callouts.quickbook 2010-08-23 17:51:53 EDT (Mon, 23 Aug 2010)
@@ -19,3 +19,8 @@
 Example 3 (again!):
 
 [example3]
+
+Example 4:
+
+[example4]
+[example4a]


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