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

Annotation of mandoc/term.c, Revision 1.11

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

CVSweb