$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r59550 - branches/quickbook-1.5-spirit2
From: daniel_james_at_[hidden]
Date: 2010-02-07 04:06:46
Author: danieljames
Date: 2010-02-07 04:06:44 EST (Sun, 07 Feb 2010)
New Revision: 59550
URL: http://svn.boost.org/trac/boost/changeset/59550
Log:
Reorder the rules within the block and phrase grammars.
I think this order makes sense, I'm not sure if anyone else would agree.
Text files modified: 
   branches/quickbook-1.5-spirit2/block.cpp  |   400 +++++++++++++++++++-------------------- 
   branches/quickbook-1.5-spirit2/phrase.cpp |   346 +++++++++++++++++-----------------      
   2 files changed, 370 insertions(+), 376 deletions(-)
Modified: branches/quickbook-1.5-spirit2/block.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/block.cpp	(original)
+++ branches/quickbook-1.5-spirit2/block.cpp	2010-02-07 04:06:44 EST (Sun, 07 Feb 2010)
@@ -122,66 +122,54 @@
         quickbook::actions& actions;
         bool no_eols;
         phrase_grammar common;
-        qi::rule<iterator>
-                        start_, blocks, block_markup, space, blank, comment,
-                        phrase_end, hard_space, eol, paragraph_end, dummy_block;
-
-        qi::symbols<> paragraph_end_markups;
-        qi::rule<iterator, quickbook::paragraph()> paragraph;
-        qi::rule<iterator, std::string()> paragraph_content;
-
-        qi::rule<iterator, quickbook::list()> list;
-        qi::rule<iterator, quickbook::list_item()> list_item;
-        qi::rule<iterator, std::string()> list_item_content;
         
-        qi::rule<iterator, quickbook::hr()> hr;
-
-        qi::rule<iterator, boost::optional<std::string>()> element_id, element_id_1_5;
-        qi::rule<iterator, std::string()> element_id_part;
-
+        qi::rule<iterator> start_, blocks, block_markup;
         qi::rule<iterator, quickbook::begin_section()> begin_section;
         qi::rule<iterator, quickbook::end_section()> end_section;
-
-        qi::symbols<char, int> heading_symbol;
         qi::rule<iterator, quickbook::heading()> heading;
-        
-        qi::rule<iterator, std::string()> inside_paragraph;
-        qi::rule<iterator, quickbook::formatted()> inside_paragraph2;
-        
-        qi::symbols<char, quickbook::markup> paragraph_blocks;
+        qi::symbols<char, int> heading_symbol;
         qi::rule<iterator, quickbook::formatted()> paragraph_block, blockquote, preformatted;
-
-        qi::rule<iterator, std::string()> macro_identifier;
+        qi::symbols<char, quickbook::markup> paragraph_blocks;
         qi::rule<iterator, quickbook::def_macro()> def_macro;
-
-        qi::rule<iterator, quickbook::define_template()> define_template;
-        qi::rule<iterator, std::string()> identifier;
-        qi::rule<iterator, std::string()> punctuation_identifier;
-        qi::rule<iterator, std::string()> template_id;
-        qi::rule<iterator, std::string()> template_body;
-        qi::rule<iterator> template_body_recurse;
-
+        qi::rule<iterator, quickbook::table()> table;
+        qi::rule<iterator, quickbook::table_row()> table_row;
+        qi::rule<iterator, quickbook::table_cell()> table_cell;
+        qi::rule<iterator, quickbook::formatted()> table_cell_body;        
         qi::rule<iterator, quickbook::variablelist()> variablelist;
         qi::rule<iterator, quickbook::varlistentry()> varlistentry;
         qi::rule<iterator, quickbook::formatted()>
             varlistterm, varlistterm_body,
             varlistitem, varlistitem_body;
-
-        qi::rule<iterator, quickbook::table()> table;
-        qi::rule<iterator, quickbook::table_row()> table_row;
-        qi::rule<iterator, quickbook::table_cell()> table_cell;
-        qi::rule<iterator, quickbook::formatted()> table_cell_body;
-        
-        qi::rule<iterator, quickbook::code()> code;
-        qi::rule<iterator> code_line;
-
         qi::rule<iterator, quickbook::xinclude()> xinclude;
         qi::rule<iterator, quickbook::include()> include;
         qi::rule<iterator, quickbook::import()> import;
-        
+        qi::rule<iterator, quickbook::define_template()> define_template;
+        qi::rule<iterator, std::string()> template_body;
+        qi::rule<iterator> template_body_recurse;
+        qi::rule<iterator, quickbook::code()> code;
+        qi::rule<iterator> code_line;
+        qi::rule<iterator, quickbook::list()> list;
+        qi::rule<iterator, quickbook::list_item()> list_item;
+        qi::rule<iterator, std::string()> list_item_content;
+                qi::rule<iterator, quickbook::hr()> hr;
+        qi::rule<iterator, quickbook::paragraph()> paragraph;
+        qi::rule<iterator, std::string()> paragraph_content;
+        qi::rule<iterator> paragraph_end;
+        qi::symbols<> paragraph_end_markups;
         qi::rule<iterator, quickbook::title()> title_phrase;
+        qi::rule<iterator, std::string()> inside_paragraph;
+        qi::rule<iterator, quickbook::formatted()> inside_paragraph2;
         qi::rule<iterator, std::string()> phrase_attr;
-        
+        qi::rule<iterator> phrase_end;
+        qi::rule<iterator> comment, dummy_block;
+        qi::rule<iterator, boost::optional<std::string>()> element_id_1_5;
+        qi::rule<iterator, boost::optional<std::string>()> element_id;
+        qi::rule<iterator, std::string()> element_id_part;
+        qi::rule<iterator, std::string()> macro_identifier;
+        qi::rule<iterator, std::string()> template_id;
+        qi::rule<iterator, std::string()> identifier;
+        qi::rule<iterator, std::string()> punctuation_identifier;
+        qi::rule<iterator> hard_space, space, blank, eol;
         qi::rule<iterator, file_position()> position;
         qi::rule<iterator> error;
     };
@@ -211,44 +199,6 @@
             )
             ;
 
-        space =
-            *(qi::space | comment)
-            ;
-
-        blank =
-            *(qi::blank | comment)
-            ;
-
-        eol = blank >> qi::eol
-            ;
-
-        phrase_end =
-            ']' |
-            qi::eps(ph::ref(no_eols)) >>
-                eol >> eol                      // Make sure that we don't go
-                                                // past a single block, except
-            ;                                   // when preformatted.
-
-        hard_space =
-            !(qi::alnum | '_') >> space         // must not be preceded by
-            ;                                   // alpha-numeric or underscore
-
-        comment =
-            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
-            ;
-
-        dummy_block =
-            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
-            ;
-
-        hr =
-            qi::omit[
-                "----"
-            >>  *(qi::char_ - eol)
-            >>  +eol
-            ] >> qi::attr(quickbook::hr())
-            ;
-
         block_markup =
                 '[' >> space
             >>  (   begin_section
@@ -270,23 +220,6 @@
                 )
             ;
         
-        element_id =
-            (   ':'
-            >>  -(qi::eps(qbk_since(105u)) >> space) 
-            >>  (
-                    element_id_part
-                |   qi::omit[
-                        qi::raw[qi::eps]        [actions.element_id_warning]
-                    ]
-                )
-            )
-            | qi::eps
-            ;
-
-        element_id_part = +(qi::alnum | qi::char_('_'));
-        
-        element_id_1_5 = (qi::eps(qbk_since(105u)) >> element_id) | qi::eps;
-
         begin_section =
                 "section"
             >>  hard_space
@@ -311,23 +244,10 @@
             ("h6", 6)
             ("heading", -1);
 
-        static const bool true_ = true;
-        static const bool false_ = false;
-
-        inside_paragraph =
-                qi::eps                             [actions.phrase_push]
-            >>  inside_paragraph2                   [actions.process]
-            >>  *(  eol
-                >>  eol
-                >>  inside_paragraph2               [actions.process]
-                )
-            >>  qi::eps                             [actions.phrase_pop]
+        paragraph_block =
+            paragraph_blocks >> hard_space >> inside_paragraph
             ;
 
-        inside_paragraph2 =
-                qi::attr(markup(paragraph_pre, paragraph_post))
-            >>  phrase_attr;
-
         paragraph_blocks.add
             ("blurb", markup(blurb_pre, blurb_post))
             ("warning", markup(warning_pre, warning_post))
@@ -337,10 +257,6 @@
             ("tip", markup(tip_pre, tip_post))
             ;
 
-        paragraph_block =
-            paragraph_blocks >> hard_space >> inside_paragraph
-            ;
-
         blockquote =
                 ':'
             >>  blank
@@ -350,15 +266,11 @@
 
         preformatted %=
                 "pre"
-            >>  hard_space                      [ph::ref(no_eols) = false_]
+            >>  hard_space                      [ph::ref(no_eols) = false]
             >>  -eol
             >>  qi::attr(markup(preformatted_pre, preformatted_post))
             >>  phrase_attr
-            >>  qi::eps                         [ph::ref(no_eols) = true_]
-            ;
-
-        macro_identifier =
-            +(qi::char_ - (qi::space | ']'))
+            >>  qi::eps                         [ph::ref(no_eols) = true]
             ;
 
         def_macro =
@@ -369,43 +281,35 @@
             >>  phrase_attr
             ;
 
-        identifier =
-            (qi::alpha | '_') >> *(qi::alnum | '_')
-            ;
-        
-        punctuation_identifier =
-            qi::repeat(1)[qi::punct - (qi::char_('[') | ']')]
-            ;
-
-        template_id =
-            identifier | punctuation_identifier
+        table =
+                "table"
+            >>  (&(*qi::blank >> qi::eol) | hard_space)
+            >>  element_id_1_5
+            >>  (&(*qi::blank >> qi::eol) | space)
+            >>  *(qi::char_ - eol)
+            >>  +eol
+            >>  *table_row
             ;
 
-        define_template =
-                "template"
-            >>  hard_space
-            >>  template_id
-            >>  -(
-                    space
-                >>  '['
-                >>  *(space >> template_id)
-                >>  space
-                >>  ']'
+        table_row =
+                space
+            >>  '['
+            >>  (   *table_cell >> ']' >> space
+                |   error >> qi::attr(quickbook::table_row())
                 )
-            >>  position
-            >>  template_body
             ;
 
-        template_body =
-            qi::raw[template_body_recurse]
+        table_cell =
+                space
+            >>  '['
+            >>  (   table_cell_body >> ']' >> space
+                |   error >> qi::attr(quickbook::table_cell())
+                )
             ;
 
-        template_body_recurse =
-                *(  ('[' >> template_body_recurse >> ']')
-                |   (qi::char_ - ']')
-                )
-            >>  space
-            >>  &qi::lit(']')
+        table_cell_body =
+                qi::attr(markup(start_cell_, end_cell_))
+            >>  inside_paragraph
             ;
 
         variablelist =
@@ -453,37 +357,7 @@
             >>  inside_paragraph
             ;
 
-        table =
-                "table"
-            >>  (&(*qi::blank >> qi::eol) | hard_space)
-            >>  element_id_1_5
-            >>  (&(*qi::blank >> qi::eol) | space)
-            >>  *(qi::char_ - eol)
-            >>  +eol
-            >>  *table_row
-            ;
-
-        table_row =
-                space
-            >>  '['
-            >>  (   *table_cell >> ']' >> space
-                |   error >> qi::attr(quickbook::table_row())
-                )
-            ;
-
-        table_cell =
-                space
-            >>  '['
-            >>  (   table_cell_body >> ']' >> space
-                |   error >> qi::attr(quickbook::table_cell())
-                )
-            ;
-
-        table_cell_body =
-                qi::attr(markup(start_cell_, end_cell_))
-            >>  inside_paragraph
-            ;
-
+        // TODO: Why do these use phrase_end? It doesn't make any sense.
         xinclude =
                 "xinclude"
             >>  hard_space
@@ -491,6 +365,17 @@
             >>  qi::attr("dummy")
             ;
 
+        include =
+                "include"
+            >>  hard_space
+            >>  -(
+                    ':'
+                >>  *((qi::alnum | '_') - qi::space)
+                >>  space
+                )
+            >>  *(qi::char_ - phrase_end)
+            ;
+
         import =
                 "import"
             >>  hard_space
@@ -498,17 +383,35 @@
             >>  qi::attr("dummy")
             ;
 
-        include =
-                "include"
+        define_template =
+                "template"
             >>  hard_space
+            >>  template_id
             >>  -(
-                    ':'
-                >>  *((qi::alnum | '_') - qi::space)
+                    space
+                >>  '['
+                >>  *(space >> template_id)
                 >>  space
+                >>  ']'
                 )
-            >>  *(qi::char_ - phrase_end)
+            >>  position
+            >>  template_body
+            ;
+
+        template_body =
+            qi::raw[template_body_recurse]
             ;
 
+        template_body_recurse =
+                *(  ('[' >> template_body_recurse >> ']')
+                |   (qi::char_ - ']')
+                )
+            >>  space
+            >>  &qi::lit(']')
+            ;
+
+        // Blocks indicated by text layout (indentation, leading characters etc.)
+
         code =
                 position
             >>  qi::raw[
@@ -551,16 +454,15 @@
             >> qi::eps[actions.phrase_pop]
             ;
 
-        paragraph_end_markups =
-            "section", "endsect", "h1", "h2", "h3", "h4", "h5", "h6",
-            "blurb", ":", "pre", "def", "table", "include", "xinclude",
-            "variablelist", "import", "template", "warning", "caution",
-            "important", "note", "tip", ":"
+        hr =
+            qi::omit[
+                "----"
+            >>  *(qi::char_ - eol)
+            >>  +eol
+            ] >> qi::attr(quickbook::hr())
             ;
 
-        paragraph_end =
-            '[' >> space >> paragraph_end_markups >> hard_space | eol >> eol
-            ;
+        paragraph = paragraph_content >> qi::attr("dummy");
 
         paragraph_content =
                 qi::eps                         [actions.phrase_push]
@@ -573,14 +475,41 @@
             >> (&qi::lit('[') | +eol)
             ;
 
-        paragraph = paragraph_content >> qi::attr("dummy");
+        paragraph_end =
+            '[' >> space >> paragraph_end_markups >> hard_space | eol >> eol
+            ;
+
+        paragraph_end_markups =
+            "section", "endsect", "h1", "h2", "h3", "h4", "h5", "h6",
+            "blurb", ":", "pre", "def", "table", "include", "xinclude",
+            "variablelist", "import", "template", "warning", "caution",
+            "important", "note", "tip", ":"
+            ;
 
+        // Block contents
+
+        // Used when the title is used both to generate the title text and
+        // possibly to generate an id (based on the raw source).
         title_phrase =
             qi::raw[
                 phrase_attr                     [ph::at_c<1>(qi::_val) = qi::_1]
             ]                                   [ph::at_c<0>(qi::_val) = as_string(qi::_1)]
             ;
 
+        inside_paragraph =
+                qi::eps                             [actions.phrase_push]
+            >>  inside_paragraph2                   [actions.process]
+            >>  *(  eol
+                >>  eol
+                >>  inside_paragraph2               [actions.process]
+                )
+            >>  qi::eps                             [actions.phrase_pop]
+            ;
+
+        inside_paragraph2 =
+                qi::attr(markup(paragraph_pre, paragraph_post))
+            >>  phrase_attr;
+
         phrase_attr =
                 qi::eps                         [actions.phrase_push]        
             >> *(   common
@@ -590,7 +519,76 @@
             >>  qi::eps                         [actions.phrase_pop]
             ;
 
-        position = qi::raw[qi::eps] [get_position];
-        error = qi::raw[qi::eps] [actions.error];
+        // Make sure that we don't go past a single block, except when
+        // preformatted.
+        phrase_end =
+            ']' | qi::eps(ph::ref(no_eols)) >> eol >> eol
+            ;
+
+        comment =
+            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
+            ;
+
+        dummy_block =
+            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
+            ;
+
+        // Identifiers
+
+        element_id_1_5 = (qi::eps(qbk_since(105u)) >> element_id) | qi::eps;
+
+        element_id =
+            (   ':'
+            >>  -(qi::eps(qbk_since(105u)) >> space) 
+            >>  (
+                    element_id_part
+                |   qi::omit[
+                        qi::raw[qi::eps]        [actions.element_id_warning]
+                    ]
+                )
+            )
+            | qi::eps
+            ;
+
+        element_id_part = +(qi::alnum | qi::char_('_'));
+
+        macro_identifier =
+            +(qi::char_ - (qi::space | ']'))
+            ;
+
+        template_id =
+            identifier | punctuation_identifier
+            ;
+
+        identifier =
+            (qi::alpha | '_') >> *(qi::alnum | '_')
+            ;
+        
+        punctuation_identifier =
+            qi::repeat(1)[qi::punct - qi::char_("[]")]
+            ;
+
+        // Used after an identifier that must not be immediately
+        // followed by an alpha-numeric character or underscore.
+        hard_space =
+            !(qi::alnum | '_') >> space
+            ;
+
+        space =
+            *(qi::space | comment)
+            ;
+
+        blank =
+            *(qi::blank | comment)
+            ;
+
+        eol = blank >> qi::eol
+            ;
+
+        position =
+            qi::raw[qi::eps] [get_position];
+
+        error =
+            qi::raw[qi::eps] [actions.error];
     }
 }
Modified: branches/quickbook-1.5-spirit2/phrase.cpp
==============================================================================
--- branches/quickbook-1.5-spirit2/phrase.cpp	(original)
+++ branches/quickbook-1.5-spirit2/phrase.cpp	2010-02-07 04:06:44 EST (Sun, 07 Feb 2010)
@@ -84,48 +84,45 @@
         quickbook::actions& actions;
         bool& no_eols;
 
-        qi::rule<iterator>
-                        space, blank, comment, phrase_markup,
-                        phrase_end,
-                        escape, common,
-                        hard_space, eol,
-                        replaceable, macro,
-                        dummy_block,
-                        brackets_1_4, template_inner_arg_1_5, brackets_1_5
-                        ;
-
-        qi::rule<iterator, file_position()> position;
-
-        qi::rule<iterator, quickbook::call_template()> call_template;
-        qi::rule<iterator, std::string()> template_arg_1_4, template_arg_1_5;
-        qi::rule<iterator, std::vector<std::string>() > template_args;
-
         qi::rule<iterator, std::string()> phrase;
-        
-        qi::rule<iterator, quickbook::formatted()> escape_punct, escape_markup;
-        qi::rule<iterator, quickbook::break_()> break_, escape_break;
-
-        qi::rule<iterator, std::string()> macro_identifier;
+        qi::rule<iterator> common;
+        qi::rule<iterator> macro;
+        qi::rule<iterator> phrase_markup;
+        qi::rule<iterator, quickbook::code()> code_block;
+        qi::rule<iterator, quickbook::code()> inline_code;
+        qi::rule<iterator, quickbook::simple_markup(), qi::locals<char> > simple_format;
+        qi::rule<iterator> escape;        
+        qi::rule<iterator, quickbook::break_()> escape_break;
+        qi::rule<iterator, quickbook::formatted()> escape_punct;
+        qi::rule<iterator, quickbook::formatted()> escape_markup;
+        qi::rule<iterator> comment;
+        qi::rule<iterator> dummy_block;
         qi::rule<iterator, quickbook::cond_phrase()> cond_phrase;
-
+        qi::rule<iterator, std::string()> macro_identifier;
         qi::rule<iterator, quickbook::image()> image, image_1_4, image_1_5;
-        qi::rule<iterator, std::string()> image_filename, image_attribute_key, image_attribute_value;
+        qi::rule<iterator, std::string()> image_filename;
         qi::rule<iterator, quickbook::image::attribute_map()> image_attributes;
         qi::rule<iterator, std::pair<std::string, std::string>()> image_attribute;
-        
-        qi::rule<iterator, quickbook::code()> inline_code, code_block;
-        
-        qi::rule<iterator, quickbook::simple_markup(), qi::locals<char> > simple_format;
-        
-        qi::rule<iterator, quickbook::anchor()> anchor;
-
+        qi::rule<iterator, std::string()> image_attribute_key, image_attribute_value;
+        qi::rule<iterator, quickbook::link()> url;
+        qi::rule<iterator, quickbook::link()> link;
         qi::symbols<char, markup> link_symbol;
-        qi::rule<iterator, quickbook::link()> link, url;
-
+        qi::rule<iterator, quickbook::anchor()> anchor;
+        qi::symbols<char, quickbook::source_mode> source_mode;
+        qi::rule<iterator, quickbook::formatted()> formatted;
         qi::symbols<char, markup> format_symbol;
-        qi::rule<iterator, quickbook::formatted()> formatted, footnote;
+        qi::rule<iterator, quickbook::formatted()> footnote;
+        qi::rule<iterator, quickbook::call_template()> call_template;
+        qi::rule<iterator, std::vector<std::string>() > template_args;
+        qi::rule<iterator, std::string()> template_arg_1_4;
+        qi::rule<iterator> brackets_1_4;
+        qi::rule<iterator, std::string()> template_arg_1_5;
+        qi::rule<iterator> template_inner_arg_1_5;
+        qi::rule<iterator> brackets_1_5;
+        qi::rule<iterator, quickbook::break_()> break_;
+        qi::rule<iterator> space, blank, eol, phrase_end, hard_space;
+        qi::rule<iterator, file_position()> position;
         
-        qi::symbols<char, quickbook::source_mode> source_mode;
     };
 
     phrase_grammar::phrase_grammar(quickbook::actions& actions, bool& no_eols)
@@ -140,35 +137,13 @@
     phrase_grammar::rules::rules(quickbook::actions& actions, bool& no_eols)
         : actions(actions), no_eols(no_eols)
     {
-        space =
-            *(qi::space | comment)
-            ;
-
-        blank =
-            *(qi::blank | comment)
-            ;
-
-        eol = blank >> qi::eol
-            ;
-
-        phrase_end =
-            ']' |
-            qi::eps(ph::ref(no_eols)) >>
-                eol >> eol                      // Make sure that we don't go
-            ;                                   // past a single block, except
-                                                // when preformatted.
-
-        hard_space =
-            !(qi::alnum | '_') >> space
-            ;                                   // must not be preceded by
-                                                // alpha-numeric or underscore
-
-        comment =
-            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
-            ;
-
-        dummy_block =
-            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
+        phrase =
+                qi::eps                         [actions.phrase_push]        
+            >> *(   common
+                |   comment
+                |   (qi::char_ - phrase_end)    [actions.plain_char]
+                )
+            >>  qi::eps                         [actions.phrase_pop]
             ;
 
         common =
@@ -187,58 +162,21 @@
             )                                       [actions.process]
             ;
 
-        // Template call
-
-        call_template =
-                position
-            >>  (   '`' >> qi::attr(true)
-                |   qi::attr(false)
-                )
-            >>  (                                   // Lookup the template name
-                    (&qi::punct >> actions.templates.scope)
-                |   (actions.templates.scope >> hard_space)
+        phrase_markup =
+            (   '['
+            >>  (   cond_phrase                     
+                |   image
+                |   url
+                |   link
+                |   anchor
+                |   source_mode
+                |   formatted
+                |   footnote
+                |   call_template
+                |   break_
                 )
-            >>  template_args
-            >>  &qi::lit(']')
-            ;
-
-        template_args =
-            qi::eps(qbk_before(105u)) >> -(template_arg_1_4 % "..") |
-            qi::eps(qbk_since(105u)) >> -(template_arg_1_5 % "..");
-
-        template_arg_1_4 =
-            qi::raw[+(brackets_1_4 | (qi::char_ - (qi::lit("..") | ']')))]
-            ;
-
-        brackets_1_4 =
-            '[' >> +template_arg_1_4 >> ']'
-            ;
-
-        template_arg_1_5 =
-            qi::raw[+(brackets_1_5 | ('\\' >> qi::char_) | (qi::char_ - (qi::lit("..") | '[' | ']')))]
-            ;
-
-        template_inner_arg_1_5 =
-            +(brackets_1_5 | ('\\' >> qi::char_) | (qi::char_ - (qi::lit('[') | ']')))
-            ;
-
-        brackets_1_5 =
-            '[' >> +template_inner_arg_1_5 >> ']'
-            ;
-
-        inline_code =
-                '`'
-            >>  position
-            >>  qi::raw
-                [   *(  qi::char_ -
-                        (   '`'
-                        |   (eol >> eol)            // Make sure that we don't go
-                        )                           // past a single block
-                    )
-                    >>  &qi::lit('`')
-                ]
-            >>  '`'
-            >>  qi::attr(false)
+            >>  ']'
+            )                                       [actions.process]
             ;
 
         code_block =
@@ -258,6 +196,21 @@
                 )
             ;
 
+        inline_code =
+                '`'
+            >>  position
+            >>  qi::raw
+                [   *(  qi::char_ -
+                        (   '`'
+                        |   (eol >> eol)            // Make sure that we don't go
+                        )                           // past a single block
+                    )
+                    >>  &qi::lit('`')
+                ]
+            >>  '`'
+            >>  qi::attr(false)
+            ;
+
         simple_format %=
                 qi::char_("*/_=")               [qi::_a = qi::_1]
             >>  qi::raw
@@ -283,38 +236,6 @@
             >> qi::omit[qi::char_(qi::_a)]
             ;
 
-        phrase =
-                qi::eps                         [actions.phrase_push]        
-            >> *(   common
-                |   comment
-                |   (qi::char_ - phrase_end)    [actions.plain_char]
-                )
-            >>  qi::eps                         [actions.phrase_pop]
-            ;
-
-        phrase_markup =
-            (   '['
-            >>  (   cond_phrase                     
-                |   image
-                |   url
-                |   link
-                |   anchor
-                |   source_mode
-                |   formatted
-                |   footnote
-                |   call_template
-                |   break_
-                )
-            >>  ']'
-            )                                       [actions.process]
-            ;
-
-        break_ =
-                position
-            >>  "br"
-            >>  qi::attr("dummy")
-            ;
-
         escape =
             (   escape_break
             |   "\\ "                               // ignore an escaped char
@@ -342,8 +263,12 @@
             >>  "'''"
             ;
 
-        macro_identifier =
-            +(qi::char_ - (qi::space | ']'))
+        comment =
+            "[/" >> *(dummy_block | (qi::char_ - ']')) >> ']'
+            ;
+
+        dummy_block =
+            '[' >> *(dummy_block | (qi::char_ - ']')) >> ']'
             ;
 
         cond_phrase =
@@ -353,6 +278,10 @@
             >>  -phrase
             ;
 
+        macro_identifier =
+            +(qi::char_ - (qi::space | ']'))
+            ;
+
         image =
             (qi::eps(qbk_since(105u)) >> image_1_5) |
             (qi::eps(qbk_before(105u)) >> image_1_4);
@@ -395,11 +324,22 @@
         image_attribute_key = *(qi::alnum | '_');
         image_attribute_value = *(qi::char_ - (phrase_end | '['));
 
-        anchor =
-                '#'
-            >>  blank
-            >>  *(qi::char_ - phrase_end)
-            >>  qi::attr("dummy")
+        url =
+                '@'
+            >>  qi::attr(markup(url_pre_, url_post_))
+            >>  *(qi::char_ - (']' | qi::space))
+            >>  (   &qi::lit(']')
+                |   (hard_space >> phrase)
+                )
+            ;
+
+        link =
+                link_symbol
+            >>  hard_space
+            >>  *(qi::char_ - (']' | qi::space))
+            >>  (   &qi::lit(']')
+                |   (hard_space >> phrase)
+                )
             ;
 
         link_symbol.add
@@ -414,24 +354,21 @@
             ("globalref", markup(globalref_pre_, globalref_post_))
             ;
 
-        link =
-                link_symbol
-            >>  hard_space
-            >>  *(qi::char_ - (']' | qi::space))
-            >>  (   &qi::lit(']')
-                |   (hard_space >> phrase)
-                )
+        anchor =
+                '#'
+            >>  blank
+            >>  *(qi::char_ - phrase_end)
+            >>  qi::attr("dummy")
             ;
 
-        url =
-                '@'
-            >>  qi::attr(markup(url_pre_, url_post_))
-            >>  *(qi::char_ - (']' | qi::space))
-            >>  (   &qi::lit(']')
-                |   (hard_space >> phrase)
-                )
+        source_mode.add
+            ("c++", quickbook::source_mode("c++"))
+            ("python", quickbook::source_mode("python"))
+            ("teletype", quickbook::source_mode("teletype"))
             ;
 
+        formatted = format_symbol >> blank >> phrase;
+
         format_symbol.add
             ("*", markup(bold_pre_, bold_post_))
             ("'", markup(italic_pre_, italic_post_))
@@ -442,14 +379,6 @@
             ("~", markup(replaceable_pre_, replaceable_post_))
             ;
 
-        formatted = format_symbol >> blank >> phrase;
-
-        source_mode.add
-            ("c++", quickbook::source_mode("c++"))
-            ("python", quickbook::source_mode("python"))
-            ("teletype", quickbook::source_mode("teletype"))
-            ;
-
         footnote =
                 "footnote"
             >>  qi::attr(markup(footnote_pre_, footnote_post_))
@@ -457,6 +386,73 @@
             >>  phrase
             ;
 
+        // Template call
+
+        call_template =
+                position
+            >>  (   '`' >> qi::attr(true)
+                |   qi::attr(false)
+                )
+            >>  (                                   // Lookup the template name
+                    (&qi::punct >> actions.templates.scope)
+                |   (actions.templates.scope >> hard_space)
+                )
+            >>  template_args
+            >>  &qi::lit(']')
+            ;
+
+        template_args =
+            qi::eps(qbk_before(105u)) >> -(template_arg_1_4 % "..") |
+            qi::eps(qbk_since(105u)) >> -(template_arg_1_5 % "..");
+
+        template_arg_1_4 =
+            qi::raw[+(brackets_1_4 | (qi::char_ - (qi::lit("..") | ']')))]
+            ;
+
+        brackets_1_4 =
+            '[' >> +template_arg_1_4 >> ']'
+            ;
+
+        template_arg_1_5 =
+            qi::raw[+(brackets_1_5 | ('\\' >> qi::char_) | (qi::char_ - (qi::lit("..") | '[' | ']')))]
+            ;
+
+        template_inner_arg_1_5 =
+            +(brackets_1_5 | ('\\' >> qi::char_) | (qi::char_ - (qi::lit('[') | ']')))
+            ;
+
+        brackets_1_5 =
+            '[' >> +template_inner_arg_1_5 >> ']'
+            ;
+
+        break_ =
+                position
+            >>  "br"
+            >>  qi::attr("dummy")
+            ;
+
+        space =
+            *(qi::space | comment)
+            ;
+
+        blank =
+            *(qi::blank | comment)
+            ;
+
+        eol = blank >> qi::eol
+            ;
+
+        phrase_end =
+            ']' |
+            qi::eps(ph::ref(no_eols)) >>
+                eol >> eol                      // Make sure that we don't go
+            ;                                   // past a single block, except
+                                                // when preformatted.
+
+        hard_space =
+            !(qi::alnum | '_') >> space
+            ;                                   // must not be preceded by
+                                                // alpha-numeric or underscore
          position = qi::raw[qi::eps] [get_position];
     }