• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/==============================================================================
2    Copyright (C) 2001-2011 Hartmut Kaiser
3    Copyright (C) 2001-2011 Joel de Guzman
4
5    Distributed under the Boost Software License, Version 1.0. (See accompanying
6    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7===============================================================================/]
8
9[section Karma Confix Generator]
10
11[heading Description]
12
13The __karma__ `confix` generator is a generator directive component
14allowing to embed any generated output inside an opening (a prefix) and a
15closing (a suffix). A simple example is a C comment: `/* This is a C comment */`
16which can be generated using the `confix` generator as:
17`confix("/*", "*/")["This is a C comment"]`. The general syntax for using the
18`confix` is:
19
20    confix(prefix, suffix)[subject]
21
22which results in generating a sequence equivalent to
23
24    prefix << subject << suffix
25
26Using the `confix` component instead of the explicit sequence has the advantage
27of being able to encapsulate the prefix and the suffix into a separate generator
28construct. The following code snippet illustrates the idea:
29
30    // Define a metafunction allowing to compute the type of the confix()
31    // construct
32    namespace traits
33    {
34        using namespace boost::spirit;
35
36        template <typename Prefix, typename Suffix = Prefix>
37        struct confix_spec
38          : spirit::result_of::terminal<repository::tag::confix(Prefix, Suffix)>
39        {};
40    };
41
42    // Define a helper function allowing to create a confix() construct from
43    // arbitrary prefix and suffix generators
44    template <typename Prefix, typename Suffix>
45    typename traits::confix_spec<Prefix, Suffix>::type
46    confix_spec(Prefix const& prefix, Suffix const& suffix)
47    {
48        using namespace boost::spirit;
49        return repository::confix(prefix, suffix);
50    }
51
52    // Define a helper function to  construct a HTML tag from the tag name
53    inline typename traits::confix_spec<std::string>::type
54    tag (std::string const& tagname)
55    {
56        return confix_spec("<" + tagname + ">", "</" + tagname + ">");
57    }
58
59    // Define generators for different HTML tags the HTML tag
60    typedef traits::confix_spec<std::string>::type ol = tag("ol");      // <ol>...</ol>
61    typedef traits::confix_spec<std::string>::type li = tag("li");      // <li>...</li>
62
63Now, for instance, the above definitions allow to generate the HTML 'ol' tag
64using a simple: `ol["Some text"]` (which results in `<ol>Some text</ol>`).
65
66[heading Header]
67
68    // forwards to <boost/spirit/repository/home/karma/directive/confix.hpp>
69    #include <boost/spirit/repository/include/karma_confix.hpp>
70
71[heading Synopsis]
72
73    confix(prefix, suffix)[subject]
74
75[heading Parameters]
76
77[table
78    [[Parameter]            [Description]]
79    [[`prefix`]             [The generator construct to use to format the
80                             opening (the prefix). The prefix is the part
81                             generated /before/ any output as generated by
82                             the `subject`.]]
83    [[`suffix`]             [The generator construct to use to format the
84                             ending (the suffix). The suffix is the part
85                             generated /after/ any output as generated by
86                             the `subject`.]]
87    [[`subject`]            [The generator construct to use to format the
88                             actual output in between the `prefix` and `suffix`
89                             parts.]]
90]
91
92All three parameters can be arbitrary complex generators themselves.
93
94[heading Attribute]
95
96The `confix` component exposes the attribute type of its subject as its own
97attribute type. If the `subject` does not expose any attribute (the type is
98`unused_type`), then the `confix` does not expose any attribute either.
99
100    a: A --> confix(p, s)[a]: A
101
102[note This notation is used all over the Spirit documentation and reads as:
103      Given, `a` is generator, and `A` is the type of the attribute of generator
104      `a`, then the type of the attribute exposed by `confix(p, s)[a]` will be
105      `A` as well.]
106
107[heading Example]
108
109The following example shows simple use cases of the `confix` generator. We will
110illustrate its usage by generating different comment styles and a function
111prototype (for the full example code see here:
112[@../../example/karma/confix.cpp confix.cpp])
113
114[import ../../example/karma/confix.cpp]
115
116[heading Prerequisites]
117
118In addition to the main header file needed to include the core components
119implemented in __karma__ we add the header file needed for the new `confix`
120generator.
121
122[karma_confix_includes]
123
124To make all the code below more readable we introduce the following namespaces.
125
126[karma_confix_namespace]
127
128[heading Generating Different Comment Styles]
129
130We will show how to generate different comment styles. First we will generate
131a C++ comment:
132
133[karma_confix_cpp_comment]
134
135This code snippet will obviouly generate `// This is a comment \n `. Similarly
136generating a 'C'-style comment proves to be straightforward:
137
138[karma_confix_c_comment]
139
140which again will generate `/* This is a comment */ `.
141
142[heading Generating a Function Prototype]
143
144Generating a function prototype given a function name a vector or parameter
145names is simple as well:
146
147[karma_confix_function]
148
149which generates the expected output: `func(par1,par2,par3)`.
150
151[endsect]
152