From 85e8c03d7007847f968bc9d3671897bbc7524065 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 3 Apr 2011 19:19:07 +0000 Subject: [PATCH] Quickbook: Include code file in 1.6. [SVN r70960] --- src/actions.cpp | 300 ++++++++++-------- src/actions.hpp | 3 +- src/code_snippet.cpp | 18 +- test/Jamfile.v2 | 1 - test/import.quickbook | 12 - test/include/Jamfile.v2 | 2 + .../{import.gold => include/code-import.gold} | 0 test/include/code-import.quickbook | 12 + test/include/code-include.gold | 214 +++++++++++++ test/include/code-include.quickbook | 16 + 10 files changed, 428 insertions(+), 150 deletions(-) delete mode 100644 test/import.quickbook rename test/{import.gold => include/code-import.gold} (100%) create mode 100644 test/include/code-import.quickbook create mode 100644 test/include/code-include.gold create mode 100644 test/include/code-include.quickbook diff --git a/src/actions.cpp b/src/actions.cpp index e2ba0e1..e36c89e 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -78,7 +78,7 @@ namespace quickbook void variable_list_action(quickbook::actions&, value); void table_action(quickbook::actions&, value); void xinclude_action(quickbook::actions&, value); - void include_action(quickbook::actions&, value); + void include_action(quickbook::actions&, value, file_position); void image_action(quickbook::actions&, value); void anchor_action(quickbook::actions&, value); void link_action(quickbook::actions&, value); @@ -136,7 +136,7 @@ namespace quickbook return xinclude_action(actions, v); case block_tags::import: case block_tags::include: - return include_action(actions, v); + return include_action(actions, v, first.get_position()); case phrase_tags::image: return image_action(actions, v); case phrase_tags::anchor: @@ -1063,7 +1063,7 @@ namespace quickbook std::pair::const_iterator> get_arguments( - std::vector& args + std::vector const& args , std::vector const& params , template_scope const& scope , file_position const& pos @@ -1074,7 +1074,6 @@ namespace quickbook std::vector::const_iterator tpl = params.begin(); std::vector empty_params; - // Store each of the argument passed in as local templates: while (arg != args.end()) { @@ -1132,28 +1131,11 @@ namespace quickbook int callout_id = 0; } - void do_template_action(quickbook::actions& actions, value template_list, + void call_template(quickbook::actions& actions, bool template_escape, + template_symbol const* symbol, + std::vector const& args, file_position pos) { - if(!(actions.process_state & actions.process_output)) return; - - // Get the arguments - value_consumer values = template_list; - - bool template_escape = values.check(template_tags::escape); - if(template_escape) values.consume(); - - std::string identifier = values.consume(template_tags::identifier).get_quickbook(); - - std::vector args; - - BOOST_FOREACH(value arg, values) - { - args.push_back(template_body(arg, actions.filename)); - } - - values.finish(); - ++actions.template_depth; if (actions.template_depth > actions.max_template_depth) { @@ -1171,15 +1153,12 @@ namespace quickbook // arguments are expanded. template_scope const& call_scope = actions.templates.top_scope(); - template_symbol const* symbol = actions.templates.find(identifier); - BOOST_ASSERT(symbol); - std::string block; std::string phrase; { template_state state(actions); - + // Store the current section level so that we can ensure that // [section] and [endsect] tags in the template are balanced. actions.min_section_level = actions.section_level; @@ -1191,65 +1170,18 @@ namespace quickbook if (qbk_version_n >= 105) actions.templates.set_parent_scope(*symbol->parent); - /////////////////////////////////// - // Initialise the arguments - - if (!symbol->callouts.check()) - { - // Break the arguments for a template - - if (!break_arguments(args, symbol->params, actions.filename, pos)) - { - --actions.template_depth; - ++actions.error_count; - return; - } - } - else - { - if (!args.empty()) - { - detail::outerr(actions.filename, pos.line) - << "Arguments for code snippet." - <params.size(); - - for(unsigned int i = 0; i < size; ++i) - { - std::string callout_id = actions.doc_id + - boost::lexical_cast(detail::callout_id + i); - - std::string code; - code += "'''"; - code += ""; - code += "'''"; - - args.push_back(template_body( - qbk_value(code, pos, template_tags::phrase), - actions.filename)); - } - } - /////////////////////////////////// // Prepare the arguments as local templates bool get_arg_result; std::vector::const_iterator tpl; boost::tie(get_arg_result, tpl) = - get_arguments(args, symbol->params, - call_scope, pos, actions); + get_arguments(args, symbol->params, call_scope, pos, actions); if (!get_arg_result) { --actions.template_depth; return; } - /////////////////////////////////// // parse the template body: @@ -1272,7 +1204,9 @@ namespace quickbook if (actions.section_level != actions.min_section_level) { detail::outerr(actions.filename, pos.line) - << "Mismatched sections in template " << detail::utf8(identifier) << std::endl; + << "Mismatched sections in template " + << detail::utf8(symbol->identifier) + << std::endl; --actions.template_depth; ++actions.error_count; return; @@ -1282,45 +1216,6 @@ namespace quickbook actions.phrase.swap(phrase); } - if(!symbol->callouts.empty()) - { - BOOST_ASSERT(phrase.empty()); - block += ""; - BOOST_FOREACH(value c, symbol->callouts) - { - std::string callout_id = actions.doc_id + - boost::lexical_cast(detail::callout_id++); - - std::string callout_value; - { - template_state state(actions); - bool r = parse_template( - template_body(c, symbol->body.filename), false, actions); - - if(!r) - { - detail::outerr(symbol->body.filename, c.get_position().line) - << "Expanding callout." << std::endl - << "------------------begin------------------" << std::endl - << detail::utf8(c.get_quickbook()) - << std::endl - << "------------------end--------------------" << std::endl - ; - ++actions.error_count; - return; - } - - actions.out.swap(callout_value); - } - - block += ""; - block += callout_value; - block += ""; - } - block += ""; - } - if(symbol->body.is_block() || !block.empty()) { actions.paragraph(); // For paragraphs before the template call. actions.out << block; @@ -1332,6 +1227,139 @@ namespace quickbook --actions.template_depth; } + void call_code_snippet(quickbook::actions& actions, + bool template_escape, + template_symbol const* symbol, + file_position pos) + { + assert(symbol->body.is_block()); + + std::vector args; + unsigned int size = symbol->params.size(); + + for(unsigned int i = 0; i < size; ++i) + { + std::string callout_id = actions.doc_id + + boost::lexical_cast(detail::callout_id + i); + + std::string code; + code += "'''"; + code += ""; + code += "'''"; + + args.push_back(template_body( + qbk_value(code, pos, template_tags::phrase), + actions.filename)); + } + + call_template(actions, template_escape, symbol, args, pos); + + std::string block; + + if(!symbol->callouts.empty()) + { + template_state state(actions); + ++actions.template_depth; + + block += ""; + BOOST_FOREACH(value c, symbol->callouts) + { + std::string callout_id = actions.doc_id + + boost::lexical_cast(detail::callout_id++); + + std::string callout_value; + { + template_state state(actions); + bool r = parse_template( + template_body(c, symbol->body.filename), false, actions); + + if(!r) + { + detail::outerr(symbol->body.filename, c.get_position().line) + << "Expanding callout." << std::endl + << "------------------begin------------------" << std::endl + << detail::utf8(c.get_quickbook()) + << std::endl + << "------------------end--------------------" << std::endl + ; + ++actions.error_count; + --actions.template_depth; + return; + } + + actions.out.swap(callout_value); + } + + block += ""; + block += callout_value; + block += ""; + } + block += ""; + + --actions.template_depth; + } + + actions.out << block; + } + + void do_template_action(quickbook::actions& actions, value template_list, + file_position pos) + { + if(!(actions.process_state & actions.process_output)) return; + + // Get the arguments + value_consumer values = template_list; + + bool template_escape = values.check(template_tags::escape); + if(template_escape) values.consume(); + + std::string identifier = values.consume(template_tags::identifier).get_quickbook(); + + std::vector args; + + BOOST_FOREACH(value arg, values) + { + args.push_back(template_body(arg, actions.filename)); + } + + values.finish(); + + template_symbol const* symbol = actions.templates.find(identifier); + BOOST_ASSERT(symbol); + + /////////////////////////////////// + // Initialise the arguments + + if (!symbol->callouts.check()) + { + // Break the arguments for a template + + if (!break_arguments(args, symbol->params, actions.filename, pos)) + { + ++actions.error_count; + return; + } + + call_template(actions, template_escape, symbol, args, pos); + } + else + { + if (!args.empty()) + { + detail::outerr(actions.filename, pos.line) + << "Arguments for code snippet." + < storage; actions.error_count += - load_snippets(paths.filename.string(), storage, ext); + load_snippets(paths.filename.string(), storage, ext, load_type); - BOOST_FOREACH(template_symbol& ts, storage) + if (load_type == block_tags::import) { - std::string tname = ts.identifier; - ts.parent = &actions.templates.top_scope(); - if (!actions.templates.add(ts)) + BOOST_FOREACH(template_symbol& ts, storage) { - detail::outerr(ts.body.filename, ts.body.content.get_position().line) - << "Template Redefinition: " << detail::utf8(tname) << std::endl; - ++actions.error_count; + std::string tname = ts.identifier; + ts.parent = &actions.templates.top_scope(); + if (!actions.templates.add(ts)) + { + detail::outerr(ts.body.filename, ts.body.content.get_position().line) + << "Template Redefinition: " << detail::utf8(tname) << std::endl; + ++actions.error_count; + } } } + else + { + template_symbol* snippet = &storage.back(); + snippet->parent = &actions.templates.top_scope(); + call_code_snippet(actions, false, snippet, pos); + } } - void include_action(quickbook::actions& actions, value include) + void include_action(quickbook::actions& actions, value include, file_position pos) { if (!(actions.process_state & actions.process_output)) return; write_anchors(actions, actions.out); @@ -1846,7 +1876,7 @@ namespace quickbook } else { - load_source_file(actions, paths, include.get_tag(), include_doc_id); + load_source_file(actions, paths, include.get_tag(), pos, include_doc_id); } } else @@ -1857,7 +1887,7 @@ namespace quickbook } else { - load_source_file(actions, paths, include.get_tag(), include_doc_id); + load_source_file(actions, paths, include.get_tag(), pos, include_doc_id); } } } diff --git a/src/actions.hpp b/src/actions.hpp index 80dbe65..8cc1d1a 100644 --- a/src/actions.hpp +++ b/src/actions.hpp @@ -53,7 +53,8 @@ namespace quickbook } int load_snippets(std::string const& file, std::vector& storage, - std::string const& extension); + std::string const& extension, value::tag_type load_type); + std::string syntax_highlight( iterator first, iterator last, actions& escape_actions, diff --git a/src/code_snippet.cpp b/src/code_snippet.cpp index 5b02c3e..6b799e2 100644 --- a/src/code_snippet.cpp +++ b/src/code_snippet.cpp @@ -13,6 +13,7 @@ #include #include #include +#include "block_tags.hpp" #include "template_stack.hpp" #include "actions.hpp" #include "values.hpp" @@ -312,8 +313,12 @@ namespace quickbook std::string const& file , std::vector& storage // snippets are stored in a // vector of template_symbols - , std::string const& extension) + , std::string const& extension + , value::tag_type load_type) { + assert(load_type == block_tags::include || + load_type == block_tags::import); + std::string code; int err = detail::load(file, code); if (err != 0) @@ -325,6 +330,13 @@ namespace quickbook bool is_python = extension == ".py"; code_snippet_actions a(storage, file, is_python ? "[python]" : "[c++]"); // TODO: Should I check that parse succeeded? + + if (load_type == block_tags::include) { + // Use an id that couldn't occur normally. + a.id = "global tag"; + a.start_snippet(first, first); + } + if(is_python) { boost::spirit::classic::parse(first, last, python_code_snippet_grammar(a)); } @@ -332,6 +344,10 @@ namespace quickbook boost::spirit::classic::parse(first, last, cpp_code_snippet_grammar(a)); } + if (load_type == block_tags::include) { + a.end_snippet(first, first); + } + return 0; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e56b964..fb4efb2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -38,7 +38,6 @@ test-suite quickbook.test : [ quickbook-test mismatched-brackets-2 ] [ quickbook-error-test mismatched-brackets-3 ] [ quickbook-test xinclude : : : ../src ] - [ quickbook-test import ] [ quickbook-test include_1_5 ] [ quickbook-test include_1_6 ] [ quickbook-test include_1_6-2 ] diff --git a/test/import.quickbook b/test/import.quickbook deleted file mode 100644 index b43987e..0000000 --- a/test/import.quickbook +++ /dev/null @@ -1,12 +0,0 @@ -[article Import] - -[import stub.c] -[import stub.py] -[import stub.cpp] - -[foo] - -[foo_py] - -[foo_c] - diff --git a/test/include/Jamfile.v2 b/test/include/Jamfile.v2 index 66e4155..2b02915 100644 --- a/test/include/Jamfile.v2 +++ b/test/include/Jamfile.v2 @@ -24,6 +24,8 @@ test-suite quickbook.test : [ quickbook-test templates-1.6 ] [ quickbook-test macros-1.5 ] [ quickbook-test macros-1.6 ] + [ quickbook-test code-import ] + [ quickbook-test code-include ] [ quickbook-error-test section-fail1 ] [ quickbook-error-test section-fail2 ] ; diff --git a/test/import.gold b/test/include/code-import.gold similarity index 100% rename from test/import.gold rename to test/include/code-import.gold diff --git a/test/include/code-import.quickbook b/test/include/code-import.quickbook new file mode 100644 index 0000000..587d297 --- /dev/null +++ b/test/include/code-import.quickbook @@ -0,0 +1,12 @@ +[article Import] + +[import ../stub.c] +[import ../stub.py] +[import ../stub.cpp] + +[foo] + +[foo_py] + +[foo_c] + diff --git a/test/include/code-include.gold b/test/include/code-include.gold new file mode 100644 index 0000000..603c52e --- /dev/null +++ b/test/include/code-include.gold @@ -0,0 +1,214 @@ + + +
+ Include + + +/*============================================================================= + Copyright (c) 2006 Joel de Guzman + 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) +=============================================================================*/ + + + + + This is the C foo function. + + + This description can have paragraphs... + + + + + lists + + + + + etc. + + + + + And any quickbook block markup. + + + +char* foo() +{ + // return 'em, foo man! + return "foo"; +} + + + + +# Copyright 2009 Daniel James +# +# 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) + + + + + This is the Python foo + function. + + + This description can have paragraphs... + + + + + lists + + + + + etc. + + + + + And any quickbook block markup. + + + +def foo(): + # return 'em, foo man! + return "foo" + +print foo() + + + +/*============================================================================= + Copyright (c) 2006 Joel de Guzman + 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 <string> + + + + + This is the bar function + + + +std::string bar() +{ + // return 'em, bar man! + return "bar"; +} + + + Some trailing text here + + + This is the foo function. + + + This description can have paragraphs... + + + + + lists + + + + + etc. + + + + + And any quickbook block markup. + + + +std::string foo() +{ + // return 'em, foo man! + return "foo"; +} +std::string foo_bar() +{ + return "foo-bar"; +} +class x +{ +public: + + x() : n(0) + { + } + + ~x() + { + } + + int get() const + { + return n; + } + + void set(int n_) + { + n = n_; + } +}; + + + + + + The Mythical FooBar. See Foobar + for details + + + + + return 'em, foo-bar man! + + + + + Constructor + + + + + Destructor + + + + + Get the n member variable + + + + + Set the n member variable + + + + + [foo] + + + [foo_py] + + + [foo_c] + +
diff --git a/test/include/code-include.quickbook b/test/include/code-include.quickbook new file mode 100644 index 0000000..8a47538 --- /dev/null +++ b/test/include/code-include.quickbook @@ -0,0 +1,16 @@ +[article Include +[quickbook 1.6] +] + +[include ../stub.c] +[include ../stub.py] +[include ../stub.cpp] + +[/ These shouldn't expand ] + +[foo] + +[foo_py] + +[foo_c] +