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