From 5f7743da2fa5791e624b41ea1a749ccfa58a8f53 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 30 Oct 2015 10:47:45 +0200 Subject: Implement scope documentation generation in HTML --- cli/context.cxx | 7 +- cli/context.hxx | 4 +- cli/html.cxx | 203 +++++++++++++++++++++++++-------------------- cli/man.cxx | 4 +- cli/semantics/elements.hxx | 6 ++ cli/source.cxx | 6 +- 6 files changed, 132 insertions(+), 98 deletions(-) (limited to 'cli') diff --git a/cli/context.cxx b/cli/context.cxx index 1324b0c..332c22e 100644 --- a/cli/context.cxx +++ b/cli/context.cxx @@ -315,12 +315,13 @@ translate (string const& s, std::set const& set) } string context:: -format (string const& s, output_type ot) +format (output_type ot, string const& s, bool para) { string r; - r.reserve (s.size ()); - bool para (false); + if (para && ot == ot_html) + r += "

"; + bool escape (false); std::stack blocks; // Bit 0: code; 1: italic; 2: bold. diff --git a/cli/context.hxx b/cli/context.hxx index b6ce420..6eeaa3b 100644 --- a/cli/context.hxx +++ b/cli/context.hxx @@ -93,8 +93,10 @@ public: static string translate (string const&, std::set const&); + // If para is true, start a new paragraph. + // static string - format (string const&, output_type); + format (output_type, string const&, bool para); public: static string const& diff --git a/cli/html.cxx b/cli/html.cxx index 1679fd3..dd49a91 100644 --- a/cli/html.cxx +++ b/cli/html.cxx @@ -12,6 +12,98 @@ using namespace std; namespace { + static string + escape_html (string const& s) + { + string r; + r.reserve (s.size ()); + + for (size_t i (0), n (s.size ()); i < n; ++i) + { + switch (s[i]) + { + case '<': + { + r += "<"; + break; + } + case '&': + { + r += "&"; + break; + } + default: + { + r += s[i]; + break; + } + } + } + + return r; + } + + static void + wrap_lines (ostream& os, const string& d, size_t indent) + { + assert (!d.empty ()); + + size_t lim (78 - indent); + string ind (indent, ' '); + + size_t b (0), e (0), i (0); + + for (size_t n (d.size ()); i < n; ++i) + { + if (d[i] == ' ' || d[i] == '\n') + e = i; + + if (d[i] == '\n' || (i - b >= lim && e != b)) + { + os << (b != 0 ? "\n" : "") << ind << string (d, b, e - b); + + if (d[i] == '\n') + os << endl; + + b = e = e + 1; + } + } + + // Write the last line. + // + if (b != i) + os << (b != 0 ? "\n" : "") << ind << string (d, b, i - b); + } + + struct doc: traversal::doc, context + { + doc (context& c) : context (c) {} + + virtual void + traverse (type& ds) + { + // n = 1 - common doc string + // n = 2 - arg string, common doc string + // n > 2 - arg string, usage string, man string + // + size_t n (ds.size ()); + const string& d (n == 1 ? ds[0] : n == 2 ? ds[1] : ds[2]); + + if (d.empty ()) + return; + + std::set arg_set; + if (n > 1) + translate_arg (ds[0], arg_set); + + string s (format (ot_html, escape_html (translate (d, arg_set)), true)); + + wrap_lines (os, s, 2); + os << endl + << endl; + } + }; + struct option: traversal::option, context { option (context& c) : context (c) {} @@ -28,7 +120,7 @@ namespace names& n (o.named ()); - os << "

"; + os << "
"; for (names::name_iterator i (n.name_begin ()); i != n.name_end (); ++i) { @@ -50,7 +142,7 @@ namespace translate_arg ( doc.size () > 0 ? doc[0] : string (""), arg_set)); - os << ' ' << format (escape_html (s), ot_html); + os << ' ' << format (ot_html, escape_html (s), false); } os << "
" << endl; @@ -77,85 +169,14 @@ namespace // Format the documentation string. // - d = format (escape_html (translate (d, arg_set)), ot_html); - - os << "
"; - - if (!d.empty ()) - { - size_t b (0), e (0), i (0); - - for (size_t n (d.size ()); i < n; ++i) - { - if (d[i] == ' ' || d[i] == '\n') - e = i; - - if (d[i] == '\n' || (i - b >= 76 && e != b)) - { - if (b != 0) - { - os << endl - << " "; - } - - os << string (d, b, e - b); - - if (d[i] == '\n') - os << endl; - - b = e = e + 1; - } - } - - // Flush the last line. - // - if (b != i) - { - if (b != 0) - { - os << endl - << " "; - } - - os << string (d, b, i - b); - } - } + d = format (ot_html, escape_html (translate (d, arg_set)), false); - os << "
" << endl + wrap_lines (os, "
" + d + "
", 4); + os << endl << endl; } private: - string - escape_html (string const& s) - { - string r; - r.reserve (s.size ()); - - for (size_t i (0), n (s.size ()); i < n; ++i) - { - switch (s[i]) - { - case '<': - { - r += "<"; - break; - } - case '&': - { - r += "&"; - break; - } - default: - { - r += s[i]; - break; - } - } - } - - return r; - } }; // @@ -165,9 +186,7 @@ namespace class_ (context& c) : context (c), option_ (c) { - *this >> inherits_base_ >> base_ >> inherits_base_; - base_ >> names_option_; - + *this >> inherits_base_ >> *this; names_option_ >> option_; } @@ -177,15 +196,20 @@ namespace if (!options.exclude_base ()) inherits (c, inherits_base_); - names (c, names_option_); + if (!c.names_empty ()) + { + os << "
" << endl; + names (c, names_option_); + os << "
" << endl + << endl; + } } private: + traversal::inherits inherits_base_; + option option_; traversal::names names_option_; - - traversal::class_ base_; - traversal::inherits inherits_base_; }; } @@ -195,18 +219,21 @@ generate_html (context& ctx) traversal::cli_unit unit; traversal::names unit_names; traversal::namespace_ ns; + doc dc (ctx); class_ cl (ctx); - unit >> unit_names >> ns; + unit >> unit_names; + unit_names >> dc; + unit_names >> ns; unit_names >> cl; traversal::names ns_names; - ns >> ns_names >> ns; + ns >> ns_names; + ns_names >> dc; + ns_names >> ns; ns_names >> cl; - ctx.os << "
" << endl; - if (ctx.options.class_ ().empty ()) unit.dispatch (ctx.unit); else @@ -230,6 +257,4 @@ generate_html (context& ctx) } } } - - ctx.os << "
" << endl; } diff --git a/cli/man.cxx b/cli/man.cxx index b6fd7e8..d4ef7c5 100644 --- a/cli/man.cxx +++ b/cli/man.cxx @@ -50,7 +50,7 @@ namespace translate_arg ( doc.size () > 0 ? doc[0] : string (""), arg_set)); - os << ' ' << format (s, ot_man); + os << ' ' << format (ot_man, s, false); } os << "\"" << endl; @@ -77,7 +77,7 @@ namespace // Format the documentation string. // - d = format (translate (d, arg_set), ot_man); + d = format (ot_man, translate (d, arg_set), false); if (!d.empty ()) { diff --git a/cli/semantics/elements.hxx b/cli/semantics/elements.hxx index a0adce0..65a9382 100644 --- a/cli/semantics/elements.hxx +++ b/cli/semantics/elements.hxx @@ -347,6 +347,12 @@ namespace semantics return names_.end (); } + bool + names_empty () const + { + return names_.empty (); + } + virtual names_iterator_pair find (string const& name) const; diff --git a/cli/source.cxx b/cli/source.cxx index d5c3fd3..19cdb82 100644 --- a/cli/source.cxx +++ b/cli/source.cxx @@ -208,7 +208,7 @@ namespace l++; // ' ' seperator if (doc.size () > 0) - l += format (doc[0], ot_plain).size (); + l += format (ot_plain, doc[0], false).size (); else l += 5; // } @@ -268,7 +268,7 @@ namespace if (doc.size () > 0) { - string s (format (doc[0], ot_plain)); + string s (format (ot_plain, doc[0], false)); os << escape_str (s); l += s.size (); } @@ -306,7 +306,7 @@ namespace // Format the documentation string. // - d = format (d, ot_plain); + d = format (ot_plain, d, false); if (!d.empty ()) { -- cgit v1.1