1 /*============================================================================= 2 Copyright (c) 2002 2004 2006Joel 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 11 #include "utils.hpp" 12 #include "state.hpp" 13 #include "actions.hpp" 14 #include "grammar_impl.hpp" 15 #include "block_tags.hpp" 16 #include "template_tags.hpp" 17 #include <boost/spirit/include/classic_assign_actor.hpp> 18 #include <boost/spirit/include/classic_if.hpp> 19 #include <boost/spirit/include/classic_clear_actor.hpp> 20 #include <boost/spirit/include/phoenix1_primitives.hpp> 21 #include <boost/spirit/include/phoenix1_casts.hpp> 22 23 namespace quickbook 24 { 25 namespace cl = boost::spirit::classic; 26 namespace ph = phoenix; 27 28 struct block_element_grammar_local 29 { 30 cl::rule<scanner> 31 heading, inner_block, inner_phrase, def_macro, 32 table, table_title, table_row, variablelist, 33 varlistentry, varlistterm, list, cell, 34 preformatted, begin_section, end_section, 35 xinclude, include, include_filename, 36 template_, template_id, template_formal_arg, 37 template_body, identifier, import, 38 element_id, 39 same_line; 40 }; 41 init_block_elements()42 void quickbook_grammar::impl::init_block_elements() 43 { 44 block_element_grammar_local& local = cleanup_.add( 45 new block_element_grammar_local); 46 47 // Actions 48 error_action error(state); 49 element_id_warning_action element_id_warning(state); 50 raw_char_action raw_char(state); 51 explicit_list_action explicit_list(state); 52 scoped_parser<to_value_scoped_action> to_value(state); 53 54 local.element_id = 55 !( ':' 56 >> ( qbk_ver(107u) 57 >> to_value(general_tags::element_id) [attribute_value_1_7] 58 | qbk_ver(0, 107u) 59 >> !(qbk_ver(105u) >> space) 60 >> (+(cl::alnum_p | '_')) [state.values.entry(ph::arg1, ph::arg2, general_tags::element_id)] 61 | cl::eps_p [element_id_warning] 62 ) 63 ) 64 ; 65 66 elements.add 67 ("section", element_info(element_info::section_block, &local.begin_section, block_tags::begin_section)) 68 ("endsect", element_info(element_info::section_block, &local.end_section, block_tags::end_section)) 69 ; 70 71 local.begin_section = 72 space 73 >> local.element_id 74 >> space 75 >> local.inner_phrase 76 ; 77 78 local.end_section = 79 cl::eps_p 80 ; 81 82 local.heading 83 = space 84 >> !(qbk_ver(106u) >> local.element_id) 85 >> space 86 >> local.inner_phrase 87 ; 88 89 elements.add 90 ("heading", element_info(element_info::conditional_or_block, &local.heading, block_tags::generic_heading)) 91 ("h1", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading1)) 92 ("h2", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading2)) 93 ("h3", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading3)) 94 ("h4", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading4)) 95 ("h5", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading5)) 96 ("h6", element_info(element_info::conditional_or_block, &local.heading, block_tags::heading6)) 97 ; 98 99 elements.add 100 ("blurb", element_info(element_info::nested_block, &local.inner_block, block_tags::blurb)) 101 (":", element_info(element_info::nested_block, &local.inner_block, block_tags::blockquote)) 102 ("warning", element_info(element_info::nested_block, &local.inner_block, block_tags::warning)) 103 ("caution", element_info(element_info::nested_block, &local.inner_block, block_tags::caution)) 104 ("important", element_info(element_info::nested_block, &local.inner_block, block_tags::important)) 105 ("note", element_info(element_info::nested_block, &local.inner_block, block_tags::note)) 106 ("tip", element_info(element_info::nested_block, &local.inner_block, block_tags::tip)) 107 ; 108 109 elements.add 110 ("block", element_info(element_info::nested_block, &local.inner_phrase, block_tags::block, 106u)) 111 ; 112 113 elements.add 114 ("pre", element_info(element_info::nested_block, &local.preformatted, block_tags::preformatted)) 115 ; 116 117 local.preformatted = 118 ( qbk_ver(0, 106) >> space 119 | qbk_ver(106) >> blank >> !eol 120 ) 121 >> to_value() 122 [ 123 inside_preformatted 124 ] 125 ; 126 127 elements.add 128 ("def", element_info(element_info::conditional_or_block, &local.def_macro, block_tags::macro_definition)) 129 ; 130 131 local.def_macro = 132 space 133 >> macro_identifier [state.values.entry(ph::arg1, ph::arg2)] 134 >> blank 135 >> local.inner_phrase 136 ; 137 138 local.identifier = 139 (cl::alpha_p | '_') >> *(cl::alnum_p | '_') 140 ; 141 142 local.template_id = 143 local.identifier | (cl::punct_p - (cl::ch_p('[') | ']')) 144 ; 145 146 elements.add 147 ("template", element_info(element_info::conditional_or_block, &local.template_, block_tags::template_definition)) 148 ; 149 150 local.template_ = 151 space 152 >> local.template_id [state.values.entry(ph::arg1, ph::arg2)] 153 >> state.values.list()[ 154 !( 155 space >> '[' 156 >> *( 157 space 158 >> local.template_id [state.values.entry(ph::arg1, ph::arg2)] 159 ) 160 >> space >> ']' 161 ) 162 ] 163 >> ( cl::eps_p(*cl::blank_p >> cl::eol_p) 164 >> local.template_body [state.values.entry(ph::arg1, ph::arg2, template_tags::block)] 165 | local.template_body [state.values.entry(ph::arg1, ph::arg2, template_tags::phrase)] 166 ) 167 ; 168 169 local.template_body = 170 qbk_ver(106u) 171 >> *(~cl::eps_p(']') >> skip_entity) 172 | qbk_ver(0,106u) 173 >> *(('[' >> local.template_body >> ']') | (cl::anychar_p - ']')) 174 >> cl::eps_p(space >> ']') 175 >> space 176 ; 177 178 elements.add 179 ("variablelist", element_info(element_info::nested_block, &local.variablelist, block_tags::variable_list)) 180 ; 181 182 local.variablelist = 183 (cl::eps_p(*cl::blank_p >> cl::eol_p) | space) 184 >> local.table_title 185 >> *local.varlistentry 186 ; 187 188 local.varlistentry = 189 space 190 >> cl::ch_p('[') 191 >> state.values.list() 192 [ 193 ( 194 local.varlistterm 195 >> ( +local.cell 196 | cl::eps_p [error] 197 ) 198 >> cl::ch_p(']') 199 >> space 200 ) 201 | cl::eps_p [error] 202 ] 203 ; 204 205 local.varlistterm = 206 space 207 >> cl::ch_p('[') 208 >> local.inner_phrase 209 >> ( cl::ch_p(']') 210 >> space 211 | cl::eps_p [error] 212 ) 213 ; 214 215 elements.add 216 ("table", element_info(element_info::nested_block, &local.table, block_tags::table)) 217 ; 218 219 local.same_line = *cl::blank_p >> !(comment >> space); 220 221 local.table = 222 local.same_line 223 >> !(qbk_ver(105u) >> local.element_id) 224 >> local.same_line 225 >> local.table_title 226 >> *local.table_row 227 ; 228 229 local.table_row = 230 space 231 >> cl::ch_p('[') 232 >> 233 ( 234 ( 235 state.values.list(table_tags::row) 236 [ *local.cell 237 ] 238 >> cl::ch_p(']') 239 >> space 240 ) 241 | cl::eps_p [error] 242 ) 243 ; 244 245 local.table_title = 246 qbk_ver(0, 106) 247 >> (*(cl::anychar_p - eol)) [state.values.entry(ph::arg1, ph::arg2, table_tags::title)] 248 >> (+eol) 249 | qbk_ver(106) 250 >> to_value(table_tags::title) 251 [ 252 table_title_phrase 253 ] 254 >> space 255 ; 256 257 elements.add 258 ("ordered_list", element_info(element_info::nested_block, &local.list, block_tags::ordered_list, 106)) 259 ("itemized_list", element_info(element_info::nested_block, &local.list, block_tags::itemized_list, 106)) 260 ; 261 262 local.list = 263 *( cl::eps_p [explicit_list] 264 >> local.cell 265 ) 266 ; 267 268 local.cell = 269 space 270 >> cl::ch_p('[') 271 >> ( local.inner_block 272 >> cl::ch_p(']') 273 >> space 274 | cl::eps_p [error] 275 ) 276 ; 277 278 elements.add 279 ("xinclude", element_info(element_info::conditional_or_block, &local.xinclude, block_tags::xinclude)) 280 ("import", element_info(element_info::conditional_or_block, &local.import, block_tags::import)) 281 ("include", element_info(element_info::conditional_or_block, &local.include, block_tags::include)) 282 ; 283 284 local.xinclude = 285 space 286 >> local.include_filename 287 ; 288 289 local.import = 290 space 291 >> local.include_filename 292 ; 293 294 local.include = 295 space 296 >> 297 !( 298 ':' 299 >> (*((cl::alnum_p | '_') - cl::space_p)) 300 [state.values.entry(ph::arg1, ph::arg2, general_tags::include_id)] 301 >> space 302 ) 303 >> local.include_filename 304 ; 305 306 local.include_filename = 307 qbk_ver(0, 106u) 308 >> (*(cl::anychar_p - phrase_end)) [state.values.entry(ph::arg1, ph::arg2)] 309 | qbk_ver(106u, 107u) 310 >> to_value() 311 [ *( raw_escape 312 | (cl::anychar_p - phrase_end) 313 [raw_char] 314 ) 315 ] 316 | qbk_ver(107u) 317 >> to_value() [ attribute_value_1_7 ] 318 ; 319 320 local.inner_block = 321 to_value() 322 [ 323 inside_paragraph 324 ] 325 ; 326 327 local.inner_phrase = 328 to_value() 329 [ 330 paragraph_phrase 331 ] 332 ; 333 } 334 } 335