summaryrefslogtreecommitdiffstats
path: root/eqn.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2014-09-28 11:32:08 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2014-09-28 11:32:08 +0000
commitb4ad463b0c72a6199c558ac2e87077f7773d5f9d (patch)
treee4b77332a6b56b892e5d6c86463c53d9963a4772 /eqn.c
parent2de34eb0e01415539c913fb6e544bc4e76fd913c (diff)
downloadmandoc-b4ad463b0c72a6199c558ac2e87077f7773d5f9d.tar.gz
Add support for EQNPOS_SUBSUP and a doubly-linked eqn_box list.
Diffstat (limited to 'eqn.c')
-rw-r--r--eqn.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/eqn.c b/eqn.c
index 0da67f19..6fb9e236 100644
--- a/eqn.c
+++ b/eqn.c
@@ -198,6 +198,7 @@ static const struct eqnstr eqnposs[EQNPOS__MAX] = {
{ "", 0 }, /* EQNPOS_NONE */
{ "over", 4 }, /* EQNPOS_OVER */
{ "sup", 3 }, /* EQNPOS_SUP */
+ { NULL, 0 }, /* EQNPOS_SUPSUB */
{ "sub", 3 }, /* EQNPOS_SUB */
{ "to", 2 }, /* EQNPOS_TO */
{ "from", 4 }, /* EQNPOS_FROM */
@@ -569,14 +570,30 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last)
return(EQN_OK);
}
+ /*
+ * Positional elements (e.g., over, sub, sup, ...).
+ */
for (i = 0; i < (int)EQNPOS__MAX; i++) {
- if ( ! EQNSTREQ(&eqnposs[i], start, sz))
+ /* Some elements don't have names (are virtual). */
+ if (NULL == eqnposs[i].name)
+ continue;
+ else if ( ! EQNSTREQ(&eqnposs[i], start, sz))
continue;
if (NULL == last->last) {
EQN_MSG(MANDOCERR_EQNSYNT, ep);
return(EQN_ERR);
}
- last->last->pos = (enum eqn_post)i;
+ /*
+ * If we encounter x sub y sup z, then according to the
+ * eqn manual, we regard this as x subsup y z.
+ */
+ if (EQNPOS_SUP == i &&
+ NULL != last->last->prev &&
+ EQNPOS_SUB == last->last->prev->pos)
+ last->last->prev->pos = EQNPOS_SUBSUP;
+ else
+ last->last->pos = (enum eqn_post)i;
+
if (EQN_EOF == (c = eqn_box(ep, last))) {
EQN_MSG(MANDOCERR_EQNEOF, ep);
return(EQN_ERR);
@@ -665,10 +682,11 @@ eqn_box_alloc(struct eqn_node *ep, struct eqn_box *parent)
bp->parent = parent;
bp->size = ep->gsize;
- if (NULL == parent->first)
- parent->first = bp;
- else
+ if (NULL != parent->first) {
parent->last->next = bp;
+ bp->prev = parent->last;
+ } else
+ parent->first = bp;
parent->last = bp;
return(bp);