diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2018-11-26 17:44:30 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2018-11-26 17:44:30 +0000 |
commit | 566544af034122e6317c9f9d8f09fc178ebd8bec (patch) | |
tree | 23ece239b91d3b2de049a27609586b8ec0633532 /usr.bin/mandoc | |
parent | 4ccf58fa492629e4c6e388600062de91caacb6fb (diff) |
When a conditional block is closed by putting "\}" on a text line
by itself (which is somewhat unusual but not invalid; most authors
use the empty macro line ".\}" instead), agree more closely with
groff and do not produce a double space in the output.
Quirk reported by millert@.
While here, tweak the rest of the function body of roff_cond_text()
to more closely match roff_cond_sub(). The subtly different handling
could make people (including myself) wonder whether there is any
point in being different. Testing shows there is not.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r-- | usr.bin/mandoc/roff.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index aa3a3f53493..caed1da5cc5 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.214 2018/10/25 01:21:30 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.215 2018/11/26 17:44:29 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> @@ -2105,7 +2105,10 @@ roff_cond_sub(ROFF_ARGS) if (ep[0] == '\\' && ep[1] == '}') rr = 0; - /* Always check for the closing delimiter `\}'. */ + /* + * The closing delimiter `\}' rewinds the conditional scope + * but is otherwise ignored when interpreting the line. + */ while ((ep = strchr(ep, '\\')) != NULL) { switch (ep[1]) { @@ -2148,15 +2151,34 @@ roff_cond_text(ROFF_ARGS) if (roffnode_cleanscope(r)) irc |= endloop; + /* + * If `\}' occurs on a text line with neither preceding + * nor following characters, drop the line completely. + */ + ep = buf->buf + pos; + if (strcmp(ep, "\\}") == 0) + rr = 0; + + /* + * The closing delimiter `\}' rewinds the conditional scope + * but is otherwise ignored when interpreting the line. + */ + while ((ep = strchr(ep, '\\')) != NULL) { - if (*(++ep) == '}') { - *ep = '&'; - if (roff_ccond(r, ln, ep - buf->buf - 1)) + switch (ep[1]) { + case '}': + memmove(ep, ep + 2, strlen(ep + 2) + 1); + if (roff_ccond(r, ln, ep - buf->buf)) irc |= endloop; - } - if (*ep != '\0') + break; + case '\0': ++ep; + break; + default: + ep += 2; + break; + } } if (rr) irc |= ROFF_CONT; |