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

Annotation of mandoc/termact.c, Revision 1.5

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

CVSweb