1 /*============================================================================= 2 Copyright (c) 2002 2004 2006 Joel de Guzman 3 Copyright (c) 2004 Eric Niebler 4 http://spirit.sourceforge.net/ 5 6 Use, modification and distribution is subject to the Boost Software 7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 8 http://www.boost.org/LICENSE_1_0.txt) 9 =============================================================================*/ 10 #if !defined(BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP) 11 #define BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP 12 13 #include <string> 14 #include <vector> 15 #include <boost/spirit/include/classic_parser.hpp> 16 #include "fwd.hpp" 17 #include "iterator.hpp" 18 #include "scoped.hpp" 19 #include "utils.hpp" 20 #include "values.hpp" 21 22 namespace quickbook 23 { 24 namespace cl = boost::spirit::classic; 25 26 // Match if quickbook version is within range 27 struct quickbook_range : cl::parser<quickbook_range> 28 { quickbook_rangequickbook::quickbook_range29 explicit quickbook_range(unsigned lower_, unsigned upper_) 30 : lower(lower_), upper(upper_) 31 { 32 } 33 34 bool in_range() const; 35 36 template <typename ScannerT> parsequickbook::quickbook_range37 typename cl::parser_result<quickbook_range, ScannerT>::type parse( 38 ScannerT const& scan) const 39 { 40 return in_range() ? scan.empty_match() : scan.no_match(); 41 } 42 43 unsigned lower, upper; 44 }; 45 qbk_ver(unsigned lower,unsigned upper=999u)46 inline quickbook_range qbk_ver(unsigned lower, unsigned upper = 999u) 47 { 48 return quickbook_range(lower, upper); 49 } 50 51 // Match if in strict mode. 52 struct quickbook_strict : cl::parser<quickbook_strict> 53 { quickbook_strictquickbook::quickbook_strict54 explicit quickbook_strict( 55 quickbook::state& state_, bool positive_ = true) 56 : state(state_), positive(positive_) 57 { 58 } 59 60 bool is_strict_checking() const; 61 62 template <typename ScannerT> parsequickbook::quickbook_strict63 typename cl::parser_result<quickbook_range, ScannerT>::type parse( 64 ScannerT const& scan) const 65 { 66 return is_strict_checking() == positive ? scan.empty_match() 67 : scan.no_match(); 68 } 69 operator ~quickbook::quickbook_strict70 quickbook_strict operator~() const 71 { 72 return quickbook_strict(state, !positive); 73 } 74 75 quickbook::state& state; 76 bool positive; 77 }; 78 qbk_strict(quickbook::state & state,unsigned lower=999u)79 inline quickbook_strict qbk_strict( 80 quickbook::state& state, unsigned lower = 999u) 81 { 82 return quickbook_strict(state, lower); 83 } 84 85 // Throws load_error 86 int load_snippets( 87 fs::path const& file, 88 std::vector<template_symbol>& storage, 89 std::string const& extension, 90 value::tag_type load_type); 91 92 struct error_message_action 93 { 94 // Prints an error message to std::cerr 95 error_message_actionquickbook::error_message_action96 explicit error_message_action( 97 quickbook::state& state_, std::string const& message_) 98 : state(state_), message(message_) 99 { 100 } 101 102 void operator()(parse_iterator, parse_iterator) const; 103 104 quickbook::state& state; 105 std::string message; 106 }; 107 108 struct error_action 109 { 110 // Prints an error message to std::cerr 111 error_actionquickbook::error_action112 explicit error_action(quickbook::state& state_) : state(state_) {} 113 114 void operator()(parse_iterator first, parse_iterator last) const; 115 operator ()quickbook::error_action116 error_message_action operator()(std::string const& message) 117 { 118 return error_message_action(state, message); 119 } 120 121 quickbook::state& state; 122 }; 123 124 struct element_action 125 { element_actionquickbook::element_action126 explicit element_action(quickbook::state& state_) : state(state_) {} 127 128 void operator()(parse_iterator, parse_iterator) const; 129 130 quickbook::state& state; 131 }; 132 133 struct paragraph_action 134 { 135 // implicit paragraphs 136 // doesn't output the paragraph if it's only whitespace. 137 paragraph_actionquickbook::paragraph_action138 explicit paragraph_action(quickbook::state& state_) : state(state_) {} 139 140 void operator()() const; operator ()quickbook::paragraph_action141 void operator()(parse_iterator, parse_iterator) const { (*this)(); } 142 143 quickbook::state& state; 144 }; 145 146 struct explicit_list_action 147 { 148 // implicit paragraphs 149 // doesn't output the paragraph if it's only whitespace. 150 explicit_list_actionquickbook::explicit_list_action151 explicit explicit_list_action(quickbook::state& state_) : state(state_) 152 { 153 } 154 155 void operator()() const; operator ()quickbook::explicit_list_action156 void operator()(parse_iterator, parse_iterator) const { (*this)(); } 157 158 quickbook::state& state; 159 }; 160 161 struct phrase_end_action 162 { phrase_end_actionquickbook::phrase_end_action163 explicit phrase_end_action(quickbook::state& state_) : state(state_) {} 164 165 void operator()() const; operator ()quickbook::phrase_end_action166 void operator()(parse_iterator, parse_iterator) const { (*this)(); } 167 168 quickbook::state& state; 169 }; 170 171 struct simple_phrase_action 172 { 173 // Handles simple text formats 174 simple_phrase_actionquickbook::simple_phrase_action175 explicit simple_phrase_action(quickbook::state& state_) : state(state_) 176 { 177 } 178 179 void operator()(char) const; 180 181 quickbook::state& state; 182 }; 183 184 struct cond_phrase_push : scoped_action_base 185 { cond_phrase_pushquickbook::cond_phrase_push186 cond_phrase_push(quickbook::state& x) : state(x) {} 187 188 bool start(); 189 void cleanup(); 190 191 quickbook::state& state; 192 bool saved_conditional; 193 std::vector<std::string> anchors; 194 }; 195 196 struct do_macro_action 197 { 198 // Handles macro substitutions 199 do_macro_actionquickbook::do_macro_action200 explicit do_macro_action(quickbook::state& state_) : state(state_) {} 201 202 void operator()(std::string const& str) const; 203 quickbook::state& state; 204 }; 205 206 struct raw_char_action 207 { 208 // Prints a space 209 raw_char_actionquickbook::raw_char_action210 explicit raw_char_action(quickbook::state& state_) : state(state_) {} 211 212 void operator()(char ch) const; 213 void operator()(parse_iterator first, parse_iterator last) const; 214 215 quickbook::state& state; 216 }; 217 218 struct plain_char_action 219 { 220 // Prints a single plain char. 221 // Converts '<' to "<"... etc See utils.hpp 222 plain_char_actionquickbook::plain_char_action223 explicit plain_char_action(quickbook::state& state_) : state(state_) {} 224 225 void operator()(char ch) const; 226 void operator()(parse_iterator first, parse_iterator last) const; 227 228 quickbook::state& state; 229 }; 230 231 struct escape_unicode_action 232 { escape_unicode_actionquickbook::escape_unicode_action233 explicit escape_unicode_action(quickbook::state& state_) : state(state_) 234 { 235 } 236 237 void operator()(parse_iterator first, parse_iterator last) const; 238 239 quickbook::state& state; 240 }; 241 242 struct break_action 243 { break_actionquickbook::break_action244 explicit break_action(quickbook::state& state_) : state(state_) {} 245 246 void operator()(parse_iterator f, parse_iterator) const; 247 248 quickbook::state& state; 249 }; 250 251 struct element_id_warning_action 252 { element_id_warning_actionquickbook::element_id_warning_action253 explicit element_id_warning_action(quickbook::state& state_) 254 : state(state_) 255 { 256 } 257 258 void operator()(parse_iterator first, parse_iterator last) const; 259 260 quickbook::state& state; 261 }; 262 263 // Returns the doc_type, or an empty string if there isn't one. 264 std::string pre( 265 quickbook::state& state, 266 parse_iterator pos, 267 value include_doc_id, 268 bool nested_file); 269 void post(quickbook::state& state, std::string const& doc_type); 270 271 struct to_value_scoped_action : scoped_action_base 272 { to_value_scoped_actionquickbook::to_value_scoped_action273 to_value_scoped_action(quickbook::state& state_) : state(state_) {} 274 275 bool start(value::tag_type = value::default_tag); 276 void success(parse_iterator, parse_iterator); 277 void cleanup(); 278 279 quickbook::state& state; 280 std::vector<std::string> saved_anchors; 281 value::tag_type tag; 282 }; 283 284 // member_action 285 // 286 // Action for calling a member function taking two parse iterators. 287 288 template <typename T> struct member_action 289 { 290 typedef void (T::*member_function)(parse_iterator, parse_iterator); 291 292 T& l; 293 member_function mf; 294 member_actionquickbook::member_action295 explicit member_action(T& l_, member_function mf_) : l(l_), mf(mf_) {} 296 operator ()quickbook::member_action297 void operator()(parse_iterator first, parse_iterator last) const 298 { 299 (l.*mf)(first, last); 300 } 301 }; 302 303 // member_action1 304 // 305 // Action for calling a member function taking two parse iterators and a 306 // value. 307 308 template <typename T, typename Arg1> struct member_action1 309 { 310 typedef void (T::*member_function)( 311 parse_iterator, parse_iterator, Arg1); 312 313 T& l; 314 member_function mf; 315 member_action1quickbook::member_action1316 explicit member_action1(T& l_, member_function mf_) : l(l_), mf(mf_) {} 317 318 struct impl 319 { 320 member_action1 a; 321 Arg1 value; 322 implquickbook::member_action1::impl323 explicit impl(member_action1& a_, Arg1 value_) 324 : a(a_), value(value_) 325 { 326 } 327 operator ()quickbook::member_action1::impl328 void operator()(parse_iterator first, parse_iterator last) const 329 { 330 (a.l.*a.mf)(first, last, value); 331 } 332 }; 333 operator ()quickbook::member_action1334 impl operator()(Arg1 a1) { return impl(*this, a1); } 335 }; 336 337 // member_action_value 338 // 339 // Action for calling a unary member function. 340 341 template <typename T, typename Value> struct member_action_value 342 { 343 typedef void (T::*member_function)(Value); 344 345 T& l; 346 member_function mf; 347 member_action_valuequickbook::member_action_value348 explicit member_action_value(T& l_, member_function mf_) 349 : l(l_), mf(mf_) 350 { 351 } 352 operator ()quickbook::member_action_value353 void operator()(Value v) const { (l.*mf)(v); } 354 }; 355 356 // member_action_value 357 // 358 // Action for calling a unary member function with a fixed value. 359 360 template <typename T, typename Value> struct member_action_fixed_value 361 { 362 typedef void (T::*member_function)(Value); 363 364 T& l; 365 member_function mf; 366 Value v; 367 member_action_fixed_valuequickbook::member_action_fixed_value368 explicit member_action_fixed_value(T& l_, member_function mf_, Value v_) 369 : l(l_), mf(mf_), v(v_) 370 { 371 } 372 operator ()quickbook::member_action_fixed_value373 void operator()() const { (l.*mf)(v); } 374 operator ()quickbook::member_action_fixed_value375 void operator()(parse_iterator, parse_iterator) const { (l.*mf)(v); } 376 }; 377 } 378 379 #endif // BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP 380