summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-11-18 12:55:06 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-11-18 12:55:06 +0200
commit6dc69580d6101fb1adb1733dad11b5f5ab5fc831 (patch)
treee2176e66c95b14a16748750d9b8a746e0582dae5 /cli
parent1a6cde47f6c524dc63c4a837ee6b94041320c681 (diff)
Fix man font selection logic
Diffstat (limited to 'cli')
-rw-r--r--cli/context.cxx112
-rw-r--r--cli/man.cxx4
2 files changed, 75 insertions, 41 deletions
diff --git a/cli/context.cxx b/cli/context.cxx
index ae3328f..d41bb3c 100644
--- a/cli/context.cxx
+++ b/cli/context.cxx
@@ -4,6 +4,7 @@
// license : MIT; see accompanying LICENSE file
#include <stack>
+#include <vector>
#include <cstring> // strncmp()
#include <sstream>
#include <iostream>
@@ -327,7 +328,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
const block bold = 4;
const block link = 8;
- stack<block> blocks;
+ vector<block> blocks;
string link_target;
string link_section; // If not empty, man section; target is man name.
@@ -405,7 +406,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (j < n && s[j] == '{')
{
i = j;
- blocks.push (b);
+ blocks.push_back (b);
new_block = true;
break;
}
@@ -447,7 +448,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (j < n && s[j] == '{')
{
i = j;
- blocks.push (b);
+ blocks.push_back (b);
new_block = true;
break;
}
@@ -489,7 +490,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (j < n && s[j] == '{')
{
i = j;
- blocks.push (b);
+ blocks.push_back (b);
new_block = true;
break;
}
@@ -570,7 +571,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
link_empty = i + 1 < n && s[i + 1] == '}';
- blocks.push (link);
+ blocks.push_back (link);
new_block = true;
break;
}
@@ -601,7 +602,13 @@ format_line (output_type ot, string& r, const char* s, size_t n)
//
if (new_block)
{
- block b (blocks.top ());
+ block b (blocks.back ());
+
+ block eb (0); // Effective block.
+ for (vector<block>::iterator i (blocks.begin ());
+ i != blocks.end ();
+ ++i)
+ eb |= *i & (code | itlc | bold);
switch (ot)
{
@@ -613,15 +620,6 @@ format_line (output_type ot, string& r, const char* s, size_t n)
}
case ot_html:
{
- if (b & code)
- r += "<code>";
-
- if (b & itlc)
- r += "<i>";
-
- if (b & bold)
- r += "<b>";
-
if (b & link)
{
r += "<a href=\"";
@@ -633,17 +631,31 @@ format_line (output_type ot, string& r, const char* s, size_t n)
r += "\">";
}
+ else
+ {
+ if (b & code)
+ r += "<code>";
+
+ if (b & itlc)
+ r += "<i>";
+
+ if (b & bold)
+ r += "<b>";
+ }
break;
}
case ot_man:
{
- if ((b & itlc) && (b & bold))
- r += "\\f(BI";
- else if (b & itlc)
- r += "\\fI";
- else if (b & bold)
- r += "\\fB";
+ if ((b & link) == 0)
+ {
+ if ((eb & itlc) && (eb & bold))
+ r += "\\f(BI";
+ else if (eb & itlc)
+ r += "\\fI";
+ else if (eb & bold)
+ r += "\\fB";
+ }
break;
}
@@ -673,15 +685,19 @@ format_line (output_type ot, string& r, const char* s, size_t n)
{
if (!blocks.empty ())
{
- block b (blocks.top ());
+ block b (blocks.back ());
+ blocks.pop_back ();
+
+ block eb (0); // New effective block.
+ for (vector<block>::iterator i (blocks.begin ());
+ i != blocks.end ();
+ ++i)
+ eb |= *i & (code | itlc | bold);
switch (ot)
{
case ot_plain:
{
- if (b & code)
- r += "'";
-
if (b & link)
{
if (!link_empty)
@@ -695,20 +711,16 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (!link_empty)
r += ")";
}
+ else
+ {
+ if (b & code)
+ r += "'";
+ }
break;
}
case ot_html:
{
- if (b & bold)
- r += "</b>";
-
- if (b & itlc)
- r += "</i>";
-
- if (b & code)
- r += "</code>";
-
if (b & link)
{
if (link_empty)
@@ -726,14 +738,22 @@ format_line (output_type ot, string& r, const char* s, size_t n)
r += "</a>";
}
+ else
+ {
+ if (b & bold)
+ r += "</b>";
+
+ if (b & itlc)
+ r += "</i>";
+
+ if (b & code)
+ r += "</code>";
+ }
break;
}
case ot_man:
{
- if (b & (itlc | bold))
- r += "\\fP";
-
if (b & link)
{
if (!link_empty)
@@ -750,6 +770,21 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (!link_empty)
r += ")";
}
+ else
+ {
+ // At first sight, \fP (select previous font) looks like
+ // exactly what we need here. However, it doesn't quite
+ // have the stack semantics that we need.
+ //
+ if ((eb & itlc) && (eb & bold))
+ r += "\\f(BI";
+ else if (eb & itlc)
+ r += "\\fI";
+ else if (eb & bold)
+ r += "\\fB";
+ else
+ r += "\\fR";
+ }
break;
}
@@ -758,7 +793,6 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (b & link)
link_target.clear ();
- blocks.pop ();
break;
}
@@ -780,7 +814,7 @@ format_line (output_type ot, string& r, const char* s, size_t n)
if (!blocks.empty ())
{
- unsigned char b (blocks.top ());
+ unsigned char b (blocks.back ());
string bs;
if (b & code) bs += 'c';
diff --git a/cli/man.cxx b/cli/man.cxx
index 2cbc766..70a5a4a 100644
--- a/cli/man.cxx
+++ b/cli/man.cxx
@@ -120,12 +120,12 @@ namespace
for (names::name_iterator i (n.name_begin ()); i != n.name_end (); ++i)
{
if (i != n.name_begin ())
- os << "\\fP|\\fB";
+ os << "\\fR|\\fB";
os << *i;
}
- os << "\\fP";
+ os << "\\fR";
string type (o.type ().name ());