1 |
|
|
/* $OpenBSD: mdoc_html.c,v 1.169 2017/07/15 17:57:46 schwarze Exp $ */ |
2 |
|
|
/* |
3 |
|
|
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
4 |
|
|
* Copyright (c) 2014, 2015, 2016, 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 |
|
|
#include <unistd.h> |
26 |
|
|
|
27 |
|
|
#include "mandoc_aux.h" |
28 |
|
|
#include "mandoc.h" |
29 |
|
|
#include "roff.h" |
30 |
|
|
#include "mdoc.h" |
31 |
|
|
#include "out.h" |
32 |
|
|
#include "html.h" |
33 |
|
|
#include "main.h" |
34 |
|
|
|
35 |
|
|
#define INDENT 5 |
36 |
|
|
|
37 |
|
|
#define MDOC_ARGS const struct roff_meta *meta, \ |
38 |
|
|
struct roff_node *n, \ |
39 |
|
|
struct html *h |
40 |
|
|
|
41 |
|
|
#ifndef MIN |
42 |
|
|
#define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b)) |
43 |
|
|
#endif |
44 |
|
|
|
45 |
|
|
struct htmlmdoc { |
46 |
|
|
int (*pre)(MDOC_ARGS); |
47 |
|
|
void (*post)(MDOC_ARGS); |
48 |
|
|
}; |
49 |
|
|
|
50 |
|
|
static char *cond_id(const struct roff_node *); |
51 |
|
|
static void print_mdoc_head(MDOC_ARGS); |
52 |
|
|
static void print_mdoc_node(MDOC_ARGS); |
53 |
|
|
static void print_mdoc_nodelist(MDOC_ARGS); |
54 |
|
|
static void synopsis_pre(struct html *, |
55 |
|
|
const struct roff_node *); |
56 |
|
|
|
57 |
|
|
static void mdoc_root_post(MDOC_ARGS); |
58 |
|
|
static int mdoc_root_pre(MDOC_ARGS); |
59 |
|
|
|
60 |
|
|
static void mdoc__x_post(MDOC_ARGS); |
61 |
|
|
static int mdoc__x_pre(MDOC_ARGS); |
62 |
|
|
static int mdoc_ad_pre(MDOC_ARGS); |
63 |
|
|
static int mdoc_an_pre(MDOC_ARGS); |
64 |
|
|
static int mdoc_ap_pre(MDOC_ARGS); |
65 |
|
|
static int mdoc_ar_pre(MDOC_ARGS); |
66 |
|
|
static int mdoc_bd_pre(MDOC_ARGS); |
67 |
|
|
static int mdoc_bf_pre(MDOC_ARGS); |
68 |
|
|
static void mdoc_bk_post(MDOC_ARGS); |
69 |
|
|
static int mdoc_bk_pre(MDOC_ARGS); |
70 |
|
|
static int mdoc_bl_pre(MDOC_ARGS); |
71 |
|
|
static int mdoc_cd_pre(MDOC_ARGS); |
72 |
|
|
static int mdoc_cm_pre(MDOC_ARGS); |
73 |
|
|
static int mdoc_d1_pre(MDOC_ARGS); |
74 |
|
|
static int mdoc_dv_pre(MDOC_ARGS); |
75 |
|
|
static int mdoc_fa_pre(MDOC_ARGS); |
76 |
|
|
static int mdoc_fd_pre(MDOC_ARGS); |
77 |
|
|
static int mdoc_fl_pre(MDOC_ARGS); |
78 |
|
|
static int mdoc_fn_pre(MDOC_ARGS); |
79 |
|
|
static int mdoc_ft_pre(MDOC_ARGS); |
80 |
|
|
static int mdoc_em_pre(MDOC_ARGS); |
81 |
|
|
static void mdoc_eo_post(MDOC_ARGS); |
82 |
|
|
static int mdoc_eo_pre(MDOC_ARGS); |
83 |
|
|
static int mdoc_er_pre(MDOC_ARGS); |
84 |
|
|
static int mdoc_ev_pre(MDOC_ARGS); |
85 |
|
|
static int mdoc_ex_pre(MDOC_ARGS); |
86 |
|
|
static void mdoc_fo_post(MDOC_ARGS); |
87 |
|
|
static int mdoc_fo_pre(MDOC_ARGS); |
88 |
|
|
static int mdoc_ic_pre(MDOC_ARGS); |
89 |
|
|
static int mdoc_igndelim_pre(MDOC_ARGS); |
90 |
|
|
static int mdoc_in_pre(MDOC_ARGS); |
91 |
|
|
static int mdoc_it_pre(MDOC_ARGS); |
92 |
|
|
static int mdoc_lb_pre(MDOC_ARGS); |
93 |
|
|
static int mdoc_li_pre(MDOC_ARGS); |
94 |
|
|
static int mdoc_lk_pre(MDOC_ARGS); |
95 |
|
|
static int mdoc_mt_pre(MDOC_ARGS); |
96 |
|
|
static int mdoc_ms_pre(MDOC_ARGS); |
97 |
|
|
static int mdoc_nd_pre(MDOC_ARGS); |
98 |
|
|
static int mdoc_nm_pre(MDOC_ARGS); |
99 |
|
|
static int mdoc_no_pre(MDOC_ARGS); |
100 |
|
|
static int mdoc_ns_pre(MDOC_ARGS); |
101 |
|
|
static int mdoc_pa_pre(MDOC_ARGS); |
102 |
|
|
static void mdoc_pf_post(MDOC_ARGS); |
103 |
|
|
static int mdoc_pp_pre(MDOC_ARGS); |
104 |
|
|
static void mdoc_quote_post(MDOC_ARGS); |
105 |
|
|
static int mdoc_quote_pre(MDOC_ARGS); |
106 |
|
|
static int mdoc_rs_pre(MDOC_ARGS); |
107 |
|
|
static int mdoc_sh_pre(MDOC_ARGS); |
108 |
|
|
static int mdoc_skip_pre(MDOC_ARGS); |
109 |
|
|
static int mdoc_sm_pre(MDOC_ARGS); |
110 |
|
|
static int mdoc_ss_pre(MDOC_ARGS); |
111 |
|
|
static int mdoc_st_pre(MDOC_ARGS); |
112 |
|
|
static int mdoc_sx_pre(MDOC_ARGS); |
113 |
|
|
static int mdoc_sy_pre(MDOC_ARGS); |
114 |
|
|
static int mdoc_va_pre(MDOC_ARGS); |
115 |
|
|
static int mdoc_vt_pre(MDOC_ARGS); |
116 |
|
|
static int mdoc_xr_pre(MDOC_ARGS); |
117 |
|
|
static int mdoc_xx_pre(MDOC_ARGS); |
118 |
|
|
|
119 |
|
|
static const struct htmlmdoc __mdocs[MDOC_MAX - MDOC_Dd] = { |
120 |
|
|
{NULL, NULL}, /* Dd */ |
121 |
|
|
{NULL, NULL}, /* Dt */ |
122 |
|
|
{NULL, NULL}, /* Os */ |
123 |
|
|
{mdoc_sh_pre, NULL }, /* Sh */ |
124 |
|
|
{mdoc_ss_pre, NULL }, /* Ss */ |
125 |
|
|
{mdoc_pp_pre, NULL}, /* Pp */ |
126 |
|
|
{mdoc_d1_pre, NULL}, /* D1 */ |
127 |
|
|
{mdoc_d1_pre, NULL}, /* Dl */ |
128 |
|
|
{mdoc_bd_pre, NULL}, /* Bd */ |
129 |
|
|
{NULL, NULL}, /* Ed */ |
130 |
|
|
{mdoc_bl_pre, NULL}, /* Bl */ |
131 |
|
|
{NULL, NULL}, /* El */ |
132 |
|
|
{mdoc_it_pre, NULL}, /* It */ |
133 |
|
|
{mdoc_ad_pre, NULL}, /* Ad */ |
134 |
|
|
{mdoc_an_pre, NULL}, /* An */ |
135 |
|
|
{mdoc_ap_pre, NULL}, /* Ap */ |
136 |
|
|
{mdoc_ar_pre, NULL}, /* Ar */ |
137 |
|
|
{mdoc_cd_pre, NULL}, /* Cd */ |
138 |
|
|
{mdoc_cm_pre, NULL}, /* Cm */ |
139 |
|
|
{mdoc_dv_pre, NULL}, /* Dv */ |
140 |
|
|
{mdoc_er_pre, NULL}, /* Er */ |
141 |
|
|
{mdoc_ev_pre, NULL}, /* Ev */ |
142 |
|
|
{mdoc_ex_pre, NULL}, /* Ex */ |
143 |
|
|
{mdoc_fa_pre, NULL}, /* Fa */ |
144 |
|
|
{mdoc_fd_pre, NULL}, /* Fd */ |
145 |
|
|
{mdoc_fl_pre, NULL}, /* Fl */ |
146 |
|
|
{mdoc_fn_pre, NULL}, /* Fn */ |
147 |
|
|
{mdoc_ft_pre, NULL}, /* Ft */ |
148 |
|
|
{mdoc_ic_pre, NULL}, /* Ic */ |
149 |
|
|
{mdoc_in_pre, NULL}, /* In */ |
150 |
|
|
{mdoc_li_pre, NULL}, /* Li */ |
151 |
|
|
{mdoc_nd_pre, NULL}, /* Nd */ |
152 |
|
|
{mdoc_nm_pre, NULL}, /* Nm */ |
153 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Op */ |
154 |
|
|
{mdoc_ft_pre, NULL}, /* Ot */ |
155 |
|
|
{mdoc_pa_pre, NULL}, /* Pa */ |
156 |
|
|
{mdoc_ex_pre, NULL}, /* Rv */ |
157 |
|
|
{mdoc_st_pre, NULL}, /* St */ |
158 |
|
|
{mdoc_va_pre, NULL}, /* Va */ |
159 |
|
|
{mdoc_vt_pre, NULL}, /* Vt */ |
160 |
|
|
{mdoc_xr_pre, NULL}, /* Xr */ |
161 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %A */ |
162 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %B */ |
163 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %D */ |
164 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %I */ |
165 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %J */ |
166 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %N */ |
167 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %O */ |
168 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %P */ |
169 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %R */ |
170 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %T */ |
171 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %V */ |
172 |
|
|
{NULL, NULL}, /* Ac */ |
173 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Ao */ |
174 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Aq */ |
175 |
|
|
{mdoc_xx_pre, NULL}, /* At */ |
176 |
|
|
{NULL, NULL}, /* Bc */ |
177 |
|
|
{mdoc_bf_pre, NULL}, /* Bf */ |
178 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Bo */ |
179 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Bq */ |
180 |
|
|
{mdoc_xx_pre, NULL}, /* Bsx */ |
181 |
|
|
{mdoc_xx_pre, NULL}, /* Bx */ |
182 |
|
|
{mdoc_skip_pre, NULL}, /* Db */ |
183 |
|
|
{NULL, NULL}, /* Dc */ |
184 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Do */ |
185 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Dq */ |
186 |
|
|
{NULL, NULL}, /* Ec */ /* FIXME: no space */ |
187 |
|
|
{NULL, NULL}, /* Ef */ |
188 |
|
|
{mdoc_em_pre, NULL}, /* Em */ |
189 |
|
|
{mdoc_eo_pre, mdoc_eo_post}, /* Eo */ |
190 |
|
|
{mdoc_xx_pre, NULL}, /* Fx */ |
191 |
|
|
{mdoc_ms_pre, NULL}, /* Ms */ |
192 |
|
|
{mdoc_no_pre, NULL}, /* No */ |
193 |
|
|
{mdoc_ns_pre, NULL}, /* Ns */ |
194 |
|
|
{mdoc_xx_pre, NULL}, /* Nx */ |
195 |
|
|
{mdoc_xx_pre, NULL}, /* Ox */ |
196 |
|
|
{NULL, NULL}, /* Pc */ |
197 |
|
|
{mdoc_igndelim_pre, mdoc_pf_post}, /* Pf */ |
198 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Po */ |
199 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Pq */ |
200 |
|
|
{NULL, NULL}, /* Qc */ |
201 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Ql */ |
202 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Qo */ |
203 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Qq */ |
204 |
|
|
{NULL, NULL}, /* Re */ |
205 |
|
|
{mdoc_rs_pre, NULL}, /* Rs */ |
206 |
|
|
{NULL, NULL}, /* Sc */ |
207 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* So */ |
208 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Sq */ |
209 |
|
|
{mdoc_sm_pre, NULL}, /* Sm */ |
210 |
|
|
{mdoc_sx_pre, NULL}, /* Sx */ |
211 |
|
|
{mdoc_sy_pre, NULL}, /* Sy */ |
212 |
|
|
{NULL, NULL}, /* Tn */ |
213 |
|
|
{mdoc_xx_pre, NULL}, /* Ux */ |
214 |
|
|
{NULL, NULL}, /* Xc */ |
215 |
|
|
{NULL, NULL}, /* Xo */ |
216 |
|
|
{mdoc_fo_pre, mdoc_fo_post}, /* Fo */ |
217 |
|
|
{NULL, NULL}, /* Fc */ |
218 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Oo */ |
219 |
|
|
{NULL, NULL}, /* Oc */ |
220 |
|
|
{mdoc_bk_pre, mdoc_bk_post}, /* Bk */ |
221 |
|
|
{NULL, NULL}, /* Ek */ |
222 |
|
|
{NULL, NULL}, /* Bt */ |
223 |
|
|
{NULL, NULL}, /* Hf */ |
224 |
|
|
{mdoc_em_pre, NULL}, /* Fr */ |
225 |
|
|
{NULL, NULL}, /* Ud */ |
226 |
|
|
{mdoc_lb_pre, NULL}, /* Lb */ |
227 |
|
|
{mdoc_pp_pre, NULL}, /* Lp */ |
228 |
|
|
{mdoc_lk_pre, NULL}, /* Lk */ |
229 |
|
|
{mdoc_mt_pre, NULL}, /* Mt */ |
230 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Brq */ |
231 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* Bro */ |
232 |
|
|
{NULL, NULL}, /* Brc */ |
233 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %C */ |
234 |
|
|
{mdoc_skip_pre, NULL}, /* Es */ |
235 |
|
|
{mdoc_quote_pre, mdoc_quote_post}, /* En */ |
236 |
|
|
{mdoc_xx_pre, NULL}, /* Dx */ |
237 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %Q */ |
238 |
|
|
{mdoc__x_pre, mdoc__x_post}, /* %U */ |
239 |
|
|
{NULL, NULL}, /* Ta */ |
240 |
|
|
}; |
241 |
|
|
static const struct htmlmdoc *const mdocs = __mdocs - MDOC_Dd; |
242 |
|
|
|
243 |
|
|
|
244 |
|
|
/* |
245 |
|
|
* See the same function in mdoc_term.c for documentation. |
246 |
|
|
*/ |
247 |
|
|
static void |
248 |
|
|
synopsis_pre(struct html *h, const struct roff_node *n) |
249 |
|
|
{ |
250 |
|
|
|
251 |
|
|
if (NULL == n->prev || ! (NODE_SYNPRETTY & n->flags)) |
252 |
|
|
return; |
253 |
|
|
|
254 |
|
|
if (n->prev->tok == n->tok && |
255 |
|
|
MDOC_Fo != n->tok && |
256 |
|
|
MDOC_Ft != n->tok && |
257 |
|
|
MDOC_Fn != n->tok) { |
258 |
|
|
print_otag(h, TAG_BR, ""); |
259 |
|
|
return; |
260 |
|
|
} |
261 |
|
|
|
262 |
|
|
switch (n->prev->tok) { |
263 |
|
|
case MDOC_Fd: |
264 |
|
|
case MDOC_Fn: |
265 |
|
|
case MDOC_Fo: |
266 |
|
|
case MDOC_In: |
267 |
|
|
case MDOC_Vt: |
268 |
|
|
print_paragraph(h); |
269 |
|
|
break; |
270 |
|
|
case MDOC_Ft: |
271 |
|
|
if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) { |
272 |
|
|
print_paragraph(h); |
273 |
|
|
break; |
274 |
|
|
} |
275 |
|
|
/* FALLTHROUGH */ |
276 |
|
|
default: |
277 |
|
|
print_otag(h, TAG_BR, ""); |
278 |
|
|
break; |
279 |
|
|
} |
280 |
|
|
} |
281 |
|
|
|
282 |
|
|
void |
283 |
|
|
html_mdoc(void *arg, const struct roff_man *mdoc) |
284 |
|
|
{ |
285 |
|
|
struct html *h; |
286 |
|
|
struct tag *t; |
287 |
|
|
|
288 |
|
306 |
h = (struct html *)arg; |
289 |
|
|
|
290 |
✓✗ |
153 |
if ((h->oflags & HTML_FRAGMENT) == 0) { |
291 |
|
153 |
print_gen_decls(h); |
292 |
|
153 |
print_otag(h, TAG_HTML, ""); |
293 |
|
153 |
t = print_otag(h, TAG_HEAD, ""); |
294 |
|
153 |
print_mdoc_head(&mdoc->meta, mdoc->first->child, h); |
295 |
|
153 |
print_tagq(h, t); |
296 |
|
153 |
print_otag(h, TAG_BODY, ""); |
297 |
|
153 |
} |
298 |
|
|
|
299 |
|
153 |
mdoc_root_pre(&mdoc->meta, mdoc->first->child, h); |
300 |
|
153 |
t = print_otag(h, TAG_DIV, "c", "manual-text"); |
301 |
|
153 |
print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h); |
302 |
|
153 |
print_tagq(h, t); |
303 |
|
153 |
mdoc_root_post(&mdoc->meta, mdoc->first->child, h); |
304 |
|
153 |
print_tagq(h, NULL); |
305 |
|
153 |
} |
306 |
|
|
|
307 |
|
|
static void |
308 |
|
|
print_mdoc_head(MDOC_ARGS) |
309 |
|
|
{ |
310 |
|
306 |
char *cp; |
311 |
|
|
|
312 |
|
153 |
print_gen_head(h); |
313 |
|
|
|
314 |
✗✓✗✗
|
153 |
if (meta->arch != NULL && meta->msec != NULL) |
315 |
|
|
mandoc_asprintf(&cp, "%s(%s) (%s)", meta->title, |
316 |
|
|
meta->msec, meta->arch); |
317 |
✓✗ |
153 |
else if (meta->msec != NULL) |
318 |
|
153 |
mandoc_asprintf(&cp, "%s(%s)", meta->title, meta->msec); |
319 |
|
|
else if (meta->arch != NULL) |
320 |
|
|
mandoc_asprintf(&cp, "%s (%s)", meta->title, meta->arch); |
321 |
|
|
else |
322 |
|
|
cp = mandoc_strdup(meta->title); |
323 |
|
|
|
324 |
|
153 |
print_otag(h, TAG_TITLE, ""); |
325 |
|
153 |
print_text(h, cp); |
326 |
|
153 |
free(cp); |
327 |
|
153 |
} |
328 |
|
|
|
329 |
|
|
static void |
330 |
|
|
print_mdoc_nodelist(MDOC_ARGS) |
331 |
|
|
{ |
332 |
|
|
|
333 |
✓✓ |
10737 |
while (n != NULL) { |
334 |
|
3060 |
print_mdoc_node(meta, n, h); |
335 |
|
3060 |
n = n->next; |
336 |
|
|
} |
337 |
|
1539 |
} |
338 |
|
|
|
339 |
|
|
static void |
340 |
|
|
print_mdoc_node(MDOC_ARGS) |
341 |
|
|
{ |
342 |
|
|
int child; |
343 |
|
|
struct tag *t; |
344 |
|
|
|
345 |
✓✓ |
6264 |
if (n->flags & NODE_NOPRT) |
346 |
|
459 |
return; |
347 |
|
|
|
348 |
|
|
child = 1; |
349 |
|
2673 |
t = h->tag; |
350 |
|
2673 |
n->flags &= ~NODE_ENDED; |
351 |
|
|
|
352 |
✓✓✗✓
|
2673 |
switch (n->type) { |
353 |
|
|
case ROFFT_TEXT: |
354 |
|
|
/* No tables in this mode... */ |
355 |
✗✓ |
972 |
assert(NULL == h->tblt); |
356 |
|
|
|
357 |
|
|
/* |
358 |
|
|
* Make sure that if we're in a literal mode already |
359 |
|
|
* (i.e., within a <PRE>) don't print the newline. |
360 |
|
|
*/ |
361 |
✗✓✗✗ ✗✗ |
972 |
if (*n->string == ' ' && n->flags & NODE_LINE && |
362 |
|
|
(h->flags & (HTML_LITERAL | HTML_NONEWLINE)) == 0) |
363 |
|
|
print_otag(h, TAG_BR, ""); |
364 |
✗✓ |
972 |
if (NODE_DELIMC & n->flags) |
365 |
|
|
h->flags |= HTML_NOSPACE; |
366 |
|
972 |
print_text(h, n->string); |
367 |
✗✓ |
972 |
if (NODE_DELIMO & n->flags) |
368 |
|
|
h->flags |= HTML_NOSPACE; |
369 |
|
972 |
return; |
370 |
|
|
case ROFFT_EQN: |
371 |
|
144 |
print_eqn(h, n->eqn); |
372 |
|
144 |
break; |
373 |
|
|
case ROFFT_TBL: |
374 |
|
|
/* |
375 |
|
|
* This will take care of initialising all of the table |
376 |
|
|
* state data for the first table, then tearing it down |
377 |
|
|
* for the last one. |
378 |
|
|
*/ |
379 |
|
|
print_tbl(h, n->span); |
380 |
|
|
return; |
381 |
|
|
default: |
382 |
|
|
/* |
383 |
|
|
* Close out the current table, if it's open, and unset |
384 |
|
|
* the "meta" table state. This will be reopened on the |
385 |
|
|
* next table element. |
386 |
|
|
*/ |
387 |
✗✓ |
1557 |
if (h->tblt != NULL) { |
388 |
|
|
print_tblclose(h); |
389 |
|
|
t = h->tag; |
390 |
|
|
} |
391 |
✗✓ |
1557 |
assert(h->tblt == NULL); |
392 |
✗✓ |
1557 |
if (n->tok < ROFF_MAX) { |
393 |
|
|
roff_html_pre(h, n); |
394 |
|
|
child = 0; |
395 |
|
|
break; |
396 |
|
|
} |
397 |
✓✗✗✓
|
3114 |
assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); |
398 |
✓✗✗✗
|
1557 |
if (mdocs[n->tok].pre != NULL && |
399 |
✗✓ |
1557 |
(n->end == ENDBODY_NOT || n->child != NULL)) |
400 |
|
1557 |
child = (*mdocs[n->tok].pre)(meta, n, h); |
401 |
|
|
break; |
402 |
|
|
} |
403 |
|
|
|
404 |
✗✓✗✗
|
1701 |
if (h->flags & HTML_KEEP && n->flags & NODE_LINE) { |
405 |
|
|
h->flags &= ~HTML_KEEP; |
406 |
|
|
h->flags |= HTML_PREKEEP; |
407 |
|
|
} |
408 |
|
|
|
409 |
✓✓✓✓
|
3384 |
if (child && n->child) |
410 |
|
1386 |
print_mdoc_nodelist(meta, n->child, h); |
411 |
|
|
|
412 |
|
1701 |
print_stagq(h, t); |
413 |
|
|
|
414 |
✓✓ |
1701 |
switch (n->type) { |
415 |
|
|
case ROFFT_EQN: |
416 |
|
|
break; |
417 |
|
|
default: |
418 |
✓✗✗✗
|
1557 |
if (n->tok < ROFF_MAX || |
419 |
✗✓ |
1557 |
mdocs[n->tok].post == NULL || |
420 |
|
|
n->flags & NODE_ENDED) |
421 |
|
|
break; |
422 |
|
|
(*mdocs[n->tok].post)(meta, n, h); |
423 |
|
|
if (n->end != ENDBODY_NOT) |
424 |
|
|
n->body->flags |= NODE_ENDED; |
425 |
|
|
break; |
426 |
|
|
} |
427 |
|
4833 |
} |
428 |
|
|
|
429 |
|
|
static void |
430 |
|
|
mdoc_root_post(MDOC_ARGS) |
431 |
|
|
{ |
432 |
|
|
struct tag *t, *tt; |
433 |
|
|
|
434 |
|
306 |
t = print_otag(h, TAG_TABLE, "c", "foot"); |
435 |
|
153 |
tt = print_otag(h, TAG_TR, ""); |
436 |
|
|
|
437 |
|
153 |
print_otag(h, TAG_TD, "c", "foot-date"); |
438 |
|
153 |
print_text(h, meta->date); |
439 |
|
153 |
print_stagq(h, tt); |
440 |
|
|
|
441 |
|
153 |
print_otag(h, TAG_TD, "c", "foot-os"); |
442 |
|
153 |
print_text(h, meta->os); |
443 |
|
153 |
print_tagq(h, t); |
444 |
|
153 |
} |
445 |
|
|
|
446 |
|
|
static int |
447 |
|
|
mdoc_root_pre(MDOC_ARGS) |
448 |
|
|
{ |
449 |
|
|
struct tag *t, *tt; |
450 |
|
306 |
char *volume, *title; |
451 |
|
|
|
452 |
✓✗ |
153 |
if (NULL == meta->arch) |
453 |
|
153 |
volume = mandoc_strdup(meta->vol); |
454 |
|
|
else |
455 |
|
|
mandoc_asprintf(&volume, "%s (%s)", |
456 |
|
|
meta->vol, meta->arch); |
457 |
|
|
|
458 |
✗✓ |
153 |
if (NULL == meta->msec) |
459 |
|
|
title = mandoc_strdup(meta->title); |
460 |
|
|
else |
461 |
|
153 |
mandoc_asprintf(&title, "%s(%s)", |
462 |
|
|
meta->title, meta->msec); |
463 |
|
|
|
464 |
|
153 |
t = print_otag(h, TAG_TABLE, "c", "head"); |
465 |
|
153 |
tt = print_otag(h, TAG_TR, ""); |
466 |
|
|
|
467 |
|
153 |
print_otag(h, TAG_TD, "c", "head-ltitle"); |
468 |
|
153 |
print_text(h, title); |
469 |
|
153 |
print_stagq(h, tt); |
470 |
|
|
|
471 |
|
153 |
print_otag(h, TAG_TD, "c", "head-vol"); |
472 |
|
153 |
print_text(h, volume); |
473 |
|
153 |
print_stagq(h, tt); |
474 |
|
|
|
475 |
|
153 |
print_otag(h, TAG_TD, "c", "head-rtitle"); |
476 |
|
153 |
print_text(h, title); |
477 |
|
153 |
print_tagq(h, t); |
478 |
|
|
|
479 |
|
153 |
free(title); |
480 |
|
153 |
free(volume); |
481 |
|
153 |
return 1; |
482 |
|
153 |
} |
483 |
|
|
|
484 |
|
|
static char * |
485 |
|
|
cond_id(const struct roff_node *n) |
486 |
|
|
{ |
487 |
|
|
if (n->child != NULL && |
488 |
|
|
n->child->type == ROFFT_TEXT && |
489 |
|
|
(n->prev == NULL || |
490 |
|
|
(n->prev->type == ROFFT_TEXT && |
491 |
|
|
strcmp(n->prev->string, "|") == 0)) && |
492 |
|
|
(n->parent->tok == MDOC_It || |
493 |
|
|
(n->parent->tok == MDOC_Xo && |
494 |
|
|
n->parent->parent->prev == NULL && |
495 |
|
|
n->parent->parent->parent->tok == MDOC_It))) |
496 |
|
|
return html_make_id(n); |
497 |
|
|
return NULL; |
498 |
|
|
} |
499 |
|
|
|
500 |
|
|
static int |
501 |
|
|
mdoc_sh_pre(MDOC_ARGS) |
502 |
|
|
{ |
503 |
|
|
char *id; |
504 |
|
|
|
505 |
✓✓✓ |
2448 |
switch (n->type) { |
506 |
|
|
case ROFFT_HEAD: |
507 |
|
306 |
id = html_make_id(n); |
508 |
|
306 |
print_otag(h, TAG_H1, "cTi", "Sh", id); |
509 |
✓✗ |
306 |
if (id != NULL) |
510 |
|
306 |
print_otag(h, TAG_A, "chR", "selflink", id); |
511 |
|
306 |
free(id); |
512 |
|
306 |
break; |
513 |
|
|
case ROFFT_BODY: |
514 |
✗✓ |
306 |
if (n->sec == SEC_AUTHORS) |
515 |
|
|
h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT); |
516 |
|
|
break; |
517 |
|
|
default: |
518 |
|
|
break; |
519 |
|
|
} |
520 |
|
918 |
return 1; |
521 |
|
|
} |
522 |
|
|
|
523 |
|
|
static int |
524 |
|
|
mdoc_ss_pre(MDOC_ARGS) |
525 |
|
|
{ |
526 |
|
|
char *id; |
527 |
|
|
|
528 |
|
|
if (n->type != ROFFT_HEAD) |
529 |
|
|
return 1; |
530 |
|
|
|
531 |
|
|
id = html_make_id(n); |
532 |
|
|
print_otag(h, TAG_H2, "cTi", "Ss", id); |
533 |
|
|
if (id != NULL) |
534 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
535 |
|
|
free(id); |
536 |
|
|
return 1; |
537 |
|
|
} |
538 |
|
|
|
539 |
|
|
static int |
540 |
|
|
mdoc_fl_pre(MDOC_ARGS) |
541 |
|
|
{ |
542 |
|
|
char *id; |
543 |
|
|
|
544 |
|
|
if ((id = cond_id(n)) != NULL) |
545 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
546 |
|
|
print_otag(h, TAG_B, "cTi", "Fl", id); |
547 |
|
|
free(id); |
548 |
|
|
|
549 |
|
|
print_text(h, "\\-"); |
550 |
|
|
if (!(n->child == NULL && |
551 |
|
|
(n->next == NULL || |
552 |
|
|
n->next->type == ROFFT_TEXT || |
553 |
|
|
n->next->flags & NODE_LINE))) |
554 |
|
|
h->flags |= HTML_NOSPACE; |
555 |
|
|
|
556 |
|
|
return 1; |
557 |
|
|
} |
558 |
|
|
|
559 |
|
|
static int |
560 |
|
|
mdoc_cm_pre(MDOC_ARGS) |
561 |
|
|
{ |
562 |
|
|
char *id; |
563 |
|
|
|
564 |
|
|
if ((id = cond_id(n)) != NULL) |
565 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
566 |
|
|
print_otag(h, TAG_B, "cTi", "Cm", id); |
567 |
|
|
free(id); |
568 |
|
|
return 1; |
569 |
|
|
} |
570 |
|
|
|
571 |
|
|
static int |
572 |
|
|
mdoc_nd_pre(MDOC_ARGS) |
573 |
|
|
{ |
574 |
✓✓ |
918 |
if (n->type != ROFFT_BODY) |
575 |
|
306 |
return 1; |
576 |
|
|
|
577 |
|
|
/* XXX: this tag in theory can contain block elements. */ |
578 |
|
|
|
579 |
|
153 |
print_text(h, "\\(em"); |
580 |
|
153 |
print_otag(h, TAG_SPAN, "cT", "Nd"); |
581 |
|
153 |
return 1; |
582 |
|
459 |
} |
583 |
|
|
|
584 |
|
|
static int |
585 |
|
|
mdoc_nm_pre(MDOC_ARGS) |
586 |
|
|
{ |
587 |
✗✓✗✗
|
306 |
switch (n->type) { |
588 |
|
|
case ROFFT_HEAD: |
589 |
|
|
print_otag(h, TAG_TD, ""); |
590 |
|
|
/* FALLTHROUGH */ |
591 |
|
|
case ROFFT_ELEM: |
592 |
|
153 |
print_otag(h, TAG_B, "cT", "Nm"); |
593 |
|
153 |
return 1; |
594 |
|
|
case ROFFT_BODY: |
595 |
|
|
print_otag(h, TAG_TD, ""); |
596 |
|
|
return 1; |
597 |
|
|
default: |
598 |
|
|
break; |
599 |
|
|
} |
600 |
|
|
synopsis_pre(h, n); |
601 |
|
|
print_otag(h, TAG_TABLE, "c", "Nm"); |
602 |
|
|
print_otag(h, TAG_TR, ""); |
603 |
|
|
return 1; |
604 |
|
153 |
} |
605 |
|
|
|
606 |
|
|
static int |
607 |
|
|
mdoc_xr_pre(MDOC_ARGS) |
608 |
|
|
{ |
609 |
|
|
if (NULL == n->child) |
610 |
|
|
return 0; |
611 |
|
|
|
612 |
|
|
if (h->base_man) |
613 |
|
|
print_otag(h, TAG_A, "cThM", "Xr", |
614 |
|
|
n->child->string, n->child->next == NULL ? |
615 |
|
|
NULL : n->child->next->string); |
616 |
|
|
else |
617 |
|
|
print_otag(h, TAG_A, "cT", "Xr"); |
618 |
|
|
|
619 |
|
|
n = n->child; |
620 |
|
|
print_text(h, n->string); |
621 |
|
|
|
622 |
|
|
if (NULL == (n = n->next)) |
623 |
|
|
return 0; |
624 |
|
|
|
625 |
|
|
h->flags |= HTML_NOSPACE; |
626 |
|
|
print_text(h, "("); |
627 |
|
|
h->flags |= HTML_NOSPACE; |
628 |
|
|
print_text(h, n->string); |
629 |
|
|
h->flags |= HTML_NOSPACE; |
630 |
|
|
print_text(h, ")"); |
631 |
|
|
return 0; |
632 |
|
|
} |
633 |
|
|
|
634 |
|
|
static int |
635 |
|
|
mdoc_ns_pre(MDOC_ARGS) |
636 |
|
|
{ |
637 |
|
|
|
638 |
|
|
if ( ! (NODE_LINE & n->flags)) |
639 |
|
|
h->flags |= HTML_NOSPACE; |
640 |
|
|
return 1; |
641 |
|
|
} |
642 |
|
|
|
643 |
|
|
static int |
644 |
|
|
mdoc_ar_pre(MDOC_ARGS) |
645 |
|
|
{ |
646 |
|
|
print_otag(h, TAG_VAR, "cT", "Ar"); |
647 |
|
|
return 1; |
648 |
|
|
} |
649 |
|
|
|
650 |
|
|
static int |
651 |
|
|
mdoc_xx_pre(MDOC_ARGS) |
652 |
|
|
{ |
653 |
|
|
print_otag(h, TAG_SPAN, "c", "Ux"); |
654 |
|
|
return 1; |
655 |
|
|
} |
656 |
|
|
|
657 |
|
|
static int |
658 |
|
|
mdoc_it_pre(MDOC_ARGS) |
659 |
|
|
{ |
660 |
|
|
const struct roff_node *bl; |
661 |
|
|
struct tag *t; |
662 |
|
|
const char *cattr; |
663 |
|
|
enum mdoc_list type; |
664 |
|
|
|
665 |
|
|
bl = n->parent; |
666 |
|
|
while (bl->tok != MDOC_Bl) |
667 |
|
|
bl = bl->parent; |
668 |
|
|
type = bl->norm->Bl.type; |
669 |
|
|
|
670 |
|
|
switch (type) { |
671 |
|
|
case LIST_bullet: |
672 |
|
|
cattr = "It-bullet"; |
673 |
|
|
break; |
674 |
|
|
case LIST_dash: |
675 |
|
|
case LIST_hyphen: |
676 |
|
|
cattr = "It-dash"; |
677 |
|
|
break; |
678 |
|
|
case LIST_item: |
679 |
|
|
cattr = "It-item"; |
680 |
|
|
break; |
681 |
|
|
case LIST_enum: |
682 |
|
|
cattr = "It-enum"; |
683 |
|
|
break; |
684 |
|
|
case LIST_diag: |
685 |
|
|
cattr = "It-diag"; |
686 |
|
|
break; |
687 |
|
|
case LIST_hang: |
688 |
|
|
cattr = "It-hang"; |
689 |
|
|
break; |
690 |
|
|
case LIST_inset: |
691 |
|
|
cattr = "It-inset"; |
692 |
|
|
break; |
693 |
|
|
case LIST_ohang: |
694 |
|
|
cattr = "It-ohang"; |
695 |
|
|
break; |
696 |
|
|
case LIST_tag: |
697 |
|
|
cattr = "It-tag"; |
698 |
|
|
break; |
699 |
|
|
case LIST_column: |
700 |
|
|
cattr = "It-column"; |
701 |
|
|
break; |
702 |
|
|
default: |
703 |
|
|
break; |
704 |
|
|
} |
705 |
|
|
|
706 |
|
|
switch (type) { |
707 |
|
|
case LIST_bullet: |
708 |
|
|
case LIST_dash: |
709 |
|
|
case LIST_hyphen: |
710 |
|
|
case LIST_item: |
711 |
|
|
case LIST_enum: |
712 |
|
|
switch (n->type) { |
713 |
|
|
case ROFFT_HEAD: |
714 |
|
|
return 0; |
715 |
|
|
case ROFFT_BODY: |
716 |
|
|
print_otag(h, TAG_LI, "c", cattr); |
717 |
|
|
break; |
718 |
|
|
default: |
719 |
|
|
break; |
720 |
|
|
} |
721 |
|
|
break; |
722 |
|
|
case LIST_diag: |
723 |
|
|
case LIST_hang: |
724 |
|
|
case LIST_inset: |
725 |
|
|
case LIST_ohang: |
726 |
|
|
switch (n->type) { |
727 |
|
|
case ROFFT_HEAD: |
728 |
|
|
print_otag(h, TAG_DT, "c", cattr); |
729 |
|
|
if (type == LIST_diag) |
730 |
|
|
print_otag(h, TAG_B, "c", cattr); |
731 |
|
|
break; |
732 |
|
|
case ROFFT_BODY: |
733 |
|
|
print_otag(h, TAG_DD, "csw*+l", cattr, |
734 |
|
|
bl->norm->Bl.width); |
735 |
|
|
break; |
736 |
|
|
default: |
737 |
|
|
break; |
738 |
|
|
} |
739 |
|
|
break; |
740 |
|
|
case LIST_tag: |
741 |
|
|
switch (n->type) { |
742 |
|
|
case ROFFT_HEAD: |
743 |
|
|
if (h->style != NULL && !bl->norm->Bl.comp && |
744 |
|
|
(n->parent->prev == NULL || |
745 |
|
|
n->parent->prev->body == NULL || |
746 |
|
|
n->parent->prev->body->child != NULL)) { |
747 |
|
|
t = print_otag(h, TAG_DT, "csw*+-l", |
748 |
|
|
cattr, bl->norm->Bl.width); |
749 |
|
|
print_text(h, "\\ "); |
750 |
|
|
print_tagq(h, t); |
751 |
|
|
t = print_otag(h, TAG_DD, "c", cattr); |
752 |
|
|
print_text(h, "\\ "); |
753 |
|
|
print_tagq(h, t); |
754 |
|
|
} |
755 |
|
|
print_otag(h, TAG_DT, "csw*+-l", cattr, |
756 |
|
|
bl->norm->Bl.width); |
757 |
|
|
break; |
758 |
|
|
case ROFFT_BODY: |
759 |
|
|
if (n->child == NULL) { |
760 |
|
|
print_otag(h, TAG_DD, "css?", cattr, |
761 |
|
|
"width", "auto"); |
762 |
|
|
print_text(h, "\\ "); |
763 |
|
|
} else |
764 |
|
|
print_otag(h, TAG_DD, "c", cattr); |
765 |
|
|
break; |
766 |
|
|
default: |
767 |
|
|
break; |
768 |
|
|
} |
769 |
|
|
break; |
770 |
|
|
case LIST_column: |
771 |
|
|
switch (n->type) { |
772 |
|
|
case ROFFT_HEAD: |
773 |
|
|
break; |
774 |
|
|
case ROFFT_BODY: |
775 |
|
|
print_otag(h, TAG_TD, "c", cattr); |
776 |
|
|
break; |
777 |
|
|
default: |
778 |
|
|
print_otag(h, TAG_TR, "c", cattr); |
779 |
|
|
} |
780 |
|
|
default: |
781 |
|
|
break; |
782 |
|
|
} |
783 |
|
|
|
784 |
|
|
return 1; |
785 |
|
|
} |
786 |
|
|
|
787 |
|
|
static int |
788 |
|
|
mdoc_bl_pre(MDOC_ARGS) |
789 |
|
|
{ |
790 |
|
|
char cattr[21]; |
791 |
|
|
struct tag *t; |
792 |
|
|
struct mdoc_bl *bl; |
793 |
|
|
size_t i; |
794 |
|
|
enum htmltag elemtype; |
795 |
|
|
|
796 |
|
|
bl = &n->norm->Bl; |
797 |
|
|
|
798 |
|
|
switch (n->type) { |
799 |
|
|
case ROFFT_BODY: |
800 |
|
|
return 1; |
801 |
|
|
|
802 |
|
|
case ROFFT_HEAD: |
803 |
|
|
if (bl->type != LIST_column || bl->ncols == 0) |
804 |
|
|
return 0; |
805 |
|
|
|
806 |
|
|
/* |
807 |
|
|
* For each column, print out the <COL> tag with our |
808 |
|
|
* suggested width. The last column gets min-width, as |
809 |
|
|
* in terminal mode it auto-sizes to the width of the |
810 |
|
|
* screen and we want to preserve that behaviour. |
811 |
|
|
*/ |
812 |
|
|
|
813 |
|
|
t = print_otag(h, TAG_COLGROUP, ""); |
814 |
|
|
for (i = 0; i < bl->ncols - 1; i++) |
815 |
|
|
print_otag(h, TAG_COL, "sw+w", bl->cols[i]); |
816 |
|
|
print_otag(h, TAG_COL, "swW", bl->cols[i]); |
817 |
|
|
print_tagq(h, t); |
818 |
|
|
return 0; |
819 |
|
|
|
820 |
|
|
default: |
821 |
|
|
break; |
822 |
|
|
} |
823 |
|
|
|
824 |
|
|
switch (bl->type) { |
825 |
|
|
case LIST_bullet: |
826 |
|
|
elemtype = TAG_UL; |
827 |
|
|
(void)strlcpy(cattr, "Bl-bullet", sizeof(cattr)); |
828 |
|
|
break; |
829 |
|
|
case LIST_dash: |
830 |
|
|
case LIST_hyphen: |
831 |
|
|
elemtype = TAG_UL; |
832 |
|
|
(void)strlcpy(cattr, "Bl-dash", sizeof(cattr)); |
833 |
|
|
break; |
834 |
|
|
case LIST_item: |
835 |
|
|
elemtype = TAG_UL; |
836 |
|
|
(void)strlcpy(cattr, "Bl-item", sizeof(cattr)); |
837 |
|
|
break; |
838 |
|
|
case LIST_enum: |
839 |
|
|
elemtype = TAG_OL; |
840 |
|
|
(void)strlcpy(cattr, "Bl-enum", sizeof(cattr)); |
841 |
|
|
break; |
842 |
|
|
case LIST_diag: |
843 |
|
|
elemtype = TAG_DL; |
844 |
|
|
(void)strlcpy(cattr, "Bl-diag", sizeof(cattr)); |
845 |
|
|
break; |
846 |
|
|
case LIST_hang: |
847 |
|
|
elemtype = TAG_DL; |
848 |
|
|
(void)strlcpy(cattr, "Bl-hang", sizeof(cattr)); |
849 |
|
|
break; |
850 |
|
|
case LIST_inset: |
851 |
|
|
elemtype = TAG_DL; |
852 |
|
|
(void)strlcpy(cattr, "Bl-inset", sizeof(cattr)); |
853 |
|
|
break; |
854 |
|
|
case LIST_ohang: |
855 |
|
|
elemtype = TAG_DL; |
856 |
|
|
(void)strlcpy(cattr, "Bl-ohang", sizeof(cattr)); |
857 |
|
|
break; |
858 |
|
|
case LIST_tag: |
859 |
|
|
if (bl->offs) |
860 |
|
|
print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs); |
861 |
|
|
print_otag(h, TAG_DL, "csw*+l", bl->comp ? |
862 |
|
|
"Bl-tag Bl-compact" : "Bl-tag", bl->width); |
863 |
|
|
return 1; |
864 |
|
|
case LIST_column: |
865 |
|
|
elemtype = TAG_TABLE; |
866 |
|
|
(void)strlcpy(cattr, "Bl-column", sizeof(cattr)); |
867 |
|
|
break; |
868 |
|
|
default: |
869 |
|
|
abort(); |
870 |
|
|
} |
871 |
|
|
if (bl->comp) |
872 |
|
|
(void)strlcat(cattr, " Bl-compact", sizeof(cattr)); |
873 |
|
|
print_otag(h, elemtype, "cswl", cattr, bl->offs); |
874 |
|
|
return 1; |
875 |
|
|
} |
876 |
|
|
|
877 |
|
|
static int |
878 |
|
|
mdoc_ex_pre(MDOC_ARGS) |
879 |
|
|
{ |
880 |
|
|
if (n->prev) |
881 |
|
|
print_otag(h, TAG_BR, ""); |
882 |
|
|
return 1; |
883 |
|
|
} |
884 |
|
|
|
885 |
|
|
static int |
886 |
|
|
mdoc_st_pre(MDOC_ARGS) |
887 |
|
|
{ |
888 |
|
|
print_otag(h, TAG_SPAN, "cT", "St"); |
889 |
|
|
return 1; |
890 |
|
|
} |
891 |
|
|
|
892 |
|
|
static int |
893 |
|
|
mdoc_em_pre(MDOC_ARGS) |
894 |
|
|
{ |
895 |
|
|
print_otag(h, TAG_I, "cT", "Em"); |
896 |
|
|
return 1; |
897 |
|
|
} |
898 |
|
|
|
899 |
|
|
static int |
900 |
|
|
mdoc_d1_pre(MDOC_ARGS) |
901 |
|
|
{ |
902 |
|
|
if (n->type != ROFFT_BLOCK) |
903 |
|
|
return 1; |
904 |
|
|
|
905 |
|
|
print_otag(h, TAG_DIV, "c", "D1"); |
906 |
|
|
|
907 |
|
|
if (n->tok == MDOC_Dl) |
908 |
|
|
print_otag(h, TAG_CODE, "c", "Li"); |
909 |
|
|
|
910 |
|
|
return 1; |
911 |
|
|
} |
912 |
|
|
|
913 |
|
|
static int |
914 |
|
|
mdoc_sx_pre(MDOC_ARGS) |
915 |
|
|
{ |
916 |
|
|
char *id; |
917 |
|
|
|
918 |
|
|
id = html_make_id(n); |
919 |
|
|
print_otag(h, TAG_A, "cThR", "Sx", id); |
920 |
|
|
free(id); |
921 |
|
|
return 1; |
922 |
|
|
} |
923 |
|
|
|
924 |
|
|
static int |
925 |
|
|
mdoc_bd_pre(MDOC_ARGS) |
926 |
|
|
{ |
927 |
|
|
int comp, offs, sv; |
928 |
|
|
struct roff_node *nn; |
929 |
|
|
|
930 |
✓✓ |
54 |
if (n->type == ROFFT_HEAD) |
931 |
|
9 |
return 0; |
932 |
|
|
|
933 |
✓✓ |
18 |
if (n->type == ROFFT_BLOCK) { |
934 |
|
9 |
comp = n->norm->Bd.comp; |
935 |
✓✗✓✗
|
81 |
for (nn = n; nn && ! comp; nn = nn->parent) { |
936 |
✓✓ |
27 |
if (nn->type != ROFFT_BLOCK) |
937 |
|
|
continue; |
938 |
✓✗✓✓
|
36 |
if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok) |
939 |
|
9 |
comp = 1; |
940 |
✓✓ |
18 |
if (nn->prev) |
941 |
|
|
break; |
942 |
|
|
} |
943 |
✗✓ |
9 |
if ( ! comp) |
944 |
|
|
print_paragraph(h); |
945 |
|
9 |
return 1; |
946 |
|
|
} |
947 |
|
|
|
948 |
|
|
/* Handle the -offset argument. */ |
949 |
|
|
|
950 |
✗✓✗✗
|
9 |
if (n->norm->Bd.offs == NULL || |
951 |
|
|
! strcmp(n->norm->Bd.offs, "left")) |
952 |
|
9 |
offs = 0; |
953 |
|
|
else if ( ! strcmp(n->norm->Bd.offs, "indent")) |
954 |
|
|
offs = INDENT; |
955 |
|
|
else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) |
956 |
|
|
offs = INDENT * 2; |
957 |
|
|
else |
958 |
|
|
offs = -1; |
959 |
|
|
|
960 |
✗✓ |
9 |
if (offs == -1) |
961 |
|
|
print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs); |
962 |
|
|
else |
963 |
|
9 |
print_otag(h, TAG_DIV, "cshl", "Bd", offs); |
964 |
|
|
|
965 |
✗✓✗✗
|
9 |
if (n->norm->Bd.type != DISP_unfilled && |
966 |
|
|
n->norm->Bd.type != DISP_literal) |
967 |
|
|
return 1; |
968 |
|
|
|
969 |
|
9 |
print_otag(h, TAG_PRE, "c", "Li"); |
970 |
|
|
|
971 |
|
|
/* This can be recursive: save & set our literal state. */ |
972 |
|
|
|
973 |
|
9 |
sv = h->flags & HTML_LITERAL; |
974 |
|
9 |
h->flags |= HTML_LITERAL; |
975 |
|
|
|
976 |
✓✓ |
162 |
for (nn = n->child; nn; nn = nn->next) { |
977 |
|
144 |
print_mdoc_node(meta, nn, h); |
978 |
|
|
/* |
979 |
|
|
* If the printed node flushes its own line, then we |
980 |
|
|
* needn't do it here as well. This is hacky, but the |
981 |
|
|
* notion of selective eoln whitespace is pretty dumb |
982 |
|
|
* anyway, so don't sweat it. |
983 |
|
|
*/ |
984 |
✓✗✗✗ ✗✗✗✗ ✓ |
144 |
switch (nn->tok) { |
985 |
|
|
case ROFF_br: |
986 |
|
|
case ROFF_sp: |
987 |
|
|
case MDOC_Sm: |
988 |
|
|
case MDOC_Bl: |
989 |
|
|
case MDOC_D1: |
990 |
|
|
case MDOC_Dl: |
991 |
|
|
case MDOC_Lp: |
992 |
|
|
case MDOC_Pp: |
993 |
|
|
continue; |
994 |
|
|
default: |
995 |
|
|
break; |
996 |
|
|
} |
997 |
✓✗✓✗
|
135 |
if (h->flags & HTML_NONEWLINE || |
998 |
✓✓ |
135 |
(nn->next && ! (nn->next->flags & NODE_LINE))) |
999 |
|
|
continue; |
1000 |
✓✓ |
72 |
else if (nn->next) |
1001 |
|
63 |
print_text(h, "\n"); |
1002 |
|
|
|
1003 |
|
72 |
h->flags |= HTML_NOSPACE; |
1004 |
|
72 |
} |
1005 |
|
|
|
1006 |
✓✗ |
9 |
if (0 == sv) |
1007 |
|
9 |
h->flags &= ~HTML_LITERAL; |
1008 |
|
|
|
1009 |
|
9 |
return 0; |
1010 |
|
27 |
} |
1011 |
|
|
|
1012 |
|
|
static int |
1013 |
|
|
mdoc_pa_pre(MDOC_ARGS) |
1014 |
|
|
{ |
1015 |
|
|
print_otag(h, TAG_I, "cT", "Pa"); |
1016 |
|
|
return 1; |
1017 |
|
|
} |
1018 |
|
|
|
1019 |
|
|
static int |
1020 |
|
|
mdoc_ad_pre(MDOC_ARGS) |
1021 |
|
|
{ |
1022 |
|
|
print_otag(h, TAG_I, "c", "Ad"); |
1023 |
|
|
return 1; |
1024 |
|
|
} |
1025 |
|
|
|
1026 |
|
|
static int |
1027 |
|
|
mdoc_an_pre(MDOC_ARGS) |
1028 |
|
|
{ |
1029 |
|
|
if (n->norm->An.auth == AUTH_split) { |
1030 |
|
|
h->flags &= ~HTML_NOSPLIT; |
1031 |
|
|
h->flags |= HTML_SPLIT; |
1032 |
|
|
return 0; |
1033 |
|
|
} |
1034 |
|
|
if (n->norm->An.auth == AUTH_nosplit) { |
1035 |
|
|
h->flags &= ~HTML_SPLIT; |
1036 |
|
|
h->flags |= HTML_NOSPLIT; |
1037 |
|
|
return 0; |
1038 |
|
|
} |
1039 |
|
|
|
1040 |
|
|
if (h->flags & HTML_SPLIT) |
1041 |
|
|
print_otag(h, TAG_BR, ""); |
1042 |
|
|
|
1043 |
|
|
if (n->sec == SEC_AUTHORS && ! (h->flags & HTML_NOSPLIT)) |
1044 |
|
|
h->flags |= HTML_SPLIT; |
1045 |
|
|
|
1046 |
|
|
print_otag(h, TAG_SPAN, "cT", "An"); |
1047 |
|
|
return 1; |
1048 |
|
|
} |
1049 |
|
|
|
1050 |
|
|
static int |
1051 |
|
|
mdoc_cd_pre(MDOC_ARGS) |
1052 |
|
|
{ |
1053 |
|
|
synopsis_pre(h, n); |
1054 |
|
|
print_otag(h, TAG_B, "cT", "Cd"); |
1055 |
|
|
return 1; |
1056 |
|
|
} |
1057 |
|
|
|
1058 |
|
|
static int |
1059 |
|
|
mdoc_dv_pre(MDOC_ARGS) |
1060 |
|
|
{ |
1061 |
|
|
char *id; |
1062 |
|
|
|
1063 |
|
|
if ((id = cond_id(n)) != NULL) |
1064 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1065 |
|
|
print_otag(h, TAG_CODE, "cTi", "Dv", id); |
1066 |
|
|
free(id); |
1067 |
|
|
return 1; |
1068 |
|
|
} |
1069 |
|
|
|
1070 |
|
|
static int |
1071 |
|
|
mdoc_ev_pre(MDOC_ARGS) |
1072 |
|
|
{ |
1073 |
|
|
char *id; |
1074 |
|
|
|
1075 |
|
|
if ((id = cond_id(n)) != NULL) |
1076 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1077 |
|
|
print_otag(h, TAG_CODE, "cTi", "Ev", id); |
1078 |
|
|
free(id); |
1079 |
|
|
return 1; |
1080 |
|
|
} |
1081 |
|
|
|
1082 |
|
|
static int |
1083 |
|
|
mdoc_er_pre(MDOC_ARGS) |
1084 |
|
|
{ |
1085 |
|
|
char *id; |
1086 |
|
|
|
1087 |
|
|
id = n->sec == SEC_ERRORS && |
1088 |
|
|
(n->parent->tok == MDOC_It || |
1089 |
|
|
(n->parent->tok == MDOC_Bq && |
1090 |
|
|
n->parent->parent->parent->tok == MDOC_It)) ? |
1091 |
|
|
html_make_id(n) : NULL; |
1092 |
|
|
|
1093 |
|
|
if (id != NULL) |
1094 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1095 |
|
|
print_otag(h, TAG_CODE, "cTi", "Er", id); |
1096 |
|
|
free(id); |
1097 |
|
|
return 1; |
1098 |
|
|
} |
1099 |
|
|
|
1100 |
|
|
static int |
1101 |
|
|
mdoc_fa_pre(MDOC_ARGS) |
1102 |
|
|
{ |
1103 |
|
|
const struct roff_node *nn; |
1104 |
|
|
struct tag *t; |
1105 |
|
|
|
1106 |
|
|
if (n->parent->tok != MDOC_Fo) { |
1107 |
|
|
print_otag(h, TAG_VAR, "cT", "Fa"); |
1108 |
|
|
return 1; |
1109 |
|
|
} |
1110 |
|
|
|
1111 |
|
|
for (nn = n->child; nn; nn = nn->next) { |
1112 |
|
|
t = print_otag(h, TAG_VAR, "cT", "Fa"); |
1113 |
|
|
print_text(h, nn->string); |
1114 |
|
|
print_tagq(h, t); |
1115 |
|
|
if (nn->next) { |
1116 |
|
|
h->flags |= HTML_NOSPACE; |
1117 |
|
|
print_text(h, ","); |
1118 |
|
|
} |
1119 |
|
|
} |
1120 |
|
|
|
1121 |
|
|
if (n->child && n->next && n->next->tok == MDOC_Fa) { |
1122 |
|
|
h->flags |= HTML_NOSPACE; |
1123 |
|
|
print_text(h, ","); |
1124 |
|
|
} |
1125 |
|
|
|
1126 |
|
|
return 0; |
1127 |
|
|
} |
1128 |
|
|
|
1129 |
|
|
static int |
1130 |
|
|
mdoc_fd_pre(MDOC_ARGS) |
1131 |
|
|
{ |
1132 |
|
|
struct tag *t; |
1133 |
|
|
char *buf, *cp; |
1134 |
|
|
|
1135 |
|
|
synopsis_pre(h, n); |
1136 |
|
|
|
1137 |
|
|
if (NULL == (n = n->child)) |
1138 |
|
|
return 0; |
1139 |
|
|
|
1140 |
|
|
assert(n->type == ROFFT_TEXT); |
1141 |
|
|
|
1142 |
|
|
if (strcmp(n->string, "#include")) { |
1143 |
|
|
print_otag(h, TAG_B, "cT", "Fd"); |
1144 |
|
|
return 1; |
1145 |
|
|
} |
1146 |
|
|
|
1147 |
|
|
print_otag(h, TAG_B, "cT", "In"); |
1148 |
|
|
print_text(h, n->string); |
1149 |
|
|
|
1150 |
|
|
if (NULL != (n = n->next)) { |
1151 |
|
|
assert(n->type == ROFFT_TEXT); |
1152 |
|
|
|
1153 |
|
|
if (h->base_includes) { |
1154 |
|
|
cp = n->string; |
1155 |
|
|
if (*cp == '<' || *cp == '"') |
1156 |
|
|
cp++; |
1157 |
|
|
buf = mandoc_strdup(cp); |
1158 |
|
|
cp = strchr(buf, '\0') - 1; |
1159 |
|
|
if (cp >= buf && (*cp == '>' || *cp == '"')) |
1160 |
|
|
*cp = '\0'; |
1161 |
|
|
t = print_otag(h, TAG_A, "cThI", "In", buf); |
1162 |
|
|
free(buf); |
1163 |
|
|
} else |
1164 |
|
|
t = print_otag(h, TAG_A, "cT", "In"); |
1165 |
|
|
|
1166 |
|
|
print_text(h, n->string); |
1167 |
|
|
print_tagq(h, t); |
1168 |
|
|
|
1169 |
|
|
n = n->next; |
1170 |
|
|
} |
1171 |
|
|
|
1172 |
|
|
for ( ; n; n = n->next) { |
1173 |
|
|
assert(n->type == ROFFT_TEXT); |
1174 |
|
|
print_text(h, n->string); |
1175 |
|
|
} |
1176 |
|
|
|
1177 |
|
|
return 0; |
1178 |
|
|
} |
1179 |
|
|
|
1180 |
|
|
static int |
1181 |
|
|
mdoc_vt_pre(MDOC_ARGS) |
1182 |
|
|
{ |
1183 |
|
|
if (n->type == ROFFT_BLOCK) { |
1184 |
|
|
synopsis_pre(h, n); |
1185 |
|
|
return 1; |
1186 |
|
|
} else if (n->type == ROFFT_ELEM) { |
1187 |
|
|
synopsis_pre(h, n); |
1188 |
|
|
} else if (n->type == ROFFT_HEAD) |
1189 |
|
|
return 0; |
1190 |
|
|
|
1191 |
|
|
print_otag(h, TAG_VAR, "cT", "Vt"); |
1192 |
|
|
return 1; |
1193 |
|
|
} |
1194 |
|
|
|
1195 |
|
|
static int |
1196 |
|
|
mdoc_ft_pre(MDOC_ARGS) |
1197 |
|
|
{ |
1198 |
|
|
synopsis_pre(h, n); |
1199 |
|
|
print_otag(h, TAG_VAR, "cT", "Ft"); |
1200 |
|
|
return 1; |
1201 |
|
|
} |
1202 |
|
|
|
1203 |
|
|
static int |
1204 |
|
|
mdoc_fn_pre(MDOC_ARGS) |
1205 |
|
|
{ |
1206 |
|
|
struct tag *t; |
1207 |
|
|
char nbuf[BUFSIZ]; |
1208 |
|
|
const char *sp, *ep; |
1209 |
|
|
int sz, pretty; |
1210 |
|
|
|
1211 |
|
|
pretty = NODE_SYNPRETTY & n->flags; |
1212 |
|
|
synopsis_pre(h, n); |
1213 |
|
|
|
1214 |
|
|
/* Split apart into type and name. */ |
1215 |
|
|
assert(n->child->string); |
1216 |
|
|
sp = n->child->string; |
1217 |
|
|
|
1218 |
|
|
ep = strchr(sp, ' '); |
1219 |
|
|
if (NULL != ep) { |
1220 |
|
|
t = print_otag(h, TAG_VAR, "cT", "Ft"); |
1221 |
|
|
|
1222 |
|
|
while (ep) { |
1223 |
|
|
sz = MIN((int)(ep - sp), BUFSIZ - 1); |
1224 |
|
|
(void)memcpy(nbuf, sp, (size_t)sz); |
1225 |
|
|
nbuf[sz] = '\0'; |
1226 |
|
|
print_text(h, nbuf); |
1227 |
|
|
sp = ++ep; |
1228 |
|
|
ep = strchr(sp, ' '); |
1229 |
|
|
} |
1230 |
|
|
print_tagq(h, t); |
1231 |
|
|
} |
1232 |
|
|
|
1233 |
|
|
t = print_otag(h, TAG_B, "cT", "Fn"); |
1234 |
|
|
|
1235 |
|
|
if (sp) |
1236 |
|
|
print_text(h, sp); |
1237 |
|
|
|
1238 |
|
|
print_tagq(h, t); |
1239 |
|
|
|
1240 |
|
|
h->flags |= HTML_NOSPACE; |
1241 |
|
|
print_text(h, "("); |
1242 |
|
|
h->flags |= HTML_NOSPACE; |
1243 |
|
|
|
1244 |
|
|
for (n = n->child->next; n; n = n->next) { |
1245 |
|
|
if (NODE_SYNPRETTY & n->flags) |
1246 |
|
|
t = print_otag(h, TAG_VAR, "cTss?", "Fa", |
1247 |
|
|
"white-space", "nowrap"); |
1248 |
|
|
else |
1249 |
|
|
t = print_otag(h, TAG_VAR, "cT", "Fa"); |
1250 |
|
|
print_text(h, n->string); |
1251 |
|
|
print_tagq(h, t); |
1252 |
|
|
if (n->next) { |
1253 |
|
|
h->flags |= HTML_NOSPACE; |
1254 |
|
|
print_text(h, ","); |
1255 |
|
|
} |
1256 |
|
|
} |
1257 |
|
|
|
1258 |
|
|
h->flags |= HTML_NOSPACE; |
1259 |
|
|
print_text(h, ")"); |
1260 |
|
|
|
1261 |
|
|
if (pretty) { |
1262 |
|
|
h->flags |= HTML_NOSPACE; |
1263 |
|
|
print_text(h, ";"); |
1264 |
|
|
} |
1265 |
|
|
|
1266 |
|
|
return 0; |
1267 |
|
|
} |
1268 |
|
|
|
1269 |
|
|
static int |
1270 |
|
|
mdoc_sm_pre(MDOC_ARGS) |
1271 |
|
|
{ |
1272 |
|
|
|
1273 |
|
|
if (NULL == n->child) |
1274 |
|
|
h->flags ^= HTML_NONOSPACE; |
1275 |
|
|
else if (0 == strcmp("on", n->child->string)) |
1276 |
|
|
h->flags &= ~HTML_NONOSPACE; |
1277 |
|
|
else |
1278 |
|
|
h->flags |= HTML_NONOSPACE; |
1279 |
|
|
|
1280 |
|
|
if ( ! (HTML_NONOSPACE & h->flags)) |
1281 |
|
|
h->flags &= ~HTML_NOSPACE; |
1282 |
|
|
|
1283 |
|
|
return 0; |
1284 |
|
|
} |
1285 |
|
|
|
1286 |
|
|
static int |
1287 |
|
|
mdoc_skip_pre(MDOC_ARGS) |
1288 |
|
|
{ |
1289 |
|
|
|
1290 |
|
|
return 0; |
1291 |
|
|
} |
1292 |
|
|
|
1293 |
|
|
static int |
1294 |
|
|
mdoc_pp_pre(MDOC_ARGS) |
1295 |
|
|
{ |
1296 |
|
|
|
1297 |
|
|
print_paragraph(h); |
1298 |
|
|
return 0; |
1299 |
|
|
} |
1300 |
|
|
|
1301 |
|
|
static int |
1302 |
|
|
mdoc_lk_pre(MDOC_ARGS) |
1303 |
|
|
{ |
1304 |
|
|
const struct roff_node *link, *descr, *punct; |
1305 |
|
|
struct tag *t; |
1306 |
|
|
|
1307 |
|
|
if ((link = n->child) == NULL) |
1308 |
|
|
return 0; |
1309 |
|
|
|
1310 |
|
|
/* Find beginning of trailing punctuation. */ |
1311 |
|
|
punct = n->last; |
1312 |
|
|
while (punct != link && punct->flags & NODE_DELIMC) |
1313 |
|
|
punct = punct->prev; |
1314 |
|
|
punct = punct->next; |
1315 |
|
|
|
1316 |
|
|
/* Link target and link text. */ |
1317 |
|
|
descr = link->next; |
1318 |
|
|
if (descr == punct) |
1319 |
|
|
descr = link; /* no text */ |
1320 |
|
|
t = print_otag(h, TAG_A, "cTh", "Lk", link->string); |
1321 |
|
|
do { |
1322 |
|
|
if (descr->flags & (NODE_DELIMC | NODE_DELIMO)) |
1323 |
|
|
h->flags |= HTML_NOSPACE; |
1324 |
|
|
print_text(h, descr->string); |
1325 |
|
|
descr = descr->next; |
1326 |
|
|
} while (descr != punct); |
1327 |
|
|
print_tagq(h, t); |
1328 |
|
|
|
1329 |
|
|
/* Trailing punctuation. */ |
1330 |
|
|
while (punct != NULL) { |
1331 |
|
|
h->flags |= HTML_NOSPACE; |
1332 |
|
|
print_text(h, punct->string); |
1333 |
|
|
punct = punct->next; |
1334 |
|
|
} |
1335 |
|
|
return 0; |
1336 |
|
|
} |
1337 |
|
|
|
1338 |
|
|
static int |
1339 |
|
|
mdoc_mt_pre(MDOC_ARGS) |
1340 |
|
|
{ |
1341 |
|
|
struct tag *t; |
1342 |
|
|
char *cp; |
1343 |
|
|
|
1344 |
|
|
for (n = n->child; n; n = n->next) { |
1345 |
|
|
assert(n->type == ROFFT_TEXT); |
1346 |
|
|
|
1347 |
|
|
mandoc_asprintf(&cp, "mailto:%s", n->string); |
1348 |
|
|
t = print_otag(h, TAG_A, "cTh", "Mt", cp); |
1349 |
|
|
print_text(h, n->string); |
1350 |
|
|
print_tagq(h, t); |
1351 |
|
|
free(cp); |
1352 |
|
|
} |
1353 |
|
|
|
1354 |
|
|
return 0; |
1355 |
|
|
} |
1356 |
|
|
|
1357 |
|
|
static int |
1358 |
|
|
mdoc_fo_pre(MDOC_ARGS) |
1359 |
|
|
{ |
1360 |
|
|
struct tag *t; |
1361 |
|
|
|
1362 |
|
|
if (n->type == ROFFT_BODY) { |
1363 |
|
|
h->flags |= HTML_NOSPACE; |
1364 |
|
|
print_text(h, "("); |
1365 |
|
|
h->flags |= HTML_NOSPACE; |
1366 |
|
|
return 1; |
1367 |
|
|
} else if (n->type == ROFFT_BLOCK) { |
1368 |
|
|
synopsis_pre(h, n); |
1369 |
|
|
return 1; |
1370 |
|
|
} |
1371 |
|
|
|
1372 |
|
|
if (n->child == NULL) |
1373 |
|
|
return 0; |
1374 |
|
|
|
1375 |
|
|
assert(n->child->string); |
1376 |
|
|
t = print_otag(h, TAG_B, "cT", "Fn"); |
1377 |
|
|
print_text(h, n->child->string); |
1378 |
|
|
print_tagq(h, t); |
1379 |
|
|
return 0; |
1380 |
|
|
} |
1381 |
|
|
|
1382 |
|
|
static void |
1383 |
|
|
mdoc_fo_post(MDOC_ARGS) |
1384 |
|
|
{ |
1385 |
|
|
|
1386 |
|
|
if (n->type != ROFFT_BODY) |
1387 |
|
|
return; |
1388 |
|
|
h->flags |= HTML_NOSPACE; |
1389 |
|
|
print_text(h, ")"); |
1390 |
|
|
h->flags |= HTML_NOSPACE; |
1391 |
|
|
print_text(h, ";"); |
1392 |
|
|
} |
1393 |
|
|
|
1394 |
|
|
static int |
1395 |
|
|
mdoc_in_pre(MDOC_ARGS) |
1396 |
|
|
{ |
1397 |
|
|
struct tag *t; |
1398 |
|
|
|
1399 |
|
|
synopsis_pre(h, n); |
1400 |
|
|
print_otag(h, TAG_B, "cT", "In"); |
1401 |
|
|
|
1402 |
|
|
/* |
1403 |
|
|
* The first argument of the `In' gets special treatment as |
1404 |
|
|
* being a linked value. Subsequent values are printed |
1405 |
|
|
* afterward. groff does similarly. This also handles the case |
1406 |
|
|
* of no children. |
1407 |
|
|
*/ |
1408 |
|
|
|
1409 |
|
|
if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags) |
1410 |
|
|
print_text(h, "#include"); |
1411 |
|
|
|
1412 |
|
|
print_text(h, "<"); |
1413 |
|
|
h->flags |= HTML_NOSPACE; |
1414 |
|
|
|
1415 |
|
|
if (NULL != (n = n->child)) { |
1416 |
|
|
assert(n->type == ROFFT_TEXT); |
1417 |
|
|
|
1418 |
|
|
if (h->base_includes) |
1419 |
|
|
t = print_otag(h, TAG_A, "cThI", "In", n->string); |
1420 |
|
|
else |
1421 |
|
|
t = print_otag(h, TAG_A, "cT", "In"); |
1422 |
|
|
print_text(h, n->string); |
1423 |
|
|
print_tagq(h, t); |
1424 |
|
|
|
1425 |
|
|
n = n->next; |
1426 |
|
|
} |
1427 |
|
|
|
1428 |
|
|
h->flags |= HTML_NOSPACE; |
1429 |
|
|
print_text(h, ">"); |
1430 |
|
|
|
1431 |
|
|
for ( ; n; n = n->next) { |
1432 |
|
|
assert(n->type == ROFFT_TEXT); |
1433 |
|
|
print_text(h, n->string); |
1434 |
|
|
} |
1435 |
|
|
|
1436 |
|
|
return 0; |
1437 |
|
|
} |
1438 |
|
|
|
1439 |
|
|
static int |
1440 |
|
|
mdoc_ic_pre(MDOC_ARGS) |
1441 |
|
|
{ |
1442 |
|
|
char *id; |
1443 |
|
|
|
1444 |
|
|
if ((id = cond_id(n)) != NULL) |
1445 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1446 |
|
|
print_otag(h, TAG_B, "cTi", "Ic", id); |
1447 |
|
|
free(id); |
1448 |
|
|
return 1; |
1449 |
|
|
} |
1450 |
|
|
|
1451 |
|
|
static int |
1452 |
|
|
mdoc_va_pre(MDOC_ARGS) |
1453 |
|
|
{ |
1454 |
|
|
print_otag(h, TAG_VAR, "cT", "Va"); |
1455 |
|
|
return 1; |
1456 |
|
|
} |
1457 |
|
|
|
1458 |
|
|
static int |
1459 |
|
|
mdoc_ap_pre(MDOC_ARGS) |
1460 |
|
|
{ |
1461 |
|
|
|
1462 |
|
|
h->flags |= HTML_NOSPACE; |
1463 |
|
|
print_text(h, "\\(aq"); |
1464 |
|
|
h->flags |= HTML_NOSPACE; |
1465 |
|
|
return 1; |
1466 |
|
|
} |
1467 |
|
|
|
1468 |
|
|
static int |
1469 |
|
|
mdoc_bf_pre(MDOC_ARGS) |
1470 |
|
|
{ |
1471 |
|
|
const char *cattr; |
1472 |
|
|
|
1473 |
|
|
if (n->type == ROFFT_HEAD) |
1474 |
|
|
return 0; |
1475 |
|
|
else if (n->type != ROFFT_BODY) |
1476 |
|
|
return 1; |
1477 |
|
|
|
1478 |
|
|
if (FONT_Em == n->norm->Bf.font) |
1479 |
|
|
cattr = "Em"; |
1480 |
|
|
else if (FONT_Sy == n->norm->Bf.font) |
1481 |
|
|
cattr = "Sy"; |
1482 |
|
|
else if (FONT_Li == n->norm->Bf.font) |
1483 |
|
|
cattr = "Li"; |
1484 |
|
|
else |
1485 |
|
|
cattr = "No"; |
1486 |
|
|
|
1487 |
|
|
/* |
1488 |
|
|
* We want this to be inline-formatted, but needs to be div to |
1489 |
|
|
* accept block children. |
1490 |
|
|
*/ |
1491 |
|
|
|
1492 |
|
|
print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1); |
1493 |
|
|
return 1; |
1494 |
|
|
} |
1495 |
|
|
|
1496 |
|
|
static int |
1497 |
|
|
mdoc_ms_pre(MDOC_ARGS) |
1498 |
|
|
{ |
1499 |
|
|
char *id; |
1500 |
|
|
|
1501 |
|
|
if ((id = cond_id(n)) != NULL) |
1502 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1503 |
|
|
print_otag(h, TAG_B, "cTi", "Ms", id); |
1504 |
|
|
free(id); |
1505 |
|
|
return 1; |
1506 |
|
|
} |
1507 |
|
|
|
1508 |
|
|
static int |
1509 |
|
|
mdoc_igndelim_pre(MDOC_ARGS) |
1510 |
|
|
{ |
1511 |
|
|
|
1512 |
|
|
h->flags |= HTML_IGNDELIM; |
1513 |
|
|
return 1; |
1514 |
|
|
} |
1515 |
|
|
|
1516 |
|
|
static void |
1517 |
|
|
mdoc_pf_post(MDOC_ARGS) |
1518 |
|
|
{ |
1519 |
|
|
|
1520 |
|
|
if ( ! (n->next == NULL || n->next->flags & NODE_LINE)) |
1521 |
|
|
h->flags |= HTML_NOSPACE; |
1522 |
|
|
} |
1523 |
|
|
|
1524 |
|
|
static int |
1525 |
|
|
mdoc_rs_pre(MDOC_ARGS) |
1526 |
|
|
{ |
1527 |
|
|
if (n->type != ROFFT_BLOCK) |
1528 |
|
|
return 1; |
1529 |
|
|
|
1530 |
|
|
if (n->prev && SEC_SEE_ALSO == n->sec) |
1531 |
|
|
print_paragraph(h); |
1532 |
|
|
|
1533 |
|
|
print_otag(h, TAG_CITE, "cT", "Rs"); |
1534 |
|
|
return 1; |
1535 |
|
|
} |
1536 |
|
|
|
1537 |
|
|
static int |
1538 |
|
|
mdoc_no_pre(MDOC_ARGS) |
1539 |
|
|
{ |
1540 |
|
|
char *id; |
1541 |
|
|
|
1542 |
|
|
if ((id = cond_id(n)) != NULL) |
1543 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1544 |
|
|
print_otag(h, TAG_SPAN, "ci", "No", id); |
1545 |
|
|
free(id); |
1546 |
|
|
return 1; |
1547 |
|
|
} |
1548 |
|
|
|
1549 |
|
|
static int |
1550 |
|
|
mdoc_li_pre(MDOC_ARGS) |
1551 |
|
|
{ |
1552 |
|
|
char *id; |
1553 |
|
|
|
1554 |
|
|
if ((id = cond_id(n)) != NULL) |
1555 |
|
|
print_otag(h, TAG_A, "chR", "selflink", id); |
1556 |
|
|
print_otag(h, TAG_CODE, "ci", "Li", id); |
1557 |
|
|
free(id); |
1558 |
|
|
return 1; |
1559 |
|
|
} |
1560 |
|
|
|
1561 |
|
|
static int |
1562 |
|
|
mdoc_sy_pre(MDOC_ARGS) |
1563 |
|
|
{ |
1564 |
|
|
print_otag(h, TAG_B, "cT", "Sy"); |
1565 |
|
|
return 1; |
1566 |
|
|
} |
1567 |
|
|
|
1568 |
|
|
static int |
1569 |
|
|
mdoc_lb_pre(MDOC_ARGS) |
1570 |
|
|
{ |
1571 |
|
|
if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags && n->prev) |
1572 |
|
|
print_otag(h, TAG_BR, ""); |
1573 |
|
|
|
1574 |
|
|
print_otag(h, TAG_SPAN, "cT", "Lb"); |
1575 |
|
|
return 1; |
1576 |
|
|
} |
1577 |
|
|
|
1578 |
|
|
static int |
1579 |
|
|
mdoc__x_pre(MDOC_ARGS) |
1580 |
|
|
{ |
1581 |
|
|
const char *cattr; |
1582 |
|
|
enum htmltag t; |
1583 |
|
|
|
1584 |
|
|
t = TAG_SPAN; |
1585 |
|
|
|
1586 |
|
|
switch (n->tok) { |
1587 |
|
|
case MDOC__A: |
1588 |
|
|
cattr = "RsA"; |
1589 |
|
|
if (n->prev && MDOC__A == n->prev->tok) |
1590 |
|
|
if (NULL == n->next || MDOC__A != n->next->tok) |
1591 |
|
|
print_text(h, "and"); |
1592 |
|
|
break; |
1593 |
|
|
case MDOC__B: |
1594 |
|
|
t = TAG_I; |
1595 |
|
|
cattr = "RsB"; |
1596 |
|
|
break; |
1597 |
|
|
case MDOC__C: |
1598 |
|
|
cattr = "RsC"; |
1599 |
|
|
break; |
1600 |
|
|
case MDOC__D: |
1601 |
|
|
cattr = "RsD"; |
1602 |
|
|
break; |
1603 |
|
|
case MDOC__I: |
1604 |
|
|
t = TAG_I; |
1605 |
|
|
cattr = "RsI"; |
1606 |
|
|
break; |
1607 |
|
|
case MDOC__J: |
1608 |
|
|
t = TAG_I; |
1609 |
|
|
cattr = "RsJ"; |
1610 |
|
|
break; |
1611 |
|
|
case MDOC__N: |
1612 |
|
|
cattr = "RsN"; |
1613 |
|
|
break; |
1614 |
|
|
case MDOC__O: |
1615 |
|
|
cattr = "RsO"; |
1616 |
|
|
break; |
1617 |
|
|
case MDOC__P: |
1618 |
|
|
cattr = "RsP"; |
1619 |
|
|
break; |
1620 |
|
|
case MDOC__Q: |
1621 |
|
|
cattr = "RsQ"; |
1622 |
|
|
break; |
1623 |
|
|
case MDOC__R: |
1624 |
|
|
cattr = "RsR"; |
1625 |
|
|
break; |
1626 |
|
|
case MDOC__T: |
1627 |
|
|
cattr = "RsT"; |
1628 |
|
|
break; |
1629 |
|
|
case MDOC__U: |
1630 |
|
|
print_otag(h, TAG_A, "ch", "RsU", n->child->string); |
1631 |
|
|
return 1; |
1632 |
|
|
case MDOC__V: |
1633 |
|
|
cattr = "RsV"; |
1634 |
|
|
break; |
1635 |
|
|
default: |
1636 |
|
|
abort(); |
1637 |
|
|
} |
1638 |
|
|
|
1639 |
|
|
print_otag(h, t, "c", cattr); |
1640 |
|
|
return 1; |
1641 |
|
|
} |
1642 |
|
|
|
1643 |
|
|
static void |
1644 |
|
|
mdoc__x_post(MDOC_ARGS) |
1645 |
|
|
{ |
1646 |
|
|
|
1647 |
|
|
if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok) |
1648 |
|
|
if (NULL == n->next->next || MDOC__A != n->next->next->tok) |
1649 |
|
|
if (NULL == n->prev || MDOC__A != n->prev->tok) |
1650 |
|
|
return; |
1651 |
|
|
|
1652 |
|
|
/* TODO: %U */ |
1653 |
|
|
|
1654 |
|
|
if (NULL == n->parent || MDOC_Rs != n->parent->tok) |
1655 |
|
|
return; |
1656 |
|
|
|
1657 |
|
|
h->flags |= HTML_NOSPACE; |
1658 |
|
|
print_text(h, n->next ? "," : "."); |
1659 |
|
|
} |
1660 |
|
|
|
1661 |
|
|
static int |
1662 |
|
|
mdoc_bk_pre(MDOC_ARGS) |
1663 |
|
|
{ |
1664 |
|
|
|
1665 |
|
|
switch (n->type) { |
1666 |
|
|
case ROFFT_BLOCK: |
1667 |
|
|
break; |
1668 |
|
|
case ROFFT_HEAD: |
1669 |
|
|
return 0; |
1670 |
|
|
case ROFFT_BODY: |
1671 |
|
|
if (n->parent->args != NULL || n->prev->child == NULL) |
1672 |
|
|
h->flags |= HTML_PREKEEP; |
1673 |
|
|
break; |
1674 |
|
|
default: |
1675 |
|
|
abort(); |
1676 |
|
|
} |
1677 |
|
|
|
1678 |
|
|
return 1; |
1679 |
|
|
} |
1680 |
|
|
|
1681 |
|
|
static void |
1682 |
|
|
mdoc_bk_post(MDOC_ARGS) |
1683 |
|
|
{ |
1684 |
|
|
|
1685 |
|
|
if (n->type == ROFFT_BODY) |
1686 |
|
|
h->flags &= ~(HTML_KEEP | HTML_PREKEEP); |
1687 |
|
|
} |
1688 |
|
|
|
1689 |
|
|
static int |
1690 |
|
|
mdoc_quote_pre(MDOC_ARGS) |
1691 |
|
|
{ |
1692 |
|
|
if (n->type != ROFFT_BODY) |
1693 |
|
|
return 1; |
1694 |
|
|
|
1695 |
|
|
switch (n->tok) { |
1696 |
|
|
case MDOC_Ao: |
1697 |
|
|
case MDOC_Aq: |
1698 |
|
|
print_text(h, n->child != NULL && n->child->next == NULL && |
1699 |
|
|
n->child->tok == MDOC_Mt ? "<" : "\\(la"); |
1700 |
|
|
break; |
1701 |
|
|
case MDOC_Bro: |
1702 |
|
|
case MDOC_Brq: |
1703 |
|
|
print_text(h, "\\(lC"); |
1704 |
|
|
break; |
1705 |
|
|
case MDOC_Bo: |
1706 |
|
|
case MDOC_Bq: |
1707 |
|
|
print_text(h, "\\(lB"); |
1708 |
|
|
break; |
1709 |
|
|
case MDOC_Oo: |
1710 |
|
|
case MDOC_Op: |
1711 |
|
|
print_text(h, "\\(lB"); |
1712 |
|
|
h->flags |= HTML_NOSPACE; |
1713 |
|
|
print_otag(h, TAG_SPAN, "c", "Op"); |
1714 |
|
|
break; |
1715 |
|
|
case MDOC_En: |
1716 |
|
|
if (NULL == n->norm->Es || |
1717 |
|
|
NULL == n->norm->Es->child) |
1718 |
|
|
return 1; |
1719 |
|
|
print_text(h, n->norm->Es->child->string); |
1720 |
|
|
break; |
1721 |
|
|
case MDOC_Do: |
1722 |
|
|
case MDOC_Dq: |
1723 |
|
|
case MDOC_Qo: |
1724 |
|
|
case MDOC_Qq: |
1725 |
|
|
print_text(h, "\\(lq"); |
1726 |
|
|
break; |
1727 |
|
|
case MDOC_Po: |
1728 |
|
|
case MDOC_Pq: |
1729 |
|
|
print_text(h, "("); |
1730 |
|
|
break; |
1731 |
|
|
case MDOC_Ql: |
1732 |
|
|
print_text(h, "\\(oq"); |
1733 |
|
|
h->flags |= HTML_NOSPACE; |
1734 |
|
|
print_otag(h, TAG_CODE, "c", "Li"); |
1735 |
|
|
break; |
1736 |
|
|
case MDOC_So: |
1737 |
|
|
case MDOC_Sq: |
1738 |
|
|
print_text(h, "\\(oq"); |
1739 |
|
|
break; |
1740 |
|
|
default: |
1741 |
|
|
abort(); |
1742 |
|
|
} |
1743 |
|
|
|
1744 |
|
|
h->flags |= HTML_NOSPACE; |
1745 |
|
|
return 1; |
1746 |
|
|
} |
1747 |
|
|
|
1748 |
|
|
static void |
1749 |
|
|
mdoc_quote_post(MDOC_ARGS) |
1750 |
|
|
{ |
1751 |
|
|
|
1752 |
|
|
if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM) |
1753 |
|
|
return; |
1754 |
|
|
|
1755 |
|
|
h->flags |= HTML_NOSPACE; |
1756 |
|
|
|
1757 |
|
|
switch (n->tok) { |
1758 |
|
|
case MDOC_Ao: |
1759 |
|
|
case MDOC_Aq: |
1760 |
|
|
print_text(h, n->child != NULL && n->child->next == NULL && |
1761 |
|
|
n->child->tok == MDOC_Mt ? ">" : "\\(ra"); |
1762 |
|
|
break; |
1763 |
|
|
case MDOC_Bro: |
1764 |
|
|
case MDOC_Brq: |
1765 |
|
|
print_text(h, "\\(rC"); |
1766 |
|
|
break; |
1767 |
|
|
case MDOC_Oo: |
1768 |
|
|
case MDOC_Op: |
1769 |
|
|
case MDOC_Bo: |
1770 |
|
|
case MDOC_Bq: |
1771 |
|
|
print_text(h, "\\(rB"); |
1772 |
|
|
break; |
1773 |
|
|
case MDOC_En: |
1774 |
|
|
if (n->norm->Es == NULL || |
1775 |
|
|
n->norm->Es->child == NULL || |
1776 |
|
|
n->norm->Es->child->next == NULL) |
1777 |
|
|
h->flags &= ~HTML_NOSPACE; |
1778 |
|
|
else |
1779 |
|
|
print_text(h, n->norm->Es->child->next->string); |
1780 |
|
|
break; |
1781 |
|
|
case MDOC_Qo: |
1782 |
|
|
case MDOC_Qq: |
1783 |
|
|
case MDOC_Do: |
1784 |
|
|
case MDOC_Dq: |
1785 |
|
|
print_text(h, "\\(rq"); |
1786 |
|
|
break; |
1787 |
|
|
case MDOC_Po: |
1788 |
|
|
case MDOC_Pq: |
1789 |
|
|
print_text(h, ")"); |
1790 |
|
|
break; |
1791 |
|
|
case MDOC_Ql: |
1792 |
|
|
case MDOC_So: |
1793 |
|
|
case MDOC_Sq: |
1794 |
|
|
print_text(h, "\\(cq"); |
1795 |
|
|
break; |
1796 |
|
|
default: |
1797 |
|
|
abort(); |
1798 |
|
|
} |
1799 |
|
|
} |
1800 |
|
|
|
1801 |
|
|
static int |
1802 |
|
|
mdoc_eo_pre(MDOC_ARGS) |
1803 |
|
|
{ |
1804 |
|
|
|
1805 |
|
|
if (n->type != ROFFT_BODY) |
1806 |
|
|
return 1; |
1807 |
|
|
|
1808 |
|
|
if (n->end == ENDBODY_NOT && |
1809 |
|
|
n->parent->head->child == NULL && |
1810 |
|
|
n->child != NULL && |
1811 |
|
|
n->child->end != ENDBODY_NOT) |
1812 |
|
|
print_text(h, "\\&"); |
1813 |
|
|
else if (n->end != ENDBODY_NOT ? n->child != NULL : |
1814 |
|
|
n->parent->head->child != NULL && (n->child != NULL || |
1815 |
|
|
(n->parent->tail != NULL && n->parent->tail->child != NULL))) |
1816 |
|
|
h->flags |= HTML_NOSPACE; |
1817 |
|
|
return 1; |
1818 |
|
|
} |
1819 |
|
|
|
1820 |
|
|
static void |
1821 |
|
|
mdoc_eo_post(MDOC_ARGS) |
1822 |
|
|
{ |
1823 |
|
|
int body, tail; |
1824 |
|
|
|
1825 |
|
|
if (n->type != ROFFT_BODY) |
1826 |
|
|
return; |
1827 |
|
|
|
1828 |
|
|
if (n->end != ENDBODY_NOT) { |
1829 |
|
|
h->flags &= ~HTML_NOSPACE; |
1830 |
|
|
return; |
1831 |
|
|
} |
1832 |
|
|
|
1833 |
|
|
body = n->child != NULL || n->parent->head->child != NULL; |
1834 |
|
|
tail = n->parent->tail != NULL && n->parent->tail->child != NULL; |
1835 |
|
|
|
1836 |
|
|
if (body && tail) |
1837 |
|
|
h->flags |= HTML_NOSPACE; |
1838 |
|
|
else if ( ! tail) |
1839 |
|
|
h->flags &= ~HTML_NOSPACE; |
1840 |
|
|
} |