Annotation of mandoc/term.c, Revision 1.47
1.47 ! kristaps 1: /* $Id: term.c,v 1.46 2009/03/08 14:01:46 kristaps Exp $ */
1.1 kristaps 2: /*
1.10 kristaps 3: * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
1.1 kristaps 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
7: * above copyright notice and this permission notice appear in all
8: * copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11: * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12: * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13: * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14: * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15: * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16: * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17: * PERFORMANCE OF THIS SOFTWARE.
18: */
19: #include <assert.h>
1.25 kristaps 20: #include <ctype.h>
1.23 kristaps 21: #include <err.h>
1.22 kristaps 22: #include <stdio.h>
1.1 kristaps 23: #include <stdlib.h>
24: #include <string.h>
25:
1.10 kristaps 26: #include "term.h"
27:
28: /*
29: * Performs actions on nodes of the abstract syntax tree. Both pre- and
30: * post-fix operations are defined here.
31: */
32:
1.21 kristaps 33: /* FIXME: macro arguments can be escaped. */
1.10 kristaps 34:
35: #define TTYPE_PROG 0
36: #define TTYPE_CMD_FLAG 1
37: #define TTYPE_CMD_ARG 2
38: #define TTYPE_SECTION 3
39: #define TTYPE_FUNC_DECL 4
40: #define TTYPE_VAR_DECL 5
41: #define TTYPE_FUNC_TYPE 6
42: #define TTYPE_FUNC_NAME 7
43: #define TTYPE_FUNC_ARG 8
44: #define TTYPE_LINK 9
45: #define TTYPE_SSECTION 10
46: #define TTYPE_FILE 11
1.11 kristaps 47: #define TTYPE_EMPH 12
1.14 kristaps 48: #define TTYPE_CONFIG 13
49: #define TTYPE_CMD 14
50: #define TTYPE_INCLUDE 15
1.17 kristaps 51: #define TTYPE_SYMB 16
52: #define TTYPE_SYMBOL 17
1.37 kristaps 53: #define TTYPE_DIAG 18
54: #define TTYPE_NMAX 19
1.10 kristaps 55:
56: /*
57: * These define "styles" for element types, like command arguments or
58: * executable names. This is useful when multiple macros must decorate
59: * the same thing (like .Ex -std cmd and .Nm cmd).
60: */
61:
1.36 kristaps 62: /* TODO: abstract this into mdocterm.c. */
63:
1.10 kristaps 64: const int ttypes[TTYPE_NMAX] = {
65: TERMP_BOLD, /* TTYPE_PROG */
66: TERMP_BOLD, /* TTYPE_CMD_FLAG */
67: TERMP_UNDERLINE, /* TTYPE_CMD_ARG */
68: TERMP_BOLD, /* TTYPE_SECTION */
69: TERMP_BOLD, /* TTYPE_FUNC_DECL */
70: TERMP_UNDERLINE, /* TTYPE_VAR_DECL */
71: TERMP_UNDERLINE, /* TTYPE_FUNC_TYPE */
72: TERMP_BOLD, /* TTYPE_FUNC_NAME */
73: TERMP_UNDERLINE, /* TTYPE_FUNC_ARG */
74: TERMP_UNDERLINE, /* TTYPE_LINK */
75: TERMP_BOLD, /* TTYPE_SSECTION */
1.11 kristaps 76: TERMP_UNDERLINE, /* TTYPE_FILE */
1.14 kristaps 77: TERMP_UNDERLINE, /* TTYPE_EMPH */
78: TERMP_BOLD, /* TTYPE_CONFIG */
79: TERMP_BOLD, /* TTYPE_CMD */
1.17 kristaps 80: TERMP_BOLD, /* TTYPE_INCLUDE */
81: TERMP_BOLD, /* TTYPE_SYMB */
1.37 kristaps 82: TERMP_BOLD, /* TTYPE_SYMBOL */
83: TERMP_BOLD /* TTYPE_DIAG */
1.10 kristaps 84: };
1.7 kristaps 85:
1.44 kristaps 86: static int arg_hasattr(int, const struct mdoc_node *);
87: static int arg_getattr(int, const struct mdoc_node *);
88: static size_t arg_offset(const struct mdoc_argv *);
89: static size_t arg_width(const struct mdoc_argv *);
1.39 kristaps 90: static int arg_listtype(const struct mdoc_node *);
1.10 kristaps 91:
92: /*
93: * What follows describes prefix and postfix operations for the abstract
94: * syntax tree descent.
95: */
1.1 kristaps 96:
1.10 kristaps 97: #define DECL_ARGS \
98: struct termp *p, \
1.18 kristaps 99: struct termpair *pair, \
1.10 kristaps 100: const struct mdoc_meta *meta, \
101: const struct mdoc_node *node
102:
103: #define DECL_PRE(name) \
104: static int name##_pre(DECL_ARGS)
105: #define DECL_POST(name) \
106: static void name##_post(DECL_ARGS)
107: #define DECL_PREPOST(name) \
108: DECL_PRE(name); \
109: DECL_POST(name);
110:
1.28 kristaps 111: DECL_PREPOST(termp__t);
1.10 kristaps 112: DECL_PREPOST(termp_aq);
1.12 kristaps 113: DECL_PREPOST(termp_bd);
1.15 kristaps 114: DECL_PREPOST(termp_bq);
1.10 kristaps 115: DECL_PREPOST(termp_d1);
116: DECL_PREPOST(termp_dq);
117: DECL_PREPOST(termp_fd);
118: DECL_PREPOST(termp_fn);
1.16 kristaps 119: DECL_PREPOST(termp_fo);
1.10 kristaps 120: DECL_PREPOST(termp_ft);
1.30 kristaps 121: DECL_PREPOST(termp_in);
1.10 kristaps 122: DECL_PREPOST(termp_it);
1.47 ! kristaps 123: DECL_PREPOST(termp_lb);
1.10 kristaps 124: DECL_PREPOST(termp_op);
125: DECL_PREPOST(termp_pf);
1.15 kristaps 126: DECL_PREPOST(termp_pq);
1.10 kristaps 127: DECL_PREPOST(termp_qq);
128: DECL_PREPOST(termp_sh);
129: DECL_PREPOST(termp_ss);
130: DECL_PREPOST(termp_sq);
131: DECL_PREPOST(termp_vt);
132:
1.18 kristaps 133: DECL_PRE(termp_ar);
1.14 kristaps 134: DECL_PRE(termp_at);
1.18 kristaps 135: DECL_PRE(termp_bf);
1.15 kristaps 136: DECL_PRE(termp_bsx);
1.17 kristaps 137: DECL_PRE(termp_bt);
1.18 kristaps 138: DECL_PRE(termp_cd);
139: DECL_PRE(termp_cm);
140: DECL_PRE(termp_em);
1.10 kristaps 141: DECL_PRE(termp_ex);
1.18 kristaps 142: DECL_PRE(termp_fa);
143: DECL_PRE(termp_fl);
1.16 kristaps 144: DECL_PRE(termp_fx);
1.18 kristaps 145: DECL_PRE(termp_ic);
146: DECL_PRE(termp_ms);
1.10 kristaps 147: DECL_PRE(termp_nd);
1.18 kristaps 148: DECL_PRE(termp_nm);
1.10 kristaps 149: DECL_PRE(termp_ns);
150: DECL_PRE(termp_nx);
151: DECL_PRE(termp_ox);
1.18 kristaps 152: DECL_PRE(termp_pa);
1.10 kristaps 153: DECL_PRE(termp_pp);
1.28 kristaps 154: DECL_PRE(termp_rs);
1.14 kristaps 155: DECL_PRE(termp_rv);
1.22 kristaps 156: DECL_PRE(termp_sm);
1.14 kristaps 157: DECL_PRE(termp_st);
1.18 kristaps 158: DECL_PRE(termp_sx);
159: DECL_PRE(termp_sy);
1.10 kristaps 160: DECL_PRE(termp_ud);
1.16 kristaps 161: DECL_PRE(termp_ux);
1.18 kristaps 162: DECL_PRE(termp_va);
1.10 kristaps 163: DECL_PRE(termp_xr);
164:
1.28 kristaps 165: DECL_POST(termp___);
1.10 kristaps 166: DECL_POST(termp_bl);
1.31 kristaps 167: DECL_POST(termp_bx);
1.10 kristaps 168:
169: const struct termact __termacts[MDOC_MAX] = {
170: { NULL, NULL }, /* \" */
171: { NULL, NULL }, /* Dd */
172: { NULL, NULL }, /* Dt */
173: { NULL, NULL }, /* Os */
174: { termp_sh_pre, termp_sh_post }, /* Sh */
175: { termp_ss_pre, termp_ss_post }, /* Ss */
176: { termp_pp_pre, NULL }, /* Pp */
177: { termp_d1_pre, termp_d1_post }, /* D1 */
1.29 kristaps 178: { termp_d1_pre, termp_d1_post }, /* Dl */
1.12 kristaps 179: { termp_bd_pre, termp_bd_post }, /* Bd */
1.10 kristaps 180: { NULL, NULL }, /* Ed */
181: { NULL, termp_bl_post }, /* Bl */
182: { NULL, NULL }, /* El */
183: { termp_it_pre, termp_it_post }, /* It */
184: { NULL, NULL }, /* Ad */
185: { NULL, NULL }, /* An */
1.18 kristaps 186: { termp_ar_pre, NULL }, /* Ar */
187: { termp_cd_pre, NULL }, /* Cd */
188: { termp_cm_pre, NULL }, /* Cm */
1.10 kristaps 189: { NULL, NULL }, /* Dv */
190: { NULL, NULL }, /* Er */
191: { NULL, NULL }, /* Ev */
192: { termp_ex_pre, NULL }, /* Ex */
1.18 kristaps 193: { termp_fa_pre, NULL }, /* Fa */
1.10 kristaps 194: { termp_fd_pre, termp_fd_post }, /* Fd */
1.18 kristaps 195: { termp_fl_pre, NULL }, /* Fl */
1.10 kristaps 196: { termp_fn_pre, termp_fn_post }, /* Fn */
197: { termp_ft_pre, termp_ft_post }, /* Ft */
1.18 kristaps 198: { termp_ic_pre, NULL }, /* Ic */
1.30 kristaps 199: { termp_in_pre, termp_in_post }, /* In */
1.10 kristaps 200: { NULL, NULL }, /* Li */
201: { termp_nd_pre, NULL }, /* Nd */
1.18 kristaps 202: { termp_nm_pre, NULL }, /* Nm */
1.10 kristaps 203: { termp_op_pre, termp_op_post }, /* Op */
204: { NULL, NULL }, /* Ot */
1.18 kristaps 205: { termp_pa_pre, NULL }, /* Pa */
1.14 kristaps 206: { termp_rv_pre, NULL }, /* Rv */
207: { termp_st_pre, NULL }, /* St */
1.18 kristaps 208: { termp_va_pre, NULL }, /* Va */
1.10 kristaps 209: { termp_vt_pre, termp_vt_post }, /* Vt */
210: { termp_xr_pre, NULL }, /* Xr */
1.28 kristaps 211: { NULL, termp____post }, /* %A */
1.29 kristaps 212: { NULL, termp____post }, /* %B */
1.28 kristaps 213: { NULL, termp____post }, /* %D */
1.29 kristaps 214: { NULL, termp____post }, /* %I */
1.28 kristaps 215: { NULL, termp____post }, /* %J */
1.29 kristaps 216: { NULL, termp____post }, /* %N */
217: { NULL, termp____post }, /* %O */
218: { NULL, termp____post }, /* %P */
219: { NULL, termp____post }, /* %R */
1.28 kristaps 220: { termp__t_pre, termp__t_post }, /* %T */
1.29 kristaps 221: { NULL, termp____post }, /* %V */
1.10 kristaps 222: { NULL, NULL }, /* Ac */
1.14 kristaps 223: { termp_aq_pre, termp_aq_post }, /* Ao */
1.10 kristaps 224: { termp_aq_pre, termp_aq_post }, /* Aq */
1.14 kristaps 225: { termp_at_pre, NULL }, /* At */
1.10 kristaps 226: { NULL, NULL }, /* Bc */
1.18 kristaps 227: { termp_bf_pre, NULL }, /* Bf */
1.15 kristaps 228: { termp_bq_pre, termp_bq_post }, /* Bo */
229: { termp_bq_pre, termp_bq_post }, /* Bq */
230: { termp_bsx_pre, NULL }, /* Bsx */
1.31 kristaps 231: { NULL, termp_bx_post }, /* Bx */
1.10 kristaps 232: { NULL, NULL }, /* Db */
233: { NULL, NULL }, /* Dc */
1.15 kristaps 234: { termp_dq_pre, termp_dq_post }, /* Do */
1.10 kristaps 235: { termp_dq_pre, termp_dq_post }, /* Dq */
236: { NULL, NULL }, /* Ec */
237: { NULL, NULL }, /* Ef */
1.18 kristaps 238: { termp_em_pre, NULL }, /* Em */
1.10 kristaps 239: { NULL, NULL }, /* Eo */
1.16 kristaps 240: { termp_fx_pre, NULL }, /* Fx */
1.18 kristaps 241: { termp_ms_pre, NULL }, /* Ms */
1.10 kristaps 242: { NULL, NULL }, /* No */
243: { termp_ns_pre, NULL }, /* Ns */
244: { termp_nx_pre, NULL }, /* Nx */
245: { termp_ox_pre, NULL }, /* Ox */
246: { NULL, NULL }, /* Pc */
247: { termp_pf_pre, termp_pf_post }, /* Pf */
1.15 kristaps 248: { termp_pq_pre, termp_pq_post }, /* Po */
249: { termp_pq_pre, termp_pq_post }, /* Pq */
1.10 kristaps 250: { NULL, NULL }, /* Qc */
1.16 kristaps 251: { termp_sq_pre, termp_sq_post }, /* Ql */
1.15 kristaps 252: { termp_qq_pre, termp_qq_post }, /* Qo */
1.10 kristaps 253: { termp_qq_pre, termp_qq_post }, /* Qq */
254: { NULL, NULL }, /* Re */
1.28 kristaps 255: { termp_rs_pre, NULL }, /* Rs */
1.10 kristaps 256: { NULL, NULL }, /* Sc */
1.15 kristaps 257: { termp_sq_pre, termp_sq_post }, /* So */
1.10 kristaps 258: { termp_sq_pre, termp_sq_post }, /* Sq */
1.22 kristaps 259: { termp_sm_pre, NULL }, /* Sm */
1.18 kristaps 260: { termp_sx_pre, NULL }, /* Sx */
261: { termp_sy_pre, NULL }, /* Sy */
1.10 kristaps 262: { NULL, NULL }, /* Tn */
1.16 kristaps 263: { termp_ux_pre, NULL }, /* Ux */
1.10 kristaps 264: { NULL, NULL }, /* Xc */
265: { NULL, NULL }, /* Xo */
1.16 kristaps 266: { termp_fo_pre, termp_fo_post }, /* Fo */
1.10 kristaps 267: { NULL, NULL }, /* Fc */
1.16 kristaps 268: { termp_op_pre, termp_op_post }, /* Oo */
1.10 kristaps 269: { NULL, NULL }, /* Oc */
270: { NULL, NULL }, /* Bk */
271: { NULL, NULL }, /* Ek */
1.17 kristaps 272: { termp_bt_pre, NULL }, /* Bt */
1.10 kristaps 273: { NULL, NULL }, /* Hf */
274: { NULL, NULL }, /* Fr */
275: { termp_ud_pre, NULL }, /* Ud */
1.47 ! kristaps 276: { termp_lb_pre, termp_lb_post }, /* Lb */
1.2 kristaps 277: };
278:
1.10 kristaps 279: const struct termact *termacts = __termacts;
280:
281:
282: static size_t
1.44 kristaps 283: arg_width(const struct mdoc_argv *arg)
1.10 kristaps 284: {
1.27 kristaps 285: size_t v;
286: int i, len;
1.12 kristaps 287:
288: assert(*arg->value);
1.25 kristaps 289: if (0 == strcmp(*arg->value, "indent"))
290: return(INDENT);
291: if (0 == strcmp(*arg->value, "indent-two"))
292: return(INDENT * 2);
293:
1.27 kristaps 294: len = (int)strlen(*arg->value);
1.25 kristaps 295: assert(len > 0);
296:
297: for (i = 0; i < len - 1; i++)
1.42 kristaps 298: if ( ! isdigit((u_char)(*arg->value)[i]))
1.25 kristaps 299: break;
300:
301: if (i == len - 1) {
302: if ('n' == (*arg->value)[len - 1]) {
303: v = (size_t)atoi(*arg->value);
304: return(v);
305: }
306:
307: }
1.31 kristaps 308: return(strlen(*arg->value) + 1);
1.12 kristaps 309: }
310:
311:
1.39 kristaps 312: static int
313: arg_listtype(const struct mdoc_node *n)
314: {
315: int i, len;
316:
1.44 kristaps 317: assert(MDOC_BLOCK == n->type);
318:
1.46 kristaps 319: len = (int)(n->args ? n->args->argc : 0);
1.39 kristaps 320:
321: for (i = 0; i < len; i++)
1.44 kristaps 322: switch (n->args->argv[i].arg) {
1.39 kristaps 323: case (MDOC_Bullet):
324: /* FALLTHROUGH */
325: case (MDOC_Dash):
326: /* FALLTHROUGH */
327: case (MDOC_Enum):
328: /* FALLTHROUGH */
329: case (MDOC_Hyphen):
330: /* FALLTHROUGH */
331: case (MDOC_Tag):
332: /* FALLTHROUGH */
333: case (MDOC_Inset):
334: /* FALLTHROUGH */
335: case (MDOC_Diag):
336: /* FALLTHROUGH */
337: case (MDOC_Item):
338: /* FALLTHROUGH */
339: case (MDOC_Ohang):
1.44 kristaps 340: return(n->args->argv[i].arg);
1.39 kristaps 341: default:
342: break;
343: }
344:
345: errx(1, "list type not supported");
346: /* NOTREACHED */
347: }
348:
349:
1.12 kristaps 350: static size_t
1.44 kristaps 351: arg_offset(const struct mdoc_argv *arg)
1.12 kristaps 352: {
353:
354: /* TODO */
355: assert(*arg->value);
356: if (0 == strcmp(*arg->value, "indent"))
1.10 kristaps 357: return(INDENT);
1.12 kristaps 358: if (0 == strcmp(*arg->value, "indent-two"))
1.10 kristaps 359: return(INDENT * 2);
1.12 kristaps 360: return(strlen(*arg->value));
1.10 kristaps 361: }
362:
1.3 kristaps 363:
1.10 kristaps 364: static int
1.44 kristaps 365: arg_hasattr(int arg, const struct mdoc_node *n)
1.2 kristaps 366: {
367:
1.44 kristaps 368: return(-1 != arg_getattr(arg, n));
1.10 kristaps 369: }
370:
371:
372: static int
1.44 kristaps 373: arg_getattr(int arg, const struct mdoc_node *n)
1.10 kristaps 374: {
375: int i;
376:
1.44 kristaps 377: if (NULL == n->args)
378: return(-1);
379: for (i = 0; i < (int)n->args->argc; i++)
380: if (n->args->argv[i].arg == arg)
1.10 kristaps 381: return(i);
382: return(-1);
383: }
384:
385:
386: /* ARGSUSED */
387: static int
388: termp_dq_pre(DECL_ARGS)
389: {
390:
391: if (MDOC_BODY != node->type)
392: return(1);
393:
394: word(p, "``");
395: p->flags |= TERMP_NOSPACE;
396: return(1);
397: }
398:
399:
400: /* ARGSUSED */
401: static void
402: termp_dq_post(DECL_ARGS)
403: {
404:
405: if (MDOC_BODY != node->type)
406: return;
1.3 kristaps 407:
1.10 kristaps 408: p->flags |= TERMP_NOSPACE;
409: word(p, "''");
410: }
1.2 kristaps 411:
1.3 kristaps 412:
1.10 kristaps 413: /* ARGSUSED */
1.20 kristaps 414: static int
1.39 kristaps 415: termp_it_pre_block(DECL_ARGS)
416: {
417:
418: newln(p);
1.44 kristaps 419: if ( ! arg_hasattr(MDOC_Compact, node->parent->parent))
420: if (node->prev || node->parent->parent->prev)
1.39 kristaps 421: vspace(p);
422:
423: return(1);
424: }
425:
426:
427: /* ARGSUSED */
428: static int
1.20 kristaps 429: termp_it_pre(DECL_ARGS)
1.10 kristaps 430: {
1.44 kristaps 431: const struct mdoc_node *bl;
1.39 kristaps 432: char buf[7];
1.23 kristaps 433: int i, type;
1.12 kristaps 434: size_t width, offset;
1.2 kristaps 435:
1.39 kristaps 436: if (MDOC_BLOCK == node->type)
437: return(termp_it_pre_block(p, pair, meta, node));
1.8 kristaps 438:
1.39 kristaps 439: /* Get ptr to list block, type, etc. */
1.10 kristaps 440:
1.44 kristaps 441: bl = node->parent->parent->parent;
442: type = arg_listtype(bl);
1.23 kristaps 443:
1.39 kristaps 444: /* Save parent attributes. */
1.23 kristaps 445:
1.20 kristaps 446: pair->offset = p->offset;
447: pair->rmargin = p->rmargin;
1.39 kristaps 448: pair->flag = p->flags;
1.20 kristaps 449:
1.23 kristaps 450: /* Get list width and offset. */
451:
1.44 kristaps 452: i = arg_getattr(MDOC_Width, bl);
453: width = i >= 0 ? arg_width(&bl->args->argv[i]) : 0;
1.20 kristaps 454:
1.44 kristaps 455: i = arg_getattr(MDOC_Offset, bl);
456: offset = i >= 0 ? arg_offset(&bl->args->argv[i]) : 0;
1.20 kristaps 457:
1.39 kristaps 458: /*
459: * List-type can override the width in the case of fixed-head
460: * values (bullet, dash/hyphen, enum). Tags need a non-zero
461: * offset.
462: */
1.10 kristaps 463:
1.23 kristaps 464: switch (type) {
465: case (MDOC_Bullet):
466: /* FALLTHROUGH */
467: case (MDOC_Dash):
468: /* FALLTHROUGH */
469: case (MDOC_Enum):
470: /* FALLTHROUGH */
471: case (MDOC_Hyphen):
1.38 kristaps 472: width = width > 4 ? width : 4;
1.23 kristaps 473: break;
474: case (MDOC_Tag):
1.39 kristaps 475: if (width)
476: break;
477: errx(1, "need non-zero %s for list type",
478: mdoc_argnames[MDOC_Width]);
1.23 kristaps 479: default:
480: break;
481: }
1.10 kristaps 482:
1.39 kristaps 483: /*
484: * Whitespace control. Inset bodies need an initial space.
485: */
1.21 kristaps 486:
1.23 kristaps 487: switch (type) {
1.37 kristaps 488: case (MDOC_Diag):
489: /* FALLTHROUGH */
490: case (MDOC_Inset):
1.39 kristaps 491: if (MDOC_BODY == node->type)
492: p->flags &= ~TERMP_NOSPACE;
493: else
494: p->flags |= TERMP_NOSPACE;
495: break;
496: default:
497: p->flags |= TERMP_NOSPACE;
498: break;
499: }
500:
501: /*
502: * Style flags. Diagnostic heads need TTYPE_DIAG.
503: */
504:
505: switch (type) {
506: case (MDOC_Diag):
1.37 kristaps 507: if (MDOC_HEAD == node->type)
1.39 kristaps 508: p->flags |= ttypes[TTYPE_DIAG];
509: break;
510: default:
1.37 kristaps 511: break;
1.39 kristaps 512: }
513:
514: /*
515: * Pad and break control. This is the tricker part. Lists with
516: * set right-margins for the head get TERMP_NOBREAK because, if
517: * they overrun the margin, they wrap to the new margin.
518: * Correspondingly, the body for these types don't left-pad, as
519: * the head will pad out to to the right.
520: */
521:
522: switch (type) {
1.23 kristaps 523: case (MDOC_Bullet):
524: /* FALLTHROUGH */
525: case (MDOC_Dash):
526: /* FALLTHROUGH */
527: case (MDOC_Enum):
528: /* FALLTHROUGH */
529: case (MDOC_Hyphen):
530: /* FALLTHROUGH */
531: case (MDOC_Tag):
532: if (MDOC_HEAD == node->type)
533: p->flags |= TERMP_NOBREAK;
1.39 kristaps 534: else
1.23 kristaps 535: p->flags |= TERMP_NOLPAD;
1.41 kristaps 536: if (MDOC_HEAD == node->type && MDOC_Tag == type)
537: if (NULL == node->next ||
538: NULL == node->next->child)
539: p->flags |= TERMP_NONOBREAK;
1.23 kristaps 540: break;
1.39 kristaps 541: case (MDOC_Diag):
542: if (MDOC_HEAD == node->type)
543: p->flags |= TERMP_NOBREAK;
544: break;
1.24 kristaps 545: default:
1.23 kristaps 546: break;
547: }
1.21 kristaps 548:
1.23 kristaps 549: /*
1.39 kristaps 550: * Margin control. Set-head-width lists have their right
551: * margins shortened. The body for these lists has the offset
552: * necessarily lengthened. Everybody gets the offset.
1.23 kristaps 553: */
1.21 kristaps 554:
555: p->offset += offset;
1.23 kristaps 556:
557: switch (type) {
558: case (MDOC_Bullet):
559: /* FALLTHROUGH */
560: case (MDOC_Dash):
561: /* FALLTHROUGH */
562: case (MDOC_Enum):
563: /* FALLTHROUGH */
564: case (MDOC_Hyphen):
565: /* FALLTHROUGH */
566: case (MDOC_Tag):
567: if (MDOC_HEAD == node->type)
568: p->rmargin = p->offset + width;
1.39 kristaps 569: else
1.23 kristaps 570: p->offset += width;
1.39 kristaps 571: /* FALLTHROUGH */
1.24 kristaps 572: default:
1.23 kristaps 573: break;
574: }
575:
1.39 kristaps 576: /*
577: * The dash, hyphen, bullet and enum lists all have a special
578: * HEAD character. Print it now.
579: */
580:
581: if (MDOC_HEAD == node->type)
582: switch (type) {
583: case (MDOC_Bullet):
584: word(p, "\\[bu]");
585: break;
586: case (MDOC_Dash):
587: /* FALLTHROUGH */
588: case (MDOC_Hyphen):
589: word(p, "\\-");
590: break;
591: case (MDOC_Enum):
592: /* TODO: have a wordfmt or something. */
593: (pair->ppair->ppair->count)++;
594: (void)snprintf(buf, sizeof(buf), "%d.",
595: pair->ppair->ppair->count);
596: word(p, buf);
597: break;
598: default:
599: break;
600: }
601:
602: /*
603: * If we're not going to process our header children, indicate
604: * so here.
605: */
606:
607: if (MDOC_HEAD == node->type)
608: switch (type) {
609: case (MDOC_Bullet):
610: /* FALLTHROUGH */
611: case (MDOC_Item):
612: /* FALLTHROUGH */
613: case (MDOC_Dash):
614: /* FALLTHROUGH */
615: case (MDOC_Hyphen):
616: /* FALLTHROUGH */
617: case (MDOC_Enum):
618: return(0);
619: default:
620: break;
621: }
1.23 kristaps 622:
1.39 kristaps 623: return(1);
1.10 kristaps 624: }
625:
626:
627: /* ARGSUSED */
1.20 kristaps 628: static void
629: termp_it_post(DECL_ARGS)
1.10 kristaps 630: {
1.39 kristaps 631: int type;
1.3 kristaps 632:
1.21 kristaps 633: if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
1.20 kristaps 634: return;
1.10 kristaps 635:
1.39 kristaps 636: type = arg_listtype(node->parent->parent->parent);
1.37 kristaps 637:
638: switch (type) {
639: case (MDOC_Diag):
640: /* FALLTHROUGH */
1.39 kristaps 641: case (MDOC_Item):
642: /* FALLTHROUGH */
1.37 kristaps 643: case (MDOC_Inset):
1.39 kristaps 644: if (MDOC_BODY != node->type)
645: break;
646: flushln(p);
1.37 kristaps 647: break;
648: default:
649: flushln(p);
650: break;
651: }
1.10 kristaps 652:
1.23 kristaps 653: p->offset = pair->offset;
654: p->rmargin = pair->rmargin;
1.39 kristaps 655: p->flags = pair->flag;
1.2 kristaps 656: }
657:
658:
1.10 kristaps 659: /* ARGSUSED */
1.18 kristaps 660: static int
661: termp_nm_pre(DECL_ARGS)
1.10 kristaps 662: {
663:
1.29 kristaps 664: if (SEC_SYNOPSIS == node->sec)
665: newln(p);
666:
1.31 kristaps 667: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_PROG]);
1.18 kristaps 668: if (NULL == node->child)
669: word(p, meta->name);
1.31 kristaps 670:
1.18 kristaps 671: return(1);
1.10 kristaps 672: }
673:
674:
675: /* ARGSUSED */
1.18 kristaps 676: static int
677: termp_fl_pre(DECL_ARGS)
1.10 kristaps 678: {
679:
1.31 kristaps 680: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
1.18 kristaps 681: word(p, "\\-");
682: p->flags |= TERMP_NOSPACE;
683: return(1);
1.10 kristaps 684: }
685:
686:
687: /* ARGSUSED */
688: static int
689: termp_ar_pre(DECL_ARGS)
690: {
691:
1.31 kristaps 692: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_ARG]);
1.10 kristaps 693: return(1);
694: }
695:
696:
697: /* ARGSUSED */
698: static int
699: termp_ns_pre(DECL_ARGS)
1.2 kristaps 700: {
701:
702: p->flags |= TERMP_NOSPACE;
1.10 kristaps 703: return(1);
704: }
705:
706:
707: /* ARGSUSED */
708: static int
709: termp_pp_pre(DECL_ARGS)
710: {
711:
712: vspace(p);
713: return(1);
714: }
715:
716:
717: /* ARGSUSED */
718: static int
1.14 kristaps 719: termp_st_pre(DECL_ARGS)
720: {
1.43 kristaps 721: const char *cp;
1.14 kristaps 722:
1.44 kristaps 723: if (node->child) {
724: if (MDOC_TEXT != node->child->type)
725: errx(1, "expected text line arguments");
726: if ((cp = mdoc_a2st(node->child->string)))
1.43 kristaps 727: word(p, cp);
1.44 kristaps 728: }
1.43 kristaps 729: return(0);
1.14 kristaps 730: }
731:
732:
733: /* ARGSUSED */
734: static int
1.28 kristaps 735: termp_rs_pre(DECL_ARGS)
736: {
737:
1.30 kristaps 738: if (MDOC_BLOCK == node->type && node->prev)
1.28 kristaps 739: vspace(p);
740: return(1);
741: }
742:
743:
744: /* ARGSUSED */
745: static int
1.14 kristaps 746: termp_rv_pre(DECL_ARGS)
747: {
748: int i;
749:
1.44 kristaps 750: if (-1 == (i = arg_getattr(MDOC_Std, node)))
751: errx(1, "expected -std argument");
752: if (1 != node->args->argv[i].sz)
753: errx(1, "expected -std argument");
1.14 kristaps 754:
755: newln(p);
756: word(p, "The");
757:
758: p->flags |= ttypes[TTYPE_FUNC_NAME];
1.44 kristaps 759: word(p, *node->args->argv[i].value);
1.14 kristaps 760: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
761:
762: word(p, "() function returns the value 0 if successful;");
763: word(p, "otherwise the value -1 is returned and the");
764: word(p, "global variable");
765:
766: p->flags |= ttypes[TTYPE_VAR_DECL];
767: word(p, "errno");
768: p->flags &= ~ttypes[TTYPE_VAR_DECL];
769:
770: word(p, "is set to indicate the error.");
771:
772: return(1);
773: }
774:
775:
776: /* ARGSUSED */
777: static int
1.10 kristaps 778: termp_ex_pre(DECL_ARGS)
779: {
780: int i;
781:
1.44 kristaps 782: if (-1 == (i = arg_getattr(MDOC_Std, node)))
783: errx(1, "expected -std argument");
784: if (1 != node->args->argv[i].sz)
785: errx(1, "expected -std argument");
1.10 kristaps 786:
787: word(p, "The");
788: p->flags |= ttypes[TTYPE_PROG];
1.44 kristaps 789: word(p, *node->args->argv[i].value);
1.10 kristaps 790: p->flags &= ~ttypes[TTYPE_PROG];
791: word(p, "utility exits 0 on success, and >0 if an error occurs.");
792:
793: return(1);
794: }
795:
796:
797: /* ARGSUSED */
798: static int
799: termp_nd_pre(DECL_ARGS)
800: {
801:
802: word(p, "\\-");
803: return(1);
804: }
805:
806:
807: /* ARGSUSED */
808: static void
809: termp_bl_post(DECL_ARGS)
810: {
811:
812: if (MDOC_BLOCK == node->type)
813: newln(p);
814: }
815:
816:
817: /* ARGSUSED */
818: static void
819: termp_op_post(DECL_ARGS)
820: {
821:
822: if (MDOC_BODY != node->type)
1.2 kristaps 823: return;
1.10 kristaps 824: p->flags |= TERMP_NOSPACE;
825: word(p, "\\(rB");
826: }
827:
828:
829: /* ARGSUSED */
830: static int
831: termp_xr_pre(DECL_ARGS)
832: {
833: const struct mdoc_node *n;
834:
1.44 kristaps 835: if (NULL == (n = node->child))
836: errx(1, "expected text line argument");
837: if (MDOC_TEXT != n->type)
838: errx(1, "expected text line argument");
1.10 kristaps 839:
1.44 kristaps 840: word(p, n->string);
1.10 kristaps 841:
842: if (NULL == (n = n->next))
843: return(0);
1.44 kristaps 844: if (MDOC_TEXT != n->type)
845: errx(1, "expected text line argument");
1.10 kristaps 846:
847: p->flags |= TERMP_NOSPACE;
848: word(p, "(");
849: p->flags |= TERMP_NOSPACE;
1.44 kristaps 850: word(p, n->string);
1.10 kristaps 851: p->flags |= TERMP_NOSPACE;
852: word(p, ")");
853:
854: return(0);
1.2 kristaps 855: }
856:
857:
1.10 kristaps 858: /* ARGSUSED */
859: static int
860: termp_vt_pre(DECL_ARGS)
1.2 kristaps 861: {
862:
1.10 kristaps 863: /* FIXME: this can be "type name". */
1.31 kristaps 864: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 865: return(1);
1.2 kristaps 866: }
867:
868:
1.10 kristaps 869: /* ARGSUSED */
1.2 kristaps 870: static void
1.10 kristaps 871: termp_vt_post(DECL_ARGS)
872: {
873:
874: if (node->sec == SEC_SYNOPSIS)
875: vspace(p);
876: }
877:
878:
879: /* ARGSUSED */
880: static int
881: termp_fd_pre(DECL_ARGS)
1.2 kristaps 882: {
883:
1.10 kristaps 884: /*
885: * FIXME: this naming is bad. This value is used, in general,
886: * for the #include header or other preprocessor statement.
887: */
1.31 kristaps 888: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_DECL]);
1.10 kristaps 889: return(1);
1.2 kristaps 890: }
891:
892:
1.10 kristaps 893: /* ARGSUSED */
1.2 kristaps 894: static void
1.10 kristaps 895: termp_fd_post(DECL_ARGS)
1.2 kristaps 896: {
897:
1.30 kristaps 898: if (node->sec != SEC_SYNOPSIS)
899: return;
900: newln(p);
901: if (node->next && MDOC_Fd != node->next->tok)
1.10 kristaps 902: vspace(p);
903: }
904:
905:
906: /* ARGSUSED */
907: static int
908: termp_sh_pre(DECL_ARGS)
909: {
1.2 kristaps 910:
1.10 kristaps 911: switch (node->type) {
912: case (MDOC_HEAD):
913: vspace(p);
1.31 kristaps 914: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SECTION]);
1.2 kristaps 915: break;
1.10 kristaps 916: case (MDOC_BODY):
917: p->offset = INDENT;
1.2 kristaps 918: break;
1.10 kristaps 919: default:
920: break;
921: }
922: return(1);
923: }
924:
925:
926: /* ARGSUSED */
1.19 kristaps 927: static void
928: termp_sh_post(DECL_ARGS)
929: {
930:
931: switch (node->type) {
932: case (MDOC_HEAD):
933: newln(p);
934: break;
935: case (MDOC_BODY):
936: newln(p);
937: p->offset = 0;
938: break;
939: default:
940: break;
941: }
942: }
943:
944:
945: /* ARGSUSED */
1.10 kristaps 946: static int
947: termp_op_pre(DECL_ARGS)
948: {
949:
950: switch (node->type) {
951: case (MDOC_BODY):
952: word(p, "\\(lB");
953: p->flags |= TERMP_NOSPACE;
1.2 kristaps 954: break;
955: default:
1.10 kristaps 956: break;
1.2 kristaps 957: }
1.10 kristaps 958: return(1);
959: }
960:
961:
962: /* ARGSUSED */
963: static int
1.17 kristaps 964: termp_bt_pre(DECL_ARGS)
965: {
966:
967: word(p, "is currently in beta test.");
968: return(1);
969: }
970:
971:
972: /* ARGSUSED */
1.47 ! kristaps 973: static int
! 974: termp_lb_pre(DECL_ARGS)
! 975: {
! 976: const char *lb;
! 977:
! 978: if (NULL == node->child)
! 979: errx(1, "expected text line argument");
! 980: if (MDOC_TEXT != node->child->type)
! 981: errx(1, "expected text line argument");
! 982:
! 983: if ((lb = mdoc_a2lib(node->child->string))) {
! 984: word(p, lb);
! 985: return(0);
! 986: }
! 987:
! 988: word(p, "library");
! 989: return(1);
! 990: }
! 991:
! 992:
! 993: /* ARGSUSED */
1.43 kristaps 994: static void
995: termp_lb_post(DECL_ARGS)
996: {
997:
998: newln(p);
999: }
1000:
1001:
1002: /* ARGSUSED */
1.17 kristaps 1003: static int
1.10 kristaps 1004: termp_ud_pre(DECL_ARGS)
1005: {
1006:
1007: word(p, "currently under development.");
1008: return(1);
1009: }
1010:
1011:
1012: /* ARGSUSED */
1013: static int
1014: termp_d1_pre(DECL_ARGS)
1015: {
1016:
1017: if (MDOC_BODY != node->type)
1018: return(1);
1019: newln(p);
1.19 kristaps 1020: p->offset += (pair->offset = INDENT);
1.10 kristaps 1021: return(1);
1.2 kristaps 1022: }
1023:
1024:
1.10 kristaps 1025: /* ARGSUSED */
1.2 kristaps 1026: static void
1.10 kristaps 1027: termp_d1_post(DECL_ARGS)
1028: {
1029:
1030: if (MDOC_BODY != node->type)
1031: return;
1032: newln(p);
1.19 kristaps 1033: p->offset -= pair->offset;
1.10 kristaps 1034: }
1035:
1036:
1037: /* ARGSUSED */
1038: static int
1039: termp_aq_pre(DECL_ARGS)
1.6 kristaps 1040: {
1041:
1.10 kristaps 1042: if (MDOC_BODY != node->type)
1043: return(1);
1.40 kristaps 1044: word(p, "\\(la");
1.10 kristaps 1045: p->flags |= TERMP_NOSPACE;
1046: return(1);
1047: }
1.6 kristaps 1048:
1049:
1.10 kristaps 1050: /* ARGSUSED */
1051: static void
1052: termp_aq_post(DECL_ARGS)
1053: {
1.6 kristaps 1054:
1.10 kristaps 1055: if (MDOC_BODY != node->type)
1.6 kristaps 1056: return;
1.10 kristaps 1057: p->flags |= TERMP_NOSPACE;
1.40 kristaps 1058: word(p, "\\(ra");
1.10 kristaps 1059: }
1.6 kristaps 1060:
1.10 kristaps 1061:
1062: /* ARGSUSED */
1063: static int
1064: termp_ft_pre(DECL_ARGS)
1065: {
1066:
1.34 kristaps 1067: if (SEC_SYNOPSIS == node->sec)
1068: if (node->prev && MDOC_Fo == node->prev->tok)
1069: vspace(p);
1.31 kristaps 1070: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 1071: return(1);
1.6 kristaps 1072: }
1073:
1074:
1.10 kristaps 1075: /* ARGSUSED */
1.6 kristaps 1076: static void
1.10 kristaps 1077: termp_ft_post(DECL_ARGS)
1.2 kristaps 1078: {
1079:
1.34 kristaps 1080: if (SEC_SYNOPSIS == node->sec)
1.10 kristaps 1081: newln(p);
1082: }
1.2 kristaps 1083:
1084:
1.10 kristaps 1085: /* ARGSUSED */
1086: static int
1087: termp_fn_pre(DECL_ARGS)
1088: {
1089: const struct mdoc_node *n;
1090:
1.44 kristaps 1091: if (NULL == node->child)
1092: errx(1, "expected text line arguments");
1093: if (MDOC_TEXT != node->child->type)
1094: errx(1, "expected text line arguments");
1.2 kristaps 1095:
1.10 kristaps 1096: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 1097:
1.10 kristaps 1098: p->flags |= ttypes[TTYPE_FUNC_NAME];
1.44 kristaps 1099: word(p, node->child->string);
1.10 kristaps 1100: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1101:
1102: word(p, "(");
1103:
1104: p->flags |= TERMP_NOSPACE;
1105: for (n = node->child->next; n; n = n->next) {
1.44 kristaps 1106: if (MDOC_TEXT != n->type)
1107: errx(1, "expected text line arguments");
1.10 kristaps 1108: p->flags |= ttypes[TTYPE_FUNC_ARG];
1.44 kristaps 1109: word(p, n->string);
1.10 kristaps 1110: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 1111: if (n->next)
1.10 kristaps 1112: word(p, ",");
1.6 kristaps 1113: }
1.2 kristaps 1114:
1.10 kristaps 1115: word(p, ")");
1116:
1117: if (SEC_SYNOPSIS == node->sec)
1118: word(p, ";");
1119:
1120: return(0);
1.2 kristaps 1121: }
1122:
1123:
1.10 kristaps 1124: /* ARGSUSED */
1125: static void
1126: termp_fn_post(DECL_ARGS)
1.2 kristaps 1127: {
1128:
1.30 kristaps 1129: if (node->sec == SEC_SYNOPSIS && node->next)
1.10 kristaps 1130: vspace(p);
1131:
1132: }
1.2 kristaps 1133:
1134:
1.10 kristaps 1135: /* ARGSUSED */
1136: static int
1137: termp_sx_pre(DECL_ARGS)
1138: {
1.8 kristaps 1139:
1.31 kristaps 1140: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK]);
1.10 kristaps 1141: return(1);
1.2 kristaps 1142: }
1143:
1144:
1.10 kristaps 1145: /* ARGSUSED */
1146: static int
1147: termp_fa_pre(DECL_ARGS)
1148: {
1.16 kristaps 1149: struct mdoc_node *n;
1150:
1151: if (node->parent->tok != MDOC_Fo) {
1.31 kristaps 1152: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 1153: return(1);
1154: }
1155:
1156: for (n = node->child; n; n = n->next) {
1.44 kristaps 1157: if (MDOC_TEXT != n->type)
1158: errx(1, "expected text line arguments");
1.16 kristaps 1159:
1160: p->flags |= ttypes[TTYPE_FUNC_ARG];
1.44 kristaps 1161: word(p, n->string);
1.16 kristaps 1162: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1163:
1164: if (n->next)
1165: word(p, ",");
1166: }
1167:
1168: if (node->next && node->next->tok == MDOC_Fa)
1169: word(p, ",");
1.2 kristaps 1170:
1.16 kristaps 1171: return(0);
1.10 kristaps 1172: }
1.2 kristaps 1173:
1174:
1.10 kristaps 1175: /* ARGSUSED */
1176: static int
1177: termp_va_pre(DECL_ARGS)
1178: {
1.2 kristaps 1179:
1.31 kristaps 1180: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 1181: return(1);
1.2 kristaps 1182: }
1183:
1184:
1.10 kristaps 1185: /* ARGSUSED */
1186: static int
1187: termp_bd_pre(DECL_ARGS)
1188: {
1.35 kristaps 1189: const struct mdoc_node *n;
1.44 kristaps 1190: int i, type;
1.1 kristaps 1191:
1.10 kristaps 1192: if (MDOC_BLOCK == node->type) {
1.30 kristaps 1193: if (node->prev)
1194: vspace(p);
1.10 kristaps 1195: return(1);
1196: } else if (MDOC_BODY != node->type)
1197: return(1);
1198:
1.44 kristaps 1199: if (NULL == node->parent->args)
1200: errx(1, "missing display type");
1201:
1.20 kristaps 1202: pair->offset = p->offset;
1.10 kristaps 1203:
1.44 kristaps 1204: for (type = -1, i = 0;
1205: i < (int)node->parent->args->argc; i++) {
1206: switch (node->parent->args->argv[i].arg) {
1.35 kristaps 1207: case (MDOC_Ragged):
1208: /* FALLTHROUGH */
1209: case (MDOC_Filled):
1210: /* FALLTHROUGH */
1211: case (MDOC_Unfilled):
1212: /* FALLTHROUGH */
1213: case (MDOC_Literal):
1.44 kristaps 1214: type = node->parent->args->argv[i].arg;
1215: i = (int)node->parent->args->argc;
1.35 kristaps 1216: break;
1217: default:
1.44 kristaps 1218: break;
1.35 kristaps 1219: }
1220: }
1221:
1.44 kristaps 1222: if (NULL == node->parent->args)
1223: errx(1, "missing display type");
1.12 kristaps 1224:
1.44 kristaps 1225: i = arg_getattr(MDOC_Offset, node->parent);
1.12 kristaps 1226: if (-1 != i) {
1.45 kristaps 1227: if (1 != node->parent->args->argv[i].sz)
1.44 kristaps 1228: errx(1, "expected single value");
1.45 kristaps 1229: p->offset += arg_offset(&node->parent->args->argv[i]);
1.12 kristaps 1230: }
1231:
1.35 kristaps 1232: switch (type) {
1233: case (MDOC_Literal):
1234: /* FALLTHROUGH */
1235: case (MDOC_Unfilled):
1236: break;
1237: default:
1238: return(1);
1239: }
1240:
1.10 kristaps 1241: p->flags |= TERMP_LITERAL;
1242:
1243: for (n = node->child; n; n = n->next) {
1.35 kristaps 1244: if (MDOC_TEXT != n->type) {
1245: warnx("non-text children not yet allowed");
1246: continue;
1247: }
1.44 kristaps 1248: word(p, n->string);
1.35 kristaps 1249: flushln(p);
1.10 kristaps 1250: }
1.1 kristaps 1251:
1.10 kristaps 1252: return(0);
1253: }
1.1 kristaps 1254:
1255:
1.10 kristaps 1256: /* ARGSUSED */
1.12 kristaps 1257: static void
1258: termp_bd_post(DECL_ARGS)
1259: {
1260:
1.20 kristaps 1261: if (MDOC_BODY != node->type)
1262: return;
1.35 kristaps 1263:
1264: if ( ! (p->flags & TERMP_LITERAL))
1265: flushln(p);
1266:
1267: p->flags &= ~TERMP_LITERAL;
1.20 kristaps 1268: p->offset = pair->offset;
1.12 kristaps 1269: }
1270:
1271:
1272: /* ARGSUSED */
1.10 kristaps 1273: static int
1274: termp_qq_pre(DECL_ARGS)
1275: {
1.1 kristaps 1276:
1.10 kristaps 1277: if (MDOC_BODY != node->type)
1278: return(1);
1279: word(p, "\"");
1280: p->flags |= TERMP_NOSPACE;
1281: return(1);
1.1 kristaps 1282: }
1283:
1284:
1.10 kristaps 1285: /* ARGSUSED */
1.1 kristaps 1286: static void
1.10 kristaps 1287: termp_qq_post(DECL_ARGS)
1.1 kristaps 1288: {
1289:
1.10 kristaps 1290: if (MDOC_BODY != node->type)
1291: return;
1292: p->flags |= TERMP_NOSPACE;
1293: word(p, "\"");
1294: }
1295:
1296:
1297: /* ARGSUSED */
1298: static int
1.15 kristaps 1299: termp_bsx_pre(DECL_ARGS)
1300: {
1301:
1302: word(p, "BSDI BSD/OS");
1303: return(1);
1304: }
1305:
1306:
1307: /* ARGSUSED */
1.31 kristaps 1308: static void
1309: termp_bx_post(DECL_ARGS)
1.10 kristaps 1310: {
1.1 kristaps 1311:
1.34 kristaps 1312: if (node->child)
1313: p->flags |= TERMP_NOSPACE;
1.10 kristaps 1314: word(p, "BSD");
1315: }
1316:
1317:
1318: /* ARGSUSED */
1319: static int
1320: termp_ox_pre(DECL_ARGS)
1321: {
1322:
1323: word(p, "OpenBSD");
1324: return(1);
1325: }
1326:
1327:
1328: /* ARGSUSED */
1329: static int
1.16 kristaps 1330: termp_ux_pre(DECL_ARGS)
1331: {
1332:
1333: word(p, "UNIX");
1334: return(1);
1335: }
1336:
1337:
1338: /* ARGSUSED */
1339: static int
1340: termp_fx_pre(DECL_ARGS)
1341: {
1342:
1343: word(p, "FreeBSD");
1344: return(1);
1345: }
1346:
1347:
1348: /* ARGSUSED */
1349: static int
1.10 kristaps 1350: termp_nx_pre(DECL_ARGS)
1351: {
1352:
1353: word(p, "NetBSD");
1354: return(1);
1355: }
1356:
1357:
1358: /* ARGSUSED */
1359: static int
1360: termp_sq_pre(DECL_ARGS)
1361: {
1362:
1363: if (MDOC_BODY != node->type)
1364: return(1);
1.28 kristaps 1365: word(p, "`");
1.10 kristaps 1366: p->flags |= TERMP_NOSPACE;
1367: return(1);
1368: }
1.1 kristaps 1369:
1370:
1.10 kristaps 1371: /* ARGSUSED */
1372: static void
1373: termp_sq_post(DECL_ARGS)
1374: {
1375:
1376: if (MDOC_BODY != node->type)
1377: return;
1378: p->flags |= TERMP_NOSPACE;
1379: word(p, "\'");
1380: }
1.2 kristaps 1381:
1382:
1.10 kristaps 1383: /* ARGSUSED */
1384: static int
1385: termp_pf_pre(DECL_ARGS)
1386: {
1.1 kristaps 1387:
1.10 kristaps 1388: p->flags |= TERMP_IGNDELIM;
1389: return(1);
1390: }
1.1 kristaps 1391:
1392:
1.10 kristaps 1393: /* ARGSUSED */
1394: static void
1395: termp_pf_post(DECL_ARGS)
1396: {
1.1 kristaps 1397:
1.10 kristaps 1398: p->flags &= ~TERMP_IGNDELIM;
1399: p->flags |= TERMP_NOSPACE;
1400: }
1.1 kristaps 1401:
1402:
1.10 kristaps 1403: /* ARGSUSED */
1404: static int
1405: termp_ss_pre(DECL_ARGS)
1406: {
1.1 kristaps 1407:
1.10 kristaps 1408: switch (node->type) {
1409: case (MDOC_HEAD):
1410: vspace(p);
1.31 kristaps 1411: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1412: p->offset = INDENT / 2;
1413: break;
1414: default:
1415: break;
1416: }
1.1 kristaps 1417:
1.10 kristaps 1418: return(1);
1.1 kristaps 1419: }
1420:
1421:
1.10 kristaps 1422: /* ARGSUSED */
1423: static void
1424: termp_ss_post(DECL_ARGS)
1.1 kristaps 1425: {
1426:
1.10 kristaps 1427: switch (node->type) {
1428: case (MDOC_HEAD):
1429: newln(p);
1430: p->offset = INDENT;
1431: break;
1432: default:
1433: break;
1434: }
1435: }
1.2 kristaps 1436:
1437:
1.10 kristaps 1438: /* ARGSUSED */
1439: static int
1440: termp_pa_pre(DECL_ARGS)
1441: {
1.2 kristaps 1442:
1.31 kristaps 1443: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1444: return(1);
1.1 kristaps 1445: }
1446:
1447:
1.10 kristaps 1448: /* ARGSUSED */
1.11 kristaps 1449: static int
1450: termp_em_pre(DECL_ARGS)
1451: {
1452:
1.31 kristaps 1453: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1454: return(1);
1455: }
1456:
1457:
1458: /* ARGSUSED */
1.14 kristaps 1459: static int
1460: termp_cd_pre(DECL_ARGS)
1461: {
1462:
1.31 kristaps 1463: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CONFIG]);
1.33 kristaps 1464: newln(p);
1.14 kristaps 1465: return(1);
1466: }
1467:
1468:
1469: /* ARGSUSED */
1470: static int
1471: termp_cm_pre(DECL_ARGS)
1472: {
1473:
1.31 kristaps 1474: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1475: return(1);
1476: }
1477:
1478:
1479: /* ARGSUSED */
1480: static int
1481: termp_ic_pre(DECL_ARGS)
1482: {
1483:
1.31 kristaps 1484: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1485: return(1);
1486: }
1487:
1488:
1489: /* ARGSUSED */
1490: static int
1491: termp_in_pre(DECL_ARGS)
1492: {
1493:
1.31 kristaps 1494: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_INCLUDE]);
1.30 kristaps 1495: word(p, "#include");
1496: word(p, "<");
1497: p->flags |= TERMP_NOSPACE;
1.14 kristaps 1498: return(1);
1499: }
1500:
1501:
1502: /* ARGSUSED */
1.30 kristaps 1503: static void
1504: termp_in_post(DECL_ARGS)
1505: {
1506:
1507: p->flags |= TERMP_NOSPACE;
1508: word(p, ">");
1509:
1510: newln(p);
1511: if (SEC_SYNOPSIS != node->sec)
1512: return;
1513: if (node->next && MDOC_In != node->next->tok)
1514: vspace(p);
1515: }
1516:
1517:
1518: /* ARGSUSED */
1.14 kristaps 1519: static int
1520: termp_at_pre(DECL_ARGS)
1521: {
1.43 kristaps 1522: const char *att;
1523:
1524: att = NULL;
1.14 kristaps 1525:
1526: if (node->child) {
1.44 kristaps 1527: if (MDOC_TEXT != node->child->type)
1528: errx(1, "expected text line argument");
1529: att = mdoc_a2att(node->child->string);
1.14 kristaps 1530: }
1531:
1.43 kristaps 1532: if (NULL == att)
1533: att = "AT&T UNIX";
1534:
1535: word(p, att);
1.14 kristaps 1536: return(0);
1537: }
1.15 kristaps 1538:
1539:
1540: /* ARGSUSED */
1541: static int
1542: termp_bq_pre(DECL_ARGS)
1543: {
1544:
1545: if (MDOC_BODY != node->type)
1546: return(1);
1.30 kristaps 1547: word(p, "[");
1.15 kristaps 1548: p->flags |= TERMP_NOSPACE;
1549: return(1);
1550: }
1551:
1552:
1553: /* ARGSUSED */
1554: static void
1555: termp_bq_post(DECL_ARGS)
1556: {
1557:
1558: if (MDOC_BODY != node->type)
1559: return;
1560: word(p, "]");
1561: }
1562:
1563:
1564: /* ARGSUSED */
1565: static int
1566: termp_pq_pre(DECL_ARGS)
1567: {
1568:
1569: if (MDOC_BODY != node->type)
1570: return(1);
1.31 kristaps 1571: word(p, "\\&(");
1.15 kristaps 1572: p->flags |= TERMP_NOSPACE;
1573: return(1);
1574: }
1575:
1576:
1577: /* ARGSUSED */
1578: static void
1579: termp_pq_post(DECL_ARGS)
1580: {
1581:
1582: if (MDOC_BODY != node->type)
1583: return;
1584: word(p, ")");
1585: }
1586:
1587:
1.16 kristaps 1588: /* ARGSUSED */
1589: static int
1590: termp_fo_pre(DECL_ARGS)
1591: {
1592: const struct mdoc_node *n;
1593:
1594: if (MDOC_BODY == node->type) {
1595: word(p, "(");
1596: p->flags |= TERMP_NOSPACE;
1597: return(1);
1598: } else if (MDOC_HEAD != node->type)
1599: return(1);
1600:
1.17 kristaps 1601: /* XXX - groff shows only first parameter */
1602:
1.16 kristaps 1603: p->flags |= ttypes[TTYPE_FUNC_NAME];
1604: for (n = node->child; n; n = n->next) {
1.44 kristaps 1605: if (MDOC_TEXT != n->type)
1606: errx(1, "expected text line argument");
1607: word(p, n->string);
1.16 kristaps 1608: }
1609: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1610:
1611: return(0);
1612: }
1613:
1614:
1615: /* ARGSUSED */
1616: static void
1617: termp_fo_post(DECL_ARGS)
1618: {
1619:
1620: if (MDOC_BODY != node->type)
1621: return;
1622: word(p, ")");
1623: word(p, ";");
1624: newln(p);
1625: }
1626:
1627:
1.17 kristaps 1628: /* ARGSUSED */
1629: static int
1630: termp_bf_pre(DECL_ARGS)
1631: {
1632: const struct mdoc_node *n;
1633:
1.44 kristaps 1634: if (MDOC_HEAD == node->type) {
1.17 kristaps 1635: return(0);
1.44 kristaps 1636: } else if (MDOC_BLOCK != node->type)
1.17 kristaps 1637: return(1);
1638:
1.44 kristaps 1639: if (NULL == (n = node->head->child)) {
1640: if (arg_hasattr(MDOC_Emphasis, node))
1.31 kristaps 1641: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.44 kristaps 1642: else if (arg_hasattr(MDOC_Symbolic, node))
1.31 kristaps 1643: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1644:
1645: return(1);
1646: }
1647:
1.44 kristaps 1648: if (MDOC_TEXT != n->type)
1649: errx(1, "expected text line arguments");
1.17 kristaps 1650:
1.44 kristaps 1651: if (0 == strcmp("Em", n->string))
1.31 kristaps 1652: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.44 kristaps 1653: else if (0 == strcmp("Sy", n->string))
1.31 kristaps 1654: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1655:
1656: return(1);
1657: }
1658:
1659:
1660: /* ARGSUSED */
1661: static int
1662: termp_sy_pre(DECL_ARGS)
1663: {
1664:
1.31 kristaps 1665: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1666: return(1);
1667: }
1668:
1669:
1670: /* ARGSUSED */
1671: static int
1672: termp_ms_pre(DECL_ARGS)
1673: {
1674:
1.31 kristaps 1675: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1676: return(1);
1677: }
1678:
1.22 kristaps 1679:
1680:
1681: /* ARGSUSED */
1682: static int
1683: termp_sm_pre(DECL_ARGS)
1684: {
1685:
1686: #if notyet
1687: assert(node->child);
1688: if (0 == strcmp("off", node->child->data.text.string)) {
1689: p->flags &= ~TERMP_NONOSPACE;
1690: p->flags &= ~TERMP_NOSPACE;
1691: } else {
1692: p->flags |= TERMP_NONOSPACE;
1693: p->flags |= TERMP_NOSPACE;
1694: }
1695: #endif
1696:
1697: return(0);
1698: }
1.28 kristaps 1699:
1700:
1701: /* ARGSUSED */
1702: static int
1703: termp__t_pre(DECL_ARGS)
1704: {
1705:
1.41 kristaps 1706: /* FIXME: titles are underlined. */
1.28 kristaps 1707: word(p, "\"");
1708: p->flags |= TERMP_NOSPACE;
1709: return(1);
1710: }
1711:
1712:
1713: /* ARGSUSED */
1714: static void
1715: termp__t_post(DECL_ARGS)
1716: {
1717:
1718: p->flags |= TERMP_NOSPACE;
1.41 kristaps 1719: /* FIXME: titles are underlined. */
1.28 kristaps 1720: word(p, "\"");
1721: word(p, node->next ? "," : ".");
1722: }
1723:
1724:
1725: /* ARGSUSED */
1726: static void
1727: termp____post(DECL_ARGS)
1728: {
1729:
1730: p->flags |= TERMP_NOSPACE;
1731: word(p, node->next ? "," : ".");
1732: }
CVSweb