summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2010-05-24 23:54:18 +0000
committerIngo Schwarze <schwarze@openbsd.org>2010-05-24 23:54:18 +0000
commit67f57cab47c6371e6a42d8d6952b35485c7b0b85 (patch)
treefe87e61f15aa3b0d9acd8d588cb285c09533c676
parent30f1b0c604238c5d864f10e3595ce8e10f23ceea (diff)
downloadmandoc-67f57cab47c6371e6a42d8d6952b35485c7b0b85.tar.gz
recognize ".if n" as true;
nothing fancy yet, no negation, no grammer, just that one letter; from OpenBSD; "looks fine" kristaps@
-rw-r--r--roff.712
-rw-r--r--roff.c21
2 files changed, 26 insertions, 7 deletions
diff --git a/roff.7 b/roff.7
index ed75a1e3..f46fe62e 100644
--- a/roff.7
+++ b/roff.7
@@ -126,7 +126,15 @@ which may be separated by any intervening input (or not exist at all).
Its syntax is equivalent to
.Sx \&if .
.Ss \&if
-Begins a conditional that always evaluates to false.
+Begins a conditional.
+Right now, the conditional evaluates to true
+if and only if it starts with the letter
+.Sy n ,
+indicating processing in
+.Xr nroff 1
+style as opposed to
+.Xr troff 1
+style.
If a conditional is false, its children are not processed, but are
syntactically interpreted to preserve the integrity of the input
document.
@@ -249,7 +257,7 @@ Currently, it is ignored including its arguments,
and the number of arguments is not checked.
.Ss \&tr
Output character translation.
-This macro is intended to have one argument,
+This macro is intended to have one argument,
consisting of an even number of characters.
Currently, it is ignored including its arguments,
and the number of arguments is not checked.
diff --git a/roff.c b/roff.c
index 17099449..20f22d96 100644
--- a/roff.c
+++ b/roff.c
@@ -575,7 +575,7 @@ roff_cond_sub(ROFF_ARGS)
ppos = pos;
rr = r->last->rule;
- roffnode_cleanscope(r);
+ roff_cond_text(r, tok, bufp, szp, ln, ppos, pos, offs);
if (ROFF_MAX == (t = roff_parse(*bufp, &pos)))
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
@@ -616,8 +616,10 @@ roff_cond_text(ROFF_ARGS)
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
}
- if (ep > st && '\\' != *(ep - 1))
+ if (ep > st && '\\' != *(ep - 1)) {
+ ep = '\0';
roffnode_pop(r);
+ }
roffnode_cleanscope(r);
return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
@@ -628,6 +630,7 @@ roff_cond_text(ROFF_ARGS)
static enum rofferr
roff_cond(ROFF_ARGS)
{
+ int cpos; /* position of the condition */
int sv;
/* Stack overflow! */
@@ -637,6 +640,8 @@ roff_cond(ROFF_ARGS)
return(ROFF_ERR);
}
+ cpos = pos;
+
if (ROFF_if == tok || ROFF_ie == tok) {
/*
* Read ahead past the conditional. FIXME: this does
@@ -667,9 +672,12 @@ roff_cond(ROFF_ARGS)
if ( ! roffnode_push(r, tok, ln, ppos))
return(ROFF_ERR);
- /* TODO: here we would evaluate the conditional. */
+ /* XXX: Implement more conditionals. */
- if (ROFF_el == tok) {
+ if (ROFF_if == tok || ROFF_ie == tok)
+ r->last->rule = 'n' == (*bufp)[cpos] ?
+ ROFFRULE_ALLOW : ROFFRULE_DENY;
+ else if (ROFF_el == tok) {
/*
* An `.el' will get the value of the current rstack
* entry set in prior `ie' calls or defaults to DENY.
@@ -678,7 +686,8 @@ roff_cond(ROFF_ARGS)
r->last->rule = ROFFRULE_DENY;
else
r->last->rule = r->rstack[r->rstackpos];
- } else if (ROFF_ie == tok) {
+ }
+ if (ROFF_ie == tok) {
/*
* An if-else will put the NEGATION of the current
* evaluated conditional into the stack.
@@ -689,6 +698,8 @@ roff_cond(ROFF_ARGS)
else
r->rstack[r->rstackpos] = ROFFRULE_DENY;
}
+ if (r->last->parent && ROFFRULE_DENY == r->last->parent->rule)
+ r->last->rule = ROFFRULE_DENY;
r->last->endspan = 1;