Fossil SCM

add wiki-contents macro to creole parser, plus minor bug fix

robert 2009-10-05 20:05 creole
Commit b99aa66d1f91abf5b01c793e5bbc7df2df98b0a0
1 file changed +102 -8
+102 -8
--- src/creoleparser.c
+++ src/creoleparser.c
@@ -58,14 +58,21 @@
5858
#define KIND_SUBSCRIPT 0x0002000
5959
#define KIND_MONOSPACED 0x0004000
6060
#define KIND_BREAK 0x0008000
6161
6262
#define KIND_TABLE_ROW 0x0010000
63
+#define KIND_MACRO 0X0020000
64
+//}}}
65
+//{{{ MACRO
66
+#define MACRO_NONE 0X0000000
67
+#define MACRO_FOSSIL 0x0000001
68
+#define MACRO_WIKI_CONTENTS 0X0000002
6369
//}}}
6470
//{{{ FLAG
65
-// keep first four bits free
66
-#define FLAG_CENTER 0x0000100
71
+// keep first four bits free (why?:)
72
+#define FLAG_CENTER 0x0000100
73
+#define FLAG_MACRO_BLOCK 0X0000200
6774
//}}}
6875
struct Node {//{{{
6976
7077
char *start;
7178
char *end;
@@ -110,13 +117,10 @@
110117
int inLink;
111118
int inTable;
112119
int iesc;
113120
114121
Blob *iblob;
115
-
116
-
117
-
118122
119123
};
120124
//}}}
121125
122126
#endif
@@ -199,11 +203,11 @@
199203
return z + 2;
200204
}
201205
z[0] = '\n';
202206
return z + 1;
203207
204
- case'\n':
208
+ case '\n':
205209
return z + 1;
206210
207211
case '\t':
208212
z[0] = ' ';
209213
z++;
@@ -222,10 +226,11 @@
222226
}
223227
}
224228
}
225229
//}}}
226230
//}}}
231
+
227232
228233
//{{{ INLINE PARSER
229234
230235
static int cr_isEsc(Parser *p){//{{{
231236
if (p->iesc){
@@ -359,11 +364,11 @@
359364
if (p->icursor[1]!='{' || p->icursor[2]!='{')
360365
return 0;
361366
362367
char *s = p->icursor + 3;
363368
364
- int count = p->iend - p->icursor - 6;
369
+ int count = p->iend - p->icursor - 3;
365370
while (count--){
366371
if (s[0]=='}' && s[1]=='}' && s[2]=='}' && s[3]!='}'){
367372
blob_appendf(p->iblob, "<tt class='creole-inline-nowiki'>%s</tt>", htmlize(p->icursor + 3, s - p->icursor-3));
368373
p->icursor = s + 3;
369374
return 1;
@@ -700,10 +705,23 @@
700705
blob_append(p->iblob, "</table>", -1);
701706
p->inTable = 0;
702707
703708
}
704709
//}}}
710
+
711
+static void cr_renderMacro(Parser *p, Node *n){//{{{
712
+
713
+ switch (n->level){
714
+
715
+ case MACRO_WIKI_CONTENTS:
716
+ do_macro_wiki_contents(p, n);
717
+ break;
718
+
719
+ }
720
+
721
+}
722
+//}}}
705723
706724
static void cr_render(Parser *p, Node *node){//{{{
707725
708726
if (node->kind & KIND_PARAGRAPH){
709727
blob_append(p->iblob, "\n<p>", -1);
@@ -719,10 +737,15 @@
719737
);
720738
cr_parseInline(p, node->start, node->end);
721739
blob_appendf(p->iblob, "</h%d>\n", node->level );
722740
return;
723741
}
742
+
743
+ if (node->kind & KIND_MACRO){
744
+ cr_renderMacro(p, node);
745
+ return;
746
+ }
724747
725748
if (node->kind & KIND_HORIZONTAL_RULE){
726749
blob_append(p->iblob, "<hr />", -1);
727750
return;
728751
}
@@ -813,11 +836,11 @@
813836
p->this->start = s;
814837
p->this->kind = KIND_END_WIKI_MARKER;
815838
p->cursor += 10;
816839
return 1;
817840
}
818
-///}}}
841
+//}}}
819842
static int isNoWikiBlock(Parser *p){//{{{
820843
821844
char *s = p->cursor;
822845
823846
if (s[0] != '{') return 0; s++;
@@ -847,10 +870,39 @@
847870
848871
p->cursor = s;
849872
p->this->kind = KIND_PARA_BREAK;
850873
return 1;
851874
}
875
+//}}}
876
+static int isMacro(Parser *p){//{{{
877
+
878
+ char *s = p->cursor;
879
+ int macroId;
880
+ int matchLength;
881
+
882
+ if (s[0]!='<') return 0; s++;
883
+ if (s[0]!='<') return 0; s++;
884
+ if (s[0]=='<') return 0;
885
+
886
+ matchLength = cr_has_macro(s, &macroId);
887
+ if (!matchLength) return 0;
888
+
889
+ s += matchLength;
890
+ p->this->start = s;
891
+
892
+ if (s[-1]!='>'){
893
+ while (s[0] && s[1] && s[0]!='\n' && !(s[0]=='>' && s[1]=='>')) s++;
894
+ if (!(s[0] == '>' && s[1] == '>')) return 0;
895
+ s +=2;
896
+ }
897
+ p->cursor = s;
898
+ p->this->kind = KIND_MACRO;
899
+ p->this->level = macroId;
900
+ p->this->flags &= FLAG_MACRO_BLOCK;
901
+ p->this->end = s-2;
902
+ return 1;
903
+}
852904
//}}}
853905
static int isHeading(Parser *p){//{{{
854906
855907
char *s = cr_skipBlanks(p, p->cursor);
856908
@@ -977,10 +1029,11 @@
9771029
p->this->kind = KIND_PARAGRAPH;
9781030
return 1;
9791031
9801032
}
9811033
//}}}
1034
+
9821035
static void cr_parse(Parser *p, char* z){//{{{
9831036
9841037
p->previous = pool_new(p);
9851038
p->previous->kind = KIND_PARA_BREAK;
9861039
@@ -1001,10 +1054,11 @@
10011054
// must be first
10021055
if (isNoWikiBlock(p)) break;
10031056
if (isParaBreak(p)) break;
10041057
10051058
// order not important
1059
+ if (isMacro(p)) break;
10061060
if (isHeading(p)) break;
10071061
if (isHorizontalRule(p)) break;
10081062
if (isListItem(p)) break;
10091063
if (isTable(p)) break;
10101064
@@ -1038,10 +1092,50 @@
10381092
}
10391093
}
10401094
//}}}
10411095
10421096
//}}}
1097
+
1098
+//{{{ MACROS
1099
+LOCAL void do_macro_wiki_contents(Parser *p, Node *n){//{{{
1100
+
1101
+ Stmt q;
1102
+
1103
+ blob_append(p->iblob, "<ul>", 4);
1104
+
1105
+ db_prepare(&q,
1106
+ "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname GLOB 'wiki-*'"
1107
+ " ORDER BY lower(tagname)"
1108
+ );
1109
+ while( db_step(&q)==SQLITE_ROW ){
1110
+ const char *zName = db_column_text(&q, 0);
1111
+ blob_appendf(p->iblob, "<li><a href=\"%s/wiki?name=%T\">%h</a></li>", g.zBaseURL, zName, zName);
1112
+ }
1113
+ db_finalize(&q);
1114
+ blob_append(p->iblob, "</ul>", 5);
1115
+}//}}}
1116
+
1117
+
1118
+static int cr_match(char *z1, char *z2, int *len){
1119
+ *len = strlen(z2);
1120
+ return !memcmp(z1, z2 ,*len);
1121
+}
1122
+
1123
+int cr_has_macro(char *z, int *tokenType){
1124
+
1125
+ int len;
1126
+
1127
+ if (cr_match(z, "wiki-contents>>", &len)) {
1128
+ *tokenType = MACRO_WIKI_CONTENTS;
1129
+ return len;
1130
+ }
1131
+
1132
+ tokenType = MACRO_NONE;
1133
+ return 0;
1134
+
1135
+}
1136
+//}}}
10431137
10441138
char *wiki_render_creole(Renderer *r, char *z){
10451139
10461140
Parser parser;
10471141
Parser *p = &parser;
10481142
--- src/creoleparser.c
+++ src/creoleparser.c
@@ -58,14 +58,21 @@
58 #define KIND_SUBSCRIPT 0x0002000
59 #define KIND_MONOSPACED 0x0004000
60 #define KIND_BREAK 0x0008000
61
62 #define KIND_TABLE_ROW 0x0010000
 
 
 
 
 
 
63 //}}}
64 //{{{ FLAG
65 // keep first four bits free
66 #define FLAG_CENTER 0x0000100
 
67 //}}}
68 struct Node {//{{{
69
70 char *start;
71 char *end;
@@ -110,13 +117,10 @@
110 int inLink;
111 int inTable;
112 int iesc;
113
114 Blob *iblob;
115
116
117
118
119 };
120 //}}}
121
122 #endif
@@ -199,11 +203,11 @@
199 return z + 2;
200 }
201 z[0] = '\n';
202 return z + 1;
203
204 case'\n':
205 return z + 1;
206
207 case '\t':
208 z[0] = ' ';
209 z++;
@@ -222,10 +226,11 @@
222 }
223 }
224 }
225 //}}}
226 //}}}
 
227
228 //{{{ INLINE PARSER
229
230 static int cr_isEsc(Parser *p){//{{{
231 if (p->iesc){
@@ -359,11 +364,11 @@
359 if (p->icursor[1]!='{' || p->icursor[2]!='{')
360 return 0;
361
362 char *s = p->icursor + 3;
363
364 int count = p->iend - p->icursor - 6;
365 while (count--){
366 if (s[0]=='}' && s[1]=='}' && s[2]=='}' && s[3]!='}'){
367 blob_appendf(p->iblob, "<tt class='creole-inline-nowiki'>%s</tt>", htmlize(p->icursor + 3, s - p->icursor-3));
368 p->icursor = s + 3;
369 return 1;
@@ -700,10 +705,23 @@
700 blob_append(p->iblob, "</table>", -1);
701 p->inTable = 0;
702
703 }
704 //}}}
 
 
 
 
 
 
 
 
 
 
 
 
 
705
706 static void cr_render(Parser *p, Node *node){//{{{
707
708 if (node->kind & KIND_PARAGRAPH){
709 blob_append(p->iblob, "\n<p>", -1);
@@ -719,10 +737,15 @@
719 );
720 cr_parseInline(p, node->start, node->end);
721 blob_appendf(p->iblob, "</h%d>\n", node->level );
722 return;
723 }
 
 
 
 
 
724
725 if (node->kind & KIND_HORIZONTAL_RULE){
726 blob_append(p->iblob, "<hr />", -1);
727 return;
728 }
@@ -813,11 +836,11 @@
813 p->this->start = s;
814 p->this->kind = KIND_END_WIKI_MARKER;
815 p->cursor += 10;
816 return 1;
817 }
818 ///}}}
819 static int isNoWikiBlock(Parser *p){//{{{
820
821 char *s = p->cursor;
822
823 if (s[0] != '{') return 0; s++;
@@ -847,10 +870,39 @@
847
848 p->cursor = s;
849 p->this->kind = KIND_PARA_BREAK;
850 return 1;
851 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
852 //}}}
853 static int isHeading(Parser *p){//{{{
854
855 char *s = cr_skipBlanks(p, p->cursor);
856
@@ -977,10 +1029,11 @@
977 p->this->kind = KIND_PARAGRAPH;
978 return 1;
979
980 }
981 //}}}
 
982 static void cr_parse(Parser *p, char* z){//{{{
983
984 p->previous = pool_new(p);
985 p->previous->kind = KIND_PARA_BREAK;
986
@@ -1001,10 +1054,11 @@
1001 // must be first
1002 if (isNoWikiBlock(p)) break;
1003 if (isParaBreak(p)) break;
1004
1005 // order not important
 
1006 if (isHeading(p)) break;
1007 if (isHorizontalRule(p)) break;
1008 if (isListItem(p)) break;
1009 if (isTable(p)) break;
1010
@@ -1038,10 +1092,50 @@
1038 }
1039 }
1040 //}}}
1041
1042 //}}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1043
1044 char *wiki_render_creole(Renderer *r, char *z){
1045
1046 Parser parser;
1047 Parser *p = &parser;
1048
--- src/creoleparser.c
+++ src/creoleparser.c
@@ -58,14 +58,21 @@
58 #define KIND_SUBSCRIPT 0x0002000
59 #define KIND_MONOSPACED 0x0004000
60 #define KIND_BREAK 0x0008000
61
62 #define KIND_TABLE_ROW 0x0010000
63 #define KIND_MACRO 0X0020000
64 //}}}
65 //{{{ MACRO
66 #define MACRO_NONE 0X0000000
67 #define MACRO_FOSSIL 0x0000001
68 #define MACRO_WIKI_CONTENTS 0X0000002
69 //}}}
70 //{{{ FLAG
71 // keep first four bits free (why?:)
72 #define FLAG_CENTER 0x0000100
73 #define FLAG_MACRO_BLOCK 0X0000200
74 //}}}
75 struct Node {//{{{
76
77 char *start;
78 char *end;
@@ -110,13 +117,10 @@
117 int inLink;
118 int inTable;
119 int iesc;
120
121 Blob *iblob;
 
 
 
122
123 };
124 //}}}
125
126 #endif
@@ -199,11 +203,11 @@
203 return z + 2;
204 }
205 z[0] = '\n';
206 return z + 1;
207
208 case '\n':
209 return z + 1;
210
211 case '\t':
212 z[0] = ' ';
213 z++;
@@ -222,10 +226,11 @@
226 }
227 }
228 }
229 //}}}
230 //}}}
231
232
233 //{{{ INLINE PARSER
234
235 static int cr_isEsc(Parser *p){//{{{
236 if (p->iesc){
@@ -359,11 +364,11 @@
364 if (p->icursor[1]!='{' || p->icursor[2]!='{')
365 return 0;
366
367 char *s = p->icursor + 3;
368
369 int count = p->iend - p->icursor - 3;
370 while (count--){
371 if (s[0]=='}' && s[1]=='}' && s[2]=='}' && s[3]!='}'){
372 blob_appendf(p->iblob, "<tt class='creole-inline-nowiki'>%s</tt>", htmlize(p->icursor + 3, s - p->icursor-3));
373 p->icursor = s + 3;
374 return 1;
@@ -700,10 +705,23 @@
705 blob_append(p->iblob, "</table>", -1);
706 p->inTable = 0;
707
708 }
709 //}}}
710
711 static void cr_renderMacro(Parser *p, Node *n){//{{{
712
713 switch (n->level){
714
715 case MACRO_WIKI_CONTENTS:
716 do_macro_wiki_contents(p, n);
717 break;
718
719 }
720
721 }
722 //}}}
723
724 static void cr_render(Parser *p, Node *node){//{{{
725
726 if (node->kind & KIND_PARAGRAPH){
727 blob_append(p->iblob, "\n<p>", -1);
@@ -719,10 +737,15 @@
737 );
738 cr_parseInline(p, node->start, node->end);
739 blob_appendf(p->iblob, "</h%d>\n", node->level );
740 return;
741 }
742
743 if (node->kind & KIND_MACRO){
744 cr_renderMacro(p, node);
745 return;
746 }
747
748 if (node->kind & KIND_HORIZONTAL_RULE){
749 blob_append(p->iblob, "<hr />", -1);
750 return;
751 }
@@ -813,11 +836,11 @@
836 p->this->start = s;
837 p->this->kind = KIND_END_WIKI_MARKER;
838 p->cursor += 10;
839 return 1;
840 }
841 //}}}
842 static int isNoWikiBlock(Parser *p){//{{{
843
844 char *s = p->cursor;
845
846 if (s[0] != '{') return 0; s++;
@@ -847,10 +870,39 @@
870
871 p->cursor = s;
872 p->this->kind = KIND_PARA_BREAK;
873 return 1;
874 }
875 //}}}
876 static int isMacro(Parser *p){//{{{
877
878 char *s = p->cursor;
879 int macroId;
880 int matchLength;
881
882 if (s[0]!='<') return 0; s++;
883 if (s[0]!='<') return 0; s++;
884 if (s[0]=='<') return 0;
885
886 matchLength = cr_has_macro(s, &macroId);
887 if (!matchLength) return 0;
888
889 s += matchLength;
890 p->this->start = s;
891
892 if (s[-1]!='>'){
893 while (s[0] && s[1] && s[0]!='\n' && !(s[0]=='>' && s[1]=='>')) s++;
894 if (!(s[0] == '>' && s[1] == '>')) return 0;
895 s +=2;
896 }
897 p->cursor = s;
898 p->this->kind = KIND_MACRO;
899 p->this->level = macroId;
900 p->this->flags &= FLAG_MACRO_BLOCK;
901 p->this->end = s-2;
902 return 1;
903 }
904 //}}}
905 static int isHeading(Parser *p){//{{{
906
907 char *s = cr_skipBlanks(p, p->cursor);
908
@@ -977,10 +1029,11 @@
1029 p->this->kind = KIND_PARAGRAPH;
1030 return 1;
1031
1032 }
1033 //}}}
1034
1035 static void cr_parse(Parser *p, char* z){//{{{
1036
1037 p->previous = pool_new(p);
1038 p->previous->kind = KIND_PARA_BREAK;
1039
@@ -1001,10 +1054,11 @@
1054 // must be first
1055 if (isNoWikiBlock(p)) break;
1056 if (isParaBreak(p)) break;
1057
1058 // order not important
1059 if (isMacro(p)) break;
1060 if (isHeading(p)) break;
1061 if (isHorizontalRule(p)) break;
1062 if (isListItem(p)) break;
1063 if (isTable(p)) break;
1064
@@ -1038,10 +1092,50 @@
1092 }
1093 }
1094 //}}}
1095
1096 //}}}
1097
1098 //{{{ MACROS
1099 LOCAL void do_macro_wiki_contents(Parser *p, Node *n){//{{{
1100
1101 Stmt q;
1102
1103 blob_append(p->iblob, "<ul>", 4);
1104
1105 db_prepare(&q,
1106 "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname GLOB 'wiki-*'"
1107 " ORDER BY lower(tagname)"
1108 );
1109 while( db_step(&q)==SQLITE_ROW ){
1110 const char *zName = db_column_text(&q, 0);
1111 blob_appendf(p->iblob, "<li><a href=\"%s/wiki?name=%T\">%h</a></li>", g.zBaseURL, zName, zName);
1112 }
1113 db_finalize(&q);
1114 blob_append(p->iblob, "</ul>", 5);
1115 }//}}}
1116
1117
1118 static int cr_match(char *z1, char *z2, int *len){
1119 *len = strlen(z2);
1120 return !memcmp(z1, z2 ,*len);
1121 }
1122
1123 int cr_has_macro(char *z, int *tokenType){
1124
1125 int len;
1126
1127 if (cr_match(z, "wiki-contents>>", &len)) {
1128 *tokenType = MACRO_WIKI_CONTENTS;
1129 return len;
1130 }
1131
1132 tokenType = MACRO_NONE;
1133 return 0;
1134
1135 }
1136 //}}}
1137
1138 char *wiki_render_creole(Renderer *r, char *z){
1139
1140 Parser parser;
1141 Parser *p = &parser;
1142

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button