From 4726db4a00c349550723d7cd4b8b4180661620cb Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 30 Oct 2015 12:20:47 +0200 Subject: Reimplement format() to first split string into paragraphs --- cli/context.cxx | 186 ++++++++++++++++++++++++++++++++++++-------------------- cli/context.hxx | 3 + 2 files changed, 124 insertions(+), 65 deletions(-) (limited to 'cli') diff --git a/cli/context.cxx b/cli/context.cxx index 332c22e..8de23ab 100644 --- a/cli/context.cxx +++ b/cli/context.cxx @@ -4,6 +4,7 @@ // license : MIT; see accompanying LICENSE file #include +#include #include "context.hxx" @@ -314,24 +315,21 @@ translate (string const& s, std::set const& set) return r; } -string context:: -format (output_type ot, string const& s, bool para) +void context:: +format_line (output_type ot, string& r, const char* s, size_t n) { - string r; - - if (para && ot == ot_html) - r += "

"; - bool escape (false); - std::stack blocks; // Bit 0: code; 1: italic; 2: bold. + stack blocks; // Bit 0: code; 1: italic; 2: bold. - for (size_t i (0), n (s.size ()); i < n; ++i) + for (size_t i (0); i < n; ++i) { + char c (s[i]); + if (escape) { bool block (false); - switch (s[i]) + switch (c) { case '\\': { @@ -491,8 +489,17 @@ format (output_type ot, string const& s, bool para) r += '}'; break; } + default: + { + cerr << "error: unknown escape sequence '\\" << c << "' in " + << "documentation paragraph '" << string (s, 0, n) << "'" + << endl; + throw generation_failed (); + } } + // If we just added a new block, add corresponding output markup. + // if (block) { unsigned char b (blocks.top ()); @@ -534,81 +541,130 @@ format (output_type ot, string const& s, bool para) escape = false; } - else if (s[i] == '\\') - { - escape = true; - } - else if (s[i] == '\n') + else // Not escape. { - switch (ot) + switch (c) { - case ot_plain: - case ot_man: + case '\\': { - r += '\n'; + escape = true; break; } - case ot_html: + case '.': { - if (para) - r += "

"; + if (ot == ot_man) + r += "\\."; else - para = true; - - r += "\n

"; - break; - } - } - } - else if (s[i] == '.') - { - if (ot == ot_man) - r += "\\."; - else - r += '.'; - } - else if (!blocks.empty () && s[i] == '}') - { - unsigned char b (blocks.top ()); - - switch (ot) - { - case ot_plain: - { - if (b & 1) - r += "'"; + r += '.'; break; } - case ot_html: + case '}': { - if (b & 4) - r += ""; + if (!blocks.empty ()) + { + unsigned char b (blocks.top ()); - if (b & 2) - r += ""; + switch (ot) + { + case ot_plain: + { + if (b & 1) + r += "'"; + break; + } + case ot_html: + { + if (b & 4) + r += ""; - if (b & 1) - r += ""; + if (b & 2) + r += ""; - break; - } - case ot_man: - { - if (b & 6) - r += "\\fP"; + if (b & 1) + r += ""; + + break; + } + case ot_man: + { + if (b & 6) + r += "\\fP"; + break; + } + } + + blocks.pop (); + break; + } + + // Fall through. } default: + r += c; break; } - - blocks.pop (); } - else - r += s[i]; } - if (para) - r += "

"; + if (!blocks.empty ()) + { + unsigned char b (blocks.top ()); + string bs; + + if (b & 1) bs += 'c'; + if (b & 2) bs += 'i'; + if (b & 4) bs += 'b'; + + cerr << "error: unterminated formatting block '\\" << bs << "' " + << "in documentation paragraph '" << string (s, 0, n) << "'" << endl; + throw generation_failed (); + } +} + +string context:: +format (output_type ot, string const& s, bool para) +{ + string r; + + // Iterate over lines (paragraphs). + // + for (size_t b (0), e (s.find ('\n')); b != e;) + { + bool first (b == 0), last (e == string::npos); + + if (first) // Before first line. + { + if (ot == ot_html && para) + r += "

"; + } + else // Between lines. + { + if (ot == ot_html && para) + r += "

"; + + r += '\n'; + + if (ot == ot_html) + { + r += "

"; + para = true; + } + } + + format_line (ot, r, s.c_str () + b, (last ? s.size () : e) - b); + + if (last) // After last line. + { + if (ot == ot_html && para) + r += "

"; + } + + // Get next line. + // + b = e; + if (!last) + e = s.find ('\n', ++b); + } return r; } diff --git a/cli/context.hxx b/cli/context.hxx index 6eeaa3b..33dc58e 100644 --- a/cli/context.hxx +++ b/cli/context.hxx @@ -98,6 +98,9 @@ public: static string format (output_type, string const&, bool para); + static void + format_line (output_type, string&, const char*, size_t); + public: static string const& ename (semantics::nameable& n) -- cgit v1.1