1 /*============================================================================= 2 Copyright (c) 2002 2004 2006 Joel de Guzman 3 Copyright (c) 2004 Eric Niebler 4 Copyright (c) 2005 Thomas Guest 5 http://spirit.sourceforge.net/ 6 7 Use, modification and distribution is subject to the Boost Software 8 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 9 http://www.boost.org/LICENSE_1_0.txt) 10 =============================================================================*/ 11 #include "state.hpp" 12 #include "state_save.hpp" 13 #include "document_state.hpp" 14 #include "quickbook.hpp" 15 #include "grammar.hpp" 16 #include "native_text.hpp" 17 #include "utils.hpp" 18 #include "phrase_tags.hpp" 19 #include <boost/foreach.hpp> 20 21 #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) 22 #pragma warning(disable:4355) 23 #endif 24 25 namespace quickbook 26 { 27 char const* quickbook_get_date = "__quickbook_get_date__"; 28 char const* quickbook_get_time = "__quickbook_get_time__"; 29 30 unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version 31 state(fs::path const & filein_,fs::path const & xinclude_base_,string_stream & out_,document_state & document)32 state::state(fs::path const& filein_, fs::path const& xinclude_base_, 33 string_stream& out_, document_state& document) 34 : grammar_() 35 36 , order_pos(0) 37 , xinclude_base(xinclude_base_) 38 39 , templates() 40 , error_count(0) 41 , anchors() 42 , warned_about_breaks(false) 43 , conditional(true) 44 , document(document) 45 , callouts() 46 , callout_depth(0) 47 , dependencies() 48 , explicit_list(false) 49 50 , imported(false) 51 , macro() 52 , source_mode() 53 , source_mode_next() 54 , source_mode_next_pos() 55 , current_file(0) 56 , current_path(filein_, 0, filein_.filename()) 57 58 , template_depth(0) 59 , min_section_level(1) 60 61 , in_list(false) 62 , in_list_save() 63 , out(out_) 64 , phrase() 65 66 , values(¤t_file) 67 { 68 // add the predefined macros 69 macro.add 70 ("__DATE__", std::string(quickbook_get_date)) 71 ("__TIME__", std::string(quickbook_get_time)) 72 ("__FILENAME__", std::string()) 73 ; 74 update_filename_macro(); 75 76 boost::scoped_ptr<quickbook_grammar> g( 77 new quickbook_grammar(*this)); 78 grammar_.swap(g); 79 } 80 grammar() const81 quickbook_grammar& state::grammar() const { 82 return *grammar_; 83 } 84 update_filename_macro()85 void state::update_filename_macro() { 86 *boost::spirit::classic::find(macro, "__FILENAME__") 87 = detail::encode_string( 88 detail::path_to_generic(current_path.abstract_file_path)); 89 } 90 get_new_order_pos()91 unsigned state::get_new_order_pos() { 92 return ++order_pos; 93 } 94 push_output()95 void state::push_output() { 96 out.push(); 97 phrase.push(); 98 in_list_save.push(in_list); 99 } 100 pop_output()101 void state::pop_output() { 102 phrase.pop(); 103 out.pop(); 104 in_list = in_list_save.top(); 105 in_list_save.pop(); 106 } 107 tagged_source_mode() const108 source_mode_info state::tagged_source_mode() const { 109 source_mode_info result; 110 111 BOOST_FOREACH(source_mode_info const& s, tagged_source_mode_stack) { 112 result.update(s); 113 } 114 115 return result; 116 } 117 current_source_mode() const118 source_mode_info state::current_source_mode() const { 119 source_mode_info result = source_mode; 120 121 result.update(document.section_source_mode()); 122 123 BOOST_FOREACH(source_mode_info const& s, tagged_source_mode_stack) { 124 result.update(s); 125 } 126 127 return result; 128 } 129 change_source_mode(source_mode_type s)130 void state::change_source_mode(source_mode_type s) { 131 source_mode = source_mode_info(s, get_new_order_pos()); 132 } 133 push_tagged_source_mode(source_mode_type s)134 void state::push_tagged_source_mode(source_mode_type s) { 135 tagged_source_mode_stack.push_back( 136 source_mode_info(s, s ? get_new_order_pos() : 0)); 137 } 138 pop_tagged_source_mode()139 void state::pop_tagged_source_mode() { 140 assert(!tagged_source_mode_stack.empty()); 141 tagged_source_mode_stack.pop_back(); 142 } 143 state_save(quickbook::state & state,scope_flags scope)144 state_save::state_save(quickbook::state& state, scope_flags scope) 145 : state(state) 146 , scope(scope) 147 , qbk_version(qbk_version_n) 148 , imported(state.imported) 149 , current_file(state.current_file) 150 , current_path(state.current_path) 151 , xinclude_base(state.xinclude_base) 152 , source_mode(state.source_mode) 153 , macro() 154 , template_depth(state.template_depth) 155 , min_section_level(state.min_section_level) 156 { 157 if (scope & scope_macros) macro = state.macro; 158 if (scope & scope_templates) state.templates.push(); 159 if (scope & scope_output) { 160 state.push_output(); 161 } 162 state.values.builder.save(); 163 } 164 ~state_save()165 state_save::~state_save() 166 { 167 state.values.builder.restore(); 168 boost::swap(qbk_version_n, qbk_version); 169 boost::swap(state.imported, imported); 170 boost::swap(state.current_file, current_file); 171 boost::swap(state.current_path, current_path); 172 boost::swap(state.xinclude_base, xinclude_base); 173 boost::swap(state.source_mode, source_mode); 174 if (scope & scope_output) { 175 state.pop_output(); 176 } 177 if (scope & scope_templates) state.templates.pop(); 178 if (scope & scope_macros) state.macro = macro; 179 boost::swap(state.template_depth, template_depth); 180 boost::swap(state.min_section_level, min_section_level); 181 } 182 } 183