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

Annotation of mandoc/man_html.c, Revision 1.4

1.4     ! kristaps    1: /*     $Id: man_html.c,v 1.3 2009/10/03 19:57:53 kristaps Exp $ */
1.1       kristaps    2: /*
                      3:  * Copyright (c) 2008, 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 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 <sys/types.h>
                     18: #include <sys/queue.h>
                     19:
1.4     ! kristaps   20: #include <err.h>
1.2       kristaps   21: #include <stdio.h>
1.1       kristaps   22: #include <stdlib.h>
1.4     ! kristaps   23: #include <string.h>
1.1       kristaps   24:
                     25: #include "html.h"
                     26: #include "man.h"
                     27:
1.4     ! kristaps   28: #define        INDENT            7
        !            29: #define        HALFINDENT        3
        !            30:
1.3       kristaps   31: #define        MAN_ARGS          const struct man_meta *m, \
                     32:                          const struct man_node *n, \
                     33:                          struct html *h
                     34:
                     35: struct htmlman {
                     36:        int             (*pre)(MAN_ARGS);
                     37:        int             (*post)(MAN_ARGS);
                     38: };
                     39:
                     40: static void              print_man(MAN_ARGS);
                     41: static void              print_man_head(MAN_ARGS);
1.4     ! kristaps   42: static void              print_man_nodelist(MAN_ARGS);
        !            43: static void              print_man_node(MAN_ARGS);
1.3       kristaps   44:
1.4     ! kristaps   45: static int               man_br_pre(MAN_ARGS);
        !            46: static int               man_PP_pre(MAN_ARGS);
        !            47: static void              man_root_post(MAN_ARGS);
        !            48: static int               man_root_pre(MAN_ARGS);
        !            49: static int               man_SH_pre(MAN_ARGS);
        !            50: static int               man_SS_pre(MAN_ARGS);
        !            51:
        !            52: #ifdef __linux__
        !            53: extern size_t            strlcpy(char *, const char *, size_t);
        !            54: extern size_t            strlcat(char *, const char *, size_t);
        !            55: #endif
1.3       kristaps   56:
                     57: static const struct htmlman mans[MAN_MAX] = {
1.4     ! kristaps   58:        { man_br_pre, NULL }, /* br */
1.3       kristaps   59:        { NULL, NULL }, /* TH */
1.4     ! kristaps   60:        { man_SH_pre, NULL }, /* SH */
        !            61:        { man_SS_pre, NULL }, /* SS */
1.3       kristaps   62:        { NULL, NULL }, /* TP */
1.4     ! kristaps   63:        { man_PP_pre, NULL }, /* LP */
        !            64:        { man_PP_pre, NULL }, /* PP */
        !            65:        { man_PP_pre, NULL }, /* P */
1.3       kristaps   66:        { NULL, NULL }, /* IP */
                     67:        { NULL, NULL }, /* HP */
                     68:        { NULL, NULL }, /* SM */
                     69:        { NULL, NULL }, /* SB */
                     70:        { NULL, NULL }, /* BI */
                     71:        { NULL, NULL }, /* IB */
                     72:        { NULL, NULL }, /* BR */
                     73:        { NULL, NULL }, /* RB */
                     74:        { NULL, NULL }, /* R */
                     75:        { NULL, NULL }, /* B */
                     76:        { NULL, NULL }, /* I */
                     77:        { NULL, NULL }, /* IR */
                     78:        { NULL, NULL }, /* RI */
                     79:        { NULL, NULL }, /* na */
                     80:        { NULL, NULL }, /* i */
1.4     ! kristaps   81:        { man_br_pre, NULL }, /* sp */
1.3       kristaps   82:        { NULL, NULL }, /* nf */
                     83:        { NULL, NULL }, /* fi */
                     84:        { NULL, NULL }, /* r */
                     85:        { NULL, NULL }, /* RE */
                     86:        { NULL, NULL }, /* RS */
                     87:        { NULL, NULL }, /* DT */
                     88:        { NULL, NULL }, /* UC */
                     89: };
                     90:
1.1       kristaps   91:
                     92: void
                     93: html_man(void *arg, const struct man *m)
                     94: {
1.3       kristaps   95:        struct html     *h;
                     96:        struct tag      *t;
                     97:
                     98:        h = (struct html *)arg;
                     99:
                    100:        print_gen_doctype(h);
                    101:
                    102:        t = print_otag(h, TAG_HTML, 0, NULL);
                    103:        print_man(man_meta(m), man_node(m), h);
                    104:        print_tagq(h, t);
                    105:
                    106:        printf("\n");
                    107: }
                    108:
                    109:
                    110: static void
                    111: print_man(MAN_ARGS)
                    112: {
                    113:        struct tag      *t;
                    114:        struct htmlpair  tag;
                    115:
                    116:        t = print_otag(h, TAG_HEAD, 0, NULL);
                    117:
                    118:        print_man_head(m, n, h);
                    119:        print_tagq(h, t);
                    120:        t = print_otag(h, TAG_BODY, 0, NULL);
                    121:
                    122:        tag.key = ATTR_CLASS;
                    123:        tag.val = "body";
                    124:        print_otag(h, TAG_DIV, 1, &tag);
                    125:
1.4     ! kristaps  126:        print_man_nodelist(m, n, h);
1.3       kristaps  127:
                    128:        print_tagq(h, t);
                    129: }
                    130:
                    131:
                    132: /* ARGSUSED */
                    133: static void
                    134: print_man_head(MAN_ARGS)
                    135: {
                    136:
                    137:        print_gen_head(h);
                    138:        bufinit(h);
                    139:        buffmt(h, "%s(%d)", m->title, m->msec);
                    140:
                    141:        print_otag(h, TAG_TITLE, 0, NULL);
                    142:        print_text(h, h->buf);
1.1       kristaps  143: }
1.4     ! kristaps  144:
        !           145:
        !           146: static void
        !           147: print_man_nodelist(MAN_ARGS)
        !           148: {
        !           149:
        !           150:        print_man_node(m, n, h);
        !           151:        if (n->next)
        !           152:                print_man_nodelist(m, n->next, h);
        !           153: }
        !           154:
        !           155:
        !           156: static void
        !           157: print_man_node(MAN_ARGS)
        !           158: {
        !           159:        int              child;
        !           160:        struct tag      *t;
        !           161:
        !           162:        child = 1;
        !           163:        t = SLIST_FIRST(&h->tags);
        !           164:
        !           165:        bufinit(h);
        !           166:
        !           167:        switch (n->type) {
        !           168:        case (MAN_ROOT):
        !           169:                child = man_root_pre(m, n, h);
        !           170:                break;
        !           171:        case (MAN_TEXT):
        !           172:                print_text(h, n->string);
        !           173:                break;
        !           174:        default:
        !           175:                if (mans[n->tok].pre)
        !           176:                        child = (*mans[n->tok].pre)(m, n, h);
        !           177:                break;
        !           178:        }
        !           179:
        !           180:        if (child && n->child)
        !           181:                print_man_nodelist(m, n->child, h);
        !           182:
        !           183:        print_stagq(h, t);
        !           184:
        !           185:        bufinit(h);
        !           186:
        !           187:        switch (n->type) {
        !           188:        case (MAN_ROOT):
        !           189:                man_root_post(m, n, h);
        !           190:                break;
        !           191:        case (MAN_TEXT):
        !           192:                break;
        !           193:        default:
        !           194:                if (mans[n->tok].post)
        !           195:                        (*mans[n->tok].post)(m, n, h);
        !           196:                break;
        !           197:        }
        !           198: }
        !           199:
        !           200:
        !           201: /* ARGSUSED */
        !           202: static int
        !           203: man_root_pre(MAN_ARGS)
        !           204: {
        !           205:        struct htmlpair  tag[2];
        !           206:        struct tag      *t, *tt;
        !           207:        char             b[BUFSIZ], title[BUFSIZ];
        !           208:
        !           209:        b[0] = 0;
        !           210:        if (m->vol)
        !           211:                (void)strlcat(b, m->vol, BUFSIZ);
        !           212:
        !           213:        (void)snprintf(title, BUFSIZ - 1,
        !           214:                        "%s(%d)", m->title, m->msec);
        !           215:
        !           216:        tag[0].key = ATTR_CLASS;
        !           217:        tag[0].val = "header";
        !           218:        tag[1].key = ATTR_STYLE;
        !           219:        tag[1].val = "width: 100%;";
        !           220:        t = print_otag(h, TAG_TABLE, 2, tag);
        !           221:        tt = print_otag(h, TAG_TR, 0, NULL);
        !           222:
        !           223:        tag[0].key = ATTR_STYLE;
        !           224:        tag[0].val = "width: 10%;";
        !           225:        print_otag(h, TAG_TD, 1, tag);
        !           226:        print_text(h, title);
        !           227:        print_stagq(h, tt);
        !           228:
        !           229:        tag[0].key = ATTR_STYLE;
        !           230:        tag[0].val = "width: 80%; white-space: nowrap; text-align: center;";
        !           231:        print_otag(h, TAG_TD, 1, tag);
        !           232:        print_text(h, b);
        !           233:        print_stagq(h, tt);
        !           234:
        !           235:        tag[0].key = ATTR_STYLE;
        !           236:        tag[0].val = "width: 10%; text-align: right;";
        !           237:        print_otag(h, TAG_TD, 1, tag);
        !           238:        print_text(h, title);
        !           239:        print_tagq(h, t);
        !           240:
        !           241:        return(1);
        !           242: }
        !           243:
        !           244:
        !           245: /* ARGSUSED */
        !           246: static void
        !           247: man_root_post(MAN_ARGS)
        !           248: {
        !           249:        struct tm        tm;
        !           250:        struct htmlpair  tag[2];
        !           251:        struct tag      *t, *tt;
        !           252:        char             b[BUFSIZ];
        !           253:
        !           254:        (void)localtime_r(&m->date, &tm);
        !           255:
        !           256:        if (0 == strftime(b, BUFSIZ - 1, "%B %e, %Y", &tm))
        !           257:                err(EXIT_FAILURE, "strftime");
        !           258:
        !           259:        tag[0].key = ATTR_CLASS;
        !           260:        tag[0].val = "footer";
        !           261:        tag[1].key = ATTR_STYLE;
        !           262:        tag[1].val = "width: 100%;";
        !           263:        t = print_otag(h, TAG_TABLE, 2, tag);
        !           264:        tt = print_otag(h, TAG_TR, 0, NULL);
        !           265:
        !           266:        tag[0].key = ATTR_STYLE;
        !           267:        tag[0].val = "width: 50%;";
        !           268:        print_otag(h, TAG_TD, 1, tag);
        !           269:        print_text(h, b);
        !           270:        print_stagq(h, tt);
        !           271:
        !           272:        tag[0].key = ATTR_STYLE;
        !           273:        tag[0].val = "width: 50%; text-align: right;";
        !           274:        print_otag(h, TAG_TD, 1, tag);
        !           275:        if (m->source)
        !           276:                print_text(h, m->source);
        !           277:        print_tagq(h, t);
        !           278: }
        !           279:
        !           280:
        !           281:
        !           282: /* ARGSUSED */
        !           283: static int
        !           284: man_br_pre(MAN_ARGS)
        !           285: {
        !           286:        int             len;
        !           287:        struct htmlpair tag;
        !           288:
        !           289:        switch (n->tok) {
        !           290:        case (MAN_sp):
        !           291:                len = n->child ? atoi(n->child->string) : 1;
        !           292:                break;
        !           293:        case (MAN_br):
        !           294:                len = 0;
        !           295:                break;
        !           296:        default:
        !           297:                len = 1;
        !           298:                break;
        !           299:        }
        !           300:
        !           301:        buffmt(h, "height: %dem;", len);
        !           302:        tag.key = ATTR_STYLE;
        !           303:        tag.val = h->buf;
        !           304:        print_otag(h, TAG_DIV, 1, &tag);
        !           305:        return(1);
        !           306: }
        !           307:
        !           308:
        !           309: /* ARGSUSED */
        !           310: static int
        !           311: man_SH_pre(MAN_ARGS)
        !           312: {
        !           313:        struct htmlpair         tag[2];
        !           314:
        !           315:        if (MAN_BODY == n->type) {
        !           316:                buffmt(h, "margin-left: %dem;", INDENT);
        !           317:
        !           318:                tag[0].key = ATTR_CLASS;
        !           319:                tag[0].val = "sec-body";
        !           320:                tag[1].key = ATTR_STYLE;
        !           321:                tag[1].val = h->buf;
        !           322:
        !           323:                print_otag(h, TAG_DIV, 2, tag);
        !           324:                return(1);
        !           325:        } else if (MAN_BLOCK == n->type) {
        !           326:                tag[0].key = ATTR_CLASS;
        !           327:                tag[0].val = "sec-block";
        !           328:
        !           329:                if (n->prev && MAN_SH == n->prev->tok)
        !           330:                        if (NULL == n->prev->body->child) {
        !           331:                                print_otag(h, TAG_DIV, 1, tag);
        !           332:                                return(1);
        !           333:                        }
        !           334:
        !           335:                bufcat(h, "margin-top: 1em;");
        !           336:                if (NULL == n->next)
        !           337:                        bufcat(h, "margin-bottom: 1em;");
        !           338:
        !           339:                tag[1].key = ATTR_STYLE;
        !           340:                tag[1].val = h->buf;
        !           341:
        !           342:                print_otag(h, TAG_DIV, 2, tag);
        !           343:                return(1);
        !           344:        }
        !           345:
        !           346:        tag[0].key = ATTR_CLASS;
        !           347:        tag[0].val = "sec-head";
        !           348:
        !           349:        print_otag(h, TAG_DIV, 1, tag);
        !           350:        return(1);
        !           351: }
        !           352:
        !           353:
        !           354: /* ARGSUSED */
        !           355: static int
        !           356: man_SS_pre(MAN_ARGS)
        !           357: {
        !           358:        struct htmlpair  tag[3];
        !           359:        int              i;
        !           360:
        !           361:        i = 0;
        !           362:
        !           363:        if (MAN_BODY == n->type) {
        !           364:                tag[i].key = ATTR_CLASS;
        !           365:                tag[i++].val = "ssec-body";
        !           366:
        !           367:                if (n->parent->next && n->child) {
        !           368:                        bufcat(h, "margin-bottom: 1em;");
        !           369:                        tag[i].key = ATTR_STYLE;
        !           370:                        tag[i++].val = h->buf;
        !           371:                }
        !           372:
        !           373:                print_otag(h, TAG_DIV, i, tag);
        !           374:                return(1);
        !           375:        } else if (MAN_BLOCK == n->type) {
        !           376:                tag[i].key = ATTR_CLASS;
        !           377:                tag[i++].val = "ssec-block";
        !           378:
        !           379:                if (n->prev && MAN_SS == n->prev->tok)
        !           380:                        if (n->prev->body->child) {
        !           381:                                bufcat(h, "margin-top: 1em;");
        !           382:                                tag[i].key = ATTR_STYLE;
        !           383:                                tag[i++].val = h->buf;
        !           384:                        }
        !           385:
        !           386:                print_otag(h, TAG_DIV, i, tag);
        !           387:                return(1);
        !           388:        }
        !           389:
        !           390:        buffmt(h, "margin-left: -%dem;", INDENT - HALFINDENT);
        !           391:
        !           392:        tag[0].key = ATTR_CLASS;
        !           393:        tag[0].val = "ssec-head";
        !           394:        tag[1].key = ATTR_STYLE;
        !           395:        tag[1].val = h->buf;
        !           396:
        !           397:        print_otag(h, TAG_DIV, 2, tag);
        !           398:        return(1);
        !           399: }
        !           400:
        !           401:
        !           402: /* ARGSUSED */
        !           403: static int
        !           404: man_PP_pre(MAN_ARGS)
        !           405: {
        !           406:        struct htmlpair tag;
        !           407:
        !           408:        if (MAN_BLOCK != n->type)
        !           409:                return(1);
        !           410:
        !           411:        buffmt(h, "margin-left: %dem;", INDENT);
        !           412:        if (n->next && n->next->child)
        !           413:                bufcat(h, "margin-bottom: 1em;");
        !           414:
        !           415:        tag.key = ATTR_STYLE;
        !           416:        tag.val = h->buf;
        !           417:        print_otag(h, TAG_DIV, 1, &tag);
        !           418:        return(1);
        !           419: }

CVSweb