confix.qbk 5.3 KB

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