Annotation of mandoc/term.c, Revision 1.10
1.10 ! kristaps 1: /* $Id: termact.c,v 1.6 2009/02/22 19:23:48 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. */
! 33:
! 34: #define TTYPE_PROG 0
! 35: #define TTYPE_CMD_FLAG 1
! 36: #define TTYPE_CMD_ARG 2
! 37: #define TTYPE_SECTION 3
! 38: #define TTYPE_FUNC_DECL 4
! 39: #define TTYPE_VAR_DECL 5
! 40: #define TTYPE_FUNC_TYPE 6
! 41: #define TTYPE_FUNC_NAME 7
! 42: #define TTYPE_FUNC_ARG 8
! 43: #define TTYPE_LINK 9
! 44: #define TTYPE_SSECTION 10
! 45: #define TTYPE_FILE 11
! 46: #define TTYPE_NMAX 12
! 47:
! 48: /*
! 49: * These define "styles" for element types, like command arguments or
! 50: * executable names. This is useful when multiple macros must decorate
! 51: * the same thing (like .Ex -std cmd and .Nm cmd).
! 52: */
! 53:
! 54: const int ttypes[TTYPE_NMAX] = {
! 55: TERMP_BOLD, /* TTYPE_PROG */
! 56: TERMP_BOLD, /* TTYPE_CMD_FLAG */
! 57: TERMP_UNDERLINE, /* TTYPE_CMD_ARG */
! 58: TERMP_BOLD, /* TTYPE_SECTION */
! 59: TERMP_BOLD, /* TTYPE_FUNC_DECL */
! 60: TERMP_UNDERLINE, /* TTYPE_VAR_DECL */
! 61: TERMP_UNDERLINE, /* TTYPE_FUNC_TYPE */
! 62: TERMP_BOLD, /* TTYPE_FUNC_NAME */
! 63: TERMP_UNDERLINE, /* TTYPE_FUNC_ARG */
! 64: TERMP_UNDERLINE, /* TTYPE_LINK */
! 65: TERMP_BOLD, /* TTYPE_SSECTION */
! 66: TERMP_UNDERLINE /* TTYPE_FILE */
! 67: };
1.7 kristaps 68:
1.10 ! kristaps 69: static int arg_hasattr(int, size_t,
! 70: const struct mdoc_arg *);
! 71: static int arg_getattr(int, size_t,
! 72: const struct mdoc_arg *);
! 73: static size_t arg_offset(const char *);
! 74:
! 75: /*
! 76: * What follows describes prefix and postfix operations for the abstract
! 77: * syntax tree descent.
! 78: */
1.1 kristaps 79:
1.10 ! kristaps 80: #define DECL_ARGS \
! 81: struct termp *p, \
! 82: const struct mdoc_meta *meta, \
! 83: const struct mdoc_node *node
! 84:
! 85: #define DECL_PRE(name) \
! 86: static int name##_pre(DECL_ARGS)
! 87: #define DECL_POST(name) \
! 88: static void name##_post(DECL_ARGS)
! 89: #define DECL_PREPOST(name) \
! 90: DECL_PRE(name); \
! 91: DECL_POST(name);
! 92:
! 93: DECL_PREPOST(termp_aq);
! 94: DECL_PREPOST(termp_ar);
! 95: DECL_PREPOST(termp_d1);
! 96: DECL_PREPOST(termp_dq);
! 97: DECL_PREPOST(termp_fa);
! 98: DECL_PREPOST(termp_fd);
! 99: DECL_PREPOST(termp_fl);
! 100: DECL_PREPOST(termp_fn);
! 101: DECL_PREPOST(termp_ft);
! 102: DECL_PREPOST(termp_it);
! 103: DECL_PREPOST(termp_nm);
! 104: DECL_PREPOST(termp_op);
! 105: DECL_PREPOST(termp_pa);
! 106: DECL_PREPOST(termp_pf);
! 107: DECL_PREPOST(termp_qq);
! 108: DECL_PREPOST(termp_sh);
! 109: DECL_PREPOST(termp_ss);
! 110: DECL_PREPOST(termp_sq);
! 111: DECL_PREPOST(termp_sx);
! 112: DECL_PREPOST(termp_va);
! 113: DECL_PREPOST(termp_vt);
! 114:
! 115: DECL_PRE(termp_bd);
! 116: DECL_PRE(termp_bx);
! 117: DECL_PRE(termp_ex);
! 118: DECL_PRE(termp_nd);
! 119: DECL_PRE(termp_ns);
! 120: DECL_PRE(termp_nx);
! 121: DECL_PRE(termp_ox);
! 122: DECL_PRE(termp_pp);
! 123: DECL_PRE(termp_ud);
! 124: DECL_PRE(termp_xr);
! 125:
! 126: DECL_POST(termp_bl);
! 127:
! 128: const struct termact __termacts[MDOC_MAX] = {
! 129: { NULL, NULL }, /* \" */
! 130: { NULL, NULL }, /* Dd */
! 131: { NULL, NULL }, /* Dt */
! 132: { NULL, NULL }, /* Os */
! 133: { termp_sh_pre, termp_sh_post }, /* Sh */
! 134: { termp_ss_pre, termp_ss_post }, /* Ss */
! 135: { termp_pp_pre, NULL }, /* Pp */
! 136: { termp_d1_pre, termp_d1_post }, /* D1 */
! 137: { NULL, NULL }, /* Dl */
! 138: { termp_bd_pre, NULL }, /* Bd */
! 139: { NULL, NULL }, /* Ed */
! 140: { NULL, termp_bl_post }, /* Bl */
! 141: { NULL, NULL }, /* El */
! 142: { termp_it_pre, termp_it_post }, /* It */
! 143: { NULL, NULL }, /* Ad */
! 144: { NULL, NULL }, /* An */
! 145: { termp_ar_pre, termp_ar_post }, /* Ar */
! 146: { NULL, NULL }, /* Cd */
! 147: { NULL, NULL }, /* Cm */
! 148: { NULL, NULL }, /* Dv */
! 149: { NULL, NULL }, /* Er */
! 150: { NULL, NULL }, /* Ev */
! 151: { termp_ex_pre, NULL }, /* Ex */
! 152: { termp_fa_pre, termp_fa_post }, /* Fa */
! 153: { termp_fd_pre, termp_fd_post }, /* Fd */
! 154: { termp_fl_pre, termp_fl_post }, /* Fl */
! 155: { termp_fn_pre, termp_fn_post }, /* Fn */
! 156: { termp_ft_pre, termp_ft_post }, /* Ft */
! 157: { NULL, NULL }, /* Ic */
! 158: { NULL, NULL }, /* In */
! 159: { NULL, NULL }, /* Li */
! 160: { termp_nd_pre, NULL }, /* Nd */
! 161: { termp_nm_pre, termp_nm_post }, /* Nm */
! 162: { termp_op_pre, termp_op_post }, /* Op */
! 163: { NULL, NULL }, /* Ot */
! 164: { termp_pa_pre, termp_pa_post }, /* Pa */
! 165: { NULL, NULL }, /* Rv */
! 166: { NULL, NULL }, /* St */
! 167: { termp_va_pre, termp_va_post }, /* Va */
! 168: { termp_vt_pre, termp_vt_post }, /* Vt */
! 169: { termp_xr_pre, NULL }, /* Xr */
! 170: { NULL, NULL }, /* %A */
! 171: { NULL, NULL }, /* %B */
! 172: { NULL, NULL }, /* %D */
! 173: { NULL, NULL }, /* %I */
! 174: { NULL, NULL }, /* %J */
! 175: { NULL, NULL }, /* %N */
! 176: { NULL, NULL }, /* %O */
! 177: { NULL, NULL }, /* %P */
! 178: { NULL, NULL }, /* %R */
! 179: { NULL, NULL }, /* %T */
! 180: { NULL, NULL }, /* %V */
! 181: { NULL, NULL }, /* Ac */
! 182: { NULL, NULL }, /* Ao */
! 183: { termp_aq_pre, termp_aq_post }, /* Aq */
! 184: { NULL, NULL }, /* At */
! 185: { NULL, NULL }, /* Bc */
! 186: { NULL, NULL }, /* Bf */
! 187: { NULL, NULL }, /* Bo */
! 188: { NULL, NULL }, /* Bq */
! 189: { NULL, NULL }, /* Bsx */
! 190: { termp_bx_pre, NULL }, /* Bx */
! 191: { NULL, NULL }, /* Db */
! 192: { NULL, NULL }, /* Dc */
! 193: { NULL, NULL }, /* Do */
! 194: { termp_dq_pre, termp_dq_post }, /* Dq */
! 195: { NULL, NULL }, /* Ec */
! 196: { NULL, NULL }, /* Ef */
! 197: { NULL, NULL }, /* Em */
! 198: { NULL, NULL }, /* Eo */
! 199: { NULL, NULL }, /* Fx */
! 200: { NULL, NULL }, /* Ms */
! 201: { NULL, NULL }, /* No */
! 202: { termp_ns_pre, NULL }, /* Ns */
! 203: { termp_nx_pre, NULL }, /* Nx */
! 204: { termp_ox_pre, NULL }, /* Ox */
! 205: { NULL, NULL }, /* Pc */
! 206: { termp_pf_pre, termp_pf_post }, /* Pf */
! 207: { NULL, NULL }, /* Po */
! 208: { NULL, NULL }, /* Pq */
! 209: { NULL, NULL }, /* Qc */
! 210: { NULL, NULL }, /* Ql */
! 211: { NULL, NULL }, /* Qo */
! 212: { termp_qq_pre, termp_qq_post }, /* Qq */
! 213: { NULL, NULL }, /* Re */
! 214: { NULL, NULL }, /* Rs */
! 215: { NULL, NULL }, /* Sc */
! 216: { NULL, NULL }, /* So */
! 217: { termp_sq_pre, termp_sq_post }, /* Sq */
! 218: { NULL, NULL }, /* Sm */
! 219: { termp_sx_pre, termp_sx_post }, /* Sx */
! 220: { NULL, NULL }, /* Sy */
! 221: { NULL, NULL }, /* Tn */
! 222: { NULL, NULL }, /* Ux */
! 223: { NULL, NULL }, /* Xc */
! 224: { NULL, NULL }, /* Xo */
! 225: { NULL, NULL }, /* Fo */
! 226: { NULL, NULL }, /* Fc */
! 227: { NULL, NULL }, /* Oo */
! 228: { NULL, NULL }, /* Oc */
! 229: { NULL, NULL }, /* Bk */
! 230: { NULL, NULL }, /* Ek */
! 231: { NULL, NULL }, /* Bt */
! 232: { NULL, NULL }, /* Hf */
! 233: { NULL, NULL }, /* Fr */
! 234: { termp_ud_pre, NULL }, /* Ud */
1.2 kristaps 235: };
236:
1.10 ! kristaps 237: const struct termact *termacts = __termacts;
! 238:
! 239:
! 240: static size_t
! 241: arg_offset(const char *v)
! 242: {
! 243: if (0 == strcmp(v, "indent"))
! 244: return(INDENT);
! 245: if (0 == strcmp(v, "indent-two"))
! 246: return(INDENT * 2);
! 247:
! 248: /* TODO */
! 249: return(0);
! 250: }
! 251:
1.3 kristaps 252:
1.10 ! kristaps 253: static int
! 254: arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
1.2 kristaps 255: {
256:
1.10 ! kristaps 257: return(-1 != arg_getattr(arg, argc, argv));
! 258: }
! 259:
! 260:
! 261: static int
! 262: arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
! 263: {
! 264: int i;
! 265:
! 266: for (i = 0; i < (int)argc; i++)
! 267: if (argv[i].arg == arg)
! 268: return(i);
! 269: return(-1);
! 270: }
! 271:
! 272:
! 273: /* ARGSUSED */
! 274: static int
! 275: termp_dq_pre(DECL_ARGS)
! 276: {
! 277:
! 278: if (MDOC_BODY != node->type)
! 279: return(1);
! 280:
! 281: word(p, "``");
! 282: p->flags |= TERMP_NOSPACE;
! 283: return(1);
! 284: }
! 285:
! 286:
! 287: /* ARGSUSED */
! 288: static void
! 289: termp_dq_post(DECL_ARGS)
! 290: {
! 291:
! 292: if (MDOC_BODY != node->type)
! 293: return;
1.3 kristaps 294:
1.10 ! kristaps 295: p->flags |= TERMP_NOSPACE;
! 296: word(p, "''");
! 297: }
1.2 kristaps 298:
1.3 kristaps 299:
1.10 ! kristaps 300: /* ARGSUSED */
! 301: static void
! 302: termp_it_post(DECL_ARGS)
! 303: {
! 304: const struct mdoc_node *n, *it;
! 305: const struct mdoc_block *bl;
! 306: int i;
! 307: size_t width;
1.2 kristaps 308:
1.8 kristaps 309: /*
1.10 ! kristaps 310: * This (and termp_it_pre()) are the most complicated functions
! 311: * here. They must account for a considerable number of
! 312: * switches that completely change the output behaviour, like
! 313: * -tag versus -column. Yech.
1.8 kristaps 314: */
1.10 ! kristaps 315:
! 316: switch (node->type) {
! 317: case (MDOC_BODY):
! 318: /* FALLTHROUGH */
! 319: case (MDOC_HEAD):
! 320: break;
! 321: default:
1.8 kristaps 322: return;
323: }
324:
1.10 ! kristaps 325: it = node->parent;
! 326: assert(MDOC_BLOCK == it->type);
! 327: assert(MDOC_It == it->tok);
! 328:
! 329: n = it->parent;
! 330: assert(MDOC_BODY == n->type);
! 331: assert(MDOC_Bl == n->tok);
! 332: n = n->parent;
! 333: bl = &n->data.block;
! 334:
! 335: /* If `-tag', adjust our margins accordingly. */
! 336:
! 337: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
! 338: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
! 339: assert(i >= 0);
! 340: assert(1 == bl->argv[i].sz);
! 341: width = strlen(*bl->argv[i].value); /* XXX */
! 342:
! 343: if (MDOC_HEAD == node->type) {
! 344: flushln(p);
! 345: /* FIXME: nested lists. */
! 346: p->rmargin = p->maxrmargin;
! 347: p->flags &= ~TERMP_NOBREAK;
! 348: } else {
! 349: flushln(p);
! 350: p->offset -= width + 1;
! 351: p->flags &= ~TERMP_NOLPAD;
1.2 kristaps 352: }
1.10 ! kristaps 353: return;
! 354: }
1.2 kristaps 355:
1.10 ! kristaps 356: if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
! 357: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
! 358: width = 0;
! 359: if (i >= 0) {
! 360: assert(1 == bl->argv[i].sz);
! 361: width = arg_offset(*bl->argv[i].value);
1.3 kristaps 362: }
363:
1.10 ! kristaps 364: flushln(p);
! 365: p->offset -= width;
! 366: return;
1.2 kristaps 367: }
1.10 ! kristaps 368: }
! 369:
! 370:
! 371: /* ARGSUSED */
! 372: static int
! 373: termp_it_pre(DECL_ARGS)
! 374: {
! 375: const struct mdoc_node *n, *it;
! 376: const struct mdoc_block *bl;
! 377: int i;
! 378: size_t width;
1.2 kristaps 379:
1.3 kristaps 380: /*
1.10 ! kristaps 381: * Also see termp_it_post() for general comments.
1.3 kristaps 382: */
383:
1.10 ! kristaps 384: switch (node->type) {
! 385: case (MDOC_BODY):
! 386: /* FALLTHROUGH */
! 387: case (MDOC_HEAD):
! 388: it = node->parent;
! 389: break;
! 390: case (MDOC_BLOCK):
! 391: it = node;
! 392: break;
! 393: default:
! 394: return(1);
! 395: }
! 396:
! 397: assert(MDOC_BLOCK == it->type);
! 398: assert(MDOC_It == it->tok);
! 399:
! 400: n = it->parent;
! 401: assert(MDOC_BODY == n->type);
! 402: assert(MDOC_Bl == n->tok);
! 403: n = n->parent;
! 404: bl = &n->data.block;
! 405:
! 406: /* If `-compact', don't assert vertical space. */
! 407:
! 408: if (MDOC_BLOCK == node->type) {
! 409: if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
! 410: newln(p);
! 411: else
! 412: vspace(p);
! 413: return(1);
! 414: }
! 415:
! 416: assert(MDOC_HEAD == node->type
! 417: || MDOC_BODY == node->type);
! 418:
! 419: /* If `-tag', adjust our margins accordingly. */
! 420:
! 421: if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
! 422: i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
! 423: assert(i >= 0); /* XXX */
! 424: assert(1 == bl->argv[i].sz);
! 425: width = strlen(*bl->argv[i].value); /* XXX */
! 426:
! 427: /* FIXME: nested lists. */
! 428:
! 429: if (MDOC_HEAD == node->type) {
! 430: p->flags |= TERMP_NOBREAK;
! 431: p->flags |= TERMP_NOSPACE;
! 432: p->rmargin = p->offset + width;
! 433: } else {
! 434: p->flags |= TERMP_NOSPACE;
! 435: p->flags |= TERMP_NOLPAD;
! 436: p->offset += width + 1;
! 437: }
! 438: return(1);
! 439: }
! 440:
! 441: /* If `-ohang', adjust left-margin. */
! 442:
! 443: if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
! 444: width = 0;
! 445: i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
! 446: if (i >= 0) {
! 447: assert(1 == bl->argv[i].sz);
! 448: width = arg_offset(*bl->argv[i].value);
! 449: }
! 450:
! 451: p->flags |= TERMP_NOSPACE;
! 452: p->offset += width;
! 453: return(1);
! 454: }
1.3 kristaps 455:
1.10 ! kristaps 456: return(1);
1.2 kristaps 457: }
458:
459:
1.10 ! kristaps 460: /* ARGSUSED */
! 461: static void
! 462: termp_nm_post(DECL_ARGS)
! 463: {
! 464:
! 465: p->flags &= ~ttypes[TTYPE_PROG];
! 466: }
! 467:
! 468:
! 469: /* ARGSUSED */
! 470: static void
! 471: termp_fl_post(DECL_ARGS)
! 472: {
! 473:
! 474: p->flags &= ~ttypes[TTYPE_CMD_FLAG];
! 475: }
! 476:
! 477:
! 478: /* ARGSUSED */
! 479: static int
! 480: termp_ar_pre(DECL_ARGS)
! 481: {
! 482:
! 483: p->flags |= ttypes[TTYPE_CMD_ARG];
! 484: if (NULL == node->child)
! 485: word(p, "...");
! 486: return(1);
! 487: }
! 488:
! 489:
! 490: /* ARGSUSED */
! 491: static int
! 492: termp_nm_pre(DECL_ARGS)
! 493: {
! 494:
! 495: p->flags |= ttypes[TTYPE_PROG];
! 496: if (NULL == node->child)
! 497: word(p, meta->name);
! 498: return(1);
! 499: }
! 500:
! 501:
! 502: /* ARGSUSED */
! 503: static int
! 504: termp_ns_pre(DECL_ARGS)
1.2 kristaps 505: {
506:
507: p->flags |= TERMP_NOSPACE;
1.10 ! kristaps 508: return(1);
! 509: }
! 510:
! 511:
! 512: /* ARGSUSED */
! 513: static int
! 514: termp_pp_pre(DECL_ARGS)
! 515: {
! 516:
! 517: vspace(p);
! 518: return(1);
! 519: }
! 520:
! 521:
! 522: /* ARGSUSED */
! 523: static void
! 524: termp_ar_post(DECL_ARGS)
! 525: {
! 526:
! 527: p->flags &= ~ttypes[TTYPE_CMD_ARG];
! 528: }
! 529:
! 530:
! 531: /* ARGSUSED */
! 532: static int
! 533: termp_ex_pre(DECL_ARGS)
! 534: {
! 535: int i;
! 536:
! 537: i = arg_getattr(MDOC_Std, node->data.elem.argc,
! 538: node->data.elem.argv);
! 539: assert(i >= 0);
! 540:
! 541: word(p, "The");
! 542: p->flags |= ttypes[TTYPE_PROG];
! 543: word(p, *node->data.elem.argv[i].value);
! 544: p->flags &= ~ttypes[TTYPE_PROG];
! 545: word(p, "utility exits 0 on success, and >0 if an error occurs.");
! 546:
! 547: return(1);
! 548: }
! 549:
! 550:
! 551: /* ARGSUSED */
! 552: static int
! 553: termp_nd_pre(DECL_ARGS)
! 554: {
! 555:
! 556: word(p, "\\-");
! 557: return(1);
! 558: }
! 559:
! 560:
! 561: /* ARGSUSED */
! 562: static void
! 563: termp_bl_post(DECL_ARGS)
! 564: {
! 565:
! 566: if (MDOC_BLOCK == node->type)
! 567: newln(p);
! 568: }
! 569:
! 570:
! 571: /* ARGSUSED */
! 572: static void
! 573: termp_op_post(DECL_ARGS)
! 574: {
! 575:
! 576: if (MDOC_BODY != node->type)
1.2 kristaps 577: return;
1.10 ! kristaps 578: p->flags |= TERMP_NOSPACE;
! 579: word(p, "\\(rB");
! 580: }
! 581:
! 582:
! 583: /* ARGSUSED */
! 584: static void
! 585: termp_sh_post(DECL_ARGS)
! 586: {
! 587:
! 588: switch (node->type) {
! 589: case (MDOC_HEAD):
! 590: p->flags &= ~ttypes[TTYPE_SECTION];
! 591: newln(p);
! 592: break;
! 593: case (MDOC_BODY):
! 594: newln(p);
! 595: p->offset = 0;
! 596: break;
! 597: default:
! 598: break;
! 599: }
! 600: }
! 601:
! 602:
! 603: /* ARGSUSED */
! 604: static int
! 605: termp_xr_pre(DECL_ARGS)
! 606: {
! 607: const struct mdoc_node *n;
! 608:
! 609: n = node->child;
! 610: assert(n);
! 611:
! 612: assert(MDOC_TEXT == n->type);
! 613: word(p, n->data.text.string);
! 614:
! 615: if (NULL == (n = n->next))
! 616: return(0);
! 617:
! 618: assert(MDOC_TEXT == n->type);
! 619: p->flags |= TERMP_NOSPACE;
! 620: word(p, "(");
! 621: p->flags |= TERMP_NOSPACE;
! 622: word(p, n->data.text.string);
! 623: p->flags |= TERMP_NOSPACE;
! 624: word(p, ")");
! 625:
! 626: return(0);
1.2 kristaps 627: }
628:
629:
1.10 ! kristaps 630: /* ARGSUSED */
! 631: static int
! 632: termp_vt_pre(DECL_ARGS)
1.2 kristaps 633: {
634:
1.10 ! kristaps 635: /* FIXME: this can be "type name". */
! 636: p->flags |= ttypes[TTYPE_VAR_DECL];
! 637: return(1);
1.2 kristaps 638: }
639:
640:
1.10 ! kristaps 641: /* ARGSUSED */
1.2 kristaps 642: static void
1.10 ! kristaps 643: termp_vt_post(DECL_ARGS)
! 644: {
! 645:
! 646: p->flags &= ~ttypes[TTYPE_VAR_DECL];
! 647: if (node->sec == SEC_SYNOPSIS)
! 648: vspace(p);
! 649: }
! 650:
! 651:
! 652: /* ARGSUSED */
! 653: static int
! 654: termp_fd_pre(DECL_ARGS)
1.2 kristaps 655: {
656:
1.10 ! kristaps 657: /*
! 658: * FIXME: this naming is bad. This value is used, in general,
! 659: * for the #include header or other preprocessor statement.
! 660: */
! 661: p->flags |= ttypes[TTYPE_FUNC_DECL];
! 662: return(1);
1.2 kristaps 663: }
664:
665:
1.10 ! kristaps 666: /* ARGSUSED */
1.2 kristaps 667: static void
1.10 ! kristaps 668: termp_fd_post(DECL_ARGS)
1.2 kristaps 669: {
670:
1.10 ! kristaps 671: p->flags &= ~ttypes[TTYPE_FUNC_DECL];
! 672: if (node->sec == SEC_SYNOPSIS)
! 673: vspace(p);
! 674:
! 675: }
! 676:
! 677:
! 678: /* ARGSUSED */
! 679: static int
! 680: termp_sh_pre(DECL_ARGS)
! 681: {
1.2 kristaps 682:
1.10 ! kristaps 683: switch (node->type) {
! 684: case (MDOC_HEAD):
! 685: vspace(p);
! 686: p->flags |= ttypes[TTYPE_SECTION];
1.2 kristaps 687: break;
1.10 ! kristaps 688: case (MDOC_BODY):
! 689: p->offset = INDENT;
1.2 kristaps 690: break;
1.10 ! kristaps 691: default:
! 692: break;
! 693: }
! 694: return(1);
! 695: }
! 696:
! 697:
! 698: /* ARGSUSED */
! 699: static int
! 700: termp_op_pre(DECL_ARGS)
! 701: {
! 702:
! 703: switch (node->type) {
! 704: case (MDOC_BODY):
! 705: word(p, "\\(lB");
! 706: p->flags |= TERMP_NOSPACE;
1.2 kristaps 707: break;
708: default:
1.10 ! kristaps 709: break;
1.2 kristaps 710: }
1.10 ! kristaps 711: return(1);
! 712: }
! 713:
! 714:
! 715: /* ARGSUSED */
! 716: static int
! 717: termp_ud_pre(DECL_ARGS)
! 718: {
! 719:
! 720: word(p, "currently under development.");
! 721: return(1);
! 722: }
! 723:
! 724:
! 725: /* ARGSUSED */
! 726: static int
! 727: termp_fl_pre(DECL_ARGS)
! 728: {
! 729:
! 730: p->flags |= ttypes[TTYPE_CMD_FLAG];
! 731: word(p, "\\-");
! 732: p->flags |= TERMP_NOSPACE;
! 733: return(1);
! 734: }
! 735:
! 736:
! 737: /* ARGSUSED */
! 738: static int
! 739: termp_d1_pre(DECL_ARGS)
! 740: {
! 741:
! 742: if (MDOC_BODY != node->type)
! 743: return(1);
! 744: newln(p);
! 745: p->offset += INDENT;
! 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_d1_post(DECL_ARGS)
! 753: {
! 754:
! 755: if (MDOC_BODY != node->type)
! 756: return;
! 757: newln(p);
! 758: p->offset -= INDENT;
! 759: }
! 760:
! 761:
! 762: /* ARGSUSED */
! 763: static int
! 764: termp_aq_pre(DECL_ARGS)
1.6 kristaps 765: {
766:
1.10 ! kristaps 767: if (MDOC_BODY != node->type)
! 768: return(1);
! 769: word(p, "<");
! 770: p->flags |= TERMP_NOSPACE;
! 771: return(1);
! 772: }
1.6 kristaps 773:
774:
1.10 ! kristaps 775: /* ARGSUSED */
! 776: static void
! 777: termp_aq_post(DECL_ARGS)
! 778: {
1.6 kristaps 779:
1.10 ! kristaps 780: if (MDOC_BODY != node->type)
1.6 kristaps 781: return;
1.10 ! kristaps 782: p->flags |= TERMP_NOSPACE;
! 783: word(p, ">");
! 784: }
1.6 kristaps 785:
1.10 ! kristaps 786:
! 787: /* ARGSUSED */
! 788: static int
! 789: termp_ft_pre(DECL_ARGS)
! 790: {
! 791:
! 792: p->flags |= ttypes[TTYPE_FUNC_TYPE];
! 793: return(1);
1.6 kristaps 794: }
795:
796:
1.10 ! kristaps 797: /* ARGSUSED */
1.6 kristaps 798: static void
1.10 ! kristaps 799: termp_ft_post(DECL_ARGS)
1.2 kristaps 800: {
801:
1.10 ! kristaps 802: p->flags &= ~ttypes[TTYPE_FUNC_TYPE];
! 803: if (node->sec == SEC_SYNOPSIS)
! 804: newln(p);
! 805:
! 806: }
1.2 kristaps 807:
808:
1.10 ! kristaps 809: /* ARGSUSED */
! 810: static int
! 811: termp_fn_pre(DECL_ARGS)
! 812: {
! 813: const struct mdoc_node *n;
! 814:
! 815: assert(node->child);
! 816: assert(MDOC_TEXT == node->child->type);
1.2 kristaps 817:
1.10 ! kristaps 818: /* FIXME: can be "type funcname" "type varname"... */
1.2 kristaps 819:
1.10 ! kristaps 820: p->flags |= ttypes[TTYPE_FUNC_NAME];
! 821: word(p, node->child->data.text.string);
! 822: p->flags &= ~ttypes[TTYPE_FUNC_NAME];
! 823:
! 824: p->flags |= TERMP_NOSPACE;
! 825: word(p, "(");
! 826:
! 827: p->flags |= TERMP_NOSPACE;
! 828: for (n = node->child->next; n; n = n->next) {
! 829: assert(MDOC_TEXT == n->type);
! 830: p->flags |= ttypes[TTYPE_FUNC_ARG];
! 831: word(p, n->data.text.string);
! 832: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
! 833: if ((n->next))
! 834: word(p, ",");
1.6 kristaps 835: }
1.2 kristaps 836:
1.10 ! kristaps 837: p->flags |= TERMP_NOSPACE;
! 838: word(p, ")");
! 839:
! 840: if (SEC_SYNOPSIS == node->sec)
! 841: word(p, ";");
! 842:
! 843: return(0);
1.2 kristaps 844: }
845:
846:
1.10 ! kristaps 847: /* ARGSUSED */
! 848: static void
! 849: termp_fn_post(DECL_ARGS)
1.2 kristaps 850: {
851:
1.10 ! kristaps 852: if (node->sec == SEC_SYNOPSIS)
! 853: vspace(p);
! 854:
! 855: }
1.2 kristaps 856:
857:
1.10 ! kristaps 858: /* ARGSUSED */
! 859: static int
! 860: termp_sx_pre(DECL_ARGS)
! 861: {
1.8 kristaps 862:
1.10 ! kristaps 863: p->flags |= ttypes[TTYPE_LINK];
! 864: return(1);
1.2 kristaps 865: }
866:
867:
1.10 ! kristaps 868: /* ARGSUSED */
1.1 kristaps 869: static void
1.10 ! kristaps 870: termp_sx_post(DECL_ARGS)
1.2 kristaps 871: {
872:
1.10 ! kristaps 873: p->flags &= ~ttypes[TTYPE_LINK];
! 874: }
1.2 kristaps 875:
1.4 kristaps 876:
1.10 ! kristaps 877: /* ARGSUSED */
! 878: static int
! 879: termp_fa_pre(DECL_ARGS)
! 880: {
1.2 kristaps 881:
1.10 ! kristaps 882: p->flags |= ttypes[TTYPE_FUNC_ARG];
! 883: return(1);
! 884: }
1.2 kristaps 885:
886:
1.10 ! kristaps 887: /* ARGSUSED */
! 888: static void
! 889: termp_fa_post(DECL_ARGS)
! 890: {
! 891:
! 892: p->flags &= ~ttypes[TTYPE_FUNC_ARG];
! 893: }
1.2 kristaps 894:
895:
1.10 ! kristaps 896: /* ARGSUSED */
! 897: static int
! 898: termp_va_pre(DECL_ARGS)
! 899: {
1.2 kristaps 900:
1.10 ! kristaps 901: p->flags |= ttypes[TTYPE_VAR_DECL];
! 902: return(1);
1.2 kristaps 903: }
904:
905:
1.10 ! kristaps 906: /* ARGSUSED */
1.2 kristaps 907: static void
1.10 ! kristaps 908: termp_va_post(DECL_ARGS)
1.1 kristaps 909: {
910:
1.10 ! kristaps 911: p->flags &= ~ttypes[TTYPE_VAR_DECL];
! 912: }
1.1 kristaps 913:
1.7 kristaps 914:
1.10 ! kristaps 915: /* ARGSUSED */
! 916: static int
! 917: termp_bd_pre(DECL_ARGS)
! 918: {
! 919: const struct mdoc_block *bl;
! 920: const struct mdoc_node *n;
1.1 kristaps 921:
1.10 ! kristaps 922: if (MDOC_BLOCK == node->type) {
! 923: vspace(p);
! 924: return(1);
! 925: } else if (MDOC_BODY != node->type)
! 926: return(1);
! 927:
! 928: assert(MDOC_BLOCK == node->parent->type);
! 929:
! 930: bl = &node->parent->data.block;
! 931: if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
! 932: return(1);
! 933:
! 934: p->flags |= TERMP_LITERAL;
! 935:
! 936: for (n = node->child; n; n = n->next) {
! 937: assert(MDOC_TEXT == n->type); /* FIXME */
! 938: if ((*n->data.text.string)) {
! 939: word(p, n->data.text.string);
! 940: flushln(p);
! 941: } else
! 942: vspace(p);
1.1 kristaps 943:
1.10 ! kristaps 944: }
1.1 kristaps 945:
1.10 ! kristaps 946: p->flags &= ~TERMP_LITERAL;
! 947: return(0);
! 948: }
1.1 kristaps 949:
950:
1.10 ! kristaps 951: /* ARGSUSED */
! 952: static int
! 953: termp_qq_pre(DECL_ARGS)
! 954: {
1.1 kristaps 955:
1.10 ! kristaps 956: if (MDOC_BODY != node->type)
! 957: return(1);
! 958: word(p, "\"");
! 959: p->flags |= TERMP_NOSPACE;
! 960: return(1);
1.1 kristaps 961: }
962:
963:
1.10 ! kristaps 964: /* ARGSUSED */
1.1 kristaps 965: static void
1.10 ! kristaps 966: termp_qq_post(DECL_ARGS)
1.1 kristaps 967: {
968:
1.10 ! kristaps 969: if (MDOC_BODY != node->type)
! 970: return;
! 971: p->flags |= TERMP_NOSPACE;
! 972: word(p, "\"");
! 973: }
! 974:
! 975:
! 976: /* ARGSUSED */
! 977: static int
! 978: termp_bx_pre(DECL_ARGS)
! 979: {
1.1 kristaps 980:
1.10 ! kristaps 981: word(p, "BSD");
! 982: return(1);
! 983: }
! 984:
! 985:
! 986: /* ARGSUSED */
! 987: static int
! 988: termp_ox_pre(DECL_ARGS)
! 989: {
! 990:
! 991: word(p, "OpenBSD");
! 992: return(1);
! 993: }
! 994:
! 995:
! 996: /* ARGSUSED */
! 997: static int
! 998: termp_nx_pre(DECL_ARGS)
! 999: {
! 1000:
! 1001: word(p, "NetBSD");
! 1002: return(1);
! 1003: }
! 1004:
! 1005:
! 1006: /* ARGSUSED */
! 1007: static int
! 1008: termp_sq_pre(DECL_ARGS)
! 1009: {
! 1010:
! 1011: if (MDOC_BODY != node->type)
! 1012: return(1);
! 1013: word(p, "`");
! 1014: p->flags |= TERMP_NOSPACE;
! 1015: return(1);
! 1016: }
1.1 kristaps 1017:
1018:
1.10 ! kristaps 1019: /* ARGSUSED */
! 1020: static void
! 1021: termp_sq_post(DECL_ARGS)
! 1022: {
! 1023:
! 1024: if (MDOC_BODY != node->type)
! 1025: return;
! 1026: p->flags |= TERMP_NOSPACE;
! 1027: word(p, "\'");
! 1028: }
1.2 kristaps 1029:
1030:
1.10 ! kristaps 1031: /* ARGSUSED */
! 1032: static int
! 1033: termp_pf_pre(DECL_ARGS)
! 1034: {
1.1 kristaps 1035:
1.10 ! kristaps 1036: p->flags |= TERMP_IGNDELIM;
! 1037: return(1);
! 1038: }
1.1 kristaps 1039:
1040:
1.10 ! kristaps 1041: /* ARGSUSED */
! 1042: static void
! 1043: termp_pf_post(DECL_ARGS)
! 1044: {
1.1 kristaps 1045:
1.10 ! kristaps 1046: p->flags &= ~TERMP_IGNDELIM;
! 1047: p->flags |= TERMP_NOSPACE;
! 1048: }
1.1 kristaps 1049:
1050:
1.10 ! kristaps 1051: /* ARGSUSED */
! 1052: static int
! 1053: termp_ss_pre(DECL_ARGS)
! 1054: {
1.1 kristaps 1055:
1.10 ! kristaps 1056: switch (node->type) {
! 1057: case (MDOC_HEAD):
! 1058: vspace(p);
! 1059: p->flags |= ttypes[TTYPE_SSECTION];
! 1060: p->offset = INDENT / 2;
! 1061: break;
! 1062: default:
! 1063: break;
! 1064: }
1.1 kristaps 1065:
1.10 ! kristaps 1066: return(1);
1.1 kristaps 1067: }
1068:
1069:
1.10 ! kristaps 1070: /* ARGSUSED */
! 1071: static void
! 1072: termp_ss_post(DECL_ARGS)
1.1 kristaps 1073: {
1074:
1.10 ! kristaps 1075: switch (node->type) {
! 1076: case (MDOC_HEAD):
! 1077: p->flags &= ~ttypes[TTYPE_SSECTION];
! 1078: newln(p);
! 1079: p->offset = INDENT;
! 1080: break;
! 1081: default:
! 1082: break;
! 1083: }
! 1084: }
1.2 kristaps 1085:
1086:
1.10 ! kristaps 1087: /* ARGSUSED */
! 1088: static int
! 1089: termp_pa_pre(DECL_ARGS)
! 1090: {
1.2 kristaps 1091:
1.10 ! kristaps 1092: p->flags |= ttypes[TTYPE_FILE];
! 1093: return(1);
1.1 kristaps 1094: }
1095:
1096:
1.10 ! kristaps 1097: /* ARGSUSED */
! 1098: static void
! 1099: termp_pa_post(DECL_ARGS)
! 1100: {
! 1101:
! 1102: p->flags &= ~ttypes[TTYPE_FILE];
! 1103: }
CVSweb