+ return(mdoc_nerr(mdoc, node, "displays may not be nested"));
+}
+
+
+static int
+pre_bl(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ int type, err;
+ struct mdoc_arg *argv;
+ size_t i, argc;
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ assert(MDOC_Bl == node->tok);
+
+ argv = NULL;
+ argc = node->data.block.argc;
+
+ /* LINTED */
+ for (i = type = err = 0; i < argc; i++) {
+ argv = &node->data.block.argv[(int)i];
+ assert(argv);
+ switch (argv->arg) {
+ case (MDOC_Bullet):
+ /* FALLTHROUGH */
+ case (MDOC_Dash):
+ /* FALLTHROUGH */
+ case (MDOC_Enum):
+ /* FALLTHROUGH */
+ case (MDOC_Hyphen):
+ /* FALLTHROUGH */
+ case (MDOC_Item):
+ /* FALLTHROUGH */
+ case (MDOC_Tag):
+ /* FALLTHROUGH */
+ case (MDOC_Diag):
+ /* FALLTHROUGH */
+ case (MDOC_Hang):
+ /* FALLTHROUGH */
+ case (MDOC_Ohang):
+ /* FALLTHROUGH */
+ case (MDOC_Inset):
+ /* FALLTHROUGH */
+ case (MDOC_Column):
+ if (type)
+ err++;
+ type++;
+ break;
+ default:
+ break;
+ }
+ }
+ if (0 == type)
+ return(mdoc_err(mdoc, "no list type specified"));
+ if (0 == err)
+ return(1);
+ assert(argv);
+ return(mdoc_perr(mdoc, argv->line,
+ argv->pos, "only one list type possible"));
+}
+
+
+static int
+pre_bd(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ int type, err;
+ struct mdoc_arg *argv;
+ size_t i, argc;
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ assert(MDOC_Bd == node->tok);
+
+ argv = NULL;
+ argc = node->data.block.argc;
+
+ /* LINTED */
+ for (err = i = type = 0; 0 == err && i < argc; i++) {
+ argv = &node->data.block.argv[(int)i];
+ assert(argv);
+ switch (argv->arg) {
+ case (MDOC_Ragged):
+ /* FALLTHROUGH */
+ case (MDOC_Unfilled):
+ /* FALLTHROUGH */
+ case (MDOC_Filled):
+ /* FALLTHROUGH */
+ case (MDOC_Literal):
+ /* FALLTHROUGH */
+ case (MDOC_File):
+ if (type)
+ err++;
+ type++;
+ break;
+ default:
+ break;
+ }
+ }
+ if (0 == type)
+ return(mdoc_err(mdoc, "no display type specified"));
+ if (0 == err)
+ return(1);
+ assert(argv);
+ return(mdoc_perr(mdoc, argv->line,
+ argv->pos, "only one display type possible"));
+}
+
+
+static int
+pre_ss(struct mdoc *mdoc, struct mdoc_node *node)
+{
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ return(pre_check_parent(mdoc, node, MDOC_Sh, MDOC_BODY));
+}
+
+
+static int
+pre_sh(struct mdoc *mdoc, struct mdoc_node *node)
+{
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ return(pre_check_parent(mdoc, node, -1, MDOC_ROOT));
+}
+
+
+static int
+pre_st(struct mdoc *mdoc, struct mdoc_node *node)
+{
+
+ assert(MDOC_ELEM == node->type);
+ assert(MDOC_St == node->tok);
+ if (1 == node->data.elem.argc)
+ return(1);
+ return(mdoc_nerr(mdoc, node, "macro must have one argument"));
+}
+
+
+static int
+pre_an(struct mdoc *mdoc, struct mdoc_node *node)
+{
+
+ assert(MDOC_ELEM == node->type);
+ assert(MDOC_An == node->tok);
+ if (1 >= node->data.elem.argc)
+ return(1);
+ return(mdoc_nerr(mdoc, node, "macro may only have one argument"));
+}
+
+
+static int
+pre_rv(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ enum mdoc_msec msecs[2];
+
+ assert(MDOC_ELEM == node->type);
+ assert(MDOC_Rv == node->tok);
+
+ msecs[0] = MSEC_2;
+ msecs[1] = MSEC_3;
+ if ( ! pre_check_msecs(mdoc, node, 2, msecs))
+ return(0);
+ return(pre_check_stdarg(mdoc, node));
+}
+
+
+static int
+pre_ex(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ enum mdoc_msec msecs[3];
+
+ assert(MDOC_ELEM == node->type);
+ assert(MDOC_Ex == node->tok);
+
+ msecs[0] = MSEC_1;
+ msecs[1] = MSEC_6;
+ msecs[2] = MSEC_8;
+ if ( ! pre_check_msecs(mdoc, node, 3, msecs))
+ return(0);
+ return(pre_check_stdarg(mdoc, node));
+}
+
+
+static int
+pre_er(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ enum mdoc_msec msecs[1];
+
+ msecs[0] = MSEC_2;
+ return(pre_check_msecs(mdoc, node, 1, msecs));
+}
+
+
+static int
+pre_cd(struct mdoc *mdoc, struct mdoc_node *node)
+{
+ enum mdoc_msec msecs[1];
+
+ msecs[0] = MSEC_4;
+ return(pre_check_msecs(mdoc, node, 1, msecs));
+}
+
+
+static int
+pre_it(struct mdoc *mdoc, struct mdoc_node *node)
+{
+
+ /* TODO: -width attribute must be specified for -tag. */
+ /* TODO: children too big for -width? */
+
+ if (MDOC_BLOCK != node->type)
+ return(1);
+ return(pre_check_parent(mdoc, node, MDOC_Bl, MDOC_BODY));