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