152 lines
5.3 KiB
Plaintext
152 lines
5.3 KiB
Plaintext
[/==============================================================================
|
|
Copyright (C) 2001-2011 Hartmut Kaiser
|
|
Copyright (C) 2001-2011 Joel de Guzman
|
|
|
|
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)
|
|
===============================================================================/]
|
|
|
|
[section Karma Confix Generator]
|
|
|
|
[heading Description]
|
|
|
|
The __karma__ `confix` generator is a generator directive component
|
|
allowing to embed any generated ouput inside an opening (a prefix) and a
|
|
closing (a suffix). A simple example is a C comment: `/* This is a C comment */`
|
|
which can be generated using the `confix` generator as:
|
|
`confix("/*", "*/")["This is a C comment"]`. The general syntax for using the
|
|
`confix` is:
|
|
|
|
confix(prefix, suffix)[subject]
|
|
|
|
which results in generating a sequence equivalent to
|
|
|
|
prefix << subject << suffix
|
|
|
|
Using the `confix` component instead of the explicit sequence has the advantage
|
|
of being able to encapsulate the prefix and the suffix into a separate generator
|
|
construct. The following code snippet illustrates the idea:
|
|
|
|
// Define a metafunction allowing to compute the type of the confix()
|
|
// construct
|
|
namespace traits
|
|
{
|
|
using namespace boost::spirit;
|
|
|
|
template <typename Prefix, typename Suffix = Prefix>
|
|
struct confix_spec
|
|
: spirit::result_of::terminal<repository::tag::confix(Prefix, Suffix)>
|
|
{};
|
|
};
|
|
|
|
// Define a helper function allowing to create a confix() construct from
|
|
// arbitrary prefix and suffix generators
|
|
template <typename Prefix, typename Suffix>
|
|
typename traits::confix_spec<Prefix, Suffix>::type
|
|
confix_spec(Prefix const& prefix, Suffix const& suffix)
|
|
{
|
|
using namespace boost::spirit;
|
|
return repository::confix(prefix, suffix);
|
|
}
|
|
|
|
// Define a helper function to construct a HTML tag from the tag name
|
|
inline typename traits::confix_spec<std::string>::type
|
|
tag (std::string const& tagname)
|
|
{
|
|
return confix_spec("<" + tagname + ">", "</" + tagname + ">");
|
|
}
|
|
|
|
// Define generators for different HTML tags the HTML tag
|
|
typedef traits::confix_spec<std::string>::type ol = tag("ol"); // <ol>...</ol>
|
|
typedef traits::confix_spec<std::string>::type li = tag("li"); // <li>...</li>
|
|
|
|
Now, for instance, the above definitions allow to generate the HTML 'ol' tag
|
|
using a simple: `ol["Some text"]` (which results in `<ol>Some text</ol>`).
|
|
|
|
[heading Header]
|
|
|
|
// forwards to <boost/spirit/repository/home/karma/directive/confix.hpp>
|
|
#include <boost/spirit/repository/include/karma_confix.hpp>
|
|
|
|
[heading Synopsis]
|
|
|
|
confix(prefix, suffix)[subject]
|
|
|
|
[heading Parameters]
|
|
|
|
[table
|
|
[[Parameter] [Description]]
|
|
[[`prefix`] [The generator construct to use to format the
|
|
opening (the prefix). The prefix is the part
|
|
generated /before/ any output as generated by
|
|
the `subject`.]]
|
|
[[`suffix`] [The generator construct to use to format the
|
|
ending (the suffix). The suffix is the part
|
|
generated /after/ any output as generated by
|
|
the `subject`.]]
|
|
[[`subject`] [The generator construct to use to format the
|
|
actual output in between the `prefix` and `suffix`
|
|
parts.]]
|
|
]
|
|
|
|
All three parameters can be arbitrary complex generators themselves.
|
|
|
|
[heading Attribute]
|
|
|
|
The `confix` component exposes the attribute type of its subject as its own
|
|
attribute type. If the `subject` does not expose any attribute (the type is
|
|
`unused_type`), then the `confix` does not expose any attribute either.
|
|
|
|
a: A --> confix(p, s)[a]: A
|
|
|
|
[note This notation is used all over the Spirit documentation and reads as:
|
|
Given, `a` is generator, and `A` is the type of the attribute of generator
|
|
`a`, then the type of the attribute exposed by `confix(p, s)[a]` will be
|
|
`A` as well.]
|
|
|
|
[heading Example]
|
|
|
|
The following example shows simple use cases of the `confix` generator. We will
|
|
illustrate its usage by generating different comment styles and a function
|
|
prototype (for the full example code see here:
|
|
[@../../example/karma/confix.cpp confix.cpp])
|
|
|
|
[import ../../example/karma/confix.cpp]
|
|
|
|
[heading Prerequisites]
|
|
|
|
In addition to the main header file needed to include the core components
|
|
implemented in __karma__ we add the header file needed for the new `confix`
|
|
generator.
|
|
|
|
[karma_confix_includes]
|
|
|
|
To make all the code below more readable we introduce the following namespaces.
|
|
|
|
[karma_confix_namespace]
|
|
|
|
[heading Generating Different Comment Styles]
|
|
|
|
We will show how to generate different comment styles. First we will generate
|
|
a C++ comment:
|
|
|
|
[karma_confix_cpp_comment]
|
|
|
|
This code snippet will obviouly generate `// This is a comment \n `. Similarily
|
|
generating a 'C'-style comment proves to be straightforward:
|
|
|
|
[karma_confix_c_comment]
|
|
|
|
which again will generate `/* This is a comment */ `.
|
|
|
|
[heading Generating a Function Prototype]
|
|
|
|
Generating a function prototype given a function name a vector or parameter
|
|
names is simple as well:
|
|
|
|
[karma_confix_function]
|
|
|
|
which generates the expected output: `func(par1,par2,par3)`.
|
|
|
|
[endsect]
|