summaryrefslogtreecommitdiff
path: root/cli/html.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-11-08 21:28:46 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-11-08 21:28:46 +0200
commit577a38358b295379511ea8bb130ef1dcb7157c0f (patch)
treeb127b18e013c4d09ee1f878ae367f8d83dfd20f6 /cli/html.cxx
parentbe7e864610327863e0c717fdec417ac2dcdaa2e9 (diff)
Implement HTML pages generation
Diffstat (limited to 'cli/html.cxx')
-rw-r--r--cli/html.cxx195
1 files changed, 195 insertions, 0 deletions
diff --git a/cli/html.cxx b/cli/html.cxx
new file mode 100644
index 0000000..b147703
--- /dev/null
+++ b/cli/html.cxx
@@ -0,0 +1,195 @@
+// file : cli/html.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include "html.hxx"
+
+namespace
+{
+ struct option: traversal::option, context
+ {
+ option (context& c) : context (c) {}
+
+ virtual void
+ traverse (type& o)
+ {
+ using semantics::names;
+
+ names& n (o.named ());
+
+ os << " <dt><code><b>";
+
+ for (names::name_iterator i (n.name_begin ()); i != n.name_end (); ++i)
+ {
+ if (i != n.name_begin ())
+ os << "</b></code>|<code><b>";
+
+ os << escape_html (*i);
+ }
+
+ os << "</b></code>";
+
+ type::doc_list const& doc (o.doc ());
+ string type (o.type ().name ());
+
+ std::set<string> arg_set;
+
+ if (type != "bool")
+ {
+ string s (
+ translate_arg (
+ doc.size () > 0 ? doc[0] : string ("<arg>"), arg_set));
+
+ os << ' ' << format (escape_html (s), ot_html);
+ }
+
+ os << "</dt>" << endl;
+
+ string d;
+
+ // If we have both the long and the short descriptions, use
+ // the long one.
+ //
+ if (type == "bool")
+ {
+ if (doc.size () > 1)
+ d = doc[1];
+ else if (doc.size () > 0)
+ d = doc[0];
+ }
+ else
+ {
+ if (doc.size () > 2)
+ d = doc[2];
+ else if (doc.size () > 1)
+ d = doc[1];
+ }
+
+ // Format the documentation string.
+ //
+ d = format (escape_html (translate (d, arg_set)), ot_html);
+
+ os << " <dd>";
+
+ 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);
+ }
+ }
+
+ os << "</dd>" << 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 += "&lt;";
+ break;
+ }
+ case '&':
+ {
+ r += "&amp;";
+ break;
+ }
+ default:
+ {
+ r += s[i];
+ break;
+ }
+ }
+ }
+
+ return r;
+ }
+ };
+
+ //
+ //
+ struct class_: traversal::class_, context
+ {
+ class_ (context& c)
+ : context (c), option_ (c)
+ {
+ names_option_ >> option_;
+ }
+
+ virtual void
+ traverse (type& c)
+ {
+ os << "<dl class=\"options\">" << endl;
+
+ names (c, names_option_);
+
+ os << "</dl>" << endl;
+ }
+
+ private:
+ option option_;
+ traversal::names names_option_;
+ };
+}
+
+void
+generate_html (context& ctx)
+{
+ traversal::cli_unit unit;
+ traversal::names unit_names;
+ traversal::namespace_ ns;
+ class_ cl (ctx);
+
+ unit >> unit_names >> ns;
+ unit_names >> cl;
+
+ traversal::names ns_names;
+
+ ns >> ns_names >> ns;
+ ns_names >> cl;
+
+ unit.dispatch (ctx.unit);
+}