Diff
Not logged in

Differences From:

File src/creoleparser.c part of check-in [26af399a5c] - mods to creole parser and add some default style for creole tables. by robert on 2009-05-09 06:19:39. [view]

To:

File src/creoleparser.c part of check-in [7a39dde24b] - Clean up and merge updates from trunk by robert on 2009-09-26 08:17:33. [view]

@@ -29,9 +29,9 @@
 #include "config.h"
 #include "creoleparser.h"
 
 #if INTERFACE
-#define HAVE_MACRO_EXTENSIONS 1
+#define HAVE_CREOLE_MACRO 1
 #endif
 
 //{{{ LOCAL INTERFACE
 #if LOCAL_INTERFACE
@@ -62,57 +62,57 @@
 #define KIND_TABLE_ROW       0x0010000
 //}}}
 //{{{ FLAG
 // keep first four bits free
-#define FLAG_CENTER	 0x0000100
+#define FLAG_CENTER   0x0000100
 //}}}
 struct Node {//{{{
 
-	char *start;
-	char *end;
-
-	int kind;
-	int level;
-	int flags;
-
-	Node *parent;
-	Node *next;
-	Node *children;
+  char *start;
+  char *end;
+
+  int kind;
+  int level;
+  int flags;
+
+  Node *parent;
+  Node *next;
+  Node *children;
 
 };
 //}}}
 struct NodePool {//{{{
-	NodePool *next;
-	Node a[POOL_CHUNK_SIZE];
+  NodePool *next;
+  Node a[POOL_CHUNK_SIZE];
 }
 //}}}
 struct Parser {//{{{
 
-	Blob *pOut;                 /* Output appended to this blob */
-	Renderer *r;
-
-	NodePool *pool;
-	int nFree;
+  Blob *pOut;                 /* Output appended to this blob */
+  Renderer *r;
+
+  NodePool *pool;
+  int nFree;
 
   Node *this;
-	Node *previous;
-	Node *list;
-
-	char *cursor;
-
-	int lineWasBlank;
-	int charCount;
-
-	Node *item;
-	Node *istack;
-	char *icursor;
-	char *iend;
-
-	int inLink;
-	int inTable;
-	int iesc;
-
-	Blob *iblob;
+  Node *previous;
+  Node *list;
+
+  char *cursor;
+
+  int lineWasBlank;
+  int charCount;
+
+  Node *item;
+  Node *istack;
+  char *icursor;
+  char *iend;
+
+  int inLink;
+  int inTable;
+  int iesc;
+
+  Blob *iblob;
 
 
 
 
@@ -127,482 +127,483 @@
 
 //{{{ POOL MANAGEMENT
 static Node *pool_new(Parser *p){
 
-	if ( p->pool == NULL || p->nFree == 0){
-
-		NodePool *temp = p->pool;
-
-		p->pool = malloc(sizeof(NodePool));
-		if( p->pool == NULL ) fossil_panic("out of memory");
-
-		p->pool->next = temp;
-		p->nFree = POOL_CHUNK_SIZE;
-	}
-	p->nFree -= 1;
-	Node *node = &(p->pool->a[p->nFree]);
-	memset(node, 0, sizeof(*node));
-
-	return node;
+  if ( p->pool == NULL || p->nFree == 0){
+
+    NodePool *temp = p->pool;
+
+    p->pool = malloc(sizeof(NodePool));
+    if( p->pool == NULL ) fossil_panic("out of memory");
+
+    p->pool->next = temp;
+    p->nFree = POOL_CHUNK_SIZE;
+  }
+  p->nFree -= 1;
+  Node *node = &(p->pool->a[p->nFree]);
+  memset(node, 0, sizeof(*node));
+
+  return node;
 }
 
 
 static void pool_free(Parser *p){
 
-	NodePool *temp;
-
-	while (p->pool != NULL){
-		temp = p->pool;
-		p->pool = temp->next;
-		free(temp);
-	}
+  NodePool *temp;
+
+  while (p->pool != NULL){
+    temp = p->pool;
+    p->pool = temp->next;
+    free(temp);
+  }
 
 }
 //}}}
 
 //{{{ Utility Methods
 
 static char *cr_skipBlanks(Parser *p, char* z){//{{{
-	char *s = z;
-	while (z[0] == ' ' || z[0] == '\t') z++;
-	p->charCount = z - s;
-	return z;
+  char *s = z;
+  while (z[0] == ' ' || z[0] == '\t') z++;
+  p->charCount = z - s;
+  return z;
 }
 //}}}
 static int cr_countBlanks(Parser *p, char* z){//{{{
-	cr_skipBlanks(p, z);
-	return p->charCount;
+  cr_skipBlanks(p, z);
+  return p->charCount;
 }
 //}}}
 static char *cr_skipChars(Parser *p, char *z, char c){//{{{
-	char *s = z;
-	while (z[0] == c) z++;
-	p->charCount = z - s;
-	return z;
+  char *s = z;
+  while (z[0] == c) z++;
+  p->charCount = z - s;
+  return z;
 }
 //}}}
 static int cr_countChars(Parser *p, char *z, char c){//{{{
-	cr_skipChars(p, z, c);
-	return p->charCount;
+  cr_skipChars(p, z, c);
+  return p->charCount;
 }
 //}}}
 static char *cr_nextLine(Parser *p, char *z){//{{{
 
-	p->lineWasBlank = 1;
-
-	while (1){
-
-		switch (z[0]){
-
-			case '\r':
-				if (z[1] == '\n') {
-					z[0] = ' ';
-					return z + 2;
-				}
-				z[0] = '\n';
-				return z + 1;
-
-			case'\n':
-				return z + 1;
-
-			case '\t':
-				z[0] = ' ';
-				z++;
-				break;
-
-			case ' ':
-				z++;
-				break;
-
-			case '\0':
-				return z;
-
-			default:
-				p->lineWasBlank = 0;
-				z++;
-		}
-	}
+  p->lineWasBlank = 1;
+
+  while (1){
+
+    switch (z[0]){
+
+      case '\r':
+        if (z[1] == '\n') {
+          z[0] = ' ';
+          return z + 2;
+        }
+        z[0] = '\n';
+        return z + 1;
+
+      case'\n':
+        return z + 1;
+
+      case '\t':
+        z[0] = ' ';
+        z++;
+        break;
+
+      case ' ':
+        z++;
+        break;
+
+      case '\0':
+        return z;
+
+      default:
+        p->lineWasBlank = 0;
+        z++;
+    }
+  }
 }
 //}}}
 //}}}
 
 //{{{ INLINE PARSER
 
 static int cr_isEsc(Parser *p){//{{{
-	if (p->iesc){
-		blob_append(p->iblob, p->icursor, 1);
-		p->iesc = 0;
-		p->icursor += 1;
-		return 1;
-	}
-	return 0;
+  if (p->iesc){
+    blob_append(p->iblob, p->icursor, 1);
+    p->iesc = 0;
+    p->icursor += 1;
+    return 1;
+  }
+  return 0;
 }
 //}}}
 static int cr_iOpen(Parser *p, int kind){//{{{
 
-	switch (kind){
-
-		case KIND_BOLD:
-			blob_append(p->iblob, "<strong>", 8);
-			return 1;
-
-		case KIND_ITALIC:
-			blob_append(p->iblob, "<em>", 4);
-			return 1;
-
-		case KIND_SUPERSCRIPT:
-			blob_append(p->iblob, "<sup>", 5);
-			return 1;
-
-		case KIND_SUBSCRIPT:
-			blob_append(p->iblob, "<sub>", 5);
-			return 1;
-
-		case KIND_MONOSPACED:
-			blob_append(p->iblob, "<tt>", 4);
-			return 1;
-	}
-	return 0;
+  switch (kind){
+
+    case KIND_BOLD:
+      blob_append(p->iblob, "<strong>", 8);
+      return 1;
+
+    case KIND_ITALIC:
+      blob_append(p->iblob, "<em>", 4);
+      return 1;
+
+    case KIND_SUPERSCRIPT:
+      blob_append(p->iblob, "<sup>", 5);
+      return 1;
+
+    case KIND_SUBSCRIPT:
+      blob_append(p->iblob, "<sub>", 5);
+      return 1;
+
+    case KIND_MONOSPACED:
+      blob_append(p->iblob, "<tt>", 4);
+      return 1;
+  }
+  return 0;
 }
 //}}}
 static int cr_iClose(Parser *p, int kind){//{{{
 
-	switch (kind){
-
-		case KIND_BOLD:
-			blob_append(p->iblob, "</strong>", 9);
-			return 1;
-
-		case KIND_ITALIC:
-			blob_append(p->iblob, "</em>", 5);
-			return 1;
-
-		case KIND_SUPERSCRIPT:
-			blob_append(p->iblob, "</sup>", 6);
-			return 1;
-
-		case KIND_SUBSCRIPT:
-			blob_append(p->iblob, "</sub>", 6);
-			return 1;
-
-		case KIND_MONOSPACED:
-			blob_append(p->iblob, "</tt>", 5);
-			return 1;
-	}
-	return 0;
+  switch (kind){
+
+    case KIND_BOLD:
+      blob_append(p->iblob, "</strong>", 9);
+      return 1;
+
+    case KIND_ITALIC:
+      blob_append(p->iblob, "</em>", 5);
+      return 1;
+
+    case KIND_SUPERSCRIPT:
+      blob_append(p->iblob, "</sup>", 6);
+      return 1;
+
+    case KIND_SUBSCRIPT:
+      blob_append(p->iblob, "</sub>", 6);
+      return 1;
+
+    case KIND_MONOSPACED:
+      blob_append(p->iblob, "</tt>", 5);
+      return 1;
+  }
+  return 0;
 }
 //}}}
 
 
 static void cr_iMarkup(Parser *p, int kind){//{{{
 
-	if (p->iesc) {
-		blob_append(p->iblob, p->icursor, 1);
-		p->icursor +=1;
-		p->iesc =0;
-		return;
-	}
-
-	if (p->icursor[1] != p->icursor[0]) {
-		blob_append(p->iblob, p->icursor, 1);
-		p->icursor +=1;
-		return;
-	}
-
-	p->icursor += 2;
-
-	if (kind & KIND_BREAK) {
-			blob_append(p->iblob, "<br />", 6);
-			return;
-	}
-
-	if (kind & KIND_ITALIC && p->icursor[-3] == ':'){
-				blob_append(p->iblob, "//", 2);
-				return;
-	}
-
-	Node *n = p->istack;
-
-	int found = 0;
-	while (n) {
-		if (n->kind & kind) {
-			found = 1;
-			break;
-		}
-		n = n->next;
-	}
-
-	if (!found) {
-		n = pool_new(p);
-		n->kind = kind;
-		n->next = p->istack;
-		p->istack = n;
-
-		assert(cr_iOpen(p, kind));
-		return;
-	};
-
-	n= p->istack;
-	while (n){
-		p->istack = n->next;
-
-		assert(cr_iClose(p, n->kind));
-
-		if (kind == n->kind) return;
-		n = p->istack;
-	}
+  if (p->iesc) {
+    blob_append(p->iblob, p->icursor, 1);
+    p->icursor +=1;
+    p->iesc =0;
+    return;
+  }
+
+  if (p->icursor[1] != p->icursor[0]) {
+    blob_append(p->iblob, p->icursor, 1);
+    p->icursor +=1;
+    return;
+  }
+
+  p->icursor += 2;
+
+  if (kind & KIND_BREAK) {
+      blob_append(p->iblob, "<br />", 6);
+      return;
+  }
+
+  if (kind & KIND_ITALIC && p->icursor[-3] == ':'){
+        blob_append(p->iblob, "//", 2);
+        return;
+  }
+
+  Node *n = p->istack;
+
+  int found = 0;
+  while (n) {
+    if (n->kind & kind) {
+      found = 1;
+      break;
+    }
+    n = n->next;
+  }
+
+  if (!found) {
+    n = pool_new(p);
+    n->kind = kind;
+    n->next = p->istack;
+    p->istack = n;
+
+    assert(cr_iOpen(p, kind));
+    return;
+  };
+
+  n= p->istack;
+  while (n){
+    p->istack = n->next;
+
+    assert(cr_iClose(p, n->kind));
+
+    if (kind == n->kind) return;
+    n = p->istack;
+  }
 }
 //}}}
 static int cr_iNoWiki(Parser *p){//{{{
 
-	if ((p->iend - p->icursor)<6) return 0;
-
-	if (p->icursor[1]!='{' || p->icursor[2]!='{')
-		return 0;
-
-	char *s = p->icursor + 3;
-
-	int count = p->iend - p->icursor - 6;
-	while (count--){
-		if (s[0]=='}' && s[1]=='}' && s[2]=='}' && s[3]!='}'){
-			blob_appendf(p->iblob, "<tt style='background:oldlace'>%s</tt>", htmlize(p->icursor + 3, s - p->icursor-3));
-			p->icursor = s + 3;
-			return 1;
-		}
-		s++;
-	}
-	return 0;
+  if ((p->iend - p->icursor)<6) return 0;
+
+  if (p->icursor[1]!='{' || p->icursor[2]!='{')
+    return 0;
+
+  char *s = p->icursor + 3;
+
+  int count = p->iend - p->icursor - 6;
+  while (count--){
+    if (s[0]=='}' && s[1]=='}' && s[2]=='}' && s[3]!='}'){
+      blob_appendf(p->iblob, "<tt style='background:oldlace'>%s</tt>", htmlize(p->icursor + 3, s - p->icursor-3));
+      p->icursor = s + 3;
+      return 1;
+    }
+    s++;
+  }
+  return 0;
 }
 
 //}}}
 static int cr_iImage(Parser *p){//{{{
 
-	if (p->inLink) return 0;
-	if ((p->iend - p->icursor)<3) return 0;
-
-	if (p->icursor[1]!='{') return 0;
-
-	char *s = p->icursor + 2;
-	char *bar = NULL;
-
-	int count = p->iend - p->icursor - 4;
-	while (count--){
-		if (s[0]=='}' && s[1]=='}'){
-			if (!bar) bar = p->icursor + 2;
-			blob_appendf(p->iblob, "<span style='color:green;border:1px solid green;'>%s</span>", htmlize(bar, s - bar ));
-			p->icursor = s + 2;
-			return 1;
-		}
-		if (!bar && s[0]=='|') bar=s+1;
-		s++;
-	}
-	return 0;
+  if (p->inLink) return 0;
+  if ((p->iend - p->icursor)<3) return 0;
+
+  if (p->icursor[1]!='{') return 0;
+
+  char *s = p->icursor + 2;
+  char *bar = NULL;
+
+  int count = p->iend - p->icursor - 4;
+  while (count--){
+    if (s[0]=='}' && s[1]=='}'){
+      if (!bar) bar = p->icursor + 2;
+      blob_appendf(p->iblob, "<span style='color:green;border:1px solid green;'>%s</span>", htmlize(bar, s - bar ));
+      p->icursor = s + 2;
+      return 1;
+    }
+    if (!bar && s[0]=='|') bar=s+1;
+    s++;
+  }
+  return 0;
 }
 //}}}
 static int cr_iMacro(Parser *p){//{{{
 
-	if (p->inLink) return 0;
-	if ((p->iend - p->icursor)<3) return 0;
-
-	if (p->icursor[1]!='<') return 0;
-
-	char *s = p->icursor + 2;
-
-	int count = p->iend - p->icursor - 4;
-	while (count--){
-		if (s[0]=='>' && s[1]=='>'){
-			blob_appendf(p->iblob, "<span style='color:red;border:1px solid red;'>%s</span>", htmlize(p->icursor, s - p->icursor + 2));
-			p->icursor = s + 2;
-			return 1;
-		}
-		s++;
-	}
-	return 0;
+  if (p->inLink) return 0;
+  if ((p->iend - p->icursor)<3) return 0;
+
+  if (p->icursor[1]!='<') return 0;
+
+  char *s = p->icursor + 2;
+
+  int count = p->iend - p->icursor - 3;
+  while (count--){
+    blob_appendf(p->iblob, "|~%s|", s,2 );
+    if (s[0]=='>' && s[1]=='>'){
+      blob_appendf(p->iblob, "<span style='color:red;border:1px solid red;'>%s</span>", htmlize(p->icursor, s - p->icursor + 2));
+      p->icursor = s + 2;
+      return 1;
+    }
+    s++;
+  }
+  return 0;
 
 }
 //}}}
 
 static void cr_renderLink(Parser *p, char *s, char *bar, char *e){//{{{
 
-	int tsize = bar-s;
-	int dsize = e - bar-1;
-
-	if (tsize < 1) return;
-	if (dsize < 1) dsize = 0;
-
-	char zTarget[tsize + 1];
-	memcpy(zTarget, s, tsize);
-	zTarget[tsize] = '\0';
-
-	char zClose[20];
-
-	Blob *pOut = p->r->pOut;
-
-	p->r->pOut = p->iblob;
-	wf_openHyperlink(p->r, zTarget, zClose, sizeof(zClose));
-	p->r->pOut = pOut;
-
-	if (dsize)
-		cr_parseInline(p, bar+1, e) ;
-	else
-		blob_append(p->iblob, htmlize(s, tsize), -1);
-	blob_append(p->iblob, zClose, -1);
+  int tsize = bar-s;
+  int dsize = e - bar-1;
+
+  if (tsize < 1) return;
+  if (dsize < 1) dsize = 0;
+
+  char zTarget[tsize + 1];
+  memcpy(zTarget, s, tsize);
+  zTarget[tsize] = '\0';
+
+  char zClose[20];
+
+  Blob *pOut = p->r->pOut;
+
+  p->r->pOut = p->iblob;
+  wf_openHyperlink(p->r, zTarget, zClose, sizeof(zClose));
+  p->r->pOut = pOut;
+
+  if (dsize)
+    cr_parseInline(p, bar+1, e) ;
+  else
+    blob_append(p->iblob, htmlize(s, tsize), -1);
+  blob_append(p->iblob, zClose, -1);
 }
 //}}}
 
 static int cr_iLink(Parser *p){//{{{
 
-	if (p->inLink) return 0;
-	if ((p->iend - p->icursor)<3) return 0;
-
-	if (p->icursor[1]!='[') return 0;
-
-	char *s = p->icursor + 2;
-	char *bar = NULL;
-
-	int count = p->iend - p->icursor -3;
-	while (count--){
-		if (s[0]==']' && s[1]==']'){
-			if (!bar) bar = s;
-			p->inLink = 1;
-			cr_renderLink(p, p->icursor+2, bar, s);
-			p->inLink = 0;
-			p->icursor = s + 2;
-			return 1;
-		}
-		if (!bar && s[0]=='|') bar=s;
-		s++;
-	}
-	return 0;
+  if (p->inLink) return 0;
+  if ((p->iend - p->icursor)<3) return 0;
+
+  if (p->icursor[1]!='[') return 0;
+
+  char *s = p->icursor + 2;
+  char *bar = NULL;
+
+  int count = p->iend - p->icursor -3;
+  while (count--){
+    if (s[0]==']' && s[1]==']'){
+      if (!bar) bar = s;
+      p->inLink = 1;
+      cr_renderLink(p, p->icursor+2, bar, s);
+      p->inLink = 0;
+      p->icursor = s + 2;
+      return 1;
+    }
+    if (!bar && s[0]=='|') bar=s;
+    s++;
+  }
+  return 0;
 }
 //}}}
 
 LOCAL char *cr_parseInline(Parser *p, char *s, char *e){//{{{
 
-	int save_iesc = p->iesc;
-	char *save_iend = p->iend;
-	Node *save_istack = p->istack;
-
-	p->iesc = 0;
-	p->iend = e;
-	p->istack = NULL;
-
-	p->icursor = s;
-
-	char *eof = NULL;
-	while (!eof &&  p->icursor < p->iend ){
-
-		switch (*p->icursor) {//{{{
-
-			case '~':
-				if (p->iesc) {
-					blob_append(p->iblob, "~", 1);
-					p->iesc = 0;
-				}
-				p->iesc = !p->iesc;
-				p->icursor+=1;
-				break;
-
-			case '*':
-				cr_iMarkup(p, KIND_BOLD);
-				break;
-
-			case '/':
-				cr_iMarkup(p, KIND_ITALIC);
-				break;
-
-			case '^':
-				cr_iMarkup(p, KIND_SUPERSCRIPT);
-				break;
-
-			case ',':
-				cr_iMarkup(p, KIND_SUBSCRIPT);
-				break;
-
-			case '#':
-				cr_iMarkup(p, KIND_MONOSPACED);
-				break;
-
-			case '\\':
-				cr_iMarkup(p, KIND_BREAK);
-				break;
-
-			case '{':
-				if (cr_isEsc(p)) break;
-				if (cr_iNoWiki(p)) break;
-				if (cr_iImage(p)) break;
-				blob_append(p->iblob, p->icursor, 1);
-				p->icursor += 1;
-				break;
-
-			case '[':
-				if (cr_isEsc(p)) break;
-				if (cr_iLink(p)) break;
-				blob_append(p->iblob, p->icursor, 1);
-				p->icursor += 1;
-				break;
-
-
-			case '<':
-				if (cr_isEsc(p)) break;
-				if (cr_iMacro(p)) break;
-
-				blob_append(p->iblob, "&lt;", 4);
-				p->icursor += 1;
-				break;
-
-			case '>':
-				if (p->iesc) {
-					blob_append(p->iblob, "~", 1);
-					p->iesc = 0;
-				}
-				blob_append(p->iblob, "&gt;", 4);
-				p->icursor += 1;
-				break;
-
-			case '&':
-				if (p->iesc) {
-					blob_append(p->iblob, "~", 1);
-					p->iesc = 0;
-				}
-				blob_append(p->iblob, "&amp;", 5);
-				p->icursor += 1;
-				break;
-
-			case '|':
-				if (p->inTable){
-					if (p->iesc) {
-						blob_append(p->iblob, p->icursor, 1);
-						p->iesc = 0;
-						p->icursor += 1;
-						break;
-					}
-					eof = p->icursor + 1;
-					break;
-				}
-				// fall through to default
-
-			default:
-				if (p->iesc) {
-					blob_append(p->iblob, "~", 1);
-					p->iesc = 0;
-				}
-				blob_append(p->iblob, p->icursor, 1);
-				p->icursor +=1;
-		}//}}}
-
-	}
-
-	while (p->istack){
-		cr_iClose(p, p->istack->kind);
-		p->istack = p->istack->next;
-	}
-
-	p->iesc = save_iesc;
-	p->iend = save_iend;
-	p->istack = save_istack;
-
-	return eof;
+  int save_iesc = p->iesc;
+  char *save_iend = p->iend;
+  Node *save_istack = p->istack;
+
+  p->iesc = 0;
+  p->iend = e;
+  p->istack = NULL;
+
+  p->icursor = s;
+
+  char *eof = NULL;
+  while (!eof &&  p->icursor < p->iend ){
+
+    switch (*p->icursor) {//{{{
+
+      case '~':
+        if (p->iesc) {
+          blob_append(p->iblob, "~", 1);
+          p->iesc = 0;
+        }
+        p->iesc = !p->iesc;
+        p->icursor+=1;
+        break;
+
+      case '*':
+        cr_iMarkup(p, KIND_BOLD);
+        break;
+
+      case '/':
+        cr_iMarkup(p, KIND_ITALIC);
+        break;
+
+      case '^':
+        cr_iMarkup(p, KIND_SUPERSCRIPT);
+        break;
+
+      case ',':
+        cr_iMarkup(p, KIND_SUBSCRIPT);
+        break;
+
+      case '#':
+        cr_iMarkup(p, KIND_MONOSPACED);
+        break;
+
+      case '\\':
+        cr_iMarkup(p, KIND_BREAK);
+        break;
+
+      case '{':
+        if (cr_isEsc(p)) break;
+        if (cr_iNoWiki(p)) break;
+        if (cr_iImage(p)) break;
+        blob_append(p->iblob, p->icursor, 1);
+        p->icursor += 1;
+        break;
+
+      case '[':
+        if (cr_isEsc(p)) break;
+        if (cr_iLink(p)) break;
+        blob_append(p->iblob, p->icursor, 1);
+        p->icursor += 1;
+        break;
+
+
+      case '<':
+        if (cr_isEsc(p)) break;
+        if (cr_iMacro(p)) break;
+
+        blob_append(p->iblob, "&lt;", 4);
+        p->icursor += 1;
+        break;
+
+      case '>':
+        if (p->iesc) {
+          blob_append(p->iblob, "~", 1);
+          p->iesc = 0;
+        }
+        blob_append(p->iblob, "&gt;", 4);
+        p->icursor += 1;
+        break;
+
+      case '&':
+        if (p->iesc) {
+          blob_append(p->iblob, "~", 1);
+          p->iesc = 0;
+        }
+        blob_append(p->iblob, "&amp;", 5);
+        p->icursor += 1;
+        break;
+
+      case '|':
+        if (p->inTable){
+          if (p->iesc) {
+            blob_append(p->iblob, p->icursor, 1);
+            p->iesc = 0;
+            p->icursor += 1;
+            break;
+          }
+          eof = p->icursor + 1;
+          break;
+        }
+        // fall through to default
+
+      default:
+        if (p->iesc) {
+          blob_append(p->iblob, "~", 1);
+          p->iesc = 0;
+        }
+        blob_append(p->iblob, p->icursor, 1);
+        p->icursor +=1;
+    }//}}}
+
+  }
+
+  while (p->istack){
+    cr_iClose(p, p->istack->kind);
+    p->istack = p->istack->next;
+  }
+
+  p->iesc = save_iesc;
+  p->iend = save_iend;
+  p->istack = save_istack;
+
+  return eof;
 
 }
 //}}}
 //}}}
@@ -611,471 +612,454 @@
 
 static void cr_renderListItem(Parser *p, Node *n){//{{{
 
 
-	blob_append(p->iblob, "<li>", 4);
-	cr_parseInline(p, n->start, n->end);
-
-	if (n->children){
-
-		int ord = (n->children->kind & KIND_ORDERED_LIST);
-
-		if (ord) 	blob_append(p->iblob, "<ol>", 4);
-		else 			blob_append(p->iblob, "<ul>", 4);
-
-		n = n->children;
-		while (n){
-			cr_renderListItem(p, n);
-			n = n->next;
-		}
-
-		if (ord) 	blob_append(p->iblob, "</ol>", 5);
-		else 			blob_append(p->iblob, "</ul>", 5);
-	}
-	blob_append(p->iblob, "</li>", 5);
+  blob_append(p->iblob, "<li>", 4);
+  cr_parseInline(p, n->start, n->end);
+
+  if (n->children){
+
+    int ord = (n->children->kind & KIND_ORDERED_LIST);
+
+    if (ord)   blob_append(p->iblob, "<ol>", 4);
+    else       blob_append(p->iblob, "<ul>", 4);
+
+    n = n->children;
+    while (n){
+      cr_renderListItem(p, n);
+      n = n->next;
+    }
+
+    if (ord)   blob_append(p->iblob, "</ol>", 5);
+    else       blob_append(p->iblob, "</ul>", 5);
+  }
+  blob_append(p->iblob, "</li>", 5);
 }
 //}}}
 static void cr_renderList(Parser *p){//{{{
 
-	Node *n = p->list;
-
-	while (n->parent !=n)  n = n->parent;
-
-	int ord = (n->kind & KIND_ORDERED_LIST);
-
-	if (ord) 	blob_append(p->iblob, "\n\n<ol>", -1);
-	else 			blob_append(p->iblob, "\n\n<ul>", -1);
-
-	while (n) {
-		cr_renderListItem(p, n);
-		n = n->next;
-	}
-
-	if (ord) 	blob_append(p->iblob, "</ol>", 5);
-	else 			blob_append(p->iblob, "</ul>", 5);
+  Node *n = p->list;
+
+  while (n->parent !=n)  n = n->parent;
+
+  int ord = (n->kind & KIND_ORDERED_LIST);
+
+  if (ord)   blob_append(p->iblob, "\n\n<ol>", -1);
+  else       blob_append(p->iblob, "\n\n<ul>", -1);
+
+  while (n) {
+    cr_renderListItem(p, n);
+    n = n->next;
+  }
+
+  if (ord)   blob_append(p->iblob, "</ol>", 5);
+  else       blob_append(p->iblob, "</ul>", 5);
 }
 
 //}}}
 
 static void cr_renderTableRow(Parser *p, Node *row){//{{{
 
-	char *s = row->start;
-	int th;
-
-	blob_append(p->iblob, "\n<tr>", -1);
-
-	while (s && s < row->end){
-
-		if ((th = *s == '=')) {
-			s++;
-			blob_append(p->iblob, "<th>", -1);
-		}
-		else {
-			blob_append(p->iblob, "<td>", -1);
-		}
-
-		s = cr_parseInline(p, s, row->end);
-
-		if (th)
-			blob_append(p->iblob, "</th>\n", -1);
-		else
-			blob_append(p->iblob, "</td>\n", -1);
-
-		if (!s) break;
-	}
-	blob_append(p->iblob, "</tr>", 5);
+  char *s = row->start;
+  int th;
+
+  blob_append(p->iblob, "\n<tr>", -1);
+
+  while (s && s < row->end){
+
+    if ((th = *s == '=')) {
+      s++;
+      blob_append(p->iblob, "<th>", -1);
+    }
+    else {
+      blob_append(p->iblob, "<td>", -1);
+    }
+
+    s = cr_parseInline(p, s, row->end);
+
+    if (th)
+      blob_append(p->iblob, "</th>\n", -1);
+    else
+      blob_append(p->iblob, "</td>\n", -1);
+
+    if (!s) break;
+  }
+  blob_append(p->iblob, "</tr>", 5);
 }
 //}}}
 static void cr_renderTable(Parser *p, Node *n){//{{{
 
-	Node *row = n->children;
-
-	blob_append(p->iblob, "<table class='creoletable'>", -1);
-	p->inTable = 1;
-	while (row){
-
-		cr_renderTableRow(p, row);
-		row = row->next;
-
-	}
-	blob_append(p->iblob, "</table>", -1);
-	p->inTable = 0;
+  Node *row = n->children;
+
+  blob_append(p->iblob, "<table class='creoletable'>", -1);
+  p->inTable = 1;
+  while (row){
+
+    cr_renderTableRow(p, row);
+    row = row->next;
+
+  }
+  blob_append(p->iblob, "</table>", -1);
+  p->inTable = 0;
 
 }
 //}}}
 
 static void cr_render(Parser *p, Node *node){//{{{
 
-	if (node->kind & KIND_PARAGRAPH){
-		blob_append(p->iblob, 	"\n<p>", -1);
-		cr_parseInline(p, node->start, node->end );
-		blob_append(p->iblob, "</p>\n", -1	);
-	}
-
-	if (node->kind & KIND_HEADING){
-		blob_appendf(p->iblob,
-				"\n<h%d %s>",
-				node->level,
-				(node->flags & FLAG_CENTER) ? " style='text-align:center;'" : ""
-		);
-		cr_parseInline(p, node->start, node->end);
-		blob_appendf(p->iblob, "</h%d>\n", node->level	);
-		return;
-	}
-
-	if (node->kind & KIND_HORIZONTAL_RULE){
-		blob_append(p->iblob, "<hr />", -1);
-		return;
-	}
-
-	if (node->kind & KIND_LIST){
-		cr_renderList(p);
-		p->list = NULL;
-		return;
-	}
-
-	if (node->kind & KIND_TABLE){
-		cr_renderTable(p, node);
-		return;
-	}
-
-	if (node->kind & KIND_NO_WIKI_BLOCK){
-		blob_appendf(p->iblob,
-			"\n<blockquote style='background:oldlace'><pre>%s</pre></blockquote>\n",
-				htmlize( node->start, node->end - node->start)
-		);
-	}
+  if (node->kind & KIND_PARAGRAPH){
+    blob_append(p->iblob,   "\n<p>", -1);
+    cr_parseInline(p, node->start, node->end );
+    blob_append(p->iblob, "</p>\n", -1  );
+  }
+
+  if (node->kind & KIND_HEADING){
+    blob_appendf(p->iblob,
+        "\n<h%d %s>",
+        node->level,
+        (node->flags & FLAG_CENTER) ? " style='text-align:center;'" : ""
+    );
+    cr_parseInline(p, node->start, node->end);
+    blob_appendf(p->iblob, "</h%d>\n", node->level  );
+    return;
+  }
+
+  if (node->kind & KIND_HORIZONTAL_RULE){
+    blob_append(p->iblob, "<hr />", -1);
+    return;
+  }
+
+  if (node->kind & KIND_LIST){
+    cr_renderList(p);
+    p->list = NULL;
+    return;
+  }
+
+  if (node->kind & KIND_TABLE){
+    cr_renderTable(p, node);
+    return;
+  }
+
+  if (node->kind & KIND_NO_WIKI_BLOCK){
+    blob_appendf(p->iblob,
+      "\n<blockquote style='background:oldlace'><pre>%s</pre></blockquote>\n",
+        htmlize( node->start, node->end - node->start)
+    );
+  }
 }
 //}}}
 
 static char *cr_findEndOfBlock(Parser *p, char *s, char c){//{{{
 
-	char *end;
-	while (s[0]){
-
-		end = s;
-		if (s[0] == c && s[0] == c && s[0] == c) {
-			s = cr_nextLine(p, s + 3);
-			if (p->lineWasBlank) {
-					p->cursor = s;
-					return end;
-			}
-		}
-		else {
-			s = cr_nextLine(p, s);
-		}
-	}
-	return 0;
+  char *end;
+  while (s[0]){
+
+    end = s;
+    if (s[0] == c && s[0] == c && s[0] == c) {
+      s = cr_nextLine(p, s + 3);
+      if (p->lineWasBlank) {
+          p->cursor = s;
+          return end;
+      }
+    }
+    else {
+      s = cr_nextLine(p, s);
+    }
+  }
+  return 0;
 }
 //}}}
 static int cr_addListItem(Parser *p, Node *n){//{{{
 
-	n->parent = n;
-	n->next = n->children = NULL;
-
-	if (!p->list) {
-		if (n->level != 1) return 0;
-		p->list = n;
-		return 1;
-	}
-
-	Node *list = p->list;
-
-	while (n->level < list->level){
-		list = list->parent;
-	}
-
-	if (n->level == list->level){
-
-		if (n->kind != list->kind){
-			if (n->level>1) return 0;
-			cr_renderList(p);
-			p->list = n;
-			return 1;
-		}
-		n->parent = list->parent;
-		p->list = list->next = n;
-		return 1;
-	}
-
-	if ( (n->level - list->level) > 1 ) return 0;
-	n->parent = p->list;
-	p->list->children = n;
-	p->list = n;
-	return 1;
+  n->parent = n;
+  n->next = n->children = NULL;
+
+  if (!p->list) {
+    if (n->level != 1) return 0;
+    p->list = n;
+    return 1;
+  }
+
+  Node *list = p->list;
+
+  while (n->level < list->level){
+    list = list->parent;
+  }
+
+  if (n->level == list->level){
+
+    if (n->kind != list->kind){
+      if (n->level>1) return 0;
+      cr_renderList(p);
+      p->list = n;
+      return 1;
+    }
+    n->parent = list->parent;
+    p->list = list->next = n;
+    return 1;
+  }
+
+  if ( (n->level - list->level) > 1 ) return 0;
+  n->parent = p->list;
+  p->list->children = n;
+  p->list = n;
+  return 1;
 
 }
 //}}}
 
 static int isEndWikiMarker(Parser *p){//{{{
 
-	char *s = p->cursor;
-	if (memcmp(s, "<<fossil>>", 10)) return 0;
-	p->this->start = s;
-	p->this->kind = KIND_END_WIKI_MARKER;
-	p->cursor += 10;
-	return 1;
+  char *s = p->cursor;
+  if (memcmp(s, "<<fossil>>", 10)) return 0;
+  p->this->start = s;
+  p->this->kind = KIND_END_WIKI_MARKER;
+  p->cursor += 10;
+  return 1;
 }
 ///}}}
 static int isNoWikiBlock(Parser *p){//{{{
 
-	char *s = p->cursor;
-
-	if (s[0] != '{') return 0; s++;
-	if (s[0] != '{') return 0; s++;
-	if (s[0] != '{') return 0; s++;
-
-	s = cr_nextLine(p, s);
-	if (!p->lineWasBlank) return 0;
-
-	p->this->start = s;
-
-	s = cr_findEndOfBlock(p, s, '}');
-
-	if (!s) return 0;
-
-	// p->cursor was set by findEndOfBlock
-	p->this->kind = KIND_NO_WIKI_BLOCK;
-	p->this->end = s;
-	return 1;
+  char *s = p->cursor;
+
+  if (s[0] != '{') return 0; s++;
+  if (s[0] != '{') return 0; s++;
+  if (s[0] != '{') return 0; s++;
+
+  s = cr_nextLine(p, s);
+  if (!p->lineWasBlank) return 0;
+
+  p->this->start = s;
+
+  s = cr_findEndOfBlock(p, s, '}');
+
+  if (!s) return 0;
+
+  // p->cursor was set by findEndOfBlock
+  p->this->kind = KIND_NO_WIKI_BLOCK;
+  p->this->end = s;
+  return 1;
 }
 
 //}}}
 static int isParaBreak(Parser *p){//{{{
 
-	char *s = cr_nextLine(p, p->cursor);
-	if (!p->lineWasBlank) return 0;
-
-	p->cursor = s;
-	p->this->kind = KIND_PARA_BREAK;
-	return 1;
+  char *s = cr_nextLine(p, p->cursor);
+  if (!p->lineWasBlank) return 0;
+
+  p->cursor = s;
+  p->this->kind = KIND_PARA_BREAK;
+  return 1;
 }
 //}}}
 static int isHeading(Parser *p){//{{{
 
-	char *s = cr_skipBlanks(p, p->cursor);
-
-	int flags = 0;
-	int level = cr_countChars(p, s, '=');
-	if (!level) return 0;
-
-	s += level;
-
-	if (s[0] == '<' && s[1] == '>') {
-		flags |= FLAG_CENTER;
-		s += 2;
-	}
-	s = cr_skipBlanks(p, s);
-
-	p->this->start = s;
-
-	s = cr_nextLine(p, s);
-	char *z = s;
-
-	if (s[-1] == '\n') s--;
-	while(s[-1] == ' ' || s[-1]=='\t') s--;
-	while(s[-1] == '=' ) s--;
-	if (p->this->start < s){
-		p->cursor = z;
-		p->this->kind = KIND_HEADING;
-		p->this->end = s;
-		p->this->level = level;
-		p->this->flags |= flags;
-		return 1;
-	}
-	return 0;
+  char *s = cr_skipBlanks(p, p->cursor);
+
+  int flags = 0;
+  int level = cr_countChars(p, s, '=');
+  if (!level) return 0;
+
+  s += level;
+
+  if (s[0] == '<' && s[1] == '>') {
+    flags |= FLAG_CENTER;
+    s += 2;
+  }
+  s = cr_skipBlanks(p, s);
+
+  p->this->start = s;
+
+  s = cr_nextLine(p, s);
+  char *z = s;
+
+  if (s[-1] == '\n') s--;
+  while(s[-1] == ' ' || s[-1]=='\t') s--;
+  while(s[-1] == '=' ) s--;
+  if (p->this->start < s){
+    p->cursor = z;
+    p->this->kind = KIND_HEADING;
+    p->this->end = s;
+    p->this->level = level;
+    p->this->flags |= flags;
+    return 1;
+  }
+  return 0;
 }
 //}}}
 static int isHorizontalRule(Parser *p){//{{{
 
-	char *s = cr_skipBlanks(p, p->cursor);
-
-	int level = cr_countChars(p, s, '-');
-
-	if  (level < 4) return 0;
-	s = cr_nextLine(p, s + level);
-	if (!p->lineWasBlank) return 0;
-
-	p->cursor = s;
-	p->this->kind = KIND_HORIZONTAL_RULE;
-
-	return 1;
+  char *s = cr_skipBlanks(p, p->cursor);
+
+  int level = cr_countChars(p, s, '-');
+
+  if  (level < 4) return 0;
+  s = cr_nextLine(p, s + level);
+  if (!p->lineWasBlank) return 0;
+
+  p->cursor = s;
+  p->this->kind = KIND_HORIZONTAL_RULE;
+
+  return 1;
 }
 //}}}
 static int isListItem(Parser *p){//{{{
 
-	char *s = cr_skipBlanks(p, p->cursor);
-
-	int level = cr_countChars(p, s, '#');
-	if (!level) level = cr_countChars(p, s, '*');
-
-	if ( !level) return 0;
-
-	p->this->kind = (s[0] == '#') ? KIND_ORDERED_LIST : KIND_UNORDERED_LIST;
-	p->this->level = level;
-
-	s = cr_skipBlanks(p, s + level);
-	p->this->start = s;
-
-	s = cr_nextLine(p, s);
-	if (p->lineWasBlank) return 0;
-
-	if (cr_addListItem(p, p->this)){
-		p->cursor = p->this->end = s;
-		return 1;
-	}
-	p->this->kind = 0;
-	return 0;
+  char *s = cr_skipBlanks(p, p->cursor);
+
+  int level = cr_countChars(p, s, '#');
+  if (!level) level = cr_countChars(p, s, '*');
+
+  if ( !level) return 0;
+
+  p->this->kind = (s[0] == '#') ? KIND_ORDERED_LIST : KIND_UNORDERED_LIST;
+  p->this->level = level;
+
+  s = cr_skipBlanks(p, s + level);
+  p->this->start = s;
+
+  s = cr_nextLine(p, s);
+  if (p->lineWasBlank) return 0;
+
+  if (cr_addListItem(p, p->this)){
+    p->cursor = p->this->end = s;
+    return 1;
+  }
+  p->this->kind = 0;
+  return 0;
 }
 //}}}
 static int isTable(Parser *p){//{{{
 
-	p->this->start = p->cursor;
-	char *s = cr_skipBlanks(p, p->cursor);
-	if (s[0] != '|') return 0;
+  p->this->start = p->cursor;
+  char *s = cr_skipBlanks(p, p->cursor);
+  if (s[0] != '|') return 0;
   s +=1;
-	p->this->kind = KIND_TABLE;
-
-
-	//p->cursor = 	p->this->end = cr_nextLine(p, s);
-	Node *row;
-	Node *tail = NULL;
-
-	while (1) {
-
-		row = pool_new(p);
-		row->kind = KIND_TABLE_ROW;
-
-		if (tail) 	tail = tail->next = row;
-		else p->this->children = tail = row;
-
-		row->start = s;
-		p->cursor = s = 	row->end = p->this->end = cr_nextLine(p, s);
-
-		if (row->end[-1] == '\n') row->end -= 1;
-		while(row->end[-1] == ' ' ) row->end -= 1;
-		if (row->end[-1] == '|') row->end -= 1;
-
-		if (!*s) break;
-
-		// blanks *not* normalized
-		s = cr_skipBlanks(p, p->cursor);
-		if (s[0] != '|') break;
-		s++;
-
-	}
-	return 1;
+  p->this->kind = KIND_TABLE;
+
+
+  //p->cursor =   p->this->end = cr_nextLine(p, s);
+  Node *row;
+  Node *tail = NULL;
+
+  while (1) {
+
+    row = pool_new(p);
+    row->kind = KIND_TABLE_ROW;
+
+    if (tail)   tail = tail->next = row;
+    else p->this->children = tail = row;
+
+    row->start = s;
+    p->cursor = s =   row->end = p->this->end = cr_nextLine(p, s);
+
+    if (row->end[-1] == '\n') row->end -= 1;
+    while(row->end[-1] == ' ' ) row->end -= 1;
+    if (row->end[-1] == '|') row->end -= 1;
+
+    if (!*s) break;
+
+    // blanks *not* normalized
+    s = cr_skipBlanks(p, p->cursor);
+    if (s[0] != '|') break;
+    s++;
+
+  }
+  return 1;
 
 };
 //}}}
 static int isParagraph(Parser *p){//{{{
 
-	char *s = p->cursor;
-	p->this->start = s;
-
-	s = cr_nextLine(p, s);
-	p->cursor = p->this->end = s;
-	p->this->kind = KIND_PARAGRAPH;
-	return 1;
+  char *s = p->cursor;
+  p->this->start = s;
+
+  s = cr_nextLine(p, s);
+  p->cursor = p->this->end = s;
+  p->this->kind = KIND_PARAGRAPH;
+  return 1;
 
 }
 //}}}
 static void cr_parse(Parser *p, char* z){//{{{
 
-	p->previous = pool_new(p);
-	p->previous->kind = KIND_PARA_BREAK;
-
-	p->this = pool_new(p);
-	p->this->kind = KIND_PARA_BREAK;
-
-	p->inLink = 0;
-	p->inTable = 0;
-
-	p->cursor = z;
-	p->list = NULL;
-	p->istack = NULL;
-
-	while (p->cursor[0]) {
-
-		while (1){
-
-			// must be first
-			if (isNoWikiBlock(p)) break;
-			if (isParaBreak(p)) 	break;
-
-			// order not important
-			if (isHeading(p)) break;
-			if (isHorizontalRule(p)) break;
-			if (isListItem(p)) break;
-			if (isTable(p)) break;
-
-			// here for efficiency?
-			if (isEndWikiMarker(p)) break;
-
-			// must be last
-			if (isParagraph(p)); break;
+  p->previous = pool_new(p);
+  p->previous->kind = KIND_PARA_BREAK;
+
+  p->this = pool_new(p);
+  p->this->kind = KIND_PARA_BREAK;
+
+  p->inLink = 0;
+  p->inTable = 0;
+
+  p->cursor = z;
+  p->list = NULL;
+  p->istack = NULL;
+
+  while (p->cursor[0]) {
+
+    while (1){
+
+      // must be first
+      if (isNoWikiBlock(p)) break;
+      if (isParaBreak(p))   break;
+
+      // order not important
+      if (isHeading(p)) break;
+      if (isHorizontalRule(p)) break;
+      if (isListItem(p)) break;
+      if (isTable(p)) break;
+
+      // here for efficiency?
+      if (isEndWikiMarker(p)) break;
+
+      // must be last
+      if (isParagraph(p)); break;
+
+      // doh!
+      assert(0);
+    }
+
+    int kind = p->this->kind;
+    int prev = p->previous->kind;
+
+    if (kind & KIND_END_WIKI_MARKER)  return;
+
+    if (kind == KIND_PARAGRAPH && prev & KIND_LIST_OR_PARAGRAPH) {
+        p->previous->end = p->this->end;
+        p->this = pool_new(p);
+        continue;
+    }
+
+    if ( !(kind & KIND_LIST && prev & KIND_LIST) )
+      cr_render(p, p->previous);
+
+    p->previous = p->this;
+    p->this = pool_new(p);
 
-			// doh!
-		  assert(0);
-		}
-
-		int kind = p->this->kind;
-		int prev = p->previous->kind;
-
-		if (kind & KIND_END_WIKI_MARKER)	return;
-
-		if (kind == KIND_PARAGRAPH && prev & KIND_LIST_OR_PARAGRAPH) {
-				p->previous->end = p->this->end;
-				p->this = pool_new(p);
-				continue;
-		}
-
-		if ( !(kind & KIND_LIST && prev & KIND_LIST) )
-			cr_render(p, p->previous);
-
-		p->previous = p->this;
-		p->this = pool_new(p);
-
-	}
+  }
 }
 //}}}
 
 //}}}
 
-char *wiki_render_creole(Renderer *r, char *z){//{{{
+char *wiki_render_creole(Renderer *r, char *z){
 
   Parser parser;
-	Parser *p = &parser;
+  Parser *p = &parser;
+
+  p->r = r;
+  p->iblob = r->pOut;
+
+  p->nFree = 0;
+  p->pool = NULL;
 
-	p->r = r;
-	p->iblob = r->pOut;
+  cr_parse(p, z);
 
-	p->nFree = 0;
-	p->pool = NULL;
+  cr_render(p, p->previous);
 
-	cr_parse(p, z);
+  pool_free(p);
 
-	cr_render(p, p->previous);
-
-	pool_free(p);
-
-	return p->cursor;
+  return p->cursor;
 
 }
-//}}}
-
-
-char *wiki_render_macro(Renderer *p, char *z, int *tokenType){
-	if (!memcmp(z, "<<fossil>>", 9)){
-		*tokenType = 1;
-		return z + 10;
-	}
-	if (memcmp(z, "<<creole>>", 9)) {
-		*tokenType = 0;
-		return z;
-	}
-	*tokenType = 1;
-	return wiki_render_creole(p, z+10);
-
-}
-
-/* :folding=explicit:collapseFolds=1:tabSize=2:indentSize=2:noTabs=false: */
+