GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* $OpenBSD: man_html.c,v 1.98 2017/06/25 07:23:53 bentley Exp $ */ |
||
2 |
/* |
||
3 |
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
||
4 |
* Copyright (c) 2013, 2014, 2015, 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 AUTHORS DISCLAIM ALL WARRANTIES |
||
11 |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||
12 |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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_aux.h" |
||
27 |
#include "mandoc.h" |
||
28 |
#include "roff.h" |
||
29 |
#include "man.h" |
||
30 |
#include "out.h" |
||
31 |
#include "html.h" |
||
32 |
#include "main.h" |
||
33 |
|||
34 |
/* FIXME: have PD set the default vspace width. */ |
||
35 |
|||
36 |
#define INDENT 5 |
||
37 |
|||
38 |
#define MAN_ARGS const struct roff_meta *man, \ |
||
39 |
const struct roff_node *n, \ |
||
40 |
struct html *h |
||
41 |
|||
42 |
struct htmlman { |
||
43 |
int (*pre)(MAN_ARGS); |
||
44 |
int (*post)(MAN_ARGS); |
||
45 |
}; |
||
46 |
|||
47 |
static void print_bvspace(struct html *, |
||
48 |
const struct roff_node *); |
||
49 |
static void print_man_head(MAN_ARGS); |
||
50 |
static void print_man_nodelist(MAN_ARGS); |
||
51 |
static void print_man_node(MAN_ARGS); |
||
52 |
static int fillmode(struct html *, int); |
||
53 |
static int a2width(const struct roff_node *, |
||
54 |
struct roffsu *); |
||
55 |
static int man_B_pre(MAN_ARGS); |
||
56 |
static int man_HP_pre(MAN_ARGS); |
||
57 |
static int man_IP_pre(MAN_ARGS); |
||
58 |
static int man_I_pre(MAN_ARGS); |
||
59 |
static int man_OP_pre(MAN_ARGS); |
||
60 |
static int man_PP_pre(MAN_ARGS); |
||
61 |
static int man_RS_pre(MAN_ARGS); |
||
62 |
static int man_SH_pre(MAN_ARGS); |
||
63 |
static int man_SM_pre(MAN_ARGS); |
||
64 |
static int man_SS_pre(MAN_ARGS); |
||
65 |
static int man_UR_pre(MAN_ARGS); |
||
66 |
static int man_alt_pre(MAN_ARGS); |
||
67 |
static int man_ign_pre(MAN_ARGS); |
||
68 |
static int man_in_pre(MAN_ARGS); |
||
69 |
static void man_root_post(MAN_ARGS); |
||
70 |
static void man_root_pre(MAN_ARGS); |
||
71 |
|||
72 |
static const struct htmlman __mans[MAN_MAX - MAN_TH] = { |
||
73 |
{ NULL, NULL }, /* TH */ |
||
74 |
{ man_SH_pre, NULL }, /* SH */ |
||
75 |
{ man_SS_pre, NULL }, /* SS */ |
||
76 |
{ man_IP_pre, NULL }, /* TP */ |
||
77 |
{ man_PP_pre, NULL }, /* LP */ |
||
78 |
{ man_PP_pre, NULL }, /* PP */ |
||
79 |
{ man_PP_pre, NULL }, /* P */ |
||
80 |
{ man_IP_pre, NULL }, /* IP */ |
||
81 |
{ man_HP_pre, NULL }, /* HP */ |
||
82 |
{ man_SM_pre, NULL }, /* SM */ |
||
83 |
{ man_SM_pre, NULL }, /* SB */ |
||
84 |
{ man_alt_pre, NULL }, /* BI */ |
||
85 |
{ man_alt_pre, NULL }, /* IB */ |
||
86 |
{ man_alt_pre, NULL }, /* BR */ |
||
87 |
{ man_alt_pre, NULL }, /* RB */ |
||
88 |
{ NULL, NULL }, /* R */ |
||
89 |
{ man_B_pre, NULL }, /* B */ |
||
90 |
{ man_I_pre, NULL }, /* I */ |
||
91 |
{ man_alt_pre, NULL }, /* IR */ |
||
92 |
{ man_alt_pre, NULL }, /* RI */ |
||
93 |
{ NULL, NULL }, /* nf */ |
||
94 |
{ NULL, NULL }, /* fi */ |
||
95 |
{ NULL, NULL }, /* RE */ |
||
96 |
{ man_RS_pre, NULL }, /* RS */ |
||
97 |
{ man_ign_pre, NULL }, /* DT */ |
||
98 |
{ man_ign_pre, NULL }, /* UC */ |
||
99 |
{ man_ign_pre, NULL }, /* PD */ |
||
100 |
{ man_ign_pre, NULL }, /* AT */ |
||
101 |
{ man_in_pre, NULL }, /* in */ |
||
102 |
{ man_OP_pre, NULL }, /* OP */ |
||
103 |
{ NULL, NULL }, /* EX */ |
||
104 |
{ NULL, NULL }, /* EE */ |
||
105 |
{ man_UR_pre, NULL }, /* UR */ |
||
106 |
{ NULL, NULL }, /* UE */ |
||
107 |
{ man_UR_pre, NULL }, /* MT */ |
||
108 |
{ NULL, NULL }, /* ME */ |
||
109 |
}; |
||
110 |
static const struct htmlman *const mans = __mans - MAN_TH; |
||
111 |
|||
112 |
|||
113 |
/* |
||
114 |
* Printing leading vertical space before a block. |
||
115 |
* This is used for the paragraph macros. |
||
116 |
* The rules are pretty simple, since there's very little nesting going |
||
117 |
* on here. Basically, if we're the first within another block (SS/SH), |
||
118 |
* then don't emit vertical space. If we are (RS), then do. If not the |
||
119 |
* first, print it. |
||
120 |
*/ |
||
121 |
static void |
||
122 |
print_bvspace(struct html *h, const struct roff_node *n) |
||
123 |
{ |
||
124 |
|||
125 |
if (n->body && n->body->child) |
||
126 |
if (n->body->child->type == ROFFT_TBL) |
||
127 |
return; |
||
128 |
|||
129 |
if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS) |
||
130 |
if (NULL == n->prev) |
||
131 |
return; |
||
132 |
|||
133 |
print_paragraph(h); |
||
134 |
} |
||
135 |
|||
136 |
void |
||
137 |
html_man(void *arg, const struct roff_man *man) |
||
138 |
{ |
||
139 |
struct html *h; |
||
140 |
struct tag *t; |
||
141 |
|||
142 |
126 |
h = (struct html *)arg; |
|
143 |
|||
144 |
✓✗ | 63 |
if ((h->oflags & HTML_FRAGMENT) == 0) { |
145 |
63 |
print_gen_decls(h); |
|
146 |
63 |
print_otag(h, TAG_HTML, ""); |
|
147 |
63 |
t = print_otag(h, TAG_HEAD, ""); |
|
148 |
63 |
print_man_head(&man->meta, man->first, h); |
|
149 |
63 |
print_tagq(h, t); |
|
150 |
63 |
print_otag(h, TAG_BODY, ""); |
|
151 |
63 |
} |
|
152 |
|||
153 |
63 |
man_root_pre(&man->meta, man->first, h); |
|
154 |
63 |
t = print_otag(h, TAG_DIV, "c", "manual-text"); |
|
155 |
63 |
print_man_nodelist(&man->meta, man->first->child, h); |
|
156 |
63 |
print_tagq(h, t); |
|
157 |
63 |
man_root_post(&man->meta, man->first, h); |
|
158 |
63 |
print_tagq(h, NULL); |
|
159 |
63 |
} |
|
160 |
|||
161 |
static void |
||
162 |
print_man_head(MAN_ARGS) |
||
163 |
{ |
||
164 |
126 |
char *cp; |
|
165 |
|||
166 |
63 |
print_gen_head(h); |
|
167 |
63 |
mandoc_asprintf(&cp, "%s(%s)", man->title, man->msec); |
|
168 |
63 |
print_otag(h, TAG_TITLE, ""); |
|
169 |
63 |
print_text(h, cp); |
|
170 |
63 |
free(cp); |
|
171 |
63 |
} |
|
172 |
|||
173 |
static void |
||
174 |
print_man_nodelist(MAN_ARGS) |
||
175 |
{ |
||
176 |
|||
177 |
✓✓ | 9189 |
while (n != NULL) { |
178 |
3933 |
print_man_node(man, n, h); |
|
179 |
3933 |
n = n->next; |
|
180 |
} |
||
181 |
441 |
} |
|
182 |
|||
183 |
static void |
||
184 |
print_man_node(MAN_ARGS) |
||
185 |
{ |
||
186 |
static int want_fillmode = MAN_fi; |
||
187 |
static int save_fillmode; |
||
188 |
|||
189 |
struct tag *t; |
||
190 |
int child; |
||
191 |
|||
192 |
/* |
||
193 |
* Handle fill mode switch requests up front, |
||
194 |
* they would just cause trouble in the subsequent code. |
||
195 |
*/ |
||
196 |
|||
197 |
✗✓✗✓ ✓ |
7866 |
switch (n->tok) { |
198 |
case MAN_nf: |
||
199 |
case MAN_EX: |
||
200 |
63 |
want_fillmode = MAN_nf; |
|
201 |
63 |
return; |
|
202 |
case MAN_fi: |
||
203 |
case MAN_EE: |
||
204 |
63 |
want_fillmode = MAN_fi; |
|
205 |
✗✓ | 63 |
if (fillmode(h, 0) == MAN_fi) |
206 |
print_otag(h, TAG_BR, ""); |
||
207 |
63 |
return; |
|
208 |
default: |
||
209 |
break; |
||
210 |
} |
||
211 |
|||
212 |
/* Set up fill mode for the upcoming node. */ |
||
213 |
|||
214 |
✓✗✗✓ ✓ |
7236 |
switch (n->type) { |
215 |
case ROFFT_BLOCK: |
||
216 |
378 |
save_fillmode = 0; |
|
217 |
/* Some block macros suspend or cancel .nf. */ |
||
218 |
✗✗✗✗ ✓✗✗✗ ✗✗✓✓ |
378 |
switch (n->tok) { |
219 |
case MAN_TP: /* Tagged paragraphs */ |
||
220 |
case MAN_IP: /* temporarily disable .nf */ |
||
221 |
case MAN_HP: /* for the head. */ |
||
222 |
save_fillmode = want_fillmode; |
||
223 |
/* FALLTHROUGH */ |
||
224 |
case MAN_SH: /* Section headers */ |
||
225 |
case MAN_SS: /* permanently cancel .nf. */ |
||
226 |
126 |
want_fillmode = MAN_fi; |
|
227 |
/* FALLTHROUGH */ |
||
228 |
case MAN_PP: /* These have no head. */ |
||
229 |
case MAN_LP: /* They will simply */ |
||
230 |
case MAN_P: /* reopen .nf in the body. */ |
||
231 |
case MAN_RS: |
||
232 |
case MAN_UR: |
||
233 |
case MAN_MT: |
||
234 |
126 |
fillmode(h, MAN_fi); |
|
235 |
126 |
break; |
|
236 |
default: |
||
237 |
break; |
||
238 |
} |
||
239 |
break; |
||
240 |
case ROFFT_TBL: |
||
241 |
fillmode(h, MAN_fi); |
||
242 |
break; |
||
243 |
case ROFFT_ELEM: |
||
244 |
/* |
||
245 |
* Some in-line macros produce tags and/or text |
||
246 |
* in the handler, so they require fill mode to be |
||
247 |
* configured up front just like for text nodes. |
||
248 |
* For the others, keep the traditional approach |
||
249 |
* of doing the same, for now. |
||
250 |
*/ |
||
251 |
fillmode(h, want_fillmode); |
||
252 |
break; |
||
253 |
case ROFFT_TEXT: |
||
254 |
✓✓✗✗ |
6858 |
if (fillmode(h, want_fillmode) == MAN_fi && |
255 |
3429 |
want_fillmode == MAN_fi && |
|
256 |
✓✓✗✓ |
252 |
n->flags & NODE_LINE && *n->string == ' ' && |
257 |
(h->flags & HTML_NONEWLINE) == 0) |
||
258 |
print_otag(h, TAG_BR, ""); |
||
259 |
✗✓ | 3429 |
if (*n->string != '\0') |
260 |
break; |
||
261 |
print_paragraph(h); |
||
262 |
return; |
||
263 |
default: |
||
264 |
break; |
||
265 |
} |
||
266 |
|||
267 |
/* Produce output for this node. */ |
||
268 |
|||
269 |
child = 1; |
||
270 |
✓✗✗✓ |
3807 |
switch (n->type) { |
271 |
case ROFFT_TEXT: |
||
272 |
3429 |
t = h->tag; |
|
273 |
3429 |
print_text(h, n->string); |
|
274 |
3429 |
break; |
|
275 |
case ROFFT_EQN: |
||
276 |
t = h->tag; |
||
277 |
print_eqn(h, n->eqn); |
||
278 |
break; |
||
279 |
case ROFFT_TBL: |
||
280 |
/* |
||
281 |
* This will take care of initialising all of the table |
||
282 |
* state data for the first table, then tearing it down |
||
283 |
* for the last one. |
||
284 |
*/ |
||
285 |
print_tbl(h, n->span); |
||
286 |
return; |
||
287 |
default: |
||
288 |
/* |
||
289 |
* Close out scope of font prior to opening a macro |
||
290 |
* scope. |
||
291 |
*/ |
||
292 |
✗✓ | 378 |
if (HTMLFONT_NONE != h->metac) { |
293 |
h->metal = h->metac; |
||
294 |
h->metac = HTMLFONT_NONE; |
||
295 |
} |
||
296 |
|||
297 |
/* |
||
298 |
* Close out the current table, if it's open, and unset |
||
299 |
* the "meta" table state. This will be reopened on the |
||
300 |
* next table element. |
||
301 |
*/ |
||
302 |
✗✓ | 378 |
if (h->tblt) |
303 |
print_tblclose(h); |
||
304 |
|||
305 |
378 |
t = h->tag; |
|
306 |
✗✓ | 378 |
if (n->tok < ROFF_MAX) { |
307 |
roff_html_pre(h, n); |
||
308 |
child = 0; |
||
309 |
break; |
||
310 |
} |
||
311 |
|||
312 |
✓✗✗✓ |
756 |
assert(n->tok >= MAN_TH && n->tok < MAN_MAX); |
313 |
✓✗ | 378 |
if (mans[n->tok].pre) |
314 |
378 |
child = (*mans[n->tok].pre)(man, n, h); |
|
315 |
|||
316 |
/* Some block macros resume .nf in the body. */ |
||
317 |
✗✓✗✗ |
378 |
if (save_fillmode && n->type == ROFFT_BODY) |
318 |
want_fillmode = save_fillmode; |
||
319 |
|||
320 |
break; |
||
321 |
} |
||
322 |
|||
323 |
✓✗✓✓ |
7614 |
if (child && n->child) |
324 |
378 |
print_man_nodelist(man, n->child, h); |
|
325 |
|||
326 |
/* This will automatically close out any font scope. */ |
||
327 |
3807 |
print_stagq(h, t); |
|
328 |
|||
329 |
✓✓✓✗ |
7047 |
if (fillmode(h, 0) == MAN_nf && |
330 |
✓✗ | 6480 |
n->next != NULL && n->next->flags & NODE_LINE) |
331 |
3240 |
print_endline(h); |
|
332 |
7740 |
} |
|
333 |
|||
334 |
/* |
||
335 |
* MAN_nf switches to no-fill mode, MAN_fi to fill mode. |
||
336 |
* Other arguments do not switch. |
||
337 |
* The old mode is returned. |
||
338 |
*/ |
||
339 |
static int |
||
340 |
fillmode(struct html *h, int want) |
||
341 |
{ |
||
342 |
struct tag *pre; |
||
343 |
int had; |
||
344 |
|||
345 |
✓✓ | 28953 |
for (pre = h->tag; pre != NULL; pre = pre->next) |
346 |
✓✓ | 9819 |
if (pre->tag == TAG_PRE) |
347 |
break; |
||
348 |
|||
349 |
7425 |
had = pre == NULL ? MAN_fi : MAN_nf; |
|
350 |
|||
351 |
✓✓✓✓ |
10980 |
if (want && want != had) { |
352 |
✓✗ | 63 |
if (want == MAN_nf) |
353 |
63 |
print_otag(h, TAG_PRE, ""); |
|
354 |
else |
||
355 |
print_tagq(h, pre); |
||
356 |
} |
||
357 |
7425 |
return had; |
|
358 |
} |
||
359 |
|||
360 |
static int |
||
361 |
a2width(const struct roff_node *n, struct roffsu *su) |
||
362 |
{ |
||
363 |
if (n->type != ROFFT_TEXT) |
||
364 |
return 0; |
||
365 |
return a2roffsu(n->string, su, SCALE_EN) != NULL; |
||
366 |
} |
||
367 |
|||
368 |
static void |
||
369 |
man_root_pre(MAN_ARGS) |
||
370 |
{ |
||
371 |
struct tag *t, *tt; |
||
372 |
126 |
char *title; |
|
373 |
|||
374 |
✗✓ | 63 |
assert(man->title); |
375 |
✗✓ | 63 |
assert(man->msec); |
376 |
63 |
mandoc_asprintf(&title, "%s(%s)", man->title, man->msec); |
|
377 |
|||
378 |
63 |
t = print_otag(h, TAG_TABLE, "c", "head"); |
|
379 |
63 |
tt = print_otag(h, TAG_TR, ""); |
|
380 |
|||
381 |
63 |
print_otag(h, TAG_TD, "c", "head-ltitle"); |
|
382 |
63 |
print_text(h, title); |
|
383 |
63 |
print_stagq(h, tt); |
|
384 |
|||
385 |
63 |
print_otag(h, TAG_TD, "c", "head-vol"); |
|
386 |
✓✗ | 63 |
if (NULL != man->vol) |
387 |
63 |
print_text(h, man->vol); |
|
388 |
63 |
print_stagq(h, tt); |
|
389 |
|||
390 |
63 |
print_otag(h, TAG_TD, "c", "head-rtitle"); |
|
391 |
63 |
print_text(h, title); |
|
392 |
63 |
print_tagq(h, t); |
|
393 |
63 |
free(title); |
|
394 |
63 |
} |
|
395 |
|||
396 |
static void |
||
397 |
man_root_post(MAN_ARGS) |
||
398 |
{ |
||
399 |
struct tag *t, *tt; |
||
400 |
|||
401 |
126 |
t = print_otag(h, TAG_TABLE, "c", "foot"); |
|
402 |
63 |
tt = print_otag(h, TAG_TR, ""); |
|
403 |
|||
404 |
63 |
print_otag(h, TAG_TD, "c", "foot-date"); |
|
405 |
63 |
print_text(h, man->date); |
|
406 |
63 |
print_stagq(h, tt); |
|
407 |
|||
408 |
63 |
print_otag(h, TAG_TD, "c", "foot-os"); |
|
409 |
✗✓ | 63 |
if (man->os) |
410 |
print_text(h, man->os); |
||
411 |
63 |
print_tagq(h, t); |
|
412 |
63 |
} |
|
413 |
|||
414 |
static int |
||
415 |
man_SH_pre(MAN_ARGS) |
||
416 |
{ |
||
417 |
char *id; |
||
418 |
|||
419 |
✓✓ | 756 |
if (n->type == ROFFT_HEAD) { |
420 |
126 |
id = html_make_id(n); |
|
421 |
126 |
print_otag(h, TAG_H1, "cTi", "Sh", id); |
|
422 |
✓✗ | 126 |
if (id != NULL) |
423 |
126 |
print_otag(h, TAG_A, "chR", "selflink", id); |
|
424 |
126 |
free(id); |
|
425 |
126 |
} |
|
426 |
378 |
return 1; |
|
427 |
} |
||
428 |
|||
429 |
static int |
||
430 |
man_alt_pre(MAN_ARGS) |
||
431 |
{ |
||
432 |
const struct roff_node *nn; |
||
433 |
int i; |
||
434 |
enum htmltag fp; |
||
435 |
struct tag *t; |
||
436 |
|||
437 |
for (i = 0, nn = n->child; nn; nn = nn->next, i++) { |
||
438 |
switch (n->tok) { |
||
439 |
case MAN_BI: |
||
440 |
fp = i % 2 ? TAG_I : TAG_B; |
||
441 |
break; |
||
442 |
case MAN_IB: |
||
443 |
fp = i % 2 ? TAG_B : TAG_I; |
||
444 |
break; |
||
445 |
case MAN_RI: |
||
446 |
fp = i % 2 ? TAG_I : TAG_MAX; |
||
447 |
break; |
||
448 |
case MAN_IR: |
||
449 |
fp = i % 2 ? TAG_MAX : TAG_I; |
||
450 |
break; |
||
451 |
case MAN_BR: |
||
452 |
fp = i % 2 ? TAG_MAX : TAG_B; |
||
453 |
break; |
||
454 |
case MAN_RB: |
||
455 |
fp = i % 2 ? TAG_B : TAG_MAX; |
||
456 |
break; |
||
457 |
default: |
||
458 |
abort(); |
||
459 |
} |
||
460 |
|||
461 |
if (i) |
||
462 |
h->flags |= HTML_NOSPACE; |
||
463 |
|||
464 |
if (fp != TAG_MAX) |
||
465 |
t = print_otag(h, fp, ""); |
||
466 |
|||
467 |
print_text(h, nn->string); |
||
468 |
|||
469 |
if (fp != TAG_MAX) |
||
470 |
print_tagq(h, t); |
||
471 |
} |
||
472 |
return 0; |
||
473 |
} |
||
474 |
|||
475 |
static int |
||
476 |
man_SM_pre(MAN_ARGS) |
||
477 |
{ |
||
478 |
print_otag(h, TAG_SMALL, ""); |
||
479 |
if (MAN_SB == n->tok) |
||
480 |
print_otag(h, TAG_B, ""); |
||
481 |
return 1; |
||
482 |
} |
||
483 |
|||
484 |
static int |
||
485 |
man_SS_pre(MAN_ARGS) |
||
486 |
{ |
||
487 |
char *id; |
||
488 |
|||
489 |
if (n->type == ROFFT_HEAD) { |
||
490 |
id = html_make_id(n); |
||
491 |
print_otag(h, TAG_H2, "cTi", "Ss", id); |
||
492 |
if (id != NULL) |
||
493 |
print_otag(h, TAG_A, "chR", "selflink", id); |
||
494 |
free(id); |
||
495 |
} |
||
496 |
return 1; |
||
497 |
} |
||
498 |
|||
499 |
static int |
||
500 |
man_PP_pre(MAN_ARGS) |
||
501 |
{ |
||
502 |
|||
503 |
if (n->type == ROFFT_HEAD) |
||
504 |
return 0; |
||
505 |
else if (n->type == ROFFT_BLOCK) |
||
506 |
print_bvspace(h, n); |
||
507 |
|||
508 |
return 1; |
||
509 |
} |
||
510 |
|||
511 |
static int |
||
512 |
man_IP_pre(MAN_ARGS) |
||
513 |
{ |
||
514 |
const struct roff_node *nn; |
||
515 |
|||
516 |
if (n->type == ROFFT_BODY) { |
||
517 |
print_otag(h, TAG_DD, "c", "It-tag"); |
||
518 |
return 1; |
||
519 |
} else if (n->type != ROFFT_HEAD) { |
||
520 |
print_otag(h, TAG_DL, "c", "Bl-tag"); |
||
521 |
return 1; |
||
522 |
} |
||
523 |
|||
524 |
/* FIXME: width specification. */ |
||
525 |
|||
526 |
print_otag(h, TAG_DT, "c", "It-tag"); |
||
527 |
|||
528 |
/* For IP, only print the first header element. */ |
||
529 |
|||
530 |
if (MAN_IP == n->tok && n->child) |
||
531 |
print_man_node(man, n->child, h); |
||
532 |
|||
533 |
/* For TP, only print next-line header elements. */ |
||
534 |
|||
535 |
if (MAN_TP == n->tok) { |
||
536 |
nn = n->child; |
||
537 |
while (NULL != nn && 0 == (NODE_LINE & nn->flags)) |
||
538 |
nn = nn->next; |
||
539 |
while (NULL != nn) { |
||
540 |
print_man_node(man, nn, h); |
||
541 |
nn = nn->next; |
||
542 |
} |
||
543 |
} |
||
544 |
|||
545 |
return 0; |
||
546 |
} |
||
547 |
|||
548 |
static int |
||
549 |
man_HP_pre(MAN_ARGS) |
||
550 |
{ |
||
551 |
struct roffsu sum, sui; |
||
552 |
const struct roff_node *np; |
||
553 |
|||
554 |
if (n->type == ROFFT_HEAD) |
||
555 |
return 0; |
||
556 |
else if (n->type != ROFFT_BLOCK) |
||
557 |
return 1; |
||
558 |
|||
559 |
np = n->head->child; |
||
560 |
|||
561 |
if (np == NULL || !a2width(np, &sum)) |
||
562 |
SCALE_HS_INIT(&sum, INDENT); |
||
563 |
|||
564 |
sui.unit = sum.unit; |
||
565 |
sui.scale = -sum.scale; |
||
566 |
|||
567 |
print_bvspace(h, n); |
||
568 |
print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui); |
||
569 |
return 1; |
||
570 |
} |
||
571 |
|||
572 |
static int |
||
573 |
man_OP_pre(MAN_ARGS) |
||
574 |
{ |
||
575 |
struct tag *tt; |
||
576 |
|||
577 |
print_text(h, "["); |
||
578 |
h->flags |= HTML_NOSPACE; |
||
579 |
tt = print_otag(h, TAG_SPAN, "c", "Op"); |
||
580 |
|||
581 |
if (NULL != (n = n->child)) { |
||
582 |
print_otag(h, TAG_B, ""); |
||
583 |
print_text(h, n->string); |
||
584 |
} |
||
585 |
|||
586 |
print_stagq(h, tt); |
||
587 |
|||
588 |
if (NULL != n && NULL != n->next) { |
||
589 |
print_otag(h, TAG_I, ""); |
||
590 |
print_text(h, n->next->string); |
||
591 |
} |
||
592 |
|||
593 |
print_stagq(h, tt); |
||
594 |
h->flags |= HTML_NOSPACE; |
||
595 |
print_text(h, "]"); |
||
596 |
return 0; |
||
597 |
} |
||
598 |
|||
599 |
static int |
||
600 |
man_B_pre(MAN_ARGS) |
||
601 |
{ |
||
602 |
print_otag(h, TAG_B, ""); |
||
603 |
return 1; |
||
604 |
} |
||
605 |
|||
606 |
static int |
||
607 |
man_I_pre(MAN_ARGS) |
||
608 |
{ |
||
609 |
print_otag(h, TAG_I, ""); |
||
610 |
return 1; |
||
611 |
} |
||
612 |
|||
613 |
static int |
||
614 |
man_in_pre(MAN_ARGS) |
||
615 |
{ |
||
616 |
print_otag(h, TAG_BR, ""); |
||
617 |
return 0; |
||
618 |
} |
||
619 |
|||
620 |
static int |
||
621 |
man_ign_pre(MAN_ARGS) |
||
622 |
{ |
||
623 |
|||
624 |
return 0; |
||
625 |
} |
||
626 |
|||
627 |
static int |
||
628 |
man_RS_pre(MAN_ARGS) |
||
629 |
{ |
||
630 |
struct roffsu su; |
||
631 |
|||
632 |
if (n->type == ROFFT_HEAD) |
||
633 |
return 0; |
||
634 |
else if (n->type == ROFFT_BODY) |
||
635 |
return 1; |
||
636 |
|||
637 |
SCALE_HS_INIT(&su, INDENT); |
||
638 |
if (n->head->child) |
||
639 |
a2width(n->head->child, &su); |
||
640 |
|||
641 |
print_otag(h, TAG_DIV, "sul", &su); |
||
642 |
return 1; |
||
643 |
} |
||
644 |
|||
645 |
static int |
||
646 |
man_UR_pre(MAN_ARGS) |
||
647 |
{ |
||
648 |
char *cp; |
||
649 |
n = n->child; |
||
650 |
assert(n->type == ROFFT_HEAD); |
||
651 |
if (n->child != NULL) { |
||
652 |
assert(n->child->type == ROFFT_TEXT); |
||
653 |
if (n->tok == MAN_MT) { |
||
654 |
mandoc_asprintf(&cp, "mailto:%s", n->child->string); |
||
655 |
print_otag(h, TAG_A, "cTh", "Mt", cp); |
||
656 |
free(cp); |
||
657 |
} else |
||
658 |
print_otag(h, TAG_A, "cTh", "Lk", n->child->string); |
||
659 |
} |
||
660 |
|||
661 |
assert(n->next->type == ROFFT_BODY); |
||
662 |
if (n->next->child != NULL) |
||
663 |
n = n->next; |
||
664 |
|||
665 |
print_man_nodelist(man, n->child, h); |
||
666 |
|||
667 |
return 0; |
||
668 |
} |
Generated by: GCOVR (Version 3.3) |