summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--libmdoc.h1
-rw-r--r--mdoc.c26
-rw-r--r--mdoc_macro.c12
-rw-r--r--regress/mdoc/It/freecol0.in11
-rw-r--r--regress/mdoc/It/freecol1.in12
-rw-r--r--regress/mdoc/It/freecol2.in16
7 files changed, 79 insertions, 2 deletions
diff --git a/TODO b/TODO
index 09871654..19df168c 100644
--- a/TODO
+++ b/TODO
@@ -54,6 +54,9 @@
.Bl -column
.It foo Ta bar
.El
+
+- explicitly disallow nested `Bl -column', which would clobber internal
+ flags defined for struct mdoc_macro
************************************************************************
* formatting issues: ugly output
diff --git a/libmdoc.h b/libmdoc.h
index 58483983..7406f40a 100644
--- a/libmdoc.h
+++ b/libmdoc.h
@@ -34,6 +34,7 @@ struct mdoc {
#define MDOC_NEWLINE (1 << 3) /* first macro/text in a line */
#define MDOC_PHRASELIT (1 << 4) /* literal within a partila phrase */
#define MDOC_PPHRASE (1 << 5) /* within a partial phrase */
+#define MDOC_FREECOL (1 << 6) /* `It' invocation should close */
int pflags;
enum mdoc_next next;
struct mdoc_node *last;
diff --git a/mdoc.c b/mdoc.c
index 8aeec090..2d12e06d 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -542,7 +542,8 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
static int
mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
{
- char *c, *ws, *end;
+ char *c, *ws, *end;
+ struct mdoc_node *n;
/* Ignore bogus comments. */
@@ -556,6 +557,29 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
if (SEC_NONE == m->lastnamed)
return(mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT));
+ assert(m->last);
+ n = m->last;
+
+ /*
+ * Diver directly into list processing if we're encountering a
+ * columnar MDOC_BLOCK with or without a prior MDOC_BLOCK entry
+ * (if it's a MDOC_BODY that means it's open, in which case we
+ * should process within its context).
+ */
+
+ if (MDOC_Bl == n->tok && LIST_column == n->data.list) {
+ m->flags |= MDOC_FREECOL;
+ return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
+ }
+
+ if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
+ NULL != n->parent &&
+ MDOC_Bl == n->parent->tok &&
+ LIST_column == n->parent->data.list) {
+ m->flags |= MDOC_FREECOL;
+ return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
+ }
+
/*
* Search for the beginning of unescaped trailing whitespace (ws)
* and for the first character not to be output (end).
diff --git a/mdoc_macro.c b/mdoc_macro.c
index 008efdd0..f9a6f7a1 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -1118,7 +1118,7 @@ blk_full(MACRO_PROT_ARGS)
/* If we've already opened our body, exit now. */
if (NULL != body)
- return(1);
+ goto out;
#ifdef UGLY
/*
@@ -1145,6 +1145,16 @@ blk_full(MACRO_PROT_ARGS)
if ( ! mdoc_body_alloc(m, line, ppos, tok))
return(0);
+out:
+ if ( ! (MDOC_FREECOL & m->flags))
+ return(1);
+
+ if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
+ return(0);
+ if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
+ return(0);
+
+ m->flags &= ~MDOC_FREECOL;
return(1);
}
diff --git a/regress/mdoc/It/freecol0.in b/regress/mdoc/It/freecol0.in
new file mode 100644
index 00000000..721c0682
--- /dev/null
+++ b/regress/mdoc/It/freecol0.in
@@ -0,0 +1,11 @@
+.Dd $Mdocdate$
+.Dt FOO
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+hello
+.Bl -column asdfasdf asdfasdf
+hello there
+.El
diff --git a/regress/mdoc/It/freecol1.in b/regress/mdoc/It/freecol1.in
new file mode 100644
index 00000000..efef7ee4
--- /dev/null
+++ b/regress/mdoc/It/freecol1.in
@@ -0,0 +1,12 @@
+.Dd $Mdocdate$
+.Dt FOO
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+hello
+.Bl -column asdfasdf asdfasdf
+hello there
+hello there
+.El
diff --git a/regress/mdoc/It/freecol2.in b/regress/mdoc/It/freecol2.in
new file mode 100644
index 00000000..9f0dd416
--- /dev/null
+++ b/regress/mdoc/It/freecol2.in
@@ -0,0 +1,16 @@
+.Dd $Mdocdate$
+.Dt FOO
+.Os
+.Sh NAME
+.Nm foo
+.Nd bar
+.Sh DESCRIPTION
+hello
+.Bl -column asdfasdf asdfasdf
+hello there
+hello there
+.It hello there
+.It hello Ta there
+.It hello Ta
+there
+.El