]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/quickbook_output.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / doc / src / docutils / tools / doxygen_xml2qbk / quickbook_output.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 //
3 // Copyright (c) 2010-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
5
6 // This file was modified by Oracle on 2014, 2015.
7 // Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
8
9 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
10
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14 //
15 //
16 #ifndef QUICKBOOK_OUTPUT_HPP
17 #define QUICKBOOK_OUTPUT_HPP
18
19
20 #include <string>
21 #include <vector>
22
23 #include <boost/algorithm/string.hpp>
24
25 #include <doxygen_elements.hpp>
26 #include <parameter_predicates.hpp>
27
28 std::string qbk_escaped(std::string const& s)
29 {
30 // Replace _ by unicode to avoid accidental quickbook underlining.
31 // 1) do NOT do this in quickbook markup, so not within []
32 // (e.g. to avoid [include get_point.qbk] having unicoded)
33 // 2) \[ and \] should not count as []
34 std::size_t const len = s.length();
35 int counter = 0;
36 std::string result = "";
37 for (std::size_t i = 0; i < len; i++)
38 {
39 switch(s[i])
40 {
41 case '[' : counter++; break;
42 case ']' : counter--; break;
43 case '\\' :
44 {
45 result += s[i];
46 if (i + 1 < len)
47 {
48 result += s[i + 1];
49 }
50 i++;
51 continue;
52 }
53 case '_' :
54 if (counter == 0)
55 {
56 result += "\\u005f";
57 continue;
58 }
59 }
60 result += s[i];
61 }
62
63 return result;
64 }
65
66
67 inline void next_item(std::string const& first, std::string const& indent,
68 std::size_t items_per_line,
69 std::size_t& index, std::ostream& out)
70 {
71 if (index > 0)
72 {
73 if (index % items_per_line == 0)
74 {
75 out << "," << std::endl << indent;
76 }
77 else
78 {
79 out << ", ";
80 }
81 }
82 else
83 {
84 std::cout << first;
85 }
86 index++;
87 }
88
89 void quickbook_template_parameter_list(std::vector<parameter> const& parameters,
90 std::string const& related_name,
91 std::ostream& out)
92 {
93 if (!parameters.empty())
94 {
95 std::string const header = "template<";
96 std::size_t index = 0;
97 std::string const indent(header.length(), ' ');
98 out << header;
99 BOOST_FOREACH(parameter const& p, parameters)
100 {
101 if (p.fulltype.empty())
102 {
103 std::cerr << "Warning: template parameter " << p.name << " has no type in " << related_name << std::endl;
104 }
105
106 next_item("", indent, 4, index, out);
107 out << p.fulltype;
108 }
109 out << ">" << std::endl;
110 }
111 }
112
113
114 void quickbook_synopsis(function const& f, std::ostream& out)
115 {
116 out << "``";
117 quickbook_template_parameter_list(f.template_parameters, f.name, out);
118
119 switch(f.type)
120 {
121 case function_constructor_destructor :
122 out << f.name;
123 break;
124 case function_member :
125 out << f.return_type << " " << f.name;
126 break;
127 case function_free :
128 out << f.definition;
129 break;
130 case function_define :
131 out << "#define " << f.name;
132 break;
133 case function_unknown :
134 // do nothing
135 break;
136 }
137
138 // Output the parameters
139 // Because we want to be able to skip, we cannot use the argstring
140 {
141 std::size_t index = 0;
142 std::string const indent(f.name.length() + f.return_type.length() + 2, ' ');
143 BOOST_FOREACH(parameter const& p, f.parameters)
144 {
145 if (! p.skip)
146 {
147 next_item("(", indent, 3, index, out);
148
149 out << p.fulltype << (p.fulltype.empty() ? "" : " ")
150 << p.name
151 << (p.default_value.empty() ? "" : " = ")
152 << p.default_value;
153 }
154 }
155 if (index > 0)
156 {
157 out << ")";
158 }
159 else if (f.type != function_define)
160 {
161 out << "()";
162 }
163 }
164
165 out << "``"
166 << std::endl
167 << std::endl;
168 }
169
170
171 void quickbook_synopsis(enumeration const& e, std::ostream& out)
172 {
173 out << "``enum " << e.name;
174 bool first = true;
175
176 bool has_many_values = e.enumeration_values.size() > 4;
177
178 BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
179 {
180 if (has_many_values)
181 {
182 if (first)
183 {
184 out << std::endl << "{";
185 }
186 else
187 {
188 out << ",";
189 }
190 out << std::endl << " " << value.name;
191 }
192 else
193 {
194 out << (first ? " {" : ", ") << value.name;
195 }
196 if (! value.initializer.empty())
197 {
198 // Doxygen 1.6 does not include "=" in the <initializer> tag, Doxygen 1.8 does.
199 // We just remove the "=" to have consistent output
200 out << " = " << boost::trim_copy(boost::replace_all_copy(value.initializer, "=", ""));
201 }
202 first = false;
203 }
204 if (! first)
205 {
206 if (has_many_values)
207 {
208 out << std::endl;
209 }
210 out << "};";
211 }
212 out << "``"
213 << std::endl
214 << std::endl;
215 }
216
217 inline bool includes(std::string const& filename, std::string const& header)
218 {
219 std::string result;
220
221 std::ifstream cpp_file(filename.c_str());
222 if (cpp_file.is_open())
223 {
224 while (! cpp_file.eof() )
225 {
226 std::string line;
227 std::getline(cpp_file, line);
228 boost::trim(line);
229 if (boost::starts_with(line, "#include")
230 && boost::contains(line, header))
231 {
232 return true;
233 }
234 }
235 }
236 return false;
237 }
238
239
240 std::string fix_location(std::string const& raw_location)
241 {
242 if ( raw_location.find("detail/") == std::string::npos
243 || raw_location.find("/interface.hpp") == std::string::npos )
244 {
245 return raw_location;
246 }
247
248 std::string fixed_location(raw_location);
249
250 fixed_location.erase(fixed_location.find("detail/"), 7u);
251 fixed_location.erase(fixed_location.find("/interface"), 10u);
252
253 return fixed_location;
254 }
255
256
257 std::string fix_include_header(std::string const& header)
258 {
259 if ( header.find("geometry/geometry.hpp") == std::string::npos )
260 {
261 return header;
262 }
263
264 std::string fixed_header(header);
265
266 fixed_header.erase(fixed_header.find("geometry/"), 9u);
267
268 return fixed_header;
269 }
270
271
272 void quickbook_header(std::string const& raw_location,
273 configuration const& config,
274 std::ostream& out)
275 {
276 std::string location = fix_location(raw_location);
277
278 if (! location.empty())
279 {
280 std::vector<std::string> including_headers;
281
282 // Select headerfiles containing to this location
283 BOOST_FOREACH(std::string const& header, config.convenience_headers)
284 {
285 if (includes(config.convenience_header_path + header, location))
286 {
287 including_headers.push_back(header);
288 }
289 }
290
291 out << "[heading Header]" << std::endl;
292 if (! including_headers.empty())
293 {
294 out << "Either"
295 << (including_headers.size() > 1 ? " one of" : "")
296 << std::endl << std::endl;
297 BOOST_FOREACH(std::string const& header, including_headers)
298 {
299 out << "`#include <" << fix_include_header(config.start_include + header) << ">`" << std::endl << std::endl;
300 }
301
302 out << std::endl << "Or" << std::endl << std::endl;
303 }
304 out << "`#include <" << location << ">`" << std::endl;
305 out << std::endl;
306 }
307 }
308
309
310 void quickbook_markup(std::vector<markup> const& qbk_markup,
311 markup_order_type order, markup_type type,
312 std::ostream& out)
313 {
314 bool has_output = false;
315 BOOST_FOREACH(markup const& inc, qbk_markup)
316 {
317 if (inc.type == type && inc.order == order)
318 {
319 out << inc.value << std::endl;
320 has_output = true;
321 }
322 }
323 if (has_output)
324 {
325 out << std::endl;
326 }
327 }
328
329
330
331 void quickbook_string_with_heading_if_present(std::string const& heading,
332 std::string const& contents, std::ostream& out)
333 {
334 if (! contents.empty())
335 {
336 out << "[heading " << heading << "]" << std::endl
337 << qbk_escaped(contents) << std::endl
338 << std::endl;
339 }
340 }
341
342 inline std::string to_section_name(std::string const& name)
343 {
344 // Make section-name lowercase and remove :: because these are filenames
345 return boost::to_lower_copy(boost::replace_all_copy(name, "::", "_"));
346 }
347
348 void quickbook_output_function_parameters(function const& f, std::ostream& out)
349 {
350 BOOST_FOREACH(parameter const& p, f.parameters)
351 {
352 if (! p.skip)
353 {
354 out << "[* " << p.fulltype << "]: ['" << p.name << "]: " << p.brief_description << std::endl << std::endl;
355 }
356 }
357 out << std::endl;
358 out << std::endl;
359 }
360
361 void quickbook_output_function_return(function const& f, std::ostream& out)
362 {
363 if (! f.return_description.empty())
364 {
365 out << f.return_description << std::endl;
366 }
367
368 out << std::endl;
369 }
370
371 inline std::string namespace_skipped(std::string const& name, configuration const& config)
372 {
373 return config.skip_namespace.empty()
374 ? name
375 : boost::replace_all_copy(name, config.skip_namespace, "")
376 ;
377 }
378
379 inline std::string output_if_different(std::string const& s, std::string const& s2)
380 {
381 return boost::equals(s, s2)
382 ? ""
383 : s + " "
384 ;
385 }
386
387 inline void quickbook_output_indexterm(std::string const& term, std::ostream& out
388 //, std::string const& secondary = ""
389 )
390 {
391 out << "'''";
392 if (boost::contains(term, "::"))
393 {
394 // "Unnamespace" it and add all terms (also namespaces)
395 std::vector<std::string> splitted;
396 std::string for_split = boost::replace_all_copy(term, "::", ":");
397 boost::split(splitted, for_split, boost::is_any_of(":"), boost::token_compress_on);
398 BOOST_FOREACH(std::string const& part, splitted)
399 {
400 out << "<indexterm><primary>" << part << "</primary></indexterm>";
401 }
402 }
403 else
404 {
405 out << "<indexterm><primary>" << term;
406 /*if (! secondary.empty())
407 {
408 out << "<secondary>" << secondary << "</secondary>";
409 }*/
410 out << "</primary></indexterm>";
411 }
412 out << "'''" << std::endl;
413 }
414
415 void quickbook_output(function const& f, configuration const& config, std::ostream& out)
416 {
417 // Write the parsed function
418 int arity = (int)f.parameters.size();
419
420 std::string additional_description;
421
422 if (! f.additional_description.empty())
423 {
424 additional_description = " (";
425 additional_description += f.additional_description;
426 additional_description += ")";
427 }
428
429 out << "[section:" << to_section_name(f.name);
430 // Make section name unique if necessary by arity and additional description
431 if (! f.unique)
432 {
433 out << "_" << arity;
434 if (! f.additional_description.empty())
435 {
436 out << "_" << boost::to_lower_copy(boost::replace_all_copy(f.additional_description, " ", "_"));
437 }
438 }
439 out << " " << f.name
440 << additional_description
441 << "]" << std::endl
442 << std::endl;
443
444 quickbook_output_indexterm(f.name, out);
445
446 out << qbk_escaped(f.brief_description) << std::endl;
447 out << std::endl;
448
449 quickbook_string_with_heading_if_present("Description", f.detailed_description, out);
450
451 // Synopsis
452 quickbook_markup(f.qbk_markup, markup_before, markup_synopsis, out);
453 out << "[heading Synopsis]" << std::endl;
454 quickbook_synopsis(f, out);
455 quickbook_markup(f.qbk_markup, markup_after, markup_synopsis, out);
456
457
458 out << "[heading Parameters]" << std::endl
459 << std::endl;
460
461 out << "[table" << std::endl << "[";
462 if (f.type != function_define)
463 {
464 out << "[Type] [Concept] ";
465 }
466 out << "[Name] [Description] ]" << std::endl;
467
468 // First: output any template parameter which is NOT used in the normal parameter list
469 BOOST_FOREACH(parameter const& tp, f.template_parameters)
470 {
471 if (! tp.skip)
472 {
473 std::vector<parameter>::const_iterator it = std::find_if(f.parameters.begin(), f.parameters.end(), par_by_type(tp.name));
474
475 if (it == f.parameters.end())
476 {
477 out << "[[" << tp.name << "] [" << tp.brief_description << "] [ - ] [Must be specified]]" << std::endl;
478 }
479 }
480 }
481
482 BOOST_FOREACH(parameter const& p, f.parameters)
483 {
484 if (! p.skip)
485 {
486 out << "[";
487 std::vector<parameter>::const_iterator it = std::find_if(f.template_parameters.begin(),
488 f.template_parameters.end(), par_by_name(p.type));
489
490 if (f.type != function_define)
491 {
492 out << "[" << p.fulltype
493 << "] [" << (it == f.template_parameters.end() ? "" : it->brief_description)
494 << "] ";
495 }
496 out << "[" << p.name
497 << "] [" << p.brief_description
498 << "]]"
499 << std::endl;
500 }
501 }
502 out << "]" << std::endl
503 << std::endl
504 << std::endl;
505
506 quickbook_string_with_heading_if_present("Returns", f.return_description, out);
507
508 quickbook_header(f.location, config, out);
509 quickbook_markup(f.qbk_markup, markup_any, markup_default, out);
510
511 out << std::endl;
512 out << "[endsect]" << std::endl;
513 out << std::endl;
514 }
515
516 void quickbook_output(enumeration const& e, configuration const& config, std::ostream& out)
517 {
518 out << "[section:" << to_section_name(e.name);
519 out << " " << e.name
520 << "]" << std::endl
521 << std::endl;
522
523 quickbook_output_indexterm(e.name, out);
524 BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
525 {
526 quickbook_output_indexterm(value.name, out);
527 }
528
529 out << e.brief_description << std::endl;
530 out << std::endl;
531
532 quickbook_string_with_heading_if_present("Description", e.detailed_description, out);
533
534 // Synopsis
535 quickbook_markup(e.qbk_markup, markup_before, markup_synopsis, out);
536 out << "[heading Synopsis]" << std::endl;
537 quickbook_synopsis(e, out);
538 quickbook_markup(e.qbk_markup, markup_after, markup_synopsis, out);
539
540
541 out << "[heading Values]" << std::endl
542 << std::endl;
543
544 out << "[table" << std::endl << "[";
545 out << "[Value] [Description] ]" << std::endl;
546
547 BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
548 {
549 out << "[[" << value.name
550 << "] [" << value.brief_description
551 << "]]"
552 << std::endl;
553 }
554 out << "]" << std::endl
555 << std::endl
556 << std::endl;
557
558 quickbook_header(e.location, config, out);
559 quickbook_markup(e.qbk_markup, markup_any, markup_default, out);
560
561 out << std::endl;
562 out << "[endsect]" << std::endl;
563 out << std::endl;
564 }
565
566 void quickbook_output_function(std::vector<function> const& functions,
567 function_type type,
568 std::string const& title,
569 configuration const& , std::ostream& out)
570 {
571 std::string returns = type == function_constructor_destructor ? "" : " [Returns]";
572 out << "[heading " << title << "(s)]" << std::endl
573 << "[table" << std::endl
574 << "[[Function] [Description] [Parameters] " << returns << "]" << std::endl;
575
576 BOOST_FOREACH(function const& f, functions)
577 {
578 if (f.type == type)
579 {
580 out << "[[";
581 quickbook_synopsis(f, out);
582 out << "] [" << f.brief_description << "] [";
583 quickbook_output_function_parameters(f, out);
584 out << "]";
585 if ( type != function_constructor_destructor )
586 {
587 out << "[" << std::endl;
588 quickbook_output_function_return(f, out);
589 out << "]" << std::endl;
590 }
591 out << "]" << std::endl;
592 }
593 }
594 out << "]" << std::endl
595 << std::endl;
596 }
597
598 void quickbook_output(class_or_struct const& cos, configuration const& config, std::ostream& out)
599 {
600 // Skip namespace
601 std::string short_name = namespace_skipped(cos.fullname, config);
602
603 // Write the parsed function
604 out << "[section:" << to_section_name(short_name) << " " << short_name << "]" << std::endl
605 << std::endl;
606
607 quickbook_output_indexterm(short_name, out);
608
609 out << cos.brief_description << std::endl;
610 out << std::endl;
611
612 quickbook_string_with_heading_if_present("Description", cos.detailed_description, out);
613
614 quickbook_markup(cos.qbk_markup, markup_before, markup_synopsis, out);
615 out << "[heading Synopsis]" << std::endl
616 << "``";
617 quickbook_template_parameter_list(cos.template_parameters, cos.name, out);
618 out << (cos.is_class ? "class" : "struct")
619 << " " << short_name << std::endl;
620
621 if (! cos.base_classes.empty())
622 {
623 out << " : ";
624 bool first = true;
625 BOOST_FOREACH(base_class const& bc, cos.base_classes)
626 {
627 if (! first)
628 {
629 out << std::endl << " , ";
630 }
631 out << output_if_different(bc.derivation, "private")
632 << output_if_different(bc.virtuality, "non-virtual")
633 << namespace_skipped(bc.name, config);
634 first = false;
635 }
636 out << std::endl;
637 }
638
639 out << "{" << std::endl;
640 if (! cos.variables.empty() && config.output_member_variables)
641 {
642 size_t maxlength = 0;
643 BOOST_FOREACH(parameter const& p, cos.variables)
644 {
645 if (! p.skip)
646 {
647 size_t length = 6 + p.fulltype.size() + p.name.size();
648 if (length > maxlength) maxlength = length;
649 }
650 }
651 BOOST_FOREACH(parameter const& p, cos.variables)
652 {
653 if (! p.skip)
654 {
655 size_t length = 4 + p.fulltype.size() + p.name.size();
656 out << " " << p.fulltype << " " << p.name << ";";
657 if (! p.brief_description.empty())
658 {
659 while(length++ < maxlength) out << " ";
660 out << "// " << p.brief_description;
661 }
662 out << std::endl;
663 }
664 }
665 }
666 else
667 {
668 out << " // ..." << std::endl;
669 }
670 out << "};" << std::endl
671 << "``" << std::endl << std::endl;
672 quickbook_markup(cos.qbk_markup, markup_after, markup_synopsis, out);
673
674
675
676 if (! cos.template_parameters.empty())
677 {
678 bool has_default = false;
679 BOOST_FOREACH(parameter const& p, cos.template_parameters)
680 {
681 if (! p.default_value.empty())
682 {
683 has_default = true;
684 }
685 }
686
687 out << "[heading Template parameter(s)]" << std::endl
688 << "[table" << std::endl
689 << "[[Parameter]";
690 if (has_default)
691 {
692 out << " [Default]";
693 }
694 out << " [Description]]" << std::endl;
695
696 BOOST_FOREACH(parameter const& p, cos.template_parameters)
697 {
698 out << "[[" << p.fulltype;
699 if (has_default)
700 {
701 out << "] [" << p.default_value;
702 }
703 out << "] [" << p.brief_description << "]]" << std::endl;
704 }
705 out << "]" << std::endl
706 << std::endl;
707 }
708
709
710 std::map<function_type, int> counts;
711 BOOST_FOREACH(function const& f, cos.functions)
712 {
713 counts[f.type]++;
714 }
715
716 if (counts[function_constructor_destructor] > 0)
717 {
718 quickbook_output_function(cos.functions, function_constructor_destructor, "Constructor", config, out);
719 }
720
721 if (counts[function_member] > 0)
722 {
723 quickbook_output_function(cos.functions, function_member, "Member Function", config, out);
724 }
725
726 quickbook_header(cos.location, config, out);
727 quickbook_markup(cos.qbk_markup, markup_any, markup_default, out);
728
729 out << "[endsect]" << std::endl
730 << std::endl;
731 }
732
733
734 // ----------------------------------------------------------------------------------------------- //
735 // ALT
736 // ----------------------------------------------------------------------------------------------- //
737
738 std::string remove_template_parameters(std::string const& name)
739 {
740 std::string res;
741 std::string::size_type prev_i = 0, i = 0;
742 int blocks_counter = 0;
743 for ( ;; )
744 {
745 std::string::size_type next_begin = name.find('<', i);
746 std::string::size_type next_end = name.find('>', i);
747
748 if ( next_begin == next_end )
749 {
750 res += name.substr(prev_i, next_begin - prev_i);
751 break;
752 }
753 else if ( next_begin < next_end )
754 {
755 i = next_begin + 1;
756 if ( blocks_counter == 0 )
757 res += name.substr(prev_i, next_begin - prev_i) + "<...>";
758 blocks_counter++;
759 }
760 else
761 {
762 i = next_end + 1;
763 blocks_counter--;
764 if ( blocks_counter == 0 )
765 prev_i = i;
766 }
767 }
768
769 return res;
770 }
771
772 std::string replace_brackets(std::string const& str)
773 {
774 return boost::replace_all_copy(boost::replace_all_copy(str, "[", "\\["), "]", "\\]");
775 }
776
777 void quickbook_output_enumerations(std::vector<enumeration> const& enumerations,
778 configuration const& ,
779 std::ostream& out)
780 {
781 out << "[table" << std::endl
782 << "[[Enumeration][Description]]" << std::endl;
783
784 for ( size_t i = 0 ; i < enumerations.size() ; ++i )
785 {
786 enumeration const& e = enumerations[i];
787
788 out << "[[[link " << e.id << " `";
789 out << e.name;
790 out << "`]][" << e.brief_description << "]]" << std::endl;
791 }
792 out << "]" << std::endl
793 << std::endl;
794 }
795
796 void quickbook_synopsis_short(function const& f, std::ostream& out)
797 {
798 if ( f.type != function_unknown )
799 out << f.name;
800
801 bool first = true;
802 BOOST_FOREACH(parameter const& p, f.parameters)
803 {
804 if ( !p.skip && p.default_value.empty() )
805 {
806 out << (first ? "(" : ", ") << remove_template_parameters(p.fulltype_without_links);
807 first = false;
808 }
809 }
810
811
812 if (! first)
813 out << ")";
814 else if (f.type != function_define)
815 out << "()";
816 }
817
818 void quickbook_output_functions(std::vector<function> const& functions,
819 function_type type,
820 configuration const& ,
821 std::ostream& out,
822 bool display_all = false,
823 std::string const& ColTitle = "Function")
824 {
825 bool show_modifiers = false;
826 BOOST_FOREACH(function const& f, functions)
827 {
828 if ( (display_all || f.type == type) && (f.is_const || f.is_static) && !f.brief_description.empty() )
829 show_modifiers = true;
830 }
831
832 out << "[table\n"
833 << "[";
834 if ( show_modifiers )
835 out << "[Modifier]";
836 out << "[" << ColTitle << "]";
837 out << "[Description]";
838 out << "]" << std::endl;
839
840 for ( size_t i = 0 ; i < functions.size() ; ++i )
841 {
842 function const& f = functions[i];
843
844 if ( f.brief_description.empty() )
845 continue;
846
847 if (display_all || f.type == type)
848 {
849 out << "[";
850 if ( show_modifiers )
851 {
852 out << "[";
853 out << (f.is_static ? "`static`" : "");
854 out << (f.is_const ? " `const`" : "");
855 out << "]";
856 }
857 out << "[[link " << f.id << " `";
858 quickbook_synopsis_short(f, out);
859 out << "`]]";
860 out << "[" << f.brief_description << "]";
861 out << "]" << std::endl;
862 }
863 }
864 out << "]" << std::endl
865 << std::endl;
866 }
867
868 void output_paragraphs_note_warning(element const& el, std::ostream & out)
869 {
870 // Additional paragraphs
871 if ( !el.paragraphs.empty() )
872 {
873 BOOST_FOREACH(paragraph const& p, el.paragraphs)
874 {
875 if ( !p.title.empty() )
876 out << "[heading " << p.title << "]" << std::endl;
877 else
878 out << "\n\n" << std::endl;
879 out << p.text << std::endl;
880 out << std::endl;
881 }
882 }
883
884 // Note
885 if ( !el.note.empty() )
886 {
887 out << "[note " << el.note << "]" << std::endl;
888 out << std::endl;
889 }
890
891 // Warning
892 if ( !el.warning.empty() )
893 {
894 out << "[warning " << el.warning << "]" << std::endl;
895 out << std::endl;
896 }
897 }
898
899 void inline_str_with_links(std::string const& str, std::ostream & out)
900 {
901 typedef std::string::size_type ST;
902
903 bool link_started = false;
904 bool first = true;
905 for ( ST i = 0 ; i < str.size() ; ++i )
906 {
907 if ( !link_started )
908 {
909 if ( str[i] == '[' && str.substr(i, 6) == "[link " )
910 {
911 if ( !first )
912 {
913 out << "`";
914 first = true;
915 }
916 link_started = true;
917 out << "[^[link ";
918 i += 5; // (+ 6 - 1)
919 }
920 else
921 {
922 if ( first )
923 {
924 out << "`";
925 first = false;
926 }
927 out << str[i];
928 }
929 }
930 else
931 {
932 if ( str[i] == '\\' )
933 {
934 out << str[i];
935 ++i;
936 if ( i < str.size() )
937 out << str[i];
938 }
939 else if ( str[i] == ']' )
940 {
941 out << "]]";
942 link_started = false;
943 }
944 else
945 out << str[i];
946 }
947 }
948
949 if ( !first )
950 out << "`";
951 if ( link_started )
952 out << "]]";
953 }
954
955 void quickbook_template_parameter_list_alt(std::vector<parameter> const& parameters, std::ostream& out)
956 {
957 std::string next_param;
958
959 if ( 2 < parameters.size() )
960 next_param = std::string("`,`\n") + " ";
961 else
962 next_param = "`,` ";
963
964 if (!parameters.empty())
965 {
966 out << "`template<`" ;
967 bool first = true;
968 BOOST_FOREACH(parameter const& p, parameters)
969 {
970 out << (first ? "" : next_param.c_str());
971 inline_str_with_links(p.fulltype, out);
972
973 if ( !p.default_value.empty() )
974 {
975 out << " = ";
976 // don't display default values from details
977 if ( p.default_value.find("detail") != std::string::npos )
978 out << "/default/";
979 else
980 inline_str_with_links(p.default_value, out);
981 }
982
983 first = false;
984 }
985 out << "`>`";
986 }
987 }
988
989 void quickbook_synopsis_alt(function const& f, std::ostream& out)
990 {
991 out << "[pre\n";
992 quickbook_template_parameter_list_alt(f.template_parameters, out);
993 out << "\n";
994
995 std::size_t offset = 1; // '('
996 switch(f.type)
997 {
998 case function_constructor_destructor :
999 out << "`" << f.name << "`";
1000 offset += f.name.size();
1001 break;
1002 case function_member :
1003 case function_free :
1004 // don't display return types from details
1005 if ( f.return_type.find("detail") != std::string::npos )
1006 {
1007 out << "/unspecified/";
1008 offset += 11;
1009 }
1010 else
1011 {
1012 inline_str_with_links(f.return_type, out);
1013 offset += f.return_type_without_links.size();
1014 }
1015 out << " `" << f.name << "`";
1016 offset += 1 + f.name.size();
1017 break;
1018 case function_define :
1019 out << "`#define " << f.name << "`";
1020 offset += 8 + f.name.size();
1021 break;
1022 case function_unknown :
1023 // do nothing
1024 break;
1025 }
1026
1027 std::string par_end("`,` ");
1028 if ( 2 < f.parameters.size() )
1029 par_end = std::string("`,`\n") + std::string(offset, ' ');
1030
1031 // Output the parameters
1032 // Because we want to be able to skip, we cannot use the argstring
1033 {
1034 bool first = true;
1035 BOOST_FOREACH(parameter const& p, f.parameters)
1036 {
1037 if (! p.skip)
1038 {
1039 out << (first ? "`(`" : par_end);
1040 if ( !p.fulltype.empty() )
1041 {
1042 inline_str_with_links(p.fulltype, out);
1043 out << " ";
1044 }
1045 if ( !p.name.empty() )
1046 out << "`" << p.name << "`";
1047 if ( !p.default_value.empty() )
1048 {
1049 out << " = ";
1050 // don't display default values from details
1051 if ( p.default_value.find("detail") != std::string::npos )
1052 out << "/default/";
1053 else
1054 inline_str_with_links(p.default_value, out);
1055 }
1056 first = false;
1057 }
1058 }
1059
1060 if (! first)
1061 out << "`)`\n";
1062 else if (f.type != function_define)
1063 out << "`()`\n";
1064 }
1065
1066 out << "]"
1067 << std::endl
1068 << std::endl;
1069 }
1070
1071 void quickbook_synopsis_alt(class_or_struct const& cos, configuration const& config, std::ostream & out)
1072 {
1073 std::string short_name = namespace_skipped(cos.fullname, config);
1074
1075 out << "[pre\n";
1076
1077 quickbook_template_parameter_list_alt(cos.template_parameters, out);
1078 out << "\n";
1079
1080 out << (cos.is_class ? "`class " : "`struct ");
1081 {
1082 std::string::size_type last_scope = std::string::npos;
1083 std::string::size_type i = short_name.find("<");
1084 for(std::string::size_type j = short_name.find("::") ; j < i ; j = short_name.find("::", j+1))
1085 last_scope = j;
1086 if ( last_scope == std::string::npos )
1087 out << short_name << "`" << std::endl;
1088 else
1089 out << short_name.substr(last_scope + 2) << "`" << std::endl;
1090 }
1091
1092 if (! cos.base_classes.empty())
1093 {
1094 bool first = true;
1095 BOOST_FOREACH(base_class const& bc, cos.base_classes)
1096 {
1097 // don't display base classes from details
1098 if ( bc.name.find("detail") != std::string::npos )
1099 continue;
1100
1101 if (first)
1102 out << "` : ";
1103 else
1104 out << std::endl << " , ";
1105 out << output_if_different(bc.derivation, "private")
1106 << output_if_different(bc.virtuality, "non-virtual")
1107 << namespace_skipped(bc.name, config);
1108 first = false;
1109 }
1110 if (!first)
1111 out << "`" << std::endl;
1112 }
1113
1114 out << "`{`" << std::endl
1115 << "` // ...`" << std::endl
1116 << "`};`" << std::endl
1117 << "]" << std::endl << std::endl;
1118 }
1119
1120 void quickbook_synopsis_alt(enumeration const& e, std::ostream& out)
1121 {
1122 std::string values_separator =
1123 e.enumeration_values.size() <= 2 ?
1124 std::string(", ") :
1125 ( std::string(",\n") + std::string(e.name.size() + 7, ' ') );
1126
1127 out << "``enum " << e.name << " ";
1128 bool first = true;
1129 BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
1130 {
1131 out << (first ? "{" : values_separator.c_str());
1132 out << value.name;
1133 if ( !value.initializer.empty() )
1134 {
1135 out << " = " << boost::trim_copy(boost::replace_all_copy(value.initializer, "=", ""));
1136 }
1137 first = false;
1138 }
1139 if (! first)
1140 {
1141 out << "};";
1142 }
1143 out << "``"
1144 << std::endl
1145 << std::endl;
1146 }
1147
1148 template <typename Range>
1149 bool has_brief_description(Range const& rng)
1150 {
1151 typedef typename Range::value_type V;
1152 BOOST_FOREACH(V const& bc, rng)
1153 {
1154 if ( !bc.brief_description.empty() )
1155 return true;
1156 }
1157 return false;
1158 }
1159
1160 template <typename Range>
1161 bool has_brief_description(Range const& rng, function_type t)
1162 {
1163 typedef typename Range::value_type V;
1164 BOOST_FOREACH(V const& bc, rng)
1165 {
1166 if ( bc.type == t && !bc.brief_description.empty() )
1167 return true;
1168 }
1169 return false;
1170 }
1171
1172 void quickbook_output_functions_details(std::vector<function> const& functions,
1173 function_type type,
1174 configuration const& ,
1175 std::ostream& out,
1176 bool display_all = false)
1177 {
1178 for ( size_t i = 0 ; i < functions.size() ; ++i )
1179 {
1180 function const& f = functions[i];
1181
1182 if ( f.brief_description.empty() )
1183 continue;
1184
1185 if ( display_all || f.type == type )
1186 {
1187 // Section
1188 std::stringstream ss;
1189 quickbook_synopsis_short(f, ss);
1190 out << "[#" << f.id << "]" << std::endl;
1191 out << "[section " << replace_brackets(ss.str()) << "]" << std::endl;
1192
1193 quickbook_output_indexterm(f.name, out);
1194
1195 // Brief description
1196 out << f.brief_description << std::endl;
1197 out << std::endl;
1198
1199 // Detail description
1200 if ( !f.detailed_description.empty() )
1201 {
1202 out << "[heading Description]" << std::endl;
1203 out << f.detailed_description;
1204 }
1205
1206 // Synopsis
1207 quickbook_markup(f.qbk_markup, markup_before, markup_synopsis, out);
1208 out << "[heading Synopsis]" << std::endl;
1209 quickbook_synopsis_alt(f, out);
1210 quickbook_markup(f.qbk_markup, markup_after, markup_synopsis, out);
1211
1212 if ( f.is_static || f.is_virtual || f.is_explicit || f.is_const )
1213 {
1214 out << "[heading Modifier(s)]" << std::endl;
1215 out << "``"
1216 << (f.is_static ? "static " : "")
1217 << (f.is_virtual ? "virtual " : "")
1218 << (f.is_explicit ? "explicit " : "")
1219 << (f.is_const ? "const " : "")
1220 << "``";
1221 }
1222
1223 // Template parameters
1224 if ( !f.template_parameters.empty() && has_brief_description(f.template_parameters) )
1225 {
1226 out << "[heading Template parameter(s)]" << std::endl
1227 << "[table" << std::endl
1228 << "[[Parameter] [Description]]" << std::endl;
1229
1230 BOOST_FOREACH(parameter const& p, f.template_parameters)
1231 {
1232 if ( p.brief_description.empty() )
1233 continue;
1234
1235 out << "[[`";
1236 if ( p.fulltype.find("typename ") == 0 )
1237 out << p.fulltype.substr(9);
1238 else if ( p.fulltype.find("class ") == 0 )
1239 out << p.fulltype.substr(6);
1240 else
1241 out << p.fulltype;
1242 out << "`][" << p.brief_description << "]]" << std::endl;
1243 }
1244 out << "]" << std::endl
1245 << std::endl;
1246 }
1247
1248 // Parameters
1249 if ( !f.parameters.empty() && has_brief_description(f.parameters) )
1250 {
1251 out << "[heading Parameter(s)]" << std::endl;
1252 out << "[table " << std::endl;
1253 out << "[";
1254 if ( f.type != function_define )
1255 out << "[Type]";
1256 out << "[Name][Description]]" << std::endl;
1257 BOOST_FOREACH(parameter const& p, f.parameters)
1258 {
1259 if (!p.skip)
1260 {
1261 out << "[";
1262 if ( f.type != function_define )
1263 {
1264 out << "[";
1265 inline_str_with_links(p.fulltype, out);
1266 out << "]";
1267 }
1268 out << "[ `" << p.name << "` ][" << p.brief_description << "]]"<< std::endl;
1269 }
1270 }
1271 out << "]" << std::endl;
1272 }
1273
1274 // Precondition
1275 if ( !f.precondition.empty() )
1276 {
1277 out << "[heading Precondition(s)]" << std::endl;
1278 out << f.precondition << std::endl;
1279 out << std::endl;
1280 }
1281
1282 // Return
1283 if ( !f.return_description.empty() )
1284 {
1285 out << "[heading Returns]" << std::endl;
1286 out << f.return_description << std::endl;
1287 }
1288
1289 // Additional paragraphs, note, warning
1290 output_paragraphs_note_warning(f, out);
1291
1292 // QBK markup
1293 quickbook_markup(f.qbk_markup, markup_any, markup_default, out);
1294
1295 // Section end
1296 out << "[endsect]" << std::endl
1297 //<< "[br]" << std::endl
1298 << std::endl;
1299 }
1300 }
1301 }
1302
1303 void quickbook_output_enumeration_details(enumeration const& e, configuration const& , std::ostream& out)
1304 {
1305 out << "[#" << e.id << "]\n";
1306 out << "[section " << e.name << "]" << std::endl
1307 << std::endl;
1308
1309 quickbook_output_indexterm(e.name, out);
1310 BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
1311 {
1312 quickbook_output_indexterm(value.name, out);
1313 }
1314
1315 out << e.brief_description << std::endl;
1316 out << std::endl;
1317
1318 if ( !e.detailed_description.empty() )
1319 {
1320 out << "[heading Description]\n\n";
1321 out << e.detailed_description << "\n\n";
1322 }
1323
1324 // Additional paragraphs, note, warning
1325 output_paragraphs_note_warning(e, out);
1326
1327 quickbook_markup(e.qbk_markup, markup_any, markup_default, out);
1328
1329 // Synopsis
1330 quickbook_markup(e.qbk_markup, markup_before, markup_synopsis, out);
1331 out << "[heading Synopsis]" << std::endl;
1332 quickbook_synopsis_alt(e, out);
1333 quickbook_markup(e.qbk_markup, markup_after, markup_synopsis, out);
1334
1335
1336 out << "[heading Values]" << std::endl
1337 << std::endl;
1338
1339 out << "[table" << std::endl << "[";
1340 out << "[Value] [Description] ]" << std::endl;
1341
1342 BOOST_FOREACH(enumeration_value const& value, e.enumeration_values)
1343 {
1344 out << "[[" << value.name << "] [" << value.brief_description << "]]\n";
1345 }
1346 out << "]\n\n\n";
1347
1348 out << std::endl;
1349 out << "[endsect]" << std::endl;
1350 out << std::endl;
1351 }
1352
1353 void quickbook_output_alt(documentation const& doc, configuration const& config, std::ostream& out)
1354 {
1355 if ( !doc.group_id.empty() )
1356 {
1357 std::cout << "[section:" << doc.group_id << " " << doc.group_title << "]" << std::endl;
1358 }
1359
1360 if ( !doc.enumerations.empty() )
1361 {
1362 std::cout << "[heading Enumerations]\n";
1363 quickbook_output_enumerations(doc.enumerations, config, out);
1364 }
1365
1366 if ( !doc.defines.empty() )
1367 {
1368 std::cout << "[heading Defines]\n";
1369 quickbook_output_functions(doc.defines, function_unknown, config, out, true, "Define");
1370 }
1371
1372 if ( !doc.functions.empty() )
1373 {
1374 std::cout << "[heading Functions]\n";
1375 quickbook_output_functions(doc.functions, function_unknown, config, out, true, "Function");
1376 }
1377
1378 BOOST_FOREACH(enumeration const& e, doc.enumerations)
1379 {
1380 quickbook_output_enumeration_details(e, config, out);
1381 }
1382
1383 quickbook_output_functions_details(doc.defines, function_unknown, config, out, true);
1384 quickbook_output_functions_details(doc.functions, function_unknown, config, out, true);
1385
1386 if ( !doc.group_id.empty() )
1387 {
1388 out << "[endsect]" << std::endl
1389 << std::endl;
1390 }
1391 }
1392
1393 void quickbook_output_alt(class_or_struct const& cos, configuration const& config, std::ostream& out)
1394 {
1395 // Skip namespace
1396 std::string short_name = namespace_skipped(cos.fullname, config);
1397
1398 BOOST_ASSERT(configuration::alt == config.output_style);
1399
1400 if ( !cos.id.empty() )
1401 out << "[#" << cos.id << "]" << std::endl;
1402 out << "[section " << short_name << "]" << std::endl << std::endl;
1403
1404 // WARNING! Can't be used in the case of specializations
1405 quickbook_output_indexterm(short_name, out);
1406
1407 // Brief
1408
1409 out << cos.brief_description << std::endl;
1410 out << std::endl;
1411
1412 // Description
1413
1414 quickbook_string_with_heading_if_present("Description", cos.detailed_description, out);
1415
1416 // Additional paragraphs, note, warning
1417 output_paragraphs_note_warning(cos, out);
1418
1419 // Markup
1420 quickbook_markup(cos.qbk_markup, markup_any, markup_default, out);
1421
1422 // Header
1423
1424 quickbook_header(cos.location, config, out);
1425
1426 // Class synposis
1427
1428 quickbook_markup(cos.qbk_markup, markup_before, markup_synopsis, out);
1429 out << "[heading Synopsis]" << std::endl;
1430 quickbook_synopsis_alt(cos, config, out);
1431 quickbook_markup(cos.qbk_markup, markup_after, markup_synopsis, out);
1432
1433 // Template parameters
1434
1435 if (! cos.template_parameters.empty())
1436 {
1437 if ( has_brief_description(cos.template_parameters) )
1438 {
1439 out << "[heading Template parameter(s)]" << std::endl
1440 << "[table" << std::endl
1441 << "[[Parameter] [Description]]" << std::endl;
1442
1443 BOOST_FOREACH(parameter const& p, cos.template_parameters)
1444 {
1445 if ( p.brief_description.empty() )
1446 continue;
1447
1448 out << "[[`";
1449 if ( p.fulltype.find("typename ") == 0 )
1450 out << p.fulltype.substr(9);
1451 else if ( p.fulltype.find("class ") == 0 )
1452 out << p.fulltype.substr(6);
1453 else
1454 out << p.fulltype;
1455 out << "`][" << p.brief_description << "]]" << std::endl;
1456 }
1457 out << "]" << std::endl
1458 << std::endl;
1459 }
1460 }
1461
1462 // Typedefs
1463
1464 if ( !cos.typedefs.empty() )
1465 {
1466 if ( has_brief_description(cos.typedefs) )
1467 {
1468 out << "[heading Typedef(s)]" << std::endl
1469 << "[table" << std::endl
1470 << "[[Type]";
1471 out << " [Description]]" << std::endl;
1472
1473 BOOST_FOREACH(base_element const& e, cos.typedefs)
1474 {
1475 if ( e.brief_description.empty() )
1476 continue;
1477
1478 out << "[[";
1479 if ( !e.id.empty() )
1480 out << "[#" << e.id << "]" << " ";
1481 out << "`" << e.name << "`";
1482 out << "][" << e.brief_description << "]]" << std::endl;
1483 }
1484 out << "]" << std::endl
1485 << std::endl;
1486 }
1487 }
1488
1489 // Members
1490
1491 bool display_ctors = has_brief_description(cos.functions, function_constructor_destructor);
1492 bool display_members = has_brief_description(cos.functions, function_member);
1493
1494 std::map<function_type, int> counts;
1495 BOOST_FOREACH(function const& f, cos.functions)
1496 {
1497 counts[f.type]++;
1498 }
1499
1500 if (display_ctors && counts[function_constructor_destructor] > 0)
1501 {
1502 out << "[heading Constructor(s) and destructor]" << std::endl;
1503 quickbook_output_functions(cos.functions, function_constructor_destructor, config, out);
1504 }
1505
1506 if (display_members && counts[function_member] > 0)
1507 {
1508 out << "[heading Member(s)]" << std::endl;
1509 quickbook_output_functions(cos.functions, function_member, config, out);
1510 }
1511
1512 // Details start
1513
1514 //if ( display_ctors || display_members )
1515 // out << "[br]" << std::endl;
1516
1517 if (display_ctors && counts[function_constructor_destructor] > 0)
1518 quickbook_output_functions_details(cos.functions, function_constructor_destructor, config, out);
1519
1520 if (display_members && counts[function_member] > 0)
1521 quickbook_output_functions_details(cos.functions, function_member, config, out);
1522
1523 // Details end
1524
1525 out << "[endsect]" << std::endl
1526 << std::endl;
1527 }
1528
1529 #endif // QUICKBOOK_OUTPUT_HPP