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

Annotation of mandoc/html.c, Revision 1.29

1.29    ! kristaps    1: /*     $Id: tree.c,v 1.14 2009/08/13 11:45:29 kristaps Exp $ */
1.1       kristaps    2: /*
1.29    ! kristaps    3:  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
1.1       kristaps    4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
1.29    ! kristaps    6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
1.1       kristaps    8:  *
1.29    ! kristaps    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.
1.1       kristaps   16:  */
                     17: #include <assert.h>
1.4       kristaps   18: #include <err.h>
1.29    ! kristaps   19: #include <stdio.h>
1.1       kristaps   20: #include <stdlib.h>
                     21:
1.29    ! kristaps   22: #include "mdoc.h"
        !            23: #include "man.h"
1.2       kristaps   24:
1.29    ! kristaps   25: #define        DOCTYPE         "-//W3C//DTD HTML 4.01//EN"
        !            26: #define        DTD             "http://www.w3.org/TR/html4/strict.dtd"
1.8       kristaps   27:
1.29    ! kristaps   28: enum   htmltag {
        !            29:        TAG_HTML,
        !            30:        TAG_HEAD,
        !            31:        TAG_BODY,
        !            32:        TAG_META,
        !            33:        TAG_TITLE,
        !            34:        TAG_DIV,
        !            35:        TAG_H1,
        !            36:        TAG_H2,
        !            37:        TAG_P,
        !            38:        TAG_SPAN,
        !            39:        TAG_LINK,
        !            40:        TAG_MAX
1.7       kristaps   41: };
                     42:
1.29    ! kristaps   43: enum   htmlattr {
        !            44:        ATTR_HTTPEQUIV,
        !            45:        ATTR_CONTENT,
        !            46:        ATTR_NAME,
        !            47:        ATTR_REL,
        !            48:        ATTR_HREF,
        !            49:        ATTR_TYPE,
        !            50:        ATTR_MEDIA,
        !            51:        ATTR_CLASS,
        !            52:        ATTR_MAX
1.7       kristaps   53: };
                     54:
1.29    ! kristaps   55: struct htmldata {
        !            56:        char             *name;
        !            57:        int               flags;
        !            58: #define        HTML_BLOCK       (1 << 0)
        !            59: };
1.7       kristaps   60:
1.29    ! kristaps   61: static const struct htmldata htmltags[TAG_MAX] = {
        !            62:        {"html",        HTML_BLOCK}, /* TAG_HTML */
        !            63:        {"head",        HTML_BLOCK}, /* TAG_HEAD */
        !            64:        {"body",        HTML_BLOCK}, /* TAG_BODY */
        !            65:        {"meta",        HTML_BLOCK}, /* TAG_META */
        !            66:        {"title",       HTML_BLOCK}, /* TAG_TITLE */
        !            67:        {"div",         HTML_BLOCK}, /* TAG_DIV */
        !            68:        {"h1",          0}, /* TAG_H1 */
        !            69:        {"h2",          0}, /* TAG_H2 */
        !            70:        {"p",           HTML_BLOCK}, /* TAG_P */
        !            71:        {"span",        0}, /* TAG_SPAN */
        !            72:        {"link",        HTML_BLOCK}, /* TAG_LINK */
        !            73: };
1.10      kristaps   74:
1.29    ! kristaps   75: static const char       *const htmlattrs[ATTR_MAX] = {
        !            76:        "http-equiv",
        !            77:        "content",
        !            78:        "name",
        !            79:        "rel",
        !            80:        "href",
        !            81:        "type",
        !            82:        "media",
        !            83:        "class"
        !            84: };
1.10      kristaps   85:
1.29    ! kristaps   86: struct htmlpair {
        !            87:        enum htmlattr     key;
        !            88:        char             *val;
        !            89: };
1.10      kristaps   90:
1.29    ! kristaps   91: struct html {
        !            92:        int               flags;
        !            93: #define        HTML_NOSPACE     (1 << 0)
        !            94: };
1.10      kristaps   95:
1.29    ! kristaps   96: #define        MDOC_ARGS         const struct mdoc_meta *m, \
        !            97:                          const struct mdoc_node *n, \
        !            98:                          struct html *h
        !            99: #define        MAN_ARGS          const struct man_meta *m, \
        !           100:                          const struct man_node *n, \
        !           101:                          struct html *h
        !           102: struct htmlmdoc {
        !           103:        int             (*pre)(MDOC_ARGS);
        !           104:        void            (*post)(MDOC_ARGS);
        !           105: };
1.13      kristaps  106:
1.29    ! kristaps  107: static void              print_gen_doctype(struct html *);
        !           108: static void              print_gen_head(struct html *);
        !           109: static void              print_mdoc(MDOC_ARGS);
        !           110: static void              print_mdoc_head(MDOC_ARGS);
        !           111: static void              print_mdoc_node(MDOC_ARGS);
        !           112: static void              print_man(MAN_ARGS);
        !           113: static void              print_man_head(MAN_ARGS);
        !           114: static void              print_man_body(MAN_ARGS);
        !           115: static void              print_otag(struct html *, enum htmltag,
        !           116:                                int, const struct htmlpair *);
        !           117: static void              print_ctag(struct html *, enum htmltag);
        !           118: static void              print_encode(const char *);
        !           119: static void              print_text(struct html *, const char *);
        !           120: static int               mdoc_root_pre(MDOC_ARGS);
        !           121: static void              mdoc_root_post(MDOC_ARGS);
        !           122:
        !           123: static int               mdoc_nd_pre(MDOC_ARGS);
        !           124: static int               mdoc_nm_pre(MDOC_ARGS);
        !           125: static void              mdoc_nm_post(MDOC_ARGS);
        !           126: static int               mdoc_pp_pre(MDOC_ARGS);
        !           127: static int               mdoc_sh_pre(MDOC_ARGS);
        !           128: static void              mdoc_sh_post(MDOC_ARGS);
        !           129: static int               mdoc_ss_pre(MDOC_ARGS);
        !           130: static void              mdoc_ss_post(MDOC_ARGS);
        !           131:
        !           132: static const struct htmlmdoc mdocs[MDOC_MAX] = {
        !           133:        {NULL, NULL}, /* Ap */
        !           134:        {NULL, NULL}, /* Dd */
        !           135:        {NULL, NULL}, /* Dt */
        !           136:        {NULL, NULL}, /* Os */
        !           137:        {mdoc_sh_pre, mdoc_sh_post }, /* Sh */
        !           138:        {mdoc_ss_pre, mdoc_ss_post }, /* Ss */
        !           139:        {mdoc_pp_pre, NULL}, /* Pp */
        !           140:        {NULL, NULL}, /* D1 */
        !           141:        {NULL, NULL}, /* Dl */
        !           142:        {NULL, NULL}, /* Bd */
        !           143:        {NULL, NULL}, /* Ed */
        !           144:        {NULL, NULL}, /* Bl */
        !           145:        {NULL, NULL}, /* El */
        !           146:        {NULL, NULL}, /* It */
        !           147:        {NULL, NULL}, /* Ad */
        !           148:        {NULL, NULL}, /* An */
        !           149:        {NULL, NULL}, /* Ar */
        !           150:        {NULL, NULL}, /* Cd */
        !           151:        {NULL, NULL}, /* Cm */
        !           152:        {NULL, NULL}, /* Dv */
        !           153:        {NULL, NULL}, /* Er */
        !           154:        {NULL, NULL}, /* Ev */
        !           155:        {NULL, NULL}, /* Ex */
        !           156:        {NULL, NULL}, /* Fa */
        !           157:        {NULL, NULL}, /* Fd */
        !           158:        {NULL, NULL}, /* Fl */
        !           159:        {NULL, NULL}, /* Fn */
        !           160:        {NULL, NULL}, /* Ft */
        !           161:        {NULL, NULL}, /* Ic */
        !           162:        {NULL, NULL}, /* In */
        !           163:        {NULL, NULL}, /* Li */
        !           164:        {mdoc_nd_pre, NULL}, /* Nd */
        !           165:        {mdoc_nm_pre, mdoc_nm_post}, /* Nm */
        !           166:        {NULL, NULL}, /* Op */
        !           167:        {NULL, NULL}, /* Ot */
        !           168:        {NULL, NULL}, /* Pa */
        !           169:        {NULL, NULL}, /* Rv */
        !           170:        {NULL, NULL}, /* St */
        !           171:        {NULL, NULL}, /* Va */
        !           172:        {NULL, NULL}, /* Vt */
        !           173:        {NULL, 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:        {NULL, NULL}, /* 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:        {NULL, NULL}, /* Bx */
        !           195:        {NULL, NULL}, /* Db */
        !           196:        {NULL, NULL}, /* Dc */
        !           197:        {NULL, NULL}, /* Do */
        !           198:        {NULL, NULL}, /* Dq */
        !           199:        {NULL, NULL}, /* Ec */
        !           200:        {NULL, NULL}, /* Ef */
        !           201:        {NULL, NULL}, /* Em */
        !           202:        {NULL, NULL}, /* Eo */
        !           203:        {NULL, NULL}, /* Fx */
        !           204:        {NULL, NULL}, /* Ms */
        !           205:        {NULL, NULL}, /* No */
        !           206:        {NULL, NULL}, /* Ns */
        !           207:        {NULL, NULL}, /* Nx */
        !           208:        {NULL, NULL}, /* Ox */
        !           209:        {NULL, NULL}, /* Pc */
        !           210:        {NULL, NULL}, /* Pf */
        !           211:        {NULL, NULL}, /* Po */
        !           212:        {NULL, NULL}, /* Pq */
        !           213:        {NULL, NULL}, /* Qc */
        !           214:        {NULL, NULL}, /* Ql */
        !           215:        {NULL, NULL}, /* Qo */
        !           216:        {NULL, NULL}, /* Qq */
        !           217:        {NULL, NULL}, /* Re */
        !           218:        {NULL, NULL}, /* Rs */
        !           219:        {NULL, NULL}, /* Sc */
        !           220:        {NULL, NULL}, /* So */
        !           221:        {NULL, NULL}, /* Sq */
        !           222:        {NULL, NULL}, /* Sm */
        !           223:        {NULL, NULL}, /* 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:        {NULL, NULL}, /* Ud */
        !           239:        {NULL, NULL}, /* Lb */
        !           240:        {NULL, NULL}, /* Lp */
        !           241:        {NULL, NULL}, /* Lk */
        !           242:        {NULL, NULL}, /* Mt */
        !           243:        {NULL, NULL}, /* Brq */
        !           244:        {NULL, NULL}, /* Bro */
        !           245:        {NULL, NULL}, /* Brc */
        !           246:        {NULL, NULL}, /* %C */
        !           247:        {NULL, NULL}, /* Es */
        !           248:        {NULL, NULL}, /* En */
        !           249:        {NULL, NULL}, /* Dx */
        !           250:        {NULL, NULL}, /* %Q */
        !           251:        {NULL, NULL}, /* br */
        !           252:        {NULL, NULL}, /* sp */
        !           253: };
1.10      kristaps  254:
                    255:
1.29    ! kristaps  256: int
        !           257: html_mdoc(void *arg, const struct mdoc *m)
1.10      kristaps  258: {
1.29    ! kristaps  259:        struct html     *h;
1.10      kristaps  260:
1.29    ! kristaps  261:        h = (struct html *)arg;
1.10      kristaps  262:
1.29    ! kristaps  263:        print_gen_doctype(h);
        !           264:        print_otag(h, TAG_HTML, 0, NULL);
        !           265:        print_mdoc(mdoc_meta(m), mdoc_node(m), h);
        !           266:        print_ctag(h, TAG_HTML);
        !           267:        printf("\n");
        !           268:        return(1);
1.10      kristaps  269: }
                    270:
                    271:
1.29    ! kristaps  272: int
        !           273: html_man(void *arg, const struct man *m)
1.10      kristaps  274: {
1.29    ! kristaps  275:        struct html     *h;
1.10      kristaps  276:
1.29    ! kristaps  277:        h = (struct html *)arg;
1.10      kristaps  278:
1.29    ! kristaps  279:        print_gen_doctype(h);
        !           280:        print_otag(h, TAG_HTML, 0, NULL);
        !           281:        print_man(man_meta(m), man_node(m), h);
        !           282:        print_ctag(h, TAG_HTML);
        !           283:        printf("\n");
        !           284:        return(1);
1.10      kristaps  285: }
                    286:
                    287:
1.29    ! kristaps  288: void *
        !           289: html_alloc(void)
1.10      kristaps  290: {
                    291:
1.29    ! kristaps  292:        return(calloc(1, sizeof(struct html)));
        !           293: }
1.10      kristaps  294:
1.13      kristaps  295:
1.29    ! kristaps  296: void
        !           297: html_free(void *p)
        !           298: {
1.10      kristaps  299:
1.29    ! kristaps  300:        free(p);
1.10      kristaps  301: }
1.2       kristaps  302:
                    303:
1.29    ! kristaps  304: static void
        !           305: print_mdoc(MDOC_ARGS)
1.4       kristaps  306: {
                    307:
1.29    ! kristaps  308:        print_otag(h, TAG_HEAD, 0, NULL);
        !           309:        print_mdoc_head(m, n, h);
        !           310:        print_ctag(h, TAG_HEAD);
        !           311:        print_otag(h, TAG_BODY, 0, NULL);
        !           312:        print_mdoc_node(m, n, h);
        !           313:        print_ctag(h, TAG_BODY);
        !           314: }
1.4       kristaps  315:
                    316:
1.29    ! kristaps  317: static void
        !           318: print_gen_head(struct html *h)
        !           319: {
        !           320:        struct htmlpair  meta0[2];
        !           321:        struct htmlpair  meta1[2];
        !           322:        struct htmlpair  link[4];
        !           323:
        !           324:        meta0[0].key = ATTR_HTTPEQUIV;
        !           325:        meta0[0].val = "Content-Type";
        !           326:        meta0[1].key = ATTR_CONTENT;
        !           327:        meta0[1].val = "text/html; charest-utf-8";
        !           328:
        !           329:        meta1[0].key = ATTR_NAME;
        !           330:        meta1[0].val = "resource-type";
        !           331:        meta1[1].key = ATTR_CONTENT;
        !           332:        meta1[1].val = "document";
        !           333:
        !           334:        link[0].key = ATTR_REL;
        !           335:        link[0].val = "stylesheet";
        !           336:        link[1].key = ATTR_HREF;
        !           337:        link[1].val = "style.css";
        !           338:        link[2].key = ATTR_TYPE;
        !           339:        link[2].val = "text/css";
        !           340:        link[3].key = ATTR_MEDIA;
        !           341:        link[3].val = "all";
        !           342:
        !           343:        print_otag(h, TAG_META, 2, meta0);
        !           344:        print_otag(h, TAG_META, 2, meta1);
        !           345:        print_otag(h, TAG_LINK, 4, link);
1.4       kristaps  346: }
                    347:
                    348:
1.29    ! kristaps  349: static void
        !           350: print_mdoc_head(MDOC_ARGS)
1.18      kristaps  351: {
                    352:
1.29    ! kristaps  353:        print_gen_head(h);
        !           354:        print_otag(h, TAG_TITLE, 0, NULL);
        !           355:        print_encode(m->title);
        !           356:        print_ctag(h, TAG_TITLE);
1.18      kristaps  357: }
                    358:
                    359:
                    360: static int
1.29    ! kristaps  361: mdoc_root_pre(MDOC_ARGS)
1.18      kristaps  362: {
1.29    ! kristaps  363:        struct htmlpair  div;
1.18      kristaps  364:
1.29    ! kristaps  365:        div.key = ATTR_CLASS;
        !           366:        div.val = "body";
1.18      kristaps  367:
1.29    ! kristaps  368:        print_otag(h, TAG_DIV, 1, &div);
        !           369:        return(1);
1.2       kristaps  370: }
                    371:
                    372:
1.29    ! kristaps  373: static void
        !           374: mdoc_root_post(MDOC_ARGS)
1.2       kristaps  375: {
1.22      kristaps  376:
1.29    ! kristaps  377:        print_ctag(h, TAG_DIV);
1.2       kristaps  378: }
                    379:
                    380:
1.7       kristaps  381: static int
1.29    ! kristaps  382: mdoc_ss_pre(MDOC_ARGS)
1.2       kristaps  383: {
1.3       kristaps  384:
1.29    ! kristaps  385:        if (MDOC_BODY == n->type)
        !           386:                print_otag(h, TAG_P, 0, NULL);
        !           387:        if (MDOC_HEAD == n->type)
        !           388:                print_otag(h, TAG_H2, 0, NULL);
        !           389:        return(1);
1.3       kristaps  390: }
                    391:
                    392:
1.29    ! kristaps  393: static void
        !           394: mdoc_ss_post(MDOC_ARGS)
        !           395: {
1.10      kristaps  396:
1.29    ! kristaps  397:        if (MDOC_BODY == n->type)
        !           398:                print_ctag(h, TAG_P);
        !           399:        if (MDOC_HEAD == n->type)
        !           400:                print_ctag(h, TAG_H2);
1.3       kristaps  401: }
                    402:
                    403:
1.7       kristaps  404: static int
1.29    ! kristaps  405: mdoc_pp_pre(MDOC_ARGS)
1.3       kristaps  406: {
                    407:
1.29    ! kristaps  408:        print_otag(h, TAG_P, 0, NULL);
        !           409:        return(0);
1.3       kristaps  410: }
                    411:
                    412:
1.7       kristaps  413: static int
1.29    ! kristaps  414: mdoc_nd_pre(MDOC_ARGS)
1.3       kristaps  415: {
                    416:
1.29    ! kristaps  417:        if (MDOC_BODY == n->type)
        !           418:                print_text(h, "--");
        !           419:        return(1);
1.3       kristaps  420: }
                    421:
                    422:
1.7       kristaps  423: static int
1.29    ! kristaps  424: mdoc_nm_pre(MDOC_ARGS)
1.3       kristaps  425: {
1.29    ! kristaps  426:        struct htmlpair class;
1.3       kristaps  427:
1.29    ! kristaps  428:        class.key = ATTR_CLASS;
        !           429:        class.val = "name";
1.3       kristaps  430:
1.29    ! kristaps  431:        print_otag(h, TAG_SPAN, 1, &class);
        !           432:        if (NULL == n->child)
        !           433:                print_text(h, m->name);
1.3       kristaps  434:
1.29    ! kristaps  435:        return(1);
1.2       kristaps  436: }
                    437:
                    438:
1.29    ! kristaps  439: static void
        !           440: mdoc_nm_post(MDOC_ARGS)
1.2       kristaps  441: {
1.3       kristaps  442:
1.29    ! kristaps  443:        print_ctag(h, TAG_SPAN);
1.2       kristaps  444: }
1.1       kristaps  445:
                    446:
1.7       kristaps  447: static int
1.29    ! kristaps  448: mdoc_sh_pre(MDOC_ARGS)
        !           449: {
1.19      kristaps  450:
1.29    ! kristaps  451:        if (MDOC_BODY == n->type)
        !           452:                print_otag(h, TAG_P, 0, NULL);
        !           453:        if (MDOC_HEAD == n->type)
        !           454:                print_otag(h, TAG_H1, 0, NULL);
1.12      kristaps  455:        return(1);
1.2       kristaps  456: }
                    457:
                    458:
1.29    ! kristaps  459: static void
        !           460: mdoc_sh_post(MDOC_ARGS)
1.2       kristaps  461: {
                    462:
1.29    ! kristaps  463:        if (MDOC_BODY == n->type)
        !           464:                print_ctag(h, TAG_P);
        !           465:        if (MDOC_HEAD == n->type)
        !           466:                print_ctag(h, TAG_H1);
1.2       kristaps  467: }
                    468:
                    469:
1.29    ! kristaps  470: static void
        !           471: print_mdoc_node(MDOC_ARGS)
1.2       kristaps  472: {
1.29    ! kristaps  473:        int              child;
1.8       kristaps  474:
1.29    ! kristaps  475:        child = 1;
1.8       kristaps  476:
1.29    ! kristaps  477:        switch (n->type) {
        !           478:        case (MDOC_ROOT):
        !           479:                child = mdoc_root_pre(m, n, h);
1.7       kristaps  480:                break;
1.29    ! kristaps  481:        case (MDOC_TEXT):
        !           482:                print_text(h, n->string);
1.7       kristaps  483:                break;
1.3       kristaps  484:        default:
1.29    ! kristaps  485:                if (mdocs[n->tok].pre)
        !           486:                        child = (*mdocs[n->tok].pre)(m, n, h);
1.3       kristaps  487:                break;
1.2       kristaps  488:        }
                    489:
1.29    ! kristaps  490:        if (child && n->child)
        !           491:                print_mdoc_node(m, n->child, h);
1.8       kristaps  492:
1.29    ! kristaps  493:        switch (n->type) {
        !           494:        case (MDOC_ROOT):
        !           495:                mdoc_root_post(m, n, h);
1.7       kristaps  496:                break;
1.29    ! kristaps  497:        case (MDOC_TEXT):
1.7       kristaps  498:                break;
1.3       kristaps  499:        default:
1.29    ! kristaps  500:                if (mdocs[n->tok].post)
        !           501:                        (*mdocs[n->tok].post)(m, n, h);
1.3       kristaps  502:                break;
                    503:        }
1.2       kristaps  504:
1.29    ! kristaps  505:        if (n->next)
        !           506:                print_mdoc_node(m, n->next, h);
1.2       kristaps  507: }
                    508:
                    509:
1.29    ! kristaps  510: static void
        !           511: print_man(MAN_ARGS)
1.9       kristaps  512: {
                    513:
1.29    ! kristaps  514:        print_otag(h, TAG_HEAD, 0, NULL);
        !           515:        print_man_head(m, n, h);
        !           516:        print_ctag(h, TAG_HEAD);
        !           517:        print_otag(h, TAG_BODY, 0, NULL);
        !           518:        print_man_body(m, n, h);
        !           519:        print_ctag(h, TAG_BODY);
1.9       kristaps  520: }
                    521:
                    522:
                    523: static void
1.29    ! kristaps  524: print_man_head(MAN_ARGS)
1.9       kristaps  525: {
                    526:
1.29    ! kristaps  527:        print_gen_head(h);
        !           528:        print_otag(h, TAG_TITLE, 0, NULL);
        !           529:        print_encode(m->title);
        !           530:        print_ctag(h, TAG_TITLE);
        !           531: }
1.9       kristaps  532:
                    533:
1.29    ! kristaps  534: static void
        !           535: print_man_body(MAN_ARGS)
        !           536: {
1.9       kristaps  537: }
                    538:
                    539:
1.29    ! kristaps  540: static void
        !           541: print_encode(const char *p)
        !           542: {
1.14      kristaps  543:
1.29    ! kristaps  544:        printf("%s", p); /* XXX */
1.14      kristaps  545: }
                    546:
                    547:
1.29    ! kristaps  548: static void
        !           549: print_otag(struct html *h, enum htmltag tag,
        !           550:                int sz, const struct htmlpair *p)
1.14      kristaps  551: {
1.29    ! kristaps  552:        int              i;
        !           553:
        !           554:        if ( ! (HTML_NOSPACE & h->flags))
        !           555:                if ( ! (HTML_BLOCK & htmltags[tag].flags))
        !           556:                        printf(" ");
        !           557:
        !           558:        printf("<%s", htmltags[tag].name);
        !           559:        for (i = 0; i < sz; i++) {
        !           560:                printf(" %s=\"", htmlattrs[p[i].key]);
        !           561:                assert(p->val);
        !           562:                print_encode(p[i].val);
        !           563:                printf("\"");
        !           564:        }
        !           565:        printf(">");
1.14      kristaps  566:
1.29    ! kristaps  567:        h->flags |= HTML_NOSPACE;
1.14      kristaps  568:
                    569: }
                    570:
                    571:
                    572: /* ARGSUSED */
1.29    ! kristaps  573: static void
        !           574: print_ctag(struct html *h, enum htmltag tag)
1.14      kristaps  575: {
                    576:
1.29    ! kristaps  577:        printf("</%s>", htmltags[tag].name);
        !           578:        if (HTML_BLOCK & htmltags[tag].flags)
        !           579:                h->flags |= HTML_NOSPACE;
1.14      kristaps  580: }
                    581:
                    582:
1.29    ! kristaps  583: /* ARGSUSED */
        !           584: static void
        !           585: print_gen_doctype(struct html *h)
1.1       kristaps  586: {
1.29    ! kristaps  587:
        !           588:        printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">\n", DOCTYPE, DTD);
1.1       kristaps  589: }
                    590:
                    591:
1.29    ! kristaps  592: static void
        !           593: print_text(struct html *h, const char *p)
1.1       kristaps  594: {
                    595:
1.29    ! kristaps  596:        if (*p && 0 == *(p + 1))
        !           597:                switch (*p) {
        !           598:                case('.'):
        !           599:                        /* FALLTHROUGH */
        !           600:                case(','):
        !           601:                        /* FALLTHROUGH */
        !           602:                case(';'):
        !           603:                        /* FALLTHROUGH */
        !           604:                case(':'):
        !           605:                        /* FALLTHROUGH */
        !           606:                case('?'):
        !           607:                        /* FALLTHROUGH */
        !           608:                case('!'):
        !           609:                        /* FALLTHROUGH */
        !           610:                case(')'):
        !           611:                        /* FALLTHROUGH */
        !           612:                case(']'):
        !           613:                        /* FALLTHROUGH */
        !           614:                case('}'):
        !           615:                        h->flags |= HTML_NOSPACE;
        !           616:                default:
        !           617:                        break;
        !           618:                }
1.1       kristaps  619:
1.29    ! kristaps  620:        if ( ! (h->flags & HTML_NOSPACE))
        !           621:                printf(" ");
        !           622:        h->flags &= ~HTML_NOSPACE;
1.1       kristaps  623:
1.29    ! kristaps  624:        if (p)
        !           625:                print_encode(p);
1.8       kristaps  626:
1.29    ! kristaps  627:        if (*p && 0 == *(p + 1))
        !           628:                switch (*p) {
        !           629:                case('('):
        !           630:                        /* FALLTHROUGH */
        !           631:                case('['):
        !           632:                        /* FALLTHROUGH */
        !           633:                case('{'):
        !           634:                        h->flags |= HTML_NOSPACE;
        !           635:                default:
        !           636:                        break;
        !           637:                }
1.1       kristaps  638: }

CVSweb