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