Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/quickbook/quickbook.hpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 18 years ago

added boost

  • Property svn:executable set to *
File size: 22.3 KB
Line 
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_HPP)
11#define BOOST_SPIRIT_QUICKBOOK_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
20namespace quickbook
21{
22    using namespace boost::spirit;
23
24    template <typename Actions>
25    struct quickbook_grammar
26    : public grammar<quickbook_grammar<Actions> >
27    {
28        quickbook_grammar(Actions& actions_)
29        : actions(actions_) {}
30
31        template <typename Scanner>
32        struct definition
33        {
34            definition(quickbook_grammar const& self)
35                : is_not_preformatted(true)
36            {
37                using detail::var;
38
39                library =
40                    *(space_p | comment) >> blocks >> blank
41                    ;
42
43                blocks =
44                   +(   block_markup
45                    |   code
46                    |   list                            [self.actions.list]
47                    |   hr                              [self.actions.hr]
48                    |   comment >> *eol
49                    |   paragraph                       [self.actions.paragraph]
50                    |   eol
51                    )
52                    ;
53
54                space =
55                    *(space_p | comment)
56                    ;
57
58                blank =
59                    *(blank_p | comment)
60                    ;
61
62                eol = blank >> eol_p
63                    ;
64
65                close_bracket =
66                    ']' |
67                    if_p(var(is_not_preformatted))
68                    [
69                        eol_p >> eol_p                  // Make sure that we don't go
70                    ]                                   // past a single block, except
71                    ;                                   // when preformatted.
72
73                hard_space =
74                    (eps_p - (alnum_p | '_')) >> space  // must not be followed by
75                    ;                                   // alpha-numeric or underscore
76
77                comment =
78                    "[/" >> *(anychar_p - ']') >> ']'
79                    ;
80
81                hr =
82                    str_p("----")
83                    >> *(anychar_p - eol)
84                    >> +eol
85                    ;
86
87                block_markup =
88                        '['
89                    >>  (   begin_section
90                        |   end_section
91                        |   headings
92                        |   blurb
93                        |   blockquote
94                        |   preformatted
95                        |   def_macro
96                        |   table
97                        |   variablelist
98                        |   xinclude
99                        )
100                    >>  (   (']' >> +eol)
101                        |   eps_p                       [self.actions.error]
102                        )
103                    ;
104
105                begin_section =
106                       "section"
107                    >> hard_space
108                    >>  (':' >> (*(alnum_p | '_'))      [assign_a(self.actions.section_id)]
109                        | eps_p                         [assign_a(self.actions.section_id)]
110                        )
111                    >> (*(anychar_p -
112                            close_bracket))             [self.actions.begin_section]
113                    ;
114
115                end_section =
116                    str_p("endsect")                    [self.actions.end_section]
117                    ;
118
119                headings =
120                    h1 | h2 | h3 | h4 | h5 | h6
121                    ;
122
123                h1 = "h1" >> hard_space >> phrase       [self.actions.h1];
124                h2 = "h2" >> hard_space >> phrase       [self.actions.h2];
125                h3 = "h3" >> hard_space >> phrase       [self.actions.h3];
126                h4 = "h4" >> hard_space >> phrase       [self.actions.h4];
127                h5 = "h5" >> hard_space >> phrase       [self.actions.h5];
128                h6 = "h6" >> hard_space >> phrase       [self.actions.h6];
129
130                blurb =
131                    "blurb" >> hard_space
132                    >> phrase                           [self.actions.blurb]
133                    ;
134
135                blockquote =
136                    ':' >> blank >>
137                    phrase                              [self.actions.blockquote]
138                    ;
139
140                preformatted =
141                    "pre" >> hard_space                 [assign_a(is_not_preformatted, false)]
142                    >> !eol >> phrase                   [self.actions.preformatted]
143                    >> eps_p                            [assign_a(is_not_preformatted, true)]
144                    ;
145
146                def_macro =
147                    "def" >> hard_space
148                    >> identifier                       [self.actions.identifier]
149                    >> blank >> phrase                  [self.actions.macro_def]
150                    ;
151
152                variablelist =
153                    "variablelist" >> hard_space
154                    >>  (*(anychar_p - eol))            [assign_a(self.actions.table_title)]
155                    >>  +eol
156                    >>  *varlistentry
157                    >>  eps_p                           [self.actions.variablelist]
158                    ;
159
160                varlistentry =
161                    space
162                    >>  ch_p('[')                       [self.actions.start_varlistentry]
163                    >>
164                    (
165                        (
166                            varlistterm
167                            >> +varlistitem
168                            >>  ch_p(']')               [self.actions.end_varlistentry]
169                            >>  space
170                        )
171                        | eps_p                         [self.actions.error]
172                    )
173                    ;
174
175                varlistterm =
176                    space
177                    >>  ch_p('[')                       [self.actions.start_varlistterm]
178                    >>
179                    (
180                        (
181                            phrase
182                            >>  ch_p(']')               [self.actions.end_varlistterm]
183                            >>  space
184                        )
185                        | eps_p                         [self.actions.error]
186                    )
187                    ;
188
189                varlistitem =
190                    space
191                    >>  ch_p('[')                       [self.actions.start_varlistitem]
192                    >>
193                    (
194                        (
195                            phrase                      [self.actions.end_varlistitem]
196                            >>  ch_p(']')
197                            >>  space
198                        )
199                        | eps_p                         [self.actions.error]
200                    )
201                    ;
202
203                table =
204                    "table" >> hard_space
205                    >>  (*(anychar_p - eol))            [assign_a(self.actions.table_title)]
206                    >>  +eol
207                    >>  *table_row
208                    >>  eps_p                           [self.actions.table]
209                    ;
210
211                table_row =
212                    space
213                    >>  ch_p('[')                       [self.actions.start_row]
214                    >>
215                    (
216                        (
217                            *table_cell
218                            >>  ch_p(']')               [self.actions.end_row]
219                            >>  space
220                        )
221                        | eps_p                         [self.actions.error]
222                    )
223                    ;
224
225                table_cell =
226                    space
227                    >>  ch_p('[')                       [self.actions.start_cell]
228                    >>
229                    (
230                        (
231                            phrase
232                            >>  ch_p(']')               [self.actions.end_cell]
233                            >>  space
234                        )
235                        | eps_p                         [self.actions.error]
236                    )
237                    ;
238
239                xinclude =
240                       "xinclude"
241                    >> hard_space
242                    >> (*(anychar_p -
243                            close_bracket))             [self.actions.xinclude]
244                    ;
245
246                identifier =
247                    *(anychar_p - (space_p | ']'))
248                    ;
249
250                source_mode =
251                    (
252                        str_p("c++")
253                    |   "python"
254                    )                                   [assign_a(self.actions.source_mode)]
255                    ;
256               
257                code =
258                    (
259                        code_line
260                        >> *(*eol >> code_line)
261                    )                                   [self.actions.code]
262                    >> +eol
263                    ;
264
265                code_line =
266                    ((ch_p(' ') | '\t'))
267                    >> *(anychar_p - eol) >> eol
268                    ;
269
270                list =
271                    eps_p(ch_p('*') | '#') >>
272                   +(
273                        (*blank_p
274                        >> (ch_p('*') | '#'))           [self.actions.list_format]
275                        >> *blank_p
276                        >> list_item
277                    )                                   [self.actions.list_item]
278                    ;
279
280                list_item =
281                   *(   common
282                    |   (anychar_p -
283                            (   eol_p >> *blank_p >> eps_p(ch_p('*') | '#')
284                            |   (eol >> eol)
285                            )
286                        )                               [self.actions.plain_char]
287                    )
288                    >> +eol
289                    ;
290
291                common =
292                        self.actions.macro              [self.actions.do_macro]
293                    |   phrase_markup
294                    |   inline_code
295                    |   simple_format
296                    |   escape
297                    |   comment
298                    ;
299
300                inline_code =
301                    '`' >>
302                    (
303                       *(anychar_p -
304                            (   '`'
305                            |   (eol >> eol)            // Make sure that we don't go
306                            )                           // past a single block
307                        ) >> eps_p('`')
308                    )                                   [self.actions.inline_code]
309                    >>  '`'
310                    ;
311
312                simple_format =
313                        simple_bold
314                    |   simple_italic
315                    |   simple_underline
316                    |   simple_teletype
317                    ;
318
319                simple_bold =
320                    '*' >>
321                    (
322                        (   graph_p >>                  // graph_p must follow '*'
323                            *(anychar_p -
324                                (   eol                 // Make sure that we don't go
325                                |   (graph_p >> '*')    // past a single line
326                                )
327                            ) >> graph_p                // graph_p must precede '*'
328                            >> eps_p('*'
329                                >> (space_p | punct_p)) // space_p or punct_p must
330                        )                               // follow '*'
331                    |   (
332                            graph_p                     // A single char. e.g. *c*
333                            >> eps_p('*'
334                                >> (space_p | punct_p))
335                        )
336                    )                                   [self.actions.simple_bold]
337                    >> '*'
338                    ;
339
340                simple_italic =
341                    '/' >>
342                    (
343                        (   graph_p >>                  // graph_p must follow '/'
344                            *(anychar_p -
345                                (   eol                 // Make sure that we don't go
346                                |   (graph_p >> '/')    // past a single line
347                                )
348                            ) >> graph_p                // graph_p must precede '/'
349                            >> eps_p('/'
350                                >> (space_p | punct_p)) // space_p or punct_p must
351                        )                               // follow '/'
352                    |   (
353                            graph_p                     // A single char. e.g. /c/
354                            >> eps_p('/'
355                                >> (space_p | punct_p))
356                        )
357                    )                                   [self.actions.simple_italic]
358                    >> '/'
359                    ;
360
361                simple_underline =
362                    '_' >>
363                    (
364                        (   graph_p >>                  // graph_p must follow '_'
365                            *(anychar_p -
366                                (   eol                 // Make sure that we don't go
367                                |   (graph_p >> '_')    // past a single line
368                                )
369                            ) >> graph_p                // graph_p must precede '_'
370                            >> eps_p('_'
371                                >> (space_p | punct_p)) // space_p or punct_p must
372                        )                               // follow '_'
373                    |   (
374                            graph_p                     // A single char. e.g. _c_
375                            >> eps_p('_'
376                                >> (space_p | punct_p))
377                        )
378                    )                                   [self.actions.simple_underline]
379                    >> '_'
380                    ;
381
382                simple_teletype =
383                    '=' >>
384                    (
385                        (   graph_p >>                  // graph_p must follow '='
386                            *(anychar_p -
387                                (   eol                 // Make sure that we don't go
388                                |   (graph_p >> '=')    // past a single line
389                                )
390                            ) >> graph_p                // graph_p must precede '='
391                            >> eps_p('='
392                                >> (space_p | punct_p)) // space_p or punct_p must
393                        )                               // follow '='
394                    |   (
395                            graph_p                     // A single char. e.g. =c=
396                            >> eps_p('='
397                                >> (space_p | punct_p))
398                        )
399                    )                                   [self.actions.simple_teletype]
400                    >> '='
401                    ;
402
403                paragraph =
404                   *(   common
405                    |   (anychar_p -                    // Make sure we don't go past
406                            (eol >> eol)                // a single block.
407                        )                               [self.actions.plain_char]
408                    )
409                    >> +eol
410                    ;
411
412                phrase =
413                   *(   common
414                    |   comment
415                    |   (anychar_p -
416                            close_bracket)              [self.actions.plain_char]
417                    )
418                    ;
419
420                phrase_markup =
421                        '['
422                    >>  (   image
423                        |   url
424                        |   link
425                        |   anchor
426                        |   source_mode   
427                        |   funcref
428                        |   classref
429                        |   memberref
430                        |   enumref
431                        |   headerref
432                        |   bold
433                        |   italic
434                        |   underline
435                        |   teletype
436                        |   str_p("br")                 [self.actions.break_]
437                        )
438                    >>  ']'
439                    ;
440
441                escape =
442                        str_p("\\n")                    [self.actions.break_]
443                    |   '\\' >> punct_p                 [self.actions.raw_char]
444                    |   (
445                            "'''" >> !eol
446                        >>  *(anychar_p - "'''")        [self.actions.raw_char]
447                        >>  "'''"
448                        )
449                    ;
450
451                image =
452                        '$' >> blank
453                    >> (*(anychar_p -
454                            close_bracket))             [self.actions.image]
455                    ;
456
457                url =
458                        '@'
459                    >>  (*(anychar_p -
460                            (']' | hard_space)))        [self.actions.url_pre]
461                    >>  (   eps_p(']')
462                        |   (hard_space >> phrase)
463                        )                               [self.actions.url_post]
464                    ;
465
466                link =
467                        "link" >> hard_space
468                    >>  (*(anychar_p -
469                            (']' | hard_space)))        [self.actions.link_pre]
470                    >>  (   eps_p(']')
471                        |   (hard_space >> phrase)
472                        )                               [self.actions.link_post]
473                    ;
474
475                anchor =
476                        '#'
477                    >>  blank
478                    >>  (   *(anychar_p -
479                                close_bracket)
480                        )                               [self.actions.anchor]
481                    ;
482
483                funcref =
484                    "funcref" >> hard_space
485                    >>  (*(anychar_p -
486                            (']' | hard_space)))        [self.actions.funcref_pre]
487                    >>  (   eps_p(']')
488                        |   (hard_space >> phrase)
489                        )                               [self.actions.funcref_post]
490                    ;
491
492                classref =
493                    "classref" >> hard_space
494                    >>  (*(anychar_p -
495                            (']' | hard_space)))        [self.actions.classref_pre]
496                    >>  (   eps_p(']')
497                        |   (hard_space >> phrase)
498                        )                               [self.actions.classref_post]
499                    ;
500
501                memberref =
502                    "memberref" >> hard_space
503                    >>  (*(anychar_p -
504                            (']' | hard_space)))        [self.actions.memberref_pre]
505                    >>  (   eps_p(']')
506                        |   (hard_space >> phrase)
507                        )                               [self.actions.memberref_post]
508                    ;
509
510                enumref =
511                    "enumref" >> hard_space
512                    >>  (*(anychar_p -
513                            (']' | hard_space)))        [self.actions.enumref_pre]
514                    >>  (   eps_p(']')
515                        |   (hard_space >> phrase)
516                        )                               [self.actions.enumref_post]
517                    ;
518
519                headerref =
520                    "headerref" >> hard_space
521                    >>  (*(anychar_p -
522                            (']' | hard_space)))        [self.actions.headerref_pre]
523                    >>  (   eps_p(']')
524                        |   (hard_space >> phrase)
525                        )                               [self.actions.headerref_post]
526                    ;
527
528                bold =
529                        ch_p('*')                       [self.actions.bold_pre]
530                    >>  blank >> phrase                 [self.actions.bold_post]
531                    ;
532
533                italic =
534                        ch_p('\'')                      [self.actions.italic_pre]
535                    >>  blank >> phrase                 [self.actions.italic_post]
536                    ;
537
538                underline =
539                        ch_p('_')                       [self.actions.underline_pre]
540                    >>  blank >> phrase                 [self.actions.underline_post]
541                    ;
542
543                teletype =
544                        ch_p('^')                       [self.actions.teletype_pre]
545                    >>  blank >> phrase                 [self.actions.teletype_post]
546                    ;
547            }
548
549            bool is_not_preformatted;
550           
551            rule<Scanner>   library, blocks, lib_info, block_markup, source_mode, code,
552                            code_line, paragraph, space, blank, comment, headings,
553                            h1, h2, h3, h4, h5, h6, hr, blurb, blockquote,
554                            phrase, phrase_markup, image, list, close_bracket,
555                            ordered_list, bold, italic, underline, teletype,
556                            escape, def_macro, identifier, url, table, table_row,
557                            variablelist, varlistentry, varlistterm, varlistitem,
558                            table_cell, preformatted, list_item, common,
559                            funcref, classref, memberref, enumref, headerref, anchor, link,
560                            begin_section, end_section, xinclude, hard_space, eol,
561                            inline_code, simple_format, simple_bold, simple_italic,
562                            simple_underline, simple_teletype;
563
564            rule<Scanner> const&
565            start() const { return library; }
566        };
567
568        Actions&   actions;
569    };
570}
571
572#endif // BOOST_SPIRIT_QUICKBOOK_HPP
573
Note: See TracBrowser for help on using the repository browser.