]>
git.cameronkatri.com Git - mandoc.git/blob - eqn_html.c
1 /* $Id: eqn_html.c,v 1.17 2017/07/14 13:32:35 schwarze Exp $ */
3 * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
4 * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
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.
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.
20 #include <sys/types.h>
33 eqn_box(struct html
*p
, const struct eqn_box
*bp
)
35 struct tag
*post
, *row
, *cell
, *t
;
36 const struct eqn_box
*child
, *parent
;
48 * Special handling for a matrix, which is presented to us in
49 * column order, but must be printed in row-order.
51 if (EQN_MATRIX
== bp
->type
) {
52 if (NULL
== bp
->first
)
54 if (bp
->first
->type
!= EQN_LIST
||
55 bp
->first
->expectargs
== 1) {
56 eqn_box(p
, bp
->first
);
59 if (NULL
== (parent
= bp
->first
->first
))
61 /* Estimate the number of rows, first. */
62 if (NULL
== (child
= parent
->first
))
64 for (rows
= 0; NULL
!= child
; rows
++)
66 /* Print row-by-row. */
67 post
= print_otag(p
, TAG_MTABLE
, "");
68 for (i
= 0; i
< rows
; i
++) {
69 parent
= bp
->first
->first
;
70 row
= print_otag(p
, TAG_MTR
, "");
71 while (NULL
!= parent
) {
72 child
= parent
->first
;
73 for (j
= 0; j
< i
; j
++) {
78 cell
= print_otag(p
, TAG_MTD
, "");
80 * If we have no data for this
81 * particular cell, then print a
82 * placeholder and continue--don't puke.
85 eqn_box(p
, child
->first
);
87 parent
= parent
->next
;
96 post
= print_otag(p
, TAG_MOVER
, "");
99 post
= print_otag(p
, TAG_MSUP
, "");
102 post
= print_otag(p
, TAG_MUNDER
, "");
105 post
= print_otag(p
, TAG_MSUB
, "");
108 post
= print_otag(p
, TAG_MFRAC
, "");
111 post
= print_otag(p
, TAG_MUNDEROVER
, "");
114 post
= print_otag(p
, TAG_MSUBSUP
, "");
117 post
= print_otag(p
, TAG_MSQRT
, "");
123 if (bp
->top
|| bp
->bottom
) {
124 assert(NULL
== post
);
125 if (bp
->top
&& NULL
== bp
->bottom
)
126 post
= print_otag(p
, TAG_MOVER
, "");
127 else if (bp
->top
&& bp
->bottom
)
128 post
= print_otag(p
, TAG_MUNDEROVER
, "");
130 post
= print_otag(p
, TAG_MUNDER
, "");
133 if (EQN_PILE
== bp
->type
) {
134 assert(NULL
== post
);
135 if (bp
->first
!= NULL
&&
136 bp
->first
->type
== EQN_LIST
&&
137 bp
->first
->expectargs
> 1)
138 post
= print_otag(p
, TAG_MTABLE
, "");
139 } else if (bp
->type
== EQN_LIST
&& bp
->expectargs
> 1 &&
140 bp
->parent
&& bp
->parent
->type
== EQN_PILE
) {
141 assert(NULL
== post
);
142 post
= print_otag(p
, TAG_MTR
, "");
143 print_otag(p
, TAG_MTD
, "");
146 if (bp
->text
!= NULL
) {
147 assert(post
== NULL
);
150 if (isdigit((unsigned char)cp
[0]) ||
151 (cp
[0] == '.' && isdigit((unsigned char)cp
[1]))) {
153 while (*++cp
!= '\0') {
155 isdigit((unsigned char)*cp
) == 0) {
160 } else if (*cp
!= '\0' && isalpha((unsigned char)*cp
) == 0) {
162 while (*cp
!= '\0') {
163 if (cp
[0] == '\\' && cp
[1] != '\0') {
165 mandoc_escape(&cp
, NULL
, NULL
);
166 } else if (isalnum((unsigned char)*cp
)) {
174 if (bp
->text
[0] != '\0' &&
175 (((tag
== TAG_MN
|| tag
== TAG_MO
) &&
176 font
== EQNFONT_ROMAN
) ||
177 (tag
== TAG_MI
&& font
== (bp
->text
[1] == '\0' ?
178 EQNFONT_ITALIC
: EQNFONT_ROMAN
))))
182 post
= print_otag(p
, tag
, "");
185 post
= print_otag(p
, tag
, "?", "fontstyle", "normal");
189 post
= print_otag(p
, tag
, "?", "fontweight", "bold");
192 post
= print_otag(p
, tag
, "?", "fontstyle", "italic");
197 print_text(p
, bp
->text
);
198 } else if (NULL
== post
) {
199 if (NULL
!= bp
->left
|| NULL
!= bp
->right
)
200 post
= print_otag(p
, TAG_MFENCED
, "??",
201 "open", bp
->left
== NULL
? "" : bp
->left
,
202 "close", bp
->right
== NULL
? "" : bp
->right
);
204 post
= print_otag(p
, TAG_MROW
, "");
206 print_otag(p
, TAG_MROW
, "");
209 eqn_box(p
, bp
->first
);
212 if (NULL
!= bp
->bottom
) {
213 t
= print_otag(p
, TAG_MO
, "");
214 print_text(p
, bp
->bottom
);
217 if (NULL
!= bp
->top
) {
218 t
= print_otag(p
, TAG_MO
, "");
219 print_text(p
, bp
->top
);
226 eqn_box(p
, bp
->next
);
230 print_eqn(struct html
*p
, const struct eqn_box
*bp
)
234 if (bp
->first
== NULL
)
237 t
= print_otag(p
, TAG_MATH
, "c", "eqn");
239 p
->flags
|= HTML_NONOSPACE
;
241 p
->flags
&= ~HTML_NONOSPACE
;