PageRenderTime 65ms CodeModel.GetById 21ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp

http://hadesmem.googlecode.com/
C++ Header | 605 lines | 485 code | 90 blank | 30 comment | 51 complexity | 6b4377e5932d434e96490bf649c2f691 MD5 | raw file
  1// Boost.Geometry (aka GGL, Generic Geometry Library)
  2//
  3// Copyright (c) 2010-2011 Barend Gehrels, Amsterdam, the Netherlands.
  4// Use, modification and distribution is subject to the Boost Software License,
  5// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6// http://www.boost.org/LICENSE_1_0.txt)
  7//
  8//
  9#ifndef QUICKBOOK_OUTPUT_HPP
 10#define QUICKBOOK_OUTPUT_HPP
 11
 12
 13#include <string>
 14#include <vector>
 15
 16#include <boost/algorithm/string.hpp>
 17
 18#include <doxygen_elements.hpp>
 19#include <parameter_predicates.hpp>
 20
 21std::string qbk_escaped(std::string const& s)
 22{
 23    // Replace _ by unicode to avoid accidental quickbook underlining.
 24    // 1) do NOT do this in quickbook markup, so not within []
 25    // (e.g. to avoid [include get_point.qbk] having unicoded)
 26    // 2) \[ and \] should not count as []
 27    std::size_t const len = s.length();
 28    int counter = 0;
 29    std::string result = "";
 30    for (std::size_t i = 0; i < len; i++)
 31    {
 32        switch(s[i])
 33        {
 34            case '[' : counter++; break;
 35            case ']' : counter--; break;
 36            case '\\' : 
 37                {
 38                    result += s[i];
 39                    if (i + 1 < len)
 40                    {
 41                        result += s[i + 1];
 42                    }
 43                    i++;
 44                    continue;
 45                }
 46            case '_' : 
 47                if (counter == 0)
 48                {
 49                    result += "\\u005f";
 50                    continue;
 51                }
 52        }
 53        result += s[i];
 54    }
 55
 56    return result;
 57}
 58
 59
 60
 61void quickbook_template_parameter_list(std::vector<parameter> const& parameters, std::ostream& out, bool name = false)
 62{
 63    if (!parameters.empty())
 64    {
 65        out << "template<" ;
 66        bool first = true;
 67        BOOST_FOREACH(parameter const& p, parameters)
 68        {
 69            out << (first ? "" : ", ") << p.fulltype;
 70            first = false;
 71        }
 72        out << ">" << std::endl;
 73    }
 74}
 75
 76
 77void quickbook_synopsis(function const& f, std::ostream& out)
 78{
 79    out << "``";
 80    quickbook_template_parameter_list(f.template_parameters, out);
 81    switch(f.type)
 82    {
 83        case function_constructor :
 84            out << f.name;
 85            break;
 86        case function_member :
 87            out << f.return_type << " " << f.name;
 88            break;
 89        case function_free :
 90            out << f.definition;
 91            break;
 92        case function_define :
 93            out << "#define " << f.name;
 94            break;
 95        case function_unknown :
 96            // do nothing
 97            break;
 98    }
 99
100    // Output the parameters
101    // Because we want to be able to skip, we cannot use the argstring
102    {
103        bool first = true;
104        BOOST_FOREACH(parameter const& p, f.parameters)
105        {
106            if (! p.skip)
107            {
108                out 
109                    << (first ? "(" : ", ")
110                    << p.fulltype << (p.fulltype.empty() ? "" : " ")
111                    << p.name
112                    << (p.default_value.empty() ? "" : " = ")
113                    << p.default_value;
114                first = false;
115            }
116        }
117        if (! first)
118        {
119            out << ")";
120        }
121        else if (f.type != function_define)
122        {
123            out << "()";
124        }
125    }
126
127    out << "``" 
128        << std::endl
129        << std::endl;
130}
131
132
133void quickbook_synopsis(enumeration const& e, std::ostream& out)
134{
135    out << "``enum " << e.name;
136    bool first = true;
137    BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
138    {
139        out << (first ? " {" : ", ") << value.name;
140        if (! value.initializer.empty())
141        {
142            out << " = " << boost::trim_copy(value.initializer);
143        }
144        first = false;
145    }
146    if (! first)
147    {
148        out << "};";
149    }
150    out << "``" 
151        << std::endl
152        << std::endl;
153}
154
155inline bool includes(std::string const& filename, std::string const& header)
156{
157    std::string result;
158
159    std::ifstream cpp_file(filename.c_str());
160    if (cpp_file.is_open())
161    {
162        while (! cpp_file.eof() )
163        {
164            std::string line;
165            std::getline(cpp_file, line);
166            boost::trim(line);
167            if (boost::starts_with(line, "#include")
168                && boost::contains(line, header))
169            {
170                return true;
171            }
172        }
173    }
174    return false;
175}
176
177
178void quickbook_header(std::string const& location,
179    configuration const& config,
180    std::ostream& out)
181{
182    if (! location.empty())
183    {
184        std::vector<std::string> including_headers;
185
186        // Select headerfiles containing to this location
187        BOOST_FOREACH(std::string const& header, config.convenience_headers)
188        {
189            if (includes(config.convenience_header_path + header, location))
190            {
191                including_headers.push_back(header);
192            }
193        }
194
195        out << "[heading Header]" << std::endl;
196        if (! including_headers.empty())
197        {
198            out << "Either"
199                << (including_headers.size() > 1 ? " one of" : "")
200                << std::endl << std::endl;
201            BOOST_FOREACH(std::string const& header, including_headers)
202            {
203                out << "`#include <" << config.start_include << header << ">`" << std::endl;
204            }
205
206            out << std::endl << "Or" << std::endl << std::endl;
207        }
208        out << "`#include <" << location << ">`" << std::endl;
209        out << std::endl;
210    }
211}
212
213
214void quickbook_markup(std::vector<markup> const& qbk_markup, 
215            markup_order_type order, markup_type type, 
216            std::ostream& out)
217{
218    bool has_output = false;
219    BOOST_FOREACH(markup const& inc, qbk_markup)
220    {
221        if (inc.type == type && inc.order == order)
222        {
223            out << inc.value << std::endl;
224            has_output = true;
225        }
226    }
227    if (has_output)
228    {
229        out << std::endl;
230    }
231}
232
233
234
235void quickbook_string_with_heading_if_present(std::string const& heading,
236            std::string const& contents, std::ostream& out)
237{
238    if (! contents.empty())
239    {
240        out << "[heading " << heading << "]" << std::endl
241            << qbk_escaped(contents) << std::endl
242            << std::endl;
243    }
244}
245
246inline std::string to_section_name(std::string const& name)
247{
248    // Make section-name lowercase and remove :: because these are filenames
249    return boost::to_lower_copy(boost::replace_all_copy(name, "::", "_"));
250}
251
252
253
254void quickbook_short_output(function const& f, std::ostream& out)
255{
256    BOOST_FOREACH(parameter const& p, f.parameters)
257    {
258        if (! p.skip)
259        {
260            out << "[* " << p.fulltype << "]: ['" << p.name << "]:  " << p.brief_description << std::endl << std::endl;
261        }
262    }
263    out << std::endl;
264    out << std::endl;
265
266    if (! f.return_description.empty())
267    {
268        out << "][" << std::endl;
269        out << f.return_description << std::endl;
270        out << std::endl;
271    }
272
273    out << std::endl;
274}
275
276inline std::string namespace_skipped(std::string const& name, configuration const& config)
277{
278    return config.skip_namespace.empty()
279        ? name
280        : boost::replace_all_copy(name, config.skip_namespace, "")
281        ;
282}
283
284inline std::string output_if_different(std::string const& s, std::string const& s2)
285{
286    return boost::equals(s, s2)
287        ? ""
288        : s + " "
289        ;
290}
291
292inline void quickbook_output_indexterm(std::string const& term, std::ostream& out
293            //, std::string const& secondary = ""
294            )
295{
296    out << "'''";
297    if (boost::contains(term, "::"))
298    {
299        // "Unnamespace" it and add all terms (also namespaces)
300        std::vector<std::string> splitted;
301        std::string for_split = boost::replace_all_copy(term, "::", ":");
302        boost::split(splitted, for_split, boost::is_any_of(":"), boost::token_compress_on);
303        BOOST_FOREACH(std::string const& part, splitted)
304        {
305            out << "<indexterm><primary>" << part << "</primary></indexterm>";
306        }
307    }
308    else
309    {
310        out << "<indexterm><primary>" << term;
311        /*if (! secondary.empty())
312        {
313            out << "<secondary>" << secondary << "</secondary>";
314        }*/
315        out << "</primary></indexterm>";
316    }
317    out << "'''" << std::endl;
318}
319
320void quickbook_output(function const& f, configuration const& config, std::ostream& out)
321{
322    // Write the parsed function
323    int arity = (int)f.parameters.size();
324
325    std::string additional_description;
326
327    if (! f.additional_description.empty())
328    {
329        additional_description = " (";
330        additional_description += f.additional_description;
331        additional_description += ")";
332    }
333
334    out << "[section:" << to_section_name(f.name);
335    // Make section name unique if necessary by arity and additional description
336    if (! f.unique)
337    {
338        out << "_" << arity;
339        if (! f.additional_description.empty())
340        {
341            out << "_" << boost::to_lower_copy(boost::replace_all_copy(f.additional_description, " ", "_"));
342        }
343    }
344    out << " " << f.name
345        << additional_description
346        << "]" << std::endl
347        << std::endl;
348
349    quickbook_output_indexterm(f.name, out);
350        
351    out << qbk_escaped(f.brief_description) << std::endl;
352    out << std::endl;
353
354    quickbook_string_with_heading_if_present("Description", f.detailed_description, out);
355
356    // Synopsis
357    quickbook_markup(f.qbk_markup, markup_before, markup_synopsis, out);
358    out << "[heading Synopsis]" << std::endl;
359    quickbook_synopsis(f, out);
360    quickbook_markup(f.qbk_markup, markup_after, markup_synopsis, out);
361
362
363    out << "[heading Parameters]" << std::endl
364        << std::endl;
365
366    out << "[table" << std::endl << "[";
367    if (f.type != function_define)
368    {
369        out << "[Type] [Concept] ";
370    }
371    out << "[Name] [Description] ]" << std::endl;
372
373    // First: output any template parameter which is NOT used in the normal parameter list
374    BOOST_FOREACH(parameter const& tp, f.template_parameters)
375    {
376        if (! tp.skip)
377        {
378            std::vector<parameter>::const_iterator it = std::find_if(f.parameters.begin(), f.parameters.end(), par_by_type(tp.name));
379
380            if (it == f.parameters.end())
381            {
382                out << "[[" << tp.name << "] [" << tp.brief_description << "] [ - ] [Must be specified]]" << std::endl;
383            }
384        }
385    }
386
387    BOOST_FOREACH(parameter const& p, f.parameters)
388    {
389        if (! p.skip)
390        {
391            out << "[";
392            std::vector<parameter>::const_iterator it = std::find_if(f.template_parameters.begin(),
393                f.template_parameters.end(), par_by_name(p.type));
394
395            if (f.type != function_define)
396            {
397                out << "[" << p.fulltype
398                    << "] [" << (it == f.template_parameters.end() ? "" : it->brief_description)
399                    << "] ";
400            }
401            out << "[" << p.name
402                << "] [" << p.brief_description
403                << "]]"
404                << std::endl;
405        }
406    }
407    out << "]" << std::endl
408        << std::endl
409        << std::endl;
410
411    quickbook_string_with_heading_if_present("Returns", f.return_description, out);
412
413    quickbook_header(f.location, config, out);
414    quickbook_markup(f.qbk_markup, markup_any, markup_default, out);
415
416    out << std::endl;
417    out << "[endsect]" << std::endl;
418    out << std::endl;
419}
420
421
422void quickbook_output(enumeration const& e, configuration const& config, std::ostream& out)
423{
424    out << "[section:" << to_section_name(e.name);
425    out << " " << e.name
426        << "]" << std::endl
427        << std::endl;
428
429    quickbook_output_indexterm(e.name, out);
430    BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
431    {
432        quickbook_output_indexterm(value.name, out);
433    }
434
435    out << e.brief_description << std::endl;
436    out << std::endl;
437
438    quickbook_string_with_heading_if_present("Description", e.detailed_description, out);
439
440    // Synopsis
441    quickbook_markup(e.qbk_markup, markup_before, markup_synopsis, out);
442    out << "[heading Synopsis]" << std::endl;
443    quickbook_synopsis(e, out);
444    quickbook_markup(e.qbk_markup, markup_after, markup_synopsis, out);
445
446
447    out << "[heading Values]" << std::endl
448        << std::endl;
449
450    out << "[table" << std::endl << "[";
451    out << "[Value] [Description] ]" << std::endl;
452
453    BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
454    {
455        out << "[[" << value.name
456            << "] [" << value.brief_description
457            << "]]"
458            << std::endl;
459    }
460    out << "]" << std::endl
461        << std::endl
462        << std::endl;
463
464    quickbook_header(e.location, config, out);
465    quickbook_markup(e.qbk_markup, markup_any, markup_default, out);
466
467    out << std::endl;
468    out << "[endsect]" << std::endl;
469    out << std::endl;
470}
471
472void quickbook_output_member(std::vector<function> const& functions, 
473        function_type type, 
474        std::string const& title,
475        configuration const& config, std::ostream& out)
476{
477    std::string returns = type == function_constructor ? "" : " [Returns]";
478    out << "[heading " << title << "(s)]" << std::endl
479        << "[table" << std::endl
480        << "[[Function] [Description] [Parameters] " << returns << "]" << std::endl;
481
482    BOOST_FOREACH(function const& f, functions)
483    {
484        if (f.type == type)
485        {
486            out << "[[";
487            quickbook_synopsis(f, out);
488            out << "] [" << f.brief_description << "] [";
489            quickbook_short_output(f, out);
490            out << "]]" << std::endl;
491        }
492    }
493    out << "]" << std::endl
494        << std::endl;
495}
496
497
498void quickbook_output(class_or_struct const& cos, configuration const& config, std::ostream& out)
499{
500    // Skip namespace
501    std::string short_name = namespace_skipped(cos.fullname, config);
502
503    // Write the parsed function
504    out << "[section:" << to_section_name(short_name) << " " << short_name << "]" << std::endl
505        << std::endl;
506
507    quickbook_output_indexterm(short_name, out);
508
509    out << cos.brief_description << std::endl;
510    out << std::endl;
511
512    quickbook_string_with_heading_if_present("Description", cos.detailed_description, out);
513
514    quickbook_markup(cos.qbk_markup, markup_before, markup_synopsis, out);
515    out << "[heading Synopsis]" << std::endl
516        << "``";
517    quickbook_template_parameter_list(cos.template_parameters, out);
518    out << (cos.is_class ? "class" : "struct")
519        << " " << short_name << std::endl;
520
521    if (! cos.base_classes.empty())
522    {
523        out << "      : ";
524        bool first = true;
525        BOOST_FOREACH(base_class const& bc, cos.base_classes)
526        {
527            if (! first)
528            {
529                out << std::endl << "      , ";
530            }
531            out << output_if_different(bc.derivation, "private")
532                << output_if_different(bc.virtuality, "non-virtual")
533                << namespace_skipped(bc.name, config);
534            first = false;
535        }
536        out << std::endl;
537    }
538
539    out << "{" << std::endl
540        << "  // ..." << std::endl
541        << "};" << std::endl
542        << "``" << std::endl << std::endl;
543    quickbook_markup(cos.qbk_markup, markup_after, markup_synopsis, out);
544
545
546
547    if (! cos.template_parameters.empty())
548    {
549        bool has_default = false;
550        BOOST_FOREACH(parameter const& p, cos.template_parameters)
551        {
552            if (! p.default_value.empty())
553            {
554                has_default = true;
555            }
556        }
557
558        out << "[heading Template parameter(s)]" << std::endl
559            << "[table" << std::endl
560            << "[[Parameter]";
561        if (has_default)
562        {
563            out << " [Default]";
564        }
565        out << " [Description]]" << std::endl;
566
567        BOOST_FOREACH(parameter const& p, cos.template_parameters)
568        {
569            out << "[[" << p.fulltype;
570            if (has_default)
571            {
572                out << "] [" << p.default_value;
573            }
574            out << "] [" << p.brief_description << "]]" << std::endl;
575        }
576        out << "]" << std::endl
577            << std::endl;
578    }
579
580
581    std::map<function_type, int> counts;
582    BOOST_FOREACH(function const& f, cos.functions)
583    {
584        counts[f.type]++;
585    }
586
587    if (counts[function_constructor] > 0)
588    {
589        quickbook_output_member(cos.functions, function_constructor, "Constructor", config, out);
590    }
591
592    if (counts[function_member] > 0)
593    {
594        quickbook_output_member(cos.functions, function_member, "Member Function", config, out);
595    }
596
597    quickbook_header(cos.location, config, out);
598    quickbook_markup(cos.qbk_markup, markup_any, markup_default, out);
599
600    out << "[endsect]" << std::endl
601        << std::endl;
602}
603
604
605#endif // QUICKBOOK_OUTPUT_HPP