| [/============================================================================== |
| Copyright (C) 2001-2010 Hartmut Kaiser |
| Copyright (C) 2001-2010 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] |