]> git.cameronkatri.com Git - mandoc.git/blob - html.c
More html.
[mandoc.git] / html.c
1 /* $Id: html.c,v 1.32 2009/09/17 08:21:42 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #include <sys/queue.h>
18
19 #include <assert.h>
20 #include <err.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include "chars.h"
25 #include "mdoc.h"
26 #include "man.h"
27
28 #define DOCTYPE "-//W3C//DTD HTML 4.01//EN"
29 #define DTD "http://www.w3.org/TR/html4/strict.dtd"
30
31 enum htmltag {
32 TAG_HTML,
33 TAG_HEAD,
34 TAG_BODY,
35 TAG_META,
36 TAG_TITLE,
37 TAG_DIV,
38 TAG_H1,
39 TAG_H2,
40 TAG_P,
41 TAG_SPAN,
42 TAG_LINK,
43 TAG_BR,
44 TAG_A,
45 TAG_MAX
46 };
47
48 enum htmlattr {
49 ATTR_HTTPEQUIV,
50 ATTR_CONTENT,
51 ATTR_NAME,
52 ATTR_REL,
53 ATTR_HREF,
54 ATTR_TYPE,
55 ATTR_MEDIA,
56 ATTR_CLASS,
57 ATTR_MAX
58 };
59
60 struct htmldata {
61 char *name;
62 int flags;
63 #define HTML_CLRLINE (1 << 0)
64 #define HTML_NOSTACK (1 << 1)
65 };
66
67 static const struct htmldata htmltags[TAG_MAX] = {
68 {"html", HTML_CLRLINE}, /* TAG_HTML */
69 {"head", HTML_CLRLINE}, /* TAG_HEAD */
70 {"body", HTML_CLRLINE}, /* TAG_BODY */
71 {"meta", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_META */
72 {"title", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_TITLE */
73 {"div", HTML_CLRLINE}, /* TAG_DIV */
74 {"h1", 0}, /* TAG_H1 */
75 {"h2", 0}, /* TAG_H2 */
76 {"p", HTML_CLRLINE}, /* TAG_P */
77 {"span", 0}, /* TAG_SPAN */
78 {"link", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
79 {"br", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
80 {"a", 0}, /* TAG_A */
81 };
82
83 static const char *const htmlattrs[ATTR_MAX] = {
84 "http-equiv",
85 "content",
86 "name",
87 "rel",
88 "href",
89 "type",
90 "media",
91 "class"
92 };
93
94 struct htmlpair {
95 enum htmlattr key;
96 char *val;
97 };
98
99 struct tag {
100 enum htmltag tag;
101 SLIST_ENTRY(tag) entry;
102 };
103
104 SLIST_HEAD(tagq, tag);
105
106 struct html {
107 int flags;
108 #define HTML_NOSPACE (1 << 0)
109 #define HTML_NEWLINE (1 << 1)
110 struct tagq stack;
111 void *symtab;
112 };
113
114 #define MDOC_ARGS const struct mdoc_meta *m, \
115 const struct mdoc_node *n, \
116 struct html *h
117 #define MAN_ARGS const struct man_meta *m, \
118 const struct man_node *n, \
119 struct html *h
120 struct htmlmdoc {
121 int (*pre)(MDOC_ARGS);
122 void (*post)(MDOC_ARGS);
123 };
124
125 static void print_gen_doctype(struct html *);
126 static void print_gen_head(struct html *);
127 static void print_mdoc(MDOC_ARGS);
128 static void print_mdoc_head(MDOC_ARGS);
129 static void print_mdoc_title(MDOC_ARGS);
130 static void print_mdoc_node(MDOC_ARGS);
131 static void print_man(MAN_ARGS);
132 static void print_man_head(MAN_ARGS);
133 static void print_man_body(MAN_ARGS);
134 static struct tag *print_otag(struct html *, enum htmltag,
135 int, const struct htmlpair *);
136 static void print_tagq(struct html *, const struct tag *);
137 static void print_stagq(struct html *, const struct tag *);
138 static void print_ctag(struct html *, enum htmltag);
139 static void print_encode(struct html *, const char *);
140 static void print_escape(struct html *, const char **);
141 static void print_text(struct html *, const char *);
142 static void print_res(struct html *, const char *, int);
143 static void print_spec(struct html *, const char *, int);
144 static int mdoc_root_pre(MDOC_ARGS);
145
146 static int mdoc_ar_pre(MDOC_ARGS);
147 static int mdoc_fl_pre(MDOC_ARGS);
148 static int mdoc_nd_pre(MDOC_ARGS);
149 static int mdoc_nm_pre(MDOC_ARGS);
150 static int mdoc_ns_pre(MDOC_ARGS);
151 static int mdoc_op_pre(MDOC_ARGS);
152 static void mdoc_op_post(MDOC_ARGS);
153 static int mdoc_pp_pre(MDOC_ARGS);
154 static int mdoc_sh_pre(MDOC_ARGS);
155 static int mdoc_ss_pre(MDOC_ARGS);
156 static int mdoc_xr_pre(MDOC_ARGS);
157
158 static const struct htmlmdoc mdocs[MDOC_MAX] = {
159 {NULL, NULL}, /* Ap */
160 {NULL, NULL}, /* Dd */
161 {NULL, NULL}, /* Dt */
162 {NULL, NULL}, /* Os */
163 {mdoc_sh_pre, NULL }, /* Sh */
164 {mdoc_ss_pre, NULL }, /* Ss */
165 {mdoc_pp_pre, NULL}, /* Pp */
166 {NULL, NULL}, /* D1 */
167 {NULL, NULL}, /* Dl */
168 {NULL, NULL}, /* Bd */
169 {NULL, NULL}, /* Ed */
170 {NULL, NULL}, /* Bl */
171 {NULL, NULL}, /* El */
172 {NULL, NULL}, /* It */
173 {NULL, NULL}, /* Ad */
174 {NULL, NULL}, /* An */
175 {mdoc_ar_pre, NULL}, /* Ar */
176 {NULL, NULL}, /* Cd */
177 {NULL, NULL}, /* Cm */
178 {NULL, NULL}, /* Dv */
179 {NULL, NULL}, /* Er */
180 {NULL, NULL}, /* Ev */
181 {NULL, NULL}, /* Ex */
182 {NULL, NULL}, /* Fa */
183 {NULL, NULL}, /* Fd */
184 {mdoc_fl_pre, NULL}, /* Fl */
185 {NULL, NULL}, /* Fn */
186 {NULL, NULL}, /* Ft */
187 {NULL, NULL}, /* Ic */
188 {NULL, NULL}, /* In */
189 {NULL, NULL}, /* Li */
190 {mdoc_nd_pre, NULL}, /* Nd */
191 {mdoc_nm_pre, NULL}, /* Nm */
192 {mdoc_op_pre, mdoc_op_post}, /* Op */
193 {NULL, NULL}, /* Ot */
194 {NULL, NULL}, /* Pa */
195 {NULL, NULL}, /* Rv */
196 {NULL, NULL}, /* St */
197 {NULL, NULL}, /* Va */
198 {NULL, NULL}, /* Vt */
199 {mdoc_xr_pre, NULL}, /* Xr */
200 {NULL, NULL}, /* %A */
201 {NULL, NULL}, /* %B */
202 {NULL, NULL}, /* %D */
203 {NULL, NULL}, /* %I */
204 {NULL, NULL}, /* %J */
205 {NULL, NULL}, /* %N */
206 {NULL, NULL}, /* %O */
207 {NULL, NULL}, /* %P */
208 {NULL, NULL}, /* %R */
209 {NULL, NULL}, /* %T */
210 {NULL, NULL}, /* %V */
211 {NULL, NULL}, /* Ac */
212 {NULL, NULL}, /* Ao */
213 {NULL, NULL}, /* Aq */
214 {NULL, NULL}, /* At */
215 {NULL, NULL}, /* Bc */
216 {NULL, NULL}, /* Bf */
217 {NULL, NULL}, /* Bo */
218 {NULL, NULL}, /* Bq */
219 {NULL, NULL}, /* Bsx */
220 {NULL, NULL}, /* Bx */
221 {NULL, NULL}, /* Db */
222 {NULL, NULL}, /* Dc */
223 {NULL, NULL}, /* Do */
224 {NULL, NULL}, /* Dq */
225 {NULL, NULL}, /* Ec */
226 {NULL, NULL}, /* Ef */
227 {NULL, NULL}, /* Em */
228 {NULL, NULL}, /* Eo */
229 {NULL, NULL}, /* Fx */
230 {NULL, NULL}, /* Ms */
231 {NULL, NULL}, /* No */
232 {mdoc_ns_pre, NULL}, /* Ns */
233 {NULL, NULL}, /* Nx */
234 {NULL, NULL}, /* Ox */
235 {NULL, NULL}, /* Pc */
236 {NULL, NULL}, /* Pf */
237 {NULL, NULL}, /* Po */
238 {NULL, NULL}, /* Pq */
239 {NULL, NULL}, /* Qc */
240 {NULL, NULL}, /* Ql */
241 {NULL, NULL}, /* Qo */
242 {NULL, NULL}, /* Qq */
243 {NULL, NULL}, /* Re */
244 {NULL, NULL}, /* Rs */
245 {NULL, NULL}, /* Sc */
246 {NULL, NULL}, /* So */
247 {NULL, NULL}, /* Sq */
248 {NULL, NULL}, /* Sm */
249 {NULL, NULL}, /* Sx */
250 {NULL, NULL}, /* Sy */
251 {NULL, NULL}, /* Tn */
252 {NULL, NULL}, /* Ux */
253 {NULL, NULL}, /* Xc */
254 {NULL, NULL}, /* Xo */
255 {NULL, NULL}, /* Fo */
256 {NULL, NULL}, /* Fc */
257 {NULL, NULL}, /* Oo */
258 {NULL, NULL}, /* Oc */
259 {NULL, NULL}, /* Bk */
260 {NULL, NULL}, /* Ek */
261 {NULL, NULL}, /* Bt */
262 {NULL, NULL}, /* Hf */
263 {NULL, NULL}, /* Fr */
264 {NULL, NULL}, /* Ud */
265 {NULL, NULL}, /* Lb */
266 {NULL, NULL}, /* Lp */
267 {NULL, NULL}, /* Lk */
268 {NULL, NULL}, /* Mt */
269 {NULL, NULL}, /* Brq */
270 {NULL, NULL}, /* Bro */
271 {NULL, NULL}, /* Brc */
272 {NULL, NULL}, /* %C */
273 {NULL, NULL}, /* Es */
274 {NULL, NULL}, /* En */
275 {NULL, NULL}, /* Dx */
276 {NULL, NULL}, /* %Q */
277 {NULL, NULL}, /* br */
278 {NULL, NULL}, /* sp */
279 };
280
281 void
282 html_mdoc(void *arg, const struct mdoc *m)
283 {
284 struct html *h;
285 struct tag *t;
286
287 h = (struct html *)arg;
288
289 print_gen_doctype(h);
290 t = print_otag(h, TAG_HTML, 0, NULL);
291 print_mdoc(mdoc_meta(m), mdoc_node(m), h);
292 print_tagq(h, t);
293
294 printf("\n");
295 }
296
297 void
298 html_man(void *arg, const struct man *m)
299 {
300 struct html *h;
301 struct tag *t;
302
303 h = (struct html *)arg;
304
305 print_gen_doctype(h);
306 t = print_otag(h, TAG_HTML, 0, NULL);
307 print_man(man_meta(m), man_node(m), h);
308 print_tagq(h, t);
309
310 printf("\n");
311 }
312
313 void *
314 html_alloc(void)
315 {
316 struct html *h;
317
318 if (NULL == (h = calloc(1, sizeof(struct html))))
319 return(NULL);
320
321 SLIST_INIT(&h->stack);
322 if (NULL == (h->symtab = chars_init(CHARS_HTML))) {
323 free(h);
324 return(NULL);
325 }
326 return(h);
327 }
328
329 void
330 html_free(void *p)
331 {
332 struct tag *tag;
333 struct html *h;
334
335 h = (struct html *)p;
336
337 while ( ! SLIST_EMPTY(&h->stack)) {
338 tag = SLIST_FIRST(&h->stack);
339 SLIST_REMOVE_HEAD(&h->stack, entry);
340 free(tag);
341 }
342 free(h);
343 }
344
345 static void
346 print_mdoc(MDOC_ARGS)
347 {
348 struct tag *t;
349
350 t = print_otag(h, TAG_HEAD, 0, NULL);
351 print_mdoc_head(m, n, h);
352 print_tagq(h, t);
353
354 t = print_otag(h, TAG_BODY, 0, NULL);
355 print_mdoc_title(m, n, h);
356 print_mdoc_node(m, n, h);
357 print_tagq(h, t);
358 }
359
360 static void
361 print_gen_head(struct html *h)
362 {
363 struct htmlpair meta0[2];
364 struct htmlpair meta1[2];
365 struct htmlpair link[4];
366
367 meta0[0].key = ATTR_HTTPEQUIV;
368 meta0[0].val = "Content-Type";
369 meta0[1].key = ATTR_CONTENT;
370 meta0[1].val = "text/html; charest-utf-8";
371
372 meta1[0].key = ATTR_NAME;
373 meta1[0].val = "resource-type";
374 meta1[1].key = ATTR_CONTENT;
375 meta1[1].val = "document";
376
377 link[0].key = ATTR_REL;
378 link[0].val = "stylesheet";
379 link[1].key = ATTR_HREF;
380 link[1].val = "style.css"; /* XXX */
381 link[2].key = ATTR_TYPE;
382 link[2].val = "text/css";
383 link[3].key = ATTR_MEDIA;
384 link[3].val = "all";
385
386 print_otag(h, TAG_META, 2, meta0);
387 print_otag(h, TAG_META, 2, meta1);
388 print_otag(h, TAG_LINK, 4, link);
389 }
390
391 /* ARGSUSED */
392 static void
393 print_mdoc_head(MDOC_ARGS)
394 {
395
396 print_gen_head(h);
397 print_otag(h, TAG_TITLE, 0, NULL);
398 print_encode(h, m->title);
399 }
400
401 /* ARGSUSED */
402 static void
403 print_mdoc_title(MDOC_ARGS)
404 {
405
406 /* TODO */
407 }
408
409 static void
410 print_mdoc_node(MDOC_ARGS)
411 {
412 int child;
413 struct tag *t;
414
415 child = 1;
416 t = SLIST_FIRST(&h->stack);
417
418 switch (n->type) {
419 case (MDOC_ROOT):
420 child = mdoc_root_pre(m, n, h);
421 break;
422 case (MDOC_TEXT):
423 print_text(h, n->string);
424 break;
425 default:
426 if (mdocs[n->tok].pre)
427 child = (*mdocs[n->tok].pre)(m, n, h);
428 break;
429 }
430
431 if (child && n->child)
432 print_mdoc_node(m, n->child, h);
433
434 print_stagq(h, t);
435
436 switch (n->type) {
437 case (MDOC_ROOT):
438 break;
439 case (MDOC_TEXT):
440 break;
441 default:
442 if (mdocs[n->tok].post)
443 (*mdocs[n->tok].post)(m, n, h);
444 break;
445 }
446
447 if (n->next)
448 print_mdoc_node(m, n->next, h);
449 }
450
451 static void
452 print_man(MAN_ARGS)
453 {
454 struct tag *t;
455
456 t = print_otag(h, TAG_HEAD, 0, NULL);
457 print_man_head(m, n, h);
458 print_tagq(h, t);
459
460 t = print_otag(h, TAG_BODY, 0, NULL);
461 print_man_body(m, n, h);
462 print_tagq(h, t);
463 }
464
465 /* ARGSUSED */
466 static void
467 print_man_head(MAN_ARGS)
468 {
469
470 print_gen_head(h);
471 print_otag(h, TAG_TITLE, 0, NULL);
472 print_encode(h, m->title);
473 }
474
475 /* ARGSUSED */
476 static void
477 print_man_body(MAN_ARGS)
478 {
479
480 /* TODO */
481 }
482
483 static void
484 print_spec(struct html *h, const char *p, int len)
485 {
486 const char *rhs;
487 int i;
488 size_t sz;
489
490 rhs = chars_a2ascii(h->symtab, p, (size_t)len, &sz);
491
492 if (NULL == rhs)
493 return;
494 for (i = 0; i < (int)sz; i++)
495 putchar(rhs[i]);
496 }
497
498 static void
499 print_res(struct html *h, const char *p, int len)
500 {
501 const char *rhs;
502 int i;
503 size_t sz;
504
505 rhs = chars_a2res(h->symtab, p, (size_t)len, &sz);
506
507 if (NULL == rhs)
508 return;
509 for (i = 0; i < (int)sz; i++)
510 putchar(rhs[i]);
511 }
512
513 static void
514 print_escape(struct html *h, const char **p)
515 {
516 int j, type;
517 const char *wp;
518
519 wp = *p;
520 type = 1;
521
522 if (0 == *(++wp)) {
523 *p = wp;
524 return;
525 }
526
527 if ('(' == *wp) {
528 wp++;
529 if (0 == *wp || 0 == *(wp + 1)) {
530 *p = 0 == *wp ? wp : wp + 1;
531 return;
532 }
533
534 print_spec(h, wp, 2);
535 *p = ++wp;
536 return;
537
538 } else if ('*' == *wp) {
539 if (0 == *(++wp)) {
540 *p = wp;
541 return;
542 }
543
544 switch (*wp) {
545 case ('('):
546 wp++;
547 if (0 == *wp || 0 == *(wp + 1)) {
548 *p = 0 == *wp ? wp : wp + 1;
549 return;
550 }
551
552 print_res(h, wp, 2);
553 *p = ++wp;
554 return;
555 case ('['):
556 type = 0;
557 break;
558 default:
559 print_res(h, wp, 1);
560 *p = wp;
561 return;
562 }
563
564 } else if ('f' == *wp) {
565 if (0 == *(++wp)) {
566 *p = wp;
567 return;
568 }
569
570 switch (*wp) {
571 case ('B'):
572 /* TODO */
573 break;
574 case ('I'):
575 /* TODO */
576 break;
577 case ('P'):
578 /* FALLTHROUGH */
579 case ('R'):
580 /* TODO */
581 break;
582 default:
583 break;
584 }
585
586 *p = wp;
587 return;
588
589 } else if ('[' != *wp) {
590 print_spec(h, wp, 1);
591 *p = wp;
592 return;
593 }
594
595 wp++;
596 for (j = 0; *wp && ']' != *wp; wp++, j++)
597 /* Loop... */ ;
598
599 if (0 == *wp) {
600 *p = wp;
601 return;
602 }
603
604 if (type)
605 print_spec(h, wp - j, j);
606 else
607 print_res(h, wp - j, j);
608
609 *p = wp;
610 }
611
612
613 static void
614 print_encode(struct html *h, const char *p)
615 {
616
617 for (; *p; p++) {
618 if ('\\' != *p) {
619 putchar(*p);
620 continue;
621 }
622 print_escape(h, &p);
623 }
624 }
625
626
627 static struct tag *
628 print_otag(struct html *h, enum htmltag tag,
629 int sz, const struct htmlpair *p)
630 {
631 int i;
632 struct tag *t;
633
634 if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
635 if (NULL == (t = malloc(sizeof(struct tag))))
636 err(EXIT_FAILURE, "malloc");
637 t->tag = tag;
638 SLIST_INSERT_HEAD(&h->stack, t, entry);
639 } else
640 t = NULL;
641
642 if ( ! (HTML_NOSPACE & h->flags))
643 if ( ! (HTML_CLRLINE & htmltags[tag].flags))
644 printf(" ");
645
646 printf("<%s", htmltags[tag].name);
647 for (i = 0; i < sz; i++) {
648 printf(" %s=\"", htmlattrs[p[i].key]);
649 assert(p->val);
650 print_encode(h, p[i].val);
651 printf("\"");
652 }
653 printf(">");
654
655 h->flags |= HTML_NOSPACE;
656 if (HTML_CLRLINE & htmltags[tag].flags)
657 h->flags |= HTML_NEWLINE;
658 else
659 h->flags &= ~HTML_NEWLINE;
660
661 return(t);
662 }
663
664
665 /* ARGSUSED */
666 static void
667 print_ctag(struct html *h, enum htmltag tag)
668 {
669
670 printf("</%s>", htmltags[tag].name);
671 if (HTML_CLRLINE & htmltags[tag].flags)
672 h->flags |= HTML_NOSPACE;
673 if (HTML_CLRLINE & htmltags[tag].flags)
674 h->flags |= HTML_NEWLINE;
675 else
676 h->flags &= ~HTML_NEWLINE;
677 }
678
679
680 /* ARGSUSED */
681 static void
682 print_gen_doctype(struct html *h)
683 {
684
685 printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">\n", DOCTYPE, DTD);
686 }
687
688
689 static void
690 print_text(struct html *h, const char *p)
691 {
692
693 if (*p && 0 == *(p + 1))
694 switch (*p) {
695 case('.'):
696 /* FALLTHROUGH */
697 case(','):
698 /* FALLTHROUGH */
699 case(';'):
700 /* FALLTHROUGH */
701 case(':'):
702 /* FALLTHROUGH */
703 case('?'):
704 /* FALLTHROUGH */
705 case('!'):
706 /* FALLTHROUGH */
707 case(')'):
708 /* FALLTHROUGH */
709 case(']'):
710 /* FALLTHROUGH */
711 case('}'):
712 h->flags |= HTML_NOSPACE;
713 break;
714 default:
715 break;
716 }
717
718 if ( ! (h->flags & HTML_NOSPACE))
719 printf(" ");
720
721 h->flags &= ~HTML_NOSPACE;
722 h->flags &= ~HTML_NEWLINE;
723
724 if (p)
725 print_encode(h, p);
726
727 if (*p && 0 == *(p + 1))
728 switch (*p) {
729 case('('):
730 /* FALLTHROUGH */
731 case('['):
732 /* FALLTHROUGH */
733 case('{'):
734 h->flags |= HTML_NOSPACE;
735 break;
736 default:
737 break;
738 }
739 }
740
741
742 static void
743 print_tagq(struct html *h, const struct tag *until)
744 {
745 struct tag *tag;
746
747 while ( ! SLIST_EMPTY(&h->stack)) {
748 tag = SLIST_FIRST(&h->stack);
749 print_ctag(h, tag->tag);
750 SLIST_REMOVE_HEAD(&h->stack, entry);
751 free(tag);
752 if (until && tag == until)
753 return;
754 }
755 }
756
757
758 static void
759 print_stagq(struct html *h, const struct tag *suntil)
760 {
761 struct tag *tag;
762
763 while ( ! SLIST_EMPTY(&h->stack)) {
764 tag = SLIST_FIRST(&h->stack);
765 if (suntil && tag == suntil)
766 return;
767 print_ctag(h, tag->tag);
768 SLIST_REMOVE_HEAD(&h->stack, entry);
769 free(tag);
770 }
771 }
772
773
774 /* ARGSUSED */
775 static int
776 mdoc_root_pre(MDOC_ARGS)
777 {
778 struct htmlpair tag;
779
780 tag.key = ATTR_CLASS;
781 tag.val = "body";
782
783 print_otag(h, TAG_DIV, 1, &tag);
784 return(1);
785 }
786
787
788 /* ARGSUSED */
789 static int
790 mdoc_ss_pre(MDOC_ARGS)
791 {
792
793 if (MDOC_BODY == n->type)
794 print_otag(h, TAG_P, 0, NULL);
795 if (MDOC_HEAD == n->type)
796 print_otag(h, TAG_H2, 0, NULL);
797 return(1);
798 }
799
800
801 /* ARGSUSED */
802 static int
803 mdoc_fl_pre(MDOC_ARGS)
804 {
805 struct htmlpair tag;
806
807 tag.key = ATTR_CLASS;
808 tag.val = "flag";
809
810 print_otag(h, TAG_SPAN, 1, &tag);
811 print_text(h, "\\-");
812 h->flags |= HTML_NOSPACE;
813 return(1);
814 }
815
816
817 /* ARGSUSED */
818 static int
819 mdoc_pp_pre(MDOC_ARGS)
820 {
821
822 print_otag(h, TAG_BR, 0, NULL);
823 print_otag(h, TAG_BR, 0, NULL);
824 return(0);
825 }
826
827
828 /* ARGSUSED */
829 static int
830 mdoc_nd_pre(MDOC_ARGS)
831 {
832
833 if (MDOC_BODY == n->type)
834 print_text(h, "\\(en");
835 return(1);
836 }
837
838
839 /* ARGSUSED */
840 static int
841 mdoc_op_pre(MDOC_ARGS)
842 {
843
844 if (MDOC_BODY == n->type) {
845 print_text(h, "\\(lB");
846 h->flags |= HTML_NOSPACE;
847 }
848 return(1);
849 }
850
851
852 /* ARGSUSED */
853 static void
854 mdoc_op_post(MDOC_ARGS)
855 {
856
857 if (MDOC_BODY != n->type)
858 return;
859 h->flags |= HTML_NOSPACE;
860 print_text(h, "\\(rB");
861 }
862
863
864 static int
865 mdoc_nm_pre(MDOC_ARGS)
866 {
867 struct htmlpair class;
868
869 if ( ! (HTML_NEWLINE & h->flags))
870 if (SEC_SYNOPSIS == n->sec)
871 print_otag(h, TAG_BR, 0, NULL);
872
873 class.key = ATTR_CLASS;
874 class.val = "name";
875
876 print_otag(h, TAG_SPAN, 1, &class);
877 if (NULL == n->child)
878 print_text(h, m->name);
879
880 return(1);
881 }
882
883
884 /* ARGSUSED */
885 static int
886 mdoc_sh_pre(MDOC_ARGS)
887 {
888
889 if (MDOC_BODY == n->type)
890 print_otag(h, TAG_P, 0, NULL);
891 if (MDOC_HEAD == n->type)
892 print_otag(h, TAG_H1, 0, NULL);
893 return(1);
894 }
895
896
897 /* ARGSUSED */
898 static int
899 mdoc_xr_pre(MDOC_ARGS)
900 {
901 struct htmlpair tag;
902
903 tag.key = ATTR_HREF;
904 tag.val = "#"; /* TODO */
905
906 print_otag(h, TAG_A, 1, &tag);
907
908 n = n->child;
909 print_text(h, n->string);
910 if (NULL == (n = n->next))
911 return(0);
912
913 h->flags |= HTML_NOSPACE;
914 print_text(h, "(");
915 h->flags |= HTML_NOSPACE;
916 print_text(h, n->string);
917 h->flags |= HTML_NOSPACE;
918 print_text(h, ")");
919
920 return(0);
921 }
922
923
924 /* ARGSUSED */
925 static int
926 mdoc_ns_pre(MDOC_ARGS)
927 {
928
929 h->flags |= HTML_NOSPACE;
930 return(1);
931 }
932
933
934 /* ARGSUSED */
935 static int
936 mdoc_ar_pre(MDOC_ARGS)
937 {
938 struct htmlpair tag;
939
940 tag.key = ATTR_CLASS;
941 tag.val = "arg";
942
943 print_otag(h, TAG_SPAN, 1, &tag);
944 return(1);
945 }