mirror of
https://github.com/boostorg/quickbook.git
synced 2026-02-26 04:52:22 +00:00
135 lines
4.1 KiB
C++
135 lines
4.1 KiB
C++
/*=============================================================================
|
|
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
|