Annotation of mandoc/term.c, Revision 1.46
1.46 ! kristaps 1: /* $Id: term.c,v 1.45 2009/03/08 13:57:07 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);
123: DECL_PREPOST(termp_op);
124: DECL_PREPOST(termp_pf);
1.15 kristaps 125: DECL_PREPOST(termp_pq);
1.10 kristaps 126: DECL_PREPOST(termp_qq);
127: DECL_PREPOST(termp_sh);
128: DECL_PREPOST(termp_ss);
129: DECL_PREPOST(termp_sq);
130: DECL_PREPOST(termp_vt);
131:
1.18 kristaps 132: DECL_PRE(termp_ar);
1.14 kristaps 133: DECL_PRE(termp_at);
1.18 kristaps 134: DECL_PRE(termp_bf);
1.15 kristaps 135: DECL_PRE(termp_bsx);
1.17 kristaps 136: DECL_PRE(termp_bt);
1.18 kristaps 137: DECL_PRE(termp_cd);
138: DECL_PRE(termp_cm);
139: DECL_PRE(termp_em);
1.10 kristaps 140: DECL_PRE(termp_ex);
1.18 kristaps 141: DECL_PRE(termp_fa);
142: DECL_PRE(termp_fl);
1.16 kristaps 143: DECL_PRE(termp_fx);
1.18 kristaps 144: DECL_PRE(termp_ic);
145: DECL_PRE(termp_ms);
1.10 kristaps 146: DECL_PRE(termp_nd);
1.18 kristaps 147: DECL_PRE(termp_nm);
1.10 kristaps 148: DECL_PRE(termp_ns);
149: DECL_PRE(termp_nx);
150: DECL_PRE(termp_ox);
1.18 kristaps 151: DECL_PRE(termp_pa);
1.10 kristaps 152: DECL_PRE(termp_pp);
1.28 kristaps 153: DECL_PRE(termp_rs);
1.14 kristaps 154: DECL_PRE(termp_rv);
1.22 kristaps 155: DECL_PRE(termp_sm);
1.14 kristaps 156: DECL_PRE(termp_st);
1.18 kristaps 157: DECL_PRE(termp_sx);
158: DECL_PRE(termp_sy);
1.10 kristaps 159: DECL_PRE(termp_ud);
1.16 kristaps 160: DECL_PRE(termp_ux);
1.18 kristaps 161: DECL_PRE(termp_va);
1.10 kristaps 162: DECL_PRE(termp_xr);
163:
1.28 kristaps 164: DECL_POST(termp___);
1.10 kristaps 165: DECL_POST(termp_bl);
1.31 kristaps 166: DECL_POST(termp_bx);
1.43 kristaps 167: DECL_POST(termp_lb);
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.43 kristaps 276: { NULL, 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.43 kristaps 973: static void
974: termp_lb_post(DECL_ARGS)
975: {
976:
977: newln(p);
978: }
979:
980:
981: /* ARGSUSED */
1.17 kristaps 982: static int
1.10 kristaps 983: termp_ud_pre(DECL_ARGS)
984: {
985:
986: word(p, "currently under development.");
987: return(1);
988: }
989:
990:
991: /* ARGSUSED */
992: static int
993: termp_d1_pre(DECL_ARGS)
994: {
995:
996: if (MDOC_BODY != node->type)
997: return(1);
998: newln(p);
1.19 kristaps 999: p->offset += (pair->offset = INDENT);
1.10 kristaps 1000: return(1);
1.2 kristaps 1001: }
1002:
1003:
1.10 kristaps 1004: /* ARGSUSED */
1.2 kristaps 1005: static void
1.10 kristaps 1006: termp_d1_post(DECL_ARGS)
1007: {
1008:
1009: if (MDOC_BODY != node->type)
1010: return;
1011: newln(p);
1.19 kristaps 1012: p->offset -= pair->offset;
1.10 kristaps 1013: }
1014:
1015:
1016: /* ARGSUSED */
1017: static int
1018: termp_aq_pre(DECL_ARGS)
1.6 kristaps 1019: {
1020:
1.10 kristaps 1021: if (MDOC_BODY != node->type)
1022: return(1);
1.40 kristaps 1023: word(p, "\\(la");
1.10 kristaps 1024: p->flags |= TERMP_NOSPACE;
1025: return(1);
1026: }
1.6 kristaps 1027:
1028:
1.10 kristaps 1029: /* ARGSUSED */
1030: static void
1031: termp_aq_post(DECL_ARGS)
1032: {
1.6 kristaps 1033:
1.10 kristaps 1034: if (MDOC_BODY != node->type)
1.6 kristaps 1035: return;
1.10 kristaps 1036: p->flags |= TERMP_NOSPACE;
1.40 kristaps 1037: word(p, "\\(ra");
1.10 kristaps 1038: }
1.6 kristaps 1039:
1.10 kristaps 1040:
1041: /* ARGSUSED */
1042: static int
1043: termp_ft_pre(DECL_ARGS)
1044: {
1045:
1.34 kristaps 1046: if (SEC_SYNOPSIS == node->sec)
1047: if (node->prev && MDOC_Fo == node->prev->tok)
1048: vspace(p);
1.31 kristaps 1049: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 1050: return(1);
1.6 kristaps 1051: }
1052:
1053:
1.10 kristaps 1054: /* ARGSUSED */
1.6 kristaps 1055: static void
1.10 kristaps 1056: termp_ft_post(DECL_ARGS)
1.2 kristaps 1057: {
1058:
1.34 kristaps 1059: if (SEC_SYNOPSIS == node->sec)
1.10 kristaps 1060: newln(p);
1061: }
1.2 kristaps 1062:
1063:
1.10 kristaps 1064: /* ARGSUSED */
1065: static int
1066: termp_fn_pre(DECL_ARGS)
1067: {
1068: const struct mdoc_node *n;
1069:
1.44 kristaps 1070: if (NULL == node->child)
1071: errx(1, "expected text line arguments");
1072: if (MDOC_TEXT != node->child->type)
1073: errx(1, "expected text line arguments");
1.2 kristaps 1074:
1.10 kristaps 1075: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 1076:
1.10 kristaps 1077: p->flags |= ttypes[TTYPE_FUNC_NAME];
1.44 kristaps 1078: word(p, node->child->string);
1.10 kristaps 1079: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1080:
1081: word(p, "(");
1082:
1083: p->flags |= TERMP_NOSPACE;
1084: for (n = node->child->next; n; n = n->next) {
1.44 kristaps 1085: if (MDOC_TEXT != n->type)
1086: errx(1, "expected text line arguments");
1.10 kristaps 1087: p->flags |= ttypes[TTYPE_FUNC_ARG];
1.44 kristaps 1088: word(p, n->string);
1.10 kristaps 1089: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 1090: if (n->next)
1.10 kristaps 1091: word(p, ",");
1.6 kristaps 1092: }
1.2 kristaps 1093:
1.10 kristaps 1094: word(p, ")");
1095:
1096: if (SEC_SYNOPSIS == node->sec)
1097: word(p, ";");
1098:
1099: return(0);
1.2 kristaps 1100: }
1101:
1102:
1.10 kristaps 1103: /* ARGSUSED */
1104: static void
1105: termp_fn_post(DECL_ARGS)
1.2 kristaps 1106: {
1107:
1.30 kristaps 1108: if (node->sec == SEC_SYNOPSIS && node->next)
1.10 kristaps 1109: vspace(p);
1110:
1111: }
1.2 kristaps 1112:
1113:
1.10 kristaps 1114: /* ARGSUSED */
1115: static int
1116: termp_sx_pre(DECL_ARGS)
1117: {
1.8 kristaps 1118:
1.31 kristaps 1119: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK]);
1.10 kristaps 1120: return(1);
1.2 kristaps 1121: }
1122:
1123:
1.10 kristaps 1124: /* ARGSUSED */
1125: static int
1126: termp_fa_pre(DECL_ARGS)
1127: {
1.16 kristaps 1128: struct mdoc_node *n;
1129:
1130: if (node->parent->tok != MDOC_Fo) {
1.31 kristaps 1131: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 1132: return(1);
1133: }
1134:
1135: for (n = node->child; n; n = n->next) {
1.44 kristaps 1136: if (MDOC_TEXT != n->type)
1137: errx(1, "expected text line arguments");
1.16 kristaps 1138:
1139: p->flags |= ttypes[TTYPE_FUNC_ARG];
1.44 kristaps 1140: word(p, n->string);
1.16 kristaps 1141: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1142:
1143: if (n->next)
1144: word(p, ",");
1145: }
1146:
1147: if (node->next && node->next->tok == MDOC_Fa)
1148: word(p, ",");
1.2 kristaps 1149:
1.16 kristaps 1150: return(0);
1.10 kristaps 1151: }
1.2 kristaps 1152:
1153:
1.10 kristaps 1154: /* ARGSUSED */
1155: static int
1156: termp_va_pre(DECL_ARGS)
1157: {
1.2 kristaps 1158:
1.31 kristaps 1159: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 1160: return(1);
1.2 kristaps 1161: }
1162:
1163:
1.10 kristaps 1164: /* ARGSUSED */
1165: static int
1166: termp_bd_pre(DECL_ARGS)
1167: {
1.35 kristaps 1168: const struct mdoc_node *n;
1.44 kristaps 1169: int i, type;
1.1 kristaps 1170:
1.10 kristaps 1171: if (MDOC_BLOCK == node->type) {
1.30 kristaps 1172: if (node->prev)
1173: vspace(p);
1.10 kristaps 1174: return(1);
1175: } else if (MDOC_BODY != node->type)
1176: return(1);
1177:
1.44 kristaps 1178: if (NULL == node->parent->args)
1179: errx(1, "missing display type");
1180:
1.20 kristaps 1181: pair->offset = p->offset;
1.10 kristaps 1182:
1.44 kristaps 1183: for (type = -1, i = 0;
1184: i < (int)node->parent->args->argc; i++) {
1185: switch (node->parent->args->argv[i].arg) {
1.35 kristaps 1186: case (MDOC_Ragged):
1187: /* FALLTHROUGH */
1188: case (MDOC_Filled):
1189: /* FALLTHROUGH */
1190: case (MDOC_Unfilled):
1191: /* FALLTHROUGH */
1192: case (MDOC_Literal):
1.44 kristaps 1193: type = node->parent->args->argv[i].arg;
1194: i = (int)node->parent->args->argc;
1.35 kristaps 1195: break;
1196: default:
1.44 kristaps 1197: break;
1.35 kristaps 1198: }
1199: }
1200:
1.44 kristaps 1201: if (NULL == node->parent->args)
1202: errx(1, "missing display type");
1.12 kristaps 1203:
1.44 kristaps 1204: i = arg_getattr(MDOC_Offset, node->parent);
1.12 kristaps 1205: if (-1 != i) {
1.45 kristaps 1206: if (1 != node->parent->args->argv[i].sz)
1.44 kristaps 1207: errx(1, "expected single value");
1.45 kristaps 1208: p->offset += arg_offset(&node->parent->args->argv[i]);
1.12 kristaps 1209: }
1210:
1.35 kristaps 1211: switch (type) {
1212: case (MDOC_Literal):
1213: /* FALLTHROUGH */
1214: case (MDOC_Unfilled):
1215: break;
1216: default:
1217: return(1);
1218: }
1219:
1.10 kristaps 1220: p->flags |= TERMP_LITERAL;
1221:
1222: for (n = node->child; n; n = n->next) {
1.35 kristaps 1223: if (MDOC_TEXT != n->type) {
1224: warnx("non-text children not yet allowed");
1225: continue;
1226: }
1.44 kristaps 1227: word(p, n->string);
1.35 kristaps 1228: flushln(p);
1.10 kristaps 1229: }
1.1 kristaps 1230:
1.10 kristaps 1231: return(0);
1232: }
1.1 kristaps 1233:
1234:
1.10 kristaps 1235: /* ARGSUSED */
1.12 kristaps 1236: static void
1237: termp_bd_post(DECL_ARGS)
1238: {
1239:
1.20 kristaps 1240: if (MDOC_BODY != node->type)
1241: return;
1.35 kristaps 1242:
1243: if ( ! (p->flags & TERMP_LITERAL))
1244: flushln(p);
1245:
1246: p->flags &= ~TERMP_LITERAL;
1.20 kristaps 1247: p->offset = pair->offset;
1.12 kristaps 1248: }
1249:
1250:
1251: /* ARGSUSED */
1.10 kristaps 1252: static int
1253: termp_qq_pre(DECL_ARGS)
1254: {
1.1 kristaps 1255:
1.10 kristaps 1256: if (MDOC_BODY != node->type)
1257: return(1);
1258: word(p, "\"");
1259: p->flags |= TERMP_NOSPACE;
1260: return(1);
1.1 kristaps 1261: }
1262:
1263:
1.10 kristaps 1264: /* ARGSUSED */
1.1 kristaps 1265: static void
1.10 kristaps 1266: termp_qq_post(DECL_ARGS)
1.1 kristaps 1267: {
1268:
1.10 kristaps 1269: if (MDOC_BODY != node->type)
1270: return;
1271: p->flags |= TERMP_NOSPACE;
1272: word(p, "\"");
1273: }
1274:
1275:
1276: /* ARGSUSED */
1277: static int
1.15 kristaps 1278: termp_bsx_pre(DECL_ARGS)
1279: {
1280:
1281: word(p, "BSDI BSD/OS");
1282: return(1);
1283: }
1284:
1285:
1286: /* ARGSUSED */
1.31 kristaps 1287: static void
1288: termp_bx_post(DECL_ARGS)
1.10 kristaps 1289: {
1.1 kristaps 1290:
1.34 kristaps 1291: if (node->child)
1292: p->flags |= TERMP_NOSPACE;
1.10 kristaps 1293: word(p, "BSD");
1294: }
1295:
1296:
1297: /* ARGSUSED */
1298: static int
1299: termp_ox_pre(DECL_ARGS)
1300: {
1301:
1302: word(p, "OpenBSD");
1303: return(1);
1304: }
1305:
1306:
1307: /* ARGSUSED */
1308: static int
1.16 kristaps 1309: termp_ux_pre(DECL_ARGS)
1310: {
1311:
1312: word(p, "UNIX");
1313: return(1);
1314: }
1315:
1316:
1317: /* ARGSUSED */
1318: static int
1319: termp_fx_pre(DECL_ARGS)
1320: {
1321:
1322: word(p, "FreeBSD");
1323: return(1);
1324: }
1325:
1326:
1327: /* ARGSUSED */
1328: static int
1.10 kristaps 1329: termp_nx_pre(DECL_ARGS)
1330: {
1331:
1332: word(p, "NetBSD");
1333: return(1);
1334: }
1335:
1336:
1337: /* ARGSUSED */
1338: static int
1339: termp_sq_pre(DECL_ARGS)
1340: {
1341:
1342: if (MDOC_BODY != node->type)
1343: return(1);
1.28 kristaps 1344: word(p, "`");
1.10 kristaps 1345: p->flags |= TERMP_NOSPACE;
1346: return(1);
1347: }
1.1 kristaps 1348:
1349:
1.10 kristaps 1350: /* ARGSUSED */
1351: static void
1352: termp_sq_post(DECL_ARGS)
1353: {
1354:
1355: if (MDOC_BODY != node->type)
1356: return;
1357: p->flags |= TERMP_NOSPACE;
1358: word(p, "\'");
1359: }
1.2 kristaps 1360:
1361:
1.10 kristaps 1362: /* ARGSUSED */
1363: static int
1364: termp_pf_pre(DECL_ARGS)
1365: {
1.1 kristaps 1366:
1.10 kristaps 1367: p->flags |= TERMP_IGNDELIM;
1368: return(1);
1369: }
1.1 kristaps 1370:
1371:
1.10 kristaps 1372: /* ARGSUSED */
1373: static void
1374: termp_pf_post(DECL_ARGS)
1375: {
1.1 kristaps 1376:
1.10 kristaps 1377: p->flags &= ~TERMP_IGNDELIM;
1378: p->flags |= TERMP_NOSPACE;
1379: }
1.1 kristaps 1380:
1381:
1.10 kristaps 1382: /* ARGSUSED */
1383: static int
1384: termp_ss_pre(DECL_ARGS)
1385: {
1.1 kristaps 1386:
1.10 kristaps 1387: switch (node->type) {
1388: case (MDOC_HEAD):
1389: vspace(p);
1.31 kristaps 1390: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1391: p->offset = INDENT / 2;
1392: break;
1393: default:
1394: break;
1395: }
1.1 kristaps 1396:
1.10 kristaps 1397: return(1);
1.1 kristaps 1398: }
1399:
1400:
1.10 kristaps 1401: /* ARGSUSED */
1402: static void
1403: termp_ss_post(DECL_ARGS)
1.1 kristaps 1404: {
1405:
1.10 kristaps 1406: switch (node->type) {
1407: case (MDOC_HEAD):
1408: newln(p);
1409: p->offset = INDENT;
1410: break;
1411: default:
1412: break;
1413: }
1414: }
1.2 kristaps 1415:
1416:
1.10 kristaps 1417: /* ARGSUSED */
1418: static int
1419: termp_pa_pre(DECL_ARGS)
1420: {
1.2 kristaps 1421:
1.31 kristaps 1422: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1423: return(1);
1.1 kristaps 1424: }
1425:
1426:
1.10 kristaps 1427: /* ARGSUSED */
1.11 kristaps 1428: static int
1429: termp_em_pre(DECL_ARGS)
1430: {
1431:
1.31 kristaps 1432: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1433: return(1);
1434: }
1435:
1436:
1437: /* ARGSUSED */
1.14 kristaps 1438: static int
1439: termp_cd_pre(DECL_ARGS)
1440: {
1441:
1.31 kristaps 1442: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CONFIG]);
1.33 kristaps 1443: newln(p);
1.14 kristaps 1444: return(1);
1445: }
1446:
1447:
1448: /* ARGSUSED */
1449: static int
1450: termp_cm_pre(DECL_ARGS)
1451: {
1452:
1.31 kristaps 1453: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1454: return(1);
1455: }
1456:
1457:
1458: /* ARGSUSED */
1459: static int
1460: termp_ic_pre(DECL_ARGS)
1461: {
1462:
1.31 kristaps 1463: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1464: return(1);
1465: }
1466:
1467:
1468: /* ARGSUSED */
1469: static int
1470: termp_in_pre(DECL_ARGS)
1471: {
1472:
1.31 kristaps 1473: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_INCLUDE]);
1.30 kristaps 1474: word(p, "#include");
1475: word(p, "<");
1476: p->flags |= TERMP_NOSPACE;
1.14 kristaps 1477: return(1);
1478: }
1479:
1480:
1481: /* ARGSUSED */
1.30 kristaps 1482: static void
1483: termp_in_post(DECL_ARGS)
1484: {
1485:
1486: p->flags |= TERMP_NOSPACE;
1487: word(p, ">");
1488:
1489: newln(p);
1490: if (SEC_SYNOPSIS != node->sec)
1491: return;
1492: if (node->next && MDOC_In != node->next->tok)
1493: vspace(p);
1494: }
1495:
1496:
1497: /* ARGSUSED */
1.14 kristaps 1498: static int
1499: termp_at_pre(DECL_ARGS)
1500: {
1.43 kristaps 1501: const char *att;
1502:
1503: att = NULL;
1.14 kristaps 1504:
1505: if (node->child) {
1.44 kristaps 1506: if (MDOC_TEXT != node->child->type)
1507: errx(1, "expected text line argument");
1508: att = mdoc_a2att(node->child->string);
1.14 kristaps 1509: }
1510:
1.43 kristaps 1511: if (NULL == att)
1512: att = "AT&T UNIX";
1513:
1514: word(p, att);
1.14 kristaps 1515: return(0);
1516: }
1.15 kristaps 1517:
1518:
1519: /* ARGSUSED */
1520: static int
1521: termp_bq_pre(DECL_ARGS)
1522: {
1523:
1524: if (MDOC_BODY != node->type)
1525: return(1);
1.30 kristaps 1526: word(p, "[");
1.15 kristaps 1527: p->flags |= TERMP_NOSPACE;
1528: return(1);
1529: }
1530:
1531:
1532: /* ARGSUSED */
1533: static void
1534: termp_bq_post(DECL_ARGS)
1535: {
1536:
1537: if (MDOC_BODY != node->type)
1538: return;
1539: word(p, "]");
1540: }
1541:
1542:
1543: /* ARGSUSED */
1544: static int
1545: termp_pq_pre(DECL_ARGS)
1546: {
1547:
1548: if (MDOC_BODY != node->type)
1549: return(1);
1.31 kristaps 1550: word(p, "\\&(");
1.15 kristaps 1551: p->flags |= TERMP_NOSPACE;
1552: return(1);
1553: }
1554:
1555:
1556: /* ARGSUSED */
1557: static void
1558: termp_pq_post(DECL_ARGS)
1559: {
1560:
1561: if (MDOC_BODY != node->type)
1562: return;
1563: word(p, ")");
1564: }
1565:
1566:
1.16 kristaps 1567: /* ARGSUSED */
1568: static int
1569: termp_fo_pre(DECL_ARGS)
1570: {
1571: const struct mdoc_node *n;
1572:
1573: if (MDOC_BODY == node->type) {
1574: word(p, "(");
1575: p->flags |= TERMP_NOSPACE;
1576: return(1);
1577: } else if (MDOC_HEAD != node->type)
1578: return(1);
1579:
1.17 kristaps 1580: /* XXX - groff shows only first parameter */
1581:
1.16 kristaps 1582: p->flags |= ttypes[TTYPE_FUNC_NAME];
1583: for (n = node->child; n; n = n->next) {
1.44 kristaps 1584: if (MDOC_TEXT != n->type)
1585: errx(1, "expected text line argument");
1586: word(p, n->string);
1.16 kristaps 1587: }
1588: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1589:
1590: return(0);
1591: }
1592:
1593:
1594: /* ARGSUSED */
1595: static void
1596: termp_fo_post(DECL_ARGS)
1597: {
1598:
1599: if (MDOC_BODY != node->type)
1600: return;
1601: word(p, ")");
1602: word(p, ";");
1603: newln(p);
1604: }
1605:
1606:
1.17 kristaps 1607: /* ARGSUSED */
1608: static int
1609: termp_bf_pre(DECL_ARGS)
1610: {
1611: const struct mdoc_node *n;
1612:
1.44 kristaps 1613: if (MDOC_HEAD == node->type) {
1.17 kristaps 1614: return(0);
1.44 kristaps 1615: } else if (MDOC_BLOCK != node->type)
1.17 kristaps 1616: return(1);
1617:
1.44 kristaps 1618: if (NULL == (n = node->head->child)) {
1619: if (arg_hasattr(MDOC_Emphasis, node))
1.31 kristaps 1620: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.44 kristaps 1621: else if (arg_hasattr(MDOC_Symbolic, node))
1.31 kristaps 1622: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1623:
1624: return(1);
1625: }
1626:
1.44 kristaps 1627: if (MDOC_TEXT != n->type)
1628: errx(1, "expected text line arguments");
1.17 kristaps 1629:
1.44 kristaps 1630: if (0 == strcmp("Em", n->string))
1.31 kristaps 1631: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.44 kristaps 1632: else if (0 == strcmp("Sy", n->string))
1.31 kristaps 1633: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1634:
1635: return(1);
1636: }
1637:
1638:
1639: /* ARGSUSED */
1640: static int
1641: termp_sy_pre(DECL_ARGS)
1642: {
1643:
1.31 kristaps 1644: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1645: return(1);
1646: }
1647:
1648:
1649: /* ARGSUSED */
1650: static int
1651: termp_ms_pre(DECL_ARGS)
1652: {
1653:
1.31 kristaps 1654: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1655: return(1);
1656: }
1657:
1.22 kristaps 1658:
1659:
1660: /* ARGSUSED */
1661: static int
1662: termp_sm_pre(DECL_ARGS)
1663: {
1664:
1665: #if notyet
1666: assert(node->child);
1667: if (0 == strcmp("off", node->child->data.text.string)) {
1668: p->flags &= ~TERMP_NONOSPACE;
1669: p->flags &= ~TERMP_NOSPACE;
1670: } else {
1671: p->flags |= TERMP_NONOSPACE;
1672: p->flags |= TERMP_NOSPACE;
1673: }
1674: #endif
1675:
1676: return(0);
1677: }
1.28 kristaps 1678:
1679:
1680: /* ARGSUSED */
1681: static int
1682: termp__t_pre(DECL_ARGS)
1683: {
1684:
1.41 kristaps 1685: /* FIXME: titles are underlined. */
1.28 kristaps 1686: word(p, "\"");
1687: p->flags |= TERMP_NOSPACE;
1688: return(1);
1689: }
1690:
1691:
1692: /* ARGSUSED */
1693: static void
1694: termp__t_post(DECL_ARGS)
1695: {
1696:
1697: p->flags |= TERMP_NOSPACE;
1.41 kristaps 1698: /* FIXME: titles are underlined. */
1.28 kristaps 1699: word(p, "\"");
1700: word(p, node->next ? "," : ".");
1701: }
1702:
1703:
1704: /* ARGSUSED */
1705: static void
1706: termp____post(DECL_ARGS)
1707: {
1708:
1709: p->flags |= TERMP_NOSPACE;
1710: word(p, node->next ? "," : ".");
1711: }
CVSweb