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

Annotation of mandoc/html.c, Revision 1.7

1.7     ! kristaps    1: /* $Id: html.c,v 1.6 2008/12/04 23:10:51 kristaps Exp $ */
1.1       kristaps    2: /*
                      3:  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the
                      7:  * above copyright notice and this permission notice appear in all
                      8:  * copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
                     11:  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
                     12:  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
                     13:  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
                     14:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
                     15:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
                     16:  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
                     17:  * PERFORMANCE OF THIS SOFTWARE.
                     18:  */
1.4       kristaps   19: #include <sys/param.h>
                     20: #include <sys/stat.h>
                     21:
1.1       kristaps   22: #include <assert.h>
1.4       kristaps   23: #include <err.h>
                     24: #include <fcntl.h>
1.1       kristaps   25: #include <stdlib.h>
1.4       kristaps   26: #include <stdio.h>
1.2       kristaps   27: #include <string.h>
1.4       kristaps   28: #include <unistd.h>
1.1       kristaps   29:
                     30: #include "libmdocml.h"
                     31: #include "private.h"
1.2       kristaps   32: #include "ml.h"
                     33:
                     34:
1.7     ! kristaps   35: struct htmlnode {
        !            36:        int              type;
        !            37:        int             *argc[ROFF_MAXLINEARG];
        !            38:        char            *argv[ROFF_MAXLINEARG];
        !            39:        struct htmlnode *parent;
        !            40: };
        !            41:
        !            42:
        !            43: struct htmlq {
        !            44:        struct htmlnode *last;
        !            45: };
        !            46:
        !            47:
1.4       kristaps   48: static int             html_loadcss(struct md_mbuf *, const char *);
                     49:
1.2       kristaps   50: static ssize_t         html_endtag(struct md_mbuf *,
                     51:                                const struct md_args *,
                     52:                                enum md_ns, int);
                     53: static ssize_t         html_begintag(struct md_mbuf *,
                     54:                                const struct md_args *,
                     55:                                enum md_ns, int,
                     56:                                const int *, const char **);
1.4       kristaps   57: static int             html_begin(struct md_mbuf *,
                     58:                                const struct md_args *,
                     59:                                const struct tm *,
                     60:                                const char *, const char *,
                     61:                                const char *, const char *);
1.7     ! kristaps   62: static int             html_printargs(struct md_mbuf *, int,
        !            63:                                const char *, const int *,
        !            64:                                const char **, size_t *);
1.2       kristaps   65: static int             html_end(struct md_mbuf *,
                     66:                                const struct md_args *);
1.7     ! kristaps   67: static int             html_blocktagname(struct md_mbuf *,
        !            68:                                const struct md_args *, int, size_t *);
        !            69: static int             html_blocktagargs(struct md_mbuf *,
1.2       kristaps   70:                                const struct md_args *, int,
1.7     ! kristaps   71:                                const int *, const char **, size_t *);
        !            72: static int             html_blockheadtagname(struct md_mbuf *,
        !            73:                                const struct md_args *, int, size_t *);
        !            74: static int             html_blockheadtagargs(struct md_mbuf *,
1.3       kristaps   75:                                const struct md_args *, int,
1.7     ! kristaps   76:                                const int *, const char **, size_t *);
        !            77: static int             html_blockbodytagname(struct md_mbuf *,
        !            78:                                const struct md_args *, int, size_t *);
        !            79: static int             html_blockbodytagargs(struct md_mbuf *,
1.3       kristaps   80:                                const struct md_args *, int,
1.7     ! kristaps   81:                                const int *, const char **, size_t *);
        !            82: static int             html_inlinetagname(struct md_mbuf *,
        !            83:                                const struct md_args *, int, size_t *);
        !            84: static int             html_inlinetagargs(struct md_mbuf *,
1.2       kristaps   85:                                const struct md_args *, int,
1.7     ! kristaps   86:                                const int *, const char **, size_t *);
1.2       kristaps   87:
                     88:
1.4       kristaps   89: static int
                     90: html_loadcss(struct md_mbuf *mbuf, const char *css)
                     91: {
                     92:        size_t           res, bufsz;
                     93:        char            *buf;
                     94:        struct stat      st;
                     95:        int              fd, c;
                     96:        ssize_t          ssz;
                     97:
                     98:        c = 0;
                     99:        res = 0;
                    100:        buf = NULL;
                    101:
                    102:        if (-1 == (fd = open(css, O_RDONLY, 0))) {
                    103:                warn("%s", css);
                    104:                return(0);
                    105:        }
                    106:
                    107:        if (-1 == fstat(fd, &st)) {
                    108:                warn("%s", css);
                    109:                goto out;
                    110:        }
                    111:
                    112:        bufsz = MAX(st.st_blksize, BUFSIZ);
                    113:        if (NULL == (buf = malloc(bufsz))) {
                    114:                warn("malloc");
                    115:                goto out;
                    116:        }
                    117:
                    118:        for (;;) {
                    119:                if (-1 == (ssz = read(fd, buf, bufsz))) {
                    120:                        warn("%s", css);
                    121:                        goto out;
                    122:                } else if (0 == ssz)
                    123:                        break;
                    124:                if ( ! ml_nputs(mbuf, buf, (size_t)ssz, &res))
                    125:                        goto out;
                    126:        }
                    127:
                    128:        c = 1;
                    129:
                    130: out:
                    131:        if (-1 == close(fd)) {
                    132:                warn("%s", css);
                    133:                c = 0;
                    134:        }
                    135:
                    136:        if (buf)
                    137:                free(buf);
                    138:
                    139:        return(c);
                    140: }
                    141:
                    142:
1.3       kristaps  143: /* ARGSUSED */
1.2       kristaps  144: static int
1.4       kristaps  145: html_begin(struct md_mbuf *mbuf, const struct md_args *args,
                    146:                const struct tm *tm, const char *os,
                    147:                const char *title, const char *section,
                    148:                const char *vol)
1.2       kristaps  149: {
1.4       kristaps  150:        const char      *preamble, *css, *trail;
                    151:        char             buf[512];
1.2       kristaps  152:        size_t           res;
                    153:
1.4       kristaps  154:        preamble =
                    155:        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n"
                    156:        "    \"http://www.w3.org/TR/html4/strict.dtd\">\n"
                    157:        "<html>\n"
                    158:        "<head>\n"
                    159:        "    <meta http-equiv=\"Content-Type\"\n"
                    160:        "         content=\"text/html;charset=utf-8\">\n"
                    161:        "    <meta name=\"resource-type\" content=\"document\">\n"
                    162:        "    <title>Manual Page for %s(%s)</title>\n";
                    163:
                    164:        css =
                    165:        "    <link rel=\"stylesheet\" type=\"text/css\"\n"
                    166:        "         href=\"%s\">\n";
                    167:        trail =
                    168:        "</head>\n"
                    169:        "<body>\n"
                    170:        "<div class=\"mdoc\">\n";
                    171:
1.2       kristaps  172:        res = 0;
1.4       kristaps  173:
                    174:        (void)snprintf(buf, sizeof(buf) - 1,
                    175:                        preamble, title, section);
                    176:
                    177:        if ( ! ml_puts(mbuf, buf, &res))
1.2       kristaps  178:                return(0);
1.4       kristaps  179:
                    180:        assert(args->params.html.css);
                    181:        if (HTML_CSS_EMBED & args->params.html.flags) {
1.5       kristaps  182:                if ( ! ml_puts(mbuf, "    <style type=\"text/css\"><!--\n", &res))
1.4       kristaps  183:                        return(0);
                    184:                if ( ! html_loadcss(mbuf, args->params.html.css))
                    185:                        return(0);
                    186:                if ( ! ml_puts(mbuf, "    --!></style>\n", &res))
                    187:                        return(0);
                    188:        } else {
                    189:                (void)snprintf(buf, sizeof(buf) - 1, css,
                    190:                                args->params.html.css);
                    191:                if ( ! ml_puts(mbuf, buf, &res))
                    192:                        return(0);
                    193:        }
                    194:
                    195:        if ( ! ml_puts(mbuf, trail, &res))
1.2       kristaps  196:                return(0);
                    197:
                    198:        return(1);
                    199: }
                    200:
                    201:
1.3       kristaps  202: /* ARGSUSED */
1.2       kristaps  203: static int
                    204: html_end(struct md_mbuf *mbuf, const struct md_args *args)
                    205: {
                    206:        size_t           res;
                    207:
                    208:        res = 0;
1.4       kristaps  209:        if ( ! ml_puts(mbuf, "</div></body>\n</html>", &res))
1.2       kristaps  210:                return(0);
                    211:
                    212:        return(1);
                    213: }
                    214:
                    215:
1.3       kristaps  216: /* ARGSUSED */
1.7     ! kristaps  217: static int
1.3       kristaps  218: html_blockbodytagname(struct md_mbuf *mbuf,
1.7     ! kristaps  219:                const struct md_args *args, int tok, size_t *res)
1.2       kristaps  220: {
1.3       kristaps  221:
1.7     ! kristaps  222:        return(ml_puts(mbuf, "div", res));
1.3       kristaps  223: }
                    224:
                    225:
                    226:
                    227:
                    228: /* ARGSUSED */
1.7     ! kristaps  229: static int
1.3       kristaps  230: html_blockheadtagname(struct md_mbuf *mbuf,
1.7     ! kristaps  231:                const struct md_args *args, int tok, size_t *res)
1.3       kristaps  232: {
                    233:
1.7     ! kristaps  234:        return(ml_puts(mbuf, "div", res));
1.3       kristaps  235: }
                    236:
                    237:
                    238: /* ARGSUSED */
1.7     ! kristaps  239: static int
1.3       kristaps  240: html_blocktagname(struct md_mbuf *mbuf,
1.7     ! kristaps  241:                const struct md_args *args, int tok, size_t *res)
1.3       kristaps  242: {
                    243:
1.7     ! kristaps  244:        return(ml_puts(mbuf, "div", res));
1.3       kristaps  245: }
                    246:
                    247:
1.7     ! kristaps  248: static int
        !           249: html_printargs(struct md_mbuf *mbuf, int tok, const char *ns,
        !           250:                const int *argc, const char **argv, size_t *res)
1.3       kristaps  251: {
1.7     ! kristaps  252:        int              i, c;
1.3       kristaps  253:
1.7     ! kristaps  254:        if ( ! ml_puts(mbuf, " class=\"", res))
        !           255:                return(0);
        !           256:        if ( ! ml_puts(mbuf, ns, res))
        !           257:                return(0);
        !           258:        if ( ! ml_puts(mbuf, "-", res))
1.3       kristaps  259:                return(0);
1.7     ! kristaps  260:        if ( ! ml_puts(mbuf, toknames[tok], res))
1.3       kristaps  261:                return(0);
1.7     ! kristaps  262:        if ( ! ml_puts(mbuf, "\"", res))
1.3       kristaps  263:                return(0);
                    264:
1.7     ! kristaps  265:        if (NULL == argv || NULL == argc)
        !           266:                return(1);
        !           267:        assert(argv && argc);
        !           268:
        !           269:        /* FIXME: ignores values. */
        !           270:
        !           271:        for (i = 0; ROFF_ARGMAX != (c = argc[i]); i++) {
        !           272:                if (argv[i])
        !           273:                        continue;
        !           274:                if ( ! ml_puts(mbuf, " class=\"", res))
        !           275:                        return(0);
        !           276:                if ( ! ml_puts(mbuf, ns, res))
        !           277:                        return(0);
        !           278:                if ( ! ml_puts(mbuf, "-", res))
        !           279:                        return(0);
        !           280:                if ( ! ml_puts(mbuf, toknames[tok], res))
        !           281:                        return(0);
        !           282:                if ( ! ml_puts(mbuf, "-", res))
        !           283:                        return(0);
        !           284:                if ( ! ml_puts(mbuf, tokargnames[c], res))
        !           285:                        return(0);
        !           286:                if ( ! ml_puts(mbuf, "\"", res))
        !           287:                        return(0);
1.3       kristaps  288:        }
                    289:
1.7     ! kristaps  290:        return(1);
1.3       kristaps  291: }
                    292:
                    293:
                    294: /* ARGSUSED */
1.7     ! kristaps  295: static int
        !           296: html_blockheadtagargs(struct md_mbuf *mbuf,
        !           297:                const struct md_args *args, int tok,
        !           298:                const int *argc, const char **argv, size_t *res)
1.3       kristaps  299: {
                    300:
1.7     ! kristaps  301:        return(html_printargs(mbuf, tok, "head", argc, argv, res));
        !           302: }
1.3       kristaps  303:
                    304:
1.7     ! kristaps  305: /* ARGSUSED */
        !           306: static int
        !           307: html_blockbodytagargs(struct md_mbuf *mbuf,
        !           308:                const struct md_args *args, int tok,
        !           309:                const int *argc, const char **argv, size_t *res)
        !           310: {
1.3       kristaps  311:
1.7     ! kristaps  312:        return(html_printargs(mbuf, tok, "body", argc, argv, res));
1.2       kristaps  313: }
                    314:
                    315:
                    316: /* ARGSUSED */
1.7     ! kristaps  317: static int
        !           318: html_blocktagargs(struct md_mbuf *mbuf,
        !           319:                const struct md_args *args, int tok,
        !           320:                const int *argc, const char **argv, size_t *res)
1.2       kristaps  321: {
1.3       kristaps  322:
1.7     ! kristaps  323:        return(html_printargs(mbuf, tok, "block", argc, argv, res));
1.2       kristaps  324: }
1.1       kristaps  325:
                    326:
                    327: /* ARGSUSED */
1.7     ! kristaps  328: static int
        !           329: html_inlinetagargs(struct md_mbuf *mbuf,
        !           330:                const struct md_args *args, int tok,
        !           331:                const int *argc, const char **argv, size_t *res)
1.2       kristaps  332: {
                    333:
1.7     ! kristaps  334:        return(html_printargs(mbuf, tok, "inline", argc, argv, res));
1.2       kristaps  335: }
                    336:
                    337:
1.3       kristaps  338: /* ARGSUSED */
1.7     ! kristaps  339: static int
1.2       kristaps  340: html_inlinetagname(struct md_mbuf *mbuf,
1.7     ! kristaps  341:                const struct md_args *args, int tok, size_t *res)
1.2       kristaps  342: {
                    343:
                    344:        switch (tok) {
1.4       kristaps  345:        case (ROFF_Pp):
1.7     ! kristaps  346:                return(ml_puts(mbuf, "div", res));
1.2       kristaps  347:        default:
1.7     ! kristaps  348:                return(ml_puts(mbuf, "span", res));
1.2       kristaps  349:        }
1.7     ! kristaps  350:        return(1);
1.2       kristaps  351: }
                    352:
                    353:
                    354: static ssize_t
                    355: html_begintag(struct md_mbuf *mbuf, const struct md_args *args,
                    356:                enum md_ns ns, int tok,
                    357:                const int *argc, const char **argv)
                    358: {
1.7     ! kristaps  359:        size_t           res;
1.2       kristaps  360:
                    361:        assert(ns != MD_NS_DEFAULT);
1.7     ! kristaps  362:        res = 0;
        !           363:
1.3       kristaps  364:        switch (ns) {
                    365:        case (MD_NS_BLOCK):
1.7     ! kristaps  366:                if ( ! html_blocktagname(mbuf, args, tok, &res))
        !           367:                        return(-1);
        !           368:                if ( ! html_blocktagargs(mbuf, args, tok,
        !           369:                                        argc, argv, &res))
        !           370:                        return(-1);
        !           371:                break;
1.3       kristaps  372:        case (MD_NS_BODY):
1.7     ! kristaps  373:                if ( ! html_blockbodytagname(mbuf, args, tok, &res))
        !           374:                        return(-1);
        !           375:                if ( ! html_blockbodytagargs(mbuf, args, tok,
        !           376:                                        argc, argv, &res))
        !           377:                        return(-1);
        !           378:                break;
1.3       kristaps  379:        case (MD_NS_HEAD):
1.7     ! kristaps  380:                if ( ! html_blockheadtagname(mbuf, args, tok, &res))
        !           381:                        return(-1);
        !           382:                if ( ! html_blockheadtagargs(mbuf, args, tok,
        !           383:                                        argc, argv, &res))
        !           384:                        return(-1);
        !           385:                break;
1.3       kristaps  386:        default:
1.7     ! kristaps  387:                if ( ! html_inlinetagname(mbuf, args, tok, &res))
        !           388:                        return(-1);
        !           389:                if ( ! html_inlinetagargs(mbuf, args, tok,
        !           390:                                        argc, argv, &res))
        !           391:                        return(-1);
1.3       kristaps  392:                break;
1.2       kristaps  393:        }
                    394:
1.7     ! kristaps  395:        return((ssize_t)res);
1.2       kristaps  396: }
                    397:
                    398:
                    399: static ssize_t
                    400: html_endtag(struct md_mbuf *mbuf, const struct md_args *args,
                    401:                enum md_ns ns, int tok)
                    402: {
1.7     ! kristaps  403:        size_t           res;
1.2       kristaps  404:
                    405:        assert(ns != MD_NS_DEFAULT);
1.7     ! kristaps  406:        res = 0;
        !           407:
1.3       kristaps  408:        switch (ns) {
                    409:        case (MD_NS_BLOCK):
1.7     ! kristaps  410:                if ( ! html_blocktagname(mbuf, args, tok, &res))
        !           411:                        return(-1);
        !           412:                break;
1.3       kristaps  413:        case (MD_NS_BODY):
1.7     ! kristaps  414:                if ( ! html_blockbodytagname(mbuf, args, tok, &res))
        !           415:                        return(-1);
        !           416:                break;
1.3       kristaps  417:        case (MD_NS_HEAD):
1.7     ! kristaps  418:                if ( ! html_blockheadtagname(mbuf, args, tok, &res))
        !           419:                        return(-1);
        !           420:                break;
1.3       kristaps  421:        default:
1.7     ! kristaps  422:                if ( ! html_inlinetagname(mbuf, args, tok, &res))
        !           423:                        return(-1);
1.3       kristaps  424:                break;
                    425:        }
1.2       kristaps  426:
1.7     ! kristaps  427:        return((ssize_t)res);
1.2       kristaps  428: }
                    429:
                    430:
1.1       kristaps  431: int
                    432: md_line_html(void *data, char *buf)
                    433: {
                    434:
1.2       kristaps  435:        return(mlg_line((struct md_mlg *)data, buf));
1.1       kristaps  436: }
                    437:
                    438:
                    439: int
                    440: md_exit_html(void *data, int flush)
                    441: {
                    442:
1.2       kristaps  443:        return(mlg_exit((struct md_mlg *)data, flush));
1.1       kristaps  444: }
                    445:
                    446:
                    447: void *
                    448: md_init_html(const struct md_args *args,
                    449:                struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
                    450: {
                    451:
1.2       kristaps  452:        return(mlg_alloc(args, rbuf, mbuf, html_begintag,
                    453:                                html_endtag, html_begin, html_end));
1.1       kristaps  454: }
1.2       kristaps  455:

CVSweb