Annotation of mandoc/html.c, Revision 1.10
1.10 ! kristaps 1: /* $Id: html.c,v 1.9 2008/12/05 19:45:15 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.8 kristaps 35: /* TODO: allow head/tail-less invocations (just "div" start). */
36:
1.7 kristaps 37: struct htmlnode {
1.8 kristaps 38: int tok;
39: enum md_ns ns;
1.10 ! kristaps 40: int argc[ROFF_MAXLINEARG];
1.7 kristaps 41: char *argv[ROFF_MAXLINEARG];
42: struct htmlnode *parent;
43: };
44:
45:
46: struct htmlq {
47: struct htmlnode *last;
48: };
49:
50:
1.4 kristaps 51: static int html_loadcss(struct md_mbuf *, const char *);
52:
1.9 kristaps 53: static int html_alloc(void **);
54: static void html_free(void *);
1.8 kristaps 55: static ssize_t html_endtag(struct md_mbuf *, void *,
1.2 kristaps 56: const struct md_args *,
57: enum md_ns, int);
1.8 kristaps 58: static ssize_t html_begintag(struct md_mbuf *, void *,
1.2 kristaps 59: const struct md_args *,
60: enum md_ns, int,
61: const int *, const char **);
1.4 kristaps 62: static int html_begin(struct md_mbuf *,
63: const struct md_args *,
64: const struct tm *,
65: const char *, const char *,
66: const char *, const char *);
1.7 kristaps 67: static int html_printargs(struct md_mbuf *, int,
68: const char *, const int *,
69: const char **, size_t *);
1.2 kristaps 70: static int html_end(struct md_mbuf *,
71: const struct md_args *);
1.7 kristaps 72: static int html_blocktagname(struct md_mbuf *,
1.10 ! kristaps 73: const struct md_args *, int,
! 74: struct htmlq *, const int *,
! 75: const char **, size_t *);
1.7 kristaps 76: static int html_blocktagargs(struct md_mbuf *,
1.2 kristaps 77: const struct md_args *, int,
1.7 kristaps 78: const int *, const char **, size_t *);
1.10 ! kristaps 79: static int html_headtagname(struct md_mbuf *,
! 80: const struct md_args *, int,
! 81: struct htmlq *, const int *,
! 82: const char **, size_t *);
! 83: static int html_headtagargs(struct md_mbuf *,
1.3 kristaps 84: const struct md_args *, int,
1.7 kristaps 85: const int *, const char **, size_t *);
86: static int html_blockbodytagname(struct md_mbuf *,
1.10 ! kristaps 87: const struct md_args *,
! 88: int, struct htmlq *, const int *,
! 89: const char **, size_t *);
1.7 kristaps 90: static int html_blockbodytagargs(struct md_mbuf *,
1.3 kristaps 91: const struct md_args *, int,
1.7 kristaps 92: const int *, const char **, size_t *);
93: static int html_inlinetagname(struct md_mbuf *,
94: const struct md_args *, int, size_t *);
95: static int html_inlinetagargs(struct md_mbuf *,
1.2 kristaps 96: const struct md_args *, int,
1.7 kristaps 97: const int *, const char **, size_t *);
1.10 ! kristaps 98: static int html_Bl_bodytagname(struct md_mbuf *,
! 99: struct htmlq *, const int *,
! 100: const char **, size_t *);
! 101: static int html_It_blocktagname(struct md_mbuf *,
! 102: struct htmlq *, const int *,
! 103: const char **, size_t *);
! 104: static int html_It_headtagname(struct md_mbuf *,
! 105: struct htmlq *, const int *,
! 106: const char **, size_t *);
! 107: static int html_It_bodytagname(struct md_mbuf *,
! 108: struct htmlq *, const int *,
! 109: const char **, size_t *);
! 110:
! 111:
! 112: /* ARGSUSED */
! 113: static int
! 114: html_It_headtagname(struct md_mbuf *mbuf, struct htmlq *q,
! 115: const int *argc, const char **argv, size_t *res)
! 116: {
! 117: struct htmlnode *n;
! 118: int i, c;
! 119:
! 120: for (n = q->last; n; n = n->parent)
! 121: if (n->tok == ROFF_Bl)
! 122: break;
! 123:
! 124: assert(n);
! 125: for (i = 0; ROFF_ARGMAX != (c = n->argc[i]) &&
! 126: i < ROFF_MAXLINEARG; i++) {
! 127: switch (n->argc[i]) {
! 128: case (ROFF_Tag):
! 129: /* FALLTHROUGH */
! 130: case (ROFF_Column):
! 131: return(ml_nputs(mbuf, "td", 2, res));
! 132: default:
! 133: break;
! 134: }
! 135: }
! 136:
! 137: assert(i != ROFF_MAXLINEARG);
! 138: abort();
! 139: /* NOTREACHED */
! 140:
! 141: return(1);
! 142: }
! 143:
! 144:
! 145: /* ARGSUSED */
! 146: static int
! 147: html_It_bodytagname(struct md_mbuf *mbuf, struct htmlq *q,
! 148: const int *argc, const char **argv, size_t *res)
! 149: {
! 150: struct htmlnode *n;
! 151: int i, c;
! 152:
! 153: for (n = q->last; n; n = n->parent)
! 154: if (n->tok == ROFF_Bl)
! 155: break;
! 156:
! 157: assert(n);
! 158: for (i = 0; ROFF_ARGMAX != (c = n->argc[i]) &&
! 159: i < ROFF_MAXLINEARG; i++) {
! 160: switch (n->argc[i]) {
! 161: case (ROFF_Enum):
! 162: /* FALLTHROUGH */
! 163: case (ROFF_Bullet):
! 164: /* FALLTHROUGH */
! 165: case (ROFF_Dash):
! 166: /* FALLTHROUGH */
! 167: case (ROFF_Hyphen):
! 168: /* FALLTHROUGH */
! 169: case (ROFF_Item):
! 170: /* FALLTHROUGH */
! 171: case (ROFF_Diag):
! 172: /* FALLTHROUGH */
! 173: case (ROFF_Hang):
! 174: /* FALLTHROUGH */
! 175: case (ROFF_Ohang):
! 176: /* FALLTHROUGH */
! 177: case (ROFF_Inset):
! 178: return(ml_nputs(mbuf, "div", 3, res));
! 179: case (ROFF_Tag):
! 180: /* FALLTHROUGH */
! 181: case (ROFF_Column):
! 182: return(ml_nputs(mbuf, "td", 2, res));
! 183: default:
! 184: break;
! 185: }
! 186: }
! 187:
! 188: assert(i != ROFF_MAXLINEARG);
! 189: abort();
! 190: /* NOTREACHED */
! 191:
! 192: return(1);
! 193: }
! 194:
! 195:
! 196: /* ARGSUSED */
! 197: static int
! 198: html_Bl_bodytagname(struct md_mbuf *mbuf, struct htmlq *q,
! 199: const int *argc, const char **argv, size_t *res)
! 200: {
! 201: int c, i;
! 202:
! 203: for (i = 0; ROFF_ARGMAX != (c = argc[i])
! 204: && i < ROFF_MAXLINEARG; i++) {
! 205: switch (argc[i]) {
! 206: case (ROFF_Enum):
! 207: return(ml_nputs(mbuf, "ol", 2, res));
! 208: case (ROFF_Bullet):
! 209: /* FALLTHROUGH */
! 210: case (ROFF_Dash):
! 211: /* FALLTHROUGH */
! 212: case (ROFF_Hyphen):
! 213: /* FALLTHROUGH */
! 214: case (ROFF_Item):
! 215: /* FALLTHROUGH */
! 216: case (ROFF_Diag):
! 217: /* FALLTHROUGH */
! 218: case (ROFF_Hang):
! 219: /* FALLTHROUGH */
! 220: case (ROFF_Ohang):
! 221: /* FALLTHROUGH */
! 222: case (ROFF_Inset):
! 223: return(ml_nputs(mbuf, "ul", 2, res));
! 224: case (ROFF_Tag):
! 225: /* FALLTHROUGH */
! 226: case (ROFF_Column):
! 227: return(ml_nputs(mbuf, "table", 5, res));
! 228: default:
! 229: break;
! 230: }
! 231: }
! 232:
! 233: assert(i != ROFF_MAXLINEARG);
! 234: abort();
! 235: /* NOTREACHED */
! 236: }
! 237:
! 238:
! 239: /* ARGSUSED */
! 240: static int
! 241: html_It_blocktagname(struct md_mbuf *mbuf, struct htmlq *q,
! 242: const int *argc, const char **argv, size_t *res)
! 243: {
! 244: struct htmlnode *n;
! 245: int i, c;
! 246:
! 247: for (n = q->last; n; n = n->parent)
! 248: if (n->tok == ROFF_Bl)
! 249: break;
! 250:
! 251: assert(n);
! 252: for (i = 0; ROFF_ARGMAX != (c = n->argc[i]) &&
! 253: i < ROFF_MAXLINEARG; i++) {
! 254: switch (n->argc[i]) {
! 255: case (ROFF_Enum):
! 256: /* FALLTHROUGH */
! 257: case (ROFF_Bullet):
! 258: /* FALLTHROUGH */
! 259: case (ROFF_Dash):
! 260: /* FALLTHROUGH */
! 261: case (ROFF_Hyphen):
! 262: /* FALLTHROUGH */
! 263: case (ROFF_Item):
! 264: /* FALLTHROUGH */
! 265: case (ROFF_Diag):
! 266: /* FALLTHROUGH */
! 267: case (ROFF_Hang):
! 268: /* FALLTHROUGH */
! 269: case (ROFF_Ohang):
! 270: /* FALLTHROUGH */
! 271: case (ROFF_Inset):
! 272: return(ml_nputs(mbuf, "li", 2, res));
! 273: case (ROFF_Tag):
! 274: /* FALLTHROUGH */
! 275: case (ROFF_Column):
! 276: return(ml_nputs(mbuf, "tr", 2, res));
! 277: default:
! 278: break;
! 279: }
! 280: }
! 281:
! 282: assert(i != ROFF_MAXLINEARG);
! 283: abort();
! 284: /* NOTREACHED */
! 285: }
1.2 kristaps 286:
287:
1.4 kristaps 288: static int
289: html_loadcss(struct md_mbuf *mbuf, const char *css)
290: {
291: size_t res, bufsz;
292: char *buf;
293: struct stat st;
294: int fd, c;
295: ssize_t ssz;
296:
297: c = 0;
298: res = 0;
299: buf = NULL;
300:
301: if (-1 == (fd = open(css, O_RDONLY, 0))) {
302: warn("%s", css);
303: return(0);
304: }
305:
306: if (-1 == fstat(fd, &st)) {
307: warn("%s", css);
308: goto out;
309: }
310:
311: bufsz = MAX(st.st_blksize, BUFSIZ);
312: if (NULL == (buf = malloc(bufsz))) {
313: warn("malloc");
314: goto out;
315: }
316:
317: for (;;) {
318: if (-1 == (ssz = read(fd, buf, bufsz))) {
319: warn("%s", css);
320: goto out;
321: } else if (0 == ssz)
322: break;
323: if ( ! ml_nputs(mbuf, buf, (size_t)ssz, &res))
324: goto out;
325: }
326:
327: c = 1;
328:
329: out:
330: if (-1 == close(fd)) {
331: warn("%s", css);
332: c = 0;
333: }
334:
335: if (buf)
336: free(buf);
337:
338: return(c);
339: }
340:
341:
1.3 kristaps 342: /* ARGSUSED */
1.2 kristaps 343: static int
1.4 kristaps 344: html_begin(struct md_mbuf *mbuf, const struct md_args *args,
345: const struct tm *tm, const char *os,
346: const char *title, const char *section,
347: const char *vol)
1.2 kristaps 348: {
1.4 kristaps 349: const char *preamble, *css, *trail;
350: char buf[512];
1.2 kristaps 351: size_t res;
352:
1.4 kristaps 353: preamble =
354: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n"
355: " \"http://www.w3.org/TR/html4/strict.dtd\">\n"
356: "<html>\n"
357: "<head>\n"
358: " <meta http-equiv=\"Content-Type\"\n"
359: " content=\"text/html;charset=utf-8\">\n"
360: " <meta name=\"resource-type\" content=\"document\">\n"
361: " <title>Manual Page for %s(%s)</title>\n";
362:
363: css =
364: " <link rel=\"stylesheet\" type=\"text/css\"\n"
365: " href=\"%s\">\n";
366: trail =
367: "</head>\n"
368: "<body>\n"
1.10 ! kristaps 369: "<div class=\"mdoc\">";
1.4 kristaps 370:
1.2 kristaps 371: res = 0;
1.4 kristaps 372:
373: (void)snprintf(buf, sizeof(buf) - 1,
374: preamble, title, section);
375:
376: if ( ! ml_puts(mbuf, buf, &res))
1.2 kristaps 377: return(0);
1.4 kristaps 378:
379: assert(args->params.html.css);
380: if (HTML_CSS_EMBED & args->params.html.flags) {
1.5 kristaps 381: if ( ! ml_puts(mbuf, " <style type=\"text/css\"><!--\n", &res))
1.4 kristaps 382: return(0);
383: if ( ! html_loadcss(mbuf, args->params.html.css))
384: return(0);
385: if ( ! ml_puts(mbuf, " --!></style>\n", &res))
386: return(0);
387: } else {
388: (void)snprintf(buf, sizeof(buf) - 1, css,
389: args->params.html.css);
390: if ( ! ml_puts(mbuf, buf, &res))
391: return(0);
392: }
393:
394: if ( ! ml_puts(mbuf, trail, &res))
1.2 kristaps 395: return(0);
396:
397: return(1);
398: }
399:
400:
1.3 kristaps 401: /* ARGSUSED */
1.2 kristaps 402: static int
403: html_end(struct md_mbuf *mbuf, const struct md_args *args)
404: {
405:
1.9 kristaps 406: return(ml_puts(mbuf, "</div></body>\n</html>", NULL));
1.2 kristaps 407: }
408:
409:
1.3 kristaps 410: /* ARGSUSED */
1.7 kristaps 411: static int
1.3 kristaps 412: html_blockbodytagname(struct md_mbuf *mbuf,
1.10 ! kristaps 413: const struct md_args *args, int tok, struct htmlq *q,
! 414: const int *argc, const char **argv, size_t *res)
1.2 kristaps 415: {
1.3 kristaps 416:
1.10 ! kristaps 417: switch (tok) {
! 418: case (ROFF_Bl):
! 419: return(html_Bl_bodytagname(mbuf, q, argc, argv, res));
! 420: case (ROFF_It):
! 421: return(html_It_bodytagname(mbuf, q, argc, argv, res));
! 422: default:
! 423: break;
! 424: }
! 425:
1.7 kristaps 426: return(ml_puts(mbuf, "div", res));
1.3 kristaps 427: }
428:
429:
430: /* ARGSUSED */
1.7 kristaps 431: static int
1.10 ! kristaps 432: html_headtagname(struct md_mbuf *mbuf,
! 433: const struct md_args *args, int tok, struct htmlq *q,
! 434: const int *argc, const char **argv, size_t *res)
1.3 kristaps 435: {
436:
1.10 ! kristaps 437: switch (tok) {
! 438: case (ROFF_It):
! 439: return(html_It_headtagname(mbuf, q, argc, argv, res));
! 440: case (ROFF_Sh):
! 441: return(ml_puts(mbuf, "h1", res));
! 442: case (ROFF_Ss):
! 443: return(ml_puts(mbuf, "h2", res));
! 444: default:
! 445: break;
! 446: }
! 447:
1.7 kristaps 448: return(ml_puts(mbuf, "div", res));
1.3 kristaps 449: }
450:
451:
452: /* ARGSUSED */
1.7 kristaps 453: static int
1.10 ! kristaps 454: html_blocktagname(struct md_mbuf *mbuf, const struct md_args *args,
! 455: int tok, struct htmlq *q, const int *argc,
! 456: const char **argv, size_t *res)
1.3 kristaps 457: {
458:
1.10 ! kristaps 459: switch (tok) {
! 460: case (ROFF_It):
! 461: return(html_It_blocktagname(mbuf, q, argc, argv, res));
! 462: default:
! 463: break;
! 464: }
! 465:
1.7 kristaps 466: return(ml_puts(mbuf, "div", res));
1.3 kristaps 467: }
468:
469:
1.9 kristaps 470: /* ARGSUSED */
1.7 kristaps 471: static int
472: html_printargs(struct md_mbuf *mbuf, int tok, const char *ns,
473: const int *argc, const char **argv, size_t *res)
1.3 kristaps 474: {
475:
1.7 kristaps 476: if ( ! ml_puts(mbuf, " class=\"", res))
477: return(0);
478: if ( ! ml_puts(mbuf, ns, res))
479: return(0);
480: if ( ! ml_puts(mbuf, "-", res))
1.3 kristaps 481: return(0);
1.7 kristaps 482: if ( ! ml_puts(mbuf, toknames[tok], res))
1.3 kristaps 483: return(0);
1.9 kristaps 484: return(ml_puts(mbuf, "\"", res));
1.3 kristaps 485: }
486:
487:
488: /* ARGSUSED */
1.7 kristaps 489: static int
1.10 ! kristaps 490: html_headtagargs(struct md_mbuf *mbuf,
1.7 kristaps 491: const struct md_args *args, int tok,
492: const int *argc, const char **argv, size_t *res)
1.3 kristaps 493: {
494:
1.7 kristaps 495: return(html_printargs(mbuf, tok, "head", argc, argv, res));
496: }
1.3 kristaps 497:
498:
1.7 kristaps 499: /* ARGSUSED */
500: static int
501: html_blockbodytagargs(struct md_mbuf *mbuf,
502: const struct md_args *args, int tok,
503: const int *argc, const char **argv, size_t *res)
504: {
1.3 kristaps 505:
1.7 kristaps 506: return(html_printargs(mbuf, tok, "body", argc, argv, res));
1.2 kristaps 507: }
508:
509:
510: /* ARGSUSED */
1.7 kristaps 511: static int
512: html_blocktagargs(struct md_mbuf *mbuf,
513: const struct md_args *args, int tok,
514: const int *argc, const char **argv, size_t *res)
1.2 kristaps 515: {
1.3 kristaps 516:
1.7 kristaps 517: return(html_printargs(mbuf, tok, "block", argc, argv, res));
1.2 kristaps 518: }
1.1 kristaps 519:
520:
521: /* ARGSUSED */
1.7 kristaps 522: static int
523: html_inlinetagargs(struct md_mbuf *mbuf,
524: const struct md_args *args, int tok,
525: const int *argc, const char **argv, size_t *res)
1.2 kristaps 526: {
527:
1.7 kristaps 528: return(html_printargs(mbuf, tok, "inline", argc, argv, res));
1.2 kristaps 529: }
530:
531:
1.3 kristaps 532: /* ARGSUSED */
1.7 kristaps 533: static int
1.2 kristaps 534: html_inlinetagname(struct md_mbuf *mbuf,
1.7 kristaps 535: const struct md_args *args, int tok, size_t *res)
1.2 kristaps 536: {
537:
538: switch (tok) {
1.4 kristaps 539: case (ROFF_Pp):
1.7 kristaps 540: return(ml_puts(mbuf, "div", res));
1.2 kristaps 541: default:
1.9 kristaps 542: break;
1.2 kristaps 543: }
1.9 kristaps 544:
545: return(ml_puts(mbuf, "span", res));
1.2 kristaps 546: }
547:
548:
549: static ssize_t
1.8 kristaps 550: html_begintag(struct md_mbuf *mbuf, void *data,
551: const struct md_args *args, enum md_ns ns,
552: int tok, const int *argc, const char **argv)
1.2 kristaps 553: {
1.7 kristaps 554: size_t res;
1.8 kristaps 555: struct htmlq *q;
556: struct htmlnode *node;
1.10 ! kristaps 557: int i, c;
1.2 kristaps 558:
559: assert(ns != MD_NS_DEFAULT);
1.7 kristaps 560: res = 0;
561:
1.8 kristaps 562: assert(data);
563: q = (struct htmlq *)data;
564:
565: if (NULL == (node = calloc(1, sizeof(struct htmlnode)))) {
566: warn("calloc");
567: return(-1);
568: }
569:
570: node->parent = q->last;
571: node->tok = tok;
572: node->ns = ns;
573:
1.10 ! kristaps 574: if (argc) {
! 575: /* TODO: argv. */
! 576:
! 577: assert(argv);
! 578: for (i = 0; ROFF_ARGMAX != (c = argc[i])
! 579: && i < ROFF_MAXLINEARG; i++)
! 580: node->argc[i] = argc[i];
! 581: assert(i != ROFF_MAXLINEARG);
! 582: } else
! 583: assert(NULL == argv);
! 584:
! 585:
1.8 kristaps 586: q->last = node;
587:
1.3 kristaps 588: switch (ns) {
589: case (MD_NS_BLOCK):
1.10 ! kristaps 590: if ( ! html_blocktagname(mbuf, args, tok,
! 591: q, argc, argv, &res))
1.7 kristaps 592: return(-1);
593: if ( ! html_blocktagargs(mbuf, args, tok,
594: argc, argv, &res))
595: return(-1);
596: break;
1.3 kristaps 597: case (MD_NS_BODY):
1.10 ! kristaps 598: if ( ! html_blockbodytagname(mbuf, args, tok,
! 599: q, argc, argv, &res))
1.7 kristaps 600: return(-1);
601: if ( ! html_blockbodytagargs(mbuf, args, tok,
602: argc, argv, &res))
603: return(-1);
604: break;
1.3 kristaps 605: case (MD_NS_HEAD):
1.10 ! kristaps 606: if ( ! html_headtagname(mbuf, args, tok, q,
! 607: argc, argv, &res))
1.7 kristaps 608: return(-1);
1.10 ! kristaps 609: if ( ! html_headtagargs(mbuf, args, tok,
1.7 kristaps 610: argc, argv, &res))
611: return(-1);
612: break;
1.3 kristaps 613: default:
1.7 kristaps 614: if ( ! html_inlinetagname(mbuf, args, tok, &res))
615: return(-1);
616: if ( ! html_inlinetagargs(mbuf, args, tok,
617: argc, argv, &res))
618: return(-1);
1.3 kristaps 619: break;
1.2 kristaps 620: }
621:
1.7 kristaps 622: return((ssize_t)res);
1.2 kristaps 623: }
624:
625:
626: static ssize_t
1.8 kristaps 627: html_endtag(struct md_mbuf *mbuf, void *data,
628: const struct md_args *args, enum md_ns ns, int tok)
1.2 kristaps 629: {
1.7 kristaps 630: size_t res;
1.8 kristaps 631: struct htmlq *q;
632: struct htmlnode *node;
1.2 kristaps 633:
634: assert(ns != MD_NS_DEFAULT);
1.7 kristaps 635: res = 0;
636:
1.8 kristaps 637: assert(data);
638: q = (struct htmlq *)data;
1.10 ! kristaps 639: node = q->last;
1.8 kristaps 640:
1.3 kristaps 641: switch (ns) {
642: case (MD_NS_BLOCK):
1.10 ! kristaps 643: if ( ! html_blocktagname(mbuf, args, tok,
! 644: q, node->argc,
! 645: (const char **)node->argv, &res))
1.7 kristaps 646: return(-1);
647: break;
1.3 kristaps 648: case (MD_NS_BODY):
1.10 ! kristaps 649: if ( ! html_blockbodytagname(mbuf, args, tok,
! 650: q, node->argc,
! 651: (const char **)node->argv, &res))
1.7 kristaps 652: return(-1);
653: break;
1.3 kristaps 654: case (MD_NS_HEAD):
1.10 ! kristaps 655: if ( ! html_headtagname(mbuf, args, tok,
! 656: q, node->argc,
! 657: (const char **)node->argv, &res))
1.7 kristaps 658: return(-1);
659: break;
1.3 kristaps 660: default:
1.7 kristaps 661: if ( ! html_inlinetagname(mbuf, args, tok, &res))
662: return(-1);
1.3 kristaps 663: break;
664: }
1.2 kristaps 665:
1.8 kristaps 666: q->last = node->parent;
667:
1.9 kristaps 668: free(node);
1.8 kristaps 669:
1.7 kristaps 670: return((ssize_t)res);
1.2 kristaps 671: }
672:
673:
1.9 kristaps 674: static int
675: html_alloc(void **p)
676: {
677:
678: if (NULL == (*p = calloc(1, sizeof(struct htmlq)))) {
679: warn("calloc");
680: return(0);
681: }
682: return(1);
683: }
684:
685:
686: static void
687: html_free(void *p)
688: {
689: struct htmlq *q;
690: struct htmlnode *n;
691:
692: assert(p);
693: q = (struct htmlq *)p;
694:
695: while ((n = q->last)) {
696: q->last = n->parent;
697: free(n);
698: }
699:
700: free(q);
701: }
702:
703:
1.1 kristaps 704: int
705: md_line_html(void *data, char *buf)
706: {
707:
1.2 kristaps 708: return(mlg_line((struct md_mlg *)data, buf));
1.1 kristaps 709: }
710:
711:
712: int
713: md_exit_html(void *data, int flush)
714: {
715:
1.2 kristaps 716: return(mlg_exit((struct md_mlg *)data, flush));
1.1 kristaps 717: }
718:
719:
720: void *
721: md_init_html(const struct md_args *args,
722: struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
723: {
1.9 kristaps 724: struct ml_cbs cbs;
1.8 kristaps 725:
1.9 kristaps 726: cbs.ml_alloc = html_alloc;
727: cbs.ml_free = html_free;
728: cbs.ml_begintag = html_begintag;
729: cbs.ml_endtag = html_endtag;
730: cbs.ml_begin = html_begin;
731: cbs.ml_end = html_end;
1.1 kristaps 732:
1.9 kristaps 733: return(mlg_alloc(args, rbuf, mbuf, &cbs));
1.1 kristaps 734: }
1.2 kristaps 735:
CVSweb