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 "document_state.hpp" 13 #include "for.hpp" 14 #include "grammar.hpp" 15 #include "path.hpp" 16 #include "phrase_tags.hpp" 17 #include "quickbook.hpp" 18 #include "state_save.hpp" 19 #include "utils.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( 33 fs::path const& filein_, 34 fs::path const& xinclude_base_, 35 string_stream& out_, 36 document_state& document_) 37 : grammar_() 38 39 , order_pos(0) 40 , xinclude_base(xinclude_base_) 41 42 , templates() 43 , error_count(0) 44 , anchors() 45 , warned_about_breaks(false) 46 , conditional(true) 47 , document(document_) 48 , callouts() 49 , callout_depth(0) 50 , dependencies() 51 , explicit_list(false) 52 , strict_mode(false) 53 54 , imported(false) 55 , macro() 56 , source_mode() 57 , source_mode_next() 58 , source_mode_next_pos() 59 , current_file(0) 60 , current_path(filein_, 0, filein_.filename()) 61 62 , template_depth(0) 63 , min_section_level(1) 64 65 , in_list(false) 66 , in_list_save() 67 , out(out_) 68 , phrase() 69 70 , values(¤t_file) 71 { 72 // add the predefined macros 73 macro.add("__DATE__", std::string(quickbook_get_date))( 74 "__TIME__", 75 std::string(quickbook_get_time))("__FILENAME__", std::string()); 76 update_filename_macro(); 77 78 boost::scoped_ptr<quickbook_grammar> g(new quickbook_grammar(*this)); 79 grammar_.swap(g); 80 } 81 grammar() const82 quickbook_grammar& state::grammar() const { return *grammar_; } 83 update_filename_macro()84 void state::update_filename_macro() 85 { 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() { return ++order_pos; } 92 push_output()93 void state::push_output() 94 { 95 out.push(); 96 phrase.push(); 97 in_list_save.push(in_list); 98 } 99 pop_output()100 void state::pop_output() 101 { 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 { 110 source_mode_info result; 111 112 QUICKBOOK_FOR (source_mode_info const& s, tagged_source_mode_stack) { 113 result.update(s); 114 } 115 116 return result; 117 } 118 current_source_mode() const119 source_mode_info state::current_source_mode() const 120 { 121 source_mode_info result = source_mode; 122 123 result.update(document.section_source_mode()); 124 125 QUICKBOOK_FOR (source_mode_info const& s, tagged_source_mode_stack) { 126 result.update(s); 127 } 128 129 return result; 130 } 131 change_source_mode(source_mode_type s)132 void state::change_source_mode(source_mode_type s) 133 { 134 source_mode = source_mode_info(s, get_new_order_pos()); 135 } 136 push_tagged_source_mode(source_mode_type s)137 void state::push_tagged_source_mode(source_mode_type s) 138 { 139 tagged_source_mode_stack.push_back( 140 source_mode_info(s, s ? get_new_order_pos() : 0)); 141 } 142 pop_tagged_source_mode()143 void state::pop_tagged_source_mode() 144 { 145 assert(!tagged_source_mode_stack.empty()); 146 tagged_source_mode_stack.pop_back(); 147 } 148 state_save(quickbook::state & state_,scope_flags scope_)149 state_save::state_save(quickbook::state& state_, scope_flags scope_) 150 : state(state_) 151 , scope(scope_) 152 , qbk_version(qbk_version_n) 153 , imported(state.imported) 154 , current_file(state.current_file) 155 , current_path(state.current_path) 156 , xinclude_base(state.xinclude_base) 157 , source_mode(state.source_mode) 158 , macro() 159 , template_depth(state.template_depth) 160 , min_section_level(state.min_section_level) 161 { 162 if (scope & scope_macros) macro = state.macro; 163 if (scope & scope_templates) state.templates.push(); 164 if (scope & scope_output) { 165 state.push_output(); 166 } 167 state.values.builder.save(); 168 } 169 ~state_save()170 state_save::~state_save() 171 { 172 state.values.builder.restore(); 173 boost::swap(qbk_version_n, qbk_version); 174 boost::swap(state.imported, imported); 175 boost::swap(state.current_file, current_file); 176 boost::swap(state.current_path, current_path); 177 boost::swap(state.xinclude_base, xinclude_base); 178 boost::swap(state.source_mode, source_mode); 179 if (scope & scope_output) { 180 state.pop_output(); 181 } 182 if (scope & scope_templates) state.templates.pop(); 183 if (scope & scope_macros) state.macro = macro; 184 boost::swap(state.template_depth, template_depth); 185 boost::swap(state.min_section_level, min_section_level); 186 } 187 } 188