Files
quickbook/code_snippet.hpp
2009-05-15 06:13:34 +00:00

216 lines
7.4 KiB
C++

/*=============================================================================
Copyright (c) 2006 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_QUICKBOOK_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 "./detail/template_stack.hpp"
namespace quickbook
{
struct code_snippet_actions
{
code_snippet_actions(std::vector<template_symbol>& storage,
std::string const& doc_id,
char const* source_type)
: storage(storage)
, doc_id(doc_id)
, source_type(source_type)
{}
void pass_thru(iterator first, iterator last);
void escaped_comment(iterator first, iterator last);
void compile(iterator first, iterator last);
void callout(iterator first, iterator last, char const* role);
void inline_callout(iterator first, iterator last);
void line_callout(iterator first, iterator last);
std::string code;
std::string snippet;
std::string id;
std::vector<std::string> callouts;
std::vector<template_symbol>& storage;
std::string const doc_id;
char const* const source_type;
};
struct python_code_snippet_grammar
: grammar<python_code_snippet_grammar>
{
typedef code_snippet_actions actions_type;
python_code_snippet_grammar(actions_type & actions)
: actions(actions)
{}
template <typename Scanner>
struct definition
{
typedef code_snippet_actions actions_type;
definition(python_code_snippet_grammar const& self)
{
actions_type& actions = self.actions;
start_ =
+(
snippet [boost::bind(&actions_type::compile, &actions, _1, _2)]
| anychar_p
)
;
identifier =
(alpha_p | '_') >> *(alnum_p | '_')
;
snippet =
"#[" >> *space_p
>> identifier [assign_a(actions.id)]
>> (*(code_elements - "#]"))
>> "#]"
;
code_elements =
escaped_comment
| ignore
| (anychar_p - "#]") [boost::bind(&actions_type::pass_thru, &actions, _1, _2)]
;
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)]
>> "\"\"\""
;
}
rule<Scanner>
start_, snippet, identifier, code_elements, escaped_comment,
inline_callout, line_callout, ignore;
rule<Scanner> const&
start() const { return start_; }
};
actions_type& actions;
};
struct cpp_code_snippet_grammar
: grammar<cpp_code_snippet_grammar>
{
typedef code_snippet_actions actions_type;
cpp_code_snippet_grammar(actions_type & actions)
: actions(actions)
{}
template <typename Scanner>
struct definition
{
definition(cpp_code_snippet_grammar const& self)
{
actions_type& actions = self.actions;
start_ =
+(
snippet [boost::bind(&actions_type::compile, &actions, _1, _2)]
| anychar_p
)
;
identifier =
(alpha_p | '_') >> *(alnum_p | '_')
;
snippet =
"//[" >> *space_p
>> identifier [assign_a(actions.id)]
>> (*(code_elements - "//]"))
>> "//]"
|
"/*[" >> *space_p
>> identifier [assign_a(actions.id)]
>> *space_p >> "*/"
>> (*(code_elements - "/*]*"))
>> "/*]*/"
;
code_elements =
escaped_comment
| ignore
| line_callout
| inline_callout
| (anychar_p - "//]" - "/*]*/") [boost::bind(&actions_type::pass_thru, &actions, _1, _2)]
;
inline_callout =
"/*<"
>> (*(anychar_p - ">*/")) [boost::bind(&actions_type::inline_callout, &actions, _1, _2)]
>> ">*/"
;
line_callout =
"/*<<"
>> (*(anychar_p - ">>*/")) [boost::bind(&actions_type::line_callout, &actions, _1, _2)]
>> ">>*/"
>> *space_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)]
>> "*/"
;
}
rule<Scanner>
start_, snippet, identifier, code_elements, escaped_comment,
inline_callout, line_callout, ignore;
rule<Scanner> const&
start() const { return start_; }
};
actions_type& actions;
};
}
#endif // BOOST_SPIRIT_QUICKBOOK_CODE_SNIPPET_HPP