Merge quickbook from trunk.

[SVN r65433]
This commit is contained in:
Daniel James
2010-09-15 22:54:21 +00:00
parent 59669b5afc
commit b783f785df
40 changed files with 1521 additions and 1130 deletions

View File

@@ -26,6 +26,10 @@ namespace quickbook
char const* quickbook_get_date = "__quickbook_get_date__";
char const* quickbook_get_time = "__quickbook_get_time__";
int qbk_major_version = -1;
int qbk_minor_version = -1;
unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version
namespace {
std::string fully_qualified_id(std::string const& library_id,
std::string const& qualified_section_id,
@@ -43,7 +47,7 @@ namespace quickbook
// Handles line-breaks (DEPRECATED!!!)
void break_action::operator()(iterator first, iterator) const
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", "
<< "[br] and \\n are deprecated" << ".\n";
phrase << break_mark;
@@ -51,12 +55,17 @@ namespace quickbook
void error_action::operator()(iterator first, iterator /*last*/) const
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outerr(pos.file,pos.line)
<< "Syntax Error near column " << pos.column << ".\n";
++error_count;
}
void tagged_action::operator()(std::string const& str) const
{
out << pre << str << post;
}
void phrase_action::operator()(iterator first, iterator last) const
{
std::string str;
@@ -271,7 +280,7 @@ namespace quickbook
if (mark != list_marks.top().first) // new_indent == list_indent
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outerr(pos.file,pos.line)
<< "Illegal change of list style near column " << pos.column << ".\n";
detail::outwarn(pos.file,pos.line)
@@ -290,7 +299,7 @@ namespace quickbook
void unexpected_char::operator()(iterator first, iterator last) const
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outwarn(pos.file, pos.line)
<< "in column:" << pos.column
@@ -371,7 +380,7 @@ namespace quickbook
phrase.swap(save);
// print the code with syntax coloring
std::string str = syntax_p(first_, last_);
std::string str = syntax_highlight(first_, last_, actions, actions.source_mode);
phrase.swap(save);
@@ -390,7 +399,7 @@ namespace quickbook
out.swap(save);
// print the code with syntax coloring
std::string str = syntax_p(first, last);
std::string str = syntax_highlight(first, last, actions, actions.source_mode);
out.swap(save);
@@ -440,7 +449,7 @@ namespace quickbook
void attribute_action::operator()(iterator first, iterator last) const
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
if (!attributes.insert(
attribute_map::value_type(attribute_name, std::string(first, last))
@@ -563,6 +572,7 @@ namespace quickbook
void macro_definition_action::operator()(iterator first, iterator last) const
{
actions.copy_macros_for_write();
actions.macro.add(
actions.macro_id.begin()
, actions.macro_id.end()
@@ -577,7 +587,7 @@ namespace quickbook
std::string(first, last), first.get_position(),
actions.template_block, &actions.templates.top_scope())))
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outerr(pos.file,pos.line)
<< "Template Redefinition: " << actions.template_identifier << std::endl;
++actions.error_count;
@@ -647,7 +657,7 @@ namespace quickbook
bool break_arguments(
std::vector<template_body>& args
, std::vector<std::string> const& params
, boost::spirit::classic::file_position const& pos
, position const& pos
)
{
// Quickbook 1.4-: If there aren't enough parameters seperated by
@@ -668,7 +678,8 @@ namespace quickbook
// arguments, or if there are no more spaces left.
template_body& body = args.back();
iterator begin(body.content.begin(), body.content.end(), body.position.file);
iterator begin(body.content.begin(), body.content.end(),
position(body.position.file.c_str(), body.position.line, body.position.column));
iterator end(body.content.end(), body.content.end());
iterator l_pos = find_first_seperator(begin, end);
@@ -680,7 +691,7 @@ namespace quickbook
while(r_pos != end && std::find(whitespace, whitespace_end, *r_pos) != whitespace_end) ++r_pos;
if (r_pos == end)
break;
template_body second(std::string(r_pos, end), begin.get_position(), false);
template_body second(std::string(r_pos, end), r_pos.get_position(), false);
body.content = std::string(begin, l_pos);
args.push_back(second);
}
@@ -705,7 +716,7 @@ namespace quickbook
std::vector<template_body>& args
, std::vector<std::string> const& params
, template_scope const& scope
, boost::spirit::classic::file_position const& pos
, position const& pos
, quickbook::actions& actions
)
{
@@ -734,7 +745,6 @@ namespace quickbook
bool parse_template(
template_body const& body
, bool escape
, std::string& result
, quickbook::actions& actions
)
{
@@ -749,7 +759,7 @@ namespace quickbook
{
// escape the body of the template
// we just copy out the literal body
result = body.content;
(body.is_block ? actions.out : actions.phrase) << body.content;
return true;
}
else if (!body.is_block)
@@ -757,11 +767,10 @@ namespace quickbook
simple_phrase_grammar phrase_p(actions);
// do a phrase level parse
iterator first(body.content.begin(), body.content.end(), body.position);
iterator first(body.content.begin(), body.content.end(),
position(body.position.file.c_str(), body.position.line, body.position.column));
iterator last(body.content.end(), body.content.end());
bool r = quickbook::parse(first, last, phrase_p).full;
actions.phrase.swap(result);
return r;
return call_parse(first, last, phrase_p).full;
}
else
{
@@ -772,12 +781,10 @@ namespace quickbook
// the need to check for end of file in the grammar.
std::string content = body.content + "\n\n";
iterator first(content.begin(), content.end(), body.position);
iterator first(content.begin(), content.end(),
position(body.position.file.c_str(), body.position.line, body.position.column));
iterator last(content.end(), content.end());
bool r = quickbook::parse(first, last, block_p).full;
actions.inside_paragraph();
actions.out.swap(result);
return r;
return call_parse(first, last, block_p).full;
}
}
}
@@ -804,7 +811,7 @@ namespace quickbook
std::string identifier;
std::swap(args, actions.template_args);
std::swap(identifier, actions.template_identifier);
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
++actions.template_depth;
if (actions.template_depth > actions.max_template_depth)
@@ -825,8 +832,10 @@ namespace quickbook
template_symbol const* symbol = actions.templates.find(identifier);
BOOST_ASSERT(symbol);
std::string result;
std::string block;
std::string phrase;
actions.push(); // scope the actions' states
{
// Store the current section level so that we can ensure that
@@ -902,9 +911,9 @@ namespace quickbook
///////////////////////////////////
// parse the template body:
if (!parse_template(symbol->body, actions.template_escape, result, actions))
if (!parse_template(symbol->body, actions.template_escape, actions))
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outerr(pos.file,pos.line)
<< "Expanding "
<< (symbol->body.is_block ? "block" : "phrase")
@@ -922,7 +931,7 @@ namespace quickbook
if (actions.section_level != actions.min_section_level)
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outerr(pos.file,pos.line)
<< "Mismatched sections in template " << identifier << std::endl;
actions.pop(); // restore the actions' states
@@ -932,11 +941,14 @@ namespace quickbook
}
}
actions.out.swap(block);
actions.phrase.swap(phrase);
actions.pop(); // restore the actions' states
if(symbol->callout && symbol->callouts.size() > 0)
{
result += "<calloutlist>";
BOOST_ASSERT(phrase.empty());
block += "<calloutlist>";
BOOST_FOREACH(template_body const& c, symbol->callouts)
{
std::string callout_id = actions.doc_id +
@@ -944,31 +956,38 @@ namespace quickbook
std::string callout_value;
actions.push();
bool r = parse_template(c, false, callout_value, actions);
bool r = parse_template(c, false, actions);
actions.out.swap(callout_value);
actions.pop();
if(!r)
{
detail::outerr(c.position.file, c.position.line)
<< "Expanding callout." << std::endl;
<< "Expanding callout." << std::endl
<< "------------------begin------------------" << std::endl
<< c.content
<< std::endl
<< "------------------end--------------------" << std::endl
;
++actions.error_count;
return;
}
result += "<callout arearefs=\"" + callout_id + "co\" ";
result += "id=\"" + callout_id + "\">";
result += callout_value;
result += "</callout>";
block += "<callout arearefs=\"" + callout_id + "co\" ";
block += "id=\"" + callout_id + "\">";
block += callout_value;
block += "</callout>";
}
result += "</calloutlist>";
block += "</calloutlist>";
}
if(symbol->body.is_block) {
if(symbol->body.is_block || !block.empty()) {
actions.inside_paragraph();
actions.temp_para << result; // print it!!!
actions.out << block;
actions.phrase << phrase;
}
else {
actions.phrase << result; // print it!!!
actions.phrase << phrase;
}
--actions.template_depth;
}
@@ -1015,20 +1034,6 @@ namespace quickbook
actions.table_title.clear();
}
void start_varlistitem_action::operator()() const
{
phrase << start_varlistitem_;
phrase.push();
}
void end_varlistitem_action::operator()() const
{
std::string str;
temp_para.swap(str);
phrase.pop();
phrase << str << end_varlistitem_;
}
void table_action::operator()(iterator, iterator) const
{
std::string::iterator first = actions.table_title.begin();
@@ -1114,21 +1119,12 @@ namespace quickbook
(*this)(*f);
}
void start_col_action::operator()(char) const
void col_action::operator()(std::string const& contents) const
{
phrase << start_cell_;
phrase.push();
phrase << start_cell_ << contents << end_cell_;
++span;
}
void end_col_action::operator()(char) const
{
std::string str;
temp_para.swap(str);
phrase.pop();
phrase << str << end_cell_;
}
void begin_section_action::operator()(iterator first, iterator last) const
{
section_id = element_id.empty() ?
@@ -1175,7 +1171,7 @@ namespace quickbook
{
if (section_level <= min_section_level)
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outerr(pos.file,pos.line)
<< "Mismatched [endsect] near column " << pos.column << ".\n";
++error_count;
@@ -1200,7 +1196,7 @@ namespace quickbook
void element_id_warning_action::operator()(iterator first, iterator) const
{
boost::spirit::classic::file_position const pos = first.get_position();
position const pos = first.get_position();
detail::outwarn(pos.file,pos.line) << "Empty id.\n";
}
@@ -1291,7 +1287,7 @@ namespace quickbook
ts.parent = &actions.templates.top_scope();
if (!actions.templates.add(ts))
{
boost::spirit::classic::file_position const pos = ts.body.position;
cl::file_position const pos = ts.body.position;
detail::outerr(pos.file, pos.line)
<< "Template Redefinition: " << tname << std::endl;
++actions.error_count;
@@ -1329,6 +1325,7 @@ namespace quickbook
// scope the macros
string_symbols macro = actions.macro;
std::size_t macro_change_depth = actions.macro_change_depth;
// scope the templates
//~ template_symbols templates = actions.templates; $$$ fixme $$$
@@ -1363,6 +1360,7 @@ namespace quickbook
// restore the macros
actions.macro = macro;
actions.macro_change_depth = macro_change_depth;
// restore the templates
//~ actions.templates = templates; $$$ fixme $$$
}
@@ -1379,11 +1377,4 @@ namespace quickbook
phrase.swap(out.encoded);
out.raw = std::string(first, last);
}
void copy_stream_action::operator()(iterator first, iterator last) const
{
std::string str;
phrase.swap(str);
out << str;
}
}

View File

@@ -10,16 +10,15 @@
#if !defined(BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP)
#define BOOST_SPIRIT_QUICKBOOK_ACTIONS_HPP
#include <time.h>
#include <map>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <boost/spirit/include/classic_iterator.hpp>
#include <boost/filesystem/v2/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>
#include "fwd.hpp"
#include "collector.hpp"
#include "template_stack.hpp"
#include "utils.hpp"
@@ -35,22 +34,44 @@ namespace quickbook
namespace cl = boost::spirit::classic;
namespace fs = boost::filesystem;
typedef cl::position_iterator<std::string::const_iterator> iterator;
extern int qbk_major_version;
extern int qbk_minor_version;
extern unsigned qbk_version_n; // qbk_major_version * 100 + qbk_minor_version
struct quickbook_range {
template <typename Arg>
struct result
{
typedef bool type;
};
quickbook_range(unsigned min_, unsigned max_)
: min_(min_), max_(max_) {}
bool operator()() const {
return qbk_version_n >= min_ && qbk_version_n < max_;
}
unsigned min_, max_;
};
inline quickbook_range qbk_since(unsigned min_) {
return quickbook_range(min_, 999);
}
inline quickbook_range qbk_before(unsigned max_) {
return quickbook_range(0, max_);
}
typedef cl::symbols<std::string> string_symbols;
typedef std::map<std::string, std::string> attribute_map;
struct actions;
extern tm* current_time; // the current time
extern tm* current_gm_time; // the current UTC time
extern bool debug_mode;
extern std::vector<std::string> include_path;
extern std::vector<std::string> preset_defines;
// forward declarations
struct actions;
int parse_file(char const* filein_, actions& actor, bool ignore_docinfo = false);
int load_snippets(std::string const& file, std::vector<template_symbol>& storage,
std::string const& extension, std::string const& doc_id);
std::string syntax_highlight(
iterator first, iterator last,
actions& escape_actions,
std::string const& source_mode);
struct error_action
{
@@ -65,6 +86,23 @@ namespace quickbook
int& error_count;
};
struct tagged_action
{
tagged_action(
collector& out,
std::string const& pre,
std::string const& post)
: out(out)
, pre(pre)
, post(post) {}
void operator()(std::string const&) const;
collector& out;
std::string pre;
std::string post;
};
struct phrase_action
{
// blurb, blockquote, preformatted, list_item,
@@ -471,29 +509,6 @@ namespace quickbook
std::string str;
};
struct syntax_highlight
{
syntax_highlight(
collector& temp
, std::string const& source_mode
, string_symbols const& macro
, actions& escape_actions)
: temp(temp)
, source_mode(source_mode)
, macro(macro)
, escape_actions(escape_actions)
{
}
std::string operator()(iterator begin, iterator end) const;
collector& temp;
std::string const& source_mode;
string_symbols const& macro;
actions& escape_actions;
};
struct code_action
{
// Does the actual syntax highlighing of code
@@ -501,10 +516,10 @@ namespace quickbook
code_action(
collector& out
, collector& phrase
, syntax_highlight& syntax_p)
, quickbook::actions& actions)
: out(out)
, phrase(phrase)
, syntax_p(syntax_p)
, actions(actions)
{
}
@@ -512,7 +527,7 @@ namespace quickbook
collector& out;
collector& phrase;
syntax_highlight& syntax_p;
quickbook::actions& actions;
};
struct inline_code_action
@@ -521,46 +536,15 @@ namespace quickbook
inline_code_action(
collector& out
, syntax_highlight& syntax_p)
, quickbook::actions& actions)
: out(out)
, syntax_p(syntax_p)
, actions(actions)
{}
void operator()(iterator first, iterator last) const;
collector& out;
syntax_highlight& syntax_p;
};
struct start_varlistitem_action
{
start_varlistitem_action(collector& phrase)
: phrase(phrase) {}
void operator()() const;
template <typename T1>
void operator()(T1 const&) const { return (*this)(); }
template <typename T1, typename T2>
void operator()(T1 const&, T2 const&) const { return (*this)(); }
collector& phrase;
};
struct end_varlistitem_action
{
end_varlistitem_action(collector& phrase, collector& temp_para)
: phrase(phrase), temp_para(temp_para) {}
void operator()() const;
template <typename T1>
void operator()(T1 const&) const { return (*this)(); }
template <typename T1, typename T2>
void operator()(T1 const&, T2 const&) const { return (*this)(); }
collector& phrase;
collector& temp_para;
quickbook::actions& actions;
};
struct break_action
@@ -687,30 +671,17 @@ namespace quickbook
std::string& header;
};
struct start_col_action
struct col_action
{
// Handles table columns
start_col_action(collector& phrase, unsigned& span)
col_action(collector& phrase, unsigned& span)
: phrase(phrase), span(span) {}
void operator()(char) const;
void operator()(std::string const&) const;
collector& phrase;
unsigned& span;
};
struct end_col_action
{
end_col_action(collector& phrase, collector& temp_para)
: phrase(phrase), temp_para(temp_para) {}
void operator()(char) const;
collector& phrase;
collector& temp_para;
};
struct begin_section_action
{
// Handles begin page
@@ -854,17 +825,6 @@ namespace quickbook
docinfo_string& out;
collector& phrase;
};
struct copy_stream_action
{
copy_stream_action(collector& out, collector& phrase)
: out(out) , phrase(phrase) {}
void operator()(iterator first, iterator last) const;
collector& out;
collector& phrase;
};
}
#ifdef BOOST_MSVC

View File

@@ -10,6 +10,7 @@
=============================================================================*/
#include "actions_class.hpp"
#include "markups.hpp"
#include "quickbook.hpp"
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
#pragma warning(disable:4355)
@@ -37,12 +38,12 @@ namespace quickbook
// auxilliary streams
, phrase()
, temp()
, list_buffer()
// state
, filename(fs::complete(fs::path(filein_)))
, outdir(outdir_)
, macro_change_depth(0)
, macro()
, section_level(0)
, min_section_level(0)
@@ -81,12 +82,11 @@ namespace quickbook
, extract_name_first(name.first, phrase)
, extract_doc_last_revision(doc_last_revision, phrase)
, extract_doc_category(doc_category, phrase)
, syntax_p(temp, source_mode, macro, *this)
, code(out, phrase, syntax_p)
, code_block(phrase, phrase, syntax_p)
, inline_code(phrase, syntax_p)
, inside_paragraph(temp_para, phrase, paragraph_pre, paragraph_post)
, write_paragraphs(out, temp_para)
, extract_doc_biblioid(doc_biblioid.second, phrase)
, code(out, phrase, *this)
, code_block(phrase, phrase, *this)
, inline_code(phrase, *this)
, inside_paragraph(out, phrase, paragraph_pre, paragraph_post)
, h(out, phrase, element_id, doc_id, section_id, qualified_section_id, section_level)
, h1(out, phrase, element_id, doc_id, section_id, qualified_section_id, h1_pre, h1_post)
, h2(out, phrase, element_id, doc_id, section_id, qualified_section_id, h2_pre, h2_post)
@@ -95,14 +95,14 @@ namespace quickbook
, h5(out, phrase, element_id, doc_id, section_id, qualified_section_id, h5_pre, h5_post)
, h6(out, phrase, element_id, doc_id, section_id, qualified_section_id, h6_pre, h6_post)
, hr(out, hr_)
, blurb(out, temp_para, blurb_pre, blurb_post)
, blockquote(out, temp_para, blockquote_pre, blockquote_post)
, blurb(out, blurb_pre, blurb_post)
, blockquote(out, blockquote_pre, blockquote_post)
, preformatted(out, phrase, preformatted_pre, preformatted_post)
, warning(out, temp_para, warning_pre, warning_post)
, caution(out, temp_para, caution_pre, caution_post)
, important(out, temp_para, important_pre, important_post)
, note(out, temp_para, note_pre, note_post)
, tip(out, temp_para, tip_pre, tip_post)
, warning(out, warning_pre, warning_post)
, caution(out, caution_pre, caution_post)
, important(out, important_pre, important_post)
, note(out, note_pre, note_post)
, tip(out, tip_pre, tip_post)
, plain_char(phrase)
, raw_char(phrase)
, escape_unicode(phrase)
@@ -160,8 +160,7 @@ namespace quickbook
, end_varlistentry(phrase, end_varlistentry_)
, start_varlistterm(phrase, start_varlistterm_)
, end_varlistterm(phrase, end_varlistterm_)
, start_varlistitem(phrase)
, end_varlistitem(phrase, temp_para)
, varlistitem(phrase, start_varlistitem_, end_varlistitem_)
, break_(phrase)
, macro_identifier(*this)
@@ -177,8 +176,7 @@ namespace quickbook
, table(*this)
, start_row(phrase, table_span, table_header)
, end_row(phrase, end_row_)
, start_cell(phrase, table_span)
, end_cell(phrase, temp_para)
, cell(phrase, table_span)
, anchor(out)
, begin_section(out, phrase, doc_id, section_id, section_level, qualified_section_id, element_id)
@@ -209,7 +207,7 @@ namespace quickbook
boost::make_tuple(
filename
, outdir
, macro
, macro_change_depth
, section_level
, min_section_level
, section_id
@@ -220,18 +218,36 @@ namespace quickbook
out.push();
phrase.push();
temp.push();
temp_para.push();
list_buffer.push();
templates.push();
}
// Pushing and popping the macro symbol table is pretty expensive, so
// instead implement a sort of 'stack on write'. Call this whenever a
// change is made to the macro table, and it'll stack the current macros
// if necessary. Would probably be better to implement macros in a less
// expensive manner.
void actions::copy_macros_for_write()
{
if(macro_change_depth != state_stack.size())
{
macro_stack.push(macro);
macro_change_depth = state_stack.size();
}
}
void actions::pop()
{
if(macro_change_depth == state_stack.size())
{
macro = macro_stack.top();
macro_stack.pop();
}
boost::tie(
filename
, outdir
, macro
, macro_change_depth
, section_level
, min_section_level
, section_id
@@ -242,8 +258,6 @@ namespace quickbook
out.pop();
phrase.pop();
temp.pop();
temp_para.pop();
list_buffer.pop();
templates.pop();
}

View File

@@ -33,6 +33,8 @@ namespace quickbook
typedef std::vector<author> author_list;
typedef std::pair<string_list, docinfo_string> copyright_item;
typedef std::vector<copyright_item> copyright_list;
typedef std::pair<std::string, docinfo_string> biblioid_item;
typedef std::vector<biblioid_item> biblioid_list;
typedef std::pair<char, int> mark_type;
static int const max_template_depth = 100;
@@ -48,8 +50,10 @@ namespace quickbook
author_list doc_authors;
docinfo_string doc_license;
docinfo_string doc_last_revision;
biblioid_list doc_biblioid_items;
std::string include_doc_id;
//temporary state
biblioid_item doc_biblioid;
docinfo_string doc_id_tmp;
author name;
copyright_item copyright;
@@ -61,13 +65,12 @@ namespace quickbook
// auxilliary streams
collector phrase;
collector temp;
collector temp_para;
collector list_buffer;
// state
fs::path filename;
fs::path outdir;
std::size_t macro_change_depth;
string_symbols macro;
int section_level;
int min_section_level;
@@ -78,7 +81,7 @@ namespace quickbook
typedef boost::tuple<
fs::path
, fs::path
, string_symbols
, std::size_t
, int
, int
, std::string
@@ -87,6 +90,8 @@ namespace quickbook
state_tuple;
std::stack<state_tuple> state_stack;
// Stack macros separately as copying macros is expensive.
std::stack<string_symbols> macro_stack;
// temporary or global state
std::string element_id;
@@ -111,6 +116,7 @@ namespace quickbook
attribute_map attributes;
// push/pop the states and the streams
void copy_macros_for_write();
void push();
void pop();
@@ -129,18 +135,18 @@ namespace quickbook
phrase_to_docinfo_action extract_name_first;
phrase_to_docinfo_action extract_doc_last_revision;
phrase_to_docinfo_action extract_doc_category;
phrase_to_docinfo_action extract_doc_biblioid;
syntax_highlight syntax_p;
code_action code;
code_action code_block;
inline_code_action inline_code;
implicit_paragraph_action inside_paragraph;
copy_stream_action write_paragraphs;
generic_header_action h;
header_action h1, h2, h3, h4, h5, h6;
markup_action hr;
phrase_action blurb, blockquote, preformatted;
phrase_action warning, caution, important, note, tip;
tagged_action blurb, blockquote;
phrase_action preformatted;
tagged_action warning, caution, important, note, tip;
plain_char_action plain_char;
raw_char_action raw_char;
escape_unicode_action escape_unicode;
@@ -198,8 +204,7 @@ namespace quickbook
markup_action end_varlistentry;
markup_action start_varlistterm;
markup_action end_varlistterm;
start_varlistitem_action start_varlistitem;
end_varlistitem_action end_varlistitem;
tagged_action varlistitem;
break_action break_;
macro_identifier_action macro_identifier;
@@ -215,8 +220,7 @@ namespace quickbook
table_action table;
start_row_action start_row;
markup_action end_row;
start_col_action start_cell;
end_col_action end_cell;
col_action cell;
anchor_action anchor;
begin_section_action begin_section;

View File

@@ -9,9 +9,9 @@
=============================================================================*/
#include "phrase_grammar.hpp"
#include "quickbook.hpp"
#include "utils.hpp"
#include "actions_class.hpp"
#include "scoped_block.hpp"
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_chset.hpp>
#include <boost/spirit/include/classic_assign_actor.hpp>
@@ -21,7 +21,7 @@
namespace quickbook
{
using namespace boost::spirit::classic;
namespace cl = boost::spirit::classic;
template <typename Scanner>
struct block_grammar::definition
@@ -30,7 +30,8 @@ namespace quickbook
bool no_eols;
rule<Scanner> start_, blocks, block_markup, code, code_line, blank_line,
cl::rule<Scanner>
start_, blocks, block_markup, code, code_line, blank_line,
paragraph, space, blank, comment, headings, h, h1, h2,
h3, h4, h5, h6, hr, blurb, blockquote, admonition,
phrase, list, phrase_end, ordered_list, def_macro,
@@ -43,11 +44,11 @@ namespace quickbook
inside_paragraph,
element_id, element_id_1_5, element_id_1_6;
symbols<> paragraph_end_markups;
cl::symbols<> paragraph_end_markups;
phrase_grammar common;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return start_; }
};
@@ -62,7 +63,7 @@ namespace quickbook
if (self.skip_initial_spaces)
{
start_ =
*(blank_p | comment) >> blocks >> blank
*(cl::blank_p | comment) >> blocks >> blank
;
}
else
@@ -79,45 +80,46 @@ namespace quickbook
| hr [actions.hr]
| +eol
| paragraph [actions.inside_paragraph]
[actions.write_paragraphs]
)
;
space =
*(space_p | comment)
*(cl::space_p | comment)
;
blank =
*(blank_p | comment)
*(cl::blank_p | comment)
;
eol = blank >> eol_p
eol = blank >> cl::eol_p
;
phrase_end =
']' |
if_p(var(no_eols))
cl::if_p(var(no_eols))
[
eol >> *blank_p >> eol_p
eol >> *cl::blank_p >> cl::eol_p
// Make sure that we don't go
] // past a single block, except
; // when preformatted.
// Follows after an alphanumeric identifier - ensures that it doesn't
// match an empty space in the middle of the identifier.
hard_space =
(eps_p - (alnum_p | '_')) >> space // must not be preceded by
(cl::eps_p - (cl::alnum_p | '_')) >> space // must not be preceded by
; // alpha-numeric or underscore
comment =
"[/" >> *(dummy_block | (anychar_p - ']')) >> ']'
"[/" >> *(dummy_block | (cl::anychar_p - ']')) >> ']'
;
dummy_block =
'[' >> *(dummy_block | (anychar_p - ']')) >> ']'
'[' >> *(dummy_block | (cl::anychar_p - ']')) >> ']'
;
hr =
str_p("----")
>> *(anychar_p - eol)
cl::str_p("----")
>> *(cl::anychar_p - eol)
>> +eol
;
@@ -139,7 +141,7 @@ namespace quickbook
| template_
)
>> ( (space >> ']' >> +eol)
| eps_p [actions.error]
| cl::eps_p [actions.error]
)
;
@@ -147,29 +149,29 @@ namespace quickbook
':'
>>
(
if_p(qbk_since(105u)) [space]
>> (+(alnum_p | '_')) [assign_a(actions.element_id)]
| eps_p [actions.element_id_warning]
[assign_a(actions.element_id)]
cl::if_p(qbk_since(105u)) [space]
>> (+(cl::alnum_p | '_')) [cl::assign_a(actions.element_id)]
| cl::eps_p [actions.element_id_warning]
[cl::assign_a(actions.element_id)]
)
| eps_p [assign_a(actions.element_id)]
| cl::eps_p [cl::assign_a(actions.element_id)]
;
element_id_1_5 =
if_p(qbk_since(105u)) [
cl::if_p(qbk_since(105u)) [
element_id
]
.else_p [
eps_p [assign_a(actions.element_id)]
cl::eps_p [cl::assign_a(actions.element_id)]
]
;
element_id_1_6 =
if_p(qbk_since(106u)) [
cl::if_p(qbk_since(106u)) [
element_id
]
.else_p [
eps_p [assign_a(actions.element_id)]
cl::eps_p [cl::assign_a(actions.element_id)]
]
;
@@ -182,7 +184,7 @@ namespace quickbook
;
end_section =
str_p("endsect") [actions.end_section]
cl::str_p("endsect") [actions.end_section]
;
headings =
@@ -209,40 +211,46 @@ namespace quickbook
blurb =
"blurb" >> hard_space
>> inside_paragraph [actions.blurb]
>> eps_p
>> scoped_block(actions)[inside_paragraph]
[actions.blurb]
;
blockquote =
':' >> blank >>
inside_paragraph [actions.blockquote]
scoped_block(actions)[inside_paragraph]
[actions.blockquote]
;
admonition =
"warning" >> blank >>
inside_paragraph [actions.warning]
"warning" >> hard_space >>
scoped_block(actions)[inside_paragraph]
[actions.warning]
|
"caution" >> blank >>
inside_paragraph [actions.caution]
"caution" >> hard_space >>
scoped_block(actions)[inside_paragraph]
[actions.caution]
|
"important" >> blank >>
inside_paragraph [actions.important]
"important" >> hard_space >>
scoped_block(actions)[inside_paragraph]
[actions.important]
|
"note" >> blank >>
inside_paragraph [actions.note]
"note" >> hard_space >>
scoped_block(actions)[inside_paragraph]
[actions.note]
|
"tip" >> blank >>
inside_paragraph [actions.tip]
"tip" >> hard_space >>
scoped_block(actions)[inside_paragraph]
[actions.tip]
;
preformatted =
"pre" >> hard_space [assign_a(no_eols, false_)]
"pre" >> hard_space [cl::assign_a(no_eols, false_)]
>> !eol >> phrase [actions.preformatted]
>> eps_p [assign_a(no_eols, true_)]
>> cl::eps_p [cl::assign_a(no_eols, true_)]
;
macro_identifier =
+(anychar_p - (space_p | ']'))
+(cl::anychar_p - (cl::space_p | ']'))
;
def_macro =
@@ -252,142 +260,142 @@ namespace quickbook
;
identifier =
(alpha_p | '_') >> *(alnum_p | '_')
(cl::alpha_p | '_') >> *(cl::alnum_p | '_')
;
template_id =
identifier | (punct_p - (ch_p('[') | ']'))
identifier | (cl::punct_p - (cl::ch_p('[') | ']'))
;
template_ =
"template"
>> hard_space
>> template_id [assign_a(actions.template_identifier)]
[clear_a(actions.template_info)]
>> template_id [cl::assign_a(actions.template_identifier)]
[cl::clear_a(actions.template_info)]
>>
!(
space >> '['
>> *(
space >> template_id [push_back_a(actions.template_info)]
space >> template_id [cl::push_back_a(actions.template_info)]
)
>> space >> ']'
)
>> ( eps_p(*blank_p >> eol_p) [assign_a(actions.template_block, true_)]
| eps_p [assign_a(actions.template_block, false_)]
>> ( cl::eps_p(*cl::blank_p >> cl::eol_p)
[cl::assign_a(actions.template_block, true_)]
| cl::eps_p [cl::assign_a(actions.template_block, false_)]
)
>> template_body [actions.template_body]
;
template_body =
*(('[' >> template_body >> ']') | (anychar_p - ']'))
>> eps_p(space >> ']')
*(('[' >> template_body >> ']') | (cl::anychar_p - ']'))
>> cl::eps_p(space >> ']')
>> space
;
variablelist =
"variablelist"
>> (eps_p(*blank_p >> eol_p) | hard_space)
>> (*(anychar_p - eol)) [assign_a(actions.table_title)]
>> (cl::eps_p(*cl::blank_p >> cl::eol_p) | hard_space)
>> (*(cl::anychar_p - eol)) [cl::assign_a(actions.table_title)]
>> +eol
>> *varlistentry
>> eps_p [actions.variablelist]
>> cl::eps_p [actions.variablelist]
;
varlistentry =
space
>> ch_p('[') [actions.start_varlistentry]
>> cl::ch_p('[') [actions.start_varlistentry]
>>
(
(
varlistterm [actions.start_varlistitem]
>> ( +varlistitem
| eps_p [actions.error]
) [actions.end_varlistitem]
>> ch_p(']') [actions.end_varlistentry]
varlistterm
>> ( scoped_block(actions) [+varlistitem]
[actions.varlistitem]
| cl::eps_p [actions.error]
)
>> cl::ch_p(']') [actions.end_varlistentry]
>> space
)
| eps_p [actions.error]
| cl::eps_p [actions.error]
)
;
varlistterm =
space
>> ch_p('[') [actions.start_varlistterm]
>> cl::ch_p('[') [actions.start_varlistterm]
>>
(
(
phrase
>> ch_p(']') [actions.end_varlistterm]
>> cl::ch_p(']') [actions.end_varlistterm]
>> space
)
| eps_p [actions.error]
| cl::eps_p [actions.error]
)
;
varlistitem =
space
>> ch_p('[')
>> cl::ch_p('[')
>>
(
(
inside_paragraph
>> ch_p(']')
>> cl::ch_p(']')
>> space
)
| eps_p [actions.error]
| cl::eps_p [actions.error]
)
;
table =
"table"
>> (eps_p(*blank_p >> eol_p) | hard_space)
>> (cl::eps_p(*cl::blank_p >> cl::eol_p) | hard_space)
>> element_id_1_5
>> (eps_p(*blank_p >> eol_p) | space)
>> (*(anychar_p - eol)) [assign_a(actions.table_title)]
>> (cl::eps_p(*cl::blank_p >> cl::eol_p) | space)
>> (*(cl::anychar_p - eol)) [cl::assign_a(actions.table_title)]
>> +eol
>> *table_row
>> eps_p [actions.table]
>> cl::eps_p [actions.table]
;
table_row =
space
>> ch_p('[') [actions.start_row]
>> cl::ch_p('[') [actions.start_row]
>>
(
(
*table_cell
>> ch_p(']') [actions.end_row]
>> cl::ch_p(']') [actions.end_row]
>> space
)
| eps_p [actions.error]
| cl::eps_p [actions.error]
)
;
table_cell =
space
>> ch_p('[') [actions.start_cell]
>>
(
(
inside_paragraph
>> ch_p(']') [actions.end_cell]
space
>> cl::ch_p('[')
>> ( scoped_block(actions) [
inside_paragraph
>> cl::ch_p(']')
>> space
] [actions.cell]
| cl::eps_p [actions.error]
)
| eps_p [actions.error]
)
;
xinclude =
"xinclude"
>> hard_space
>> (*(anychar_p -
>> (*(cl::anychar_p -
phrase_end)) [actions.xinclude]
;
import =
"import"
>> hard_space
>> (*(anychar_p -
>> (*(cl::anychar_p -
phrase_end)) [actions.import]
;
@@ -397,10 +405,11 @@ namespace quickbook
>>
!(
':'
>> (*((alnum_p | '_') - space_p))[assign_a(actions.include_doc_id)]
>> (*((cl::alnum_p | '_') - cl::space_p))
[cl::assign_a(actions.include_doc_id)]
>> space
)
>> (*(anychar_p -
>> (*(cl::anychar_p -
phrase_end)) [actions.include]
;
@@ -413,27 +422,27 @@ namespace quickbook
;
code_line =
blank_p >> *(anychar_p - eol_p) >> eol_p
cl::blank_p >> *(cl::anychar_p - cl::eol_p) >> cl::eol_p
;
blank_line =
*blank_p >> eol_p
*cl::blank_p >> cl::eol_p
;
list =
eps_p(ch_p('*') | '#') >>
cl::eps_p(cl::ch_p('*') | '#') >>
+(
(*blank_p
>> (ch_p('*') | '#')) [actions.list_format]
>> *blank_p
(*cl::blank_p
>> (cl::ch_p('*') | '#')) [actions.list_format]
>> *cl::blank_p
>> list_item
) [actions.list_item]
;
list_item =
*( common
| (anychar_p -
( eol_p >> *blank_p >> eps_p(ch_p('*') | '#')
| (cl::anychar_p -
( cl::eol_p >> *cl::blank_p >> cl::eps_p(cl::ch_p('*') | '#')
| (eol >> eol)
)
) [actions.plain_char]
@@ -449,34 +458,30 @@ namespace quickbook
;
paragraph_end =
'[' >> space >> paragraph_end_markups >> hard_space | eol >> *blank_p >> eol_p
'[' >> space >> paragraph_end_markups >> hard_space | eol >> *cl::blank_p >> cl::eol_p
;
paragraph =
+( common
| (anychar_p - // Make sure we don't go past
| (cl::anychar_p - // Make sure we don't go past
paragraph_end // a single block.
) [actions.plain_char]
)
>> (eps_p('[') | +eol)
>> (cl::eps_p('[') | +eol)
;
phrase =
*( common
| comment
| (anychar_p -
| (cl::anychar_p -
phrase_end) [actions.plain_char]
)
;
}
template <typename Iterator, typename Grammar>
parse_info<Iterator> parse(Iterator& first, Iterator last, Grammar& g)
cl::parse_info<iterator> call_parse(
iterator& first, iterator last, block_grammar& g)
{
return boost::spirit::classic::parse(first, last, g);
}
void instantiate_block_grammar(quickbook::iterator i, block_grammar& g) {
parse(i, i, g);
}
}

View File

@@ -6,11 +6,10 @@
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_CODE_SNIPPET_HPP)
#define BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_actor.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include "template_stack.hpp"
@@ -18,7 +17,7 @@
namespace quickbook
{
using namespace boost::spirit::classic;
namespace cl = boost::spirit::classic;
struct code_snippet_actions
{
@@ -69,7 +68,7 @@ namespace quickbook
};
struct python_code_snippet_grammar
: grammar<python_code_snippet_grammar>
: cl::grammar<python_code_snippet_grammar>
{
typedef code_snippet_actions actions_type;
@@ -90,7 +89,7 @@ namespace quickbook
start_ = *code_elements;
identifier =
(alpha_p | '_') >> *(alnum_p | '_')
(cl::alpha_p | '_') >> *(cl::alnum_p | '_')
;
code_elements =
@@ -98,45 +97,55 @@ namespace quickbook
| end_snippet [boost::bind(&actions_type::end_snippet, &actions, _1, _2)]
| escaped_comment
| ignore
| anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
| cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
;
start_snippet =
"#[" >> *space_p
>> identifier [assign_a(actions.id)]
"#[" >> *cl::space_p
>> identifier [cl::assign_a(actions.id)]
;
end_snippet =
str_p("#]")
cl::str_p("#]")
;
ignore =
*blank_p >> "#<-"
>> (*(anychar_p - "#->"))
>> "#->" >> *blank_p >> eol_p
| "\"\"\"<-\"\"\""
>> (*(anychar_p - "\"\"\"->\"\"\""))
>> "\"\"\"->\"\"\""
| "\"\"\"<-"
>> (*(anychar_p - "->\"\"\""))
>> "->\"\"\""
ignore
= cl::confix_p(
*cl::blank_p >> "#<-",
*cl::anychar_p,
"#->" >> *cl::blank_p >> cl::eol_p
)
| cl::confix_p(
"\"\"\"<-\"\"\"",
*cl::anychar_p,
"\"\"\"->\"\"\""
)
| cl::confix_p(
"\"\"\"<-",
*cl::anychar_p,
"->\"\"\""
)
;
escaped_comment =
*space_p >> "#`"
>> ((*(anychar_p - eol_p))
>> eol_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)]
| *space_p >> "\"\"\"`"
>> (*(anychar_p - "\"\"\"")) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)]
>> "\"\"\""
cl::confix_p(
*cl::space_p >> "#`",
(*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)],
cl::eol_p
)
| cl::confix_p(
*cl::space_p >> "\"\"\"`",
(*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)],
"\"\"\""
)
;
}
rule<Scanner>
cl::rule<Scanner>
start_, identifier, code_elements, start_snippet, end_snippet,
escaped_comment, ignore;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return start_; }
};
@@ -144,7 +153,7 @@ namespace quickbook
};
struct cpp_code_snippet_grammar
: grammar<cpp_code_snippet_grammar>
: cl::grammar<cpp_code_snippet_grammar>
{
typedef code_snippet_actions actions_type;
@@ -162,7 +171,7 @@ namespace quickbook
start_ = *code_elements;
identifier =
(alpha_p | '_') >> *(alnum_p | '_')
(cl::alpha_p | '_') >> *(cl::alnum_p | '_')
;
code_elements =
@@ -172,64 +181,78 @@ namespace quickbook
| ignore
| line_callout
| inline_callout
| anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
| cl::anychar_p [boost::bind(&actions_type::pass_thru_char, &actions, _1)]
;
start_snippet =
"//[" >> *space_p
>> identifier [assign_a(actions.id)]
"//[" >> *cl::space_p
>> identifier [cl::assign_a(actions.id)]
|
"/*[" >> *space_p
>> identifier [assign_a(actions.id)]
>> *space_p >> "*/"
"/*[" >> *cl::space_p
>> identifier [cl::assign_a(actions.id)]
>> *cl::space_p >> "*/"
;
end_snippet =
str_p("//]") | "/*]*/"
cl::str_p("//]") | "/*]*/"
;
inline_callout =
"/*<"
>> *space_p
>> (*(anychar_p - ">*/")) [boost::bind(&actions_type::callout, &actions, _1, _2)]
>> ">*/"
inline_callout
= cl::confix_p(
"/*<" >> *cl::space_p,
(*cl::anychar_p) [boost::bind(&actions_type::callout, &actions, _1, _2)],
">*/"
)
;
line_callout
= cl::confix_p(
"/*<<" >> *cl::space_p,
(*cl::anychar_p) [boost::bind(&actions_type::callout, &actions, _1, _2)],
">>*/"
)
>> *cl::space_p
;
line_callout =
"/*<<"
>> *space_p
>> (*(anychar_p - ">>*/")) [boost::bind(&actions_type::callout, &actions, _1, _2)]
>> ">>*/"
>> *space_p
ignore
= cl::confix_p(
*cl::blank_p >> "//<-",
*cl::anychar_p,
"//->"
)
>> *cl::blank_p
>> cl::eol_p
| cl::confix_p(
"/*<-*/",
*cl::anychar_p,
"/*->*/"
)
| cl::confix_p(
"/*<-",
*cl::anychar_p,
"->*/"
)
;
ignore =
*blank_p >> "//<-"
>> (*(anychar_p - "//->"))
>> "//->" >> *blank_p >> eol_p
| "/*<-*/"
>> (*(anychar_p - "/*->*/"))
>> "/*->*/"
| "/*<-"
>> (*(anychar_p - "->*/"))
>> "->*/"
;
escaped_comment =
*space_p >> "//`"
>> ((*(anychar_p - eol_p))
>> eol_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)]
| *space_p >> "/*`"
>> (*(anychar_p - "*/")) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)]
>> "*/"
escaped_comment
= cl::confix_p(
*cl::space_p >> "//`",
(*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)],
cl::eol_p
)
| cl::confix_p(
*cl::space_p >> "/*`",
(*cl::anychar_p) [boost::bind(&actions_type::escaped_comment, &actions, _1, _2)],
"*/"
)
;
}
rule<Scanner>
start_, identifier, code_elements, start_snippet, end_snippet,
cl::rule<Scanner>
start_, identifier, code_elements, start_snippet, end_snippet,
escaped_comment, inline_callout, line_callout, ignore;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return start_; }
};
@@ -248,9 +271,8 @@ namespace quickbook
if (err != 0)
return err; // return early on error
typedef position_iterator<std::string::const_iterator> iterator_type;
iterator_type first(code.begin(), code.end(), file);
iterator_type last(code.end(), code.end());
iterator first(code.begin(), code.end(), file.c_str());
iterator last(code.end(), code.end());
size_t fname_len = file.size();
bool is_python = fname_len >= 3
@@ -406,6 +428,3 @@ namespace quickbook
}
}
}
#endif // BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP

View File

@@ -31,7 +31,7 @@ namespace quickbook
// *before* anything else.
if (!actions.doc_id_tmp.empty())
actions.doc_id = actions.doc_id_tmp.get(103);
actions.doc_id = actions.doc_id_tmp.get(106);
if (actions.doc_id.empty())
actions.doc_id = detail::make_identifier(
@@ -145,18 +145,18 @@ namespace quickbook
if(actions.doc_type == "library")
{
out << " name=\"" << actions.doc_title.get(103) << "\"\n";
out << " name=\"" << actions.doc_title.get(106) << "\"\n";
}
if(!actions.doc_dirname.empty())
{
out << " dirname=\""
<< actions.doc_dirname.get(103)
<< actions.doc_dirname.get(106)
<< "\"\n";
}
out << " last-revision=\""
<< actions.doc_last_revision.get(103)
<< actions.doc_last_revision.get(106)
<< "\" \n"
<< " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n";
@@ -188,9 +188,9 @@ namespace quickbook
if (!actions.doc_title.empty())
{
out << " <title>"
<< actions.doc_title.get(103);
<< actions.doc_title.get(106);
if (!actions.doc_version.empty()) {
out << ' ' << actions.doc_version.get(103);
out << ' ' << actions.doc_version.get(106);
}
out<< "</title>\n\n\n";
}
@@ -210,10 +210,10 @@ namespace quickbook
{
tmp << " <author>\n"
<< " <firstname>"
<< it->first.get(103)
<< it->first.get(106)
<< "</firstname>\n"
<< " <surname>"
<< it->second.get(103)
<< it->second.get(106)
<< "</surname>\n"
<< " </author>\n";
}
@@ -238,7 +238,7 @@ namespace quickbook
}
tmp << " <holder>"
<< it->second.get(103)
<< it->second.get(106)
<< "</holder>\n"
<< " </copyright>\n"
<< "\n"
@@ -274,13 +274,27 @@ namespace quickbook
it != end; ++it)
{
tmp << " <" << actions.doc_type << "category name=\"category:"
<< it->get(103)
<< it->get(106)
<< "\"></" << actions.doc_type << "category>\n"
<< "\n"
;
}
}
for (actions::biblioid_list::const_iterator
it = actions.doc_biblioid_items.begin(),
end = actions.doc_biblioid_items.end();
it != end; ++it)
{
tmp << " <biblioid class=\""
<< it->first
<< "\">"
<< it->second.get(103)
<< "</biblioid>"
<< "\n"
;
}
std::string value = tmp.str();
if(!value.empty())
{
@@ -291,4 +305,4 @@ namespace quickbook
;
}
}
}
}

View File

@@ -9,7 +9,6 @@
=============================================================================*/
#include "phrase_grammar.hpp"
#include "quickbook.hpp"
#include "actions_class.hpp"
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_actor.hpp>
@@ -19,26 +18,27 @@
namespace quickbook
{
using namespace boost::spirit::classic;
namespace cl = boost::spirit::classic;
template <typename Scanner>
struct doc_info_grammar::definition
{
definition(doc_info_grammar const&);
typedef uint_parser<int, 10, 1, 2> uint2_t;
typedef cl::uint_parser<int, 10, 1, 2> uint2_t;
bool unused;
std::string category;
rule<Scanner> doc_info, doc_title, doc_version, doc_id, doc_dirname,
cl::rule<Scanner>
doc_info, doc_title, doc_version, doc_id, doc_dirname,
doc_copyright, doc_purpose, doc_category, doc_authors,
doc_author, comment, space, hard_space, doc_license,
doc_last_revision, doc_source_mode, phrase, quickbook_version,
char_;
doc_last_revision, doc_source_mode, doc_biblioid,
phrase, quickbook_version, char_;
phrase_grammar common;
symbols<> doc_types;
cl::symbols<> doc_types;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return doc_info; }
};
@@ -57,9 +57,9 @@ namespace quickbook
doc_info =
space
>> '[' >> space
>> (doc_types >> eps_p) [assign_a(actions.doc_type)]
>> (doc_types >> cl::eps_p) [cl::assign_a(actions.doc_type)]
>> hard_space
>> ( *(~eps_p(ch_p('[') | ']' | eol_p) >> char_)
>> ( *(~cl::eps_p(cl::ch_p('[') | ']' | cl::eol_p) >> char_)
) [actions.extract_doc_title]
>> !(
space >> '[' >>
@@ -73,51 +73,57 @@ namespace quickbook
doc_version
| doc_id
| doc_dirname
| doc_copyright [push_back_a(actions.doc_copyrights, actions.copyright)]
| doc_copyright [cl::push_back_a(actions.doc_copyrights, actions.copyright)]
| doc_purpose
| doc_category
| doc_authors
| doc_license
| doc_last_revision
| doc_source_mode
| doc_biblioid
)
>> space >> ']' >> +eol_p
>> space >> ']' >> +cl::eol_p
)
>> space >> ']' >> +eol_p
>> space >> ']' >> +cl::eol_p
;
quickbook_version =
"quickbook" >> hard_space
>> ( uint_p [assign_a(qbk_major_version)]
>> ( cl::uint_p [cl::assign_a(qbk_major_version)]
>> '.'
>> uint2_t() [assign_a(qbk_minor_version)]
>> uint2_t() [cl::assign_a(qbk_minor_version)]
)
;
doc_version =
"version" >> hard_space
>> (*(~eps_p(']') >> char_)) [actions.extract_doc_version]
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_doc_version]
;
// TODO: Restrictions on doc_id?
doc_id =
"id" >> hard_space
>> (*(~eps_p(']') >> char_)) [actions.extract_doc_id]
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_doc_id]
;
// TODO: Restrictions on doc_dirname?
doc_dirname =
"dirname" >> hard_space
>> (*(~eps_p(']') >> char_)) [actions.extract_doc_dirname]
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_doc_dirname]
;
doc_copyright =
"copyright" >> hard_space [clear_a(actions.copyright.first)]
>> +( repeat_p(4)[digit_p] [push_back_a(actions.copyright.first)]
"copyright" >> hard_space [cl::clear_a(actions.copyright.first)]
>> +( cl::repeat_p(4)[cl::digit_p]
[cl::push_back_a(actions.copyright.first)]
>> space
)
>> space
>> (*(~eps_p(']') >> char_)) [actions.extract_copyright_second]
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_copyright_second]
;
doc_purpose =
@@ -127,25 +133,28 @@ namespace quickbook
doc_category =
"category" >> hard_space
>> (*(~eps_p(']') >> char_)) [actions.extract_doc_category]
[push_back_a(actions.doc_categories, actions.doc_category)]
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_doc_category]
[cl::push_back_a(actions.doc_categories, actions.doc_category)]
;
doc_author =
'[' >> space
>> (*(~eps_p(',') >> char_)) [actions.extract_name_second] // surname
>> (*(~cl::eps_p(',') >> char_))
[actions.extract_name_second]
>> ',' >> space
>> (*(~eps_p(']') >> char_)) [actions.extract_name_first] // firstname
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_name_first]
>> ']'
;
doc_authors =
"authors"
>> hard_space
>> doc_author [push_back_a(actions.doc_authors, actions.name)]
>> doc_author [cl::push_back_a(actions.doc_authors, actions.name)]
>> space
>> *( !(ch_p(',') >> space)
>> doc_author [push_back_a(actions.doc_authors, actions.name)]
>> *( !(cl::ch_p(',') >> space)
>> doc_author [cl::push_back_a(actions.doc_authors, actions.name)]
>> space
)
;
@@ -157,61 +166,70 @@ namespace quickbook
doc_last_revision =
"last-revision" >> hard_space
>> (*(~eps_p(']') >> char_)) [actions.extract_doc_last_revision]
>> (*(~cl::eps_p(']') >> char_))
[actions.extract_doc_last_revision]
;
doc_source_mode =
"source-mode" >> hard_space
>> (
str_p("c++")
cl::str_p("c++")
| "python"
| "teletype"
) [assign_a(actions.source_mode)]
) [cl::assign_a(actions.source_mode)]
;
doc_biblioid =
"biblioid"
>> hard_space
>> (+cl::alnum_p) [cl::assign_a(actions.doc_biblioid.first)]
>> hard_space
>> (+(~cl::eps_p(']') >> char_))
[actions.extract_doc_biblioid]
[cl::push_back_a(actions.doc_biblioid_items, actions.doc_biblioid)]
;
comment =
"[/" >> *(anychar_p - ']') >> ']'
"[/" >> *(cl::anychar_p - ']') >> ']'
;
space =
*(space_p | comment)
*(cl::space_p | comment)
;
hard_space =
(eps_p - (alnum_p | '_')) >> space // must not be preceded by
(cl::eps_p - (cl::alnum_p | '_')) >> space // must not be preceded by
; // alpha-numeric or underscore
phrase =
*( common
| comment
| (anychar_p - ']') [actions.plain_char]
| (cl::anychar_p - ']') [actions.plain_char]
)
;
char_ =
str_p("\\n") [actions.break_]
cl::str_p("\\n") [actions.break_]
| "\\ " // ignore an escaped space
| '\\' >> punct_p [actions.raw_char]
| "\\u" >> repeat_p(4) [chset<>("0-9a-fA-F")]
| '\\' >> cl::punct_p [actions.raw_char]
| "\\u" >> cl::repeat_p(4)
[cl::chset<>("0-9a-fA-F")]
[actions.escape_unicode]
| "\\U" >> repeat_p(8) [chset<>("0-9a-fA-F")]
| "\\U" >> cl::repeat_p(8)
[cl::chset<>("0-9a-fA-F")]
[actions.escape_unicode]
| (
("'''" >> !eol_p) [actions.escape_pre]
>> *(anychar_p - "'''") [actions.raw_char]
>> str_p("'''") [actions.escape_post]
("'''" >> !cl::eol_p) [actions.escape_pre]
>> *(cl::anychar_p - "'''")[actions.raw_char]
>> cl::str_p("'''") [actions.escape_post]
)
| anychar_p [actions.plain_char]
| cl::anychar_p [actions.plain_char]
;
}
template <typename Iterator, typename Grammar>
parse_info<Iterator> parse(Iterator& first, Iterator last, Grammar& g)
cl::parse_info<iterator> call_parse(
iterator& first, iterator last, doc_info_grammar& g)
{
return boost::spirit::classic::parse(first, last, g);
}
void instantiate_doc_info_grammar(quickbook::iterator i, doc_info_grammar& g) {
parse(i, i, g);
}
}

27
src/fwd.hpp Normal file
View File

@@ -0,0 +1,27 @@
/*=============================================================================
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_FWD_HPP)
#define BOOST_SPIRIT_FWD_HPP
#include <boost/spirit/include/classic_iterator.hpp>
#include <boost/range.hpp>
#include <boost/shared_ptr.hpp>
namespace quickbook
{
struct actions;
typedef boost::spirit::classic::file_position_base<char const*> position;
typedef boost::spirit::classic::position_iterator<
std::string::const_iterator, position> iterator;
}
#endif

View File

@@ -11,7 +11,7 @@
#define BOOST_SPIRIT_QUICKBOOK_GRAMMARS_HPP
#include <boost/spirit/include/classic_core.hpp>
#include "actions.hpp"
#include "fwd.hpp"
namespace quickbook
{
@@ -41,7 +41,8 @@ namespace quickbook
bool const skip_initial_spaces;
};
struct phrase_grammar : cl::grammar<phrase_grammar>
struct phrase_grammar
: cl::grammar<phrase_grammar>
{
phrase_grammar(quickbook::actions& actions, bool& no_eols)
: no_eols(no_eols), actions(actions) {}
@@ -53,7 +54,8 @@ namespace quickbook
quickbook::actions& actions;
};
struct simple_phrase_grammar : public cl::grammar<simple_phrase_grammar >
struct simple_phrase_grammar
: public cl::grammar<simple_phrase_grammar >
{
simple_phrase_grammar(quickbook::actions& actions)
: actions(actions) {}
@@ -76,8 +78,16 @@ namespace quickbook
quickbook::actions& actions;
};
template <typename Iterator, typename Grammar>
cl::parse_info<Iterator> parse(Iterator&, Iterator, Grammar&);
cl::parse_info<iterator> call_parse(
iterator&, iterator, doc_info_grammar&);
cl::parse_info<iterator> call_parse(
iterator&, iterator, block_grammar&);
cl::parse_info<iterator> call_parse(
iterator&, iterator, phrase_grammar&);
cl::parse_info<iterator> call_parse(
iterator&, iterator, simple_phrase_grammar&);
cl::parse_info<iterator> call_parse(
iterator&, iterator, command_line_grammar&);
}
#endif

View File

@@ -9,459 +9,9 @@
=============================================================================*/
#include "phrase_grammar.hpp"
#include "quickbook.hpp"
#include "actions_class.hpp"
#include "utils.hpp"
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_chset.hpp>
#include <boost/spirit/include/classic_assign_actor.hpp>
#include <boost/spirit/include/classic_clear_actor.hpp>
#include <boost/spirit/include/classic_if.hpp>
#include <boost/spirit/include/classic_loops.hpp>
namespace quickbook
{
using namespace boost::spirit::classic;
template <typename Rule, typename Action>
inline void
simple_markup(
Rule& simple
, char mark
, Action const& action
, Rule const& close
)
{
simple =
mark >>
(
(
graph_p // A single char. e.g. *c*
>> eps_p(mark
>> (space_p | punct_p | end_p))
// space_p, punct_p or end_p
) // must follow mark
|
( graph_p >> // graph_p must follow mark
*(anychar_p -
( (graph_p >> mark) // Make sure that we don't go
| close // past a single block
)
) >> graph_p // graph_p must precede mark
>> eps_p(mark
>> (space_p | punct_p | end_p))
// space_p, punct_p or end_p
) // must follow mark
) [action]
>> mark
;
}
template <typename Scanner>
phrase_grammar::definition<Scanner>::definition(phrase_grammar const& self)
{
using detail::var;
quickbook::actions& actions = self.actions;
space =
*(space_p | comment)
;
blank =
*(blank_p | comment)
;
eol = blank >> eol_p
;
phrase_end =
']' |
if_p(var(self.no_eols))
[
eol >> eol // Make sure that we don't go
] // past a single block, except
; // when preformatted.
hard_space =
(eps_p - (alnum_p | '_')) >> space // must not be preceded by
; // alpha-numeric or underscore
comment =
"[/" >> *(dummy_block | (anychar_p - ']')) >> ']'
;
dummy_block =
'[' >> *(dummy_block | (anychar_p - ']')) >> ']'
;
common =
macro
| phrase_markup
| code_block
| inline_code
| simple_format
| escape
| comment
;
macro =
eps_p(actions.macro // must not be followed by
>> (eps_p - (alpha_p | '_'))) // alpha or underscore
>> actions.macro [actions.do_macro]
;
static const bool true_ = true;
static const bool false_ = false;
template_ =
(
ch_p('`') [assign_a(actions.template_escape,true_)]
|
eps_p [assign_a(actions.template_escape,false_)]
)
>>
( (
(eps_p(punct_p)
>> actions.templates.scope
) [assign_a(actions.template_identifier)]
[clear_a(actions.template_args)]
>> !template_args
) | (
(actions.templates.scope
>> eps_p(hard_space)
) [assign_a(actions.template_identifier)]
[clear_a(actions.template_args)]
>> space
>> !template_args
) )
>> eps_p(']')
;
template_args =
if_p(qbk_since(105u)) [
template_args_1_5
].else_p [
template_args_1_4
]
;
template_args_1_4 = template_arg_1_4 >> *(".." >> template_arg_1_4);
template_arg_1_4 =
( eps_p(*blank_p >> eol_p) [assign_a(actions.template_block, true_)]
| eps_p [assign_a(actions.template_block, false_)]
)
>> template_inner_arg_1_4 [actions.template_arg]
;
template_inner_arg_1_4 =
+(brackets_1_4 | (anychar_p - (str_p("..") | ']')))
;
brackets_1_4 =
'[' >> template_inner_arg_1_4 >> ']'
;
template_args_1_5 = template_arg_1_5 >> *(".." >> template_arg_1_5);
template_arg_1_5 =
( eps_p(*blank_p >> eol_p) [assign_a(actions.template_block, true_)]
| eps_p [assign_a(actions.template_block, false_)]
)
>> (+(brackets_1_5 | ('\\' >> anychar_p) | (anychar_p - (str_p("..") | '[' | ']'))))
[actions.template_arg]
;
template_inner_arg_1_5 =
+(brackets_1_5 | ('\\' >> anychar_p) | (anychar_p - (str_p('[') | ']')))
;
brackets_1_5 =
'[' >> template_inner_arg_1_5 >> ']'
;
inline_code =
'`' >>
(
*(anychar_p -
( '`'
| (eol >> eol) // Make sure that we don't go
) // past a single block
) >> eps_p('`')
) [actions.inline_code]
>> '`'
;
code_block =
(
"```" >>
(
*(anychar_p - "```")
>> eps_p("```")
) [actions.code_block]
>> "```"
)
| (
"``" >>
(
*(anychar_p - "``")
>> eps_p("``")
) [actions.code_block]
>> "``"
)
;
simple_format =
simple_bold
| simple_italic
| simple_underline
| simple_teletype
;
simple_phrase_end = '[' | phrase_end;
simple_markup(simple_bold,
'*', actions.simple_bold, simple_phrase_end);
simple_markup(simple_italic,
'/', actions.simple_italic, simple_phrase_end);
simple_markup(simple_underline,
'_', actions.simple_underline, simple_phrase_end);
simple_markup(simple_teletype,
'=', actions.simple_teletype, simple_phrase_end);
phrase =
*( common
| comment
| (anychar_p - phrase_end) [actions.plain_char]
)
;
phrase_markup =
'['
>> ( cond_phrase
| image
| url
| link
| anchor
| source_mode
| funcref
| classref
| memberref
| enumref
| macroref
| headerref
| conceptref
| globalref
| bold
| italic
| underline
| teletype
| strikethrough
| quote
| replaceable
| footnote
| template_ [actions.do_template]
| str_p("br") [actions.break_]
)
>> ']'
;
escape =
str_p("\\ ") // ignore an escaped space
| '\\' >> punct_p [actions.raw_char]
| "\\u" >> repeat_p(4) [chset<>("0-9a-fA-F")]
[actions.escape_unicode]
| "\\U" >> repeat_p(8) [chset<>("0-9a-fA-F")]
[actions.escape_unicode]
| (
("'''" >> !eol) [actions.escape_pre]
>> *(anychar_p - "'''") [actions.raw_char]
>> str_p("'''") [actions.escape_post]
)
;
macro_identifier =
+(anychar_p - (space_p | ']'))
;
cond_phrase =
'?' >> blank
>> macro_identifier [actions.cond_phrase_pre]
>> (!phrase) [actions.cond_phrase_post]
;
image =
'$' >> blank [clear_a(actions.attributes)]
>> if_p(qbk_since(105u)) [
(+(
*space_p
>> +(anychar_p - (space_p | phrase_end | '['))
)) [assign_a(actions.image_fileref)]
>> hard_space
>> *(
'['
>> (*(alnum_p | '_')) [assign_a(actions.attribute_name)]
>> space
>> (*(anychar_p - (phrase_end | '[')))
[actions.attribute]
>> ']'
>> space
)
].else_p [
(*(anychar_p -
phrase_end)) [assign_a(actions.image_fileref)]
]
>> eps_p(']') [actions.image]
;
url =
'@'
>> (*(anychar_p -
(']' | hard_space))) [actions.url_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.url_post]
;
link =
"link" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.link_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.link_post]
;
anchor =
'#'
>> blank
>> ( *(anychar_p -
phrase_end)
) [actions.anchor]
;
funcref =
"funcref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.funcref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.funcref_post]
;
classref =
"classref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.classref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.classref_post]
;
memberref =
"memberref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.memberref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.memberref_post]
;
enumref =
"enumref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.enumref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.enumref_post]
;
macroref =
"macroref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.macroref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.macroref_post]
;
headerref =
"headerref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.headerref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.headerref_post]
;
conceptref =
"conceptref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.conceptref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.conceptref_post]
;
globalref =
"globalref" >> hard_space
>> (*(anychar_p -
(']' | hard_space))) [actions.globalref_pre]
>> ( eps_p(']')
| (hard_space >> phrase)
) [actions.globalref_post]
;
bold =
ch_p('*') [actions.bold_pre]
>> blank >> phrase [actions.bold_post]
;
italic =
ch_p('\'') [actions.italic_pre]
>> blank >> phrase [actions.italic_post]
;
underline =
ch_p('_') [actions.underline_pre]
>> blank >> phrase [actions.underline_post]
;
teletype =
ch_p('^') [actions.teletype_pre]
>> blank >> phrase [actions.teletype_post]
;
strikethrough =
ch_p('-') [actions.strikethrough_pre]
>> blank >> phrase [actions.strikethrough_post]
;
quote =
ch_p('"') [actions.quote_pre]
>> blank >> phrase [actions.quote_post]
;
replaceable =
ch_p('~') [actions.replaceable_pre]
>> blank >> phrase [actions.replaceable_post]
;
source_mode =
(
str_p("c++")
| "python"
| "teletype"
) [assign_a(actions.source_mode)]
;
footnote =
str_p("footnote") [actions.footnote_pre]
>> blank >> phrase [actions.footnote_post]
;
}
template <typename Scanner>
struct simple_phrase_grammar::definition
{
@@ -473,24 +23,24 @@ namespace quickbook
phrase =
*( common
| comment
| (anychar_p - ']') [actions.plain_char]
| (cl::anychar_p - ']') [actions.plain_char]
)
;
comment =
"[/" >> *(dummy_block | (anychar_p - ']')) >> ']'
"[/" >> *(dummy_block | (cl::anychar_p - ']')) >> ']'
;
dummy_block =
'[' >> *(dummy_block | (anychar_p - ']')) >> ']'
'[' >> *(dummy_block | (cl::anychar_p - ']')) >> ']'
;
}
bool unused;
rule<Scanner> phrase, comment, dummy_block;
cl::rule<Scanner> phrase, comment, dummy_block;
phrase_grammar common;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return phrase; }
};
@@ -503,51 +53,51 @@ namespace quickbook
quickbook::actions& actions = self.actions;
macro =
*space_p
*cl::space_p
>> macro_identifier [actions.macro_identifier]
>> *space_p
>> *cl::space_p
>> ( '='
>> *space_p
>> *cl::space_p
>> phrase [actions.macro_definition]
>> *space_p
>> *cl::space_p
)
| eps_p [actions.macro_definition]
| cl::eps_p [actions.macro_definition]
;
macro_identifier =
+(anychar_p - (space_p | ']' | '='))
+(cl::anychar_p - (cl::space_p | ']' | '='))
;
phrase =
*( common
| (anychar_p - ']') [actions.plain_char]
| (cl::anychar_p - ']') [actions.plain_char]
)
;
}
bool unused;
rule<Scanner> macro, macro_identifier, phrase;
cl::rule<Scanner> macro, macro_identifier, phrase;
phrase_grammar common;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return macro; }
};
template <typename Iterator, typename Grammar>
parse_info<Iterator> parse(Iterator& first, Iterator last, Grammar& g)
cl::parse_info<iterator> call_parse(
iterator& first, iterator last, phrase_grammar& g)
{
return boost::spirit::classic::parse(first, last, g);
}
void instantiate_phrase_grammar(quickbook::iterator i, phrase_grammar& g) {
parse(i, i, g);
cl::parse_info<iterator> call_parse(
iterator& first, iterator last, simple_phrase_grammar& g)
{
return boost::spirit::classic::parse(first, last, g);
}
void instantiate_simple_phrase_grammar(quickbook::iterator i, simple_phrase_grammar& g) {
parse(i, i, g);
}
void instantiate_command_line_grammar(quickbook::iterator i, command_line_grammar& g) {
parse(i, i, g);
cl::parse_info<iterator> call_parse(
iterator& first, iterator last, command_line_grammar& g)
{
return boost::spirit::classic::parse(first, last, g);
}
}

View File

@@ -11,11 +11,54 @@
#define BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP
#include "grammar.hpp"
#include "actions_class.hpp"
#include "utils.hpp"
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_chset.hpp>
#include <boost/spirit/include/classic_assign_actor.hpp>
#include <boost/spirit/include/classic_clear_actor.hpp>
#include <boost/spirit/include/classic_if.hpp>
#include <boost/spirit/include/classic_loops.hpp>
namespace quickbook
{
namespace cl = boost::spirit::classic;
template <typename Rule, typename Action>
inline void
simple_markup(
Rule& simple
, char mark
, Action const& action
, Rule const& close
)
{
simple =
mark >>
(
(
cl::graph_p // A single char. e.g. *c*
>> cl::eps_p(mark
>> (cl::space_p | cl::punct_p | cl::end_p))
// space_p, punct_p or end_p
) // must follow mark
|
( cl::graph_p >> // graph_p must follow mark
*(cl::anychar_p -
( (cl::graph_p >> mark) // Make sure that we don't go
| close // past a single block
)
) >> cl::graph_p // graph_p must precede mark
>> cl::eps_p(mark
>> (cl::space_p | cl::punct_p | cl::end_p))
// space_p, punct_p or end_p
) // must follow mark
) [action]
>> mark
;
}
template <typename Scanner>
struct phrase_grammar::definition
{
@@ -40,6 +83,402 @@ namespace quickbook
cl::rule<Scanner> const&
start() const { return common; }
};
template <typename Scanner>
phrase_grammar::definition<Scanner>::definition(phrase_grammar const& self)
{
using detail::var;
quickbook::actions& actions = self.actions;
space =
*(cl::space_p | comment)
;
blank =
*(cl::blank_p | comment)
;
eol = blank >> cl::eol_p
;
phrase_end =
']' |
cl::if_p(var(self.no_eols))
[
eol >> eol // Make sure that we don't go
] // past a single block, except
; // when preformatted.
// Follows an alphanumeric identifier - ensures that it doesn't
// match an empty space in the middle of the identifier.
hard_space =
(cl::eps_p - (cl::alnum_p | '_')) >> space
;
comment =
"[/" >> *(dummy_block | (cl::anychar_p - ']')) >> ']'
;
dummy_block =
'[' >> *(dummy_block | (cl::anychar_p - ']')) >> ']'
;
common =
macro
| phrase_markup
| code_block
| inline_code
| simple_format
| escape
| comment
;
macro =
// must not be followed by alpha or underscore
cl::eps_p(actions.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
>> actions.macro [actions.do_macro]
;
static const bool true_ = true;
static const bool false_ = false;
template_ =
(
cl::ch_p('`') [cl::assign_a(actions.template_escape,true_)]
|
cl::eps_p [cl::assign_a(actions.template_escape,false_)]
)
>>
( (
(cl::eps_p(cl::punct_p)
>> actions.templates.scope
) [cl::assign_a(actions.template_identifier)]
[cl::clear_a(actions.template_args)]
>> !template_args
) | (
(actions.templates.scope
>> cl::eps_p(hard_space)
) [cl::assign_a(actions.template_identifier)]
[cl::clear_a(actions.template_args)]
>> space
>> !template_args
) )
>> cl::eps_p(']')
;
template_args =
cl::if_p(qbk_since(105u)) [
template_args_1_5
].else_p [
template_args_1_4
]
;
template_args_1_4 = template_arg_1_4 >> *(".." >> template_arg_1_4);
template_arg_1_4 =
( cl::eps_p(*cl::blank_p >> cl::eol_p)
[cl::assign_a(actions.template_block, true_)]
| cl::eps_p [cl::assign_a(actions.template_block, false_)]
)
>> template_inner_arg_1_4 [actions.template_arg]
;
template_inner_arg_1_4 =
+(brackets_1_4 | (cl::anychar_p - (cl::str_p("..") | ']')))
;
brackets_1_4 =
'[' >> template_inner_arg_1_4 >> ']'
;
template_args_1_5 = template_arg_1_5 >> *(".." >> template_arg_1_5);
template_arg_1_5 =
( cl::eps_p(*cl::blank_p >> cl::eol_p)
[cl::assign_a(actions.template_block, true_)]
| cl::eps_p [cl::assign_a(actions.template_block, false_)]
)
>> (+(brackets_1_5 | ('\\' >> cl::anychar_p) | (cl::anychar_p - (cl::str_p("..") | '[' | ']'))))
[actions.template_arg]
;
template_inner_arg_1_5 =
+(brackets_1_5 | ('\\' >> cl::anychar_p) | (cl::anychar_p - (cl::str_p('[') | ']')))
;
brackets_1_5 =
'[' >> template_inner_arg_1_5 >> ']'
;
inline_code =
'`' >>
(
*(cl::anychar_p -
( '`'
| (eol >> eol) // Make sure that we don't go
) // past a single block
) >> cl::eps_p('`')
) [actions.inline_code]
>> '`'
;
code_block =
(
"```" >>
(
*(cl::anychar_p - "```")
>> cl::eps_p("```")
) [actions.code_block]
>> "```"
)
| (
"``" >>
(
*(cl::anychar_p - "``")
>> cl::eps_p("``")
) [actions.code_block]
>> "``"
)
;
simple_format =
simple_bold
| simple_italic
| simple_underline
| simple_teletype
;
simple_phrase_end = '[' | phrase_end;
simple_markup(simple_bold,
'*', actions.simple_bold, simple_phrase_end);
simple_markup(simple_italic,
'/', actions.simple_italic, simple_phrase_end);
simple_markup(simple_underline,
'_', actions.simple_underline, simple_phrase_end);
simple_markup(simple_teletype,
'=', actions.simple_teletype, simple_phrase_end);
phrase =
*( common
| comment
| (cl::anychar_p - phrase_end) [actions.plain_char]
)
;
phrase_markup =
'['
>> ( cond_phrase
| image
| url
| link
| anchor
| source_mode
| funcref
| classref
| memberref
| enumref
| macroref
| headerref
| conceptref
| globalref
| bold
| italic
| underline
| teletype
| strikethrough
| quote
| replaceable
| footnote
| template_ [actions.do_template]
| cl::str_p("br") [actions.break_]
)
>> ']'
;
escape =
cl::str_p("\\ ") // ignore an escaped space
| '\\' >> cl::punct_p [actions.raw_char]
| "\\u" >> cl::repeat_p(4) [cl::chset<>("0-9a-fA-F")]
[actions.escape_unicode]
| "\\U" >> cl::repeat_p(8) [cl::chset<>("0-9a-fA-F")]
[actions.escape_unicode]
| (
("'''" >> !eol) [actions.escape_pre]
>> *(cl::anychar_p - "'''") [actions.raw_char]
>> cl::str_p("'''") [actions.escape_post]
)
;
macro_identifier =
+(cl::anychar_p - (cl::space_p | ']'))
;
cond_phrase =
'?' >> blank
>> macro_identifier [actions.cond_phrase_pre]
>> (!phrase) [actions.cond_phrase_post]
;
image =
'$' >> blank [cl::clear_a(actions.attributes)]
>> cl::if_p(qbk_since(105u)) [
(+(
*cl::space_p
>> +(cl::anychar_p - (cl::space_p | phrase_end | '['))
)) [cl::assign_a(actions.image_fileref)]
>> hard_space
>> *(
'['
>> (*(cl::alnum_p | '_')) [cl::assign_a(actions.attribute_name)]
>> space
>> (*(cl::anychar_p - (phrase_end | '[')))
[actions.attribute]
>> ']'
>> space
)
].else_p [
(*(cl::anychar_p - phrase_end))
[cl::assign_a(actions.image_fileref)]
]
>> cl::eps_p(']') [actions.image]
;
url =
'@'
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.url_pre]
>> hard_space
>> phrase [actions.url_post]
;
link =
"link" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.link_pre]
>> hard_space
>> phrase [actions.link_post]
;
anchor =
blank
>> (*(cl::anychar_p - phrase_end)) [actions.anchor]
;
funcref =
"funcref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.funcref_pre]
>> hard_space
>> phrase [actions.funcref_post]
;
classref =
"classref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.classref_pre]
>> hard_space
>> phrase [actions.classref_post]
;
memberref =
"memberref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.memberref_pre]
>> hard_space
>> phrase [actions.memberref_post]
;
enumref =
"enumref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.enumref_pre]
>> hard_space
>> phrase [actions.enumref_post]
;
macroref =
"macroref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.macroref_pre]
>> hard_space
>> phrase [actions.macroref_post]
;
headerref =
"headerref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.headerref_pre]
>> hard_space
>> phrase [actions.headerref_post]
;
conceptref =
"conceptref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.conceptref_pre]
>> hard_space
>> phrase [actions.conceptref_post]
;
globalref =
"globalref" >> hard_space
>> (*(cl::anychar_p -
(']' | hard_space))) [actions.globalref_pre]
>> hard_space
>> phrase [actions.globalref_post]
;
bold =
cl::ch_p('*') [actions.bold_pre]
>> blank >> phrase [actions.bold_post]
;
italic =
cl::ch_p('\'') [actions.italic_pre]
>> blank >> phrase [actions.italic_post]
;
underline =
cl::ch_p('_') [actions.underline_pre]
>> blank >> phrase [actions.underline_post]
;
teletype =
cl::ch_p('^') [actions.teletype_pre]
>> blank >> phrase [actions.teletype_post]
;
strikethrough =
cl::ch_p('-') [actions.strikethrough_pre]
>> blank >> phrase [actions.strikethrough_post]
;
quote =
cl::ch_p('"') [actions.quote_pre]
>> blank >> phrase [actions.quote_post]
;
replaceable =
cl::ch_p('~') [actions.replaceable_pre]
>> blank >> phrase [actions.replaceable_post]
;
source_mode =
(
cl::str_p("c++")
| "python"
| "teletype"
) [cl::assign_a(actions.source_mode)]
;
footnote =
cl::str_p("footnote") [actions.footnote_pre]
>> blank >> phrase [actions.footnote_post]
;
}
}
#endif // BOOST_SPIRIT_QUICKBOOK_PHRASE_HPP

View File

@@ -16,8 +16,7 @@
namespace quickbook
{
using namespace boost::spirit::classic;
using boost::bind;
namespace cl = boost::spirit::classic;
typedef std::string::const_iterator iter_type;
struct printer
@@ -256,7 +255,7 @@ namespace quickbook
std::string current_tag;
};
struct tidy_grammar : grammar<tidy_grammar>
struct tidy_grammar : cl::grammar<tidy_grammar>
{
tidy_grammar(tidy_compiler& state, int indent)
: state(state), indent(indent) {}
@@ -266,43 +265,43 @@ namespace quickbook
{
definition(tidy_grammar const& self)
{
tag = (lexeme_d[+(alpha_p | '_' | ':')]) [boost::bind(&tidy_grammar::do_tag, &self, _1, _2)];
tag = (cl::lexeme_d[+(cl::alpha_p | '_' | ':')]) [boost::bind(&tidy_grammar::do_tag, &self, _1, _2)];
code =
"<programlisting>"
>> *(anychar_p - "</programlisting>")
>> *(cl::anychar_p - "</programlisting>")
>> "</programlisting>"
;
// What's the business of lexeme_d['>' >> *space_p]; ?
// What's the business of cl::lexeme_d['>' >> *cl::space_p]; ?
// It is there to preserve the space after the tag that is
// otherwise consumed by the space_p skipper.
// otherwise consumed by the cl::space_p skipper.
escape =
str_p("<!--quickbook-escape-prefix-->") >>
(*(anychar_p - str_p("<!--quickbook-escape-postfix-->")))
cl::str_p("<!--quickbook-escape-prefix-->") >>
(*(cl::anychar_p - cl::str_p("<!--quickbook-escape-postfix-->")))
[
boost::bind(&tidy_grammar::do_escape, &self, _1, _2)
]
>> lexeme_d
>> cl::lexeme_d
[
str_p("<!--quickbook-escape-postfix-->") >>
(*space_p)
cl::str_p("<!--quickbook-escape-postfix-->") >>
(*cl::space_p)
[
boost::bind(&tidy_grammar::do_escape_post, &self, _1, _2)
]
]
;
start_tag = '<' >> tag >> *(anychar_p - '>') >> lexeme_d['>' >> *space_p];
start_tag = '<' >> tag >> *(cl::anychar_p - '>') >> cl::lexeme_d['>' >> *cl::space_p];
start_end_tag =
'<' >> tag >> *(anychar_p - ("/>" | ch_p('>'))) >> lexeme_d["/>" >> *space_p]
| "<?" >> tag >> *(anychar_p - '?') >> lexeme_d["?>" >> *space_p]
| "<!--" >> *(anychar_p - "-->") >> lexeme_d["-->" >> *space_p]
| "<!" >> tag >> *(anychar_p - '>') >> lexeme_d['>' >> *space_p]
'<' >> tag >> *(cl::anychar_p - ("/>" | cl::ch_p('>'))) >> cl::lexeme_d["/>" >> *cl::space_p]
| "<?" >> tag >> *(cl::anychar_p - '?') >> cl::lexeme_d["?>" >> *cl::space_p]
| "<!--" >> *(cl::anychar_p - "-->") >> cl::lexeme_d["-->" >> *cl::space_p]
| "<!" >> tag >> *(cl::anychar_p - '>') >> cl::lexeme_d['>' >> *cl::space_p]
;
content = lexeme_d[ +(anychar_p - '<') ];
end_tag = "</" >> +(anychar_p - '>') >> lexeme_d['>' >> *space_p];
content = cl::lexeme_d[ +(cl::anychar_p - '<') ];
end_tag = "</" >> +(cl::anychar_p - '>') >> cl::lexeme_d['>' >> *cl::space_p];
markup =
escape
@@ -316,10 +315,11 @@ namespace quickbook
tidy = +markup;
}
rule<Scanner> const&
cl::rule<Scanner> const&
start() { return tidy; }
rule<Scanner> tidy, tag, start_tag, start_end_tag,
cl::rule<Scanner>
tidy, tag, start_tag, start_end_tag,
content, end_tag, markup, code, escape;
};
@@ -435,7 +435,7 @@ namespace quickbook
std::string tidy;
tidy_compiler state(tidy, linewidth);
tidy_grammar g(state, indent);
parse_info<iter_type> r = parse(in.begin(), in.end(), g, space_p);
cl::parse_info<iter_type> r = parse(in.begin(), in.end(), g, cl::space_p);
if (r.full)
{
out << tidy;

View File

@@ -32,14 +32,12 @@
namespace quickbook
{
using namespace boost::spirit::classic;
namespace cl = boost::spirit::classic;
namespace fs = boost::filesystem;
tm* current_time; // the current time
tm* current_gm_time; // the current UTC time
bool debug_mode; // for quickbook developers only
int qbk_major_version = -1;
int qbk_minor_version = -1;
unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version
bool ms_errors = false; // output errors/warnings as if for VS
std::vector<std::string> include_path;
std::vector<std::string> preset_defines;
@@ -53,11 +51,10 @@ namespace quickbook
end = preset_defines.end();
it != end; ++it)
{
typedef position_iterator<std::string::const_iterator> iterator_type;
iterator_type first(it->begin(), it->end(), "command line parameter");
iterator_type last(it->end(), it->end());
iterator first(it->begin(), it->end(), "command line parameter");
iterator last(it->end(), it->end());
parse(first, last, grammar);
call_parse(first, last, grammar);
// TODO: Check result?
}
}
@@ -81,19 +78,18 @@ namespace quickbook
return err;
}
typedef position_iterator<std::string::const_iterator> iterator_type;
iterator_type first(storage.begin(), storage.end(), filein_);
iterator_type last(storage.end(), storage.end());
iterator first(storage.begin(), storage.end(), filein_);
iterator last(storage.end(), storage.end());
doc_info_grammar l(actor);
parse_info<iterator_type> info = parse(first, last, l);
cl::parse_info<iterator> info = call_parse(first, last, l);
if (info.hit || ignore_docinfo)
{
pre(actor.out, actor, ignore_docinfo);
block_grammar g(actor);
info = parse(info.hit ? info.stop : first, last, g);
info = call_parse(info.hit ? info.stop : first, last, g);
if (info.full)
{
post(actor.out, actor, ignore_docinfo);
@@ -102,7 +98,7 @@ namespace quickbook
if (!info.full)
{
file_position const pos = info.stop.get_position();
position const pos = info.stop.get_position();
detail::outerr(pos.file,pos.line)
<< "Syntax Error near column " << pos.column << ".\n";
++actor.error_count;
@@ -140,24 +136,24 @@ namespace quickbook
, bool pretty_print)
{
int result = 0;
std::ofstream fileout(fileout_);
fs::path outdir = fs::path(fileout_).parent_path();
if (outdir.empty())
outdir = ".";
if (pretty_print)
string_stream buffer;
result = parse_document(filein_, outdir, buffer);
if (result == 0)
{
string_stream buffer;
result = parse_document(filein_, outdir, buffer);
if (result == 0)
std::ofstream fileout(fileout_);
if (pretty_print)
{
result = post_process(buffer.str(), fileout, indent, linewidth);
}
}
else
{
string_stream buffer;
result = parse_document(filein_, outdir, buffer);
fileout << buffer.str();
else
{
fileout << buffer.str();
}
}
return result;
}

View File

@@ -12,36 +12,20 @@
#if !defined(BOOST_SPIRIT_QUICKBOOK_QUICKBOOK_HPP)
#define BOOST_SPIRIT_QUICKBOOK_QUICKBOOK_HPP
#include <time.h>
#include <vector>
#include <string>
#include "fwd.hpp"
namespace quickbook
{
extern int qbk_major_version;
extern int qbk_minor_version;
extern unsigned qbk_version_n; // qbk_major_version * 100 + qbk_minor_version
extern tm* current_time; // the current time
extern tm* current_gm_time; // the current UTC time
extern bool debug_mode;
extern std::vector<std::string> include_path;
extern std::vector<std::string> preset_defines;
struct quickbook_range {
template <typename Arg>
struct result
{
typedef bool type;
};
quickbook_range(unsigned min_, unsigned max_)
: min_(min_), max_(max_) {}
bool operator()() const {
return qbk_version_n >= min_ && qbk_version_n < max_;
}
unsigned min_, max_;
};
inline quickbook_range qbk_since(unsigned min_) {
return quickbook_range(min_, 999);
}
inline quickbook_range qbk_before(unsigned max_) {
return quickbook_range(0, max_);
}
int parse_file(char const* filein_, actions& actor, bool ignore_docinfo = false);
}
#endif

134
src/scoped_block.hpp Normal file
View File

@@ -0,0 +1,134 @@
/*=============================================================================
Copyright (c) 2010 Daniel James
Copyright (c) 2003 Martin Wille
http://spirit.sourceforge.net/
Distributed under 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)
=============================================================================*/
// Used to parse an inner block, saves the streams and restores them if the
// parse fails. On success the action is passed the resulting block.
//
// Might be a good idea to do something more generic in the future.
//
// This is based on `boost::spirit::classic::scoped_lock` by Martin Wille
#ifndef BOOST_QUICKBOOK_SCOPED_BLOCK_HPP
#define BOOST_QUICKBOOK_SCOPED_BLOCK_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include "actions_class.hpp"
namespace quickbook {
namespace cl = boost::spirit::classic;
struct scoped_block_push
{
typedef std::string attribute;
scoped_block_push(quickbook::actions& actions)
: actions(actions)
{
actions.out.push();
actions.phrase.push();
}
~scoped_block_push()
{
actions.phrase.pop();
actions.out.pop();
}
std::string const& finish()
{
actions.inside_paragraph();
return actions.out.str();
}
quickbook::actions& actions;
};
template <typename ParserT>
struct scoped_block_parser
: public cl::unary< ParserT, cl::parser< scoped_block_parser<ParserT> > >
{
typedef scoped_block_parser<ParserT> self_t;
typedef cl::unary< ParserT, cl::parser< scoped_block_parser<ParserT> > > base_t;
template <typename ScannerT>
struct result
{
typedef cl::match<std::string> type;
};
scoped_block_parser(quickbook::actions& a, ParserT const &p)
: base_t(p)
, actions(a)
{}
template <typename ScannerT>
cl::match<std::string> parse(ScannerT const &scan) const
{
typedef typename ScannerT::iterator_t iterator_t;
iterator_t save = scan.first;
scoped_block_push push(actions);
typename cl::parser_result<ParserT, ScannerT>::type result
= this->subject().parse(scan);
if (result)
return scan.create_match(result.length(), push.finish(), save, scan.first);
else
return scan.no_match();
}
quickbook::actions& actions;
};
///////////////////////////////////////////////////////////////////////////
//
// scoped_block_parser_gen
//
// generator for scoped_block_parser objects
// operator[] returns scoped_block_parser according to its argument
//
///////////////////////////////////////////////////////////////////////////
struct scoped_block_parser_gen
{
explicit scoped_block_parser_gen(quickbook::actions& actions)
: actions(actions) {}
template<typename ParserT>
scoped_block_parser
<
typename cl::as_parser<ParserT>::type
>
operator[](ParserT const &p) const
{
typedef cl::as_parser<ParserT> as_parser_t;
typedef typename as_parser_t::type parser_t;
return scoped_block_parser<parser_t>
(actions, as_parser_t::convert(p));
}
quickbook::actions& actions;
};
///////////////////////////////////////////////////////////////////////////
//
// scoped_block_d parser directive
//
// constructs a scoped_block_parser generator from its argument
//
///////////////////////////////////////////////////////////////////////////
inline scoped_block_parser_gen scoped_block(quickbook::actions& actions) {
return scoped_block_parser_gen(actions);
}
}
#endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP

View File

@@ -43,22 +43,27 @@ namespace quickbook
, collector>
teletype_p_type;
std::string syntax_highlight::operator()(iterator first, iterator last) const
std::string syntax_highlight(
iterator first, iterator last,
actions& escape_actions,
std::string const& source_mode)
{
quickbook::collector temp;
// print the code with syntax coloring
if (source_mode == "c++")
{
cpp_p_type cpp_p(temp, macro, do_macro_action(temp), escape_actions);
cpp_p_type cpp_p(temp, escape_actions.macro, do_macro_action(temp), escape_actions);
boost::spirit::classic::parse(first, last, cpp_p);
}
else if (source_mode == "python")
{
python_p_type python_p(temp, macro, do_macro_action(temp), escape_actions);
python_p_type python_p(temp, escape_actions.macro, do_macro_action(temp), escape_actions);
boost::spirit::classic::parse(first, last, python_p);
}
else if (source_mode == "teletype")
{
teletype_p_type teletype_p(temp, macro, do_macro_action(temp), escape_actions);
teletype_p_type teletype_p(temp, escape_actions.macro, do_macro_action(temp), escape_actions);
boost::spirit::classic::parse(first, last, teletype_p);
}
else

View File

@@ -19,7 +19,7 @@
namespace quickbook
{
using namespace boost::spirit::classic;
namespace cl = boost::spirit::classic;
// Grammar for C++ highlighting
template <
@@ -32,7 +32,7 @@ namespace quickbook
, typename Unexpected
, typename Out>
struct cpp_highlight
: public grammar<cpp_highlight<Process, Space, Macro, DoMacro, PreEscape, PostEscape, Unexpected, Out> >
: public cl::grammar<cpp_highlight<Process, Space, Macro, DoMacro, PreEscape, PostEscape, Unexpected, Out> >
{
cpp_highlight(Out& out, Macro const& macro, DoMacro do_macro, actions& escape_actions)
: out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {}
@@ -46,7 +46,7 @@ namespace quickbook
{
program
=
*( (+space_p) [Space(self.out)]
*( (+cl::space_p) [Space(self.out)]
| macro
| escape
| preprocessor [Process("preprocessor", self.out)]
@@ -57,51 +57,54 @@ namespace quickbook
| string_ [Process("string", self.out)]
| char_ [Process("char", self.out)]
| number [Process("number", self.out)]
| repeat_p(1)[anychar_p] [Unexpected(self.out)]
| cl::repeat_p(1)[cl::anychar_p]
[Unexpected(self.out)]
)
;
macro =
eps_p(self.macro // must not be followed by
>> (eps_p - (alpha_p | '_'))) // alpha or underscore
macro =
// must not be followed by alpha or underscore
cl::eps_p(self.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
>> self.macro [self.do_macro]
;
qbk_phrase =
*( common
| (anychar_p - str_p("``")) [self.escape_actions.plain_char]
| (cl::anychar_p - cl::str_p("``"))
[self.escape_actions.plain_char]
)
;
escape =
str_p("``") [PreEscape(self.escape_actions, save)]
cl::str_p("``") [PreEscape(self.escape_actions, save)]
>>
(
(
(
(+(anychar_p - "``") >> eps_p("``"))
(+(cl::anychar_p - "``") >> cl::eps_p("``"))
& qbk_phrase
)
>> str_p("``")
>> cl::str_p("``")
)
|
(
eps_p [self.escape_actions.error]
>> *anychar_p
cl::eps_p [self.escape_actions.error]
>> *cl::anychar_p
)
) [PostEscape(self.out, self.escape_actions, save)]
;
preprocessor
= '#' >> *space_p >> ((alpha_p | '_') >> *(alnum_p | '_'))
= '#' >> *cl::space_p >> ((cl::alpha_p | '_') >> *(cl::alnum_p | '_'))
;
comment
= comment_p("//") | comment_p("/*", "*/")
= cl::comment_p("//") | cl::comment_p("/*", "*/")
;
keyword
= keyword_ >> (eps_p - (alnum_p | '_'))
= keyword_ >> (cl::eps_p - (cl::alnum_p | '_'))
; // make sure we recognize whole words only
keyword_
@@ -122,43 +125,44 @@ namespace quickbook
;
special
= +chset_p("~!%^&*()+={[}]:;,<.>?/|\\-")
= +cl::chset_p("~!%^&*()+={[}]:;,<.>?/|\\-")
;
string_char = ('\\' >> anychar_p) | (anychar_p - '\\');
string_char = ('\\' >> cl::anychar_p) | (cl::anychar_p - '\\');
string_
= !as_lower_d['l'] >> confix_p('"', *string_char, '"')
= !cl::as_lower_d['l'] >> cl::confix_p('"', *string_char, '"')
;
char_
= !as_lower_d['l'] >> confix_p('\'', *string_char, '\'')
= !cl::as_lower_d['l'] >> cl::confix_p('\'', *string_char, '\'')
;
number
= (
as_lower_d["0x"] >> hex_p
| '0' >> oct_p
| real_p
cl::as_lower_d["0x"] >> cl::hex_p
| '0' >> cl::oct_p
| cl::real_p
)
>> *as_lower_d[chset_p("ldfu")]
>> *cl::as_lower_d[cl::chset_p("ldfu")]
;
identifier
= (alpha_p | '_') >> *(alnum_p | '_')
= (cl::alpha_p | '_') >> *(cl::alnum_p | '_')
;
}
rule<Scanner> program, macro, preprocessor, comment, special, string_,
cl::rule<Scanner>
program, macro, preprocessor, comment, special, string_,
char_, number, identifier, keyword, qbk_phrase, escape,
string_char;
symbols<> keyword_;
cl::symbols<> keyword_;
phrase_grammar common;
std::string save;
bool unused;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return program; }
};
@@ -181,7 +185,7 @@ namespace quickbook
, typename Unexpected
, typename Out>
struct python_highlight
: public grammar<python_highlight<Process, Space, Macro, DoMacro, PreEscape, PostEscape, Unexpected, Out> >
: public cl::grammar<python_highlight<Process, Space, Macro, DoMacro, PreEscape, PostEscape, Unexpected, Out> >
{
python_highlight(Out& out, Macro const& macro, DoMacro do_macro, actions& escape_actions)
: out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {}
@@ -195,7 +199,7 @@ namespace quickbook
{
program
=
*( (+space_p) [Space(self.out)]
*( (+cl::space_p) [Space(self.out)]
| macro
| escape
| comment [Process("comment", self.out)]
@@ -204,47 +208,50 @@ namespace quickbook
| special [Process("special", self.out)]
| string_ [Process("string", self.out)]
| number [Process("number", self.out)]
| repeat_p(1)[anychar_p] [Unexpected(self.out)]
| cl::repeat_p(1)[cl::anychar_p]
[Unexpected(self.out)]
)
;
macro =
eps_p(self.macro // must not be followed by
>> (eps_p - (alpha_p | '_'))) // alpha or underscore
// must not be followed by alpha or underscore
cl::eps_p(self.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
>> self.macro [self.do_macro]
;
qbk_phrase =
*( common
| (anychar_p - str_p("``")) [self.escape_actions.plain_char]
| (cl::anychar_p - cl::str_p("``"))
[self.escape_actions.plain_char]
)
;
escape =
str_p("``") [PreEscape(self.escape_actions, save)]
cl::str_p("``") [PreEscape(self.escape_actions, save)]
>>
(
(
(
(+(anychar_p - "``") >> eps_p("``"))
(+(cl::anychar_p - "``") >> cl::eps_p("``"))
& qbk_phrase
)
>> str_p("``")
>> cl::str_p("``")
)
|
(
eps_p [self.escape_actions.error]
>> *anychar_p
cl::eps_p [self.escape_actions.error]
>> *cl::anychar_p
)
) [PostEscape(self.out, self.escape_actions, save)]
;
comment
= comment_p("#")
= cl::comment_p("#")
;
keyword
= keyword_ >> (eps_p - (alnum_p | '_'))
= keyword_ >> (cl::eps_p - (cl::alnum_p | '_'))
; // make sure we recognize whole words only
keyword_
@@ -264,55 +271,56 @@ namespace quickbook
;
special
= +chset_p("~!%^&*()+={[}]:;,<.>/|\\-")
= +cl::chset_p("~!%^&*()+={[}]:;,<.>/|\\-")
;
string_prefix
= as_lower_d[str_p("u") >> ! str_p("r")]
= cl::as_lower_d[cl::str_p("u") >> ! cl::str_p("r")]
;
string_
= ! string_prefix >> (long_string | short_string)
;
string_char = ('\\' >> anychar_p) | (anychar_p - '\\');
string_char = ('\\' >> cl::anychar_p) | (cl::anychar_p - '\\');
short_string
= confix_p('\'', * string_char, '\'') |
confix_p('"', * string_char, '"')
= cl::confix_p('\'', * string_char, '\'') |
cl::confix_p('"', * string_char, '"')
;
long_string
// Note: the "str_p" on the next two lines work around
// Note: the "cl::str_p" on the next two lines work around
// an INTERNAL COMPILER ERROR when using VC7.1
= confix_p(str_p("'''"), * string_char, "'''") |
confix_p(str_p("\"\"\""), * string_char, "\"\"\"")
= cl::confix_p(cl::str_p("'''"), * string_char, "'''") |
cl::confix_p(cl::str_p("\"\"\""), * string_char, "\"\"\"")
;
number
= (
as_lower_d["0x"] >> hex_p
| '0' >> oct_p
| real_p
cl::as_lower_d["0x"] >> cl::hex_p
| '0' >> cl::oct_p
| cl::real_p
)
>> *as_lower_d[chset_p("lj")]
>> *cl::as_lower_d[cl::chset_p("lj")]
;
identifier
= (alpha_p | '_') >> *(alnum_p | '_')
= (cl::alpha_p | '_') >> *(cl::alnum_p | '_')
;
}
rule<Scanner> program, macro, comment, special, string_, string_prefix,
cl::rule<Scanner>
program, macro, comment, special, string_, string_prefix,
short_string, long_string, number, identifier, keyword,
qbk_phrase, escape, string_char;
symbols<> keyword_;
cl::symbols<> keyword_;
phrase_grammar common;
std::string save;
bool unused;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return program; }
};
@@ -331,7 +339,7 @@ namespace quickbook
, typename PostEscape
, typename Out>
struct teletype_highlight
: public grammar<teletype_highlight<CharProcess, Macro, DoMacro, PreEscape, PostEscape, Out> >
: public cl::grammar<teletype_highlight<CharProcess, Macro, DoMacro, PreEscape, PostEscape, Out> >
{
teletype_highlight(Out& out, Macro const& macro, DoMacro do_macro, actions& escape_actions)
: out(out), macro(macro), do_macro(do_macro), escape_actions(escape_actions) {}
@@ -347,49 +355,51 @@ namespace quickbook
=
*( macro
| escape
| repeat_p(1)[anychar_p] [CharProcess(self.out)]
| cl::repeat_p(1)[cl::anychar_p] [CharProcess(self.out)]
)
;
macro =
eps_p(self.macro // must not be followed by
>> (eps_p - (alpha_p | '_'))) // alpha or underscore
>> self.macro [self.do_macro]
macro =
// must not be followed by alpha or underscore
cl::eps_p(self.macro
>> (cl::eps_p - (cl::alpha_p | '_')))
>> self.macro [self.do_macro]
;
qbk_phrase =
*( common
| (anychar_p - str_p("``")) [self.escape_actions.plain_char]
| (cl::anychar_p - cl::str_p("``"))
[self.escape_actions.plain_char]
)
;
escape =
str_p("``") [PreEscape(self.escape_actions, save)]
cl::str_p("``") [PreEscape(self.escape_actions, save)]
>>
(
(
(
(+(anychar_p - "``") >> eps_p("``"))
(+(cl::anychar_p - "``") >> cl::eps_p("``"))
& qbk_phrase
)
>> str_p("``")
>> cl::str_p("``")
)
|
(
eps_p [self.escape_actions.error]
>> *anychar_p
cl::eps_p [self.escape_actions.error]
>> *cl::anychar_p
)
) [PostEscape(self.out, self.escape_actions, save)]
;
}
rule<Scanner> program, macro, qbk_phrase, escape;
cl::rule<Scanner> program, macro, qbk_phrase, escape;
phrase_grammar common;
std::string save;
bool unused;
rule<Scanner> const&
cl::rule<Scanner> const&
start() const { return program; }
};

View File

@@ -25,7 +25,7 @@ namespace quickbook
{
template_body(
std::string const& content,
boost::spirit::classic::file_position position,
boost::spirit::classic::file_position const& position,
bool is_block
)
: content(content)
@@ -33,8 +33,21 @@ namespace quickbook
, is_block(is_block)
{
}
template_body(
std::string const& content,
boost::spirit::classic::file_position_base<char const*> const& position,
bool is_block
)
: content(content)
, position(position.file, position.line, position.column)
, is_block(is_block)
{
}
std::string content;
// Note: Using file_position to store the filename after the file
// has been closed.
boost::spirit::classic::file_position position;
bool is_block;
};
@@ -57,6 +70,20 @@ namespace quickbook
, callout(false)
, callouts() {}
template_symbol(
std::string const& identifier,
std::vector<std::string> const& params,
std::string const& body,
boost::spirit::classic::file_position_base<char const*> const& position,
bool is_block,
template_scope const* parent = 0)
: identifier(identifier)
, params(params)
, body(body, position, is_block)
, parent(parent)
, callout(false)
, callouts() {}
std::string identifier;
std::vector<std::string> params;
template_body body;