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 |
12870 |
const char *cp; |
|
36 |
size_t i, j, rows; |
||
37 |
enum htmltag tag; |
||
38 |
enum eqn_fontt font; |
||
39 |
|||
40 |
✓✓ | 6435 |
if (NULL == bp) |
41 |
3294 |
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 |
✓✓ | 3141 |
if (EQN_MATRIX == bp->type) { |
50 |
✓✓ | 27 |
if (NULL == bp->first) |
51 |
goto out; |
||
52 |
✓✗✗✓ |
36 |
if (bp->first->type != EQN_LIST || |
53 |
18 |
bp->first->expectargs == 1) { |
|
54 |
eqn_box(p, bp->first); |
||
55 |
goto out; |
||
56 |
} |
||
57 |
✓✓ | 18 |
if (NULL == (parent = bp->first->first)) |
58 |
goto out; |
||
59 |
/* Estimate the number of rows, first. */ |
||
60 |
✓✗ | 9 |
if (NULL == (child = parent->first)) |
61 |
goto out; |
||
62 |
✓✓ | 54 |
for (rows = 0; NULL != child; rows++) |
63 |
18 |
child = child->next; |
|
64 |
/* Print row-by-row. */ |
||
65 |
9 |
post = print_otag(p, TAG_MTABLE, ""); |
|
66 |
✓✓ | 54 |
for (i = 0; i < rows; i++) { |
67 |
18 |
parent = bp->first->first; |
|
68 |
18 |
row = print_otag(p, TAG_MTR, ""); |
|
69 |
✓✓ | 108 |
while (NULL != parent) { |
70 |
36 |
child = parent->first; |
|
71 |
✓✓ | 162 |
for (j = 0; j < i; j++) { |
72 |
54 |
if (NULL == child) |
|
73 |
break; |
||
74 |
18 |
child = child->next; |
|
75 |
} |
||
76 |
36 |
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 |
✓✗ | 36 |
if (NULL != child) |
83 |
36 |
eqn_box(p, child->first); |
|
84 |
36 |
print_tagq(p, cell); |
|
85 |
36 |
parent = parent->next; |
|
86 |
} |
||
87 |
18 |
print_tagq(p, row); |
|
88 |
} |
||
89 |
goto out; |
||
90 |
} |
||
91 |
|||
92 |
✓✓✗✓ ✓✓✓✓ ✓ |
3573 |
switch (bp->pos) { |
93 |
case EQNPOS_TO: |
||
94 |
9 |
post = print_otag(p, TAG_MOVER, ""); |
|
95 |
9 |
break; |
|
96 |
case EQNPOS_SUP: |
||
97 |
81 |
post = print_otag(p, TAG_MSUP, ""); |
|
98 |
81 |
break; |
|
99 |
case EQNPOS_FROM: |
||
100 |
post = print_otag(p, TAG_MUNDER, ""); |
||
101 |
break; |
||
102 |
case EQNPOS_SUB: |
||
103 |
126 |
post = print_otag(p, TAG_MSUB, ""); |
|
104 |
126 |
break; |
|
105 |
case EQNPOS_OVER: |
||
106 |
72 |
post = print_otag(p, TAG_MFRAC, ""); |
|
107 |
72 |
break; |
|
108 |
case EQNPOS_FROMTO: |
||
109 |
45 |
post = print_otag(p, TAG_MUNDEROVER, ""); |
|
110 |
45 |
break; |
|
111 |
case EQNPOS_SUBSUP: |
||
112 |
63 |
post = print_otag(p, TAG_MSUBSUP, ""); |
|
113 |
63 |
break; |
|
114 |
case EQNPOS_SQRT: |
||
115 |
63 |
post = print_otag(p, TAG_MSQRT, ""); |
|
116 |
63 |
break; |
|
117 |
default: |
||
118 |
break; |
||
119 |
} |
||
120 |
|||
121 |
✓✓✓✓ |
6057 |
if (bp->top || bp->bottom) { |
122 |
✗✓ | 198 |
assert(NULL == post); |
123 |
✓✓✓✗ |
369 |
if (bp->top && NULL == bp->bottom) |
124 |
171 |
post = print_otag(p, TAG_MOVER, ""); |
|
125 |
✗✓✗✗ |
27 |
else if (bp->top && bp->bottom) |
126 |
post = print_otag(p, TAG_MUNDEROVER, ""); |
||
127 |
✓✗ | 27 |
else if (bp->bottom) |
128 |
27 |
post = print_otag(p, TAG_MUNDER, ""); |
|
129 |
} |
||
130 |
|||
131 |
✓✓ | 3114 |
if (EQN_PILE == bp->type) { |
132 |
✗✓ | 18 |
assert(NULL == post); |
133 |
✓✗✓✗ |
36 |
if (bp->first != NULL && |
134 |
✓✗ | 18 |
bp->first->type == EQN_LIST && |
135 |
18 |
bp->first->expectargs > 1) |
|
136 |
18 |
post = print_otag(p, TAG_MTABLE, ""); |
|
137 |
✓✓✓✓ ✓✓ |
3834 |
} else if (bp->type == EQN_LIST && bp->expectargs > 1 && |
138 |
✓✗ | 324 |
bp->parent && bp->parent->type == EQN_PILE) { |
139 |
✗✓ | 36 |
assert(NULL == post); |
140 |
36 |
post = print_otag(p, TAG_MTR, ""); |
|
141 |
36 |
print_otag(p, TAG_MTD, ""); |
|
142 |
36 |
} |
|
143 |
|||
144 |
✓✓ | 3114 |
if (bp->text != NULL) { |
145 |
✗✓ | 1917 |
assert(post == NULL); |
146 |
tag = TAG_MI; |
||
147 |
1917 |
cp = bp->text; |
|
148 |
✓✓✗✗ |
1917 |
if (isdigit((unsigned char)cp[0]) || |
149 |
✗✓ | 1683 |
(cp[0] == '.' && isdigit((unsigned char)cp[1]))) { |
150 |
tag = TAG_MN; |
||
151 |
✓✓ | 504 |
while (*++cp != '\0') { |
152 |
✗✓✓✗ |
72 |
if (*cp != '.' && |
153 |
36 |
isdigit((unsigned char)*cp) == 0) { |
|
154 |
tag = TAG_MI; |
||
155 |
break; |
||
156 |
} |
||
157 |
} |
||
158 |
✓✓✓✓ |
3357 |
} else if (*cp != '\0' && isalpha((unsigned char)*cp) == 0) { |
159 |
tag = TAG_MO; |
||
160 |
✓✓ | 1026 |
while (*cp != '\0') { |
161 |
✓✓✓✗ |
432 |
if (cp[0] == '\\' && cp[1] != '\0') { |
162 |
90 |
cp++; |
|
163 |
90 |
mandoc_escape(&cp, NULL, NULL); |
|
164 |
✗✓ | 342 |
} else if (isalnum((unsigned char)*cp)) { |
165 |
tag = TAG_MI; |
||
166 |
break; |
||
167 |
} else |
||
168 |
252 |
cp++; |
|
169 |
} |
||
170 |
} |
||
171 |
1917 |
font = bp->font; |
|
172 |
✓✓✓✓ |
3249 |
if (bp->text[0] != '\0' && |
173 |
✓✓ | 3816 |
(((tag == TAG_MN || tag == TAG_MO) && |
174 |
1908 |
font == EQNFONT_ROMAN) || |
|
175 |
✓✓ | 2700 |
(tag == TAG_MI && font == (bp->text[1] == '\0' ? |
176 |
EQNFONT_ITALIC : EQNFONT_ROMAN)))) |
||
177 |
1449 |
font = EQNFONT_NONE; |
|
178 |
✓✓✗✓ ✓✗ |
1917 |
switch (font) { |
179 |
case EQNFONT_NONE: |
||
180 |
1494 |
post = print_otag(p, tag, ""); |
|
181 |
1494 |
break; |
|
182 |
case EQNFONT_ROMAN: |
||
183 |
27 |
post = print_otag(p, tag, "?", "fontstyle", "normal"); |
|
184 |
27 |
break; |
|
185 |
case EQNFONT_BOLD: |
||
186 |
case EQNFONT_FAT: |
||
187 |
81 |
post = print_otag(p, tag, "?", "fontweight", "bold"); |
|
188 |
81 |
break; |
|
189 |
case EQNFONT_ITALIC: |
||
190 |
315 |
post = print_otag(p, tag, "?", "fontstyle", "italic"); |
|
191 |
315 |
break; |
|
192 |
default: |
||
193 |
abort(); |
||
194 |
} |
||
195 |
1917 |
print_text(p, bp->text); |
|
196 |
✓✓ | 3114 |
} else if (NULL == post) { |
197 |
✓✓✗✓ |
927 |
if (NULL != bp->left || NULL != bp->right) |
198 |
45 |
post = print_otag(p, TAG_MFENCED, "??", |
|
199 |
✓✗ | 135 |
"open", bp->left == NULL ? "" : bp->left, |
200 |
✓✗ | 135 |
"close", bp->right == NULL ? "" : bp->right); |
201 |
✓✓ | 972 |
if (NULL == post) |
202 |
927 |
post = print_otag(p, TAG_MROW, ""); |
|
203 |
else |
||
204 |
print_otag(p, TAG_MROW, ""); |
||
205 |
} |
||
206 |
|||
207 |
3114 |
eqn_box(p, bp->first); |
|
208 |
|||
209 |
out: |
||
210 |
✓✓ | 3141 |
if (NULL != bp->bottom) { |
211 |
27 |
t = print_otag(p, TAG_MO, ""); |
|
212 |
27 |
print_text(p, bp->bottom); |
|
213 |
27 |
print_tagq(p, t); |
|
214 |
27 |
} |
|
215 |
✓✓ | 3141 |
if (NULL != bp->top) { |
216 |
171 |
t = print_otag(p, TAG_MO, ""); |
|
217 |
171 |
print_text(p, bp->top); |
|
218 |
171 |
print_tagq(p, t); |
|
219 |
171 |
} |
|
220 |
|||
221 |
✓✓ | 3141 |
if (NULL != post) |
222 |
3123 |
print_tagq(p, post); |
|
223 |
|||
224 |
3141 |
eqn_box(p, bp->next); |
|
225 |
9576 |
} |
|
226 |
|||
227 |
void |
||
228 |
print_eqn(struct html *p, const struct eqn_box *bp) |
||
229 |
{ |
||
230 |
struct tag *t; |
||
231 |
|||
232 |
✗✓ | 288 |
if (bp->first == NULL) |
233 |
return; |
||
234 |
|||
235 |
144 |
t = print_otag(p, TAG_MATH, "c", "eqn"); |
|
236 |
|||
237 |
144 |
p->flags |= HTML_NONOSPACE; |
|
238 |
144 |
eqn_box(p, bp); |
|
239 |
144 |
p->flags &= ~HTML_NONOSPACE; |
|
240 |
|||
241 |
144 |
print_tagq(p, t); |
|
242 |
288 |
} |
Generated by: GCOVR (Version 3.3) |