Fossil SCM

Allow the type= attribute on the verbatim wiki tag. This attribute does not pass right through. If found, it is treated as the 'Language Type' and alters the output of the verbatim tag slightly. <verbatim type='cpp'> would render as <pre name='code' class='cpp'>. This allows JavaScript tools such as SyntaxHighlighter to function properly for any language.

jeremy_c 2010-03-03 13:52 trunk
Commit 63d31b0448b3d25b559f6c0e840318c26d2c90f4
1 file changed +39 -32
+39 -32
--- 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
@@ -258,22 +258,22 @@
258258
{ "h2", MARKUP_H2, MUTYPE_BLOCK, AMSK_ALIGN },
259259
{ "h3", MARKUP_H3, MUTYPE_BLOCK, AMSK_ALIGN },
260260
{ "h4", MARKUP_H4, MUTYPE_BLOCK, AMSK_ALIGN },
261261
{ "h5", MARKUP_H5, MUTYPE_BLOCK, AMSK_ALIGN },
262262
{ "h6", MARKUP_H6, MUTYPE_BLOCK, AMSK_ALIGN },
263
- { "hr", MARKUP_HR, MUTYPE_SINGLE,
263
+ { "hr", MARKUP_HR, MUTYPE_SINGLE,
264264
AMSK_ALIGN|AMSK_COLOR|AMSK_SIZE|AMSK_WIDTH },
265265
{ "i", MARKUP_I, MUTYPE_FONT, 0 },
266
- { "img", MARKUP_IMG, MUTYPE_SINGLE,
266
+ { "img", MARKUP_IMG, MUTYPE_SINGLE,
267267
AMSK_ALIGN|AMSK_ALT|AMSK_BORDER|AMSK_HEIGHT|
268268
AMSK_HSPACE|AMSK_SRC|AMSK_VSPACE|AMSK_WIDTH },
269269
{ "kbd", MARKUP_KBD, MUTYPE_FONT, 0 },
270
- { "li", MARKUP_LI, MUTYPE_LI,
270
+ { "li", MARKUP_LI, MUTYPE_LI,
271271
AMSK_TYPE|AMSK_VALUE },
272272
{ "nobr", MARKUP_NOBR, MUTYPE_FONT, 0 },
273273
{ "nowiki", MARKUP_NOWIKI, MUTYPE_SPECIAL, 0 },
274
- { "ol", MARKUP_OL, MUTYPE_LIST,
274
+ { "ol", MARKUP_OL, MUTYPE_LIST,
275275
AMSK_START|AMSK_TYPE|AMSK_COMPACT },
276276
{ "p", MARKUP_P, MUTYPE_BLOCK, AMSK_ALIGN },
277277
{ "pre", MARKUP_PRE, MUTYPE_BLOCK, 0 },
278278
{ "s", MARKUP_S, MUTYPE_FONT, 0 },
279279
{ "samp", MARKUP_SAMP, MUTYPE_FONT, 0 },
@@ -280,27 +280,27 @@
280280
{ "small", MARKUP_SMALL, MUTYPE_FONT, 0 },
281281
{ "strike", MARKUP_STRIKE, MUTYPE_FONT, 0 },
282282
{ "strong", MARKUP_STRONG, MUTYPE_FONT, 0 },
283283
{ "sub", MARKUP_SUB, MUTYPE_FONT, 0 },
284284
{ "sup", MARKUP_SUP, MUTYPE_FONT, 0 },
285
- { "table", MARKUP_TABLE, MUTYPE_TABLE,
285
+ { "table", MARKUP_TABLE, MUTYPE_TABLE,
286286
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_BORDER|AMSK_CELLPADDING|
287287
AMSK_CELLSPACING|AMSK_HSPACE|AMSK_VSPACE },
288
- { "td", MARKUP_TD, MUTYPE_TD,
288
+ { "td", MARKUP_TD, MUTYPE_TD,
289289
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
290290
AMSK_ROWSPAN|AMSK_VALIGN },
291291
{ "th", MARKUP_TH, MUTYPE_TD,
292292
AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN|
293293
AMSK_ROWSPAN|AMSK_VALIGN },
294
- { "tr", MARKUP_TR, MUTYPE_TR,
294
+ { "tr", MARKUP_TR, MUTYPE_TR,
295295
AMSK_ALIGN|AMSK_BGCOLOR||AMSK_VALIGN },
296296
{ "tt", MARKUP_TT, MUTYPE_FONT, 0 },
297297
{ "u", MARKUP_U, MUTYPE_FONT, 0 },
298
- { "ul", MARKUP_UL, MUTYPE_LIST,
298
+ { "ul", MARKUP_UL, MUTYPE_LIST,
299299
AMSK_TYPE|AMSK_COMPACT },
300300
{ "var", MARKUP_VAR, MUTYPE_FONT, 0 },
301
- { "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, AMSK_ID },
301
+ { "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, AMSK_ID|AMSK_TYPE },
302302
};
303303
304304
/*
305305
** Use binary search to locate a tag in the aMarkup[] table.
306306
*/
@@ -436,11 +436,11 @@
436436
while( (c = z[0])!=0 && c!='<' && c!='&' &&
437437
(useWiki==0 || (c!='[' && c!='\n')) ){
438438
n++;
439439
z++;
440440
}
441
- return n;
441
+ return n;
442442
}
443443
444444
/*
445445
** Return true if z[] begins with an HTML character element.
446446
*/
@@ -550,11 +550,11 @@
550550
}
551551
}
552552
553553
/*
554554
** Get the next wiki token.
555
-**
555
+**
556556
** z points to the start of a token. Return the number of
557557
** characters in that token. Write the token type into *pTokenType.
558558
*/
559559
static int nextWikiToken(const char *z, Renderer *p, int *pTokenType){
560560
int n;
@@ -616,11 +616,11 @@
616616
return 1 + textLength(z+1, p->state & ALLOW_WIKI);
617617
}
618618
619619
/*
620620
** Parse only Wiki links, return everything else as TOKEN_RAW.
621
-**
621
+**
622622
** z points to the start of a token. Return the number of
623623
** characters in that token. Write the token type into *pTokenType.
624624
*/
625625
626626
static int nextRawToken(const char *z, Renderer *p, int *pTokenType){
@@ -652,11 +652,11 @@
652652
653653
/*
654654
** z[] is an HTML markup element - something that begins with '<'.
655655
** Parse this element into the p structure.
656656
**
657
-** The content of z[] might be modified by converting characters
657
+** The content of z[] might be modified by converting characters
658658
** to lowercase and by inserting some "\000" characters.
659659
*/
660660
static void parseMarkup(ParsedMarkup *p, char *z){
661661
int i, j, c;
662662
int iACode;
@@ -670,11 +670,11 @@
670670
}else{
671671
p->endTag = 0;
672672
i = 1;
673673
}
674674
j = 0;
675
- while( isalnum(z[i]) ){
675
+ while( isalnum(z[i]) ){
676676
if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
677677
i++;
678678
}
679679
zTag[j] = 0;
680680
p->iCode = findTag(zTag);
@@ -682,11 +682,11 @@
682682
p->nAttr = 0;
683683
while( isspace(z[i]) ){ i++; }
684684
while( p->nAttr<8 && isalpha(z[i]) ){
685685
int attrOk; /* True to preserver attribute. False to ignore it */
686686
j = 0;
687
- while( isalnum(z[i]) ){
687
+ while( isalnum(z[i]) ){
688688
if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
689689
i++;
690690
}
691691
zTag[j] = 0;
692692
p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
@@ -825,11 +825,11 @@
825825
}
826826
}
827827
828828
/*
829829
** Attempt to find a find a tag of type iTag with id zId. Return -1
830
-** if not found. If found, return its stack level.
830
+** if not found. If found, return its stack level.
831831
*/
832832
static int findTagWithId(Renderer *p, int iTag, const char *zId){
833833
int i;
834834
assert( zId!=0 );
835835
for(i=p->nStack-1; i>=0; i--){
@@ -915,11 +915,11 @@
915915
canonical16(zLower, n+1);
916916
memcpy(zUpper, zLower, n+1);
917917
zUpper[n-1]++;
918918
if( once ){
919919
const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
920
- db_static_prepare(&q,
920
+ db_static_prepare(&q,
921921
"SELECT %s FROM ticket "
922922
" WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
923923
zClosedExpr
924924
);
925925
once = 0;
@@ -970,13 +970,13 @@
970970
int nClose /* Bytes available in zClose[] */
971971
){
972972
const char *zTerm = "</a>";
973973
assert( nClose>=20 );
974974
975
- if( strncmp(zTarget, "http:", 5)==0
975
+ if( strncmp(zTarget, "http:", 5)==0
976976
|| strncmp(zTarget, "https:", 6)==0
977
- || strncmp(zTarget, "ftp:", 4)==0
977
+ || strncmp(zTarget, "ftp:", 4)==0
978978
|| strncmp(zTarget, "mailto:", 7)==0
979979
){
980980
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
981981
/* zTerm = "&#x27FE;</a>"; // doesn't work on windows */
982982
}else if( zTarget[0]=='/' ){
@@ -1218,11 +1218,11 @@
12181218
int iDiv;
12191219
parseMarkup(&markup, z);
12201220
12211221
/* Markup of the form </div id=ID> where there is a matching
12221222
** ID somewhere on the stack. Exit the verbatim if were are in
1223
- ** it. Pop the stack up to the matching <div>. Discard the
1223
+ ** it. Pop the stack up to the matching <div>. Discard the
12241224
** </div>
12251225
*/
12261226
if( markup.iCode==MARKUP_DIV && markup.endTag &&
12271227
(zId = markupId(&markup))!=0 &&
12281228
(iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
@@ -1242,11 +1242,11 @@
12421242
p->nStack--;
12431243
}else
12441244
12451245
/* If within <verbatim id=ID> ignore everything other than
12461246
** </verbatim id=ID> and the </dev id=ID2> above.
1247
- */
1247
+ */
12481248
if( p->inVerbatim ){
12491249
if( endVerbatim(p, &markup) ){
12501250
p->inVerbatim = 0;
12511251
p->state = p->preVerbState;
12521252
blob_append(p->pOut, "</pre>", 6);
@@ -1300,22 +1300,29 @@
13001300
(p->state & ALLOW_WIKI)!=0);
13011301
}else
13021302
13031303
/* Enter <verbatim> processing. With verbatim enabled, all other
13041304
** markup other than the corresponding end-tag with the same ID is
1305
- ** ignored.
1305
+ ** ignored.
13061306
*/
13071307
if( markup.iCode==MARKUP_VERBATIM ){
1308
- if( markup.nAttr==1 ){
1309
- p->zVerbatimId = markup.aAttr[0].zValue;
1310
- }else{
1311
- p->zVerbatimId = 0;
1312
- }
1308
+ int vAttrIdx, vAttrDidAppend=0;
1309
+ p->zVerbatimId = 0;
13131310
p->inVerbatim = 1;
13141311
p->preVerbState = p->state;
13151312
p->state &= ~ALLOW_WIKI;
1316
- blob_append(p->pOut, "<pre class='verbatim'>",-1);
1313
+ for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
1314
+ if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
1315
+ p->zVerbatimId = markup.aAttr[0].zValue;
1316
+ }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
1317
+ blob_appendf(p->pOut, "<pre name='code' class='%s'>",
1318
+ markup.aAttr[vAttrIdx].zValue);
1319
+ vAttrDidAppend=1;
1320
+ }
1321
+ }
1322
+ if( !vAttrDidAppend )
1323
+ blob_append(p->pOut, "<pre class='verbatim'>",-1);
13171324
p->wantAutoParagraph = 0;
13181325
}else
13191326
if( markup.iType==MUTYPE_LI ){
13201327
if( backupToType(p, MUTYPE_LIST)==0 ){
13211328
pushStack(p, MARKUP_UL);
@@ -1373,11 +1380,11 @@
13731380
** reply.
13741381
*/
13751382
void wiki_convert(Blob *pIn, Blob *pOut, int flags){
13761383
char *z;
13771384
Renderer renderer;
1378
-
1385
+
13791386
memset(&renderer, 0, sizeof(renderer));
13801387
renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
13811388
if( flags & WIKI_NOBLOCK ){
13821389
renderer.state |= INLINE_MARKUP_ONLY;
13831390
}
@@ -1419,11 +1426,11 @@
14191426
14201427
/*
14211428
** Search for a <title>...</title> at the beginning of a wiki page.
14221429
** Return true (nonzero) if a title is found. Return zero if there is
14231430
** not title.
1424
-**
1431
+**
14251432
** If a title is found, initialize the pTitle blob to be the content
14261433
** of the title and initialize pTail to be the text that follows the
14271434
** title.
14281435
*/
14291436
int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
14301437
--- 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
@@ -258,22 +258,22 @@
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,27 +280,27 @@
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
304 /*
305 ** Use binary search to locate a tag in the aMarkup[] table.
306 */
@@ -436,11 +436,11 @@
436 while( (c = z[0])!=0 && c!='<' && c!='&' &&
437 (useWiki==0 || (c!='[' && c!='\n')) ){
438 n++;
439 z++;
440 }
441 return n;
442 }
443
444 /*
445 ** Return true if z[] begins with an HTML character element.
446 */
@@ -550,11 +550,11 @@
550 }
551 }
552
553 /*
554 ** Get the next wiki token.
555 **
556 ** z points to the start of a token. Return the number of
557 ** characters in that token. Write the token type into *pTokenType.
558 */
559 static int nextWikiToken(const char *z, Renderer *p, int *pTokenType){
560 int n;
@@ -616,11 +616,11 @@
616 return 1 + textLength(z+1, p->state & ALLOW_WIKI);
617 }
618
619 /*
620 ** Parse only Wiki links, return everything else as TOKEN_RAW.
621 **
622 ** z points to the start of a token. Return the number of
623 ** characters in that token. Write the token type into *pTokenType.
624 */
625
626 static int nextRawToken(const char *z, Renderer *p, int *pTokenType){
@@ -652,11 +652,11 @@
652
653 /*
654 ** z[] is an HTML markup element - something that begins with '<'.
655 ** Parse this element into the p structure.
656 **
657 ** The content of z[] might be modified by converting characters
658 ** to lowercase and by inserting some "\000" characters.
659 */
660 static void parseMarkup(ParsedMarkup *p, char *z){
661 int i, j, c;
662 int iACode;
@@ -670,11 +670,11 @@
670 }else{
671 p->endTag = 0;
672 i = 1;
673 }
674 j = 0;
675 while( isalnum(z[i]) ){
676 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
677 i++;
678 }
679 zTag[j] = 0;
680 p->iCode = findTag(zTag);
@@ -682,11 +682,11 @@
682 p->nAttr = 0;
683 while( isspace(z[i]) ){ i++; }
684 while( p->nAttr<8 && isalpha(z[i]) ){
685 int attrOk; /* True to preserver attribute. False to ignore it */
686 j = 0;
687 while( isalnum(z[i]) ){
688 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
689 i++;
690 }
691 zTag[j] = 0;
692 p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
@@ -825,11 +825,11 @@
825 }
826 }
827
828 /*
829 ** Attempt to find a find a tag of type iTag with id zId. Return -1
830 ** if not found. If found, return its stack level.
831 */
832 static int findTagWithId(Renderer *p, int iTag, const char *zId){
833 int i;
834 assert( zId!=0 );
835 for(i=p->nStack-1; i>=0; i--){
@@ -915,11 +915,11 @@
915 canonical16(zLower, n+1);
916 memcpy(zUpper, zLower, n+1);
917 zUpper[n-1]++;
918 if( once ){
919 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
920 db_static_prepare(&q,
921 "SELECT %s FROM ticket "
922 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
923 zClosedExpr
924 );
925 once = 0;
@@ -970,13 +970,13 @@
970 int nClose /* Bytes available in zClose[] */
971 ){
972 const char *zTerm = "</a>";
973 assert( nClose>=20 );
974
975 if( strncmp(zTarget, "http:", 5)==0
976 || strncmp(zTarget, "https:", 6)==0
977 || strncmp(zTarget, "ftp:", 4)==0
978 || strncmp(zTarget, "mailto:", 7)==0
979 ){
980 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
981 /* zTerm = "&#x27FE;</a>"; // doesn't work on windows */
982 }else if( zTarget[0]=='/' ){
@@ -1218,11 +1218,11 @@
1218 int iDiv;
1219 parseMarkup(&markup, z);
1220
1221 /* Markup of the form </div id=ID> where there is a matching
1222 ** ID somewhere on the stack. Exit the verbatim if were are in
1223 ** it. Pop the stack up to the matching <div>. Discard the
1224 ** </div>
1225 */
1226 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1227 (zId = markupId(&markup))!=0 &&
1228 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
@@ -1242,11 +1242,11 @@
1242 p->nStack--;
1243 }else
1244
1245 /* If within <verbatim id=ID> ignore everything other than
1246 ** </verbatim id=ID> and the </dev id=ID2> above.
1247 */
1248 if( p->inVerbatim ){
1249 if( endVerbatim(p, &markup) ){
1250 p->inVerbatim = 0;
1251 p->state = p->preVerbState;
1252 blob_append(p->pOut, "</pre>", 6);
@@ -1300,22 +1300,29 @@
1300 (p->state & ALLOW_WIKI)!=0);
1301 }else
1302
1303 /* Enter <verbatim> processing. With verbatim enabled, all other
1304 ** markup other than the corresponding end-tag with the same ID is
1305 ** ignored.
1306 */
1307 if( markup.iCode==MARKUP_VERBATIM ){
1308 if( markup.nAttr==1 ){
1309 p->zVerbatimId = markup.aAttr[0].zValue;
1310 }else{
1311 p->zVerbatimId = 0;
1312 }
1313 p->inVerbatim = 1;
1314 p->preVerbState = p->state;
1315 p->state &= ~ALLOW_WIKI;
1316 blob_append(p->pOut, "<pre class='verbatim'>",-1);
 
 
 
 
 
 
 
 
 
 
1317 p->wantAutoParagraph = 0;
1318 }else
1319 if( markup.iType==MUTYPE_LI ){
1320 if( backupToType(p, MUTYPE_LIST)==0 ){
1321 pushStack(p, MARKUP_UL);
@@ -1373,11 +1380,11 @@
1373 ** reply.
1374 */
1375 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1376 char *z;
1377 Renderer renderer;
1378
1379 memset(&renderer, 0, sizeof(renderer));
1380 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
1381 if( flags & WIKI_NOBLOCK ){
1382 renderer.state |= INLINE_MARKUP_ONLY;
1383 }
@@ -1419,11 +1426,11 @@
1419
1420 /*
1421 ** Search for a <title>...</title> at the beginning of a wiki page.
1422 ** Return true (nonzero) if a title is found. Return zero if there is
1423 ** not title.
1424 **
1425 ** If a title is found, initialize the pTitle blob to be the content
1426 ** of the title and initialize pTail to be the text that follows the
1427 ** title.
1428 */
1429 int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
1430
--- 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
@@ -258,22 +258,22 @@
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,27 +280,27 @@
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|AMSK_TYPE },
302 };
303
304 /*
305 ** Use binary search to locate a tag in the aMarkup[] table.
306 */
@@ -436,11 +436,11 @@
436 while( (c = z[0])!=0 && c!='<' && c!='&' &&
437 (useWiki==0 || (c!='[' && c!='\n')) ){
438 n++;
439 z++;
440 }
441 return n;
442 }
443
444 /*
445 ** Return true if z[] begins with an HTML character element.
446 */
@@ -550,11 +550,11 @@
550 }
551 }
552
553 /*
554 ** Get the next wiki token.
555 **
556 ** z points to the start of a token. Return the number of
557 ** characters in that token. Write the token type into *pTokenType.
558 */
559 static int nextWikiToken(const char *z, Renderer *p, int *pTokenType){
560 int n;
@@ -616,11 +616,11 @@
616 return 1 + textLength(z+1, p->state & ALLOW_WIKI);
617 }
618
619 /*
620 ** Parse only Wiki links, return everything else as TOKEN_RAW.
621 **
622 ** z points to the start of a token. Return the number of
623 ** characters in that token. Write the token type into *pTokenType.
624 */
625
626 static int nextRawToken(const char *z, Renderer *p, int *pTokenType){
@@ -652,11 +652,11 @@
652
653 /*
654 ** z[] is an HTML markup element - something that begins with '<'.
655 ** Parse this element into the p structure.
656 **
657 ** The content of z[] might be modified by converting characters
658 ** to lowercase and by inserting some "\000" characters.
659 */
660 static void parseMarkup(ParsedMarkup *p, char *z){
661 int i, j, c;
662 int iACode;
@@ -670,11 +670,11 @@
670 }else{
671 p->endTag = 0;
672 i = 1;
673 }
674 j = 0;
675 while( isalnum(z[i]) ){
676 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
677 i++;
678 }
679 zTag[j] = 0;
680 p->iCode = findTag(zTag);
@@ -682,11 +682,11 @@
682 p->nAttr = 0;
683 while( isspace(z[i]) ){ i++; }
684 while( p->nAttr<8 && isalpha(z[i]) ){
685 int attrOk; /* True to preserver attribute. False to ignore it */
686 j = 0;
687 while( isalnum(z[i]) ){
688 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]);
689 i++;
690 }
691 zTag[j] = 0;
692 p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag);
@@ -825,11 +825,11 @@
825 }
826 }
827
828 /*
829 ** Attempt to find a find a tag of type iTag with id zId. Return -1
830 ** if not found. If found, return its stack level.
831 */
832 static int findTagWithId(Renderer *p, int iTag, const char *zId){
833 int i;
834 assert( zId!=0 );
835 for(i=p->nStack-1; i>=0; i--){
@@ -915,11 +915,11 @@
915 canonical16(zLower, n+1);
916 memcpy(zUpper, zLower, n+1);
917 zUpper[n-1]++;
918 if( once ){
919 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'");
920 db_static_prepare(&q,
921 "SELECT %s FROM ticket "
922 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr",
923 zClosedExpr
924 );
925 once = 0;
@@ -970,13 +970,13 @@
970 int nClose /* Bytes available in zClose[] */
971 ){
972 const char *zTerm = "</a>";
973 assert( nClose>=20 );
974
975 if( strncmp(zTarget, "http:", 5)==0
976 || strncmp(zTarget, "https:", 6)==0
977 || strncmp(zTarget, "ftp:", 4)==0
978 || strncmp(zTarget, "mailto:", 7)==0
979 ){
980 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
981 /* zTerm = "&#x27FE;</a>"; // doesn't work on windows */
982 }else if( zTarget[0]=='/' ){
@@ -1218,11 +1218,11 @@
1218 int iDiv;
1219 parseMarkup(&markup, z);
1220
1221 /* Markup of the form </div id=ID> where there is a matching
1222 ** ID somewhere on the stack. Exit the verbatim if were are in
1223 ** it. Pop the stack up to the matching <div>. Discard the
1224 ** </div>
1225 */
1226 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1227 (zId = markupId(&markup))!=0 &&
1228 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
@@ -1242,11 +1242,11 @@
1242 p->nStack--;
1243 }else
1244
1245 /* If within <verbatim id=ID> ignore everything other than
1246 ** </verbatim id=ID> and the </dev id=ID2> above.
1247 */
1248 if( p->inVerbatim ){
1249 if( endVerbatim(p, &markup) ){
1250 p->inVerbatim = 0;
1251 p->state = p->preVerbState;
1252 blob_append(p->pOut, "</pre>", 6);
@@ -1300,22 +1300,29 @@
1300 (p->state & ALLOW_WIKI)!=0);
1301 }else
1302
1303 /* Enter <verbatim> processing. With verbatim enabled, all other
1304 ** markup other than the corresponding end-tag with the same ID is
1305 ** ignored.
1306 */
1307 if( markup.iCode==MARKUP_VERBATIM ){
1308 int vAttrIdx, vAttrDidAppend=0;
1309 p->zVerbatimId = 0;
 
 
 
1310 p->inVerbatim = 1;
1311 p->preVerbState = p->state;
1312 p->state &= ~ALLOW_WIKI;
1313 for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
1314 if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
1315 p->zVerbatimId = markup.aAttr[0].zValue;
1316 }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
1317 blob_appendf(p->pOut, "<pre name='code' class='%s'>",
1318 markup.aAttr[vAttrIdx].zValue);
1319 vAttrDidAppend=1;
1320 }
1321 }
1322 if( !vAttrDidAppend )
1323 blob_append(p->pOut, "<pre class='verbatim'>",-1);
1324 p->wantAutoParagraph = 0;
1325 }else
1326 if( markup.iType==MUTYPE_LI ){
1327 if( backupToType(p, MUTYPE_LIST)==0 ){
1328 pushStack(p, MARKUP_UL);
@@ -1373,11 +1380,11 @@
1380 ** reply.
1381 */
1382 void wiki_convert(Blob *pIn, Blob *pOut, int flags){
1383 char *z;
1384 Renderer renderer;
1385
1386 memset(&renderer, 0, sizeof(renderer));
1387 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH;
1388 if( flags & WIKI_NOBLOCK ){
1389 renderer.state |= INLINE_MARKUP_ONLY;
1390 }
@@ -1419,11 +1426,11 @@
1426
1427 /*
1428 ** Search for a <title>...</title> at the beginning of a wiki page.
1429 ** Return true (nonzero) if a title is found. Return zero if there is
1430 ** not title.
1431 **
1432 ** If a title is found, initialize the pTitle blob to be the content
1433 ** of the title and initialize pTail to be the text that follows the
1434 ** title.
1435 */
1436 int wiki_find_title(Blob *pIn, Blob *pTitle, Blob *pTail){
1437

Keyboard Shortcuts

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