1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
[/==============================================================================
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 output 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 `. Similarly
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]
|