node.c (2751B)
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 // writebuf 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, " ", 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 }