| 1 | /*============================================================================= |
|---|
| 2 | Copyright (c) 2002 2004 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_PHRASE_HPP) |
|---|
| 11 | #define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP |
|---|
| 12 | |
|---|
| 13 | #include "detail/utils.hpp" |
|---|
| 14 | #include <boost/spirit/core.hpp> |
|---|
| 15 | #include <boost/spirit/utility/confix.hpp> |
|---|
| 16 | #include <boost/spirit/utility/chset.hpp> |
|---|
| 17 | #include <boost/spirit/actor/assign_actor.hpp> |
|---|
| 18 | #include <boost/spirit/dynamic/if.hpp> |
|---|
| 19 | |
|---|
| 20 | namespace quickbook |
|---|
| 21 | { |
|---|
| 22 | using namespace boost::spirit; |
|---|
| 23 | |
|---|
| 24 | template <typename Rule, typename Action> |
|---|
| 25 | inline void |
|---|
| 26 | simple_markup(Rule& simple, char mark, Action const& action, Rule const& eol) |
|---|
| 27 | { |
|---|
| 28 | simple = |
|---|
| 29 | mark >> |
|---|
| 30 | ( |
|---|
| 31 | ( |
|---|
| 32 | graph_p // A single char. e.g. *c* |
|---|
| 33 | >> eps_p(mark |
|---|
| 34 | >> (space_p | punct_p)) |
|---|
| 35 | ) |
|---|
| 36 | | ( graph_p >> // graph_p must follow mark |
|---|
| 37 | *(anychar_p - |
|---|
| 38 | ( eol // Make sure that we don't go |
|---|
| 39 | | (graph_p >> mark) // past a single line |
|---|
| 40 | ) |
|---|
| 41 | ) >> graph_p // graph_p must precede mark |
|---|
| 42 | >> eps_p(mark |
|---|
| 43 | >> (space_p | punct_p)) // space_p or punct_p must |
|---|
| 44 | ) // follow mark |
|---|
| 45 | ) [action] |
|---|
| 46 | >> mark |
|---|
| 47 | ; |
|---|
| 48 | } |
|---|
| 49 | |
|---|
| 50 | template <typename Actions> |
|---|
| 51 | struct phrase_grammar : grammar<phrase_grammar<Actions> > |
|---|
| 52 | { |
|---|
| 53 | phrase_grammar(Actions& actions, bool& is_not_preformatted) |
|---|
| 54 | : is_not_preformatted(is_not_preformatted), actions(actions) {} |
|---|
| 55 | |
|---|
| 56 | template <typename Scanner> |
|---|
| 57 | struct definition |
|---|
| 58 | { |
|---|
| 59 | definition(phrase_grammar const& self) |
|---|
| 60 | { |
|---|
| 61 | using detail::var; |
|---|
| 62 | Actions& actions = self.actions; |
|---|
| 63 | |
|---|
| 64 | space = |
|---|
| 65 | *(space_p | comment) |
|---|
| 66 | ; |
|---|
| 67 | |
|---|
| 68 | blank = |
|---|
| 69 | *(blank_p | comment) |
|---|
| 70 | ; |
|---|
| 71 | |
|---|
| 72 | eol = blank >> eol_p |
|---|
| 73 | ; |
|---|
| 74 | |
|---|
| 75 | close_bracket = |
|---|
| 76 | ']' | |
|---|
| 77 | if_p(var(self.is_not_preformatted)) |
|---|
| 78 | [ |
|---|
| 79 | eol_p >> eol_p // Make sure that we don't go |
|---|
| 80 | ] // past a single block, except |
|---|
| 81 | ; // when preformatted. |
|---|
| 82 | |
|---|
| 83 | hard_space = |
|---|
| 84 | (eps_p - (alnum_p | '_')) >> space // must not be followed by |
|---|
| 85 | ; // alpha-numeric or underscore |
|---|
| 86 | |
|---|
| 87 | comment = |
|---|
| 88 | "[/" >> *(anychar_p - ']') >> ']' |
|---|
| 89 | ; |
|---|
| 90 | |
|---|
| 91 | common = |
|---|
| 92 | actions.macro [actions.do_macro] |
|---|
| 93 | | phrase_markup |
|---|
| 94 | | code_block |
|---|
| 95 | | inline_code |
|---|
| 96 | | simple_format |
|---|
| 97 | | escape |
|---|
| 98 | | comment |
|---|
| 99 | ; |
|---|
| 100 | |
|---|
| 101 | inline_code = |
|---|
| 102 | '`' >> |
|---|
| 103 | ( |
|---|
| 104 | *(anychar_p - |
|---|
| 105 | ( '`' |
|---|
| 106 | | (eol >> eol) // Make sure that we don't go |
|---|
| 107 | ) // past a single block |
|---|
| 108 | ) >> eps_p('`') |
|---|
| 109 | ) [actions.inline_code] |
|---|
| 110 | >> '`' |
|---|
| 111 | ; |
|---|
| 112 | |
|---|
| 113 | code_block = |
|---|
| 114 | "``" >> |
|---|
| 115 | ( |
|---|
| 116 | *(anychar_p - "``") |
|---|
| 117 | >> eps_p("``") |
|---|
| 118 | ) [actions.code_block] |
|---|
| 119 | >> "``" |
|---|
| 120 | ; |
|---|
| 121 | |
|---|
| 122 | simple_format = |
|---|
| 123 | simple_bold |
|---|
| 124 | | simple_italic |
|---|
| 125 | | simple_underline |
|---|
| 126 | | simple_teletype |
|---|
| 127 | ; |
|---|
| 128 | |
|---|
| 129 | simple_markup(simple_bold, |
|---|
| 130 | '*', actions.simple_bold, eol); |
|---|
| 131 | simple_markup(simple_italic, |
|---|
| 132 | '/', actions.simple_italic, eol); |
|---|
| 133 | simple_markup(simple_underline, |
|---|
| 134 | '_', actions.simple_underline, eol); |
|---|
| 135 | simple_markup(simple_teletype, |
|---|
| 136 | '=', actions.simple_teletype, eol); |
|---|
| 137 | |
|---|
| 138 | phrase = |
|---|
| 139 | *( common |
|---|
| 140 | | comment |
|---|
| 141 | | (anychar_p - |
|---|
| 142 | close_bracket) [actions.plain_char] |
|---|
| 143 | ) |
|---|
| 144 | ; |
|---|
| 145 | |
|---|
| 146 | phrase_markup = |
|---|
| 147 | '[' |
|---|
| 148 | >> ( image |
|---|
| 149 | | url |
|---|
| 150 | | link |
|---|
| 151 | | anchor |
|---|
| 152 | | source_mode |
|---|
| 153 | | funcref |
|---|
| 154 | | classref |
|---|
| 155 | | memberref |
|---|
| 156 | | enumref |
|---|
| 157 | | headerref |
|---|
| 158 | | bold |
|---|
| 159 | | italic |
|---|
| 160 | | underline |
|---|
| 161 | | teletype |
|---|
| 162 | | strikethrough |
|---|
| 163 | | quote |
|---|
| 164 | | replaceable |
|---|
| 165 | | footnote |
|---|
| 166 | | str_p("br") [actions.break_] |
|---|
| 167 | ) |
|---|
| 168 | >> ']' |
|---|
| 169 | ; |
|---|
| 170 | |
|---|
| 171 | escape = |
|---|
| 172 | str_p("\\n") [actions.break_] |
|---|
| 173 | | '\\' >> punct_p [actions.raw_char] |
|---|
| 174 | | ( |
|---|
| 175 | ("'''" >> !eol) [actions.escape_pre] |
|---|
| 176 | >> *(anychar_p - "'''") [actions.raw_char] |
|---|
| 177 | >> str_p("'''") [actions.escape_post] |
|---|
| 178 | ) |
|---|
| 179 | ; |
|---|
| 180 | |
|---|
| 181 | image = |
|---|
| 182 | '$' >> blank |
|---|
| 183 | >> (*(anychar_p - |
|---|
| 184 | close_bracket)) [actions.image] |
|---|
| 185 | ; |
|---|
| 186 | |
|---|
| 187 | url = |
|---|
| 188 | '@' |
|---|
| 189 | >> (*(anychar_p - |
|---|
| 190 | (']' | hard_space))) [actions.url_pre] |
|---|
| 191 | >> ( eps_p(']') |
|---|
| 192 | | (hard_space >> phrase) |
|---|
| 193 | ) [actions.url_post] |
|---|
| 194 | ; |
|---|
| 195 | |
|---|
| 196 | link = |
|---|
| 197 | "link" >> hard_space |
|---|
| 198 | >> (*(anychar_p - |
|---|
| 199 | (']' | hard_space))) [actions.link_pre] |
|---|
| 200 | >> ( eps_p(']') |
|---|
| 201 | | (hard_space >> phrase) |
|---|
| 202 | ) [actions.link_post] |
|---|
| 203 | ; |
|---|
| 204 | |
|---|
| 205 | anchor = |
|---|
| 206 | '#' |
|---|
| 207 | >> blank |
|---|
| 208 | >> ( *(anychar_p - |
|---|
| 209 | close_bracket) |
|---|
| 210 | ) [actions.anchor] |
|---|
| 211 | ; |
|---|
| 212 | |
|---|
| 213 | funcref = |
|---|
| 214 | "funcref" >> hard_space |
|---|
| 215 | >> (*(anychar_p - |
|---|
| 216 | (']' | hard_space))) [actions.funcref_pre] |
|---|
| 217 | >> ( eps_p(']') |
|---|
| 218 | | (hard_space >> phrase) |
|---|
| 219 | ) [actions.funcref_post] |
|---|
| 220 | ; |
|---|
| 221 | |
|---|
| 222 | classref = |
|---|
| 223 | "classref" >> hard_space |
|---|
| 224 | >> (*(anychar_p - |
|---|
| 225 | (']' | hard_space))) [actions.classref_pre] |
|---|
| 226 | >> ( eps_p(']') |
|---|
| 227 | | (hard_space >> phrase) |
|---|
| 228 | ) [actions.classref_post] |
|---|
| 229 | ; |
|---|
| 230 | |
|---|
| 231 | memberref = |
|---|
| 232 | "memberref" >> hard_space |
|---|
| 233 | >> (*(anychar_p - |
|---|
| 234 | (']' | hard_space))) [actions.memberref_pre] |
|---|
| 235 | >> ( eps_p(']') |
|---|
| 236 | | (hard_space >> phrase) |
|---|
| 237 | ) [actions.memberref_post] |
|---|
| 238 | ; |
|---|
| 239 | |
|---|
| 240 | enumref = |
|---|
| 241 | "enumref" >> hard_space |
|---|
| 242 | >> (*(anychar_p - |
|---|
| 243 | (']' | hard_space))) [actions.enumref_pre] |
|---|
| 244 | >> ( eps_p(']') |
|---|
| 245 | | (hard_space >> phrase) |
|---|
| 246 | ) [actions.enumref_post] |
|---|
| 247 | ; |
|---|
| 248 | |
|---|
| 249 | headerref = |
|---|
| 250 | "headerref" >> hard_space |
|---|
| 251 | >> (*(anychar_p - |
|---|
| 252 | (']' | hard_space))) [actions.headerref_pre] |
|---|
| 253 | >> ( eps_p(']') |
|---|
| 254 | | (hard_space >> phrase) |
|---|
| 255 | ) [actions.headerref_post] |
|---|
| 256 | ; |
|---|
| 257 | |
|---|
| 258 | bold = |
|---|
| 259 | ch_p('*') [actions.bold_pre] |
|---|
| 260 | >> blank >> phrase [actions.bold_post] |
|---|
| 261 | ; |
|---|
| 262 | |
|---|
| 263 | italic = |
|---|
| 264 | ch_p('\'') [actions.italic_pre] |
|---|
| 265 | >> blank >> phrase [actions.italic_post] |
|---|
| 266 | ; |
|---|
| 267 | |
|---|
| 268 | underline = |
|---|
| 269 | ch_p('_') [actions.underline_pre] |
|---|
| 270 | >> blank >> phrase [actions.underline_post] |
|---|
| 271 | ; |
|---|
| 272 | |
|---|
| 273 | teletype = |
|---|
| 274 | ch_p('^') [actions.teletype_pre] |
|---|
| 275 | >> blank >> phrase [actions.teletype_post] |
|---|
| 276 | ; |
|---|
| 277 | |
|---|
| 278 | strikethrough = |
|---|
| 279 | ch_p('-') [actions.strikethrough_pre] |
|---|
| 280 | >> blank >> phrase [actions.strikethrough_post] |
|---|
| 281 | ; |
|---|
| 282 | |
|---|
| 283 | quote = |
|---|
| 284 | ch_p('"') [actions.quote_pre] |
|---|
| 285 | >> blank >> phrase [actions.quote_post] |
|---|
| 286 | ; |
|---|
| 287 | |
|---|
| 288 | replaceable = |
|---|
| 289 | ch_p('~') [actions.replaceable_pre] |
|---|
| 290 | >> blank >> phrase [actions.replaceable_post] |
|---|
| 291 | ; |
|---|
| 292 | |
|---|
| 293 | source_mode = |
|---|
| 294 | ( |
|---|
| 295 | str_p("c++") |
|---|
| 296 | | "python" |
|---|
| 297 | ) [assign_a(actions.source_mode)] |
|---|
| 298 | ; |
|---|
| 299 | |
|---|
| 300 | footnote = |
|---|
| 301 | str_p("footnote") [actions.footnote_pre] |
|---|
| 302 | >> blank >> phrase [actions.footnote_post] |
|---|
| 303 | ; |
|---|
| 304 | } |
|---|
| 305 | |
|---|
| 306 | rule<Scanner> space, blank, comment, phrase, phrase_markup, image, |
|---|
| 307 | close_bracket, bold, italic, underline, teletype, |
|---|
| 308 | strikethrough, escape, url, common, funcref, |
|---|
| 309 | classref, memberref, enumref, headerref, anchor, |
|---|
| 310 | link, hard_space, eol, inline_code, simple_format, |
|---|
| 311 | simple_bold, simple_italic, simple_underline, |
|---|
| 312 | simple_teletype, source_mode, |
|---|
| 313 | quote, code_block, footnote, replaceable; |
|---|
| 314 | |
|---|
| 315 | rule<Scanner> const& |
|---|
| 316 | start() const { return common; } |
|---|
| 317 | }; |
|---|
| 318 | |
|---|
| 319 | bool& is_not_preformatted; |
|---|
| 320 | Actions& actions; |
|---|
| 321 | }; |
|---|
| 322 | } |
|---|
| 323 | |
|---|
| 324 | #endif // BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP |
|---|
| 325 | |
|---|