+ blk = NULL;
+ for (n = mdoc->last; n != NULL; n = n->parent) {
+ if (n->flags & NODE_ENDED) {
+ if ( ! (n->flags & NODE_VALID))
+ n->flags |= NODE_BROKEN;
+ continue;
+ }
+ if (n->type != ROFFT_BLOCK)
+ continue;
+
+ if (tok == MDOC_It && n->tok == MDOC_Bl) {
+ if (blk != NULL) {
+ mandoc_vmsg(MANDOCERR_BLK_BROKEN,
+ mdoc->parse, line, ppos,
+ "It breaks %s",
+ roff_name[blk->tok]);
+ rew_pending(mdoc, blk);
+ }
+ break;
+ }
+
+ if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
+ switch (tok) {
+ case MDOC_Sh:
+ case MDOC_Ss:
+ mandoc_vmsg(MANDOCERR_BLK_BROKEN,
+ mdoc->parse, line, ppos,
+ "%s breaks %s", roff_name[tok],
+ roff_name[n->tok]);
+ rew_pending(mdoc, n);
+ n = mdoc->last;
+ continue;
+ case MDOC_It:
+ /* Delay in case it's astray. */
+ blk = n;
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+
+ /* Here, n is one of Sh Ss Nm Nd It. */
+
+ if (tok != MDOC_Sh && (n->tok == MDOC_Sh ||
+ (tok != MDOC_Ss && (n->tok == MDOC_Ss ||
+ (tok != MDOC_It && n->tok == MDOC_It)))))
+ break;
+
+ /* Item breaking an explicit block. */
+
+ if (blk != NULL) {
+ mandoc_vmsg(MANDOCERR_BLK_BROKEN,
+ mdoc->parse, line, ppos,
+ "It breaks %s", roff_name[blk->tok]);
+ rew_pending(mdoc, blk);
+ blk = NULL;
+ }
+
+ /* Close out prior implicit scopes. */
+
+ rew_pending(mdoc, n);
+ }
+
+ /* Skip items outside lists. */
+
+ if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
+ mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
+ line, ppos, "It %s", buf + *pos);
+ roff_elem_alloc(mdoc, line, ppos, ROFF_br);
+ rew_elem(mdoc, ROFF_br);
+ return;
+ }