-/* $Id: mdoc_macro.c,v 1.158 2014/12/18 03:10:11 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.161 2014/12/22 23:27:32 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
* When starting to rewind, skip plain text
* and nodes that have already been rewound.
*/
- if (MDOC_TEXT == p->type || MDOC_VALID & p->flags)
+ if (p->type == MDOC_TEXT || p->flags & (MDOC_VALID | MDOC_BREAK))
return(REWIND_MORE);
/*
rew_sub(enum mdoc_type t, struct mdoc *mdoc,
enum mdoct tok, int line, int ppos)
{
- struct mdoc_node *n;
+ struct mdoc_node *n, *to;
+ to = NULL;
n = mdoc->last;
while (n) {
switch (rew_dohalt(tok, t, n)) {
case REWIND_NONE:
- return;
+ if (to == NULL)
+ return;
+ n = to;
+ break;
case REWIND_THIS:
n->lastline = line -
(mdoc->flags & MDOC_NEWLINE &&
case REWIND_MORE:
n->lastline = line -
(mdoc->flags & MDOC_NEWLINE ? 1 : 0);
+ to = n;
n = n->parent;
continue;
case REWIND_LATER:
struct mdoc_node *later; /* A sub-block starting later. */
struct mdoc_node *n; /* For searching backwards. */
- int j, lastarg, maxargs, flushed, nl;
+ int flushed, have_it, j, lastarg, maxargs, nl;
enum margserr ac;
enum mdoct atok, ntok;
char *p;
* both of our own and of pending sub-blocks.
*/
+ have_it = 0;
atok = rew_alt(tok);
body = endbody = later = NULL;
for (n = mdoc->last; n; n = n->parent) {
- if (n->flags & MDOC_VALID)
+ if (n->flags & (MDOC_VALID | MDOC_BREAK))
continue;
/* Remember the start of our own body. */
if (n->type != MDOC_BLOCK || n->tok == MDOC_Nm)
continue;
+
+ if (n->tok == MDOC_It) {
+ have_it = 1;
+ continue;
+ }
+
if (atok == n->tok) {
assert(body);
* just proceed to closing out.
*/
- if (later == NULL)
+ if (later == NULL ||
+ (tok == MDOC_El && !have_it))
break;
/*
* implicit ones, the first open implicit block.
*/
- if (later &&
- mdoc_macros[later->tok].flags & MDOC_EXPLICIT)
- continue;
- if (n->tok != MDOC_It)
+ if (later == NULL ||
+ ! (mdoc_macros[later->tok].flags & MDOC_EXPLICIT))
later = n;
}
rew_sub(MDOC_BODY, mdoc, tok, line, ppos);
/* Make sure we are in a column list or ignore this macro. */
n = mdoc->last;
- while (n != NULL && n->tok != MDOC_Bl)
+ while (n != NULL &&
+ (n->tok != MDOC_Bl || n->flags & (MDOC_VALID | MDOC_BREAK)))
n = n->parent;
if (n == NULL || n->norm->Bl.type != LIST_column) {
mandoc_msg(MANDOCERR_TA_STRAY, mdoc->parse,