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

Annotation of mandoc/mdoc_man.c, Revision 1.1

1.1     ! schwarze    1: /*     $Id$ */
        !             2: /*
        !             3:  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
        !             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 above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17: #include <stdio.h>
        !            18: #include <string.h>
        !            19:
        !            20: #include "mandoc.h"
        !            21: #include "mdoc.h"
        !            22: #include "main.h"
        !            23:
        !            24: static int       need_space = 0;
        !            25: static int       need_nl = 0;
        !            26:
        !            27: #define        DECL_ARGS const struct mdoc_meta *m, \
        !            28:                  const struct mdoc_node *n
        !            29:
        !            30: struct manact {
        !            31:        int             (*cond)(DECL_ARGS);
        !            32:        int             (*pre)(DECL_ARGS);
        !            33:        void            (*post)(DECL_ARGS);
        !            34:        char             *prefix;
        !            35:        char             *suffix;
        !            36: };
        !            37:
        !            38: static void      print_word(const char *);
        !            39: static void      print_node(DECL_ARGS);
        !            40:
        !            41: static int       cond_head(DECL_ARGS);
        !            42: static int       cond_body(DECL_ARGS);
        !            43: static int       pre_enc(DECL_ARGS);
        !            44: static void      post_enc(DECL_ARGS);
        !            45: static void      post_percent(DECL_ARGS);
        !            46:
        !            47: static int       pre_dl(DECL_ARGS);
        !            48: static void      post_dl(DECL_ARGS);
        !            49: static int       pre_it(DECL_ARGS);
        !            50: static int       pre_nm(DECL_ARGS);
        !            51: static void      post_nm(DECL_ARGS);
        !            52: static int       pre_ns(DECL_ARGS);
        !            53: static int       pre_pp(DECL_ARGS);
        !            54: static int       pre_sh(DECL_ARGS);
        !            55: static void      post_sh(DECL_ARGS);
        !            56: static int       pre_xr(DECL_ARGS);
        !            57:
        !            58:
        !            59: static const struct manact manacts[MDOC_MAX] = {
        !            60:        { NULL, NULL, NULL, NULL, NULL }, /* _Ap */
        !            61:        { NULL, NULL, NULL, NULL, NULL }, /* _Dd */
        !            62:        { NULL, NULL, NULL, NULL, NULL }, /* _Dt */
        !            63:        { NULL, NULL, NULL, NULL, NULL }, /* _Os */
        !            64:        { NULL, pre_sh, post_sh, NULL, NULL }, /* Sh */
        !            65:        { NULL, NULL, NULL, NULL, NULL }, /* _Ss */
        !            66:        { NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
        !            67:        { NULL, NULL, NULL, NULL, NULL }, /* _D1 */
        !            68:        { cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
        !            69:        { NULL, NULL, NULL, NULL, NULL }, /* _Bd */
        !            70:        { NULL, NULL, NULL, NULL, NULL }, /* _Ed */
        !            71:        { NULL, NULL, NULL, NULL, NULL }, /* _Bl */
        !            72:        { NULL, NULL, NULL, NULL, NULL }, /* _El */
        !            73:        { NULL, pre_it, NULL, NULL, NULL }, /* _It */
        !            74:        { NULL, NULL, NULL, NULL, NULL }, /* _Ad */
        !            75:        { NULL, NULL, NULL, NULL, NULL }, /* _An */
        !            76:        { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ar */
        !            77:        { NULL, NULL, NULL, NULL, NULL }, /* _Cd */
        !            78:        { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cm */
        !            79:        { NULL, NULL, NULL, NULL, NULL }, /* _Dv */
        !            80:        { NULL, NULL, NULL, NULL, NULL }, /* _Er */
        !            81:        { NULL, NULL, NULL, NULL, NULL }, /* _Ev */
        !            82:        { NULL, pre_enc, post_enc, "The \\fB",
        !            83:            "\\fP\nutility exits 0 on success, and >0 if an error occurs."
        !            84:            }, /* Ex */
        !            85:        { NULL, NULL, NULL, NULL, NULL }, /* _Fa */
        !            86:        { NULL, NULL, NULL, NULL, NULL }, /* _Fd */
        !            87:        { NULL, pre_enc, post_enc, "\\fB-", "\\fP" }, /* Fl */
        !            88:        { NULL, NULL, NULL, NULL, NULL }, /* _Fn */
        !            89:        { NULL, NULL, NULL, NULL, NULL }, /* _Ft */
        !            90:        { NULL, NULL, NULL, NULL, NULL }, /* _Ic */
        !            91:        { NULL, NULL, NULL, NULL, NULL }, /* _In */
        !            92:        { NULL, NULL, NULL, NULL, NULL }, /* _Li */
        !            93:        { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
        !            94:        { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
        !            95:        { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
        !            96:        { NULL, NULL, NULL, NULL, NULL }, /* _Ot */
        !            97:        { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* _Pa */
        !            98:        { NULL, NULL, NULL, NULL, NULL }, /* _Rv */
        !            99:        { NULL, NULL, NULL, NULL, NULL }, /* _St */
        !           100:        { NULL, NULL, NULL, NULL, NULL }, /* _Va */
        !           101:        { NULL, NULL, NULL, NULL, NULL }, /* _Vt */
        !           102:        { NULL, pre_xr, NULL, NULL, NULL }, /* _Xr */
        !           103:        { NULL, NULL, post_percent, NULL, NULL }, /* _%A */
        !           104:        { NULL, NULL, NULL, NULL, NULL }, /* _%B */
        !           105:        { NULL, NULL, post_percent, NULL, NULL }, /* _%D */
        !           106:        { NULL, NULL, NULL, NULL, NULL }, /* _%I */
        !           107:        { NULL, pre_enc, post_percent, "\\fI", "\\fP" }, /* %J */
        !           108:        { NULL, NULL, NULL, NULL, NULL }, /* _%N */
        !           109:        { NULL, NULL, NULL, NULL, NULL }, /* _%O */
        !           110:        { NULL, NULL, NULL, NULL, NULL }, /* _%P */
        !           111:        { NULL, NULL, NULL, NULL, NULL }, /* _%R */
        !           112:        { NULL, pre_enc, post_percent, "\"", "\"" }, /* %T */
        !           113:        { NULL, NULL, NULL, NULL, NULL }, /* _%V */
        !           114:        { NULL, NULL, NULL, NULL, NULL }, /* _Ac */
        !           115:        { NULL, NULL, NULL, NULL, NULL }, /* _Ao */
        !           116:        { cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
        !           117:        { NULL, NULL, NULL, NULL, NULL }, /* _At */
        !           118:        { NULL, NULL, NULL, NULL, NULL }, /* _Bc */
        !           119:        { NULL, NULL, NULL, NULL, NULL }, /* _Bf */
        !           120:        { NULL, NULL, NULL, NULL, NULL }, /* _Bo */
        !           121:        { NULL, NULL, NULL, NULL, NULL }, /* _Bq */
        !           122:        { NULL, NULL, NULL, NULL, NULL }, /* _Bsx */
        !           123:        { NULL, NULL, NULL, NULL, NULL }, /* _Bx */
        !           124:        { NULL, NULL, NULL, NULL, NULL }, /* _Db */
        !           125:        { NULL, NULL, NULL, NULL, NULL }, /* _Dc */
        !           126:        { NULL, NULL, NULL, NULL, NULL }, /* _Do */
        !           127:        { cond_body, pre_enc, post_enc, "``", "''" }, /* Dq */
        !           128:        { NULL, NULL, NULL, NULL, NULL }, /* _Ec */
        !           129:        { NULL, NULL, NULL, NULL, NULL }, /* _Ef */
        !           130:        { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* _Em */
        !           131:        { NULL, NULL, NULL, NULL, NULL }, /* _Eo */
        !           132:        { NULL, NULL, NULL, NULL, NULL }, /* _Fx */
        !           133:        { NULL, NULL, NULL, NULL, NULL }, /* _Ms */
        !           134:        { NULL, NULL, NULL, NULL, NULL }, /* _No */
        !           135:        { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
        !           136:        { NULL, NULL, NULL, NULL, NULL }, /* _Nx */
        !           137:        { NULL, NULL, NULL, NULL, NULL }, /* _Ox */
        !           138:        { NULL, NULL, NULL, NULL, NULL }, /* _Pc */
        !           139:        { NULL, NULL, NULL, NULL, NULL }, /* _Pf */
        !           140:        { NULL, NULL, NULL, NULL, NULL }, /* _Po */
        !           141:        { cond_body, pre_enc, post_enc, "(", ")" }, /* _Pq */
        !           142:        { NULL, NULL, NULL, NULL, NULL }, /* _Qc */
        !           143:        { cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
        !           144:        { NULL, NULL, NULL, NULL, NULL }, /* _Qo */
        !           145:        { NULL, NULL, NULL, NULL, NULL }, /* _Qq */
        !           146:        { NULL, NULL, NULL, NULL, NULL }, /* _Re */
        !           147:        { cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
        !           148:        { NULL, NULL, NULL, NULL, NULL }, /* _Sc */
        !           149:        { NULL, NULL, NULL, NULL, NULL }, /* _So */
        !           150:        { cond_body, pre_enc, post_enc, "`", "'" }, /* Sq */
        !           151:        { NULL, NULL, NULL, NULL, NULL }, /* _Sm */
        !           152:        { NULL, NULL, NULL, NULL, NULL }, /* _Sx */
        !           153:        { NULL, NULL, NULL, NULL, NULL }, /* _Sy */
        !           154:        { NULL, NULL, NULL, NULL, NULL }, /* _Tn */
        !           155:        { NULL, NULL, NULL, NULL, NULL }, /* _Ux */
        !           156:        { NULL, NULL, NULL, NULL, NULL }, /* _Xc */
        !           157:        { NULL, NULL, NULL, NULL, NULL }, /* _Xo */
        !           158:        { NULL, NULL, NULL, NULL, NULL }, /* _Fo */
        !           159:        { NULL, NULL, NULL, NULL, NULL }, /* _Fc */
        !           160:        { NULL, NULL, NULL, NULL, NULL }, /* _Oo */
        !           161:        { NULL, NULL, NULL, NULL, NULL }, /* _Oc */
        !           162:        { NULL, NULL, NULL, NULL, NULL }, /* _Bk */
        !           163:        { NULL, NULL, NULL, NULL, NULL }, /* _Ek */
        !           164:        { NULL, NULL, NULL, NULL, NULL }, /* _Bt */
        !           165:        { NULL, NULL, NULL, NULL, NULL }, /* _Hf */
        !           166:        { NULL, NULL, NULL, NULL, NULL }, /* _Fr */
        !           167:        { NULL, NULL, NULL, NULL, NULL }, /* _Ud */
        !           168:        { NULL, NULL, NULL, NULL, NULL }, /* _Lb */
        !           169:        { NULL, NULL, NULL, NULL, NULL }, /* _Lp */
        !           170:        { NULL, NULL, NULL, NULL, NULL }, /* _Lk */
        !           171:        { NULL, NULL, NULL, NULL, NULL }, /* _Mt */
        !           172:        { NULL, NULL, NULL, NULL, NULL }, /* _Brq */
        !           173:        { NULL, NULL, NULL, NULL, NULL }, /* _Bro */
        !           174:        { NULL, NULL, NULL, NULL, NULL }, /* _Brc */
        !           175:        { NULL, NULL, NULL, NULL, NULL }, /* _%C */
        !           176:        { NULL, NULL, NULL, NULL, NULL }, /* _Es */
        !           177:        { NULL, NULL, NULL, NULL, NULL }, /* _En */
        !           178:        { NULL, NULL, NULL, NULL, NULL }, /* _Dx */
        !           179:        { NULL, NULL, NULL, NULL, NULL }, /* _%Q */
        !           180:        { NULL, NULL, NULL, NULL, NULL }, /* _br */
        !           181:        { NULL, NULL, NULL, NULL, NULL }, /* _sp */
        !           182:        { NULL, NULL, NULL, NULL, NULL }, /* _%U */
        !           183:        { NULL, NULL, NULL, NULL, NULL }, /* _Ta */
        !           184: };
        !           185:
        !           186:
        !           187: static void
        !           188: print_word(const char *s)
        !           189: {
        !           190:        if (need_nl) {
        !           191:                putchar('\n');
        !           192:                need_space = 0;
        !           193:                need_nl = 0;
        !           194:        } else if (need_space &&
        !           195:            (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]))
        !           196:                putchar(' ');
        !           197:        need_space = ('(' != s[0] && '[' != s[0]) || '\0' != s[1];
        !           198:        for ( ; *s; s++) {
        !           199:                switch (*s) {
        !           200:                case (ASCII_NBRSP):
        !           201:                        printf("\\~");
        !           202:                        break;
        !           203:                case (ASCII_HYPH):
        !           204:                        putchar('-');
        !           205:                        break;
        !           206:                default:
        !           207:                        putchar(*s);
        !           208:                        break;
        !           209:                }
        !           210:        }
        !           211: }
        !           212:
        !           213: void
        !           214: man_mdoc(void *arg, const struct mdoc *mdoc)
        !           215: {
        !           216:        const struct mdoc_meta *m;
        !           217:        const struct mdoc_node *n;
        !           218:
        !           219:        m = mdoc_meta(mdoc);
        !           220:        n = mdoc_node(mdoc);
        !           221:
        !           222:        printf(".TH \"%s\" \"%s\" \"%s\"", m->title, m->msec, m->date);
        !           223:        need_nl = 1;
        !           224:        need_space = 0;
        !           225:
        !           226:        print_node(m, n);
        !           227: }
        !           228:
        !           229: static void
        !           230: print_node(DECL_ARGS)
        !           231: {
        !           232:        const struct mdoc_node  *prev, *sub;
        !           233:        const struct manact     *act = NULL;
        !           234:        int                      cond, do_sub;
        !           235:
        !           236:        prev = n->prev ? n->prev : n->parent;
        !           237:        if (prev && prev->line < n->line)
        !           238:                need_nl = 1;
        !           239:
        !           240:        cond = 0;
        !           241:        do_sub = 1;
        !           242:        if (MDOC_TEXT == n->type) {
        !           243:                print_word(n->string);
        !           244:        } else {
        !           245:                act = manacts + n->tok;
        !           246:                cond = NULL == act->cond || (*act->cond)(m, n);
        !           247:                if (cond && act->pre)
        !           248:                        do_sub = (*act->pre)(m, n);
        !           249:        }
        !           250:
        !           251:        if (do_sub)
        !           252:                for (sub = n->child; sub; sub = sub->next)
        !           253:                        print_node(m, sub);
        !           254:
        !           255:        if (cond && act->post)
        !           256:                (*act->post)(m, n);
        !           257: }
        !           258:
        !           259: static int
        !           260: cond_head(DECL_ARGS)
        !           261: {
        !           262:        return(MDOC_HEAD == n->type);
        !           263: }
        !           264:
        !           265: static int
        !           266: cond_body(DECL_ARGS)
        !           267: {
        !           268:        return(MDOC_BODY == n->type);
        !           269: }
        !           270:
        !           271: static int
        !           272: pre_enc(DECL_ARGS)
        !           273: {
        !           274:        const char *prefix;
        !           275:
        !           276:        prefix = manacts[n->tok].prefix;
        !           277:        if (NULL == prefix)
        !           278:                return(1);
        !           279:        print_word(prefix);
        !           280:        need_space = 0;
        !           281:        return(1);
        !           282: }
        !           283:
        !           284: static void
        !           285: post_enc(DECL_ARGS)
        !           286: {
        !           287:        const char *suffix;
        !           288:
        !           289:        suffix = manacts[n->tok].suffix;
        !           290:        if (NULL == suffix)
        !           291:                return;
        !           292:        need_space = 0;
        !           293:        print_word(suffix);
        !           294: }
        !           295:
        !           296: static void
        !           297: post_percent(DECL_ARGS)
        !           298: {
        !           299:
        !           300:        post_enc(m, n);
        !           301:        if (n->next)
        !           302:                print_word(",");
        !           303:        else {
        !           304:                print_word(".");
        !           305:                need_nl = 1;
        !           306:        }
        !           307: }
        !           308:
        !           309: static int
        !           310: pre_dl(DECL_ARGS)
        !           311: {
        !           312:
        !           313:        need_nl = 1;
        !           314:        print_word(".RS 6n");
        !           315:        need_nl = 1;
        !           316:        return(1);
        !           317: }
        !           318:
        !           319: static void
        !           320: post_dl(DECL_ARGS)
        !           321: {
        !           322:
        !           323:        need_nl = 1;
        !           324:        print_word(".RE");
        !           325:        need_nl = 1;
        !           326: }
        !           327:
        !           328: static int
        !           329: pre_it(DECL_ARGS)
        !           330: {
        !           331:        const struct mdoc_node *bln;
        !           332:
        !           333:        if (MDOC_HEAD == n->type) {
        !           334:                need_nl = 1;
        !           335:                print_word(".TP");
        !           336:                bln = n->parent->parent->prev;
        !           337:                print_word(bln->norm->Bl.width);
        !           338:                need_nl = 1;
        !           339:        }
        !           340:        return(1);
        !           341: }
        !           342:
        !           343: static int
        !           344: pre_nm(DECL_ARGS)
        !           345: {
        !           346:
        !           347:        if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
        !           348:                return(1);
        !           349:        print_word("\\fB");
        !           350:        need_space = 0;
        !           351:        if (NULL == n->child)
        !           352:                print_word(m->name);
        !           353:        return(1);
        !           354: }
        !           355:
        !           356: static void
        !           357: post_nm(DECL_ARGS)
        !           358: {
        !           359:
        !           360:        if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
        !           361:                return;
        !           362:        need_space = 0;
        !           363:        print_word("\\fP");
        !           364: }
        !           365:
        !           366: static int
        !           367: pre_ns(DECL_ARGS)
        !           368: {
        !           369:
        !           370:        need_space = 0;
        !           371:        return(0);
        !           372: }
        !           373:
        !           374: static int
        !           375: pre_pp(DECL_ARGS)
        !           376: {
        !           377:
        !           378:        need_nl = 1;
        !           379:        if (MDOC_It == n->parent->tok)
        !           380:                print_word(".sp");
        !           381:        else
        !           382:                print_word(".PP");
        !           383:        need_nl = 1;
        !           384:        return(1);
        !           385: }
        !           386:
        !           387: static int
        !           388: pre_sh(DECL_ARGS)
        !           389: {
        !           390:
        !           391:        if (MDOC_HEAD != n->type)
        !           392:                return(1);
        !           393:        need_nl = 1;
        !           394:        print_word(".SH \"");
        !           395:        need_space = 0;
        !           396:        return(1);
        !           397: }
        !           398:
        !           399: static void
        !           400: post_sh(DECL_ARGS)
        !           401: {
        !           402:
        !           403:        if (MDOC_HEAD != n->type)
        !           404:                return;
        !           405:        need_space = 0;
        !           406:        print_word("\"");
        !           407:        need_nl = 1;
        !           408: }
        !           409:
        !           410: static int
        !           411: pre_xr(DECL_ARGS)
        !           412: {
        !           413:
        !           414:        n = n->child;
        !           415:        if (NULL == n)
        !           416:                return(0);
        !           417:        print_node(m, n);
        !           418:        n = n->next;
        !           419:        if (NULL == n)
        !           420:                return(0);
        !           421:        need_space = 0;
        !           422:        print_word("(");
        !           423:        print_node(m, n);
        !           424:        print_word(")");
        !           425:        return(0);
        !           426: }

CVSweb