+ st = &(*bufp)[pos];
+ if (NULL == (ep = strstr(st, "\\}"))) {
+ roffnode_cleanscope(r);
+ return(ROFF_IGN);
+ }
+
+ if (ep > st && '\\' != *(ep - 1)) {
+ ROFF_MDEBUG(r, "closing explicit scope (in-line)");
+ roffnode_pop(r);
+ }
+
+ roffnode_cleanscope(r);
+ return(ROFF_IGN);
+}
+
+
+/* ARGSUSED */
+static enum rofferr
+roff_if(ROFF_ARGS)
+{
+ int sv;
+
+ /*
+ * Read ahead past the conditional.
+ * FIXME: this does not work, as conditionals don't end on
+ * whitespace, but are parsed according to a formal grammar.
+ * It's good enough for now, however.
+ */
+
+ while ((*bufp)[pos] && ' ' != (*bufp)[pos])
+ pos++;
+
+ sv = pos;
+ while (' ' == (*bufp)[pos])
+ pos++;
+
+ /*
+ * Roff is weird. If we have just white-space after the
+ * conditional, it's considered the BODY and we exit without
+ * really doing anything. Warn about this. It's probably
+ * wrong.
+ */
+
+ if ('\0' == (*bufp)[pos] && sv != pos) {
+ if ( ! (*r->msg)(MANDOCERR_NOARGS, r->data, ln, ppos, NULL))
+ return(ROFF_ERR);
+ return(ROFF_IGN);
+ }
+
+ if ( ! roffnode_push(r, tok, ln, ppos))
+ return(ROFF_ERR);
+
+ /* Don't evaluate: just assume NO. */
+
+ r->last->endspan = 1;
+
+ if ('\\' == (*bufp)[pos] && '{' == (*bufp)[pos + 1]) {
+ ROFF_MDEBUG(r, "opening explicit scope");
+ r->last->endspan = -1;
+ pos += 2;
+ } else
+ ROFF_MDEBUG(r, "opening implicit scope");
+
+ /*
+ * If there are no arguments on the line, the next-line scope is
+ * assumed.
+ */
+
+ if ('\0' == (*bufp)[pos])
+ return(ROFF_IGN);
+
+ /* Otherwise re-run the roff parser after recalculating. */
+
+ *offs = pos;
+ return(ROFF_RERUN);