summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-04-12 17:42:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-04-12 17:42:06 +0200
commit28328f1366db8bce39bd5a862f835d778b91d5ca (patch)
tree53bcf16350f0357575b4fa37e5de64f1e1c28671
parentbffe74e67f69fb4ad928230e86ca776bd39ae432 (diff)
Add support for note block and span
For example: \N|This is a block note. It may consist of multiple paragraphs.| And this is \N{an inline note} that is inside a paragraph. Notes are currently only support for the html output.
-rw-r--r--cli/context.cxx92
-rw-r--r--tests/note/buildfile5
-rw-r--r--tests/note/testscript83
3 files changed, 175 insertions, 5 deletions
diff --git a/cli/context.cxx b/cli/context.cxx
index b7181fd..a0900ce 100644
--- a/cli/context.cxx
+++ b/cli/context.cxx
@@ -419,6 +419,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
const block itlc = 2;
const block bold = 4;
const block link = 8;
+ const block note = 16;
vector<block> blocks;
@@ -753,6 +754,19 @@ format_line (output_type ot, string& r, const char* s, size_t n)
r += 'l';
break;
}
+ case 'N':
+ {
+ if (i + 1 < n && s[i + 1] == '{')
+ {
+ ++i;
+ blocks.push_back (note);
+ new_block = true;
+ break;
+ }
+
+ r += 'N';
+ break;
+ }
case '\\':
{
switch (ot)
@@ -815,6 +829,13 @@ format_line (output_type ot, string& r, const char* s, size_t n)
{
case ot_plain:
{
+ if ((b & note) != 0)
+ {
+ cerr << "error: \\N{} in plain text output not yet supported"
+ << endl;
+ throw generation_failed ();
+ }
+
if ((b & link) == 0)
{
if (color)
@@ -831,7 +852,11 @@ format_line (output_type ot, string& r, const char* s, size_t n)
}
case ot_html:
{
- if (b & link)
+ if (b & note)
+ {
+ r += "<span class=\"note\">";
+ }
+ else if (b & link)
{
r += "<a href=\"";
@@ -869,6 +894,12 @@ format_line (output_type ot, string& r, const char* s, size_t n)
}
case ot_man:
{
+ if ((b & note) != 0)
+ {
+ cerr << "error: \\N{} in man output not yet supported" << endl;
+ throw generation_failed ();
+ }
+
if ((b & link) == 0)
{
if ((eb & itlc) && (eb & bold))
@@ -920,6 +951,8 @@ format_line (output_type ot, string& r, const char* s, size_t n)
{
case ot_plain:
{
+ assert ((b & note) == 0);
+
if (b & link)
{
string t (link_section.empty ()
@@ -981,7 +1014,11 @@ format_line (output_type ot, string& r, const char* s, size_t n)
}
case ot_html:
{
- if (b & link)
+ if (b & note)
+ {
+ r += "</span>";
+ }
+ else if (b & link)
{
if (link_empty)
{
@@ -1013,6 +1050,8 @@ format_line (output_type ot, string& r, const char* s, size_t n)
}
case ot_man:
{
+ assert ((b & note) == 0);
+
if (b & link)
{
string t (link_section.empty ()
@@ -1094,6 +1133,8 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (b & itlc) bs += 'i';
if (b & bold) bs += 'b';
if (b & link) bs = 'l';
+ if (b & note) bs = 'N';
+
cerr << "error: unterminated formatting block '\\" << bs << "' "
<< "in documentation paragraph '" << string (s, 0, n) << "'" << endl;
@@ -1116,7 +1157,7 @@ struct block
//
// The specifier (0, H, 1, h, 2) is stored in header.
//
- enum kind_type {h, ul, ol, dl, li, text, pre};
+ enum kind_type {h, ul, ol, dl, li, note, text, pre};
kind_type kind;
bool para; // True if first text fragment should be in own paragraph.
@@ -1131,7 +1172,7 @@ struct block
};
static const char* block_kind_str[] = {
- "\\h", "\\ul", "\\ol", "\\dl", "\\li", "text", "preformatted text"};
+ "\\h", "\\ul", "\\ol", "\\dl", "\\li", "\\N", "text", "preformatted text"};
inline ostream&
operator<< (ostream& os, block::kind_type k)
@@ -1403,6 +1444,18 @@ format (semantics::scope& scope, string const& s, bool para)
l += 4;
n -= 4;
}
+ //
+ // \N (note)
+ //
+ else if (n >= 3 &&
+ l[0] == '\\' &&
+ l[1] == 'N' &&
+ (l[2] == '|' || l[2] == '#'))
+ {
+ k = block::note;
+ l += 3;
+ n -= 3;
+ }
else
k = block::text;
@@ -1474,7 +1527,10 @@ format (semantics::scope& scope, string const& s, bool para)
case block::ul:
case block::ol:
case block::dl: good = (k == block::li); break;
- case block::li: good = (k == block::text || k == block::pre); break;
+ case block::li: good = (k == block::note ||
+ k == block::text ||
+ k == block::pre ); break;
+ case block::note: good = (k == block::text || k == block::pre); break;
case block::text: good = (k != block::li); break;
case block::pre: assert (false);
}
@@ -1569,6 +1625,7 @@ format (semantics::scope& scope, string const& s, bool para)
break;
}
+ case block::note:
case block::text:
case block::pre:
break;
@@ -1606,6 +1663,11 @@ format (semantics::scope& scope, string const& s, bool para)
blocks.push (block (k, false, id, header));
break;
}
+ case block::note:
+ {
+ blocks.push (block (k, true, id, header));
+ break;
+ }
case block::text: break; // No push.
case block::pre: break; // No push.
}
@@ -2025,6 +2087,12 @@ format (semantics::scope& scope, string const& s, bool para)
break;
}
+ case block::note:
+ {
+ cerr << "error: " << pb.kind << "| in plain text output not "
+ << "yet supported" << endl;
+ throw generation_failed ();
+ }
case block::text:
case block::pre: assert (false);
}
@@ -2112,6 +2180,14 @@ format (semantics::scope& scope, string const& s, bool para)
break;
}
+ case block::note:
+ {
+ v += "<div class=\"note\">\n";
+ v += pv;
+ v += "\n</div>";
+
+ break;
+ }
case block::text:
case block::pre: assert (false);
}
@@ -2165,6 +2241,12 @@ format (semantics::scope& scope, string const& s, bool para)
break;
}
+ case block::note:
+ {
+ cerr << "error: " << pb.kind << "| in man output not yet "
+ << "supported" << endl;
+ throw generation_failed ();
+ }
case block::text:
case block::pre: assert (false);
}
diff --git a/tests/note/buildfile b/tests/note/buildfile
new file mode 100644
index 0000000..2051ed0
--- /dev/null
+++ b/tests/note/buildfile
@@ -0,0 +1,5 @@
+# file : tests/note/buildfile
+# copyright : Copyright (c) 2009-2017 Code Synthesis Tools CC
+# license : MIT; see accompanying LICENSE file
+
+./: test{testscript}
diff --git a/tests/note/testscript b/tests/note/testscript
new file mode 100644
index 0000000..1e302bd
--- /dev/null
+++ b/tests/note/testscript
@@ -0,0 +1,83 @@
+# file : tests/note/testscript
+# copyright : Copyright (c) 2009-2017 Code Synthesis Tools CC
+# license : MIT; see accompanying LICENSE file
+
+test = $effect($cli.path)
+
+: block-basics
+:
+cat <<EOI >=test.cli;
+"
+Leading paragraph.
+
+\N|This is a note block one.|
+
+Interleaving paragraph.
+
+\N|This is a note block two.|
+
+Trailing paragraph.
+"
+EOI
+$* --generate-html --stdout test.cli >>EOO
+ <p>Leading paragraph.</p>
+
+ <div class="note">
+ <p>This is a note block one.</p>
+ </div>
+
+ <p>Interleaving paragraph.</p>
+
+ <div class="note">
+ <p>This is a note block two.</p>
+ </div>
+
+ <p>Trailing paragraph.</p>
+
+EOO
+
+: block-multi-para
+:
+cat <<EOI >=test.cli;
+"
+\N|
+This is a note para one.
+
+This is a note para two.
+|
+"
+EOI
+$* --generate-html --stdout test.cli >>EOO
+ <div class="note">
+ <p>This is a note para one.</p>
+
+ <p>This is a note para two.</p>
+ </div>
+
+EOO
+
+: span-basics
+:
+cat <<EOI >=test.cli;
+"
+This is normal text. \N{This is a note.} And this is normal text again.
+"
+EOI
+$* --generate-html --stdout test.cli >>EOO
+ <p>This is normal text. <span class="note">This is a note.</span> And this
+ is normal text again.</p>
+
+EOO
+
+: span-nested-link
+:
+cat <<EOI >=test.cli;
+"
+\N{This is a note with a \l{https://example.com link} inside.}
+"
+EOI
+$* --generate-html --stdout test.cli >>EOO
+ <p><span class="note">This is a note with a <a
+ href="https://example.com">link</a> inside.</span></p>
+
+EOO