From 68381760c89c01520ac2286f0fe48ce8c2ab9a41 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 16 Apr 2018 14:07:04 +0200 Subject: Add support for note formatting in plain text output --- cli/context.cxx | 43 ++++++++++------ cli/source.cxx | 2 +- cli/txt.cxx | 34 ++++++++++--- cli/txt.hxx | 5 +- tests/note/testscript | 137 ++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 188 insertions(+), 33 deletions(-) diff --git a/cli/context.cxx b/cli/context.cxx index 7c653a1..66f91c6 100644 --- a/cli/context.cxx +++ b/cli/context.cxx @@ -831,12 +831,9 @@ format_line (output_type ot, string& r, const char* l, size_t n) { if ((s & note) != 0) { - cerr << "error: \\N{} in plain text output not yet supported" - << endl; - throw generation_failed (); + r += "[Note: "; } - - if ((s & link) == 0) + else if ((s & link) == 0) { if (color) { @@ -951,9 +948,11 @@ format_line (output_type ot, string& r, const char* l, size_t n) { case ot_plain: { - assert ((s & note) == 0); - - if (s & link) + if ((s & note) != 0) + { + r += ']'; + } + else if ((s & link) != 0) { string t (link_section.empty () ? link_target @@ -1014,11 +1013,11 @@ format_line (output_type ot, string& r, const char* l, size_t n) } case ot_html: { - if (s & note) + if ((s & note) != 0) { r += ""; } - else if (s & link) + else if ((s & link) != 0) { if (link_empty) { @@ -1052,7 +1051,7 @@ format_line (output_type ot, string& r, const char* l, size_t n) { assert ((s & note) == 0); - if (s & link) + if ((s & link) != 0) { string t (link_section.empty () ? link_target @@ -2089,9 +2088,25 @@ format (semantics::scope& scope, string const& s, bool para) } case block::note: { - cerr << "error: " << pb.kind << "| in plain text output not " - << "yet supported" << endl; - throw generation_failed (); + v += dn; + + // Add a special character (bell) plus space in front of every + // line (including blanks). The bell is recognized and + // translated by txt_wrap_lines() to '|'. + // + char p ('\n'); // Previous character. + for (size_t i (0), n (pv.size ()); i != n; ++i) + { + char c (pv[i]); + + if (p == '\n') + v += (c != '\n' ? "\x07 " : "\x07"); + + v += c; + p = c; + } + + break; } case block::text: case block::pre: assert (false); diff --git a/cli/source.cxx b/cli/source.cxx index 282d5e5..be7ff3f 100644 --- a/cli/source.cxx +++ b/cli/source.cxx @@ -207,7 +207,7 @@ namespace inline void wrap_lines (ostream& os, - const string& d, + string& d, size_t indent = 0, size_t first = 0) { diff --git a/cli/txt.cxx b/cli/txt.cxx index c44e4ff..1b6dbc6 100644 --- a/cli/txt.cxx +++ b/cli/txt.cxx @@ -4,6 +4,7 @@ // license : MIT; see accompanying LICENSE file #include +#include // strlen() #include #include @@ -38,7 +39,7 @@ txt_size (const string& s, size_t p, size_t n) void txt_wrap_lines (ostream& os, - const string& d, + string& d, size_t indent, size_t first, const char* line_start, @@ -61,19 +62,33 @@ txt_wrap_lines (ostream& os, size_t wc (0), wi (0); // Count and count-based indentation. bool cws (true); // Count flag. + // @@ TODO: while this should support notes inside lists, lists inside + // notes will require splitting indentation into before/after '|'. + // + const char* ne (""); // Note. + const char* np (""); // Note prefix. + size_t b (0), e (0), i (0); for (size_t n (d.size ()); i < n; ++i) { - char c (d[i]); + char& c (d[i]); + + // Translate note character. + // + if (c == 0x07) + { + c = '|'; + ne = "| "; + } if (c == ' ' || c == '\n') e = i; - if (c == '\n' || txt_size (d, b, i - b) == 79 - indent - wi) + if (c == '\n' || txt_size (d, b, i - b) == 79 - indent - wi - strlen (np)) { if (b != 0) // Not a first line. os << endl - << line_start << string (indent + wi, ' '); + << line_start << string (indent + wi, ' ') << np; string s (d, b, (e != b ? e : i) - b); @@ -92,14 +107,19 @@ txt_wrap_lines (ostream& os, } b = e = (e != b ? e : i) + 1; - wi = wc; // Start indent beginning with the next break. + + // Start indenting/noting beginning with the next break. + // + wi = wc; + np = ne; } if (c == '\n') { - // Reset and start counting. + // Reset counters, clear notes, and start counting. // wc = wi = 0; + ne = np = ""; cws = true; } else if (cws) @@ -117,7 +137,7 @@ txt_wrap_lines (ostream& os, { if (b != 0) os << endl - << line_start << string (indent + wi, ' '); + << line_start << string (indent + wi, ' ') << np; string s (d, b, i - b); diff --git a/cli/txt.hxx b/cli/txt.hxx index b8cf7f0..6a9f8de 100644 --- a/cli/txt.hxx +++ b/cli/txt.hxx @@ -31,9 +31,12 @@ txt_size (const std::string&, // line_{start, end, blank} arguments specify optional extra text for the // start/end of the non-empty line as well as for the blank (empty) line. // +// Note that the funtion modifies the passed string in order to translate +// notes. +// void txt_wrap_lines (std::ostream& os, - const std::string&, + std::string&, std::size_t indent = 0, std::size_t first = 0, const char* line_start = "", diff --git a/tests/note/testscript b/tests/note/testscript index 1e302bd..c51b935 100644 --- a/tests/note/testscript +++ b/tests/note/testscript @@ -12,49 +12,159 @@ Leading paragraph. \N|This is a note block one.| -Interleaving paragraph. +Interleaving paragraph that is quite long and therefore it may span many +lines in order to make text easy to read. -\N|This is a note block two.| +\N|This is a note block two that is quite long and therefore it may span many +lines in order to make text easy to read.| Trailing paragraph. " EOI -$* --generate-html --stdout test.cli >>EOO +$* --generate-html --stdout test.cli >>EOO;

Leading paragraph.

This is a note block one.

-

Interleaving paragraph.

+

Interleaving paragraph that is quite long and therefore it may span many + lines in order to make text easy to read.

-

This is a note block two.

+

This is a note block two that is quite long and therefore it may span + many lines in order to make text easy to read.

Trailing paragraph.

EOO + $* --generate-txt --stdout test.cli >>EOO +Leading paragraph. + +| This is a note block one. + +Interleaving paragraph that is quite long and therefore it may span many lines +in order to make text easy to read. + +| This is a note block two that is quite long and therefore it may span many +| lines in order to make text easy to read. + +Trailing paragraph. +EOO + : block-multi-para : cat <=test.cli; " \N| -This is a note para one. +This is a note para one that is quite long and therefore it may span many +lines in order to make text easy to read. This is a note para two. | " EOI -$* --generate-html --stdout test.cli >>EOO +$* --generate-html --stdout test.cli >>EOO;
-

This is a note para one.

+

This is a note para one that is quite long and therefore it may span many + lines in order to make text easy to read.

This is a note para two.

EOO +$* --generate-txt --stdout test.cli >>EOO +| This is a note para one that is quite long and therefore it may span many +| lines in order to make text easy to read. +| +| This is a note para two. +EOO + +: block-pre +: +cat <=test.cli; +" + +\N| +This is a note para one. + +\ +And this is a +pre-formatter text fragment. +\ + +| +" +EOI +$* --generate-html --stdout test.cli >>EOO; +
+

This is a note para one.

+ +
And this is a
+pre-formatter text fragment.
+
+ +EOO +$* --generate-txt --stdout test.cli >>EOO +| This is a note para one. +| +| And this is a +| pre-formatter text fragment. +EOO + +# This is not yet supported (see txt_wrap_lines()). +# +#\ +: block-list +: +cat <=test.cli; +" +\N|This is a note para one followed by a list. + +\ul| + +\li|This is a list item that is quite long and therefore it may span many +lines in order to make text easy to read.||| +" +EOI +$* --generate-html --stdout test.cli >>EOO; +EOO +$* --generate-txt --stdout test.cli >>EOO +EOO +#\ + +: block-in-list +: +cat <=test.cli; +" +\ul| + +\li|Normal text para. + +\N|This is a note para one that is quite long and therefore it may span many +lines in order to make text easy to read.||| +" +EOI +$* --generate-html --stdout test.cli >>EOO; +
    +
  • Normal text para. + +
    +

    This is a note para one that is quite long and therefore it may span many + lines in order to make text easy to read.

    +
  • +
+ +EOO +$* --generate-txt --stdout test.cli >>EOO +* Normal text para. + + | This is a note para one that is quite long and therefore it may span many + | lines in order to make text easy to read. +EOO + : span-basics : @@ -63,11 +173,15 @@ cat <=test.cli; This is normal text. \N{This is a note.} And this is normal text again. " EOI -$* --generate-html --stdout test.cli >>EOO +$* --generate-html --stdout test.cli >>EOO;

This is normal text. This is a note. And this is normal text again.

EOO + $* --generate-txt --stdout test.cli >>EOO +This is normal text. [Note: This is a note.] And this is normal text again. +EOO + : span-nested-link : @@ -76,8 +190,11 @@ cat <=test.cli; \N{This is a note with a \l{https://example.com link} inside.} " EOI -$* --generate-html --stdout test.cli >>EOO +$* --generate-html --stdout test.cli >>EOO;

This is a note with a link inside.

EOO +$* --generate-txt --stdout test.cli >>EOO +[Note: This is a note with a link (https://example.com) inside.] +EOO -- cgit v1.1