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

Annotation of mandoc/termact.c, Revision 1.6

1.6     ! kristaps    1: /* $Id: termact.c,v 1.5 2009/02/22 15:50:45 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);
1.6     ! kristaps   99: DECL_PRE(termp_nx);
1.1       kristaps  100: DECL_PRE(termp_op);
1.6     ! kristaps  101: DECL_PRE(termp_ox);
        !           102: DECL_PRE(termp_pf);
1.1       kristaps  103: DECL_PRE(termp_pp);
1.5       kristaps  104: DECL_PRE(termp_qq);
1.1       kristaps  105: DECL_PRE(termp_sh);
1.6     ! kristaps  106: DECL_PRE(termp_sq);
1.4       kristaps  107: DECL_PRE(termp_sx);
1.1       kristaps  108: DECL_PRE(termp_ud);
1.5       kristaps  109: DECL_PRE(termp_va);
1.4       kristaps  110: DECL_PRE(termp_vt);
1.1       kristaps  111: DECL_PRE(termp_xr);
                    112:
                    113: DECL_POST(termp_aq);
                    114: DECL_POST(termp_ar);
                    115: DECL_POST(termp_bl);
                    116: DECL_POST(termp_d1);
                    117: DECL_POST(termp_dq);
1.4       kristaps  118: DECL_POST(termp_fa);
                    119: DECL_POST(termp_fd);
1.1       kristaps  120: DECL_POST(termp_fl);
1.4       kristaps  121: DECL_POST(termp_fn);
                    122: DECL_POST(termp_ft);
1.1       kristaps  123: DECL_POST(termp_it);
                    124: DECL_POST(termp_nm);
                    125: DECL_POST(termp_op);
1.6     ! kristaps  126: DECL_POST(termp_pf);
1.5       kristaps  127: DECL_POST(termp_qq);
1.1       kristaps  128: DECL_POST(termp_sh);
1.6     ! kristaps  129: DECL_POST(termp_sq);
1.4       kristaps  130: DECL_POST(termp_sx);
1.5       kristaps  131: DECL_POST(termp_va);
1.4       kristaps  132: DECL_POST(termp_vt);
1.1       kristaps  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:        { NULL, NULL }, /* Ss */
                    141:        { termp_pp_pre, NULL }, /* Pp */
                    142:        { termp_d1_pre, termp_d1_post }, /* D1 */
                    143:        { NULL, NULL }, /* Dl */
1.5       kristaps  144:        { termp_bd_pre, NULL }, /* Bd */
1.1       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 */
1.4       kristaps  158:        { termp_fa_pre, termp_fa_post }, /* Fa */
                    159:        { termp_fd_pre, termp_fd_post }, /* Fd */
1.1       kristaps  160:        { termp_fl_pre, termp_fl_post }, /* Fl */
1.4       kristaps  161:        { termp_fn_pre, termp_fn_post }, /* Fn */
                    162:        { termp_ft_pre, termp_ft_post }, /* Ft */
1.1       kristaps  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:        { NULL, NULL }, /* Pa */
                    171:        { NULL, NULL }, /* Rv */
                    172:        { NULL, NULL }, /* St */
1.5       kristaps  173:        { termp_va_pre, termp_va_post }, /* Va */
1.4       kristaps  174:        { termp_vt_pre, termp_vt_post }, /* Vt */
1.1       kristaps  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:        { NULL, 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 */
                    203:        { NULL, NULL }, /* Em */
                    204:        { NULL, NULL }, /* Eo */
                    205:        { NULL, NULL }, /* Fx */
                    206:        { NULL, NULL }, /* Ms */
                    207:        { NULL, NULL }, /* No */
                    208:        { termp_ns_pre, NULL }, /* Ns */
1.6     ! kristaps  209:        { termp_nx_pre, NULL }, /* Nx */
        !           210:        { termp_ox_pre, NULL }, /* Ox */
1.1       kristaps  211:        { NULL, NULL }, /* Pc */
1.6     ! kristaps  212:        { termp_pf_pre, termp_pf_post }, /* Pf */
1.1       kristaps  213:        { NULL, NULL }, /* Po */
                    214:        { NULL, NULL }, /* Pq */
                    215:        { NULL, NULL }, /* Qc */
                    216:        { NULL, NULL }, /* Ql */
                    217:        { NULL, NULL }, /* Qo */
1.5       kristaps  218:        { termp_qq_pre, termp_qq_post }, /* Qq */
1.1       kristaps  219:        { NULL, NULL }, /* Re */
                    220:        { NULL, NULL }, /* Rs */
                    221:        { NULL, NULL }, /* Sc */
                    222:        { NULL, NULL }, /* So */
1.6     ! kristaps  223:        { termp_sq_pre, termp_sq_post }, /* Sq */
1.1       kristaps  224:        { NULL, NULL }, /* Sm */
1.4       kristaps  225:        { termp_sx_pre, termp_sx_post }, /* Sx */
1.1       kristaps  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 */
                    241: };
                    242:
                    243: const struct termact *termacts = __termacts;
                    244:
                    245:
1.4       kristaps  246: static size_t
                    247: arg_offset(const char *v)
                    248: {
                    249:        if (0 == strcmp(v, "indent"))
                    250:                return(INDENT);
                    251:        if (0 == strcmp(v, "indent-two"))
                    252:                return(INDENT * 2);
                    253:
                    254:        /* TODO */
                    255:        return(0);
                    256: }
                    257:
                    258:
                    259: static int
                    260: arg_hasattr(int arg, size_t argc, const struct mdoc_arg *argv)
                    261: {
                    262:
                    263:        return(-1 != arg_getattr(arg, argc, argv));
                    264: }
                    265:
                    266:
                    267: static int
                    268: arg_getattr(int arg, size_t argc, const struct mdoc_arg *argv)
                    269: {
                    270:        int              i;
                    271:
                    272:        for (i = 0; i < (int)argc; i++)
                    273:                if (argv[i].arg == arg)
                    274:                        return(i);
                    275:        return(-1);
                    276: }
                    277:
                    278:
1.1       kristaps  279: /* ARGSUSED */
                    280: static int
                    281: termp_dq_pre(DECL_ARGS)
                    282: {
                    283:
                    284:        if (MDOC_BODY != node->type)
                    285:                return(1);
                    286:
                    287:        word(p, "``");
                    288:        p->flags |= TERMP_NOSPACE;
                    289:        return(1);
                    290: }
                    291:
                    292:
                    293: /* ARGSUSED */
1.2       kristaps  294: static void
1.1       kristaps  295: termp_dq_post(DECL_ARGS)
                    296: {
                    297:
                    298:        if (MDOC_BODY != node->type)
1.2       kristaps  299:                return;
1.1       kristaps  300:
                    301:        p->flags |= TERMP_NOSPACE;
                    302:        word(p, "''");
                    303: }
                    304:
                    305:
                    306: /* ARGSUSED */
1.2       kristaps  307: static void
1.1       kristaps  308: termp_it_post(DECL_ARGS)
                    309: {
                    310:        const struct mdoc_node *n, *it;
                    311:        const struct mdoc_block *bl;
                    312:        int              i;
                    313:        size_t           width;
                    314:
                    315:        /*
                    316:         * This (and termp_it_pre()) are the most complicated functions
                    317:         * here.  They must account for a considerable number of
                    318:         * switches that completely change the output behaviour, like
                    319:         * -tag versus -column.  Yech.
                    320:         */
                    321:
                    322:        switch (node->type) {
                    323:        case (MDOC_BODY):
                    324:                /* FALLTHROUGH */
                    325:        case (MDOC_HEAD):
                    326:                break;
                    327:        default:
1.2       kristaps  328:                return;
1.1       kristaps  329:        }
                    330:
                    331:        it = node->parent;
                    332:        assert(MDOC_BLOCK == it->type);
                    333:        assert(MDOC_It == it->tok);
                    334:
                    335:        n = it->parent;
                    336:        assert(MDOC_BODY == n->type);
                    337:        assert(MDOC_Bl == n->tok);
                    338:        n = n->parent;
                    339:        bl = &n->data.block;
                    340:
                    341:        /* If `-tag', adjust our margins accordingly. */
                    342:
                    343:        if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
                    344:                i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
                    345:                assert(i >= 0);
                    346:                assert(1 == bl->argv[i].sz);
                    347:                width = strlen(*bl->argv[i].value); /* XXX */
                    348:
                    349:                if (MDOC_HEAD == node->type) {
                    350:                        flushln(p);
                    351:                        /* FIXME: nested lists. */
                    352:                        p->rmargin = p->maxrmargin;
                    353:                        p->flags &= ~TERMP_NOBREAK;
                    354:                } else {
                    355:                        flushln(p);
                    356:                        p->offset -= width + 1;
                    357:                        p->flags &= ~TERMP_NOLPAD;
                    358:                }
1.4       kristaps  359:                return;
                    360:        }
                    361:
                    362:        if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
                    363:                i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
                    364:                assert(i >= 0);
                    365:                assert(1 == bl->argv[i].sz);
                    366:                width = arg_offset(*bl->argv[i].value);
                    367:
                    368:                flushln(p);
                    369:                p->offset -= width + 1;
                    370:                return;
1.1       kristaps  371:        }
                    372: }
                    373:
                    374:
                    375: /* ARGSUSED */
                    376: static int
                    377: termp_it_pre(DECL_ARGS)
                    378: {
                    379:        const struct mdoc_node *n, *it;
                    380:        const struct mdoc_block *bl;
                    381:        int              i;
                    382:        size_t           width;
                    383:
                    384:        /*
                    385:         * Also see termp_it_post() for general comments.
                    386:         */
                    387:
                    388:        switch (node->type) {
                    389:        case (MDOC_BODY):
                    390:                /* FALLTHROUGH */
                    391:        case (MDOC_HEAD):
                    392:                it = node->parent;
                    393:                break;
                    394:        case (MDOC_BLOCK):
                    395:                it = node;
                    396:                break;
                    397:        default:
                    398:                return(1);
                    399:        }
                    400:
                    401:        assert(MDOC_BLOCK == it->type);
                    402:        assert(MDOC_It == it->tok);
                    403:
                    404:        n = it->parent;
                    405:        assert(MDOC_BODY == n->type);
                    406:        assert(MDOC_Bl == n->tok);
                    407:        n = n->parent;
                    408:        bl = &n->data.block;
                    409:
                    410:        /* If `-compact', don't assert vertical space. */
                    411:
                    412:        if (MDOC_BLOCK == node->type) {
                    413:                if (arg_hasattr(MDOC_Compact, bl->argc, bl->argv))
                    414:                        newln(p);
                    415:                else
                    416:                        vspace(p);
                    417:                return(1);
                    418:        }
                    419:
                    420:        assert(MDOC_HEAD == node->type
                    421:                        || MDOC_BODY == node->type);
                    422:
                    423:        /* If `-tag', adjust our margins accordingly. */
                    424:
                    425:        if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) {
                    426:                i = arg_getattr(MDOC_Width, bl->argc, bl->argv);
                    427:                assert(i >= 0); /* XXX */
                    428:                assert(1 == bl->argv[i].sz);
                    429:                width = strlen(*bl->argv[i].value); /* XXX */
                    430:
                    431:                /* FIXME: nested lists. */
                    432:
                    433:                if (MDOC_HEAD == node->type) {
                    434:                        p->flags |= TERMP_NOBREAK;
                    435:                        p->flags |= TERMP_NOSPACE;
                    436:                        p->rmargin = p->offset + width;
                    437:                } else {
                    438:                        p->flags |= TERMP_NOSPACE;
                    439:                        p->flags |= TERMP_NOLPAD;
                    440:                        p->offset += width + 1;
                    441:                }
1.4       kristaps  442:                return(1);
                    443:        }
                    444:
                    445:        /* If `-ohang', adjust left-margin. */
                    446:
                    447:        if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) {
                    448:                i = arg_getattr(MDOC_Offset, bl->argc, bl->argv);
                    449:                assert(i >= 0);
                    450:                assert(1 == bl->argv[i].sz);
                    451:                width = arg_offset(*bl->argv[i].value);
                    452:
                    453:                p->flags |= TERMP_NOSPACE;
                    454:                p->offset += width + 1;
                    455:                return(1);
1.1       kristaps  456:        }
                    457:
                    458:        return(1);
                    459: }
                    460:
                    461:
                    462: /* ARGSUSED */
1.2       kristaps  463: static void
1.1       kristaps  464: termp_nm_post(DECL_ARGS)
                    465: {
                    466:
                    467:        p->flags &= ~ttypes[TTYPE_PROG];
                    468: }
                    469:
                    470:
                    471: /* ARGSUSED */
1.2       kristaps  472: static void
1.1       kristaps  473: termp_fl_post(DECL_ARGS)
                    474: {
                    475:
                    476:        p->flags &= ~ttypes[TTYPE_CMD_FLAG];
                    477: }
                    478:
                    479:
                    480: /* ARGSUSED */
                    481: static int
                    482: termp_ar_pre(DECL_ARGS)
                    483: {
                    484:
                    485:        p->flags |= ttypes[TTYPE_CMD_ARG];
                    486:        if (NULL == node->child)
                    487:                word(p, "...");
                    488:        return(1);
                    489: }
                    490:
                    491:
                    492: /* ARGSUSED */
                    493: static int
                    494: termp_nm_pre(DECL_ARGS)
                    495: {
                    496:
                    497:        p->flags |= ttypes[TTYPE_PROG];
                    498:        if (NULL == node->child)
                    499:                word(p, meta->name);
                    500:        return(1);
                    501: }
                    502:
                    503:
                    504: /* ARGSUSED */
                    505: static int
                    506: termp_ns_pre(DECL_ARGS)
                    507: {
                    508:
                    509:        p->flags |= TERMP_NOSPACE;
                    510:        return(1);
                    511: }
                    512:
                    513:
                    514: /* ARGSUSED */
                    515: static int
                    516: termp_pp_pre(DECL_ARGS)
                    517: {
                    518:
                    519:        vspace(p);
                    520:        return(1);
                    521: }
                    522:
                    523:
                    524: /* ARGSUSED */
1.2       kristaps  525: static void
1.1       kristaps  526: termp_ar_post(DECL_ARGS)
                    527: {
                    528:
                    529:        p->flags &= ~ttypes[TTYPE_CMD_ARG];
                    530: }
                    531:
                    532:
                    533: /* ARGSUSED */
                    534: static int
                    535: termp_ex_pre(DECL_ARGS)
                    536: {
                    537:        int              i;
                    538:
                    539:        i = arg_getattr(MDOC_Std, node->data.elem.argc,
                    540:                        node->data.elem.argv);
                    541:        assert(i >= 0);
                    542:
                    543:        word(p, "The");
                    544:        p->flags |= ttypes[TTYPE_PROG];
                    545:        word(p, *node->data.elem.argv[i].value);
                    546:        p->flags &= ~ttypes[TTYPE_PROG];
                    547:                word(p, "utility exits 0 on success, and >0 if an error occurs.");
                    548:
                    549:        return(1);
                    550: }
                    551:
                    552:
                    553: /* ARGSUSED */
                    554: static int
                    555: termp_nd_pre(DECL_ARGS)
                    556: {
                    557:
                    558:        word(p, "\\-");
                    559:        return(1);
                    560: }
                    561:
                    562:
                    563: /* ARGSUSED */
1.2       kristaps  564: static void
1.1       kristaps  565: termp_bl_post(DECL_ARGS)
                    566: {
                    567:
1.2       kristaps  568:        if (MDOC_BLOCK == node->type)
1.1       kristaps  569:                newln(p);
                    570: }
                    571:
                    572:
                    573: /* ARGSUSED */
1.2       kristaps  574: static void
1.1       kristaps  575: termp_op_post(DECL_ARGS)
                    576: {
                    577:
1.2       kristaps  578:        if (MDOC_BODY != node->type)
                    579:                return;
                    580:        p->flags |= TERMP_NOSPACE;
                    581:        word(p, "\\(rB");
1.1       kristaps  582: }
                    583:
                    584:
                    585: /* ARGSUSED */
1.2       kristaps  586: static void
1.1       kristaps  587: termp_sh_post(DECL_ARGS)
                    588: {
                    589:
                    590:        switch (node->type) {
                    591:        case (MDOC_HEAD):
                    592:                p->flags &= ~ttypes[TTYPE_SECTION];
                    593:                newln(p);
                    594:                break;
                    595:        case (MDOC_BODY):
                    596:                newln(p);
1.4       kristaps  597:                p->offset -= INDENT;
1.1       kristaps  598:                break;
                    599:        default:
                    600:                break;
                    601:        }
                    602: }
                    603:
                    604:
                    605: /* ARGSUSED */
                    606: static int
                    607: termp_xr_pre(DECL_ARGS)
                    608: {
                    609:        const struct mdoc_node *n;
                    610:
                    611:        n = node->child;
                    612:        assert(n);
                    613:
                    614:        assert(MDOC_TEXT == n->type);
                    615:        word(p, n->data.text.string);
                    616:
                    617:        if (NULL == (n = n->next))
                    618:                return(0);
                    619:
                    620:        assert(MDOC_TEXT == n->type);
                    621:        p->flags |= TERMP_NOSPACE;
1.2       kristaps  622:        word(p, "(");
1.1       kristaps  623:        p->flags |= TERMP_NOSPACE;
                    624:        word(p, n->data.text.string);
                    625:        p->flags |= TERMP_NOSPACE;
1.2       kristaps  626:        word(p, ")");
1.1       kristaps  627:
                    628:        return(0);
                    629: }
                    630:
                    631:
                    632: /* ARGSUSED */
                    633: static int
1.4       kristaps  634: termp_vt_pre(DECL_ARGS)
                    635: {
                    636:
                    637:        /* FIXME: this can be "type name". */
                    638:        p->flags |= ttypes[TTYPE_VAR_DECL];
                    639:        return(1);
                    640: }
                    641:
                    642:
                    643: /* ARGSUSED */
                    644: static void
                    645: termp_vt_post(DECL_ARGS)
                    646: {
                    647:
                    648:        p->flags &= ~ttypes[TTYPE_VAR_DECL];
                    649:        if (node->sec == SEC_SYNOPSIS)
                    650:                vspace(p);
                    651: }
                    652:
                    653:
                    654: /* ARGSUSED */
                    655: static int
                    656: termp_fd_pre(DECL_ARGS)
                    657: {
                    658:
                    659:        /*
                    660:         * FIXME: this naming is bad.  This value is used, in general,
                    661:         * for the #include header or other preprocessor statement.
                    662:         */
                    663:        p->flags |= ttypes[TTYPE_FUNC_DECL];
                    664:        return(1);
                    665: }
                    666:
                    667:
                    668: /* ARGSUSED */
                    669: static void
                    670: termp_fd_post(DECL_ARGS)
                    671: {
                    672:
                    673:        p->flags &= ~ttypes[TTYPE_FUNC_DECL];
                    674:        if (node->sec == SEC_SYNOPSIS)
                    675:                vspace(p);
                    676:
                    677: }
                    678:
                    679:
                    680: /* ARGSUSED */
                    681: static int
1.1       kristaps  682: termp_sh_pre(DECL_ARGS)
                    683: {
                    684:
                    685:        switch (node->type) {
                    686:        case (MDOC_HEAD):
                    687:                vspace(p);
                    688:                p->flags |= ttypes[TTYPE_SECTION];
                    689:                break;
                    690:        case (MDOC_BODY):
1.4       kristaps  691:                p->offset += INDENT;
1.1       kristaps  692:                break;
                    693:        default:
                    694:                break;
                    695:        }
                    696:        return(1);
                    697: }
                    698:
                    699:
                    700: /* ARGSUSED */
                    701: static int
                    702: termp_op_pre(DECL_ARGS)
                    703: {
                    704:
                    705:        switch (node->type) {
                    706:        case (MDOC_BODY):
1.2       kristaps  707:                word(p, "\\(lB");
1.1       kristaps  708:                p->flags |= TERMP_NOSPACE;
                    709:                break;
                    710:        default:
                    711:                break;
                    712:        }
                    713:        return(1);
                    714: }
                    715:
                    716:
                    717: /* ARGSUSED */
                    718: static int
                    719: termp_ud_pre(DECL_ARGS)
                    720: {
                    721:
                    722:        word(p, "currently under development.");
                    723:        return(1);
                    724: }
                    725:
                    726:
                    727: /* ARGSUSED */
                    728: static int
                    729: termp_fl_pre(DECL_ARGS)
                    730: {
                    731:
                    732:        p->flags |= ttypes[TTYPE_CMD_FLAG];
                    733:        word(p, "\\-");
                    734:        p->flags |= TERMP_NOSPACE;
                    735:        return(1);
                    736: }
                    737:
                    738:
                    739: /* ARGSUSED */
                    740: static int
                    741: termp_d1_pre(DECL_ARGS)
                    742: {
                    743:
                    744:        if (MDOC_BODY != node->type)
                    745:                return(1);
                    746:        newln(p);
1.4       kristaps  747:        p->offset += INDENT;
1.1       kristaps  748:        return(1);
                    749: }
                    750:
                    751:
                    752: /* ARGSUSED */
1.2       kristaps  753: static void
1.1       kristaps  754: termp_d1_post(DECL_ARGS)
                    755: {
                    756:
1.2       kristaps  757:        if (MDOC_BODY != node->type)
                    758:                return;
1.1       kristaps  759:        newln(p);
1.4       kristaps  760:        p->offset -= INDENT;
1.1       kristaps  761: }
                    762:
                    763:
                    764: /* ARGSUSED */
                    765: static int
                    766: termp_aq_pre(DECL_ARGS)
                    767: {
                    768:
                    769:        if (MDOC_BODY != node->type)
                    770:                return(1);
1.3       kristaps  771:        word(p, "<");
1.1       kristaps  772:        p->flags |= TERMP_NOSPACE;
                    773:        return(1);
                    774: }
                    775:
                    776:
                    777: /* ARGSUSED */
1.2       kristaps  778: static void
1.1       kristaps  779: termp_aq_post(DECL_ARGS)
                    780: {
                    781:
                    782:        if (MDOC_BODY != node->type)
1.2       kristaps  783:                return;
1.1       kristaps  784:        p->flags |= TERMP_NOSPACE;
1.3       kristaps  785:        word(p, ">");
1.1       kristaps  786: }
                    787:
                    788:
1.4       kristaps  789: /* ARGSUSED */
                    790: static int
                    791: termp_ft_pre(DECL_ARGS)
                    792: {
                    793:
                    794:        p->flags |= ttypes[TTYPE_FUNC_TYPE];
                    795:        return(1);
                    796: }
                    797:
                    798:
                    799: /* ARGSUSED */
                    800: static void
                    801: termp_ft_post(DECL_ARGS)
                    802: {
                    803:
                    804:        p->flags &= ~ttypes[TTYPE_FUNC_TYPE];
                    805:        if (node->sec == SEC_SYNOPSIS)
                    806:                newln(p);
                    807:
                    808: }
                    809:
                    810:
                    811: /* ARGSUSED */
1.1       kristaps  812: static int
1.4       kristaps  813: termp_fn_pre(DECL_ARGS)
                    814: {
                    815:        const struct mdoc_node *n;
                    816:
                    817:        assert(node->child);
                    818:        assert(MDOC_TEXT == node->child->type);
                    819:
                    820:        /* FIXME: can be "type funcname" "type varname"... */
                    821:
                    822:        p->flags |= ttypes[TTYPE_FUNC_NAME];
                    823:        word(p, node->child->data.text.string);
                    824:        p->flags &= ~ttypes[TTYPE_FUNC_NAME];
                    825:
                    826:        p->flags |= TERMP_NOSPACE;
                    827:        word(p, "(");
                    828:
                    829:        p->flags |= TERMP_NOSPACE;
                    830:        for (n = node->child->next; n; n = n->next) {
                    831:                assert(MDOC_TEXT == n->type);
                    832:                p->flags |= ttypes[TTYPE_FUNC_ARG];
                    833:                word(p, n->data.text.string);
                    834:                p->flags &= ~ttypes[TTYPE_FUNC_ARG];
                    835:                if ((n->next))
                    836:                        word(p, ",");
                    837:        }
                    838:
                    839:        p->flags |= TERMP_NOSPACE;
                    840:        word(p, ")");
                    841:
                    842:        if (SEC_SYNOPSIS == node->sec)
                    843:                word(p, ";");
                    844:
                    845:        return(0);
                    846: }
                    847:
                    848:
                    849: /* ARGSUSED */
                    850: static void
                    851: termp_fn_post(DECL_ARGS)
                    852: {
                    853:
                    854:        if (node->sec == SEC_SYNOPSIS)
                    855:                vspace(p);
                    856:
                    857: }
                    858:
                    859:
                    860: /* ARGSUSED */
                    861: static int
                    862: termp_sx_pre(DECL_ARGS)
                    863: {
                    864:
                    865:        p->flags |= ttypes[TTYPE_LINK];
                    866:        return(1);
                    867: }
                    868:
                    869:
                    870: /* ARGSUSED */
                    871: static void
                    872: termp_sx_post(DECL_ARGS)
1.1       kristaps  873: {
                    874:
1.4       kristaps  875:        p->flags &= ~ttypes[TTYPE_LINK];
1.1       kristaps  876: }
                    877:
                    878:
1.4       kristaps  879: /* ARGSUSED */
1.1       kristaps  880: static int
1.4       kristaps  881: termp_fa_pre(DECL_ARGS)
                    882: {
                    883:
                    884:        p->flags |= ttypes[TTYPE_FUNC_ARG];
                    885:        return(1);
                    886: }
                    887:
                    888:
                    889: /* ARGSUSED */
                    890: static void
                    891: termp_fa_post(DECL_ARGS)
1.1       kristaps  892: {
                    893:
1.4       kristaps  894:        p->flags &= ~ttypes[TTYPE_FUNC_ARG];
1.1       kristaps  895: }
                    896:
1.4       kristaps  897:
1.5       kristaps  898: /* ARGSUSED */
                    899: static int
                    900: termp_va_pre(DECL_ARGS)
                    901: {
                    902:
                    903:        p->flags |= ttypes[TTYPE_VAR_DECL];
                    904:        return(1);
                    905: }
                    906:
                    907:
                    908: /* ARGSUSED */
                    909: static void
                    910: termp_va_post(DECL_ARGS)
                    911: {
                    912:
                    913:        p->flags &= ~ttypes[TTYPE_VAR_DECL];
                    914: }
                    915:
                    916:
                    917: /* ARGSUSED */
                    918: static int
                    919: termp_bd_pre(DECL_ARGS)
                    920: {
                    921:        const struct mdoc_block *bl;
                    922:        const struct mdoc_node *n;
                    923:
                    924:        if (MDOC_BLOCK == node->type) {
                    925:                vspace(p);
                    926:                return(1);
                    927:        } else if (MDOC_BODY != node->type)
                    928:                return(1);
                    929:
                    930:        assert(MDOC_BLOCK == node->parent->type);
                    931:
                    932:        bl = &node->parent->data.block;
                    933:        if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv))
                    934:                return(1);
                    935:
                    936:        p->flags |= TERMP_LITERAL;
                    937:
                    938:        for (n = node->child; n; n = n->next) {
                    939:                assert(MDOC_TEXT == n->type); /* FIXME */
                    940:                if ((*n->data.text.string)) {
                    941:                        word(p, n->data.text.string);
                    942:                        flushln(p);
                    943:                } else
                    944:                        vspace(p);
                    945:
                    946:        }
                    947:
                    948:        p->flags &= ~TERMP_LITERAL;
                    949:        return(0);
                    950: }
                    951:
                    952:
                    953: /* ARGSUSED */
                    954: static int
                    955: termp_qq_pre(DECL_ARGS)
                    956: {
                    957:
                    958:        if (MDOC_BODY != node->type)
                    959:                return(1);
                    960:        word(p, "\"");
                    961:        p->flags |= TERMP_NOSPACE;
                    962:        return(1);
                    963: }
                    964:
                    965:
                    966: /* ARGSUSED */
                    967: static void
                    968: termp_qq_post(DECL_ARGS)
                    969: {
                    970:
                    971:        if (MDOC_BODY != node->type)
                    972:                return;
                    973:        p->flags |= TERMP_NOSPACE;
                    974:        word(p, "\"");
                    975: }
                    976:
                    977:
1.6     ! kristaps  978: /* ARGSUSED */
        !           979: static int
        !           980: termp_ox_pre(DECL_ARGS)
        !           981: {
        !           982:
        !           983:        word(p, "OpenBSD");
        !           984:        return(1);
        !           985: }
        !           986:
        !           987:
        !           988: /* ARGSUSED */
        !           989: static int
        !           990: termp_nx_pre(DECL_ARGS)
        !           991: {
        !           992:
        !           993:        word(p, "NetBSD");
        !           994:        return(1);
        !           995: }
        !           996:
        !           997:
        !           998: /* ARGSUSED */
        !           999: static int
        !          1000: termp_sq_pre(DECL_ARGS)
        !          1001: {
        !          1002:
        !          1003:        if (MDOC_BODY != node->type)
        !          1004:                return(1);
        !          1005:        word(p, "`");
        !          1006:        p->flags |= TERMP_NOSPACE;
        !          1007:        return(1);
        !          1008: }
        !          1009:
        !          1010:
        !          1011: /* ARGSUSED */
        !          1012: static void
        !          1013: termp_sq_post(DECL_ARGS)
        !          1014: {
        !          1015:
        !          1016:        if (MDOC_BODY != node->type)
        !          1017:                return;
        !          1018:        p->flags |= TERMP_NOSPACE;
        !          1019:        word(p, "\'");
        !          1020: }
        !          1021:
        !          1022:
        !          1023: /* ARGSUSED */
        !          1024: static int
        !          1025: termp_pf_pre(DECL_ARGS)
        !          1026: {
        !          1027:
        !          1028:        p->flags |= TERMP_IGNDELIM;
        !          1029:        return(1);
        !          1030: }
        !          1031:
        !          1032:
        !          1033: /* ARGSUSED */
        !          1034: static void
        !          1035: termp_pf_post(DECL_ARGS)
        !          1036: {
        !          1037:
        !          1038:        p->flags &= ~TERMP_IGNDELIM;
        !          1039:        p->flags |= TERMP_NOSPACE;
        !          1040: }
        !          1041:
        !          1042:

CVSweb