txt2html

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

node.c (raw) (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 }