@@ -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, "<", 4);
- p->icursor += 1;
- break;
-
- case '>':
- if (p->iesc) {
- blob_append(p->iblob, "~", 1);
- p->iesc = 0;
- }
- blob_append(p->iblob, ">", 4);
- p->icursor += 1;
- break;
-
- case '&':
- if (p->iesc) {
- blob_append(p->iblob, "~", 1);
- p->iesc = 0;
- }
- blob_append(p->iblob, "&", 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, "<", 4);
+ p->icursor += 1;
+ break;
+
+ case '>':
+ if (p->iesc) {
+ blob_append(p->iblob, "~", 1);
+ p->iesc = 0;
+ }
+ blob_append(p->iblob, ">", 4);
+ p->icursor += 1;
+ break;
+
+ case '&':
+ if (p->iesc) {
+ blob_append(p->iblob, "~", 1);
+ p->iesc = 0;
+ }
+ blob_append(p->iblob, "&", 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: */
+