summaryrefslogtreecommitdiffstats
path: root/contrib/mdocml/eqn_html.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/mdocml/eqn_html.c')
-rw-r--r--contrib/mdocml/eqn_html.c189
1 files changed, 150 insertions, 39 deletions
diff --git a/contrib/mdocml/eqn_html.c b/contrib/mdocml/eqn_html.c
index 3e58ab5..f297336 100644
--- a/contrib/mdocml/eqn_html.c
+++ b/contrib/mdocml/eqn_html.c
@@ -1,6 +1,6 @@
-/* $Id: eqn_html.c,v 1.3 2014/04/20 16:46:04 schwarze Exp $ */
+/* $Id: eqn_html.c,v 1.10 2014/10/12 19:31:41 schwarze Exp $ */
/*
- * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,9 +14,9 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
+
+#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
@@ -27,16 +27,153 @@
#include "out.h"
#include "html.h"
-static const enum htmltag fontmap[EQNFONT__MAX] = {
- TAG_SPAN, /* EQNFONT_NONE */
- TAG_SPAN, /* EQNFONT_ROMAN */
- TAG_B, /* EQNFONT_BOLD */
- TAG_B, /* EQNFONT_FAT */
- TAG_I /* EQNFONT_ITALIC */
-};
+static void
+eqn_box(struct html *p, const struct eqn_box *bp)
+{
+ struct tag *post, *row, *cell, *t;
+ struct htmlpair tag[2];
+ const struct eqn_box *child, *parent;
+ size_t i, j, rows;
+
+ if (NULL == bp)
+ return;
+
+ post = NULL;
+
+ /*
+ * Special handling for a matrix, which is presented to us in
+ * column order, but must be printed in row-order.
+ */
+ if (EQN_MATRIX == bp->type) {
+ if (NULL == bp->first)
+ goto out;
+ if (EQN_LIST != bp->first->type) {
+ eqn_box(p, bp->first);
+ goto out;
+ }
+ if (NULL == (parent = bp->first->first))
+ goto out;
+ /* Estimate the number of rows, first. */
+ if (NULL == (child = parent->first))
+ goto out;
+ for (rows = 0; NULL != child; rows++)
+ child = child->next;
+ /* Print row-by-row. */
+ post = print_otag(p, TAG_MTABLE, 0, NULL);
+ for (i = 0; i < rows; i++) {
+ parent = bp->first->first;
+ row = print_otag(p, TAG_MTR, 0, NULL);
+ while (NULL != parent) {
+ child = parent->first;
+ for (j = 0; j < i; j++) {
+ if (NULL == child)
+ break;
+ child = child->next;
+ }
+ cell = print_otag
+ (p, TAG_MTD, 0, NULL);
+ /*
+ * If we have no data for this
+ * particular cell, then print a
+ * placeholder and continue--don't puke.
+ */
+ if (NULL != child)
+ eqn_box(p, child->first);
+ print_tagq(p, cell);
+ parent = parent->next;
+ }
+ print_tagq(p, row);
+ }
+ goto out;
+ }
+
+ switch (bp->pos) {
+ case (EQNPOS_TO):
+ post = print_otag(p, TAG_MOVER, 0, NULL);
+ break;
+ case (EQNPOS_SUP):
+ post = print_otag(p, TAG_MSUP, 0, NULL);
+ break;
+ case (EQNPOS_FROM):
+ post = print_otag(p, TAG_MUNDER, 0, NULL);
+ break;
+ case (EQNPOS_SUB):
+ post = print_otag(p, TAG_MSUB, 0, NULL);
+ break;
+ case (EQNPOS_OVER):
+ post = print_otag(p, TAG_MFRAC, 0, NULL);
+ break;
+ case (EQNPOS_FROMTO):
+ post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
+ break;
+ case (EQNPOS_SUBSUP):
+ post = print_otag(p, TAG_MSUBSUP, 0, NULL);
+ break;
+ case (EQNPOS_SQRT):
+ post = print_otag(p, TAG_MSQRT, 0, NULL);
+ break;
+ default:
+ break;
+ }
+
+ if (bp->top || bp->bottom) {
+ assert(NULL == post);
+ if (bp->top && NULL == bp->bottom)
+ post = print_otag(p, TAG_MOVER, 0, NULL);
+ else if (bp->top && bp->bottom)
+ post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
+ else if (bp->bottom)
+ post = print_otag(p, TAG_MUNDER, 0, NULL);
+ }
+
+ if (EQN_PILE == bp->type) {
+ assert(NULL == post);
+ if (bp->first != NULL && bp->first->type == EQN_LIST)
+ post = print_otag(p, TAG_MTABLE, 0, NULL);
+ } else if (bp->type == EQN_LIST &&
+ bp->parent && bp->parent->type == EQN_PILE) {
+ assert(NULL == post);
+ post = print_otag(p, TAG_MTR, 0, NULL);
+ print_otag(p, TAG_MTD, 0, NULL);
+ }
+
+ if (NULL != bp->text) {
+ assert(NULL == post);
+ post = print_otag(p, TAG_MI, 0, NULL);
+ print_text(p, bp->text);
+ } else if (NULL == post) {
+ if (NULL != bp->left || NULL != bp->right) {
+ PAIR_INIT(&tag[0], ATTR_OPEN,
+ NULL == bp->left ? "" : bp->left);
+ PAIR_INIT(&tag[1], ATTR_CLOSE,
+ NULL == bp->right ? "" : bp->right);
+ post = print_otag(p, TAG_MFENCED, 2, tag);
+ }
+ if (NULL == post)
+ post = print_otag(p, TAG_MROW, 0, NULL);
+ else
+ print_otag(p, TAG_MROW, 0, NULL);
+ }
+
+ eqn_box(p, bp->first);
+
+out:
+ if (NULL != bp->bottom) {
+ t = print_otag(p, TAG_MO, 0, NULL);
+ print_text(p, bp->bottom);
+ print_tagq(p, t);
+ }
+ if (NULL != bp->top) {
+ t = print_otag(p, TAG_MO, 0, NULL);
+ print_text(p, bp->top);
+ print_tagq(p, t);
+ }
-static void eqn_box(struct html *, const struct eqn_box *);
+ if (NULL != post)
+ print_tagq(p, post);
+ eqn_box(p, bp->next);
+}
void
print_eqn(struct html *p, const struct eqn *ep)
@@ -45,7 +182,7 @@ print_eqn(struct html *p, const struct eqn *ep)
struct tag *t;
PAIR_CLASS_INIT(&tag, "eqn");
- t = print_otag(p, TAG_SPAN, 1, &tag);
+ t = print_otag(p, TAG_MATH, 1, &tag);
p->flags |= HTML_NONOSPACE;
eqn_box(p, ep->root);
@@ -53,29 +190,3 @@ print_eqn(struct html *p, const struct eqn *ep)
print_tagq(p, t);
}
-
-static void
-eqn_box(struct html *p, const struct eqn_box *bp)
-{
- struct tag *t;
-
- t = EQNFONT_NONE == bp->font ? NULL :
- print_otag(p, fontmap[(int)bp->font], 0, NULL);
-
- if (bp->left)
- print_text(p, bp->left);
-
- if (bp->text)
- print_text(p, bp->text);
-
- if (bp->first)
- eqn_box(p, bp->first);
-
- if (NULL != t)
- print_tagq(p, t);
- if (bp->right)
- print_text(p, bp->right);
-
- if (bp->next)
- eqn_box(p, bp->next);
-}
OpenPOWER on IntegriCloud