Annotation of mandoc/term.c, Revision 1.38
1.38 ! kristaps 1: /* $Id: term.c,v 1.37 2009/03/03 22:17:19 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.10 kristaps 86: static int arg_hasattr(int, size_t,
87: const struct mdoc_arg *);
88: static int arg_getattr(int, size_t,
89: const struct mdoc_arg *);
1.12 kristaps 90: static size_t arg_offset(const struct mdoc_arg *);
91: static size_t arg_width(const struct mdoc_arg *);
1.10 kristaps 92:
93: /*
94: * What follows describes prefix and postfix operations for the abstract
95: * syntax tree descent.
96: */
1.1 kristaps 97:
1.10 kristaps 98: #define DECL_ARGS \
99: struct termp *p, \
1.18 kristaps 100: struct termpair *pair, \
1.10 kristaps 101: const struct mdoc_meta *meta, \
102: const struct mdoc_node *node
103:
104: #define DECL_PRE(name) \
105: static int name##_pre(DECL_ARGS)
106: #define DECL_POST(name) \
107: static void name##_post(DECL_ARGS)
108: #define DECL_PREPOST(name) \
109: DECL_PRE(name); \
110: DECL_POST(name);
111:
1.28 kristaps 112: DECL_PREPOST(termp__t);
1.10 kristaps 113: DECL_PREPOST(termp_aq);
1.12 kristaps 114: DECL_PREPOST(termp_bd);
1.15 kristaps 115: DECL_PREPOST(termp_bq);
1.10 kristaps 116: DECL_PREPOST(termp_d1);
117: DECL_PREPOST(termp_dq);
118: DECL_PREPOST(termp_fd);
119: DECL_PREPOST(termp_fn);
1.16 kristaps 120: DECL_PREPOST(termp_fo);
1.10 kristaps 121: DECL_PREPOST(termp_ft);
1.30 kristaps 122: DECL_PREPOST(termp_in);
1.10 kristaps 123: DECL_PREPOST(termp_it);
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.2 kristaps 276: };
277:
1.10 kristaps 278: const struct termact *termacts = __termacts;
279:
280:
281: static size_t
1.12 kristaps 282: arg_width(const struct mdoc_arg *arg)
1.10 kristaps 283: {
1.27 kristaps 284: size_t v;
285: int i, len;
1.12 kristaps 286:
287: assert(*arg->value);
1.25 kristaps 288: if (0 == strcmp(*arg->value, "indent"))
289: return(INDENT);
290: if (0 == strcmp(*arg->value, "indent-two"))
291: return(INDENT * 2);
292:
1.27 kristaps 293: len = (int)strlen(*arg->value);
1.25 kristaps 294: assert(len > 0);
295:
296: for (i = 0; i < len - 1; i++)
297: if ( ! isdigit((int)(*arg->value)[i]))
298: break;
299:
300: if (i == len - 1) {
301: if ('n' == (*arg->value)[len - 1]) {
302: v = (size_t)atoi(*arg->value);
303: return(v);
304: }
305:
306: }
1.31 kristaps 307: return(strlen(*arg->value) + 1);
1.12 kristaps 308: }
309:
310:
311: static size_t
312: arg_offset(const struct mdoc_arg *arg)
313: {
314:
315: /* TODO */
316: assert(*arg->value);
317: if (0 == strcmp(*arg->value, "indent"))
1.10 kristaps 318: return(INDENT);
1.12 kristaps 319: if (0 == strcmp(*arg->value, "indent-two"))
1.10 kristaps 320: return(INDENT * 2);
1.12 kristaps 321: return(strlen(*arg->value));
1.10 kristaps 322: }
323:
1.3 kristaps 324:
1.10 kristaps 325: static int
326: arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
1.2 kristaps 327: {
328:
1.10 kristaps 329: return(-1 != arg_getattr(arg, argc, argv));
330: }
331:
332:
333: static int
334: arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
335: {
336: int i;
337:
338: for (i = 0; i < (int)argc; i++)
339: if (argv[i].arg == arg)
340: return(i);
341: return(-1);
342: }
343:
344:
345: /* ARGSUSED */
346: static int
347: termp_dq_pre(DECL_ARGS)
348: {
349:
350: if (MDOC_BODY != node->type)
351: return(1);
352:
353: word(p, "``");
354: p->flags |= TERMP_NOSPACE;
355: return(1);
356: }
357:
358:
359: /* ARGSUSED */
360: static void
361: termp_dq_post(DECL_ARGS)
362: {
363:
364: if (MDOC_BODY != node->type)
365: return;
1.3 kristaps 366:
1.10 kristaps 367: p->flags |= TERMP_NOSPACE;
368: word(p, "''");
369: }
1.2 kristaps 370:
1.3 kristaps 371:
1.10 kristaps 372: /* ARGSUSED */
1.20 kristaps 373: static int
374: termp_it_pre(DECL_ARGS)
1.10 kristaps 375: {
376: const struct mdoc_node *n, *it;
377: const struct mdoc_block *bl;
1.23 kristaps 378: char buf[7], *tp;
379: int i, type;
1.12 kristaps 380: size_t width, offset;
1.2 kristaps 381:
1.10 kristaps 382: switch (node->type) {
383: case (MDOC_BODY):
384: /* FALLTHROUGH */
385: case (MDOC_HEAD):
1.20 kristaps 386: it = node->parent;
387: break;
388: case (MDOC_BLOCK):
389: it = node;
1.10 kristaps 390: break;
391: default:
1.20 kristaps 392: return(1);
1.8 kristaps 393: }
394:
1.21 kristaps 395: n = it->parent->parent;
1.10 kristaps 396: bl = &n->data.block;
397:
1.20 kristaps 398: if (MDOC_BLOCK == node->type) {
1.29 kristaps 399: newln(p);
400: if ( ! arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
401: if (node->prev || n->prev)
402: vspace(p);
1.20 kristaps 403: return(1);
404: }
405:
1.23 kristaps 406: /* Get our list type. */
407:
1.24 kristaps 408: for (type = -1, i = 0; i < (int)bl->argc; i++)
1.23 kristaps 409: switch (bl->argv[i].arg) {
410: case (MDOC_Bullet):
411: /* FALLTHROUGH */
412: case (MDOC_Dash):
413: /* FALLTHROUGH */
414: case (MDOC_Enum):
415: /* FALLTHROUGH */
416: case (MDOC_Hyphen):
417: /* FALLTHROUGH */
418: case (MDOC_Tag):
419: /* FALLTHROUGH */
1.37 kristaps 420: case (MDOC_Inset):
421: /* FALLTHROUGH */
422: case (MDOC_Diag):
423: /* FALLTHROUGH */
1.23 kristaps 424: case (MDOC_Ohang):
425: type = bl->argv[i].arg;
426: i = (int)bl->argc;
427: break;
1.24 kristaps 428: default:
1.23 kristaps 429: errx(1, "list type not supported");
430: /* NOTREACHED */
431: }
432:
1.24 kristaps 433: assert(-1 != type);
434:
1.23 kristaps 435: /* Save our existing (inherited) margin and offset. */
436:
1.20 kristaps 437: pair->offset = p->offset;
438: pair->rmargin = p->rmargin;
439:
1.23 kristaps 440: /* Get list width and offset. */
441:
1.20 kristaps 442: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
1.23 kristaps 443: width = i >= 0 ? arg_width(&bl->argv[i]) : 0;
1.20 kristaps 444:
445: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
446: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
447:
1.23 kristaps 448: /* Override the width. */
1.10 kristaps 449:
1.23 kristaps 450: switch (type) {
451: case (MDOC_Bullet):
452: /* FALLTHROUGH */
453: case (MDOC_Dash):
454: /* FALLTHROUGH */
455: case (MDOC_Enum):
456: /* FALLTHROUGH */
457: case (MDOC_Hyphen):
1.38 ! kristaps 458: width = width > 4 ? width : 4;
1.23 kristaps 459: break;
460: case (MDOC_Tag):
461: if (0 == width)
462: errx(1, "need non-zero -width");
463: break;
464: default:
465: break;
466: }
1.10 kristaps 467:
1.23 kristaps 468: /* Word-wrap control. */
1.21 kristaps 469:
1.23 kristaps 470: switch (type) {
1.37 kristaps 471: case (MDOC_Diag):
1.38 ! kristaps 472: /* XXX - ignore child macros!? */
1.37 kristaps 473: if (MDOC_HEAD == node->type)
474: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_DIAG]);
475: /* FALLTHROUGH */
476: case (MDOC_Inset):
477: if (MDOC_HEAD == node->type)
478: p->flags |= TERMP_NOSPACE;
479: break;
1.23 kristaps 480: case (MDOC_Bullet):
481: /* FALLTHROUGH */
482: case (MDOC_Dash):
483: /* FALLTHROUGH */
484: case (MDOC_Enum):
485: /* FALLTHROUGH */
486: case (MDOC_Hyphen):
487: /* FALLTHROUGH */
488: case (MDOC_Tag):
1.37 kristaps 489: p->flags |= TERMP_NOSPACE;
1.23 kristaps 490: if (MDOC_HEAD == node->type)
491: p->flags |= TERMP_NOBREAK;
492: else if (MDOC_BODY == node->type)
493: p->flags |= TERMP_NOLPAD;
494: break;
1.24 kristaps 495: default:
1.23 kristaps 496: break;
497: }
1.21 kristaps 498:
1.23 kristaps 499: /*
500: * Get a token to use as the HEAD lead-in. If NULL, we use the
501: * HEAD child.
502: */
1.21 kristaps 503:
1.23 kristaps 504: tp = NULL;
1.24 kristaps 505:
1.23 kristaps 506: if (MDOC_HEAD == node->type) {
507: if (arg_hasattr(MDOC_Bullet, bl->argc, bl->argv))
508: tp = "\\[bu]";
509: if (arg_hasattr(MDOC_Dash, bl->argc, bl->argv))
510: tp = "\\-";
511: if (arg_hasattr(MDOC_Enum, bl->argc, bl->argv)) {
1.21 kristaps 512: (pair->ppair->ppair->count)++;
513: (void)snprintf(buf, sizeof(buf), "%d.",
514: pair->ppair->ppair->count);
1.23 kristaps 515: tp = buf;
1.2 kristaps 516: }
1.23 kristaps 517: if (arg_hasattr(MDOC_Hyphen, bl->argc, bl->argv))
518: tp = "\\-";
519: }
1.20 kristaps 520:
1.23 kristaps 521: /* Margin control. */
1.2 kristaps 522:
1.21 kristaps 523: p->offset += offset;
1.23 kristaps 524:
525: switch (type) {
526: case (MDOC_Bullet):
527: /* FALLTHROUGH */
528: case (MDOC_Dash):
529: /* FALLTHROUGH */
530: case (MDOC_Enum):
531: /* FALLTHROUGH */
532: case (MDOC_Hyphen):
533: /* FALLTHROUGH */
534: case (MDOC_Tag):
535: if (MDOC_HEAD == node->type)
536: p->rmargin = p->offset + width;
537: else if (MDOC_BODY == node->type)
538: p->offset += width;
539: break;
1.24 kristaps 540: default:
1.23 kristaps 541: break;
542: }
543:
544: if (NULL == tp)
545: return(1);
546:
547: word(p, tp);
548: return(0);
1.10 kristaps 549: }
550:
551:
552: /* ARGSUSED */
1.20 kristaps 553: static void
554: termp_it_post(DECL_ARGS)
1.10 kristaps 555: {
1.37 kristaps 556: int type, i;
557: struct mdoc_block *bl;
1.3 kristaps 558:
1.21 kristaps 559: if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
1.20 kristaps 560: return;
1.10 kristaps 561:
1.37 kristaps 562: assert(MDOC_BLOCK == node->parent->parent->parent->type);
563: assert(MDOC_Bl == node->parent->parent->parent->tok);
564: bl = &node->parent->parent->parent->data.block;
565:
566: for (type = -1, i = 0; i < (int)bl->argc; i++)
567: switch (bl->argv[i].arg) {
568: case (MDOC_Bullet):
569: /* FALLTHROUGH */
570: case (MDOC_Dash):
571: /* FALLTHROUGH */
572: case (MDOC_Enum):
573: /* FALLTHROUGH */
574: case (MDOC_Hyphen):
575: /* FALLTHROUGH */
576: case (MDOC_Tag):
577: /* FALLTHROUGH */
578: case (MDOC_Diag):
579: /* FALLTHROUGH */
580: case (MDOC_Inset):
581: /* FALLTHROUGH */
582: case (MDOC_Ohang):
583: type = bl->argv[i].arg;
584: i = (int)bl->argc;
585: break;
586: default:
587: errx(1, "list type not supported");
588: /* NOTREACHED */
589: }
590:
591:
592: switch (type) {
593: case (MDOC_Diag):
594: /* FALLTHROUGH */
595: case (MDOC_Inset):
596: break;
597: default:
598: flushln(p);
599: break;
600: }
1.10 kristaps 601:
1.23 kristaps 602: p->offset = pair->offset;
603: p->rmargin = pair->rmargin;
1.21 kristaps 604:
1.37 kristaps 605: switch (type) {
606: case (MDOC_Inset):
607: break;
608: default:
609: if (MDOC_HEAD == node->type)
610: p->flags &= ~TERMP_NOBREAK;
611: else if (MDOC_BODY == node->type)
612: p->flags &= ~TERMP_NOLPAD;
613: break;
614: }
1.2 kristaps 615: }
616:
617:
1.10 kristaps 618: /* ARGSUSED */
1.18 kristaps 619: static int
620: termp_nm_pre(DECL_ARGS)
1.10 kristaps 621: {
622:
1.29 kristaps 623: if (SEC_SYNOPSIS == node->sec)
624: newln(p);
625:
1.31 kristaps 626: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_PROG]);
1.18 kristaps 627: if (NULL == node->child)
628: word(p, meta->name);
1.31 kristaps 629:
1.18 kristaps 630: return(1);
1.10 kristaps 631: }
632:
633:
634: /* ARGSUSED */
1.18 kristaps 635: static int
636: termp_fl_pre(DECL_ARGS)
1.10 kristaps 637: {
638:
1.31 kristaps 639: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
1.18 kristaps 640: word(p, "\\-");
641: p->flags |= TERMP_NOSPACE;
642: return(1);
1.10 kristaps 643: }
644:
645:
646: /* ARGSUSED */
647: static int
648: termp_ar_pre(DECL_ARGS)
649: {
650:
1.31 kristaps 651: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_ARG]);
652: if (NULL == node->child) {
653: word(p, "file");
654: word(p, "...");
1.29 kristaps 655: }
1.10 kristaps 656: return(1);
657: }
658:
659:
660: /* ARGSUSED */
661: static int
662: termp_ns_pre(DECL_ARGS)
1.2 kristaps 663: {
664:
665: p->flags |= TERMP_NOSPACE;
1.10 kristaps 666: return(1);
667: }
668:
669:
670: /* ARGSUSED */
671: static int
672: termp_pp_pre(DECL_ARGS)
673: {
674:
675: vspace(p);
676: return(1);
677: }
678:
679:
680: /* ARGSUSED */
681: static int
1.14 kristaps 682: termp_st_pre(DECL_ARGS)
683: {
684: const char *tp;
685:
686: assert(1 == node->data.elem.argc);
687:
688: tp = mdoc_st2a(node->data.elem.argv[0].arg);
689: word(p, tp);
690:
691: return(1);
692: }
693:
694:
695: /* ARGSUSED */
696: static int
1.28 kristaps 697: termp_rs_pre(DECL_ARGS)
698: {
699:
1.30 kristaps 700: if (MDOC_BLOCK == node->type && node->prev)
1.28 kristaps 701: vspace(p);
702: return(1);
703: }
704:
705:
706: /* ARGSUSED */
707: static int
1.14 kristaps 708: termp_rv_pre(DECL_ARGS)
709: {
710: int i;
711:
712: i = arg_getattr(MDOC_Std, node->data.elem.argc,
713: node->data.elem.argv);
714: assert(i >= 0);
715:
716: newln(p);
717: word(p, "The");
718:
719: p->flags |= ttypes[TTYPE_FUNC_NAME];
720: word(p, *node->data.elem.argv[i].value);
721: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
722:
723: word(p, "() function returns the value 0 if successful;");
724: word(p, "otherwise the value -1 is returned and the");
725: word(p, "global variable");
726:
727: p->flags |= ttypes[TTYPE_VAR_DECL];
728: word(p, "errno");
729: p->flags &= ~ttypes[TTYPE_VAR_DECL];
730:
731: word(p, "is set to indicate the error.");
732:
733: return(1);
734: }
735:
736:
737: /* ARGSUSED */
738: static int
1.10 kristaps 739: termp_ex_pre(DECL_ARGS)
740: {
741: int i;
742:
743: i = arg_getattr(MDOC_Std, node->data.elem.argc,
744: node->data.elem.argv);
745: assert(i >= 0);
746:
747: word(p, "The");
748: p->flags |= ttypes[TTYPE_PROG];
749: word(p, *node->data.elem.argv[i].value);
750: p->flags &= ~ttypes[TTYPE_PROG];
751: word(p, "utility exits 0 on success, and >0 if an error occurs.");
752:
753: return(1);
754: }
755:
756:
757: /* ARGSUSED */
758: static int
759: termp_nd_pre(DECL_ARGS)
760: {
761:
762: word(p, "\\-");
763: return(1);
764: }
765:
766:
767: /* ARGSUSED */
768: static void
769: termp_bl_post(DECL_ARGS)
770: {
771:
772: if (MDOC_BLOCK == node->type)
773: newln(p);
774: }
775:
776:
777: /* ARGSUSED */
778: static void
779: termp_op_post(DECL_ARGS)
780: {
781:
782: if (MDOC_BODY != node->type)
1.2 kristaps 783: return;
1.10 kristaps 784: p->flags |= TERMP_NOSPACE;
785: word(p, "\\(rB");
786: }
787:
788:
789: /* ARGSUSED */
790: static int
791: termp_xr_pre(DECL_ARGS)
792: {
793: const struct mdoc_node *n;
794:
795: n = node->child;
796: assert(n);
797:
798: assert(MDOC_TEXT == n->type);
799: word(p, n->data.text.string);
800:
801: if (NULL == (n = n->next))
802: return(0);
803:
804: assert(MDOC_TEXT == n->type);
805: p->flags |= TERMP_NOSPACE;
806: word(p, "(");
807: p->flags |= TERMP_NOSPACE;
808: word(p, n->data.text.string);
809: p->flags |= TERMP_NOSPACE;
810: word(p, ")");
811:
812: return(0);
1.2 kristaps 813: }
814:
815:
1.10 kristaps 816: /* ARGSUSED */
817: static int
818: termp_vt_pre(DECL_ARGS)
1.2 kristaps 819: {
820:
1.10 kristaps 821: /* FIXME: this can be "type name". */
1.31 kristaps 822: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 823: return(1);
1.2 kristaps 824: }
825:
826:
1.10 kristaps 827: /* ARGSUSED */
1.2 kristaps 828: static void
1.10 kristaps 829: termp_vt_post(DECL_ARGS)
830: {
831:
832: if (node->sec == SEC_SYNOPSIS)
833: vspace(p);
834: }
835:
836:
837: /* ARGSUSED */
838: static int
839: termp_fd_pre(DECL_ARGS)
1.2 kristaps 840: {
841:
1.10 kristaps 842: /*
843: * FIXME: this naming is bad. This value is used, in general,
844: * for the #include header or other preprocessor statement.
845: */
1.31 kristaps 846: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_DECL]);
1.10 kristaps 847: return(1);
1.2 kristaps 848: }
849:
850:
1.10 kristaps 851: /* ARGSUSED */
1.2 kristaps 852: static void
1.10 kristaps 853: termp_fd_post(DECL_ARGS)
1.2 kristaps 854: {
855:
1.30 kristaps 856: if (node->sec != SEC_SYNOPSIS)
857: return;
858: newln(p);
859: if (node->next && MDOC_Fd != node->next->tok)
1.10 kristaps 860: vspace(p);
861: }
862:
863:
864: /* ARGSUSED */
865: static int
866: termp_sh_pre(DECL_ARGS)
867: {
1.2 kristaps 868:
1.10 kristaps 869: switch (node->type) {
870: case (MDOC_HEAD):
871: vspace(p);
1.31 kristaps 872: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SECTION]);
1.2 kristaps 873: break;
1.10 kristaps 874: case (MDOC_BODY):
875: p->offset = INDENT;
1.2 kristaps 876: break;
1.10 kristaps 877: default:
878: break;
879: }
880: return(1);
881: }
882:
883:
884: /* ARGSUSED */
1.19 kristaps 885: static void
886: termp_sh_post(DECL_ARGS)
887: {
888:
889: switch (node->type) {
890: case (MDOC_HEAD):
891: newln(p);
892: break;
893: case (MDOC_BODY):
894: newln(p);
895: p->offset = 0;
896: break;
897: default:
898: break;
899: }
900: }
901:
902:
903: /* ARGSUSED */
1.10 kristaps 904: static int
905: termp_op_pre(DECL_ARGS)
906: {
907:
908: switch (node->type) {
909: case (MDOC_BODY):
910: word(p, "\\(lB");
911: p->flags |= TERMP_NOSPACE;
1.2 kristaps 912: break;
913: default:
1.10 kristaps 914: break;
1.2 kristaps 915: }
1.10 kristaps 916: return(1);
917: }
918:
919:
920: /* ARGSUSED */
921: static int
1.17 kristaps 922: termp_bt_pre(DECL_ARGS)
923: {
924:
925: word(p, "is currently in beta test.");
926: return(1);
927: }
928:
929:
930: /* ARGSUSED */
931: static int
1.10 kristaps 932: termp_ud_pre(DECL_ARGS)
933: {
934:
935: word(p, "currently under development.");
936: return(1);
937: }
938:
939:
940: /* ARGSUSED */
941: static int
942: termp_d1_pre(DECL_ARGS)
943: {
944:
945: if (MDOC_BODY != node->type)
946: return(1);
947: newln(p);
1.19 kristaps 948: p->offset += (pair->offset = INDENT);
1.10 kristaps 949: return(1);
1.2 kristaps 950: }
951:
952:
1.10 kristaps 953: /* ARGSUSED */
1.2 kristaps 954: static void
1.10 kristaps 955: termp_d1_post(DECL_ARGS)
956: {
957:
958: if (MDOC_BODY != node->type)
959: return;
960: newln(p);
1.19 kristaps 961: p->offset -= pair->offset;
1.10 kristaps 962: }
963:
964:
965: /* ARGSUSED */
966: static int
967: termp_aq_pre(DECL_ARGS)
1.6 kristaps 968: {
969:
1.10 kristaps 970: if (MDOC_BODY != node->type)
971: return(1);
972: word(p, "<");
973: p->flags |= TERMP_NOSPACE;
974: return(1);
975: }
1.6 kristaps 976:
977:
1.10 kristaps 978: /* ARGSUSED */
979: static void
980: termp_aq_post(DECL_ARGS)
981: {
1.6 kristaps 982:
1.10 kristaps 983: if (MDOC_BODY != node->type)
1.6 kristaps 984: return;
1.10 kristaps 985: p->flags |= TERMP_NOSPACE;
986: word(p, ">");
987: }
1.6 kristaps 988:
1.10 kristaps 989:
990: /* ARGSUSED */
991: static int
992: termp_ft_pre(DECL_ARGS)
993: {
994:
1.34 kristaps 995: if (SEC_SYNOPSIS == node->sec)
996: if (node->prev && MDOC_Fo == node->prev->tok)
997: vspace(p);
1.31 kristaps 998: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 999: return(1);
1.6 kristaps 1000: }
1001:
1002:
1.10 kristaps 1003: /* ARGSUSED */
1.6 kristaps 1004: static void
1.10 kristaps 1005: termp_ft_post(DECL_ARGS)
1.2 kristaps 1006: {
1007:
1.34 kristaps 1008: if (SEC_SYNOPSIS == node->sec)
1.10 kristaps 1009: newln(p);
1010: }
1.2 kristaps 1011:
1012:
1.10 kristaps 1013: /* ARGSUSED */
1014: static int
1015: termp_fn_pre(DECL_ARGS)
1016: {
1017: const struct mdoc_node *n;
1018:
1019: assert(node->child);
1020: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 1021:
1.10 kristaps 1022: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 1023:
1.10 kristaps 1024: p->flags |= ttypes[TTYPE_FUNC_NAME];
1025: word(p, node->child->data.text.string);
1026: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1027:
1028: word(p, "(");
1029:
1030: p->flags |= TERMP_NOSPACE;
1031: for (n = node->child->next; n; n = n->next) {
1032: assert(MDOC_TEXT == n->type);
1033: p->flags |= ttypes[TTYPE_FUNC_ARG];
1034: word(p, n->data.text.string);
1035: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 1036: if (n->next)
1.10 kristaps 1037: word(p, ",");
1.6 kristaps 1038: }
1.2 kristaps 1039:
1.10 kristaps 1040: word(p, ")");
1041:
1042: if (SEC_SYNOPSIS == node->sec)
1043: word(p, ";");
1044:
1045: return(0);
1.2 kristaps 1046: }
1047:
1048:
1.10 kristaps 1049: /* ARGSUSED */
1050: static void
1051: termp_fn_post(DECL_ARGS)
1.2 kristaps 1052: {
1053:
1.30 kristaps 1054: if (node->sec == SEC_SYNOPSIS && node->next)
1.10 kristaps 1055: vspace(p);
1056:
1057: }
1.2 kristaps 1058:
1059:
1.10 kristaps 1060: /* ARGSUSED */
1061: static int
1062: termp_sx_pre(DECL_ARGS)
1063: {
1.8 kristaps 1064:
1.31 kristaps 1065: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_LINK]);
1.10 kristaps 1066: return(1);
1.2 kristaps 1067: }
1068:
1069:
1.10 kristaps 1070: /* ARGSUSED */
1071: static int
1072: termp_fa_pre(DECL_ARGS)
1073: {
1.16 kristaps 1074: struct mdoc_node *n;
1075:
1076: if (node->parent->tok != MDOC_Fo) {
1.31 kristaps 1077: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 1078: return(1);
1079: }
1080:
1081: for (n = node->child; n; n = n->next) {
1082: assert(MDOC_TEXT == n->type);
1083:
1084: p->flags |= ttypes[TTYPE_FUNC_ARG];
1085: word(p, n->data.text.string);
1086: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1087:
1088: if (n->next)
1089: word(p, ",");
1090: }
1091:
1092: if (node->next && node->next->tok == MDOC_Fa)
1093: word(p, ",");
1.2 kristaps 1094:
1.16 kristaps 1095: return(0);
1.10 kristaps 1096: }
1.2 kristaps 1097:
1098:
1.10 kristaps 1099: /* ARGSUSED */
1100: static int
1101: termp_va_pre(DECL_ARGS)
1102: {
1.2 kristaps 1103:
1.31 kristaps 1104: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 1105: return(1);
1.2 kristaps 1106: }
1107:
1108:
1.10 kristaps 1109: /* ARGSUSED */
1110: static int
1111: termp_bd_pre(DECL_ARGS)
1112: {
1113: const struct mdoc_block *bl;
1.35 kristaps 1114: const struct mdoc_node *n;
1115: int i, type;
1.1 kristaps 1116:
1.10 kristaps 1117: if (MDOC_BLOCK == node->type) {
1.30 kristaps 1118: if (node->prev)
1119: vspace(p);
1.10 kristaps 1120: return(1);
1121: } else if (MDOC_BODY != node->type)
1122: return(1);
1123:
1.20 kristaps 1124: pair->offset = p->offset;
1.35 kristaps 1125: bl = &node->parent->data.block;
1.10 kristaps 1126:
1.35 kristaps 1127: for (type = -1, i = 0; i < (int)bl->argc; i++) {
1128: switch (bl->argv[i].arg) {
1129: case (MDOC_Ragged):
1130: /* FALLTHROUGH */
1131: case (MDOC_Filled):
1132: /* FALLTHROUGH */
1133: case (MDOC_Unfilled):
1134: /* FALLTHROUGH */
1135: case (MDOC_Literal):
1136: type = bl->argv[i].arg;
1137: i = (int)bl->argc;
1138: break;
1139: default:
1140: errx(1, "display type not supported");
1141: }
1142: }
1143:
1144: assert(-1 != type);
1.12 kristaps 1145:
1146: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1147: if (-1 != i) {
1148: assert(1 == bl->argv[i].sz);
1.20 kristaps 1149: p->offset += arg_offset(&bl->argv[i]);
1.12 kristaps 1150: }
1151:
1.35 kristaps 1152:
1153: switch (type) {
1154: case (MDOC_Literal):
1155: /* FALLTHROUGH */
1156: case (MDOC_Unfilled):
1157: break;
1158: default:
1159: return(1);
1160: }
1161:
1.10 kristaps 1162: p->flags |= TERMP_LITERAL;
1163:
1164: for (n = node->child; n; n = n->next) {
1.35 kristaps 1165: if (MDOC_TEXT != n->type) {
1166: warnx("non-text children not yet allowed");
1167: continue;
1168: }
1169: word(p, n->data.text.string);
1170: flushln(p);
1.10 kristaps 1171: }
1.1 kristaps 1172:
1.10 kristaps 1173: return(0);
1174: }
1.1 kristaps 1175:
1176:
1.10 kristaps 1177: /* ARGSUSED */
1.12 kristaps 1178: static void
1179: termp_bd_post(DECL_ARGS)
1180: {
1181:
1.20 kristaps 1182: if (MDOC_BODY != node->type)
1183: return;
1.35 kristaps 1184:
1185: if ( ! (p->flags & TERMP_LITERAL))
1186: flushln(p);
1187:
1188: p->flags &= ~TERMP_LITERAL;
1.20 kristaps 1189: p->offset = pair->offset;
1.12 kristaps 1190: }
1191:
1192:
1193: /* ARGSUSED */
1.10 kristaps 1194: static int
1195: termp_qq_pre(DECL_ARGS)
1196: {
1.1 kristaps 1197:
1.10 kristaps 1198: if (MDOC_BODY != node->type)
1199: return(1);
1200: word(p, "\"");
1201: p->flags |= TERMP_NOSPACE;
1202: return(1);
1.1 kristaps 1203: }
1204:
1205:
1.10 kristaps 1206: /* ARGSUSED */
1.1 kristaps 1207: static void
1.10 kristaps 1208: termp_qq_post(DECL_ARGS)
1.1 kristaps 1209: {
1210:
1.10 kristaps 1211: if (MDOC_BODY != node->type)
1212: return;
1213: p->flags |= TERMP_NOSPACE;
1214: word(p, "\"");
1215: }
1216:
1217:
1218: /* ARGSUSED */
1219: static int
1.15 kristaps 1220: termp_bsx_pre(DECL_ARGS)
1221: {
1222:
1223: word(p, "BSDI BSD/OS");
1224: return(1);
1225: }
1226:
1227:
1228: /* ARGSUSED */
1.31 kristaps 1229: static void
1230: termp_bx_post(DECL_ARGS)
1.10 kristaps 1231: {
1.1 kristaps 1232:
1.34 kristaps 1233: if (node->child)
1234: p->flags |= TERMP_NOSPACE;
1.10 kristaps 1235: word(p, "BSD");
1236: }
1237:
1238:
1239: /* ARGSUSED */
1240: static int
1241: termp_ox_pre(DECL_ARGS)
1242: {
1243:
1244: word(p, "OpenBSD");
1245: return(1);
1246: }
1247:
1248:
1249: /* ARGSUSED */
1250: static int
1.16 kristaps 1251: termp_ux_pre(DECL_ARGS)
1252: {
1253:
1254: word(p, "UNIX");
1255: return(1);
1256: }
1257:
1258:
1259: /* ARGSUSED */
1260: static int
1261: termp_fx_pre(DECL_ARGS)
1262: {
1263:
1264: word(p, "FreeBSD");
1265: return(1);
1266: }
1267:
1268:
1269: /* ARGSUSED */
1270: static int
1.10 kristaps 1271: termp_nx_pre(DECL_ARGS)
1272: {
1273:
1274: word(p, "NetBSD");
1275: return(1);
1276: }
1277:
1278:
1279: /* ARGSUSED */
1280: static int
1281: termp_sq_pre(DECL_ARGS)
1282: {
1283:
1284: if (MDOC_BODY != node->type)
1285: return(1);
1.28 kristaps 1286: word(p, "`");
1.10 kristaps 1287: p->flags |= TERMP_NOSPACE;
1288: return(1);
1289: }
1.1 kristaps 1290:
1291:
1.10 kristaps 1292: /* ARGSUSED */
1293: static void
1294: termp_sq_post(DECL_ARGS)
1295: {
1296:
1297: if (MDOC_BODY != node->type)
1298: return;
1299: p->flags |= TERMP_NOSPACE;
1300: word(p, "\'");
1301: }
1.2 kristaps 1302:
1303:
1.10 kristaps 1304: /* ARGSUSED */
1305: static int
1306: termp_pf_pre(DECL_ARGS)
1307: {
1.1 kristaps 1308:
1.10 kristaps 1309: p->flags |= TERMP_IGNDELIM;
1310: return(1);
1311: }
1.1 kristaps 1312:
1313:
1.10 kristaps 1314: /* ARGSUSED */
1315: static void
1316: termp_pf_post(DECL_ARGS)
1317: {
1.1 kristaps 1318:
1.10 kristaps 1319: p->flags &= ~TERMP_IGNDELIM;
1320: p->flags |= TERMP_NOSPACE;
1321: }
1.1 kristaps 1322:
1323:
1.10 kristaps 1324: /* ARGSUSED */
1325: static int
1326: termp_ss_pre(DECL_ARGS)
1327: {
1.1 kristaps 1328:
1.10 kristaps 1329: switch (node->type) {
1330: case (MDOC_HEAD):
1331: vspace(p);
1.31 kristaps 1332: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1333: p->offset = INDENT / 2;
1334: break;
1335: default:
1336: break;
1337: }
1.1 kristaps 1338:
1.10 kristaps 1339: return(1);
1.1 kristaps 1340: }
1341:
1342:
1.10 kristaps 1343: /* ARGSUSED */
1344: static void
1345: termp_ss_post(DECL_ARGS)
1.1 kristaps 1346: {
1347:
1.10 kristaps 1348: switch (node->type) {
1349: case (MDOC_HEAD):
1350: newln(p);
1351: p->offset = INDENT;
1352: break;
1353: default:
1354: break;
1355: }
1356: }
1.2 kristaps 1357:
1358:
1.10 kristaps 1359: /* ARGSUSED */
1360: static int
1361: termp_pa_pre(DECL_ARGS)
1362: {
1.2 kristaps 1363:
1.31 kristaps 1364: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1365: return(1);
1.1 kristaps 1366: }
1367:
1368:
1.10 kristaps 1369: /* ARGSUSED */
1.11 kristaps 1370: static int
1371: termp_em_pre(DECL_ARGS)
1372: {
1373:
1.31 kristaps 1374: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1375: return(1);
1376: }
1377:
1378:
1379: /* ARGSUSED */
1.14 kristaps 1380: static int
1381: termp_cd_pre(DECL_ARGS)
1382: {
1383:
1.31 kristaps 1384: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CONFIG]);
1.33 kristaps 1385: newln(p);
1.14 kristaps 1386: return(1);
1387: }
1388:
1389:
1390: /* ARGSUSED */
1391: static int
1392: termp_cm_pre(DECL_ARGS)
1393: {
1394:
1.31 kristaps 1395: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1396: return(1);
1397: }
1398:
1399:
1400: /* ARGSUSED */
1401: static int
1402: termp_ic_pre(DECL_ARGS)
1403: {
1404:
1.31 kristaps 1405: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1406: return(1);
1407: }
1408:
1409:
1410: /* ARGSUSED */
1411: static int
1412: termp_in_pre(DECL_ARGS)
1413: {
1414:
1.31 kristaps 1415: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_INCLUDE]);
1.30 kristaps 1416: word(p, "#include");
1417: word(p, "<");
1418: p->flags |= TERMP_NOSPACE;
1.14 kristaps 1419: return(1);
1420: }
1421:
1422:
1423: /* ARGSUSED */
1.30 kristaps 1424: static void
1425: termp_in_post(DECL_ARGS)
1426: {
1427:
1428: p->flags |= TERMP_NOSPACE;
1429: word(p, ">");
1430:
1431: newln(p);
1432: if (SEC_SYNOPSIS != node->sec)
1433: return;
1434: if (node->next && MDOC_In != node->next->tok)
1435: vspace(p);
1436: }
1437:
1438:
1439: /* ARGSUSED */
1.14 kristaps 1440: static int
1441: termp_at_pre(DECL_ARGS)
1442: {
1443: enum mdoc_att c;
1444:
1445: c = ATT_DEFAULT;
1446: if (node->child) {
1447: assert(MDOC_TEXT == node->child->type);
1448: c = mdoc_atoatt(node->child->data.text.string);
1449: }
1450:
1451: word(p, mdoc_att2a(c));
1452: return(0);
1453: }
1.15 kristaps 1454:
1455:
1456: /* ARGSUSED */
1457: static int
1458: termp_bq_pre(DECL_ARGS)
1459: {
1460:
1461: if (MDOC_BODY != node->type)
1462: return(1);
1.30 kristaps 1463: word(p, "[");
1.15 kristaps 1464: p->flags |= TERMP_NOSPACE;
1465: return(1);
1466: }
1467:
1468:
1469: /* ARGSUSED */
1470: static void
1471: termp_bq_post(DECL_ARGS)
1472: {
1473:
1474: if (MDOC_BODY != node->type)
1475: return;
1476: word(p, "]");
1477: }
1478:
1479:
1480: /* ARGSUSED */
1481: static int
1482: termp_pq_pre(DECL_ARGS)
1483: {
1484:
1485: if (MDOC_BODY != node->type)
1486: return(1);
1.31 kristaps 1487: word(p, "\\&(");
1.15 kristaps 1488: p->flags |= TERMP_NOSPACE;
1489: return(1);
1490: }
1491:
1492:
1493: /* ARGSUSED */
1494: static void
1495: termp_pq_post(DECL_ARGS)
1496: {
1497:
1498: if (MDOC_BODY != node->type)
1499: return;
1500: word(p, ")");
1501: }
1502:
1503:
1.16 kristaps 1504: /* ARGSUSED */
1505: static int
1506: termp_fo_pre(DECL_ARGS)
1507: {
1508: const struct mdoc_node *n;
1509:
1510: if (MDOC_BODY == node->type) {
1511: word(p, "(");
1512: p->flags |= TERMP_NOSPACE;
1513: return(1);
1514: } else if (MDOC_HEAD != node->type)
1515: return(1);
1516:
1.17 kristaps 1517: /* XXX - groff shows only first parameter */
1518:
1.16 kristaps 1519: p->flags |= ttypes[TTYPE_FUNC_NAME];
1520: for (n = node->child; n; n = n->next) {
1521: assert(MDOC_TEXT == n->type);
1522: word(p, n->data.text.string);
1523: }
1524: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1525:
1526: return(0);
1527: }
1528:
1529:
1530: /* ARGSUSED */
1531: static void
1532: termp_fo_post(DECL_ARGS)
1533: {
1534:
1535: if (MDOC_BODY != node->type)
1536: return;
1537: word(p, ")");
1538: word(p, ";");
1539: newln(p);
1540: }
1541:
1542:
1.17 kristaps 1543: /* ARGSUSED */
1544: static int
1545: termp_bf_pre(DECL_ARGS)
1546: {
1547: const struct mdoc_node *n;
1548: const struct mdoc_block *b;
1549:
1550: /* XXX - we skip over possible trailing HEAD tokens. */
1551:
1552: if (MDOC_HEAD == node->type)
1553: return(0);
1554: else if (MDOC_BLOCK != node->type)
1555: return(1);
1556:
1557: b = &node->data.block;
1558:
1559: if (NULL == (n = b->head->child)) {
1560: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
1.31 kristaps 1561: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1562: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
1.31 kristaps 1563: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1564:
1565: return(1);
1566: }
1567:
1568: assert(MDOC_TEXT == n->type);
1569:
1570: if (0 == strcmp("Em", n->data.text.string))
1.31 kristaps 1571: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1572: else if (0 == strcmp("Sy", n->data.text.string))
1.31 kristaps 1573: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1574:
1575: return(1);
1576: }
1577:
1578:
1579: /* ARGSUSED */
1580: static int
1581: termp_sy_pre(DECL_ARGS)
1582: {
1583:
1.31 kristaps 1584: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1585: return(1);
1586: }
1587:
1588:
1589: /* ARGSUSED */
1590: static int
1591: termp_ms_pre(DECL_ARGS)
1592: {
1593:
1.31 kristaps 1594: TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1595: return(1);
1596: }
1597:
1.22 kristaps 1598:
1599:
1600: /* ARGSUSED */
1601: static int
1602: termp_sm_pre(DECL_ARGS)
1603: {
1604:
1605: #if notyet
1606: assert(node->child);
1607: if (0 == strcmp("off", node->child->data.text.string)) {
1608: p->flags &= ~TERMP_NONOSPACE;
1609: p->flags &= ~TERMP_NOSPACE;
1610: } else {
1611: p->flags |= TERMP_NONOSPACE;
1612: p->flags |= TERMP_NOSPACE;
1613: }
1614: #endif
1615:
1616: return(0);
1617: }
1.28 kristaps 1618:
1619:
1620: /* ARGSUSED */
1621: static int
1622: termp__t_pre(DECL_ARGS)
1623: {
1624:
1625: word(p, "\"");
1626: p->flags |= TERMP_NOSPACE;
1627: return(1);
1628: }
1629:
1630:
1631: /* ARGSUSED */
1632: static void
1633: termp__t_post(DECL_ARGS)
1634: {
1635:
1636: p->flags |= TERMP_NOSPACE;
1637: word(p, "\"");
1638: word(p, node->next ? "," : ".");
1639: }
1640:
1641:
1642: /* ARGSUSED */
1643: static void
1644: termp____post(DECL_ARGS)
1645: {
1646:
1647: p->flags |= TERMP_NOSPACE;
1648: word(p, node->next ? "," : ".");
1649: }
CVSweb