[BACK]Return to term.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/term.c, Revision 1.16

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

CVSweb