| /*============================================================================= |
| Copyright (c) 2002 2004 2006 Joel de Guzman |
| Copyright (c) 2004 Eric Niebler |
| Copyright (c) 2010 Daniel James |
| http://spirit.sourceforge.net/ |
| |
| Use, modification and distribution is subject to the Boost Software |
| License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| #if !defined(BOOST_SPIRIT_QUICKBOOK_GRAMMARS_IMPL_HPP) |
| #define BOOST_SPIRIT_QUICKBOOK_GRAMMARS_IMPL_HPP |
| |
| #include "grammar.hpp" |
| #include "cleanup.hpp" |
| #include "values.hpp" |
| #include <boost/spirit/include/classic_symbols.hpp> |
| |
| namespace quickbook |
| { |
| namespace cl = boost::spirit::classic; |
| |
| // Information about a square bracket element (e.g. [* word]). |
| // |
| // TODO: The naming is a bit confused as element is also sometimes used for |
| // syntactic/implicit elements (such as lists and horizontal rules). Maybe |
| // should use entity as a more general name instead of element. Or it might |
| // be better to use 'tag' for square bracket elements, although that is |
| // currently used for the type of entities. |
| struct element_info |
| { |
| // Types of elements. |
| // |
| // Used to determine: |
| // |
| // - where they can be used. |
| // - whether they end a paragraph |
| // - how following newlines are interpreted by the grammar. |
| // - and possibly other things..... |
| enum type_enum { |
| // Used when there's no element. |
| nothing = 0, |
| |
| // A section tag. These can't be nested. |
| section_block = 1, |
| |
| // Block elements that can be used in conditional phrases and lists, |
| // but not nested. (TODO: not a good name). |
| conditional_or_block = 2, |
| |
| // Block elements that can be nested in other elements. |
| nested_block = 4, |
| |
| // Phrase elements. |
| phrase = 8, |
| |
| // Depending on the context this can be a block or phrase. |
| // |
| // Currently this is only used for elements that don't actually |
| // generate output (e.g. anchors, source mode tags). The main |
| // reason is so that lists can be preceeded by the element, e.g. |
| // |
| // [#anchor] |
| // * list item. |
| // |
| // If the anchor was considered to be a phrase element, then the |
| // list wouldn't be recognised. |
| maybe_block = 16 |
| }; |
| |
| // Masks to determine which context elements can be used in (in_*), and |
| // whether they are consided to be a block element (is_*). |
| enum context { |
| // At the top level we allow everything. |
| in_top_level = phrase | maybe_block | nested_block | |
| conditional_or_block | section_block, |
| |
| // In conditional phrases and list blocks we everything but section |
| // elements. |
| in_conditional = phrase | maybe_block | nested_block | |
| conditional_or_block, |
| in_list_block = phrase | maybe_block | nested_block | |
| conditional_or_block, |
| |
| // In nested blocks we allow a more limited range of elements. |
| in_nested_block = phrase | maybe_block | nested_block, |
| |
| // In a phrase we only allow phrase elements, ('maybe_block' |
| // elements are treated as phrase elements in this context) |
| in_phrase = phrase | maybe_block, |
| |
| // At the start of a block these are all block elements. |
| is_contextual_block = maybe_block | nested_block | |
| conditional_or_block | section_block, |
| |
| // These are all block elements in all other contexts. |
| is_block = nested_block | conditional_or_block | section_block, |
| }; |
| |
| element_info() |
| : type(nothing), rule(), tag(0) {} |
| |
| element_info( |
| type_enum t, |
| cl::rule<scanner>* r, |
| value::tag_type tag = value::default_tag, |
| unsigned int v = 0) |
| : type(t), rule(r), tag(tag), qbk_version(v) {} |
| |
| type_enum type; |
| cl::rule<scanner>* rule; |
| value::tag_type tag; |
| unsigned int qbk_version; |
| }; |
| |
| struct quickbook_grammar::impl |
| { |
| quickbook::state& state; |
| cleanup cleanup_; |
| |
| // Main Grammar |
| cl::rule<scanner> block_start; |
| cl::rule<scanner> phrase_start; |
| cl::rule<scanner> nested_phrase; |
| cl::rule<scanner> inline_phrase; |
| cl::rule<scanner> paragraph_phrase; |
| cl::rule<scanner> extended_phrase; |
| cl::rule<scanner> table_title_phrase; |
| cl::rule<scanner> inside_preformatted; |
| cl::rule<scanner> inside_paragraph; |
| cl::rule<scanner> command_line; |
| cl::rule<scanner> attribute_template_body; |
| cl::rule<scanner> attribute_value_1_7; |
| cl::rule<scanner> escape; |
| cl::rule<scanner> raw_escape; |
| cl::rule<scanner> skip_entity; |
| |
| // Miscellaneous stuff |
| cl::rule<scanner> hard_space; |
| cl::rule<scanner> space; |
| cl::rule<scanner> blank; |
| cl::rule<scanner> eol; |
| cl::rule<scanner> phrase_end; |
| cl::rule<scanner> comment; |
| cl::rule<scanner> line_comment; |
| cl::rule<scanner> macro_identifier; |
| |
| // Element Symbols |
| cl::symbols<element_info> elements; |
| |
| // Source mode |
| cl::symbols<source_mode_type> source_modes; |
| |
| // Doc Info |
| cl::rule<scanner> doc_info_details; |
| |
| impl(quickbook::state&); |
| |
| private: |
| |
| void init_main(); |
| void init_block_elements(); |
| void init_phrase_elements(); |
| void init_doc_info(); |
| }; |
| } |
| |
| #endif // BOOST_SPIRIT_QUICKBOOK_GRAMMARS_HPP |