txt2html

Converts plaintext to HTML
git clone git://src.gearsix.net/txt2html
Log | Files | Refs | Atom | README

node.c (2754B)


      1 #include "txt2html.h"
      2 
      3 struct node *node_create(struct node *prev, NodeType t)
      4 {
      5 	struct node *n = calloc(1, sizeof(struct node));
      6 
      7 	if (prev) {
      8 		n->prev = prev;
      9 		prev->next = n;
     10 	}
     11 
     12 	n->type = t;
     13 
     14 	if (t == OPEN+BR+CLOSE) {
     15 		n->buf = "<br/>\n\0";
     16 	} else if (t & OPEN) {
     17 		t &= 0x0F;
     18 		if      (t == H1)  n->buf = "<h1>\0";
     19 		else if (t == H2)  n->buf = "<h2>\0";
     20 		else if (t == PRE) n->buf = "<pre>\0";
     21 		else if (t == P)   n->buf = "<p>\0";
     22 		else if (t == OL)  n->buf = "<ol>\n\0";
     23 		else if (t == UL)  n->buf = "<ul>\n\0";
     24 		else if (t == OL+LI || t == UL+LI)
     25 			n->buf = "<li>\0";
     26 	} else if (t & CLOSE) {
     27 		t &= 0x0F;
     28 		node_writec(&prev, EOF);
     29 		if      (t == H1)  n->buf = "</h1>\n\0";
     30 		else if (t == H2)  n->buf = "</h2>\n\0";
     31 		else if (t == PRE) n->buf = "</pre>\n\0";
     32 		else if (t == P)   n->buf = "</p>\n\0";
     33 		else if (t == OL)  n->buf = "</ol>\n\0";
     34 		else if (t == UL)  n->buf = "</ul>\n\0";
     35 		else if (t == UL+LI || t == OL+LI)
     36 			n->buf = "</li>\n\0";
     37 	}
     38 
     39 	return n;
     40 }
     41 
     42 // node_writec has an internal static buffer (`buf`) that it writes `c` to.
     43 // if `c == EOF` or `buf` reaches `BUFSIZ`, then `buf` it's written to n->buf.
     44 // `n->buf` will only be allocated required memory.
     45 void node_writec(struct node **n, int c)
     46 {
     47 	assert(n);
     48 
     49 	static int pg = 0;
     50 	static int len = 0;
     51 	static char buf[BUFSIZ+1];
     52 
     53 	if (len+2 == BUFSIZ || (c == EOF && len > 0)) {
     54 		if (c == EOF) {
     55 			buf[len++] = '\0';
     56 			buf[len++] = '$'; // signal malloc not assigned const
     57 		}
     58 		(*n)->buf = (pg == 0) ? malloc(len) : realloc((*n)->buf, strlen((*n)->buf) + len);
     59 		memmove((*n)->buf, buf, len);
     60 		++pg;
     61 		len = 0;
     62 		memset(buf, '\0', BUFSIZ); 
     63 	}
     64 
     65 	switch (c) {
     66 		case EOF:
     67 			pg = 0;
     68 			break;
     69 		case '\t':
     70 			strncat(buf, "&emsp;", 7);
     71 			len += 6;
     72 			break;
     73 		default:
     74 			strncat(buf, (char *)&c, 2);
     75 			len += 1;
     76 			break;
     77 	}
     78 }
     79 
     80 size_t node_next(const char *str, struct node **n)
     81 {
     82 	size_t ret = 0;
     83 	if (rule_match(&str[ret], OPEN+OL+LI)) {
     84 		ret += rule_len(OPEN+OL+LI);
     85 		*n = node_create(*n, OPEN+OL);
     86 		*n = node_create(*n, OPEN+OL+LI);
     87 		*n = node_create(*n, OL+LI);
     88 	} else if (rule_match(&str[ret], OPEN+UL+LI)) {
     89 		ret += rule_len(OPEN+UL+LI);
     90 		*n = node_create(*n, OPEN+UL);
     91 		*n = node_create(*n, OPEN+UL+LI);
     92 		*n = node_create(*n, UL+LI);
     93 	} else if (rule_match(&str[ret], OPEN+PRE)) {
     94 		ret += rule_len(OPEN+PRE);
     95 		*n = node_create(*n, OPEN+PRE);
     96 		*n = node_create(*n, PRE);
     97 	} else if (isprint(str[ret])) {
     98 		switch (rule_match_heading(&str[ret])) {
     99 			case H1:
    100 				*n = node_create(*n, OPEN+H1);
    101 				*n = node_create(*n, H1);
    102 				break;
    103 			case H2:
    104 				*n = node_create(*n, OPEN+H2);
    105 				*n = node_create(*n, H2);
    106 				break;
    107 			default:
    108 				*n = node_create(*n, OPEN+P);
    109 				*n = node_create(*n, P);
    110 				break;
    111 		}
    112 	}
    113 	return ret;
    114 }