Annotation of src/usr.bin/mandoc/man_html.c, Revision 1.84
1.84 ! schwarze 1: /* $OpenBSD: man_html.c,v 1.83 2017/01/26 18:28:04 schwarze Exp $ */
1.1 schwarze 2: /*
1.56 schwarze 3: * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
1.75 schwarze 4: * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 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: *
1.66 schwarze 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
1.1 schwarze 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1.66 schwarze 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
1.1 schwarze 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:
1.53 schwarze 26: #include "mandoc_aux.h"
1.66 schwarze 27: #include "roff.h"
1.58 schwarze 28: #include "man.h"
1.1 schwarze 29: #include "out.h"
30: #include "html.h"
31: #include "main.h"
32:
1.2 schwarze 33: /* FIXME: have PD set the default vspace width. */
1.1 schwarze 34:
35: #define INDENT 5
36:
1.68 schwarze 37: #define MAN_ARGS const struct roff_meta *man, \
1.67 schwarze 38: const struct roff_node *n, \
1.18 schwarze 39: struct mhtml *mh, \
1.1 schwarze 40: struct html *h
41:
1.18 schwarze 42: struct mhtml {
1.83 schwarze 43: struct tag *nofill;
1.18 schwarze 44: };
45:
1.1 schwarze 46: struct htmlman {
47: int (*pre)(MAN_ARGS);
48: int (*post)(MAN_ARGS);
49: };
50:
1.52 schwarze 51: static void print_bvspace(struct html *,
1.67 schwarze 52: const struct roff_node *);
1.1 schwarze 53: static void print_man_head(MAN_ARGS);
54: static void print_man_nodelist(MAN_ARGS);
55: static void print_man_node(MAN_ARGS);
1.67 schwarze 56: static int a2width(const struct roff_node *,
1.1 schwarze 57: struct roffsu *);
58: static int man_B_pre(MAN_ARGS);
59: static int man_HP_pre(MAN_ARGS);
1.46 schwarze 60: static int man_IP_pre(MAN_ARGS);
1.1 schwarze 61: static int man_I_pre(MAN_ARGS);
1.46 schwarze 62: static int man_OP_pre(MAN_ARGS);
1.1 schwarze 63: static int man_PP_pre(MAN_ARGS);
64: static int man_RS_pre(MAN_ARGS);
65: static int man_SH_pre(MAN_ARGS);
66: static int man_SM_pre(MAN_ARGS);
67: static int man_SS_pre(MAN_ARGS);
1.49 schwarze 68: static int man_UR_pre(MAN_ARGS);
1.46 schwarze 69: static int man_alt_pre(MAN_ARGS);
70: static int man_br_pre(MAN_ARGS);
1.83 schwarze 71: static int man_fill_pre(MAN_ARGS);
1.46 schwarze 72: static int man_ign_pre(MAN_ARGS);
73: static int man_in_pre(MAN_ARGS);
74: static void man_root_post(MAN_ARGS);
75: static void man_root_pre(MAN_ARGS);
1.1 schwarze 76:
77: static const struct htmlman mans[MAN_MAX] = {
78: { man_br_pre, NULL }, /* br */
79: { NULL, NULL }, /* TH */
80: { man_SH_pre, NULL }, /* SH */
81: { man_SS_pre, NULL }, /* SS */
82: { man_IP_pre, NULL }, /* TP */
83: { man_PP_pre, NULL }, /* LP */
84: { man_PP_pre, NULL }, /* PP */
85: { man_PP_pre, NULL }, /* P */
86: { man_IP_pre, NULL }, /* IP */
1.52 schwarze 87: { man_HP_pre, NULL }, /* HP */
1.1 schwarze 88: { man_SM_pre, NULL }, /* SM */
1.26 schwarze 89: { man_SM_pre, NULL }, /* SB */
1.1 schwarze 90: { man_alt_pre, NULL }, /* BI */
91: { man_alt_pre, NULL }, /* IB */
92: { man_alt_pre, NULL }, /* BR */
93: { man_alt_pre, NULL }, /* RB */
94: { NULL, NULL }, /* R */
95: { man_B_pre, NULL }, /* B */
96: { man_I_pre, NULL }, /* I */
97: { man_alt_pre, NULL }, /* IR */
98: { man_alt_pre, NULL }, /* RI */
99: { man_br_pre, NULL }, /* sp */
1.83 schwarze 100: { man_fill_pre, NULL }, /* nf */
101: { man_fill_pre, NULL }, /* fi */
1.1 schwarze 102: { NULL, NULL }, /* RE */
103: { man_RS_pre, NULL }, /* RS */
104: { man_ign_pre, NULL }, /* DT */
105: { man_ign_pre, NULL }, /* UC */
1.2 schwarze 106: { man_ign_pre, NULL }, /* PD */
1.13 schwarze 107: { man_ign_pre, NULL }, /* AT */
1.18 schwarze 108: { man_in_pre, NULL }, /* in */
1.23 schwarze 109: { man_ign_pre, NULL }, /* ft */
1.46 schwarze 110: { man_OP_pre, NULL }, /* OP */
1.83 schwarze 111: { man_fill_pre, NULL }, /* EX */
112: { man_fill_pre, NULL }, /* EE */
1.49 schwarze 113: { man_UR_pre, NULL }, /* UR */
114: { NULL, NULL }, /* UE */
1.51 schwarze 115: { man_ign_pre, NULL }, /* ll */
1.1 schwarze 116: };
117:
1.52 schwarze 118:
1.39 schwarze 119: /*
120: * Printing leading vertical space before a block.
121: * This is used for the paragraph macros.
122: * The rules are pretty simple, since there's very little nesting going
123: * on here. Basically, if we're the first within another block (SS/SH),
124: * then don't emit vertical space. If we are (RS), then do. If not the
125: * first, print it.
126: */
127: static void
1.67 schwarze 128: print_bvspace(struct html *h, const struct roff_node *n)
1.39 schwarze 129: {
130:
131: if (n->body && n->body->child)
1.66 schwarze 132: if (n->body->child->type == ROFFT_TBL)
1.39 schwarze 133: return;
134:
1.66 schwarze 135: if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
1.39 schwarze 136: if (NULL == n->prev)
137: return;
138:
1.56 schwarze 139: print_paragraph(h);
1.39 schwarze 140: }
1.1 schwarze 141:
142: void
1.69 schwarze 143: html_man(void *arg, const struct roff_man *man)
1.1 schwarze 144: {
1.18 schwarze 145: struct mhtml mh;
1.70 schwarze 146: struct html *h;
1.79 schwarze 147: struct tag *t;
1.43 schwarze 148:
1.83 schwarze 149: mh.nofill = NULL;
1.70 schwarze 150: h = (struct html *)arg;
1.1 schwarze 151:
1.79 schwarze 152: if ((h->oflags & HTML_FRAGMENT) == 0) {
1.43 schwarze 153: print_gen_decls(h);
1.79 schwarze 154: print_otag(h, TAG_HTML, "");
155: t = print_otag(h, TAG_HEAD, "");
1.70 schwarze 156: print_man_head(&man->meta, man->first, &mh, h);
1.79 schwarze 157: print_tagq(h, t);
1.75 schwarze 158: print_otag(h, TAG_BODY, "");
1.79 schwarze 159: }
1.25 schwarze 160:
1.80 schwarze 161: man_root_pre(&man->meta, man->first, &mh, h);
162: t = print_otag(h, TAG_DIV, "c", "manual-text");
163: print_man_nodelist(&man->meta, man->first->child, &mh, h);
164: print_tagq(h, t);
165: man_root_post(&man->meta, man->first, &mh, h);
1.79 schwarze 166: print_tagq(h, NULL);
1.1 schwarze 167: }
168:
169: static void
170: print_man_head(MAN_ARGS)
171: {
1.76 schwarze 172: char *cp;
1.1 schwarze 173:
174: print_gen_head(h);
1.76 schwarze 175: mandoc_asprintf(&cp, "%s(%s)", man->title, man->msec);
1.75 schwarze 176: print_otag(h, TAG_TITLE, "");
1.76 schwarze 177: print_text(h, cp);
178: free(cp);
1.1 schwarze 179: }
180:
181: static void
182: print_man_nodelist(MAN_ARGS)
183: {
184:
1.63 schwarze 185: while (n != NULL) {
186: print_man_node(man, n, mh, h);
187: n = n->next;
188: }
1.1 schwarze 189: }
190:
191: static void
192: print_man_node(MAN_ARGS)
193: {
194: int child;
195: struct tag *t;
196:
197: child = 1;
1.84 ! schwarze 198: t = h->tag;
1.83 schwarze 199: if (t == mh->nofill)
200: t = t->next;
1.1 schwarze 201:
202: switch (n->type) {
1.66 schwarze 203: case ROFFT_TEXT:
1.31 schwarze 204: if ('\0' == *n->string) {
1.56 schwarze 205: print_paragraph(h);
1.31 schwarze 206: return;
1.40 schwarze 207: }
1.83 schwarze 208: if (mh->nofill == NULL &&
209: n->flags & NODE_LINE && *n->string == ' ')
1.75 schwarze 210: print_otag(h, TAG_BR, "");
1.1 schwarze 211: print_text(h, n->string);
1.83 schwarze 212: break;
1.66 schwarze 213: case ROFFT_EQN:
1.41 schwarze 214: print_eqn(h, n->eqn);
1.37 schwarze 215: break;
1.66 schwarze 216: case ROFFT_TBL:
1.33 schwarze 217: /*
218: * This will take care of initialising all of the table
219: * state data for the first table, then tearing it down
220: * for the last one.
221: */
1.29 schwarze 222: print_tbl(h, n->span);
1.32 schwarze 223: return;
1.1 schwarze 224: default:
1.52 schwarze 225: /*
1.4 schwarze 226: * Close out scope of font prior to opening a macro
1.33 schwarze 227: * scope.
1.4 schwarze 228: */
1.27 schwarze 229: if (HTMLFONT_NONE != h->metac) {
230: h->metal = h->metac;
231: h->metac = HTMLFONT_NONE;
1.33 schwarze 232: }
233:
234: /*
235: * Close out the current table, if it's open, and unset
236: * the "meta" table state. This will be reopened on the
237: * next table element.
238: */
239: if (h->tblt) {
240: print_tblclose(h);
1.84 ! schwarze 241: t = h->tag;
1.4 schwarze 242: }
1.1 schwarze 243: if (mans[n->tok].pre)
1.48 schwarze 244: child = (*mans[n->tok].pre)(man, n, mh, h);
1.1 schwarze 245: break;
246: }
247:
248: if (child && n->child)
1.48 schwarze 249: print_man_nodelist(man, n->child, mh, h);
1.1 schwarze 250:
1.4 schwarze 251: /* This will automatically close out any font scope. */
1.83 schwarze 252: print_stagq(h, mh->nofill == NULL ? t : mh->nofill);
1.1 schwarze 253:
1.83 schwarze 254: if (n->type != ROFFT_TEXT && n->type != ROFFT_EQN &&
255: mans[n->tok].post != NULL)
256: (*mans[n->tok].post)(man, n, mh, h);
257:
258: if (mh->nofill != NULL &&
259: (n->next == NULL || n->next->flags & NODE_LINE))
260: print_endline(h);
1.1 schwarze 261: }
262:
263: static int
1.67 schwarze 264: a2width(const struct roff_node *n, struct roffsu *su)
1.1 schwarze 265: {
266:
1.66 schwarze 267: if (n->type != ROFFT_TEXT)
1.72 schwarze 268: return 0;
1.60 schwarze 269: if (a2roffsu(n->string, su, SCALE_EN))
1.72 schwarze 270: return 1;
1.1 schwarze 271:
1.72 schwarze 272: return 0;
1.1 schwarze 273: }
274:
1.38 schwarze 275: static void
1.1 schwarze 276: man_root_pre(MAN_ARGS)
277: {
278: struct tag *t, *tt;
1.53 schwarze 279: char *title;
1.1 schwarze 280:
1.48 schwarze 281: assert(man->title);
282: assert(man->msec);
1.53 schwarze 283: mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
1.1 schwarze 284:
1.75 schwarze 285: t = print_otag(h, TAG_TABLE, "c", "head");
286: print_otag(h, TAG_TBODY, "");
287: tt = print_otag(h, TAG_TR, "");
1.1 schwarze 288:
1.75 schwarze 289: print_otag(h, TAG_TD, "c", "head-ltitle");
1.1 schwarze 290: print_text(h, title);
291: print_stagq(h, tt);
292:
1.75 schwarze 293: print_otag(h, TAG_TD, "c", "head-vol");
1.54 schwarze 294: if (NULL != man->vol)
295: print_text(h, man->vol);
1.1 schwarze 296: print_stagq(h, tt);
297:
1.75 schwarze 298: print_otag(h, TAG_TD, "c", "head-rtitle");
1.1 schwarze 299: print_text(h, title);
300: print_tagq(h, t);
1.53 schwarze 301: free(title);
1.1 schwarze 302: }
303:
304: static void
305: man_root_post(MAN_ARGS)
306: {
307: struct tag *t, *tt;
308:
1.75 schwarze 309: t = print_otag(h, TAG_TABLE, "c", "foot");
310: tt = print_otag(h, TAG_TR, "");
1.25 schwarze 311:
1.75 schwarze 312: print_otag(h, TAG_TD, "c", "foot-date");
1.48 schwarze 313: print_text(h, man->date);
1.1 schwarze 314: print_stagq(h, tt);
315:
1.75 schwarze 316: print_otag(h, TAG_TD, "c", "foot-os");
1.68 schwarze 317: if (man->os)
318: print_text(h, man->os);
1.1 schwarze 319: print_tagq(h, t);
320: }
321:
322:
323: static int
324: man_br_pre(MAN_ARGS)
325: {
326: struct roffsu su;
327:
328: SCALE_VS_INIT(&su, 1);
329:
1.21 schwarze 330: if (MAN_sp == n->tok) {
1.39 schwarze 331: if (NULL != (n = n->child))
332: if ( ! a2roffsu(n->string, &su, SCALE_VS))
1.61 schwarze 333: su.scale = 1.0;
1.21 schwarze 334: } else
1.55 schwarze 335: su.scale = 0.0;
1.1 schwarze 336:
1.75 schwarze 337: print_otag(h, TAG_DIV, "suh", &su);
1.4 schwarze 338:
1.3 schwarze 339: /* So the div isn't empty: */
340: print_text(h, "\\~");
341:
1.72 schwarze 342: return 0;
1.1 schwarze 343: }
344:
345: static int
346: man_SH_pre(MAN_ARGS)
347: {
1.83 schwarze 348: if (n->type == ROFFT_BLOCK && mh->nofill != NULL) {
349: print_tagq(h, mh->nofill);
350: mh->nofill = NULL;
351: } else if (n->type == ROFFT_HEAD)
352: print_otag(h, TAG_H1, "c", "Sh");
1.72 schwarze 353: return 1;
1.1 schwarze 354: }
355:
356: static int
357: man_alt_pre(MAN_ARGS)
358: {
1.67 schwarze 359: const struct roff_node *nn;
1.83 schwarze 360: int i;
1.27 schwarze 361: enum htmltag fp;
362: struct tag *t;
1.1 schwarze 363:
364: for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
365: switch (n->tok) {
1.52 schwarze 366: case MAN_BI:
1.27 schwarze 367: fp = i % 2 ? TAG_I : TAG_B;
1.1 schwarze 368: break;
1.52 schwarze 369: case MAN_IB:
1.27 schwarze 370: fp = i % 2 ? TAG_B : TAG_I;
1.1 schwarze 371: break;
1.52 schwarze 372: case MAN_RI:
1.27 schwarze 373: fp = i % 2 ? TAG_I : TAG_MAX;
1.1 schwarze 374: break;
1.52 schwarze 375: case MAN_IR:
1.27 schwarze 376: fp = i % 2 ? TAG_MAX : TAG_I;
1.1 schwarze 377: break;
1.52 schwarze 378: case MAN_BR:
1.27 schwarze 379: fp = i % 2 ? TAG_MAX : TAG_B;
1.1 schwarze 380: break;
1.52 schwarze 381: case MAN_RB:
1.27 schwarze 382: fp = i % 2 ? TAG_B : TAG_MAX;
1.1 schwarze 383: break;
384: default:
385: abort();
386: }
387:
388: if (i)
389: h->flags |= HTML_NOSPACE;
390:
1.83 schwarze 391: if (fp != TAG_MAX)
1.75 schwarze 392: t = print_otag(h, fp, "");
1.27 schwarze 393:
1.83 schwarze 394: print_text(h, nn->string);
1.27 schwarze 395:
1.83 schwarze 396: if (fp != TAG_MAX)
1.27 schwarze 397: print_tagq(h, t);
1.1 schwarze 398: }
1.72 schwarze 399: return 0;
1.1 schwarze 400: }
401:
402: static int
1.26 schwarze 403: man_SM_pre(MAN_ARGS)
1.1 schwarze 404: {
1.75 schwarze 405: print_otag(h, TAG_SMALL, "");
1.26 schwarze 406: if (MAN_SB == n->tok)
1.75 schwarze 407: print_otag(h, TAG_B, "");
1.72 schwarze 408: return 1;
1.1 schwarze 409: }
410:
411: static int
412: man_SS_pre(MAN_ARGS)
413: {
1.83 schwarze 414: if (n->type == ROFFT_BLOCK && mh->nofill != NULL) {
415: print_tagq(h, mh->nofill);
416: mh->nofill = NULL;
417: } else if (n->type == ROFFT_HEAD)
418: print_otag(h, TAG_H2, "c", "Ss");
1.72 schwarze 419: return 1;
1.1 schwarze 420: }
421:
422: static int
423: man_PP_pre(MAN_ARGS)
424: {
425:
1.66 schwarze 426: if (n->type == ROFFT_HEAD)
1.72 schwarze 427: return 0;
1.66 schwarze 428: else if (n->type == ROFFT_BLOCK)
1.39 schwarze 429: print_bvspace(h, n);
1.22 schwarze 430:
1.72 schwarze 431: return 1;
1.1 schwarze 432: }
433:
434: static int
435: man_IP_pre(MAN_ARGS)
436: {
1.67 schwarze 437: const struct roff_node *nn;
1.1 schwarze 438:
1.66 schwarze 439: if (n->type == ROFFT_BODY) {
1.82 schwarze 440: print_otag(h, TAG_DD, "c", "It-tag");
1.72 schwarze 441: return 1;
1.66 schwarze 442: } else if (n->type != ROFFT_HEAD) {
1.82 schwarze 443: print_otag(h, TAG_DL, "c", "Bl-tag");
1.72 schwarze 444: return 1;
1.1 schwarze 445: }
446:
1.40 schwarze 447: /* FIXME: width specification. */
1.7 schwarze 448:
1.82 schwarze 449: print_otag(h, TAG_DT, "c", "It-tag");
1.1 schwarze 450:
1.28 schwarze 451: /* For IP, only print the first header element. */
1.1 schwarze 452:
1.28 schwarze 453: if (MAN_IP == n->tok && n->child)
1.48 schwarze 454: print_man_node(man, n->child, mh, h);
1.7 schwarze 455:
1.28 schwarze 456: /* For TP, only print next-line header elements. */
1.1 schwarze 457:
1.50 schwarze 458: if (MAN_TP == n->tok) {
459: nn = n->child;
1.74 schwarze 460: while (NULL != nn && 0 == (NODE_LINE & nn->flags))
1.50 schwarze 461: nn = nn->next;
462: while (NULL != nn) {
463: print_man_node(man, nn, mh, h);
464: nn = nn->next;
465: }
466: }
1.1 schwarze 467:
1.72 schwarze 468: return 0;
1.1 schwarze 469: }
470:
471: static int
472: man_HP_pre(MAN_ARGS)
473: {
1.75 schwarze 474: struct roffsu sum, sui;
1.67 schwarze 475: const struct roff_node *np;
1.1 schwarze 476:
1.66 schwarze 477: if (n->type == ROFFT_HEAD)
1.72 schwarze 478: return 0;
1.66 schwarze 479: else if (n->type != ROFFT_BLOCK)
1.72 schwarze 480: return 1;
1.38 schwarze 481:
1.40 schwarze 482: np = n->head->child;
1.1 schwarze 483:
1.75 schwarze 484: if (np == NULL || !a2width(np, &sum))
485: SCALE_HS_INIT(&sum, INDENT);
1.1 schwarze 486:
1.75 schwarze 487: sui.unit = sum.unit;
488: sui.scale = -sum.scale;
1.1 schwarze 489:
1.40 schwarze 490: print_bvspace(h, n);
1.80 schwarze 491: print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui);
1.72 schwarze 492: return 1;
1.1 schwarze 493: }
1.46 schwarze 494:
495: static int
496: man_OP_pre(MAN_ARGS)
497: {
498: struct tag *tt;
499:
500: print_text(h, "[");
501: h->flags |= HTML_NOSPACE;
1.81 schwarze 502: tt = print_otag(h, TAG_SPAN, "c", "Op");
1.46 schwarze 503:
504: if (NULL != (n = n->child)) {
1.75 schwarze 505: print_otag(h, TAG_B, "");
1.46 schwarze 506: print_text(h, n->string);
507: }
508:
509: print_stagq(h, tt);
510:
511: if (NULL != n && NULL != n->next) {
1.75 schwarze 512: print_otag(h, TAG_I, "");
1.46 schwarze 513: print_text(h, n->next->string);
514: }
515:
516: print_stagq(h, tt);
517: h->flags |= HTML_NOSPACE;
518: print_text(h, "]");
1.72 schwarze 519: return 0;
1.46 schwarze 520: }
521:
1.1 schwarze 522: static int
523: man_B_pre(MAN_ARGS)
524: {
1.75 schwarze 525: print_otag(h, TAG_B, "");
1.72 schwarze 526: return 1;
1.1 schwarze 527: }
528:
529: static int
530: man_I_pre(MAN_ARGS)
531: {
1.75 schwarze 532: print_otag(h, TAG_I, "");
1.72 schwarze 533: return 1;
1.18 schwarze 534: }
535:
536: static int
1.83 schwarze 537: man_fill_pre(MAN_ARGS)
1.18 schwarze 538: {
1.47 schwarze 539: if (MAN_fi == n->tok || MAN_EE == n->tok) {
1.83 schwarze 540: if (mh->nofill != NULL) {
541: print_tagq(h, mh->nofill);
542: mh->nofill = NULL;
543: } else
544: print_otag(h, TAG_BR, "");
545: } else {
546: if (mh->nofill == NULL)
547: mh->nofill = print_otag(h, TAG_PRE, "");
548: else
549: print_otag(h, TAG_BR, "");
550: }
1.72 schwarze 551: return 0;
1.18 schwarze 552: }
553:
554: static int
555: man_in_pre(MAN_ARGS)
556: {
1.75 schwarze 557: print_otag(h, TAG_BR, "");
1.72 schwarze 558: return 0;
1.1 schwarze 559: }
560:
561: static int
562: man_ign_pre(MAN_ARGS)
563: {
564:
1.72 schwarze 565: return 0;
1.1 schwarze 566: }
567:
568: static int
569: man_RS_pre(MAN_ARGS)
570: {
571: struct roffsu su;
572:
1.66 schwarze 573: if (n->type == ROFFT_HEAD)
1.72 schwarze 574: return 0;
1.66 schwarze 575: else if (n->type == ROFFT_BODY)
1.72 schwarze 576: return 1;
1.1 schwarze 577:
578: SCALE_HS_INIT(&su, INDENT);
1.26 schwarze 579: if (n->head->child)
1.1 schwarze 580: a2width(n->head->child, &su);
581:
1.75 schwarze 582: print_otag(h, TAG_DIV, "sul", &su);
1.72 schwarze 583: return 1;
1.49 schwarze 584: }
585:
586: static int
587: man_UR_pre(MAN_ARGS)
588: {
589: n = n->child;
1.66 schwarze 590: assert(n->type == ROFFT_HEAD);
1.73 schwarze 591: if (n->child != NULL) {
1.66 schwarze 592: assert(n->child->type == ROFFT_TEXT);
1.81 schwarze 593: print_otag(h, TAG_A, "ch", "Lk", n->child->string);
1.49 schwarze 594: }
595:
1.66 schwarze 596: assert(n->next->type == ROFFT_BODY);
1.73 schwarze 597: if (n->next->child != NULL)
1.49 schwarze 598: n = n->next;
599:
600: print_man_nodelist(man, n->child, mh, h);
601:
1.72 schwarze 602: return 0;
1.1 schwarze 603: }