Annotation of mandoc/term.c, Revision 1.27
1.27 ! kristaps 1: /* $Id: term.c,v 1.26 2009/02/27 08:20:15 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:
1.26 kristaps 28: #define INDENT 6
1.10 kristaps 29:
30: /*
31: * Performs actions on nodes of the abstract syntax tree. Both pre- and
32: * post-fix operations are defined here.
33: */
34:
35: /* FIXME: indent/tab. */
1.21 kristaps 36: /* FIXME: macro arguments can be escaped. */
1.10 kristaps 37:
38: #define TTYPE_PROG 0
39: #define TTYPE_CMD_FLAG 1
40: #define TTYPE_CMD_ARG 2
41: #define TTYPE_SECTION 3
42: #define TTYPE_FUNC_DECL 4
43: #define TTYPE_VAR_DECL 5
44: #define TTYPE_FUNC_TYPE 6
45: #define TTYPE_FUNC_NAME 7
46: #define TTYPE_FUNC_ARG 8
47: #define TTYPE_LINK 9
48: #define TTYPE_SSECTION 10
49: #define TTYPE_FILE 11
1.11 kristaps 50: #define TTYPE_EMPH 12
1.14 kristaps 51: #define TTYPE_CONFIG 13
52: #define TTYPE_CMD 14
53: #define TTYPE_INCLUDE 15
1.17 kristaps 54: #define TTYPE_SYMB 16
55: #define TTYPE_SYMBOL 17
56: #define TTYPE_NMAX 18
1.10 kristaps 57:
58: /*
59: * These define "styles" for element types, like command arguments or
60: * executable names. This is useful when multiple macros must decorate
61: * the same thing (like .Ex -std cmd and .Nm cmd).
62: */
63:
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 */
82: TERMP_BOLD /* TTYPE_SYMBOL */
1.10 kristaps 83: };
1.7 kristaps 84:
1.10 kristaps 85: static int arg_hasattr(int, size_t,
86: const struct mdoc_arg *);
87: static int arg_getattr(int, size_t,
88: const struct mdoc_arg *);
1.12 kristaps 89: static size_t arg_offset(const struct mdoc_arg *);
90: static size_t arg_width(const struct mdoc_arg *);
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:
111: DECL_PREPOST(termp_aq);
1.12 kristaps 112: DECL_PREPOST(termp_bd);
1.15 kristaps 113: DECL_PREPOST(termp_bq);
1.10 kristaps 114: DECL_PREPOST(termp_d1);
115: DECL_PREPOST(termp_dq);
116: DECL_PREPOST(termp_fd);
117: DECL_PREPOST(termp_fn);
1.16 kristaps 118: DECL_PREPOST(termp_fo);
1.10 kristaps 119: DECL_PREPOST(termp_ft);
120: DECL_PREPOST(termp_it);
121: DECL_PREPOST(termp_op);
122: DECL_PREPOST(termp_pf);
1.15 kristaps 123: DECL_PREPOST(termp_pq);
1.10 kristaps 124: DECL_PREPOST(termp_qq);
125: DECL_PREPOST(termp_sh);
126: DECL_PREPOST(termp_ss);
127: DECL_PREPOST(termp_sq);
128: DECL_PREPOST(termp_vt);
129:
1.18 kristaps 130: DECL_PRE(termp_ar);
1.14 kristaps 131: DECL_PRE(termp_at);
1.18 kristaps 132: DECL_PRE(termp_bf);
1.15 kristaps 133: DECL_PRE(termp_bsx);
1.17 kristaps 134: DECL_PRE(termp_bt);
1.10 kristaps 135: DECL_PRE(termp_bx);
1.18 kristaps 136: DECL_PRE(termp_cd);
137: DECL_PRE(termp_cm);
138: DECL_PRE(termp_em);
1.10 kristaps 139: DECL_PRE(termp_ex);
1.18 kristaps 140: DECL_PRE(termp_fa);
141: DECL_PRE(termp_fl);
1.16 kristaps 142: DECL_PRE(termp_fx);
1.18 kristaps 143: DECL_PRE(termp_ic);
144: DECL_PRE(termp_in);
145: DECL_PRE(termp_ms);
1.10 kristaps 146: DECL_PRE(termp_nd);
1.18 kristaps 147: DECL_PRE(termp_nm);
1.10 kristaps 148: DECL_PRE(termp_ns);
149: DECL_PRE(termp_nx);
150: DECL_PRE(termp_ox);
1.18 kristaps 151: DECL_PRE(termp_pa);
1.10 kristaps 152: DECL_PRE(termp_pp);
1.14 kristaps 153: DECL_PRE(termp_rv);
1.22 kristaps 154: DECL_PRE(termp_sm);
1.14 kristaps 155: DECL_PRE(termp_st);
1.18 kristaps 156: DECL_PRE(termp_sx);
157: DECL_PRE(termp_sy);
1.10 kristaps 158: DECL_PRE(termp_ud);
1.16 kristaps 159: DECL_PRE(termp_ux);
1.18 kristaps 160: DECL_PRE(termp_va);
1.10 kristaps 161: DECL_PRE(termp_xr);
162:
163: DECL_POST(termp_bl);
164:
165: const struct termact __termacts[MDOC_MAX] = {
166: { NULL, NULL }, /* \" */
167: { NULL, NULL }, /* Dd */
168: { NULL, NULL }, /* Dt */
169: { NULL, NULL }, /* Os */
170: { termp_sh_pre, termp_sh_post }, /* Sh */
171: { termp_ss_pre, termp_ss_post }, /* Ss */
172: { termp_pp_pre, NULL }, /* Pp */
173: { termp_d1_pre, termp_d1_post }, /* D1 */
174: { NULL, NULL }, /* Dl */
1.12 kristaps 175: { termp_bd_pre, termp_bd_post }, /* Bd */
1.10 kristaps 176: { NULL, NULL }, /* Ed */
177: { NULL, termp_bl_post }, /* Bl */
178: { NULL, NULL }, /* El */
179: { termp_it_pre, termp_it_post }, /* It */
180: { NULL, NULL }, /* Ad */
181: { NULL, NULL }, /* An */
1.18 kristaps 182: { termp_ar_pre, NULL }, /* Ar */
183: { termp_cd_pre, NULL }, /* Cd */
184: { termp_cm_pre, NULL }, /* Cm */
1.10 kristaps 185: { NULL, NULL }, /* Dv */
186: { NULL, NULL }, /* Er */
187: { NULL, NULL }, /* Ev */
188: { termp_ex_pre, NULL }, /* Ex */
1.18 kristaps 189: { termp_fa_pre, NULL }, /* Fa */
1.10 kristaps 190: { termp_fd_pre, termp_fd_post }, /* Fd */
1.18 kristaps 191: { termp_fl_pre, NULL }, /* Fl */
1.10 kristaps 192: { termp_fn_pre, termp_fn_post }, /* Fn */
193: { termp_ft_pre, termp_ft_post }, /* Ft */
1.18 kristaps 194: { termp_ic_pre, NULL }, /* Ic */
195: { termp_in_pre, NULL }, /* In */
1.10 kristaps 196: { NULL, NULL }, /* Li */
197: { termp_nd_pre, NULL }, /* Nd */
1.18 kristaps 198: { termp_nm_pre, NULL }, /* Nm */
1.10 kristaps 199: { termp_op_pre, termp_op_post }, /* Op */
200: { NULL, NULL }, /* Ot */
1.18 kristaps 201: { termp_pa_pre, NULL }, /* Pa */
1.14 kristaps 202: { termp_rv_pre, NULL }, /* Rv */
203: { termp_st_pre, NULL }, /* St */
1.18 kristaps 204: { termp_va_pre, NULL }, /* Va */
1.10 kristaps 205: { termp_vt_pre, termp_vt_post }, /* Vt */
206: { termp_xr_pre, NULL }, /* Xr */
207: { NULL, NULL }, /* %A */
208: { NULL, NULL }, /* %B */
209: { NULL, NULL }, /* %D */
210: { NULL, NULL }, /* %I */
211: { NULL, NULL }, /* %J */
212: { NULL, NULL }, /* %N */
213: { NULL, NULL }, /* %O */
214: { NULL, NULL }, /* %P */
215: { NULL, NULL }, /* %R */
216: { NULL, NULL }, /* %T */
217: { NULL, NULL }, /* %V */
218: { NULL, NULL }, /* Ac */
1.14 kristaps 219: { termp_aq_pre, termp_aq_post }, /* Ao */
1.10 kristaps 220: { termp_aq_pre, termp_aq_post }, /* Aq */
1.14 kristaps 221: { termp_at_pre, NULL }, /* At */
1.10 kristaps 222: { NULL, NULL }, /* Bc */
1.18 kristaps 223: { termp_bf_pre, NULL }, /* Bf */
1.15 kristaps 224: { termp_bq_pre, termp_bq_post }, /* Bo */
225: { termp_bq_pre, termp_bq_post }, /* Bq */
226: { termp_bsx_pre, NULL }, /* Bsx */
1.10 kristaps 227: { termp_bx_pre, NULL }, /* Bx */
228: { NULL, NULL }, /* Db */
229: { NULL, NULL }, /* Dc */
1.15 kristaps 230: { termp_dq_pre, termp_dq_post }, /* Do */
1.10 kristaps 231: { termp_dq_pre, termp_dq_post }, /* Dq */
232: { NULL, NULL }, /* Ec */
233: { NULL, NULL }, /* Ef */
1.18 kristaps 234: { termp_em_pre, NULL }, /* Em */
1.10 kristaps 235: { NULL, NULL }, /* Eo */
1.16 kristaps 236: { termp_fx_pre, NULL }, /* Fx */
1.18 kristaps 237: { termp_ms_pre, NULL }, /* Ms */
1.10 kristaps 238: { NULL, NULL }, /* No */
239: { termp_ns_pre, NULL }, /* Ns */
240: { termp_nx_pre, NULL }, /* Nx */
241: { termp_ox_pre, NULL }, /* Ox */
242: { NULL, NULL }, /* Pc */
243: { termp_pf_pre, termp_pf_post }, /* Pf */
1.15 kristaps 244: { termp_pq_pre, termp_pq_post }, /* Po */
245: { termp_pq_pre, termp_pq_post }, /* Pq */
1.10 kristaps 246: { NULL, NULL }, /* Qc */
1.16 kristaps 247: { termp_sq_pre, termp_sq_post }, /* Ql */
1.15 kristaps 248: { termp_qq_pre, termp_qq_post }, /* Qo */
1.10 kristaps 249: { termp_qq_pre, termp_qq_post }, /* Qq */
250: { NULL, NULL }, /* Re */
251: { NULL, NULL }, /* Rs */
252: { NULL, NULL }, /* Sc */
1.15 kristaps 253: { termp_sq_pre, termp_sq_post }, /* So */
1.10 kristaps 254: { termp_sq_pre, termp_sq_post }, /* Sq */
1.22 kristaps 255: { termp_sm_pre, NULL }, /* Sm */
1.18 kristaps 256: { termp_sx_pre, NULL }, /* Sx */
257: { termp_sy_pre, NULL }, /* Sy */
1.10 kristaps 258: { NULL, NULL }, /* Tn */
1.16 kristaps 259: { termp_ux_pre, NULL }, /* Ux */
1.10 kristaps 260: { NULL, NULL }, /* Xc */
261: { NULL, NULL }, /* Xo */
1.16 kristaps 262: { termp_fo_pre, termp_fo_post }, /* Fo */
1.10 kristaps 263: { NULL, NULL }, /* Fc */
1.16 kristaps 264: { termp_op_pre, termp_op_post }, /* Oo */
1.10 kristaps 265: { NULL, NULL }, /* Oc */
266: { NULL, NULL }, /* Bk */
267: { NULL, NULL }, /* Ek */
1.17 kristaps 268: { termp_bt_pre, NULL }, /* Bt */
1.10 kristaps 269: { NULL, NULL }, /* Hf */
270: { NULL, NULL }, /* Fr */
271: { termp_ud_pre, NULL }, /* Ud */
1.2 kristaps 272: };
273:
1.10 kristaps 274: const struct termact *termacts = __termacts;
275:
276:
277: static size_t
1.12 kristaps 278: arg_width(const struct mdoc_arg *arg)
1.10 kristaps 279: {
1.27 ! kristaps 280: size_t v;
! 281: int i, len;
1.12 kristaps 282:
283: assert(*arg->value);
1.25 kristaps 284: if (0 == strcmp(*arg->value, "indent"))
285: return(INDENT);
286: if (0 == strcmp(*arg->value, "indent-two"))
287: return(INDENT * 2);
288:
1.27 ! kristaps 289: len = (int)strlen(*arg->value);
1.25 kristaps 290: assert(len > 0);
291:
292: for (i = 0; i < len - 1; i++)
293: if ( ! isdigit((int)(*arg->value)[i]))
294: break;
295:
296: if (i == len - 1) {
297: if ('n' == (*arg->value)[len - 1]) {
298: v = (size_t)atoi(*arg->value);
299: return(v);
300: }
301:
302: }
1.12 kristaps 303: return(strlen(*arg->value));
304: }
305:
306:
307: static size_t
308: arg_offset(const struct mdoc_arg *arg)
309: {
310:
311: /* TODO */
312: assert(*arg->value);
313: if (0 == strcmp(*arg->value, "indent"))
1.10 kristaps 314: return(INDENT);
1.12 kristaps 315: if (0 == strcmp(*arg->value, "indent-two"))
1.10 kristaps 316: return(INDENT * 2);
1.12 kristaps 317: return(strlen(*arg->value));
1.10 kristaps 318: }
319:
1.3 kristaps 320:
1.10 kristaps 321: static int
322: arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
1.2 kristaps 323: {
324:
1.10 kristaps 325: return(-1 != arg_getattr(arg, argc, argv));
326: }
327:
328:
329: static int
330: arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
331: {
332: int i;
333:
334: for (i = 0; i < (int)argc; i++)
335: if (argv[i].arg == arg)
336: return(i);
337: return(-1);
338: }
339:
340:
341: /* ARGSUSED */
342: static int
343: termp_dq_pre(DECL_ARGS)
344: {
345:
346: if (MDOC_BODY != node->type)
347: return(1);
348:
349: word(p, "``");
350: p->flags |= TERMP_NOSPACE;
351: return(1);
352: }
353:
354:
355: /* ARGSUSED */
356: static void
357: termp_dq_post(DECL_ARGS)
358: {
359:
360: if (MDOC_BODY != node->type)
361: return;
1.3 kristaps 362:
1.10 kristaps 363: p->flags |= TERMP_NOSPACE;
364: word(p, "''");
365: }
1.2 kristaps 366:
1.3 kristaps 367:
1.10 kristaps 368: /* ARGSUSED */
1.20 kristaps 369: static int
370: termp_it_pre(DECL_ARGS)
1.10 kristaps 371: {
372: const struct mdoc_node *n, *it;
373: const struct mdoc_block *bl;
1.23 kristaps 374: char buf[7], *tp;
375: int i, type;
1.12 kristaps 376: size_t width, offset;
1.2 kristaps 377:
1.10 kristaps 378: switch (node->type) {
379: case (MDOC_BODY):
380: /* FALLTHROUGH */
381: case (MDOC_HEAD):
1.20 kristaps 382: it = node->parent;
383: break;
384: case (MDOC_BLOCK):
385: it = node;
1.10 kristaps 386: break;
387: default:
1.20 kristaps 388: return(1);
1.8 kristaps 389: }
390:
1.21 kristaps 391: n = it->parent->parent;
1.10 kristaps 392: bl = &n->data.block;
393:
1.20 kristaps 394: if (MDOC_BLOCK == node->type) {
395: if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
396: newln(p);
397: else
398: vspace(p);
399: return(1);
400: }
401:
1.23 kristaps 402: /* Get our list type. */
403:
1.24 kristaps 404: for (type = -1, i = 0; i < (int)bl->argc; i++)
1.23 kristaps 405: switch (bl->argv[i].arg) {
406: case (MDOC_Bullet):
407: /* FALLTHROUGH */
408: case (MDOC_Dash):
409: /* FALLTHROUGH */
410: case (MDOC_Enum):
411: /* FALLTHROUGH */
412: case (MDOC_Hyphen):
413: /* FALLTHROUGH */
414: case (MDOC_Tag):
415: /* FALLTHROUGH */
416: case (MDOC_Ohang):
417: type = bl->argv[i].arg;
418: i = (int)bl->argc;
419: break;
1.24 kristaps 420: default:
1.23 kristaps 421: errx(1, "list type not supported");
422: /* NOTREACHED */
423: }
424:
1.24 kristaps 425: assert(-1 != type);
426:
1.23 kristaps 427: /* Save our existing (inherited) margin and offset. */
428:
1.20 kristaps 429: pair->offset = p->offset;
430: pair->rmargin = p->rmargin;
431:
1.23 kristaps 432: /* Get list width and offset. */
433:
1.20 kristaps 434: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
1.23 kristaps 435: width = i >= 0 ? arg_width(&bl->argv[i]) : 0;
1.20 kristaps 436:
437: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
438: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
439:
1.23 kristaps 440: /* Override the width. */
1.10 kristaps 441:
1.23 kristaps 442: switch (type) {
443: case (MDOC_Bullet):
444: /* FALLTHROUGH */
445: case (MDOC_Dash):
446: /* FALLTHROUGH */
447: case (MDOC_Enum):
448: /* FALLTHROUGH */
449: case (MDOC_Hyphen):
450: width = width > 6 ? width : 6;
451: break;
452: case (MDOC_Tag):
1.24 kristaps 453: /* FIXME: auto-size. */
1.23 kristaps 454: if (0 == width)
455: errx(1, "need non-zero -width");
456: break;
457: default:
458: break;
459: }
1.10 kristaps 460:
1.23 kristaps 461: /* Word-wrap control. */
1.21 kristaps 462:
1.23 kristaps 463: p->flags |= TERMP_NOSPACE;
1.21 kristaps 464:
1.23 kristaps 465: switch (type) {
466: case (MDOC_Bullet):
467: /* FALLTHROUGH */
468: case (MDOC_Dash):
469: /* FALLTHROUGH */
470: case (MDOC_Enum):
471: /* FALLTHROUGH */
472: case (MDOC_Hyphen):
473: /* FALLTHROUGH */
474: case (MDOC_Tag):
475: if (MDOC_HEAD == node->type)
476: p->flags |= TERMP_NOBREAK;
477: else if (MDOC_BODY == node->type)
478: p->flags |= TERMP_NOLPAD;
479: break;
1.24 kristaps 480: default:
1.23 kristaps 481: break;
482: }
1.21 kristaps 483:
1.23 kristaps 484: /*
485: * Get a token to use as the HEAD lead-in. If NULL, we use the
486: * HEAD child.
487: */
1.21 kristaps 488:
1.23 kristaps 489: tp = NULL;
1.24 kristaps 490:
1.23 kristaps 491: if (MDOC_HEAD == node->type) {
492: if (arg_hasattr(MDOC_Bullet, bl->argc, bl->argv))
493: tp = "\\[bu]";
494: if (arg_hasattr(MDOC_Dash, bl->argc, bl->argv))
495: tp = "\\-";
496: if (arg_hasattr(MDOC_Enum, bl->argc, bl->argv)) {
1.21 kristaps 497: (pair->ppair->ppair->count)++;
498: (void)snprintf(buf, sizeof(buf), "%d.",
499: pair->ppair->ppair->count);
1.23 kristaps 500: tp = buf;
1.2 kristaps 501: }
1.23 kristaps 502: if (arg_hasattr(MDOC_Hyphen, bl->argc, bl->argv))
503: tp = "\\-";
504: }
1.20 kristaps 505:
1.23 kristaps 506: /* Margin control. */
1.2 kristaps 507:
1.21 kristaps 508: p->offset += offset;
1.23 kristaps 509:
510: switch (type) {
511: case (MDOC_Bullet):
512: /* FALLTHROUGH */
513: case (MDOC_Dash):
514: /* FALLTHROUGH */
515: case (MDOC_Enum):
516: /* FALLTHROUGH */
517: case (MDOC_Hyphen):
518: /* FALLTHROUGH */
519: case (MDOC_Tag):
520: if (MDOC_HEAD == node->type)
521: p->rmargin = p->offset + width;
522: else if (MDOC_BODY == node->type)
523: p->offset += width;
524: break;
1.24 kristaps 525: default:
1.23 kristaps 526: break;
527: }
528:
529: if (NULL == tp)
530: return(1);
531:
532: word(p, tp);
533: return(0);
1.10 kristaps 534: }
535:
536:
537: /* ARGSUSED */
1.20 kristaps 538: static void
539: termp_it_post(DECL_ARGS)
1.10 kristaps 540: {
1.3 kristaps 541:
1.21 kristaps 542: if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
1.20 kristaps 543: return;
1.10 kristaps 544:
1.23 kristaps 545: flushln(p);
1.10 kristaps 546:
1.23 kristaps 547: p->offset = pair->offset;
548: p->rmargin = pair->rmargin;
1.21 kristaps 549:
1.23 kristaps 550: if (MDOC_HEAD == node->type) {
551: p->flags &= ~TERMP_NOBREAK;
552: p->flags &= ~TERMP_NORPAD;
553: } else if (MDOC_BODY == node->type)
554: p->flags &= ~TERMP_NOLPAD;
1.2 kristaps 555: }
556:
557:
1.10 kristaps 558: /* ARGSUSED */
1.18 kristaps 559: static int
560: termp_nm_pre(DECL_ARGS)
1.10 kristaps 561: {
562:
1.18 kristaps 563: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_PROG]);
564: if (NULL == node->child)
565: word(p, meta->name);
566: return(1);
1.10 kristaps 567: }
568:
569:
570: /* ARGSUSED */
1.18 kristaps 571: static int
572: termp_fl_pre(DECL_ARGS)
1.10 kristaps 573: {
574:
1.18 kristaps 575: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
576: word(p, "\\-");
577: p->flags |= TERMP_NOSPACE;
578: return(1);
1.10 kristaps 579: }
580:
581:
582: /* ARGSUSED */
583: static int
584: termp_ar_pre(DECL_ARGS)
585: {
586:
1.18 kristaps 587: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_ARG]);
1.10 kristaps 588: if (NULL == node->child)
589: word(p, "...");
590: return(1);
591: }
592:
593:
594: /* ARGSUSED */
595: static int
596: termp_ns_pre(DECL_ARGS)
1.2 kristaps 597: {
598:
599: p->flags |= TERMP_NOSPACE;
1.10 kristaps 600: return(1);
601: }
602:
603:
604: /* ARGSUSED */
605: static int
606: termp_pp_pre(DECL_ARGS)
607: {
608:
609: vspace(p);
610: return(1);
611: }
612:
613:
614: /* ARGSUSED */
615: static int
1.14 kristaps 616: termp_st_pre(DECL_ARGS)
617: {
618: const char *tp;
619:
620: assert(1 == node->data.elem.argc);
621:
622: tp = mdoc_st2a(node->data.elem.argv[0].arg);
623: word(p, tp);
624:
625: return(1);
626: }
627:
628:
629: /* ARGSUSED */
630: static int
631: termp_rv_pre(DECL_ARGS)
632: {
633: int i;
634:
635: i = arg_getattr(MDOC_Std, node->data.elem.argc,
636: node->data.elem.argv);
637: assert(i >= 0);
638:
639: newln(p);
640: word(p, "The");
641:
642: p->flags |= ttypes[TTYPE_FUNC_NAME];
643: word(p, *node->data.elem.argv[i].value);
644: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
645:
646: word(p, "() function returns the value 0 if successful;");
647: word(p, "otherwise the value -1 is returned and the");
648: word(p, "global variable");
649:
650: p->flags |= ttypes[TTYPE_VAR_DECL];
651: word(p, "errno");
652: p->flags &= ~ttypes[TTYPE_VAR_DECL];
653:
654: word(p, "is set to indicate the error.");
655:
656: return(1);
657: }
658:
659:
660: /* ARGSUSED */
661: static int
1.10 kristaps 662: termp_ex_pre(DECL_ARGS)
663: {
664: int i;
665:
666: i = arg_getattr(MDOC_Std, node->data.elem.argc,
667: node->data.elem.argv);
668: assert(i >= 0);
669:
670: word(p, "The");
671: p->flags |= ttypes[TTYPE_PROG];
672: word(p, *node->data.elem.argv[i].value);
673: p->flags &= ~ttypes[TTYPE_PROG];
674: word(p, "utility exits 0 on success, and >0 if an error occurs.");
675:
676: return(1);
677: }
678:
679:
680: /* ARGSUSED */
681: static int
682: termp_nd_pre(DECL_ARGS)
683: {
684:
685: word(p, "\\-");
686: return(1);
687: }
688:
689:
690: /* ARGSUSED */
691: static void
692: termp_bl_post(DECL_ARGS)
693: {
694:
695: if (MDOC_BLOCK == node->type)
696: newln(p);
697: }
698:
699:
700: /* ARGSUSED */
701: static void
702: termp_op_post(DECL_ARGS)
703: {
704:
705: if (MDOC_BODY != node->type)
1.2 kristaps 706: return;
1.10 kristaps 707: p->flags |= TERMP_NOSPACE;
708: word(p, "\\(rB");
709: }
710:
711:
712: /* ARGSUSED */
713: static int
714: termp_xr_pre(DECL_ARGS)
715: {
716: const struct mdoc_node *n;
717:
718: n = node->child;
719: assert(n);
720:
721: assert(MDOC_TEXT == n->type);
722: word(p, n->data.text.string);
723:
724: if (NULL == (n = n->next))
725: return(0);
726:
727: assert(MDOC_TEXT == n->type);
728: p->flags |= TERMP_NOSPACE;
729: word(p, "(");
730: p->flags |= TERMP_NOSPACE;
731: word(p, n->data.text.string);
732: p->flags |= TERMP_NOSPACE;
733: word(p, ")");
734:
735: return(0);
1.2 kristaps 736: }
737:
738:
1.10 kristaps 739: /* ARGSUSED */
740: static int
741: termp_vt_pre(DECL_ARGS)
1.2 kristaps 742: {
743:
1.10 kristaps 744: /* FIXME: this can be "type name". */
1.18 kristaps 745: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 746: return(1);
1.2 kristaps 747: }
748:
749:
1.10 kristaps 750: /* ARGSUSED */
1.2 kristaps 751: static void
1.10 kristaps 752: termp_vt_post(DECL_ARGS)
753: {
754:
755: if (node->sec == SEC_SYNOPSIS)
756: vspace(p);
757: }
758:
759:
760: /* ARGSUSED */
761: static int
762: termp_fd_pre(DECL_ARGS)
1.2 kristaps 763: {
764:
1.10 kristaps 765: /*
766: * FIXME: this naming is bad. This value is used, in general,
767: * for the #include header or other preprocessor statement.
768: */
1.18 kristaps 769: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_DECL]);
1.10 kristaps 770: return(1);
1.2 kristaps 771: }
772:
773:
1.10 kristaps 774: /* ARGSUSED */
1.2 kristaps 775: static void
1.10 kristaps 776: termp_fd_post(DECL_ARGS)
1.2 kristaps 777: {
778:
1.10 kristaps 779: if (node->sec == SEC_SYNOPSIS)
780: vspace(p);
781: }
782:
783:
784: /* ARGSUSED */
785: static int
786: termp_sh_pre(DECL_ARGS)
787: {
1.2 kristaps 788:
1.10 kristaps 789: switch (node->type) {
790: case (MDOC_HEAD):
791: vspace(p);
1.18 kristaps 792: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SECTION]);
1.2 kristaps 793: break;
1.10 kristaps 794: case (MDOC_BODY):
795: p->offset = INDENT;
1.2 kristaps 796: break;
1.10 kristaps 797: default:
798: break;
799: }
800: return(1);
801: }
802:
803:
804: /* ARGSUSED */
1.19 kristaps 805: static void
806: termp_sh_post(DECL_ARGS)
807: {
808:
809: switch (node->type) {
810: case (MDOC_HEAD):
811: newln(p);
812: break;
813: case (MDOC_BODY):
814: newln(p);
815: p->offset = 0;
816: break;
817: default:
818: break;
819: }
820: }
821:
822:
823: /* ARGSUSED */
1.10 kristaps 824: static int
825: termp_op_pre(DECL_ARGS)
826: {
827:
828: switch (node->type) {
829: case (MDOC_BODY):
830: word(p, "\\(lB");
831: p->flags |= TERMP_NOSPACE;
1.2 kristaps 832: break;
833: default:
1.10 kristaps 834: break;
1.2 kristaps 835: }
1.10 kristaps 836: return(1);
837: }
838:
839:
840: /* ARGSUSED */
841: static int
1.17 kristaps 842: termp_bt_pre(DECL_ARGS)
843: {
844:
845: word(p, "is currently in beta test.");
846: return(1);
847: }
848:
849:
850: /* ARGSUSED */
851: static int
1.10 kristaps 852: termp_ud_pre(DECL_ARGS)
853: {
854:
855: word(p, "currently under development.");
856: return(1);
857: }
858:
859:
860: /* ARGSUSED */
861: static int
862: termp_d1_pre(DECL_ARGS)
863: {
864:
865: if (MDOC_BODY != node->type)
866: return(1);
867: newln(p);
1.19 kristaps 868: p->offset += (pair->offset = INDENT);
1.10 kristaps 869: return(1);
1.2 kristaps 870: }
871:
872:
1.10 kristaps 873: /* ARGSUSED */
1.2 kristaps 874: static void
1.10 kristaps 875: termp_d1_post(DECL_ARGS)
876: {
877:
878: if (MDOC_BODY != node->type)
879: return;
880: newln(p);
1.19 kristaps 881: p->offset -= pair->offset;
1.10 kristaps 882: }
883:
884:
885: /* ARGSUSED */
886: static int
887: termp_aq_pre(DECL_ARGS)
1.6 kristaps 888: {
889:
1.10 kristaps 890: if (MDOC_BODY != node->type)
891: return(1);
892: word(p, "<");
893: p->flags |= TERMP_NOSPACE;
894: return(1);
895: }
1.6 kristaps 896:
897:
1.10 kristaps 898: /* ARGSUSED */
899: static void
900: termp_aq_post(DECL_ARGS)
901: {
1.6 kristaps 902:
1.10 kristaps 903: if (MDOC_BODY != node->type)
1.6 kristaps 904: return;
1.10 kristaps 905: p->flags |= TERMP_NOSPACE;
906: word(p, ">");
907: }
1.6 kristaps 908:
1.10 kristaps 909:
910: /* ARGSUSED */
911: static int
912: termp_ft_pre(DECL_ARGS)
913: {
914:
1.18 kristaps 915: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 916: return(1);
1.6 kristaps 917: }
918:
919:
1.10 kristaps 920: /* ARGSUSED */
1.6 kristaps 921: static void
1.10 kristaps 922: termp_ft_post(DECL_ARGS)
1.2 kristaps 923: {
924:
1.10 kristaps 925: if (node->sec == SEC_SYNOPSIS)
926: newln(p);
927: }
1.2 kristaps 928:
929:
1.10 kristaps 930: /* ARGSUSED */
931: static int
932: termp_fn_pre(DECL_ARGS)
933: {
934: const struct mdoc_node *n;
935:
936: assert(node->child);
937: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 938:
1.10 kristaps 939: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 940:
1.10 kristaps 941: p->flags |= ttypes[TTYPE_FUNC_NAME];
942: word(p, node->child->data.text.string);
943: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
944:
945: word(p, "(");
946:
947: p->flags |= TERMP_NOSPACE;
948: for (n = node->child->next; n; n = n->next) {
949: assert(MDOC_TEXT == n->type);
950: p->flags |= ttypes[TTYPE_FUNC_ARG];
951: word(p, n->data.text.string);
952: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 953: if (n->next)
1.10 kristaps 954: word(p, ",");
1.6 kristaps 955: }
1.2 kristaps 956:
1.10 kristaps 957: word(p, ")");
958:
959: if (SEC_SYNOPSIS == node->sec)
960: word(p, ";");
961:
962: return(0);
1.2 kristaps 963: }
964:
965:
1.10 kristaps 966: /* ARGSUSED */
967: static void
968: termp_fn_post(DECL_ARGS)
1.2 kristaps 969: {
970:
1.10 kristaps 971: if (node->sec == SEC_SYNOPSIS)
972: vspace(p);
973:
974: }
1.2 kristaps 975:
976:
1.10 kristaps 977: /* ARGSUSED */
978: static int
979: termp_sx_pre(DECL_ARGS)
980: {
1.8 kristaps 981:
1.18 kristaps 982: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_LINK]);
1.10 kristaps 983: return(1);
1.2 kristaps 984: }
985:
986:
1.10 kristaps 987: /* ARGSUSED */
988: static int
989: termp_fa_pre(DECL_ARGS)
990: {
1.16 kristaps 991: struct mdoc_node *n;
992:
993: if (node->parent->tok != MDOC_Fo) {
1.18 kristaps 994: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 995: return(1);
996: }
997:
998: for (n = node->child; n; n = n->next) {
999: assert(MDOC_TEXT == n->type);
1000:
1001: p->flags |= ttypes[TTYPE_FUNC_ARG];
1002: word(p, n->data.text.string);
1003: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1004:
1005: if (n->next)
1006: word(p, ",");
1007: }
1008:
1009: if (node->next && node->next->tok == MDOC_Fa)
1010: word(p, ",");
1.2 kristaps 1011:
1.16 kristaps 1012: return(0);
1.10 kristaps 1013: }
1.2 kristaps 1014:
1015:
1.10 kristaps 1016: /* ARGSUSED */
1017: static int
1018: termp_va_pre(DECL_ARGS)
1019: {
1.2 kristaps 1020:
1.18 kristaps 1021: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 1022: return(1);
1.2 kristaps 1023: }
1024:
1025:
1.10 kristaps 1026: /* ARGSUSED */
1027: static int
1028: termp_bd_pre(DECL_ARGS)
1029: {
1030: const struct mdoc_block *bl;
1031: const struct mdoc_node *n;
1.12 kristaps 1032: int i;
1.1 kristaps 1033:
1.10 kristaps 1034: if (MDOC_BLOCK == node->type) {
1035: vspace(p);
1036: return(1);
1037: } else if (MDOC_BODY != node->type)
1038: return(1);
1039:
1040: assert(MDOC_BLOCK == node->parent->type);
1.20 kristaps 1041: pair->offset = p->offset;
1.10 kristaps 1042:
1043: bl = &node->parent->data.block;
1.12 kristaps 1044:
1.20 kristaps 1045:
1.12 kristaps 1046: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
1047: if (-1 != i) {
1048: assert(1 == bl->argv[i].sz);
1.20 kristaps 1049: p->offset += arg_offset(&bl->argv[i]);
1.12 kristaps 1050: }
1051:
1.10 kristaps 1052: if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
1053: return(1);
1054:
1055: p->flags |= TERMP_LITERAL;
1056:
1057: for (n = node->child; n; n = n->next) {
1058: assert(MDOC_TEXT == n->type); /* FIXME */
1059: if ((*n->data.text.string)) {
1060: word(p, n->data.text.string);
1061: flushln(p);
1062: } else
1063: vspace(p);
1.1 kristaps 1064:
1.10 kristaps 1065: }
1.1 kristaps 1066:
1.10 kristaps 1067: p->flags &= ~TERMP_LITERAL;
1068: return(0);
1069: }
1.1 kristaps 1070:
1071:
1.10 kristaps 1072: /* ARGSUSED */
1.12 kristaps 1073: static void
1074: termp_bd_post(DECL_ARGS)
1075: {
1076:
1.20 kristaps 1077: if (MDOC_BODY != node->type)
1078: return;
1079: newln(p);
1080: p->offset = pair->offset;
1.12 kristaps 1081: }
1082:
1083:
1084: /* ARGSUSED */
1.10 kristaps 1085: static int
1086: termp_qq_pre(DECL_ARGS)
1087: {
1.1 kristaps 1088:
1.10 kristaps 1089: if (MDOC_BODY != node->type)
1090: return(1);
1091: word(p, "\"");
1092: p->flags |= TERMP_NOSPACE;
1093: return(1);
1.1 kristaps 1094: }
1095:
1096:
1.10 kristaps 1097: /* ARGSUSED */
1.1 kristaps 1098: static void
1.10 kristaps 1099: termp_qq_post(DECL_ARGS)
1.1 kristaps 1100: {
1101:
1.10 kristaps 1102: if (MDOC_BODY != node->type)
1103: return;
1104: p->flags |= TERMP_NOSPACE;
1105: word(p, "\"");
1106: }
1107:
1108:
1109: /* ARGSUSED */
1110: static int
1.15 kristaps 1111: termp_bsx_pre(DECL_ARGS)
1112: {
1113:
1114: word(p, "BSDI BSD/OS");
1115: return(1);
1116: }
1117:
1118:
1119: /* ARGSUSED */
1120: static int
1.10 kristaps 1121: termp_bx_pre(DECL_ARGS)
1122: {
1.1 kristaps 1123:
1.10 kristaps 1124: word(p, "BSD");
1125: return(1);
1126: }
1127:
1128:
1129: /* ARGSUSED */
1130: static int
1131: termp_ox_pre(DECL_ARGS)
1132: {
1133:
1134: word(p, "OpenBSD");
1135: return(1);
1136: }
1137:
1138:
1139: /* ARGSUSED */
1140: static int
1.16 kristaps 1141: termp_ux_pre(DECL_ARGS)
1142: {
1143:
1144: word(p, "UNIX");
1145: return(1);
1146: }
1147:
1148:
1149: /* ARGSUSED */
1150: static int
1151: termp_fx_pre(DECL_ARGS)
1152: {
1153:
1154: word(p, "FreeBSD");
1155: return(1);
1156: }
1157:
1158:
1159: /* ARGSUSED */
1160: static int
1.10 kristaps 1161: termp_nx_pre(DECL_ARGS)
1162: {
1163:
1164: word(p, "NetBSD");
1165: return(1);
1166: }
1167:
1168:
1169: /* ARGSUSED */
1170: static int
1171: termp_sq_pre(DECL_ARGS)
1172: {
1173:
1174: if (MDOC_BODY != node->type)
1175: return(1);
1.13 kristaps 1176: word(p, "\'");
1.10 kristaps 1177: p->flags |= TERMP_NOSPACE;
1178: return(1);
1179: }
1.1 kristaps 1180:
1181:
1.10 kristaps 1182: /* ARGSUSED */
1183: static void
1184: termp_sq_post(DECL_ARGS)
1185: {
1186:
1187: if (MDOC_BODY != node->type)
1188: return;
1189: p->flags |= TERMP_NOSPACE;
1190: word(p, "\'");
1191: }
1.2 kristaps 1192:
1193:
1.10 kristaps 1194: /* ARGSUSED */
1195: static int
1196: termp_pf_pre(DECL_ARGS)
1197: {
1.1 kristaps 1198:
1.10 kristaps 1199: p->flags |= TERMP_IGNDELIM;
1200: return(1);
1201: }
1.1 kristaps 1202:
1203:
1.10 kristaps 1204: /* ARGSUSED */
1205: static void
1206: termp_pf_post(DECL_ARGS)
1207: {
1.1 kristaps 1208:
1.10 kristaps 1209: p->flags &= ~TERMP_IGNDELIM;
1210: p->flags |= TERMP_NOSPACE;
1211: }
1.1 kristaps 1212:
1213:
1.10 kristaps 1214: /* ARGSUSED */
1215: static int
1216: termp_ss_pre(DECL_ARGS)
1217: {
1.1 kristaps 1218:
1.10 kristaps 1219: switch (node->type) {
1220: case (MDOC_HEAD):
1221: vspace(p);
1.18 kristaps 1222: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1223: p->offset = INDENT / 2;
1224: break;
1225: default:
1226: break;
1227: }
1.1 kristaps 1228:
1.10 kristaps 1229: return(1);
1.1 kristaps 1230: }
1231:
1232:
1.10 kristaps 1233: /* ARGSUSED */
1234: static void
1235: termp_ss_post(DECL_ARGS)
1.1 kristaps 1236: {
1237:
1.10 kristaps 1238: switch (node->type) {
1239: case (MDOC_HEAD):
1240: newln(p);
1241: p->offset = INDENT;
1242: break;
1243: default:
1244: break;
1245: }
1246: }
1.2 kristaps 1247:
1248:
1.10 kristaps 1249: /* ARGSUSED */
1250: static int
1251: termp_pa_pre(DECL_ARGS)
1252: {
1.2 kristaps 1253:
1.18 kristaps 1254: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1255: return(1);
1.1 kristaps 1256: }
1257:
1258:
1.10 kristaps 1259: /* ARGSUSED */
1.11 kristaps 1260: static int
1261: termp_em_pre(DECL_ARGS)
1262: {
1263:
1.18 kristaps 1264: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1265: return(1);
1266: }
1267:
1268:
1269: /* ARGSUSED */
1.14 kristaps 1270: static int
1271: termp_cd_pre(DECL_ARGS)
1272: {
1273:
1.18 kristaps 1274: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CONFIG]);
1.14 kristaps 1275: return(1);
1276: }
1277:
1278:
1279: /* ARGSUSED */
1280: static int
1281: termp_cm_pre(DECL_ARGS)
1282: {
1283:
1.18 kristaps 1284: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1285: return(1);
1286: }
1287:
1288:
1289: /* ARGSUSED */
1290: static int
1291: termp_ic_pre(DECL_ARGS)
1292: {
1293:
1.18 kristaps 1294: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1295: return(1);
1296: }
1297:
1298:
1299: /* ARGSUSED */
1300: static int
1301: termp_in_pre(DECL_ARGS)
1302: {
1303:
1.18 kristaps 1304: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_INCLUDE]);
1.14 kristaps 1305: return(1);
1306: }
1307:
1308:
1309: /* ARGSUSED */
1310: static int
1311: termp_at_pre(DECL_ARGS)
1312: {
1313: enum mdoc_att c;
1314:
1315: c = ATT_DEFAULT;
1316: if (node->child) {
1317: assert(MDOC_TEXT == node->child->type);
1318: c = mdoc_atoatt(node->child->data.text.string);
1319: }
1320:
1321: word(p, mdoc_att2a(c));
1322: return(0);
1323: }
1.15 kristaps 1324:
1325:
1326: /* ARGSUSED */
1327: static int
1328: termp_bq_pre(DECL_ARGS)
1329: {
1330:
1331: if (MDOC_BODY != node->type)
1332: return(1);
1.26 kristaps 1333: word(p, "\\[");
1.15 kristaps 1334: p->flags |= TERMP_NOSPACE;
1335: return(1);
1336: }
1337:
1338:
1339: /* ARGSUSED */
1340: static void
1341: termp_bq_post(DECL_ARGS)
1342: {
1343:
1344: if (MDOC_BODY != node->type)
1345: return;
1346: word(p, "]");
1347: }
1348:
1349:
1350: /* ARGSUSED */
1351: static int
1352: termp_pq_pre(DECL_ARGS)
1353: {
1354:
1355: if (MDOC_BODY != node->type)
1356: return(1);
1.26 kristaps 1357: word(p, "\\&(");
1.15 kristaps 1358: p->flags |= TERMP_NOSPACE;
1359: return(1);
1360: }
1361:
1362:
1363: /* ARGSUSED */
1364: static void
1365: termp_pq_post(DECL_ARGS)
1366: {
1367:
1368: if (MDOC_BODY != node->type)
1369: return;
1370: word(p, ")");
1371: }
1372:
1373:
1.16 kristaps 1374: /* ARGSUSED */
1375: static int
1376: termp_fo_pre(DECL_ARGS)
1377: {
1378: const struct mdoc_node *n;
1379:
1380: if (MDOC_BODY == node->type) {
1381: word(p, "(");
1382: p->flags |= TERMP_NOSPACE;
1383: return(1);
1384: } else if (MDOC_HEAD != node->type)
1385: return(1);
1386:
1.17 kristaps 1387: /* XXX - groff shows only first parameter */
1388:
1.16 kristaps 1389: p->flags |= ttypes[TTYPE_FUNC_NAME];
1390: for (n = node->child; n; n = n->next) {
1391: assert(MDOC_TEXT == n->type);
1392: word(p, n->data.text.string);
1393: }
1394: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1395:
1396: return(0);
1397: }
1398:
1399:
1400: /* ARGSUSED */
1401: static void
1402: termp_fo_post(DECL_ARGS)
1403: {
1404:
1405: if (MDOC_BODY != node->type)
1406: return;
1407: word(p, ")");
1408: word(p, ";");
1409: newln(p);
1410: }
1411:
1412:
1.17 kristaps 1413: /* ARGSUSED */
1414: static int
1415: termp_bf_pre(DECL_ARGS)
1416: {
1417: const struct mdoc_node *n;
1418: const struct mdoc_block *b;
1419:
1420: /* XXX - we skip over possible trailing HEAD tokens. */
1421:
1422: if (MDOC_HEAD == node->type)
1423: return(0);
1424: else if (MDOC_BLOCK != node->type)
1425: return(1);
1426:
1427: b = &node->data.block;
1428:
1429: if (NULL == (n = b->head->child)) {
1430: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
1.18 kristaps 1431: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1432: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
1.18 kristaps 1433: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1434:
1435: return(1);
1436: }
1437:
1438: assert(MDOC_TEXT == n->type);
1439:
1440: if (0 == strcmp("Em", n->data.text.string))
1.18 kristaps 1441: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1442: else if (0 == strcmp("Sy", n->data.text.string))
1.18 kristaps 1443: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1444:
1445: return(1);
1446: }
1447:
1448:
1449: /* ARGSUSED */
1450: static int
1451: termp_sy_pre(DECL_ARGS)
1452: {
1453:
1.18 kristaps 1454: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1455: return(1);
1456: }
1457:
1458:
1459: /* ARGSUSED */
1460: static int
1461: termp_ms_pre(DECL_ARGS)
1462: {
1463:
1.18 kristaps 1464: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1465: return(1);
1466: }
1467:
1.22 kristaps 1468:
1469:
1470: /* ARGSUSED */
1471: static int
1472: termp_sm_pre(DECL_ARGS)
1473: {
1474:
1475: #if notyet
1476: assert(node->child);
1477: if (0 == strcmp("off", node->child->data.text.string)) {
1478: p->flags &= ~TERMP_NONOSPACE;
1479: p->flags &= ~TERMP_NOSPACE;
1480: } else {
1481: p->flags |= TERMP_NONOSPACE;
1482: p->flags |= TERMP_NOSPACE;
1483: }
1484: #endif
1485:
1486: return(0);
1487: }
CVSweb