Fossil SCM

Experimental - Pass < !-- --> comments through the wiki unchanged unless inside a < verbatim > block in which case it is htmlized. Also pass <span> tags, treating them as font markup. These changes make it easier to convert existing html pages and specifically allow the inclusion of license text in pages derived from copyright material.

robert 2009-04-27 08:43 trunk
Commit 47cc9dfec89c25da28bfa9ee9cfe749e31c6f04c
1 file changed +75 -39
+75 -39
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -7,11 +7,11 @@
77
**
88
** This program is distributed in the hope that it will be useful,
99
** but WITHOUT ANY WARRANTY; without even the implied warranty of
1010
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1111
** General Public License for more details.
12
-**
12
+**
1313
** You should have received a copy of the GNU General Public
1414
** License along with this library; if not, write to the
1515
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1616
** Boston, MA 02111-1307, USA.
1717
**
@@ -150,11 +150,11 @@
150150
/*
151151
** Allowed markup.
152152
**
153153
** Except for MARKUP_INVALID, this must all be in alphabetical order
154154
** and in numerical sequence. The first markup type must be zero.
155
-** The value for MARKUP_XYZ must correspond to the <xyz> entry
155
+** The value for MARKUP_XYZ must correspond to the <xyz> entry
156156
** in aAllowedMarkup[].
157157
*/
158158
#define MARKUP_INVALID 0
159159
#define MARKUP_A 1
160160
#define MARKUP_ADDRESS 2
@@ -189,23 +189,24 @@
189189
#define MARKUP_P 31
190190
#define MARKUP_PRE 32
191191
#define MARKUP_S 33
192192
#define MARKUP_SAMP 34
193193
#define MARKUP_SMALL 35
194
-#define MARKUP_STRIKE 36
195
-#define MARKUP_STRONG 37
196
-#define MARKUP_SUB 38
197
-#define MARKUP_SUP 39
198
-#define MARKUP_TABLE 40
199
-#define MARKUP_TD 41
200
-#define MARKUP_TH 42
201
-#define MARKUP_TR 43
202
-#define MARKUP_TT 44
203
-#define MARKUP_U 45
204
-#define MARKUP_UL 46
205
-#define MARKUP_VAR 47
206
-#define MARKUP_VERBATIM 48
194
+#define MARKUP_SPAN 36
195
+#define MARKUP_STRIKE 37
196
+#define MARKUP_STRONG 38
197
+#define MARKUP_SUB 39
198
+#define MARKUP_SUP 40
199
+#define MARKUP_TABLE 41
200
+#define MARKUP_TD 42
201
+#define MARKUP_TH 43
202
+#define MARKUP_TR 44
203
+#define MARKUP_TT 45
204
+#define MARKUP_U 46
205
+#define MARKUP_UL 47
206
+#define MARKUP_VAR 48
207
+#define MARKUP_VERBATIM 49
207208
208209
/*
209210
** The various markup is divided into the following types:
210211
*/
211212
#define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -258,46 +259,47 @@
258259
{ "h2", MARKUP_H2, MUTYPE_BLOCK, AMSK_ALIGN },
259260
{ "h3", MARKUP_H3, MUTYPE_BLOCK, AMSK_ALIGN },
260261
{ "h4", MARKUP_H4, MUTYPE_BLOCK, AMSK_ALIGN },
261262
{ "h5", MARKUP_H5, MUTYPE_BLOCK, AMSK_ALIGN },
262263
{ "h6", MARKUP_H6, MUTYPE_BLOCK, AMSK_ALIGN },
263
- { "hr", MARKUP_HR, MUTYPE_SINGLE,
264
+ { "hr", MARKUP_HR, MUTYPE_SINGLE,
264265
AMSK_ALIGN|AMSK_COLOR|AMSK_SIZE|AMSK_WIDTH },
265266
{ "i", MARKUP_I, MUTYPE_FONT, 0 },
266
- { "img", MARKUP_IMG, MUTYPE_SINGLE,
267
+ { "img", MARKUP_IMG, MUTYPE_SINGLE,
267268
AMSK_ALIGN|AMSK_ALT|AMSK_BORDER|AMSK_HEIGHT|
268269
AMSK_HSPACE|AMSK_SRC|AMSK_VSPACE|AMSK_WIDTH },
269270
{ "kbd", MARKUP_KBD, MUTYPE_FONT, 0 },
270
- { "li", MARKUP_LI, MUTYPE_LI,
271
+ { "li", MARKUP_LI, MUTYPE_LI,
271272
AMSK_TYPE|AMSK_VALUE },
272273
{ "nobr", MARKUP_NOBR, MUTYPE_FONT, 0 },
273274
{ "nowiki", MARKUP_NOWIKI, MUTYPE_SPECIAL, 0 },
274
- { "ol", MARKUP_OL, MUTYPE_LIST,
275
+ { "ol", MARKUP_OL, MUTYPE_LIST,
275276
AMSK_START|AMSK_TYPE|AMSK_COMPACT },
276277
{ "p", MARKUP_P, MUTYPE_BLOCK, AMSK_ALIGN },
277278
{ "pre", MARKUP_PRE, MUTYPE_BLOCK, 0 },
278279
{ "s", MARKUP_S, MUTYPE_FONT, 0 },
279280
{ "samp", MARKUP_SAMP, MUTYPE_FONT, 0 },
280281
{ "small", MARKUP_SMALL, MUTYPE_FONT, 0 },
282
+ { "span", MARKUP_SPAN, MUTYPE_FONT, 0 },
281283
{ "strike", MARKUP_STRIKE, MUTYPE_FONT, 0 },
282284
{ "strong", MARKUP_STRONG, MUTYPE_FONT, 0 },
283285
{ "sub", MARKUP_SUB, MUTYPE_FONT, 0 },
284286
{ "sup", MARKUP_SUP, MUTYPE_FONT, 0 },
285
- { "table", MARKUP_TABLE, MUTYPE_TABLE,
287
+ { "table", MARKUP_TABLE, MUTYPE_TABLE,
286288
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_BORDER|AMSK_CELLPADDING|
287289
AMSK_CELLSPACING|AMSK_HSPACE|AMSK_VSPACE },
288
- { "td", MARKUP_TD, MUTYPE_TD,
290
+ { "td", MARKUP_TD, MUTYPE_TD,
289291
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
290292
AMSK_ROWSPAN|AMSK_VALIGN },
291293
{ "th", MARKUP_TH, MUTYPE_TD,
292294
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
293295
AMSK_ROWSPAN|AMSK_VALIGN },
294
- { "tr", MARKUP_TR, MUTYPE_TR,
296
+ { "tr", MARKUP_TR, MUTYPE_TR,
295297
AMSK_ALIGN|AMSK_BGCOLOR||AMSK_VALIGN },
296298
{ "tt", MARKUP_TT, MUTYPE_FONT, 0 },
297299
{ "u", MARKUP_U, MUTYPE_FONT, 0 },
298
- { "ul", MARKUP_UL, MUTYPE_LIST,
300
+ { "ul", MARKUP_UL, MUTYPE_LIST,
299301
AMSK_TYPE|AMSK_COMPACT },
300302
{ "var", MARKUP_VAR, MUTYPE_FONT, 0 },
301303
{ "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, AMSK_ID },
302304
};
303305
@@ -332,11 +334,12 @@
332334
#define TOKEN_PARAGRAPH 4 /* blank lines */
333335
#define TOKEN_NEWLINE 5 /* A single "\n" */
334336
#define TOKEN_BULLET 6 /* " * " */
335337
#define TOKEN_ENUM 7 /* " \(?\d+[.)]? " */
336338
#define TOKEN_INDENT 8 /* " " */
337
-#define TOKEN_TEXT 9 /* None of the above */
339
+#define TOKEN_COMMENT 9 /* <!-- --> */
340
+#define TOKEN_TEXT 10 /* None of the above */
338341
339342
/*
340343
** State flags
341344
*/
342345
#define AT_NEWLINE 0x001 /* At start of a line */
@@ -376,10 +379,28 @@
376379
** it is not well-formed markup, return 0.
377380
*/
378381
static int markupLength(const char *z){
379382
int n = 1;
380383
int inparen = 0;
384
+
385
+ // is a comment - if valid return n else return 0
386
+ if( z[n]=='!' ){
387
+ n++;
388
+ if (z[n]!='-') return 0;
389
+ n++;
390
+ if (z[n]!='-') return 0;
391
+ n++;
392
+ while (z[n]){
393
+ while (z[n] && z[n]!='>') n++;
394
+ if (!z[n]) return 0;
395
+ n++;
396
+ if(n>3 && z[n-3]=='-' && z[n-2]=='-')
397
+ return (n>7) ? n : 0;
398
+ }
399
+ return 0;
400
+ }
401
+
381402
if( z[n]=='/' ){ n++; }
382403
if( !isalpha(z[n]) ) return 0;
383404
while( isalnum(z[n]) ){ n++; }
384405
if( z[n]!='>' && !isspace(z[n]) ) return 0;
385406
while( z[n] && (z[n]!='>' || inparen) ){
@@ -433,11 +454,11 @@
433454
while( (c = z[0])!=0 && c!='<' && c!='&' &&
434455
(useWiki==0 || (c!='[' && c!='\n')) ){
435456
n++;
436457
z++;
437458
}
438
- return n;
459
+ return n;
439460
}
440461
441462
/*
442463
** Return true if z[] begins with an HTML character element.
443464
*/
@@ -554,13 +575,19 @@
554575
*/
555576
static int nextToken(const char *z, Renderer *p, int *pTokenType){
556577
int n;
557578
if( z[0]=='<' ){
558579
n = markupLength(z);
559
- if( n>0 ){
560
- *pTokenType = TOKEN_MARKUP;
561
- return n;
580
+
581
+ if( n>1 ){
582
+ if (z[1]=='!'){
583
+ *pTokenType = TOKEN_COMMENT;
584
+ return n;
585
+ } else {
586
+ *pTokenType = TOKEN_MARKUP;
587
+ return n;
588
+ }
562589
}else{
563590
*pTokenType = TOKEN_CHARACTER;
564591
return 1;
565592
}
566593
}
@@ -626,11 +653,11 @@
626653
627654
/*
628655
** z[] is an HTML markup element - something that begins with '<'.
629656
** Parse this element into the p structure.
630657
**
631
-** The content of z[] might be modified by converting characters
658
+** The content of z[] might be modified by converting characters
632659
** to lowercase and by inserting some "\000" characters.
633660
*/
634661
static void parseMarkup(ParsedMarkup *p, char *z){
635662
int i, j, c;
636663
int iACode;
@@ -644,11 +671,11 @@
644671
}else{
645672
p->endTag = 0;
646673
i = 1;
647674
}
648675
j = 0;
649
- while( isalnum(z[i]) ){
676
+ while( isalnum(z[i]) ){
650677
if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
651678
i++;
652679
}
653680
zTag[j] = 0;
654681
p->iCode = findTag(zTag);
@@ -656,11 +683,11 @@
656683
p->nAttr = 0;
657684
while( isspace(z[i]) ){ i++; }
658685
while( p->nAttr<8 && isalpha(z[i]) ){
659686
int attrOk; /* True to preserver attribute. False to ignore it */
660687
j = 0;
661
- while( isalnum(z[i]) ){
688
+ while( isalnum(z[i]) ){
662689
if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
663690
i++;
664691
}
665692
zTag[j] = 0;
666693
p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
@@ -799,11 +826,11 @@
799826
}
800827
}
801828
802829
/*
803830
** Attempt to find a find a tag of type iTag with id zId. Return -1
804
-** if not found. If found, return its stack level.
831
+** if not found. If found, return its stack level.
805832
*/
806833
static int findTagWithId(Renderer *p, int iTag, const char *zId){
807834
int i;
808835
assert( zId!=0 );
809836
for(i=p->nStack-1; i>=0; i--){
@@ -889,11 +916,11 @@
889916
canonical16(zLower, n+1);
890917
memcpy(zUpper, zLower, n+1);
891918
zUpper[n-1]++;
892919
if( once ){
893920
const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
894
- db_static_prepare(&q,
921
+ db_static_prepare(&q,
895922
"SELECT %s FROM ticket "
896923
" WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
897924
zClosedExpr
898925
);
899926
once = 0;
@@ -927,13 +954,13 @@
927954
int nClose /* Bytes available in zClose[] */
928955
){
929956
const char *zTerm = "</a>";
930957
assert( nClose>10 );
931958
932
- if( strncmp(zTarget, "http:", 5)==0
959
+ if( strncmp(zTarget, "http:", 5)==0
933960
|| strncmp(zTarget, "https:", 6)==0
934
- || strncmp(zTarget, "ftp:", 4)==0
961
+ || strncmp(zTarget, "ftp:", 4)==0
935962
|| strncmp(zTarget, "mailto:", 7)==0
936963
){
937964
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
938965
}else if( zTarget[0]=='/' ){
939966
if( 1 /* g.okHistory */ ){
@@ -1022,10 +1049,19 @@
10221049
10231050
while( z[0] ){
10241051
n = nextToken(z, p, &tokenType);
10251052
p->state &= ~(AT_NEWLINE|AT_PARAGRAPH);
10261053
switch( tokenType ){
1054
+
1055
+ case TOKEN_COMMENT: {
1056
+ if (p->inVerbatim){
1057
+ blob_append(p->pOut, htmlize(z, n), -1);
1058
+ } else {
1059
+ blob_append(p->pOut, z, n);
1060
+ }
1061
+ break;
1062
+ }
10271063
case TOKEN_PARAGRAPH: {
10281064
if( inlineOnly ){
10291065
/* blob_append(p->pOut, " &para; ", -1); */
10301066
blob_append(p->pOut, " &nbsp;&nbsp; ", -1);
10311067
}else{
@@ -1143,11 +1179,11 @@
11431179
int iDiv;
11441180
parseMarkup(&markup, z);
11451181
11461182
/* Markup of the form </div id=ID> where there is a matching
11471183
** ID somewhere on the stack. Exit the verbatim if were are in
1148
- ** it. Pop the stack up to the matching <div>. Discard the
1184
+ ** it. Pop the stack up to the matching <div>. Discard the
11491185
** </div>
11501186
*/
11511187
if( markup.iCode==MARKUP_DIV && markup.endTag &&
11521188
(zId = markupId(&markup))!=0 &&
11531189
(iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
@@ -1167,11 +1203,11 @@
11671203
p->nStack--;
11681204
}else
11691205
11701206
/* If within <verbatim id=ID> ignore everything other than
11711207
** </verbatim id=ID> and the </dev id=ID2> above.
1172
- */
1208
+ */
11731209
if( p->inVerbatim ){
11741210
if( endVerbatim(p, &markup) ){
11751211
p->inVerbatim = 0;
11761212
p->state = p->preVerbState;
11771213
blob_append(p->pOut, "</pre>", 6);
@@ -1225,11 +1261,11 @@
12251261
(p->state & ALLOW_WIKI)!=0);
12261262
}else
12271263
12281264
/* Enter <verbatim> processing. With verbatim enabled, all other
12291265
** markup other than the corresponding end-tag with the same ID is
1230
- ** ignored.
1266
+ ** ignored.
12311267
*/
12321268
if( markup.iCode==MARKUP_VERBATIM ){
12331269
if( markup.nAttr==1 ){
12341270
p->zVerbatimId = markup.aAttr[0].zValue;
12351271
}else{
@@ -1298,11 +1334,11 @@
12981334
** reply.
12991335
*/
13001336
void wiki_convert(Blob *pIn, Blob *pOut, int flags){
13011337
char *z;
13021338
Renderer renderer;
1303
-
1339
+
13041340
memset(&renderer, 0, sizeof(renderer));
13051341
renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
13061342
if( flags & WIKI_NOBLOCK ){
13071343
renderer.state |= INLINE_MARKUP_ONLY;
13081344
}
13091345
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -7,11 +7,11 @@
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 ** General Public License for more details.
12 **
13 ** You should have received a copy of the GNU General Public
14 ** License along with this library; if not, write to the
15 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 ** Boston, MA 02111-1307, USA.
17 **
@@ -150,11 +150,11 @@
150 /*
151 ** Allowed markup.
152 **
153 ** Except for MARKUP_INVALID, this must all be in alphabetical order
154 ** and in numerical sequence. The first markup type must be zero.
155 ** The value for MARKUP_XYZ must correspond to the <xyz> entry
156 ** in aAllowedMarkup[].
157 */
158 #define MARKUP_INVALID 0
159 #define MARKUP_A 1
160 #define MARKUP_ADDRESS 2
@@ -189,23 +189,24 @@
189 #define MARKUP_P 31
190 #define MARKUP_PRE 32
191 #define MARKUP_S 33
192 #define MARKUP_SAMP 34
193 #define MARKUP_SMALL 35
194 #define MARKUP_STRIKE 36
195 #define MARKUP_STRONG 37
196 #define MARKUP_SUB 38
197 #define MARKUP_SUP 39
198 #define MARKUP_TABLE 40
199 #define MARKUP_TD 41
200 #define MARKUP_TH 42
201 #define MARKUP_TR 43
202 #define MARKUP_TT 44
203 #define MARKUP_U 45
204 #define MARKUP_UL 46
205 #define MARKUP_VAR 47
206 #define MARKUP_VERBATIM 48
 
207
208 /*
209 ** The various markup is divided into the following types:
210 */
211 #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -258,46 +259,47 @@
258 { "h2", MARKUP_H2, MUTYPE_BLOCK, AMSK_ALIGN },
259 { "h3", MARKUP_H3, MUTYPE_BLOCK, AMSK_ALIGN },
260 { "h4", MARKUP_H4, MUTYPE_BLOCK, AMSK_ALIGN },
261 { "h5", MARKUP_H5, MUTYPE_BLOCK, AMSK_ALIGN },
262 { "h6", MARKUP_H6, MUTYPE_BLOCK, AMSK_ALIGN },
263 { "hr", MARKUP_HR, MUTYPE_SINGLE,
264 AMSK_ALIGN|AMSK_COLOR|AMSK_SIZE|AMSK_WIDTH },
265 { "i", MARKUP_I, MUTYPE_FONT, 0 },
266 { "img", MARKUP_IMG, MUTYPE_SINGLE,
267 AMSK_ALIGN|AMSK_ALT|AMSK_BORDER|AMSK_HEIGHT|
268 AMSK_HSPACE|AMSK_SRC|AMSK_VSPACE|AMSK_WIDTH },
269 { "kbd", MARKUP_KBD, MUTYPE_FONT, 0 },
270 { "li", MARKUP_LI, MUTYPE_LI,
271 AMSK_TYPE|AMSK_VALUE },
272 { "nobr", MARKUP_NOBR, MUTYPE_FONT, 0 },
273 { "nowiki", MARKUP_NOWIKI, MUTYPE_SPECIAL, 0 },
274 { "ol", MARKUP_OL, MUTYPE_LIST,
275 AMSK_START|AMSK_TYPE|AMSK_COMPACT },
276 { "p", MARKUP_P, MUTYPE_BLOCK, AMSK_ALIGN },
277 { "pre", MARKUP_PRE, MUTYPE_BLOCK, 0 },
278 { "s", MARKUP_S, MUTYPE_FONT, 0 },
279 { "samp", MARKUP_SAMP, MUTYPE_FONT, 0 },
280 { "small", MARKUP_SMALL, MUTYPE_FONT, 0 },
 
281 { "strike", MARKUP_STRIKE, MUTYPE_FONT, 0 },
282 { "strong", MARKUP_STRONG, MUTYPE_FONT, 0 },
283 { "sub", MARKUP_SUB, MUTYPE_FONT, 0 },
284 { "sup", MARKUP_SUP, MUTYPE_FONT, 0 },
285 { "table", MARKUP_TABLE, MUTYPE_TABLE,
286 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_BORDER|AMSK_CELLPADDING|
287 AMSK_CELLSPACING|AMSK_HSPACE|AMSK_VSPACE },
288 { "td", MARKUP_TD, MUTYPE_TD,
289 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
290 AMSK_ROWSPAN|AMSK_VALIGN },
291 { "th", MARKUP_TH, MUTYPE_TD,
292 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
293 AMSK_ROWSPAN|AMSK_VALIGN },
294 { "tr", MARKUP_TR, MUTYPE_TR,
295 AMSK_ALIGN|AMSK_BGCOLOR||AMSK_VALIGN },
296 { "tt", MARKUP_TT, MUTYPE_FONT, 0 },
297 { "u", MARKUP_U, MUTYPE_FONT, 0 },
298 { "ul", MARKUP_UL, MUTYPE_LIST,
299 AMSK_TYPE|AMSK_COMPACT },
300 { "var", MARKUP_VAR, MUTYPE_FONT, 0 },
301 { "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, AMSK_ID },
302 };
303
@@ -332,11 +334,12 @@
332 #define TOKEN_PARAGRAPH 4 /* blank lines */
333 #define TOKEN_NEWLINE 5 /* A single "\n" */
334 #define TOKEN_BULLET 6 /* " * " */
335 #define TOKEN_ENUM 7 /* " \(?\d+[.)]? " */
336 #define TOKEN_INDENT 8 /* " " */
337 #define TOKEN_TEXT 9 /* None of the above */
 
338
339 /*
340 ** State flags
341 */
342 #define AT_NEWLINE 0x001 /* At start of a line */
@@ -376,10 +379,28 @@
376 ** it is not well-formed markup, return 0.
377 */
378 static int markupLength(const char *z){
379 int n = 1;
380 int inparen = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381 if( z[n]=='/' ){ n++; }
382 if( !isalpha(z[n]) ) return 0;
383 while( isalnum(z[n]) ){ n++; }
384 if( z[n]!='>' && !isspace(z[n]) ) return 0;
385 while( z[n] && (z[n]!='>' || inparen) ){
@@ -433,11 +454,11 @@
433 while( (c = z[0])!=0 && c!='<' && c!='&' &&
434 (useWiki==0 || (c!='[' && c!='\n')) ){
435 n++;
436 z++;
437 }
438 return n;
439 }
440
441 /*
442 ** Return true if z[] begins with an HTML character element.
443 */
@@ -554,13 +575,19 @@
554 */
555 static int nextToken(const char *z, Renderer *p, int *pTokenType){
556 int n;
557 if( z[0]=='<' ){
558 n = markupLength(z);
559 if( n>0 ){
560 *pTokenType = TOKEN_MARKUP;
561 return n;
 
 
 
 
 
 
562 }else{
563 *pTokenType = TOKEN_CHARACTER;
564 return 1;
565 }
566 }
@@ -626,11 +653,11 @@
626
627 /*
628 ** z[] is an HTML markup element - something that begins with '<'.
629 ** Parse this element into the p structure.
630 **
631 ** The content of z[] might be modified by converting characters
632 ** to lowercase and by inserting some "\000" characters.
633 */
634 static void parseMarkup(ParsedMarkup *p, char *z){
635 int i, j, c;
636 int iACode;
@@ -644,11 +671,11 @@
644 }else{
645 p->endTag = 0;
646 i = 1;
647 }
648 j = 0;
649 while( isalnum(z[i]) ){
650 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
651 i++;
652 }
653 zTag[j] = 0;
654 p->iCode = findTag(zTag);
@@ -656,11 +683,11 @@
656 p->nAttr = 0;
657 while( isspace(z[i]) ){ i++; }
658 while( p->nAttr<8 && isalpha(z[i]) ){
659 int attrOk; /* True to preserver attribute. False to ignore it */
660 j = 0;
661 while( isalnum(z[i]) ){
662 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
663 i++;
664 }
665 zTag[j] = 0;
666 p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
@@ -799,11 +826,11 @@
799 }
800 }
801
802 /*
803 ** Attempt to find a find a tag of type iTag with id zId. Return -1
804 ** if not found. If found, return its stack level.
805 */
806 static int findTagWithId(Renderer *p, int iTag, const char *zId){
807 int i;
808 assert( zId!=0 );
809 for(i=p->nStack-1; i>=0; i--){
@@ -889,11 +916,11 @@
889 canonical16(zLower, n+1);
890 memcpy(zUpper, zLower, n+1);
891 zUpper[n-1]++;
892 if( once ){
893 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
894 db_static_prepare(&q,
895 "SELECT %s FROM ticket "
896 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
897 zClosedExpr
898 );
899 once = 0;
@@ -927,13 +954,13 @@
927 int nClose /* Bytes available in zClose[] */
928 ){
929 const char *zTerm = "</a>";
930 assert( nClose>10 );
931
932 if( strncmp(zTarget, "http:", 5)==0
933 || strncmp(zTarget, "https:", 6)==0
934 || strncmp(zTarget, "ftp:", 4)==0
935 || strncmp(zTarget, "mailto:", 7)==0
936 ){
937 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
938 }else if( zTarget[0]=='/' ){
939 if( 1 /* g.okHistory */ ){
@@ -1022,10 +1049,19 @@
1022
1023 while( z[0] ){
1024 n = nextToken(z, p, &tokenType);
1025 p->state &= ~(AT_NEWLINE|AT_PARAGRAPH);
1026 switch( tokenType ){
 
 
 
 
 
 
 
 
 
1027 case TOKEN_PARAGRAPH: {
1028 if( inlineOnly ){
1029 /* blob_append(p->pOut, " &para; ", -1); */
1030 blob_append(p->pOut, " &nbsp;&nbsp; ", -1);
1031 }else{
@@ -1143,11 +1179,11 @@
1143 int iDiv;
1144 parseMarkup(&markup, z);
1145
1146 /* Markup of the form </div id=ID> where there is a matching
1147 ** ID somewhere on the stack. Exit the verbatim if were are in
1148 ** it. Pop the stack up to the matching <div>. Discard the
1149 ** </div>
1150 */
1151 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1152 (zId = markupId(&markup))!=0 &&
1153 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
@@ -1167,11 +1203,11 @@
1167 p->nStack--;
1168 }else
1169
1170 /* If within <verbatim id=ID> ignore everything other than
1171 ** </verbatim id=ID> and the </dev id=ID2> above.
1172 */
1173 if( p->inVerbatim ){
1174 if( endVerbatim(p, &markup) ){
1175 p->inVerbatim = 0;
1176 p->state = p->preVerbState;
1177 blob_append(p->pOut, "</pre>", 6);
@@ -1225,11 +1261,11 @@
1225 (p->state & ALLOW_WIKI)!=0);
1226 }else
1227
1228 /* Enter <verbatim> processing. With verbatim enabled, all other
1229 ** markup other than the corresponding end-tag with the same ID is
1230 ** ignored.
1231 */
1232 if( markup.iCode==MARKUP_VERBATIM ){
1233 if( markup.nAttr==1 ){
1234 p->zVerbatimId = markup.aAttr[0].zValue;
1235 }else{
@@ -1298,11 +1334,11 @@
1298 ** reply.
1299 */
1300 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1301 char *z;
1302 Renderer renderer;
1303
1304 memset(&renderer, 0, sizeof(renderer));
1305 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
1306 if( flags & WIKI_NOBLOCK ){
1307 renderer.state |= INLINE_MARKUP_ONLY;
1308 }
1309
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -7,11 +7,11 @@
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 ** General Public License for more details.
12 **
13 ** You should have received a copy of the GNU General Public
14 ** License along with this library; if not, write to the
15 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 ** Boston, MA 02111-1307, USA.
17 **
@@ -150,11 +150,11 @@
150 /*
151 ** Allowed markup.
152 **
153 ** Except for MARKUP_INVALID, this must all be in alphabetical order
154 ** and in numerical sequence. The first markup type must be zero.
155 ** The value for MARKUP_XYZ must correspond to the <xyz> entry
156 ** in aAllowedMarkup[].
157 */
158 #define MARKUP_INVALID 0
159 #define MARKUP_A 1
160 #define MARKUP_ADDRESS 2
@@ -189,23 +189,24 @@
189 #define MARKUP_P 31
190 #define MARKUP_PRE 32
191 #define MARKUP_S 33
192 #define MARKUP_SAMP 34
193 #define MARKUP_SMALL 35
194 #define MARKUP_SPAN 36
195 #define MARKUP_STRIKE 37
196 #define MARKUP_STRONG 38
197 #define MARKUP_SUB 39
198 #define MARKUP_SUP 40
199 #define MARKUP_TABLE 41
200 #define MARKUP_TD 42
201 #define MARKUP_TH 43
202 #define MARKUP_TR 44
203 #define MARKUP_TT 45
204 #define MARKUP_U 46
205 #define MARKUP_UL 47
206 #define MARKUP_VAR 48
207 #define MARKUP_VERBATIM 49
208
209 /*
210 ** The various markup is divided into the following types:
211 */
212 #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */
@@ -258,46 +259,47 @@
259 { "h2", MARKUP_H2, MUTYPE_BLOCK, AMSK_ALIGN },
260 { "h3", MARKUP_H3, MUTYPE_BLOCK, AMSK_ALIGN },
261 { "h4", MARKUP_H4, MUTYPE_BLOCK, AMSK_ALIGN },
262 { "h5", MARKUP_H5, MUTYPE_BLOCK, AMSK_ALIGN },
263 { "h6", MARKUP_H6, MUTYPE_BLOCK, AMSK_ALIGN },
264 { "hr", MARKUP_HR, MUTYPE_SINGLE,
265 AMSK_ALIGN|AMSK_COLOR|AMSK_SIZE|AMSK_WIDTH },
266 { "i", MARKUP_I, MUTYPE_FONT, 0 },
267 { "img", MARKUP_IMG, MUTYPE_SINGLE,
268 AMSK_ALIGN|AMSK_ALT|AMSK_BORDER|AMSK_HEIGHT|
269 AMSK_HSPACE|AMSK_SRC|AMSK_VSPACE|AMSK_WIDTH },
270 { "kbd", MARKUP_KBD, MUTYPE_FONT, 0 },
271 { "li", MARKUP_LI, MUTYPE_LI,
272 AMSK_TYPE|AMSK_VALUE },
273 { "nobr", MARKUP_NOBR, MUTYPE_FONT, 0 },
274 { "nowiki", MARKUP_NOWIKI, MUTYPE_SPECIAL, 0 },
275 { "ol", MARKUP_OL, MUTYPE_LIST,
276 AMSK_START|AMSK_TYPE|AMSK_COMPACT },
277 { "p", MARKUP_P, MUTYPE_BLOCK, AMSK_ALIGN },
278 { "pre", MARKUP_PRE, MUTYPE_BLOCK, 0 },
279 { "s", MARKUP_S, MUTYPE_FONT, 0 },
280 { "samp", MARKUP_SAMP, MUTYPE_FONT, 0 },
281 { "small", MARKUP_SMALL, MUTYPE_FONT, 0 },
282 { "span", MARKUP_SPAN, MUTYPE_FONT, 0 },
283 { "strike", MARKUP_STRIKE, MUTYPE_FONT, 0 },
284 { "strong", MARKUP_STRONG, MUTYPE_FONT, 0 },
285 { "sub", MARKUP_SUB, MUTYPE_FONT, 0 },
286 { "sup", MARKUP_SUP, MUTYPE_FONT, 0 },
287 { "table", MARKUP_TABLE, MUTYPE_TABLE,
288 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_BORDER|AMSK_CELLPADDING|
289 AMSK_CELLSPACING|AMSK_HSPACE|AMSK_VSPACE },
290 { "td", MARKUP_TD, MUTYPE_TD,
291 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
292 AMSK_ROWSPAN|AMSK_VALIGN },
293 { "th", MARKUP_TH, MUTYPE_TD,
294 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
295 AMSK_ROWSPAN|AMSK_VALIGN },
296 { "tr", MARKUP_TR, MUTYPE_TR,
297 AMSK_ALIGN|AMSK_BGCOLOR||AMSK_VALIGN },
298 { "tt", MARKUP_TT, MUTYPE_FONT, 0 },
299 { "u", MARKUP_U, MUTYPE_FONT, 0 },
300 { "ul", MARKUP_UL, MUTYPE_LIST,
301 AMSK_TYPE|AMSK_COMPACT },
302 { "var", MARKUP_VAR, MUTYPE_FONT, 0 },
303 { "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, AMSK_ID },
304 };
305
@@ -332,11 +334,12 @@
334 #define TOKEN_PARAGRAPH 4 /* blank lines */
335 #define TOKEN_NEWLINE 5 /* A single "\n" */
336 #define TOKEN_BULLET 6 /* " * " */
337 #define TOKEN_ENUM 7 /* " \(?\d+[.)]? " */
338 #define TOKEN_INDENT 8 /* " " */
339 #define TOKEN_COMMENT 9 /* <!-- --> */
340 #define TOKEN_TEXT 10 /* None of the above */
341
342 /*
343 ** State flags
344 */
345 #define AT_NEWLINE 0x001 /* At start of a line */
@@ -376,10 +379,28 @@
379 ** it is not well-formed markup, return 0.
380 */
381 static int markupLength(const char *z){
382 int n = 1;
383 int inparen = 0;
384
385 // is a comment - if valid return n else return 0
386 if( z[n]=='!' ){
387 n++;
388 if (z[n]!='-') return 0;
389 n++;
390 if (z[n]!='-') return 0;
391 n++;
392 while (z[n]){
393 while (z[n] && z[n]!='>') n++;
394 if (!z[n]) return 0;
395 n++;
396 if(n>3 && z[n-3]=='-' && z[n-2]=='-')
397 return (n>7) ? n : 0;
398 }
399 return 0;
400 }
401
402 if( z[n]=='/' ){ n++; }
403 if( !isalpha(z[n]) ) return 0;
404 while( isalnum(z[n]) ){ n++; }
405 if( z[n]!='>' && !isspace(z[n]) ) return 0;
406 while( z[n] && (z[n]!='>' || inparen) ){
@@ -433,11 +454,11 @@
454 while( (c = z[0])!=0 && c!='<' && c!='&' &&
455 (useWiki==0 || (c!='[' && c!='\n')) ){
456 n++;
457 z++;
458 }
459 return n;
460 }
461
462 /*
463 ** Return true if z[] begins with an HTML character element.
464 */
@@ -554,13 +575,19 @@
575 */
576 static int nextToken(const char *z, Renderer *p, int *pTokenType){
577 int n;
578 if( z[0]=='<' ){
579 n = markupLength(z);
580
581 if( n>1 ){
582 if (z[1]=='!'){
583 *pTokenType = TOKEN_COMMENT;
584 return n;
585 } else {
586 *pTokenType = TOKEN_MARKUP;
587 return n;
588 }
589 }else{
590 *pTokenType = TOKEN_CHARACTER;
591 return 1;
592 }
593 }
@@ -626,11 +653,11 @@
653
654 /*
655 ** z[] is an HTML markup element - something that begins with '<'.
656 ** Parse this element into the p structure.
657 **
658 ** The content of z[] might be modified by converting characters
659 ** to lowercase and by inserting some "\000" characters.
660 */
661 static void parseMarkup(ParsedMarkup *p, char *z){
662 int i, j, c;
663 int iACode;
@@ -644,11 +671,11 @@
671 }else{
672 p->endTag = 0;
673 i = 1;
674 }
675 j = 0;
676 while( isalnum(z[i]) ){
677 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
678 i++;
679 }
680 zTag[j] = 0;
681 p->iCode = findTag(zTag);
@@ -656,11 +683,11 @@
683 p->nAttr = 0;
684 while( isspace(z[i]) ){ i++; }
685 while( p->nAttr<8 && isalpha(z[i]) ){
686 int attrOk; /* True to preserver attribute. False to ignore it */
687 j = 0;
688 while( isalnum(z[i]) ){
689 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
690 i++;
691 }
692 zTag[j] = 0;
693 p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
@@ -799,11 +826,11 @@
826 }
827 }
828
829 /*
830 ** Attempt to find a find a tag of type iTag with id zId. Return -1
831 ** if not found. If found, return its stack level.
832 */
833 static int findTagWithId(Renderer *p, int iTag, const char *zId){
834 int i;
835 assert( zId!=0 );
836 for(i=p->nStack-1; i>=0; i--){
@@ -889,11 +916,11 @@
916 canonical16(zLower, n+1);
917 memcpy(zUpper, zLower, n+1);
918 zUpper[n-1]++;
919 if( once ){
920 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
921 db_static_prepare(&q,
922 "SELECT %s FROM ticket "
923 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
924 zClosedExpr
925 );
926 once = 0;
@@ -927,13 +954,13 @@
954 int nClose /* Bytes available in zClose[] */
955 ){
956 const char *zTerm = "</a>";
957 assert( nClose>10 );
958
959 if( strncmp(zTarget, "http:", 5)==0
960 || strncmp(zTarget, "https:", 6)==0
961 || strncmp(zTarget, "ftp:", 4)==0
962 || strncmp(zTarget, "mailto:", 7)==0
963 ){
964 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
965 }else if( zTarget[0]=='/' ){
966 if( 1 /* g.okHistory */ ){
@@ -1022,10 +1049,19 @@
1049
1050 while( z[0] ){
1051 n = nextToken(z, p, &tokenType);
1052 p->state &= ~(AT_NEWLINE|AT_PARAGRAPH);
1053 switch( tokenType ){
1054
1055 case TOKEN_COMMENT: {
1056 if (p->inVerbatim){
1057 blob_append(p->pOut, htmlize(z, n), -1);
1058 } else {
1059 blob_append(p->pOut, z, n);
1060 }
1061 break;
1062 }
1063 case TOKEN_PARAGRAPH: {
1064 if( inlineOnly ){
1065 /* blob_append(p->pOut, " &para; ", -1); */
1066 blob_append(p->pOut, " &nbsp;&nbsp; ", -1);
1067 }else{
@@ -1143,11 +1179,11 @@
1179 int iDiv;
1180 parseMarkup(&markup, z);
1181
1182 /* Markup of the form </div id=ID> where there is a matching
1183 ** ID somewhere on the stack. Exit the verbatim if were are in
1184 ** it. Pop the stack up to the matching <div>. Discard the
1185 ** </div>
1186 */
1187 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1188 (zId = markupId(&markup))!=0 &&
1189 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
@@ -1167,11 +1203,11 @@
1203 p->nStack--;
1204 }else
1205
1206 /* If within <verbatim id=ID> ignore everything other than
1207 ** </verbatim id=ID> and the </dev id=ID2> above.
1208 */
1209 if( p->inVerbatim ){
1210 if( endVerbatim(p, &markup) ){
1211 p->inVerbatim = 0;
1212 p->state = p->preVerbState;
1213 blob_append(p->pOut, "</pre>", 6);
@@ -1225,11 +1261,11 @@
1261 (p->state & ALLOW_WIKI)!=0);
1262 }else
1263
1264 /* Enter <verbatim> processing. With verbatim enabled, all other
1265 ** markup other than the corresponding end-tag with the same ID is
1266 ** ignored.
1267 */
1268 if( markup.iCode==MARKUP_VERBATIM ){
1269 if( markup.nAttr==1 ){
1270 p->zVerbatimId = markup.aAttr[0].zValue;
1271 }else{
@@ -1298,11 +1334,11 @@
1334 ** reply.
1335 */
1336 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1337 char *z;
1338 Renderer renderer;
1339
1340 memset(&renderer, 0, sizeof(renderer));
1341 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
1342 if( flags & WIKI_NOBLOCK ){
1343 renderer.state |= INLINE_MARKUP_ONLY;
1344 }
1345

Keyboard Shortcuts

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