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

Annotation of mandoc/term.c, Revision 1.12

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

CVSweb