mandoc 0.0.1

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