summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorwl <wl>2009-05-07 16:22:16 +0000
committerwl <wl>2009-05-07 16:22:16 +0000
commit71826809e5c309abdd89660a981cb9fcf6e9d6ee (patch)
tree69f0ddfd13c7cdf7dcda90c2c2c1938e93505f0d /src
parentd279b6408c775836fe2322578477ccd6cf760422 (diff)
downloadgroff-71826809e5c309abdd89660a981cb9fcf6e9d6ee.tar.gz
Accept \0 and friends within \o.
Reported by Doug McIlroy <doug@cs.dartmouth.edu>. * src/roff/troff/token.h (token): Add TOKEN_HORIZONTAL_SPACE enumeration value together with `horizontal_space' member function. Add `do_overstrike' as a friend. * src/roff/troff/input.cpp: Use TOKEN_HORIZONTAL_SPACE for \0, \|, \^, and \h. Update all affected places. (do_overstrike): Remove `static' attribute. Accept all escapes which produce a fixed horizontal space.
Diffstat (limited to 'src')
-rw-r--r--src/roff/troff/input.cpp38
-rw-r--r--src/roff/troff/token.h8
2 files changed, 35 insertions, 11 deletions
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 98b6e58f..17d24515 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1434,7 +1434,7 @@ static void define_color()
skip_line();
}
-static node *do_overstrike()
+node *do_overstrike()
{
token start;
overstrike_node *on = new overstrike_node;
@@ -1450,11 +1450,21 @@ static node *do_overstrike()
if (tok == start
&& (compatible_flag || input_stack::get_level() == start_level))
break;
- charinfo *ci = tok.get_char(1);
- if (ci) {
- node *n = curenv->make_char_node(ci);
- if (n)
- on->overstrike(n);
+ if (tok.horizontal_space())
+ on->overstrike(tok.nd->copy());
+ else if (tok.unstretchable_space())
+ {
+ node *n = new hmotion_node(curenv->get_space_width(),
+ curenv->get_fill_color());
+ on->overstrike(n);
+ }
+ else {
+ charinfo *ci = tok.get_char(1);
+ if (ci) {
+ node *n = curenv->make_char_node(ci);
+ if (n)
+ on->overstrike(n);
+ }
}
}
return on;
@@ -1799,13 +1809,13 @@ void token::next()
goto handle_escape_char;
case ESCAPE_BAR:
ESCAPE_BAR:
- type = TOKEN_NODE;
+ type = TOKEN_HORIZONTAL_SPACE;
nd = new hmotion_node(curenv->get_narrow_space_width(),
curenv->get_fill_color());
return;
case ESCAPE_CIRCUMFLEX:
ESCAPE_CIRCUMFLEX:
- type = TOKEN_NODE;
+ type = TOKEN_HORIZONTAL_SPACE;
nd = new hmotion_node(curenv->get_half_narrow_space_width(),
curenv->get_fill_color());
return;
@@ -1926,7 +1936,7 @@ void token::next()
case '0':
nd = new hmotion_node(curenv->get_digit_width(),
curenv->get_fill_color());
- type = TOKEN_NODE;
+ type = TOKEN_HORIZONTAL_SPACE;
return;
case '|':
goto ESCAPE_BAR;
@@ -2061,7 +2071,7 @@ void token::next()
case 'h':
if (!get_delim_number(&x, 'm'))
break;
- type = TOKEN_NODE;
+ type = TOKEN_HORIZONTAL_SPACE;
nd = new hmotion_node(x, curenv->get_fill_color());
return;
case 'H':
@@ -2216,7 +2226,7 @@ void token::next()
case 'z':
{
next();
- if (type == TOKEN_NODE)
+ if (type == TOKEN_NODE || type == TOKEN_HORIZONTAL_SPACE)
nd = new zero_width_node(nd);
else {
charinfo *ci = get_char(1);
@@ -2346,6 +2356,7 @@ int token::delimiter(int err)
case TOKEN_SPACE:
case TOKEN_STRETCHABLE_SPACE:
case TOKEN_UNSTRETCHABLE_SPACE:
+ case TOKEN_HORIZONTAL_SPACE:
case TOKEN_TAB:
case TOKEN_NEWLINE:
if (err)
@@ -2402,6 +2413,8 @@ const char *token::description()
return "`\\~'";
case TOKEN_UNSTRETCHABLE_SPACE:
return "`\\ '";
+ case TOKEN_HORIZONTAL_SPACE:
+ return "a horizontal space";
case TOKEN_TAB:
return "a tab character";
case TOKEN_TRANSPARENT:
@@ -2951,6 +2964,7 @@ void process_input_stack()
case token::TOKEN_EOF:
return;
case token::TOKEN_NODE:
+ case token::TOKEN_HORIZONTAL_SPACE:
{
if (possibly_handle_first_page_transition())
;
@@ -6796,6 +6810,7 @@ int token::add_to_node_list(node **pp)
set_number_reg(nm, curenv->get_input_line_position().to_units());
break;
case TOKEN_NODE:
+ case TOKEN_HORIZONTAL_SPACE:
n = nd;
nd = 0;
break;
@@ -6888,6 +6903,7 @@ void token::process()
curenv->newline();
break;
case TOKEN_NODE:
+ case TOKEN_HORIZONTAL_SPACE:
curenv->add_node(nd);
nd = 0;
break;
diff --git a/src/roff/troff/token.h b/src/roff/troff/token.h
index 22a06aa2..19842f03 100644
--- a/src/roff/troff/token.h
+++ b/src/roff/troff/token.h
@@ -54,6 +54,7 @@ class token {
TOKEN_SPREAD, // \p -- break and spread output line
TOKEN_STRETCHABLE_SPACE, // \~
TOKEN_UNSTRETCHABLE_SPACE, // `\ '
+ TOKEN_HORIZONTAL_SPACE, // \|, \^, \0, \h
TOKEN_TAB, // tab
TOKEN_TRANSPARENT, // \!
TOKEN_TRANSPARENT_DUMMY, // \)
@@ -73,6 +74,7 @@ public:
int space(); // is the current token a space?
int stretchable_space(); // is the current token a stretchable space?
int unstretchable_space(); // is the current token an unstretchable space?
+ int horizontal_space(); // is the current token a horizontal space?
int white_space(); // is the current token space or tab?
int special(); // is the current token a special character?
int newline(); // is the current token a newline?
@@ -99,6 +101,7 @@ public:
const char *description();
friend void process_input_stack();
+ friend node *do_overstrike();
};
extern token tok; // the current token
@@ -155,6 +158,11 @@ inline int token::unstretchable_space()
return type == TOKEN_UNSTRETCHABLE_SPACE;
}
+inline int token::horizontal_space()
+{
+ return type == TOKEN_HORIZONTAL_SPACE;
+}
+
inline int token::special()
{
return type == TOKEN_SPECIAL;