| /*============================================================================= |
| Copyright (c) 2002 2004 2006 Joel de Guzman |
| Copyright (c) 2004 Eric Niebler |
| Copyright (c) 2005 Thomas Guest |
| 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 "actions_class.hpp" |
| #include "quickbook.hpp" |
| #include "grammar.hpp" |
| #include "input_path.hpp" |
| |
| #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) |
| #pragma warning(disable:4355) |
| #endif |
| |
| namespace quickbook |
| { |
| actions::actions(fs::path const& filein_, fs::path const& xinclude_base_, string_stream& out_) |
| : grammar_() |
| |
| // header info |
| , doc_type() |
| , doc_title_qbk() |
| , doc_id() |
| |
| // main output stream |
| , out(out_) |
| |
| // auxilliary streams |
| , phrase() |
| |
| // value actions |
| , values() |
| , to_value(*this) |
| , docinfo_value(*this) |
| , scoped_cond_phrase(*this) |
| , scoped_output(*this) |
| , scoped_no_eols(*this) |
| , scoped_context(*this) |
| |
| // state |
| , filename(filein_) |
| , filename_relative(filein_.filename()) |
| , xinclude_base(xinclude_base_) |
| , macro_change_depth(0) |
| , macro() |
| , section_level(0) |
| , min_section_level(0) |
| , section_id() |
| , qualified_section_id() |
| , source_mode("c++") |
| |
| // temporary or global state |
| , template_depth(0) |
| , templates() |
| , error_count(0) |
| , anchors() |
| , no_eols(true) |
| , suppress(false) |
| , warned_about_breaks(false) |
| |
| // actions |
| , element(*this) |
| , error(*this) |
| , code(out, phrase, *this) |
| , code_block(phrase, phrase, *this) |
| , inline_code(phrase, *this) |
| , paragraph(*this) |
| , space_char(phrase) |
| , plain_char(phrase, *this) |
| , raw_char(phrase, *this) |
| , escape_unicode(phrase, *this) |
| |
| , simple_markup(phrase, *this) |
| |
| , break_(phrase, *this) |
| , do_macro(phrase, *this) |
| |
| , element_id_warning(*this) |
| { |
| // add the predefined macros |
| macro.add |
| ("__DATE__", std::string(quickbook_get_date)) |
| ("__TIME__", std::string(quickbook_get_time)) |
| ("__FILENAME__", detail::path_to_generic(filename_relative)) |
| ; |
| |
| boost::scoped_ptr<quickbook_grammar> g( |
| new quickbook_grammar(*this)); |
| grammar_.swap(g); |
| } |
| |
| void actions::push() |
| { |
| state_stack.push( |
| boost::make_tuple( |
| filename |
| , xinclude_base |
| , macro_change_depth |
| , section_level |
| , min_section_level |
| , section_id |
| , qualified_section_id |
| , source_mode |
| ) |
| ); |
| |
| out.push(); |
| phrase.push(); |
| templates.push(); |
| values.builder.save(); |
| } |
| |
| // Pushing and popping the macro symbol table is pretty expensive, so |
| // instead implement a sort of 'stack on write'. Call this whenever a |
| // change is made to the macro table, and it'll stack the current macros |
| // if necessary. Would probably be better to implement macros in a less |
| // expensive manner. |
| void actions::copy_macros_for_write() |
| { |
| if(macro_change_depth != state_stack.size()) |
| { |
| macro_stack.push(macro); |
| macro_change_depth = state_stack.size(); |
| } |
| } |
| |
| void actions::pop() |
| { |
| if(macro_change_depth == state_stack.size()) |
| { |
| macro = macro_stack.top(); |
| macro_stack.pop(); |
| } |
| |
| boost::tie( |
| filename |
| , xinclude_base |
| , macro_change_depth |
| , section_level |
| , min_section_level |
| , section_id |
| , qualified_section_id |
| , source_mode |
| ) = state_stack.top(); |
| state_stack.pop(); |
| |
| out.pop(); |
| phrase.pop(); |
| templates.pop(); |
| values.builder.restore(); |
| } |
| |
| quickbook_grammar& actions::grammar() const { |
| return *grammar_; |
| } |
| } |