-
- /*
- * No matching token, no delimiting block, no broken block.
- * This can happen when full implicit macros are called for
- * the first time but try to rewind their previous
- * instance anyway.
- */
- if (MDOC_ROOT == p->type)
- return(MDOC_BLOCK == type &&
- MDOC_EXPLICIT & mdoc_macros[tok].flags ?
- REWIND_ERROR : REWIND_NONE);
-
- /*
- * When starting to rewind, skip plain text
- * and nodes that have already been rewound.
- */
- if (MDOC_TEXT == p->type || MDOC_VALID & p->flags)
- return(REWIND_MORE);
-
- /*
- * The easiest case: Found a matching token.
- * This applies to both blocks and elements.
- */
- tok = rew_alt(tok);
- if (tok == p->tok)
- return(p->end ? REWIND_NONE :
- type == p->type ? REWIND_THIS : REWIND_MORE);
-
- /*
- * While elements do require rewinding for themselves,
- * they never affect rewinding of other nodes.
- */
- if (MDOC_ELEM == p->type)
- return(REWIND_MORE);
-
- /*
- * Blocks delimited by our target token get REWIND_MORE.
- * Blocks delimiting our target token get REWIND_NONE.
- */
- switch (tok) {
- case MDOC_Bl:
- if (MDOC_It == p->tok)
- return(REWIND_MORE);
- break;
- case MDOC_It:
- if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
- return(REWIND_NONE);
- break;
- /*
- * XXX Badly nested block handling still fails badly
- * when one block is breaking two blocks of the same type.
- * This is an incomplete and extremely ugly workaround,
- * required to let the OpenBSD tree build.
- */
- case MDOC_Oo:
- if (MDOC_Op == p->tok)
- return(REWIND_MORE);
- break;
- case MDOC_Nm:
- return(REWIND_NONE);
- case MDOC_Nd:
- /* FALLTHROUGH */
- case MDOC_Ss:
- if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
- return(REWIND_NONE);
- /* FALLTHROUGH */
- case MDOC_Sh:
- if (MDOC_ROOT == p->parent->type)
- return(REWIND_THIS);
- if (MDOC_Nd == p->tok || MDOC_Ss == p->tok ||
- MDOC_Sh == p->tok)
- return(REWIND_MORE);
- break;
- default:
- break;
- }
-
- /*
- * Default block rewinding rules.
- * In particular, always skip block end markers,
- * and let all blocks rewind Nm children.
- */
- if (ENDBODY_NOT != p->end || MDOC_Nm == p->tok ||
- (MDOC_BLOCK == p->type &&
- ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)))
- return(REWIND_MORE);
-
- /*
- * By default, closing out full blocks
- * forces closing of broken explicit blocks,
- * while closing out partial blocks
- * allows delayed rewinding by default.
- */
- return (&blk_full == mdoc_macros[tok].fp ?
- REWIND_FORCE : REWIND_LATER);
-}
-
-static int
-rew_elem(struct mdoc *mdoc, enum mdoct tok)
-{
- struct mdoc_node *n;