summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2010-02-26 12:12:25 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2010-02-26 12:12:25 +0000
commitedd55148017e5ed1479d7bc9d62502478202b158 (patch)
treef1cddaba4780818b8163662986418449a534964a /usr.bin
parent0a20ac85bcd33099b25bace7d035507e0d0a950c (diff)
Support .It .Xo.
The trick is to not switch from the .It header to the body at EOL, but, in case an explicit block macro follows, at the end of the block.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/mandoc/mdoc.h3
-rw-r--r--usr.bin/mandoc/mdoc_macro.c41
2 files changed, 36 insertions, 8 deletions
diff --git a/usr.bin/mandoc/mdoc.h b/usr.bin/mandoc/mdoc.h
index 732aa1607a5..92c7534a180 100644
--- a/usr.bin/mandoc/mdoc.h
+++ b/usr.bin/mandoc/mdoc.h
@@ -1,4 +1,4 @@
-/* $Id: mdoc.h,v 1.16 2009/12/22 23:58:00 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.17 2010/02/26 12:12:24 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -264,6 +264,7 @@ struct mdoc_node {
struct mdoc_node *head; /* BLOCK */
struct mdoc_node *body; /* BLOCK */
struct mdoc_node *tail; /* BLOCK */
+ struct mdoc_node *pending; /* BLOCK */
char *string; /* TEXT */
};
diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c
index c906c59a1bf..210ecfd9534 100644
--- a/usr.bin/mandoc/mdoc_macro.c
+++ b/usr.bin/mandoc/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.28 2010/02/18 02:11:26 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.29 2010/02/26 12:12:24 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
@@ -591,7 +591,21 @@ rew_sub(enum mdoc_type t, struct mdoc *m,
}
assert(n);
- return(rew_last(m, n));
+ if ( ! rew_last(m, n))
+ return(0);
+
+ /*
+ * The current block extends an enclosing block beyond a line break.
+ * Now that the current block ends, close the enclosing block, too.
+ */
+ if ((n = n->pending) != NULL) {
+ assert(MDOC_HEAD == n->type);
+ if ( ! rew_last(m, n))
+ return(0);
+ if ( ! mdoc_body_alloc(m, n->line, n->pos, n->tok))
+ return(0);
+ }
+ return(1);
}
@@ -855,6 +869,7 @@ blk_full(MACRO_PROT_ARGS)
{
int c, lastarg, reopen, dohead;
struct mdoc_arg *arg;
+ struct mdoc_node *head, *n;
char *p;
/*
@@ -900,10 +915,11 @@ blk_full(MACRO_PROT_ARGS)
if ( ! mdoc_block_alloc(m, line, ppos, tok, arg))
return(0);
+ if ( ! mdoc_head_alloc(m, line, ppos, tok))
+ return(0);
+ head = m->last;
if (0 == buf[*pos]) {
- if ( ! mdoc_head_alloc(m, line, ppos, tok))
- return(0);
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
return(0);
if ( ! mdoc_body_alloc(m, line, ppos, tok))
@@ -911,9 +927,6 @@ blk_full(MACRO_PROT_ARGS)
return(1);
}
- if ( ! mdoc_head_alloc(m, line, ppos, tok))
- return(0);
-
/* Immediately close out head and enter body, if applicable. */
if (0 == dohead) {
@@ -935,6 +948,7 @@ blk_full(MACRO_PROT_ARGS)
assert(dohead);
if (reopen && ! mdoc_head_alloc(m, line, ppos, tok))
return(0);
+ head = m->last;
/*
* Phrases are self-contained macro phrases used
* in the columnar output of a macro. They need
@@ -967,6 +981,19 @@ blk_full(MACRO_PROT_ARGS)
if (0 == dohead)
return(1);
+ /*
+ * If there is an open sub-block requiring explicit close-out,
+ * postpone switching the current block from head to body
+ * until the rew_sub() call closing out that sub-block.
+ */
+ for (n = m->last; n && n != head; n = n->parent) {
+ if (MDOC_BLOCK == n->type &&
+ MDOC_EXPLICIT & mdoc_macros[n->tok].flags) {
+ n->pending = head;
+ return(1);
+ }
+ }
+
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
return(0);
if ( ! mdoc_body_alloc(m, line, ppos, tok))