aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/mdoc_term.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2010-06-29 19:20:38 +0000
committerIngo Schwarze <schwarze@openbsd.org>2010-06-29 19:20:38 +0000
commit4c7036f39cd338c9cd69fe37813577f0f4a1bc69 (patch)
treee5acb7c52eab35523e9ecd1eea6b370402dc92f0 /mdoc_term.c
parent1d0a7892377ad99dbf5e1bcd38b15f01a53a28c9 (diff)
downloadmandoc-4c7036f39cd338c9cd69fe37813577f0f4a1bc69.tar.gz
mandoc-4c7036f39cd338c9cd69fe37813577f0f4a1bc69.tar.zst
mandoc-4c7036f39cd338c9cd69fe37813577f0f4a1bc69.zip
Support for badly nested blocks, written around the time of
the Rostock mandoc hackathon and tested and polished since, supporting constructs like: .Ao Bo Ac Bc (exp breaking exp) .Aq Bo eol Bc (imp breaking exp) .Ao Bq Ac eol (exp breaking imp) .Ao Bo So Bc Ac Sc (double break, inner before outer) .Ao Bo So Ac Bc Sc (double break, outer before inner) .Ao Bo Ac So Bc Sc (broken breaker) .Ao Bo So Bc Do Ac Sc Dc (broken double breaker) There are still two known issues which are tricky: 1) Breaking two identical explicit blocks (Ao Bo Bo Ac or Aq Bo Bo eol) fails outright, triggering a bogus syntax error. 2) Breaking a block by two identical explicit blocks (Ao Ao Bo Ac Ac Bc or Ao Ao Bq Ac Ac eol) still has a minor rendering error left: "<ao1 <ao2 [bo ac2> ac1> bc]>" should not have the final ">". We can fix these later in the tree, let's not grow this diff too large. "get it in" kristaps@
Diffstat (limited to 'mdoc_term.c')
-rw-r--r--mdoc_term.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/mdoc_term.c b/mdoc_term.c
index 33cfaac4..6995bba1 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_term.c,v 1.161 2010/06/27 17:53:27 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.162 2010/06/29 19:20:38 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -325,20 +325,37 @@ print_mdoc_node(DECL_ARGS)
memset(&npair, 0, sizeof(struct termpair));
npair.ppair = pair;
- if (MDOC_TEXT != n->type) {
- if (termacts[n->tok].pre)
- chld = (*termacts[n->tok].pre)(p, &npair, m, n);
- } else
+ if (MDOC_TEXT == n->type)
term_word(p, n->string);
+ else if (termacts[n->tok].pre && !n->end)
+ chld = (*termacts[n->tok].pre)(p, &npair, m, n);
if (chld && n->child)
print_mdoc_nodelist(p, &npair, m, n->child);
term_fontpopq(p, font);
- if (MDOC_TEXT != n->type)
- if (termacts[n->tok].post)
- (*termacts[n->tok].post)(p, &npair, m, n);
+ if (MDOC_TEXT != n->type &&
+ termacts[n->tok].post &&
+ ! (MDOC_ENDED & n->flags)) {
+ (*termacts[n->tok].post)(p, &npair, m, n);
+
+ /*
+ * Explicit end tokens not only call the post
+ * handler, but also tell the respective block
+ * that it must not call the post handler again.
+ */
+ if (n->end)
+ n->pending->flags |= MDOC_ENDED;
+
+ /*
+ * End of line terminating an implicit block
+ * while an explicit block is still open.
+ * Continue the explicit block without spacing.
+ */
+ if (ENDBODY_NOSPACE == n->end)
+ p->flags |= TERMP_NOSPACE;
+ }
if (MDOC_EOS & n->flags)
p->flags |= TERMP_SENTENCE;