From a0590dbedd34ee38d8cf6a83bc5846668e0c29fd Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Tue, 24 May 2011 15:22:14 +0000 Subject: Have conditional closure for both text and macro lines call through to ccond(). Fix the text handler to behave like the macro handler regarding escaped \}. Make \} actually become a zero-width space, too, and clean up the documentation in this regard. --- roff.7 | 23 ++++++++++++++--------- roff.c | 38 ++++++++++++-------------------------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/roff.7 b/roff.7 index 081f6762..41837a1d 100644 --- a/roff.7 +++ b/roff.7 @@ -1,4 +1,4 @@ -.\" $Id: roff.7,v 1.28 2011/04/30 10:18:25 kristaps Exp $ +.\" $Id: roff.7,v 1.29 2011/05/24 15:22:14 kristaps Exp $ .\" .\" Copyright (c) 2010 Kristaps Dzonsons .\" Copyright (c) 2010 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 30 2011 $ +.Dd $Mdocdate: May 24 2011 $ .Dt ROFF 7 .Os .Sh NAME @@ -448,15 +448,20 @@ than having the request or macro follow as The scope of a conditional is always parsed, but only executed if the conditional evaluates to true. .Pp -Note that text following an -.Sq \&.\e} -escape sequence is discarded. -Furthermore, if an explicit closing sequence +Note that the .Sq \e} -is specified in a free-form line, the entire line is accepted within the -scope of the prior request, not only the text preceding the close, with the +is converted into a zero-width escape sequence if not passed as a +standalone macro +.Sq \&.\e} . +For example, +.Pp +.D1 \&.Fl a \e} b +.Pp +will result in .Sq \e} -collapsing into a zero-width space. +being considered an argument of the +.Sq \&Fl +macro. .Ss \&ig Ignore input. Its syntax can be either diff --git a/roff.c b/roff.c index 35e0f883..4960d947 100644 --- a/roff.c +++ b/roff.c @@ -1,4 +1,4 @@ -/* $Id: roff.c,v 1.139 2011/05/24 14:00:39 kristaps Exp $ */ +/* $Id: roff.c,v 1.140 2011/05/24 15:22:14 kristaps Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2011 Ingo Schwarze @@ -853,17 +853,12 @@ roff_cond_sub(ROFF_ARGS) */ if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos))) { - /* - * Jump through hoops to detect a \}, because it could - * be (say) \\}, which is something completely - * different. - */ ep = &(*bufp)[pos]; for ( ; NULL != (ep = strchr(ep, '\\')); ep++) { ep++; if ('}' != *ep) continue; - *--ep = '\0'; + *ep = '&'; roff_ccond(r, ROFF_ccond, bufp, szp, ln, pos, pos + 2, offs); break; @@ -887,37 +882,28 @@ roff_cond_sub(ROFF_ARGS) ln, ppos, pos, offs)); } - /* ARGSUSED */ static enum rofferr roff_cond_text(ROFF_ARGS) { - char *ep, *st; + char *ep; enum roffrule rr; rr = r->last->rule; + roffnode_cleanscope(r); - /* - * We display the value of the text if out current evaluation - * scope permits us to do so. - */ - - /* FIXME: use roff_ccond? */ - - st = &(*bufp)[pos]; - if (NULL == (ep = strstr(st, "\\}"))) { - roffnode_cleanscope(r); - return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); + ep = &(*bufp)[pos]; + for ( ; NULL != (ep = strchr(ep, '\\')); ep++) { + ep++; + if ('}' != *ep) + continue; + *ep = '&'; + roff_ccond(r, ROFF_ccond, bufp, szp, + ln, pos, pos + 2, offs); } - - if (ep == st || (ep > st && '\\' != *(ep - 1))) - roffnode_pop(r); - - roffnode_cleanscope(r); return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT); } - static enum roffrule roff_evalcond(const char *v, int *pos) { -- cgit v1.2.3-56-ge451