blob: 8d37d351f19719d4368243dafd22785d0eea0601 [file] [log] [blame] [edit]
/*=============================================================================
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