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