Karma Confix Generator

| Home | Libraries | People | FAQ | More

#### Karma Confix Generator

###### Description

The Spirit.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>`).

###### Header

    // forwards to <boost/spirit/repository/home/karma/directive/confix.hpp>
    #include <boost/spirit/repository/include/karma_confix.hpp>

###### Synopsis

    confix(prefix, suffix)[subject]

###### Parameters

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.

###### 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.

###### 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: confix.cpp)

###### Prerequisites

In addition to the main header file needed to include the core components implemented in Spirit.Karma we add the header file needed for the new `confix` generator.

    #include <boost/spirit/include/karma.hpp>
    #include <boost/spirit/repository/include/karma_confix.hpp>

To make all the code below more readable we introduce the following namespaces.

    using namespace boost::spirit;
    using namespace boost::spirit::ascii;
    using boost::spirit::repository::confix;

###### Generating Different Comment Styles

We will show how to generate different comment styles. First we will generate a C++ comment:

    // C++ comment
    std::cout <<
        karma::format_delimited(
            confix("//", eol)[string],            // format description
            space,                                // delimiter
            "This is a comment"                   // data
        ) << std::endl;

This code snippet will obviouly generate `// This is a comment \n` . Similarily generating a 'C'-style comment proves to be straightforward:

    // C comment
    std::cout <<
        karma::format_delimited(
            confix("/*", "*/")[string],           // format description
            space,                                // delimiter
            "This is a comment"                   // data
        ) << std::endl;

which again will generate `/* This is a comment */` .

###### Generating a Function Prototype

Generating a function prototype given a function name a vector or parameter names is simple as well:

    // Generate a function call with an arbitrary parameter list
    std::vector<std::string> parameters;
    parameters.push_back("par1");
    parameters.push_back("par2");
    parameters.push_back("par3");

    std::cout <<
        karma::format(
            string << confix('(', ')')[string % ','],   // format description
            "func",                                     // function name
            parameters                                  // parameter names
        ) << std::endl;

which generates the expected output: `func(par1,par2,par3)`.