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