diff options
Diffstat (limited to 'mdoc_macro.c')
-rw-r--r-- | mdoc_macro.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/mdoc_macro.c b/mdoc_macro.c index f292affc..10baaec7 100644 --- a/mdoc_macro.c +++ b/mdoc_macro.c @@ -335,21 +335,44 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type, const struct mdoc_node *p) { + /* + * 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) @@ -384,9 +407,25 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type, break; } - return(p->end || (MDOC_BLOCK == p->type && - ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) ? - REWIND_MORE : REWIND_LATER); + /* + * Default block rewinding rules. + * In particular, always skip block end markers. + */ + if (p->end || (MDOC_BLOCK == p->type && + ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))) + return(REWIND_MORE); + + /* + * Partial blocks allow delayed rewinding by default. + */ + if (&blk_full != mdoc_macros[tok].fp) + return (REWIND_LATER); + + /* + * Full blocks can only be rewound when matching + * or when there is an explicit rule. + */ + return(REWIND_ERROR); } |