summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-11-26 08:17:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-11-26 08:17:28 +0200
commita9fd81899df8a412f20784b3575b9707c530d1d1 (patch)
tree6fca6398cd3f719262695049bc720b97eabb1f67
parent4d9706d81ef5415556289c97f3fbaa899816070c (diff)
Indent multi-line lists in plain text output
-rw-r--r--cli/context.cxx21
-rw-r--r--cli/source.cxx40
2 files changed, 52 insertions, 9 deletions
diff --git a/cli/context.cxx b/cli/context.cxx
index 5731222..25a88a0 100644
--- a/cli/context.cxx
+++ b/cli/context.cxx
@@ -1375,14 +1375,29 @@ format (output_type ot, string const& s, bool para)
case block::li:
{
v += sn;
+ size_t ind (0);
switch (b.kind)
{
- case block::ul: v += "* " + pv; break;
- case block::ol: v += ph + ". " + pv; break;
- case block::dl: v += ph + "\n " + pv; break;
+ case block::ul: v += "* "; ind = 2; break;
+ case block::ol: v += ph + ". "; ind = ph.size () + 2; break;
+ case block::dl: v += ph + "\n "; ind = 8; break;
default: break;
}
+
+ // Add value with indentation for subsequent paragraphs.
+ //
+ char c, p ('\0'); // Current and previous characters.
+ for (size_t i (0); i != pv.size (); p = c, ++i)
+ {
+ c = pv[i];
+
+ if (p == '\n' && c != '\n') // Don't indent blanks.
+ v += string (ind, ' ');
+
+ v += c;
+ }
+
break;
}
case block::text:
diff --git a/cli/source.cxx b/cli/source.cxx
index 7bf5e8d..58637c8 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -246,27 +246,39 @@ namespace
{
assert (!d.empty ());
- string ind (indent, ' ');
os << string (indent - first, ' ');
+ // Count the number of leading spaces at the beginning of each line.
+ // Then use it as an extra indentation if we are breaking this line.
+ // This makes multi-line definition lists look decent. Note that this
+ // doesn't work for ordered/unordered lists because they start on the
+ // same line as number/bullet. However, there is hack to make it work:
+ // break the first line at the 80 characters boundary explicitly with
+ // \n.
+ //
+ size_t wc (0), wi (0); // Count and count-based indentation.
+ bool cws (true); // Count flag.
+
size_t b (0), e (0), i (0);
for (size_t n (d.size ()); i < n; ++i)
{
- if (d[i] == ' ' || d[i] == '\n')
+ char c (d[i]);
+
+ if (c == ' ' || c == '\n')
e = i;
- if (d[i] == '\n' || text_size (d, b, i - b) == 79 - indent)
+ if (c == '\n' || text_size (d, b, i - b) == 79 - indent - wi)
{
if (b != 0) // Not a first line.
os << endl
- << " << \"" << ind;
+ << " << \"" << string (indent + wi, ' ');
string s (d, b, (e != b ? e : i) - b);
os << escape_str (s) << "\" << ::std::endl";
// Handle consecutive newlines (e.g., pre, paragraph separator).
//
- if (d[i] == '\n')
+ if (c == '\n')
{
for (; i + 1 < n && d[i + 1] == '\n'; e = ++i)
os << endl
@@ -274,6 +286,22 @@ namespace
}
b = e = (e != b ? e : i) + 1;
+ wi = wc; // Start indent beginning with the next break.
+ }
+
+ if (c == '\n')
+ {
+ // Reset and start counting.
+ //
+ wc = wi = 0;
+ cws = true;
+ }
+ else if (cws)
+ {
+ if (c == ' ')
+ ++wc;
+ else
+ cws = false;
}
}
@@ -283,7 +311,7 @@ namespace
{
if (b != 0)
os << endl
- << " << \"" << ind;
+ << " << \"" << string (indent + wi, ' ');
string s (d, b, i - b);
os << escape_str (s) << "\" << ::std::endl";