summaryrefslogtreecommitdiffstats
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
parent2de34eb0e01415539c913fb6e544bc4e76fd913c (diff)
downloadmandoc-b4ad463b0c72a6199c558ac2e87077f7773d5f9d.tar.gz
Add support for EQNPOS_SUBSUP and a doubly-linked eqn_box list.
-rw-r--r--eqn.c28
-rw-r--r--mandoc.h2
2 files changed, 25 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);
diff --git a/mandoc.h b/mandoc.h
index 4f7a193d..6fcab1e8 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -336,6 +336,7 @@ enum eqn_post {
EQNPOS_NONE = 0,
EQNPOS_OVER,
EQNPOS_SUP,
+ EQNPOS_SUBSUP,
EQNPOS_SUB,
EQNPOS_TO,
EQNPOS_FROM,
@@ -366,6 +367,7 @@ struct eqn_box {
struct eqn_box *first; /* first child node */
struct eqn_box *last; /* last child node */
struct eqn_box *next; /* node sibling */
+ struct eqn_box *prev; /* node sibling */
struct eqn_box *parent; /* node sibling */
char *text; /* text (or NULL) */
char *left;