Annotation of mandoc/term.c, Revision 1.21
1.21 ! kristaps 1: /* $Id: term.c,v 1.20 2009/02/25 13:30:53 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.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
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 */
1.20 kristaps 346: static int
347: termp_it_pre(DECL_ARGS)
1.10 kristaps 348: {
349: const struct mdoc_node *n, *it;
350: const struct mdoc_block *bl;
1.21 ! kristaps 351: char buf[7];
1.10 kristaps 352: int i;
1.12 kristaps 353: size_t width, offset;
1.2 kristaps 354:
1.10 kristaps 355: switch (node->type) {
356: case (MDOC_BODY):
357: /* FALLTHROUGH */
358: case (MDOC_HEAD):
1.20 kristaps 359: it = node->parent;
360: break;
361: case (MDOC_BLOCK):
362: it = node;
1.10 kristaps 363: break;
364: default:
1.20 kristaps 365: return(1);
1.8 kristaps 366: }
367:
1.21 ! kristaps 368: n = it->parent->parent;
1.10 kristaps 369: bl = &n->data.block;
370:
1.20 kristaps 371: if (MDOC_BLOCK == node->type) {
372: if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
373: newln(p);
374: else
375: vspace(p);
376: return(1);
377: }
378:
379: pair->offset = p->offset;
380: pair->rmargin = p->rmargin;
381:
382: /* FIXME: auto-size. */
383: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
384: width = i >= 0 ? arg_width(&bl->argv[i]) : 10;
385:
386: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
387: offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0;
388:
389: assert(MDOC_HEAD == node->type ||
390: MDOC_BODY == node->type);
1.10 kristaps 391:
392: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
1.20 kristaps 393: p->flags |= TERMP_NOSPACE;
1.21 ! kristaps 394: if (MDOC_BODY == node->type) {
! 395: p->flags |= TERMP_NOLPAD;
! 396: p->offset += width;
! 397: } else {
! 398: p->flags |= TERMP_NOBREAK;
! 399: p->rmargin = p->offset + offset + width;
! 400: }
1.10 kristaps 401:
1.21 ! kristaps 402: } else if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
! 403: p->flags |= TERMP_NOSPACE;
! 404:
! 405: } else if (arg_hasattr(MDOC_Diag, bl->argc, bl->argv)) {
! 406: /* TODO. */
! 407:
! 408: } else if (arg_hasattr(MDOC_Hang, bl->argc, bl->argv)) {
! 409: /* TODO. */
! 410:
! 411: } else if (arg_hasattr(MDOC_Bullet, bl->argc, bl->argv)) {
! 412: p->flags |= TERMP_NOSPACE;
! 413: if (MDOC_BODY == node->type) {
! 414: p->flags |= TERMP_NOLPAD;
! 415: p->offset += 6;
! 416: } else {
! 417: word(p, "\\[bu]");
1.20 kristaps 418: p->flags |= TERMP_NOBREAK;
1.21 ! kristaps 419: p->rmargin = p->offset + offset + 6;
! 420: }
! 421:
! 422: } else if (arg_hasattr(MDOC_Enum, bl->argc, bl->argv)) {
! 423: p->flags |= TERMP_NOSPACE;
! 424: if (MDOC_BODY == node->type) {
! 425: p->flags |= TERMP_NOLPAD;
! 426: p->offset += 6;
1.10 kristaps 427: } else {
1.21 ! kristaps 428: (pair->ppair->ppair->count)++;
! 429: (void)snprintf(buf, sizeof(buf), "%d.",
! 430: pair->ppair->ppair->count);
! 431: word(p, buf);
! 432: p->flags |= TERMP_NOBREAK;
! 433: p->rmargin = p->offset + offset + 6;
1.2 kristaps 434: }
1.20 kristaps 435:
1.21 ! kristaps 436: } else if (arg_hasattr(MDOC_Dash, bl->argc, bl->argv) ||
! 437: arg_hasattr(MDOC_Hyphen, bl->argc, bl->argv)) {
1.20 kristaps 438: p->flags |= TERMP_NOSPACE;
1.21 ! kristaps 439: if (MDOC_BODY == node->type) {
! 440: p->flags |= TERMP_NOLPAD;
! 441: p->offset += 6;
! 442: return(1);
! 443: } else {
! 444: word(p, "\\-");
! 445: p->flags |= TERMP_NOBREAK;
! 446: p->rmargin = p->offset + offset + 6;
! 447: }
! 448: }
1.2 kristaps 449:
1.21 ! kristaps 450: p->offset += offset;
1.20 kristaps 451: return(1);
1.10 kristaps 452: }
453:
454:
455: /* ARGSUSED */
1.20 kristaps 456: static void
457: termp_it_post(DECL_ARGS)
1.10 kristaps 458: {
459: const struct mdoc_node *n, *it;
460: const struct mdoc_block *bl;
1.3 kristaps 461:
1.21 ! kristaps 462: if (MDOC_BODY != node->type && MDOC_HEAD != node->type)
1.20 kristaps 463: return;
1.10 kristaps 464:
1.20 kristaps 465: it = node->parent;
1.21 ! kristaps 466: n = it->parent->parent;
1.10 kristaps 467: bl = &n->data.block;
468:
1.21 ! kristaps 469: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv) ||
! 470: arg_hasattr(MDOC_Bullet, bl->argc, bl->argv) ||
! 471: arg_hasattr(MDOC_Dash, bl->argc, bl->argv) ||
! 472: arg_hasattr(MDOC_Enum, bl->argc, bl->argv) ||
! 473: arg_hasattr(MDOC_Hyphen, bl->argc, bl->argv)) {
1.20 kristaps 474: flushln(p);
1.10 kristaps 475: if (MDOC_HEAD == node->type) {
1.20 kristaps 476: p->rmargin = pair->rmargin;
477: p->flags &= ~TERMP_NOBREAK;
1.21 ! kristaps 478: } else
1.20 kristaps 479: p->flags &= ~TERMP_NOLPAD;
1.10 kristaps 480:
1.20 kristaps 481: } else if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
482: flushln(p);
1.21 ! kristaps 483:
! 484: } else if (arg_hasattr(MDOC_Inset, bl->argc, bl->argv)) {
! 485: if (MDOC_BODY == node->type)
! 486: flushln(p);
! 487:
! 488: } else if (arg_hasattr(MDOC_Item, bl->argc, bl->argv)) {
! 489: if (MDOC_BODY == node->type)
! 490: flushln(p);
1.10 kristaps 491: }
1.21 ! kristaps 492:
! 493: p->offset = pair->offset;
1.2 kristaps 494: }
495:
496:
1.10 kristaps 497: /* ARGSUSED */
1.18 kristaps 498: static int
499: termp_nm_pre(DECL_ARGS)
1.10 kristaps 500: {
501:
1.18 kristaps 502: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_PROG]);
503: if (NULL == node->child)
504: word(p, meta->name);
505: return(1);
1.10 kristaps 506: }
507:
508:
509: /* ARGSUSED */
1.18 kristaps 510: static int
511: termp_fl_pre(DECL_ARGS)
1.10 kristaps 512: {
513:
1.18 kristaps 514: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
515: word(p, "\\-");
516: p->flags |= TERMP_NOSPACE;
517: return(1);
1.10 kristaps 518: }
519:
520:
521: /* ARGSUSED */
522: static int
523: termp_ar_pre(DECL_ARGS)
524: {
525:
1.18 kristaps 526: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_ARG]);
1.10 kristaps 527: if (NULL == node->child)
528: word(p, "...");
529: return(1);
530: }
531:
532:
533: /* ARGSUSED */
534: static int
535: termp_ns_pre(DECL_ARGS)
1.2 kristaps 536: {
537:
538: p->flags |= TERMP_NOSPACE;
1.10 kristaps 539: return(1);
540: }
541:
542:
543: /* ARGSUSED */
544: static int
545: termp_pp_pre(DECL_ARGS)
546: {
547:
548: vspace(p);
549: return(1);
550: }
551:
552:
553: /* ARGSUSED */
554: static int
1.14 kristaps 555: termp_st_pre(DECL_ARGS)
556: {
557: const char *tp;
558:
559: assert(1 == node->data.elem.argc);
560:
561: tp = mdoc_st2a(node->data.elem.argv[0].arg);
562: word(p, tp);
563:
564: return(1);
565: }
566:
567:
568: /* ARGSUSED */
569: static int
570: termp_rv_pre(DECL_ARGS)
571: {
572: int i;
573:
574: i = arg_getattr(MDOC_Std, node->data.elem.argc,
575: node->data.elem.argv);
576: assert(i >= 0);
577:
578: newln(p);
579: word(p, "The");
580:
581: p->flags |= ttypes[TTYPE_FUNC_NAME];
582: word(p, *node->data.elem.argv[i].value);
583: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
584:
585: word(p, "() function returns the value 0 if successful;");
586: word(p, "otherwise the value -1 is returned and the");
587: word(p, "global variable");
588:
589: p->flags |= ttypes[TTYPE_VAR_DECL];
590: word(p, "errno");
591: p->flags &= ~ttypes[TTYPE_VAR_DECL];
592:
593: word(p, "is set to indicate the error.");
594:
595: return(1);
596: }
597:
598:
599: /* ARGSUSED */
600: static int
1.10 kristaps 601: termp_ex_pre(DECL_ARGS)
602: {
603: int i;
604:
605: i = arg_getattr(MDOC_Std, node->data.elem.argc,
606: node->data.elem.argv);
607: assert(i >= 0);
608:
609: word(p, "The");
610: p->flags |= ttypes[TTYPE_PROG];
611: word(p, *node->data.elem.argv[i].value);
612: p->flags &= ~ttypes[TTYPE_PROG];
613: word(p, "utility exits 0 on success, and >0 if an error occurs.");
614:
615: return(1);
616: }
617:
618:
619: /* ARGSUSED */
620: static int
621: termp_nd_pre(DECL_ARGS)
622: {
623:
624: word(p, "\\-");
625: return(1);
626: }
627:
628:
629: /* ARGSUSED */
630: static void
631: termp_bl_post(DECL_ARGS)
632: {
633:
634: if (MDOC_BLOCK == node->type)
635: newln(p);
636: }
637:
638:
639: /* ARGSUSED */
640: static void
641: termp_op_post(DECL_ARGS)
642: {
643:
644: if (MDOC_BODY != node->type)
1.2 kristaps 645: return;
1.10 kristaps 646: p->flags |= TERMP_NOSPACE;
647: word(p, "\\(rB");
648: }
649:
650:
651: /* ARGSUSED */
652: static int
653: termp_xr_pre(DECL_ARGS)
654: {
655: const struct mdoc_node *n;
656:
657: n = node->child;
658: assert(n);
659:
660: assert(MDOC_TEXT == n->type);
661: word(p, n->data.text.string);
662:
663: if (NULL == (n = n->next))
664: return(0);
665:
666: assert(MDOC_TEXT == n->type);
667: p->flags |= TERMP_NOSPACE;
668: word(p, "(");
669: p->flags |= TERMP_NOSPACE;
670: word(p, n->data.text.string);
671: p->flags |= TERMP_NOSPACE;
672: word(p, ")");
673:
674: return(0);
1.2 kristaps 675: }
676:
677:
1.10 kristaps 678: /* ARGSUSED */
679: static int
680: termp_vt_pre(DECL_ARGS)
1.2 kristaps 681: {
682:
1.10 kristaps 683: /* FIXME: this can be "type name". */
1.18 kristaps 684: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 685: return(1);
1.2 kristaps 686: }
687:
688:
1.10 kristaps 689: /* ARGSUSED */
1.2 kristaps 690: static void
1.10 kristaps 691: termp_vt_post(DECL_ARGS)
692: {
693:
694: if (node->sec == SEC_SYNOPSIS)
695: vspace(p);
696: }
697:
698:
699: /* ARGSUSED */
700: static int
701: termp_fd_pre(DECL_ARGS)
1.2 kristaps 702: {
703:
1.10 kristaps 704: /*
705: * FIXME: this naming is bad. This value is used, in general,
706: * for the #include header or other preprocessor statement.
707: */
1.18 kristaps 708: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_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_fd_post(DECL_ARGS)
1.2 kristaps 716: {
717:
1.10 kristaps 718: if (node->sec == SEC_SYNOPSIS)
719: vspace(p);
720: }
721:
722:
723: /* ARGSUSED */
724: static int
725: termp_sh_pre(DECL_ARGS)
726: {
1.2 kristaps 727:
1.10 kristaps 728: switch (node->type) {
729: case (MDOC_HEAD):
730: vspace(p);
1.18 kristaps 731: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SECTION]);
1.2 kristaps 732: break;
1.10 kristaps 733: case (MDOC_BODY):
734: p->offset = INDENT;
1.2 kristaps 735: break;
1.10 kristaps 736: default:
737: break;
738: }
739: return(1);
740: }
741:
742:
743: /* ARGSUSED */
1.19 kristaps 744: static void
745: termp_sh_post(DECL_ARGS)
746: {
747:
748: switch (node->type) {
749: case (MDOC_HEAD):
750: newln(p);
751: break;
752: case (MDOC_BODY):
753: newln(p);
754: p->offset = 0;
755: break;
756: default:
757: break;
758: }
759: }
760:
761:
762: /* ARGSUSED */
1.10 kristaps 763: static int
764: termp_op_pre(DECL_ARGS)
765: {
766:
767: switch (node->type) {
768: case (MDOC_BODY):
769: word(p, "\\(lB");
770: p->flags |= TERMP_NOSPACE;
1.2 kristaps 771: break;
772: default:
1.10 kristaps 773: break;
1.2 kristaps 774: }
1.10 kristaps 775: return(1);
776: }
777:
778:
779: /* ARGSUSED */
780: static int
1.17 kristaps 781: termp_bt_pre(DECL_ARGS)
782: {
783:
784: word(p, "is currently in beta test.");
785: return(1);
786: }
787:
788:
789: /* ARGSUSED */
790: static int
1.10 kristaps 791: termp_ud_pre(DECL_ARGS)
792: {
793:
794: word(p, "currently under development.");
795: return(1);
796: }
797:
798:
799: /* ARGSUSED */
800: static int
801: termp_d1_pre(DECL_ARGS)
802: {
803:
804: if (MDOC_BODY != node->type)
805: return(1);
806: newln(p);
1.19 kristaps 807: p->offset += (pair->offset = INDENT);
1.10 kristaps 808: return(1);
1.2 kristaps 809: }
810:
811:
1.10 kristaps 812: /* ARGSUSED */
1.2 kristaps 813: static void
1.10 kristaps 814: termp_d1_post(DECL_ARGS)
815: {
816:
817: if (MDOC_BODY != node->type)
818: return;
819: newln(p);
1.19 kristaps 820: p->offset -= pair->offset;
1.10 kristaps 821: }
822:
823:
824: /* ARGSUSED */
825: static int
826: termp_aq_pre(DECL_ARGS)
1.6 kristaps 827: {
828:
1.10 kristaps 829: if (MDOC_BODY != node->type)
830: return(1);
831: word(p, "<");
832: p->flags |= TERMP_NOSPACE;
833: return(1);
834: }
1.6 kristaps 835:
836:
1.10 kristaps 837: /* ARGSUSED */
838: static void
839: termp_aq_post(DECL_ARGS)
840: {
1.6 kristaps 841:
1.10 kristaps 842: if (MDOC_BODY != node->type)
1.6 kristaps 843: return;
1.10 kristaps 844: p->flags |= TERMP_NOSPACE;
845: word(p, ">");
846: }
1.6 kristaps 847:
1.10 kristaps 848:
849: /* ARGSUSED */
850: static int
851: termp_ft_pre(DECL_ARGS)
852: {
853:
1.18 kristaps 854: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_TYPE]);
1.10 kristaps 855: return(1);
1.6 kristaps 856: }
857:
858:
1.10 kristaps 859: /* ARGSUSED */
1.6 kristaps 860: static void
1.10 kristaps 861: termp_ft_post(DECL_ARGS)
1.2 kristaps 862: {
863:
1.10 kristaps 864: if (node->sec == SEC_SYNOPSIS)
865: newln(p);
866: }
1.2 kristaps 867:
868:
1.10 kristaps 869: /* ARGSUSED */
870: static int
871: termp_fn_pre(DECL_ARGS)
872: {
873: const struct mdoc_node *n;
874:
875: assert(node->child);
876: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 877:
1.10 kristaps 878: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 879:
1.10 kristaps 880: p->flags |= ttypes[TTYPE_FUNC_NAME];
881: word(p, node->child->data.text.string);
882: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
883:
884: word(p, "(");
885:
886: p->flags |= TERMP_NOSPACE;
887: for (n = node->child->next; n; n = n->next) {
888: assert(MDOC_TEXT == n->type);
889: p->flags |= ttypes[TTYPE_FUNC_ARG];
890: word(p, n->data.text.string);
891: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.16 kristaps 892: if (n->next)
1.10 kristaps 893: word(p, ",");
1.6 kristaps 894: }
1.2 kristaps 895:
1.10 kristaps 896: word(p, ")");
897:
898: if (SEC_SYNOPSIS == node->sec)
899: word(p, ";");
900:
901: return(0);
1.2 kristaps 902: }
903:
904:
1.10 kristaps 905: /* ARGSUSED */
906: static void
907: termp_fn_post(DECL_ARGS)
1.2 kristaps 908: {
909:
1.10 kristaps 910: if (node->sec == SEC_SYNOPSIS)
911: vspace(p);
912:
913: }
1.2 kristaps 914:
915:
1.10 kristaps 916: /* ARGSUSED */
917: static int
918: termp_sx_pre(DECL_ARGS)
919: {
1.8 kristaps 920:
1.18 kristaps 921: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_LINK]);
1.10 kristaps 922: return(1);
1.2 kristaps 923: }
924:
925:
1.10 kristaps 926: /* ARGSUSED */
927: static int
928: termp_fa_pre(DECL_ARGS)
929: {
1.16 kristaps 930: struct mdoc_node *n;
931:
932: if (node->parent->tok != MDOC_Fo) {
1.18 kristaps 933: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FUNC_ARG]);
1.16 kristaps 934: return(1);
935: }
936:
937: for (n = node->child; n; n = n->next) {
938: assert(MDOC_TEXT == n->type);
939:
940: p->flags |= ttypes[TTYPE_FUNC_ARG];
941: word(p, n->data.text.string);
942: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
943:
944: if (n->next)
945: word(p, ",");
946: }
947:
948: if (node->next && node->next->tok == MDOC_Fa)
949: word(p, ",");
1.2 kristaps 950:
1.16 kristaps 951: return(0);
1.10 kristaps 952: }
1.2 kristaps 953:
954:
1.10 kristaps 955: /* ARGSUSED */
956: static int
957: termp_va_pre(DECL_ARGS)
958: {
1.2 kristaps 959:
1.18 kristaps 960: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_VAR_DECL]);
1.10 kristaps 961: return(1);
1.2 kristaps 962: }
963:
964:
1.10 kristaps 965: /* ARGSUSED */
966: static int
967: termp_bd_pre(DECL_ARGS)
968: {
969: const struct mdoc_block *bl;
970: const struct mdoc_node *n;
1.12 kristaps 971: int i;
1.1 kristaps 972:
1.10 kristaps 973: if (MDOC_BLOCK == node->type) {
974: vspace(p);
975: return(1);
976: } else if (MDOC_BODY != node->type)
977: return(1);
978:
979: assert(MDOC_BLOCK == node->parent->type);
1.20 kristaps 980: pair->offset = p->offset;
1.10 kristaps 981:
982: bl = &node->parent->data.block;
1.12 kristaps 983:
1.20 kristaps 984:
1.12 kristaps 985: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
986: if (-1 != i) {
987: assert(1 == bl->argv[i].sz);
1.20 kristaps 988: p->offset += arg_offset(&bl->argv[i]);
1.12 kristaps 989: }
990:
1.10 kristaps 991: if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
992: return(1);
993:
994: p->flags |= TERMP_LITERAL;
995:
996: for (n = node->child; n; n = n->next) {
997: assert(MDOC_TEXT == n->type); /* FIXME */
998: if ((*n->data.text.string)) {
999: word(p, n->data.text.string);
1000: flushln(p);
1001: } else
1002: vspace(p);
1.1 kristaps 1003:
1.10 kristaps 1004: }
1.1 kristaps 1005:
1.10 kristaps 1006: p->flags &= ~TERMP_LITERAL;
1007: return(0);
1008: }
1.1 kristaps 1009:
1010:
1.10 kristaps 1011: /* ARGSUSED */
1.12 kristaps 1012: static void
1013: termp_bd_post(DECL_ARGS)
1014: {
1015:
1.20 kristaps 1016: if (MDOC_BODY != node->type)
1017: return;
1018: newln(p);
1019: p->offset = pair->offset;
1.12 kristaps 1020: }
1021:
1022:
1023: /* ARGSUSED */
1.10 kristaps 1024: static int
1025: termp_qq_pre(DECL_ARGS)
1026: {
1.1 kristaps 1027:
1.10 kristaps 1028: if (MDOC_BODY != node->type)
1029: return(1);
1030: word(p, "\"");
1031: p->flags |= TERMP_NOSPACE;
1032: return(1);
1.1 kristaps 1033: }
1034:
1035:
1.10 kristaps 1036: /* ARGSUSED */
1.1 kristaps 1037: static void
1.10 kristaps 1038: termp_qq_post(DECL_ARGS)
1.1 kristaps 1039: {
1040:
1.10 kristaps 1041: if (MDOC_BODY != node->type)
1042: return;
1043: p->flags |= TERMP_NOSPACE;
1044: word(p, "\"");
1045: }
1046:
1047:
1048: /* ARGSUSED */
1049: static int
1.15 kristaps 1050: termp_bsx_pre(DECL_ARGS)
1051: {
1052:
1053: word(p, "BSDI BSD/OS");
1054: return(1);
1055: }
1056:
1057:
1058: /* ARGSUSED */
1059: static int
1.10 kristaps 1060: termp_bx_pre(DECL_ARGS)
1061: {
1.1 kristaps 1062:
1.10 kristaps 1063: word(p, "BSD");
1064: return(1);
1065: }
1066:
1067:
1068: /* ARGSUSED */
1069: static int
1070: termp_ox_pre(DECL_ARGS)
1071: {
1072:
1073: word(p, "OpenBSD");
1074: return(1);
1075: }
1076:
1077:
1078: /* ARGSUSED */
1079: static int
1.16 kristaps 1080: termp_ux_pre(DECL_ARGS)
1081: {
1082:
1083: word(p, "UNIX");
1084: return(1);
1085: }
1086:
1087:
1088: /* ARGSUSED */
1089: static int
1090: termp_fx_pre(DECL_ARGS)
1091: {
1092:
1093: word(p, "FreeBSD");
1094: return(1);
1095: }
1096:
1097:
1098: /* ARGSUSED */
1099: static int
1.10 kristaps 1100: termp_nx_pre(DECL_ARGS)
1101: {
1102:
1103: word(p, "NetBSD");
1104: return(1);
1105: }
1106:
1107:
1108: /* ARGSUSED */
1109: static int
1110: termp_sq_pre(DECL_ARGS)
1111: {
1112:
1113: if (MDOC_BODY != node->type)
1114: return(1);
1.13 kristaps 1115: word(p, "\'");
1.10 kristaps 1116: p->flags |= TERMP_NOSPACE;
1117: return(1);
1118: }
1.1 kristaps 1119:
1120:
1.10 kristaps 1121: /* ARGSUSED */
1122: static void
1123: termp_sq_post(DECL_ARGS)
1124: {
1125:
1126: if (MDOC_BODY != node->type)
1127: return;
1128: p->flags |= TERMP_NOSPACE;
1129: word(p, "\'");
1130: }
1.2 kristaps 1131:
1132:
1.10 kristaps 1133: /* ARGSUSED */
1134: static int
1135: termp_pf_pre(DECL_ARGS)
1136: {
1.1 kristaps 1137:
1.10 kristaps 1138: p->flags |= TERMP_IGNDELIM;
1139: return(1);
1140: }
1.1 kristaps 1141:
1142:
1.10 kristaps 1143: /* ARGSUSED */
1144: static void
1145: termp_pf_post(DECL_ARGS)
1146: {
1.1 kristaps 1147:
1.10 kristaps 1148: p->flags &= ~TERMP_IGNDELIM;
1149: p->flags |= TERMP_NOSPACE;
1150: }
1.1 kristaps 1151:
1152:
1.10 kristaps 1153: /* ARGSUSED */
1154: static int
1155: termp_ss_pre(DECL_ARGS)
1156: {
1.1 kristaps 1157:
1.10 kristaps 1158: switch (node->type) {
1159: case (MDOC_HEAD):
1160: vspace(p);
1.18 kristaps 1161: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SSECTION]);
1.10 kristaps 1162: p->offset = INDENT / 2;
1163: break;
1164: default:
1165: break;
1166: }
1.1 kristaps 1167:
1.10 kristaps 1168: return(1);
1.1 kristaps 1169: }
1170:
1171:
1.10 kristaps 1172: /* ARGSUSED */
1173: static void
1174: termp_ss_post(DECL_ARGS)
1.1 kristaps 1175: {
1176:
1.10 kristaps 1177: switch (node->type) {
1178: case (MDOC_HEAD):
1179: newln(p);
1180: p->offset = INDENT;
1181: break;
1182: default:
1183: break;
1184: }
1185: }
1.2 kristaps 1186:
1187:
1.10 kristaps 1188: /* ARGSUSED */
1189: static int
1190: termp_pa_pre(DECL_ARGS)
1191: {
1.2 kristaps 1192:
1.18 kristaps 1193: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_FILE]);
1.10 kristaps 1194: return(1);
1.1 kristaps 1195: }
1196:
1197:
1.10 kristaps 1198: /* ARGSUSED */
1.11 kristaps 1199: static int
1200: termp_em_pre(DECL_ARGS)
1201: {
1202:
1.18 kristaps 1203: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.11 kristaps 1204: return(1);
1205: }
1206:
1207:
1208: /* ARGSUSED */
1.14 kristaps 1209: static int
1210: termp_cd_pre(DECL_ARGS)
1211: {
1212:
1.18 kristaps 1213: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CONFIG]);
1.14 kristaps 1214: return(1);
1215: }
1216:
1217:
1218: /* ARGSUSED */
1219: static int
1220: termp_cm_pre(DECL_ARGS)
1221: {
1222:
1.18 kristaps 1223: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD_FLAG]);
1.14 kristaps 1224: return(1);
1225: }
1226:
1227:
1228: /* ARGSUSED */
1229: static int
1230: termp_ic_pre(DECL_ARGS)
1231: {
1232:
1.18 kristaps 1233: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_CMD]);
1.14 kristaps 1234: return(1);
1235: }
1236:
1237:
1238: /* ARGSUSED */
1239: static int
1240: termp_in_pre(DECL_ARGS)
1241: {
1242:
1.18 kristaps 1243: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_INCLUDE]);
1.14 kristaps 1244: return(1);
1245: }
1246:
1247:
1248: /* ARGSUSED */
1249: static int
1250: termp_at_pre(DECL_ARGS)
1251: {
1252: enum mdoc_att c;
1253:
1254: c = ATT_DEFAULT;
1255: if (node->child) {
1256: assert(MDOC_TEXT == node->child->type);
1257: c = mdoc_atoatt(node->child->data.text.string);
1258: }
1259:
1260: word(p, mdoc_att2a(c));
1261: return(0);
1262: }
1.15 kristaps 1263:
1264:
1265: /* ARGSUSED */
1266: static int
1267: termp_bq_pre(DECL_ARGS)
1268: {
1269:
1270: if (MDOC_BODY != node->type)
1271: return(1);
1272: word(p, "[");
1273: p->flags |= TERMP_NOSPACE;
1274: return(1);
1275: }
1276:
1277:
1278: /* ARGSUSED */
1279: static void
1280: termp_bq_post(DECL_ARGS)
1281: {
1282:
1283: if (MDOC_BODY != node->type)
1284: return;
1285: word(p, "]");
1286: }
1287:
1288:
1289: /* ARGSUSED */
1290: static int
1291: termp_pq_pre(DECL_ARGS)
1292: {
1293:
1294: if (MDOC_BODY != node->type)
1295: return(1);
1296: word(p, "(");
1297: p->flags |= TERMP_NOSPACE;
1298: return(1);
1299: }
1300:
1301:
1302: /* ARGSUSED */
1303: static void
1304: termp_pq_post(DECL_ARGS)
1305: {
1306:
1307: if (MDOC_BODY != node->type)
1308: return;
1309: word(p, ")");
1310: }
1311:
1312:
1.16 kristaps 1313: /* ARGSUSED */
1314: static int
1315: termp_fo_pre(DECL_ARGS)
1316: {
1317: const struct mdoc_node *n;
1318:
1319: if (MDOC_BODY == node->type) {
1320: word(p, "(");
1321: p->flags |= TERMP_NOSPACE;
1322: return(1);
1323: } else if (MDOC_HEAD != node->type)
1324: return(1);
1325:
1.17 kristaps 1326: /* XXX - groff shows only first parameter */
1327:
1.16 kristaps 1328: p->flags |= ttypes[TTYPE_FUNC_NAME];
1329: for (n = node->child; n; n = n->next) {
1330: assert(MDOC_TEXT == n->type);
1331: word(p, n->data.text.string);
1332: }
1333: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
1334:
1335: return(0);
1336: }
1337:
1338:
1339: /* ARGSUSED */
1340: static void
1341: termp_fo_post(DECL_ARGS)
1342: {
1343:
1344: if (MDOC_BODY != node->type)
1345: return;
1346: word(p, ")");
1347: word(p, ";");
1348: newln(p);
1349: }
1350:
1351:
1.17 kristaps 1352: /* ARGSUSED */
1353: static int
1354: termp_bf_pre(DECL_ARGS)
1355: {
1356: const struct mdoc_node *n;
1357: const struct mdoc_block *b;
1358:
1359: /* XXX - we skip over possible trailing HEAD tokens. */
1360:
1361: if (MDOC_HEAD == node->type)
1362: return(0);
1363: else if (MDOC_BLOCK != node->type)
1364: return(1);
1365:
1366: b = &node->data.block;
1367:
1368: if (NULL == (n = b->head->child)) {
1369: if (arg_hasattr(MDOC_Emphasis, b->argc, b->argv))
1.18 kristaps 1370: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1371: else if (arg_hasattr(MDOC_Symbolic, b->argc, b->argv))
1.18 kristaps 1372: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1373:
1374: return(1);
1375: }
1376:
1377: assert(MDOC_TEXT == n->type);
1378:
1379: if (0 == strcmp("Em", n->data.text.string))
1.18 kristaps 1380: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1381: else if (0 == strcmp("Sy", n->data.text.string))
1.18 kristaps 1382: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_EMPH]);
1.17 kristaps 1383:
1384: return(1);
1385: }
1386:
1387:
1388: /* ARGSUSED */
1389: static int
1390: termp_sy_pre(DECL_ARGS)
1391: {
1392:
1.18 kristaps 1393: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMB]);
1.17 kristaps 1394: return(1);
1395: }
1396:
1397:
1398: /* ARGSUSED */
1399: static int
1400: termp_ms_pre(DECL_ARGS)
1401: {
1402:
1.18 kristaps 1403: TERMPAIR_SETFLAG(pair, ttypes[TTYPE_SYMBOL]);
1.17 kristaps 1404: return(1);
1405: }
1406:
CVSweb