txt2html

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

parse.c (raw) (3270B)


   1 #include "txt2html.h"
   2 
   3 struct node *parse_buf(const char *buf, struct node **n, uint8_t opts)
   4 {
   5 	size_t i = 0;
   6 	size_t len = (buf) ? strlen(buf) : 0;
   7 
   8 	if (!buf && (*n)) {
   9 		*n = node_create(*n, CLOSE+(*n)->type);
  10 		i = len;
  11 	}
  12 
  13 	while (i < len && buf) {
  14 		while (buf[i] == '\n') ++i;
  15 		if (!(*n) || ((*n)->type & CLOSE))
  16 			i += node_next(&buf[i], n);
  17 		switch ((*n)->type) {
  18 			case H1:
  19 			case H2:
  20 				i += parse_heading(&buf[i], n);
  21 				break;
  22 			case P:     i += parse_p(&buf[i], n, opts);   break;
  23 			case OL+LI: i += parse_oli(&buf[i], n, opts); break;
  24 			case UL+LI: i += parse_uli(&buf[i], n, opts); break;
  25 			case PRE:
  26 				i += parse_textblock(&buf[i], n, opts & OPT_BR);
  27 				*n = node_create(*n, CLOSE+PRE);
  28 				break;
  29 			default:
  30 				i += node_next(&buf[i], n);
  31 				break;
  32 		}
  33 	}
  34 	
  35 	return *n;
  36 }
  37 
  38 size_t parse_textblock(const char *str, struct node **n, bool softbreaks)
  39 {
  40 	size_t ret = 0;
  41 
  42 	while (str[ret] != '\0' && (isprint(str[ret]) || str[ret] == '\n' || str[ret] == '\t')) {
  43 		if (str[ret] == '\n' && str[ret+1] == '\n')
  44 			break;
  45 		else if ((*n)->type == PRE && str[ret] == '\t')
  46 			++ret;
  47 		else if (str[ret] == '\n') {
  48 			if (((*n)->type & (OL+LI) && rule_match(&str[ret+1], OPEN+OL+LI)) ||
  49 				((*n)->type & (UL+LI) && rule_match(&str[ret+1], OPEN+UL+LI))) {
  50 				++ret;
  51 				break;
  52 			}
  53 
  54 			if ((*n)->type == PRE && str[ret+1] == '\t') {
  55 				node_writec(n, '\n');
  56 				++ret;
  57 			} else if ((*n)->type == PRE && str[ret+1] != '\t') {
  58 				break;
  59 			} else if (softbreaks) {
  60 				*n = node_create(*n, OPEN+BR+CLOSE);
  61 				*n = node_create(*n, (*n)->prev->type);
  62 			} else {
  63 				node_writec(n, str[ret]);
  64 			}
  65 		} else {
  66 			node_writec(n, str[ret]);
  67 		}
  68 		++ret;
  69 	}
  70 	node_writec(n, EOF);
  71 
  72 	return ret;
  73 }
  74 
  75 size_t parse_heading(const char *str, struct node **n)
  76 {
  77 	assert(str);
  78 	size_t i = 0;
  79 	while(str[i] && str[i] != '\n')
  80 		node_writec(n, str[i++]);
  81 	node_writec(n, EOF);
  82 	do { ++i; } while (str[i] == '-' || str[i] == '=');
  83 	*n = node_create(*n, CLOSE+(*n)->type);
  84 	return i;
  85 }
  86 
  87 size_t parse_oli(const char *str, struct node **n, uint8_t opts)
  88 {
  89 	assert(str);
  90 	size_t i = 0, len = strlen(str);
  91 	while(i < len) {
  92 		i += parse_textblock(&str[i], n, opts & OPT_BR);
  93 		*n = node_create(*n, CLOSE+OL+LI);
  94 
  95 		if (str[i] == '\0' || rule_match(&str[i], CLOSE+OL)) {
  96 			i += rule_len(CLOSE+OL);
  97 			*n = node_create(*n, CLOSE+OL);
  98 			break;
  99 		} else if (rule_match(&str[i], OPEN+OL+LI)) {
 100 			i += rule_len(OPEN+OL+LI);
 101 			*n = node_create(*n, OPEN+OL+LI);
 102 			*n = node_create(*n, OL+LI);
 103 		}
 104 	}
 105 	return i;
 106 }
 107 
 108 size_t parse_p(const char *str, struct node **n, uint8_t opts)
 109 {
 110 	size_t i = parse_textblock(str, n, opts & OPT_BR);
 111 	if (str[i] == '\n' && str[i+1] == '\n')
 112 		*n = node_create(*n, CLOSE+P);
 113 	return i;
 114 }
 115 
 116 size_t parse_uli(const char *str, struct node **n, uint8_t opts)
 117 {
 118 	size_t ret = 0;
 119 	size_t len = strlen(str);
 120 
 121 	while (ret < len) {
 122 		ret += parse_textblock(&str[ret], n, opts & OPT_BR);
 123 		*n = node_create(*n, CLOSE+UL+LI);
 124 
 125 		if (str[ret] == '\0' || rule_match(&str[ret], CLOSE+UL)) {
 126 			ret += rule_len(CLOSE+UL);
 127 			*n = node_create(*n, CLOSE+UL);
 128 			break;
 129 		} else if (rule_match(&str[ret], OPEN+UL+LI)) {
 130 			ret += rule_len(OPEN+UL+LI);
 131 			*n = node_create(*n, OPEN+UL+LI);
 132 			*n = node_create(*n, UL+LI);
 133 		} else break;
 134 	}
 135 
 136 	return ret;
 137 }