[/==============================================================================
    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]
