GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: eqn_html.c,v 1.13 2017/07/14 13:32:27 schwarze Exp $ */ |
||
2 |
/* |
||
3 |
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
||
4 |
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> |
||
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 <sys/types.h> |
||
19 |
|||
20 |
#include <assert.h> |
||
21 |
#include <ctype.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 |
|||
30 |
static void |
||
31 |
eqn_box(struct html *p, const struct eqn_box *bp) |
||
32 |
{ |
||
33 |
struct tag *post, *row, *cell, *t; |
||
34 |
const struct eqn_box *child, *parent; |
||
35 |
4290 |
const char *cp; |
|
36 |
size_t i, j, rows; |
||
37 |
enum htmltag tag; |
||
38 |
enum eqn_fontt font; |
||
39 |
|||
40 |
✓✓ | 2145 |
if (NULL == bp) |
41 |
1098 |
return; |
|
42 |
|||
43 |
post = NULL; |
||
44 |
|||
45 |
/* |
||
46 |
* Special handling for a matrix, which is presented to us in |
||
47 |
* column order, but must be printed in row-order. |
||
48 |
*/ |
||
49 |
✓✓ | 1047 |
if (EQN_MATRIX == bp->type) { |
50 |
✓✓ | 9 |
if (NULL == bp->first) |
51 |
goto out; |
||
52 |
✓✗✗✓ |
12 |
if (bp->first->type != EQN_LIST || |
53 |
6 |
bp->first->expectargs == 1) { |
|
54 |
eqn_box(p, bp->first); |
||
55 |
goto out; |
||
56 |
} |
||
57 |
✓✓ | 6 |
if (NULL == (parent = bp->first->first)) |
58 |
goto out; |
||
59 |
/* Estimate the number of rows, first. */ |
||
60 |
✓✗ | 3 |
if (NULL == (child = parent->first)) |
61 |
goto out; |
||
62 |
✓✓ | 18 |
for (rows = 0; NULL != child; rows++) |
63 |
6 |
child = child->next; |
|
64 |
/* Print row-by-row. */ |
||
65 |
3 |
post = print_otag(p, TAG_MTABLE, ""); |
|
66 |
✓✓ | 18 |
for (i = 0; i < rows; i++) { |
67 |
6 |
parent = bp->first->first; |
|
68 |
6 |
row = print_otag(p, TAG_MTR, ""); |
|
69 |
✓✓ | 36 |
while (NULL != parent) { |
70 |
12 |
child = parent->first; |
|
71 |
✓✓ | 54 |
for (j = 0; j < i; j++) { |
72 |
18 |
if (NULL == child) |
|
73 |
break; |
||
74 |
6 |
child = child->next; |
|
75 |
} |
||
76 |
12 |
cell = print_otag(p, TAG_MTD, ""); |
|
77 |
/* |
||
78 |
* If we have no data for this |
||
79 |
* particular cell, then print a |
||
80 |
* placeholder and continue--don't puke. |
||
81 |
*/ |
||
82 |
✓✗ | 12 |
if (NULL != child) |
83 |
12 |
eqn_box(p, child->first); |
|
84 |
12 |
print_tagq(p, cell); |
|
85 |
12 |
parent = parent->next; |
|
86 |
} |
||
87 |
6 |
print_tagq(p, row); |
|
88 |
} |
||
89 |
goto out; |
||
90 |
} |
||
91 |
|||
92 |
✓✓✗✓ ✓✓✓✓ ✓ |
1191 |
switch (bp->pos) { |
93 |
case EQNPOS_TO: |
||
94 |
3 |
post = print_otag(p, TAG_MOVER, ""); |
|
95 |
3 |
break; |
|
96 |
case EQNPOS_SUP: |
||
97 |
27 |
post = print_otag(p, TAG_MSUP, ""); |
|
98 |
27 |
break; |
|
99 |
case EQNPOS_FROM: |
||
100 |
post = print_otag(p, TAG_MUNDER, ""); |
||
101 |
break; |
||
102 |
case EQNPOS_SUB: |
||
103 |
42 |
post = print_otag(p, TAG_MSUB, ""); |
|
104 |
42 |
break; |
|
105 |
case EQNPOS_OVER: |
||
106 |
24 |
post = print_otag(p, TAG_MFRAC, ""); |
|
107 |
24 |
break; |
|
108 |
case EQNPOS_FROMTO: |
||
109 |
15 |
post = print_otag(p, TAG_MUNDEROVER, ""); |
|
110 |
15 |
break; |
|
111 |
case EQNPOS_SUBSUP: |
||
112 |
21 |
post = print_otag(p, TAG_MSUBSUP, ""); |
|
113 |
21 |
break; |
|
114 |
case EQNPOS_SQRT: |
||
115 |
21 |
post = print_otag(p, TAG_MSQRT, ""); |
|
116 |
21 |
break; |
|
117 |
default: |
||
118 |
break; |
||
119 |
} |
||
120 |
|||
121 |
✓✓✓✓ |
2019 |
if (bp->top || bp->bottom) { |
122 |
✗✓ | 66 |
assert(NULL == post); |
123 |
✓✓✓✗ |
123 |
if (bp->top && NULL == bp->bottom) |
124 |
57 |
post = print_otag(p, TAG_MOVER, ""); |
|
125 |
✗✓✗✗ |
9 |
else if (bp->top && bp->bottom) |
126 |
post = print_otag(p, TAG_MUNDEROVER, ""); |
||
127 |
✓✗ | 9 |
else if (bp->bottom) |
128 |
9 |
post = print_otag(p, TAG_MUNDER, ""); |
|
129 |
} |
||
130 |
|||
131 |
✓✓ | 1038 |
if (EQN_PILE == bp->type) { |
132 |
✗✓ | 6 |
assert(NULL == post); |
133 |
✓✗✓✗ |
12 |
if (bp->first != NULL && |
134 |
✓✗ | 6 |
bp->first->type == EQN_LIST && |
135 |
6 |
bp->first->expectargs > 1) |
|
136 |
6 |
post = print_otag(p, TAG_MTABLE, ""); |
|
137 |
✓✓✓✓ ✓✓ |
1278 |
} else if (bp->type == EQN_LIST && bp->expectargs > 1 && |
138 |
✓✗ | 108 |
bp->parent && bp->parent->type == EQN_PILE) { |
139 |
✗✓ | 12 |
assert(NULL == post); |
140 |
12 |
post = print_otag(p, TAG_MTR, ""); |
|
141 |
12 |
print_otag(p, TAG_MTD, ""); |
|
142 |
12 |
} |
|
143 |
|||
144 |
✓✓ | 1038 |
if (bp->text != NULL) { |
145 |
✗✓ | 639 |
assert(post == NULL); |
146 |
tag = TAG_MI; |
||
147 |
639 |
cp = bp->text; |
|
148 |
✓✓✗✗ |
639 |
if (isdigit((unsigned char)cp[0]) || |
149 |
✗✓ | 561 |
(cp[0] == '.' && isdigit((unsigned char)cp[1]))) { |
150 |
tag = TAG_MN; |
||
151 |
✓✓ | 180 |
while (*++cp != '\0') { |
152 |
✓✗✗✓ |
24 |
if (*cp != '.' && |
153 |
12 |
isdigit((unsigned char)*cp) == 0) { |
|
154 |
tag = TAG_MI; |
||
155 |
break; |
||
156 |
} |
||
157 |
} |
||
158 |
✓✓✓✓ |
1119 |
} else if (*cp != '\0' && isalpha((unsigned char)*cp) == 0) { |
159 |
tag = TAG_MO; |
||
160 |
✓✓ | 456 |
while (*cp != '\0') { |
161 |
✓✓✓✗ |
144 |
if (cp[0] == '\\' && cp[1] != '\0') { |
162 |
30 |
cp++; |
|
163 |
30 |
mandoc_escape(&cp, NULL, NULL); |
|
164 |
✗✓ | 114 |
} else if (isalnum((unsigned char)*cp)) { |
165 |
tag = TAG_MI; |
||
166 |
break; |
||
167 |
} else |
||
168 |
84 |
cp++; |
|
169 |
} |
||
170 |
} |
||
171 |
639 |
font = bp->font; |
|
172 |
✓✓✓✓ |
1083 |
if (bp->text[0] != '\0' && |
173 |
✓✓ | 1272 |
(((tag == TAG_MN || tag == TAG_MO) && |
174 |
636 |
font == EQNFONT_ROMAN) || |
|
175 |
✓✓ | 900 |
(tag == TAG_MI && font == (bp->text[1] == '\0' ? |
176 |
EQNFONT_ITALIC : EQNFONT_ROMAN)))) |
||
177 |
483 |
font = EQNFONT_NONE; |
|
178 |
✓✓✗✓ ✓✗ |
639 |
switch (font) { |
179 |
case EQNFONT_NONE: |
||
180 |
498 |
post = print_otag(p, tag, ""); |
|
181 |
498 |
break; |
|
182 |
case EQNFONT_ROMAN: |
||
183 |
9 |
post = print_otag(p, tag, "?", "fontstyle", "normal"); |
|
184 |
9 |
break; |
|
185 |
case EQNFONT_BOLD: |
||
186 |
case EQNFONT_FAT: |
||
187 |
27 |
post = print_otag(p, tag, "?", "fontweight", "bold"); |
|
188 |
27 |
break; |
|
189 |
case EQNFONT_ITALIC: |
||
190 |
105 |
post = print_otag(p, tag, "?", "fontstyle", "italic"); |
|
191 |
105 |
break; |
|
192 |
default: |
||
193 |
abort(); |
||
194 |
} |
||
195 |
639 |
print_text(p, bp->text); |
|
196 |
✓✓ | 1038 |
} else if (NULL == post) { |
197 |
✓✓✗✓ |
309 |
if (NULL != bp->left || NULL != bp->right) |
198 |
15 |
post = print_otag(p, TAG_MFENCED, "??", |
|
199 |
✓✗ | 45 |
"open", bp->left == NULL ? "" : bp->left, |
200 |
✓✗ | 45 |
"close", bp->right == NULL ? "" : bp->right); |
201 |
✓✓ | 324 |
if (NULL == post) |
202 |
309 |
post = print_otag(p, TAG_MROW, ""); |
|
203 |
else |
||
204 |
print_otag(p, TAG_MROW, ""); |
||
205 |
} |
||
206 |
|||
207 |
1038 |
eqn_box(p, bp->first); |
|
208 |
|||
209 |
out: |
||
210 |
✓✓ | 1047 |
if (NULL != bp->bottom) { |
211 |
9 |
t = print_otag(p, TAG_MO, ""); |
|
212 |
9 |
print_text(p, bp->bottom); |
|
213 |
9 |
print_tagq(p, t); |
|
214 |
9 |
} |
|
215 |
✓✓ | 1047 |
if (NULL != bp->top) { |
216 |
57 |
t = print_otag(p, TAG_MO, ""); |
|
217 |
57 |
print_text(p, bp->top); |
|
218 |
57 |
print_tagq(p, t); |
|
219 |
57 |
} |
|
220 |
|||
221 |
✓✓ | 1047 |
if (NULL != post) |
222 |
1041 |
print_tagq(p, post); |
|
223 |
|||
224 |
1047 |
eqn_box(p, bp->next); |
|
225 |
3192 |
} |
|
226 |
|||
227 |
void |
||
228 |
print_eqn(struct html *p, const struct eqn_box *bp) |
||
229 |
{ |
||
230 |
struct tag *t; |
||
231 |
|||
232 |
✗✓ | 96 |
if (bp->first == NULL) |
233 |
return; |
||
234 |
|||
235 |
48 |
t = print_otag(p, TAG_MATH, "c", "eqn"); |
|
236 |
|||
237 |
48 |
p->flags |= HTML_NONOSPACE; |
|
238 |
48 |
eqn_box(p, bp); |
|
239 |
48 |
p->flags &= ~HTML_NONOSPACE; |
|
240 |
|||
241 |
48 |
print_tagq(p, t); |
|
242 |
96 |
} |
Generated by: GCOVR (Version 3.3) |