Annotation of mandoc/eqn_html.c, Revision 1.8
1.8 ! kristaps 1: /* $Id: eqn_html.c,v 1.7 2014/09/28 20:14:20 kristaps Exp $ */
1.1 kristaps 2: /*
3: * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #include "config.h"
1.4 schwarze 18:
19: #include <sys/types.h>
1.1 kristaps 20:
21: #include <assert.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <string.h>
25:
26: #include "mandoc.h"
27: #include "out.h"
28: #include "html.h"
29:
1.8 ! kristaps 30: static void
! 31: eqn_box(struct html *p, const struct eqn_box *bp)
1.1 kristaps 32: {
1.8 ! kristaps 33: struct tag *post, *row, *cell, *t;
1.5 kristaps 34: struct htmlpair tag[2];
1.8 ! kristaps 35: const struct eqn_box *child, *parent;
! 36: size_t i, j, rows;
1.5 kristaps 37:
38: if (NULL == bp)
1.8 ! kristaps 39: return;
1.5 kristaps 40:
1.8 ! kristaps 41: post = NULL;
1.5 kristaps 42:
43: /*
1.8 ! kristaps 44: * Special handling for a matrix, which is presented to us in
! 45: * column order, but must be printed in row-order.
1.5 kristaps 46: */
1.8 ! kristaps 47: if (EQN_MATRIX == bp->type) {
! 48: if (NULL == bp->first)
! 49: goto out;
! 50: assert(EQN_LIST == bp->first->type);
! 51: if (NULL == (parent = bp->first->first))
! 52: goto out;
! 53: assert(EQN_PILE == parent->type);
! 54: /* Estimate the number of rows, first. */
! 55: if (NULL == (child = parent->first))
! 56: goto out;
! 57: for (rows = 0; NULL != child; rows++)
! 58: child = child->next;
! 59: /* Print row-by-row. */
! 60: post = print_otag(p, TAG_MTABLE, 0, NULL);
! 61: for (i = 0; i < rows; i++) {
! 62: parent = bp->first->first;
! 63: row = print_otag(p, TAG_MTR, 0, NULL);
! 64: while (NULL != parent) {
! 65: child = parent->first;
! 66: for (j = 0; j < i; j++) {
! 67: if (NULL == child)
! 68: break;
! 69: child = child->next;
! 70: }
! 71: cell = print_otag
! 72: (p, TAG_MTD, 0, NULL);
! 73: /*
! 74: * If we have no data for this
! 75: * particular cell, then print a
! 76: * placeholder and continue--don't puke.
! 77: */
! 78: if (NULL != child)
! 79: eqn_box(p, child->first);
! 80: print_tagq(p, cell);
! 81: parent = parent->next;
! 82: }
! 83: print_tagq(p, row);
! 84: }
! 85: goto out;
1.6 kristaps 86: }
1.5 kristaps 87:
88: switch (bp->pos) {
1.6 kristaps 89: case (EQNPOS_TO):
1.7 kristaps 90: post = print_otag(p, TAG_MOVER, 0, NULL);
91: break;
1.5 kristaps 92: case (EQNPOS_SUP):
93: post = print_otag(p, TAG_MSUP, 0, NULL);
94: break;
95: case (EQNPOS_FROM):
1.7 kristaps 96: post = print_otag(p, TAG_MUNDER, 0, NULL);
97: break;
1.5 kristaps 98: case (EQNPOS_SUB):
99: post = print_otag(p, TAG_MSUB, 0, NULL);
100: break;
101: case (EQNPOS_OVER):
102: post = print_otag(p, TAG_MFRAC, 0, NULL);
103: break;
1.6 kristaps 104: case (EQNPOS_FROMTO):
1.7 kristaps 105: post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
106: break;
1.5 kristaps 107: case (EQNPOS_SUBSUP):
108: post = print_otag(p, TAG_MSUBSUP, 0, NULL);
1.8 ! kristaps 109: break;
! 110: case (EQNPOS_SQRT):
! 111: post = print_otag(p, TAG_MSQRT, 0, NULL);
1.5 kristaps 112: break;
113: default:
114: break;
115: }
116:
1.8 ! kristaps 117: if (bp->top || bp->bottom) {
! 118: assert(NULL == post);
! 119: if (bp->top && NULL == bp->bottom)
! 120: post = print_otag(p, TAG_MOVER, 0, NULL);
! 121: else if (bp->top && bp->bottom)
! 122: post = print_otag(p, TAG_MUNDEROVER, 0, NULL);
! 123: else if (bp->bottom)
! 124: post = print_otag(p, TAG_MUNDER, 0, NULL);
! 125: }
! 126:
! 127: if (EQN_PILE == bp->type) {
! 128: assert(NULL == post);
! 129: post = print_otag(p, TAG_MTABLE, 0, NULL);
! 130: } else if (bp->parent && EQN_PILE == bp->parent->type) {
! 131: assert(NULL == post);
! 132: post = print_otag(p, TAG_MTR, 0, NULL);
! 133: print_otag(p, TAG_MTD, 0, NULL);
! 134: }
1.5 kristaps 135:
136: if (NULL != bp->text) {
1.8 ! kristaps 137: assert(NULL == post);
! 138: post = print_otag(p, TAG_MI, 0, NULL);
! 139: print_text(p, bp->text);
! 140: } else if (NULL == post) {
1.5 kristaps 141: if (NULL != bp->left || NULL != bp->right) {
142: PAIR_INIT(&tag[0], ATTR_OPEN,
1.8 ! kristaps 143: NULL == bp->left ? "" : bp->left);
1.5 kristaps 144: PAIR_INIT(&tag[1], ATTR_CLOSE,
1.8 ! kristaps 145: NULL == bp->right ? "" : bp->right);
! 146: post = print_otag(p, TAG_MFENCED, 2, tag);
! 147: }
! 148: if (NULL == post)
! 149: post = print_otag(p, TAG_MROW, 0, NULL);
! 150: else
1.5 kristaps 151: print_otag(p, TAG_MROW, 0, NULL);
152: }
153:
1.8 ! kristaps 154: eqn_box(p, bp->first);
! 155:
! 156: out:
! 157: if (NULL != bp->bottom) {
! 158: t = print_otag(p, TAG_MO, 0, NULL);
! 159: print_text(p, bp->bottom);
! 160: print_tagq(p, t);
! 161: }
! 162: if (NULL != bp->top) {
! 163: t = print_otag(p, TAG_MO, 0, NULL);
! 164: print_text(p, bp->top);
! 165: print_tagq(p, t);
! 166: }
! 167:
! 168: if (NULL != post)
1.5 kristaps 169: print_tagq(p, post);
170:
1.8 ! kristaps 171: eqn_box(p, bp->next);
! 172: }
! 173:
! 174: void
! 175: print_eqn(struct html *p, const struct eqn *ep)
! 176: {
! 177: struct htmlpair tag;
! 178: struct tag *t;
! 179:
! 180: PAIR_CLASS_INIT(&tag, "eqn");
! 181: t = print_otag(p, TAG_MATH, 1, &tag);
! 182:
! 183: p->flags |= HTML_NONOSPACE;
! 184: eqn_box(p, ep->root);
! 185: p->flags &= ~HTML_NONOSPACE;
1.5 kristaps 186:
1.8 ! kristaps 187: print_tagq(p, t);
1.1 kristaps 188: }
CVSweb