Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch robert-exp Excluding Merge-Ins
This is equivalent to a diff from 767ae79c3d to 47cc9dfec8
2009-05-08
| ||
09:52 | Initial commit of Creole Wiki Parser extension. check-in: ecd1f09632 user: robert tags: creole | |
2009-05-07
| ||
00:47 | Update the built-in SQLite to version 3.6.14. check-in: b4ec5750c6 user: drh tags: trunk | |
2009-04-27
| ||
08:43 | 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. Leaf check-in: 47cc9dfec8 user: robert tags: robert-exp, pass-comments | |
2009-04-24
| ||
18:40 | There is some bug in the new HTTP transport layer. The easiest solution is to close the TCP connection after each round trip, which is what this check-in does. check-in: 767ae79c3d user: drh tags: trunk | |
2009-04-13
| ||
09:50 | Update to version SQLite 3.6.13 check-in: 879e8c5f32 user: drh tags: trunk | |
Changes to src/wikiformat.c.
5 5 ** modify it under the terms of the GNU General Public 6 6 ** License version 2 as published by the Free Software Foundation. 7 7 ** 8 8 ** This program is distributed in the hope that it will be useful, 9 9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 11 ** General Public License for more details. 12 -** 12 +** 13 13 ** You should have received a copy of the GNU General Public 14 14 ** License along with this library; if not, write to the 15 15 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 16 ** Boston, MA 02111-1307, USA. 17 17 ** 18 18 ** Author contact information: 19 19 ** drh@hwaci.com ................................................................................ 148 148 149 149 150 150 /* 151 151 ** Allowed markup. 152 152 ** 153 153 ** Except for MARKUP_INVALID, this must all be in alphabetical order 154 154 ** 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 156 156 ** in aAllowedMarkup[]. 157 157 */ 158 158 #define MARKUP_INVALID 0 159 159 #define MARKUP_A 1 160 160 #define MARKUP_ADDRESS 2 161 161 #define MARKUP_B 3 162 162 #define MARKUP_BIG 4 ................................................................................ 187 187 #define MARKUP_NOWIKI 29 188 188 #define MARKUP_OL 30 189 189 #define MARKUP_P 31 190 190 #define MARKUP_PRE 32 191 191 #define MARKUP_S 33 192 192 #define MARKUP_SAMP 34 193 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 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 207 208 208 209 /* 209 210 ** The various markup is divided into the following types: 210 211 */ 211 212 #define MUTYPE_SINGLE 0x0001 /* <img>, <br>, or <hr> */ 212 213 #define MUTYPE_BLOCK 0x0002 /* Forms a new paragraph. ex: <p>, <h2> */ 213 214 #define MUTYPE_FONT 0x0004 /* Font changes. ex: <b>, <font>, <sub> */ ................................................................................ 256 257 AMSK_COLOR|AMSK_FACE|AMSK_SIZE }, 257 258 { "h1", MARKUP_H1, MUTYPE_BLOCK, AMSK_ALIGN }, 258 259 { "h2", MARKUP_H2, MUTYPE_BLOCK, AMSK_ALIGN }, 259 260 { "h3", MARKUP_H3, MUTYPE_BLOCK, AMSK_ALIGN }, 260 261 { "h4", MARKUP_H4, MUTYPE_BLOCK, AMSK_ALIGN }, 261 262 { "h5", MARKUP_H5, MUTYPE_BLOCK, AMSK_ALIGN }, 262 263 { "h6", MARKUP_H6, MUTYPE_BLOCK, AMSK_ALIGN }, 263 - { "hr", MARKUP_HR, MUTYPE_SINGLE, 264 + { "hr", MARKUP_HR, MUTYPE_SINGLE, 264 265 AMSK_ALIGN|AMSK_COLOR|AMSK_SIZE|AMSK_WIDTH }, 265 266 { "i", MARKUP_I, MUTYPE_FONT, 0 }, 266 - { "img", MARKUP_IMG, MUTYPE_SINGLE, 267 + { "img", MARKUP_IMG, MUTYPE_SINGLE, 267 268 AMSK_ALIGN|AMSK_ALT|AMSK_BORDER|AMSK_HEIGHT| 268 269 AMSK_HSPACE|AMSK_SRC|AMSK_VSPACE|AMSK_WIDTH }, 269 270 { "kbd", MARKUP_KBD, MUTYPE_FONT, 0 }, 270 - { "li", MARKUP_LI, MUTYPE_LI, 271 + { "li", MARKUP_LI, MUTYPE_LI, 271 272 AMSK_TYPE|AMSK_VALUE }, 272 273 { "nobr", MARKUP_NOBR, MUTYPE_FONT, 0 }, 273 274 { "nowiki", MARKUP_NOWIKI, MUTYPE_SPECIAL, 0 }, 274 - { "ol", MARKUP_OL, MUTYPE_LIST, 275 + { "ol", MARKUP_OL, MUTYPE_LIST, 275 276 AMSK_START|AMSK_TYPE|AMSK_COMPACT }, 276 277 { "p", MARKUP_P, MUTYPE_BLOCK, AMSK_ALIGN }, 277 278 { "pre", MARKUP_PRE, MUTYPE_BLOCK, 0 }, 278 279 { "s", MARKUP_S, MUTYPE_FONT, 0 }, 279 280 { "samp", MARKUP_SAMP, MUTYPE_FONT, 0 }, 280 281 { "small", MARKUP_SMALL, MUTYPE_FONT, 0 }, 282 + { "span", MARKUP_SPAN, MUTYPE_FONT, 0 }, 281 283 { "strike", MARKUP_STRIKE, MUTYPE_FONT, 0 }, 282 284 { "strong", MARKUP_STRONG, MUTYPE_FONT, 0 }, 283 285 { "sub", MARKUP_SUB, MUTYPE_FONT, 0 }, 284 286 { "sup", MARKUP_SUP, MUTYPE_FONT, 0 }, 285 - { "table", MARKUP_TABLE, MUTYPE_TABLE, 287 + { "table", MARKUP_TABLE, MUTYPE_TABLE, 286 288 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_BORDER|AMSK_CELLPADDING| 287 289 AMSK_CELLSPACING|AMSK_HSPACE|AMSK_VSPACE }, 288 - { "td", MARKUP_TD, MUTYPE_TD, 290 + { "td", MARKUP_TD, MUTYPE_TD, 289 291 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| 290 292 AMSK_ROWSPAN|AMSK_VALIGN }, 291 293 { "th", MARKUP_TH, MUTYPE_TD, 292 294 AMSK_ALIGN|AMSK_BGCOLOR|AMSK_COLSPAN| 293 295 AMSK_ROWSPAN|AMSK_VALIGN }, 294 - { "tr", MARKUP_TR, MUTYPE_TR, 296 + { "tr", MARKUP_TR, MUTYPE_TR, 295 297 AMSK_ALIGN|AMSK_BGCOLOR||AMSK_VALIGN }, 296 298 { "tt", MARKUP_TT, MUTYPE_FONT, 0 }, 297 299 { "u", MARKUP_U, MUTYPE_FONT, 0 }, 298 - { "ul", MARKUP_UL, MUTYPE_LIST, 300 + { "ul", MARKUP_UL, MUTYPE_LIST, 299 301 AMSK_TYPE|AMSK_COMPACT }, 300 302 { "var", MARKUP_VAR, MUTYPE_FONT, 0 }, 301 303 { "verbatim", MARKUP_VERBATIM, MUTYPE_SPECIAL, AMSK_ID }, 302 304 }; 303 305 304 306 /* 305 307 ** Use binary search to locate a tag in the aMarkup[] table. ................................................................................ 330 332 #define TOKEN_CHARACTER 2 /* "&" or "<" not part of markup */ 331 333 #define TOKEN_LINK 3 /* [...] */ 332 334 #define TOKEN_PARAGRAPH 4 /* blank lines */ 333 335 #define TOKEN_NEWLINE 5 /* A single "\n" */ 334 336 #define TOKEN_BULLET 6 /* " * " */ 335 337 #define TOKEN_ENUM 7 /* " \(?\d+[.)]? " */ 336 338 #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 */ 338 341 339 342 /* 340 343 ** State flags 341 344 */ 342 345 #define AT_NEWLINE 0x001 /* At start of a line */ 343 346 #define AT_PARAGRAPH 0x002 /* At start of a paragraph */ 344 347 #define ALLOW_WIKI 0x004 /* Allow wiki markup */ ................................................................................ 374 377 ** a valid markup. If it is, return the total number of characters in 375 378 ** the markup including the initial "<" and the terminating ">". If 376 379 ** it is not well-formed markup, return 0. 377 380 */ 378 381 static int markupLength(const char *z){ 379 382 int n = 1; 380 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 + 381 402 if( z[n]=='/' ){ n++; } 382 403 if( !isalpha(z[n]) ) return 0; 383 404 while( isalnum(z[n]) ){ n++; } 384 405 if( z[n]!='>' && !isspace(z[n]) ) return 0; 385 406 while( z[n] && (z[n]!='>' || inparen) ){ 386 407 if( z[n]=='"' ){ 387 408 inparen = !inparen; ................................................................................ 431 452 int n = 0; 432 453 int c; 433 454 while( (c = z[0])!=0 && c!='<' && c!='&' && 434 455 (useWiki==0 || (c!='[' && c!='\n')) ){ 435 456 n++; 436 457 z++; 437 458 } 438 - return n; 459 + return n; 439 460 } 440 461 441 462 /* 442 463 ** Return true if z[] begins with an HTML character element. 443 464 */ 444 465 static int isElement(const char *z){ 445 466 int i; ................................................................................ 552 573 ** z points to the start of a token. Return the number of 553 574 ** characters in that token. Write the token type into *pTokenType. 554 575 */ 555 576 static int nextToken(const char *z, Renderer *p, int *pTokenType){ 556 577 int n; 557 578 if( z[0]=='<' ){ 558 579 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 + } 562 589 }else{ 563 590 *pTokenType = TOKEN_CHARACTER; 564 591 return 1; 565 592 } 566 593 } 567 594 if( z[0]=='&' && (p->inVerbatim || !isElement(z)) ){ 568 595 *pTokenType = TOKEN_CHARACTER; ................................................................................ 624 651 } aAttr[10]; 625 652 }; 626 653 627 654 /* 628 655 ** z[] is an HTML markup element - something that begins with '<'. 629 656 ** Parse this element into the p structure. 630 657 ** 631 -** The content of z[] might be modified by converting characters 658 +** The content of z[] might be modified by converting characters 632 659 ** to lowercase and by inserting some "\000" characters. 633 660 */ 634 661 static void parseMarkup(ParsedMarkup *p, char *z){ 635 662 int i, j, c; 636 663 int iACode; 637 664 char *zValue; 638 665 int seen = 0; ................................................................................ 642 669 p->endTag = 1; 643 670 i = 2; 644 671 }else{ 645 672 p->endTag = 0; 646 673 i = 1; 647 674 } 648 675 j = 0; 649 - while( isalnum(z[i]) ){ 676 + while( isalnum(z[i]) ){ 650 677 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]); 651 678 i++; 652 679 } 653 680 zTag[j] = 0; 654 681 p->iCode = findTag(zTag); 655 682 p->iType = aMarkup[p->iCode].iType; 656 683 p->nAttr = 0; 657 684 while( isspace(z[i]) ){ i++; } 658 685 while( p->nAttr<8 && isalpha(z[i]) ){ 659 686 int attrOk; /* True to preserver attribute. False to ignore it */ 660 687 j = 0; 661 - while( isalnum(z[i]) ){ 688 + while( isalnum(z[i]) ){ 662 689 if( j<sizeof(zTag)-1 ) zTag[j++] = tolower(z[i]); 663 690 i++; 664 691 } 665 692 zTag[j] = 0; 666 693 p->aAttr[p->nAttr].iACode = iACode = findAttr(zTag); 667 694 attrOk = iACode!=0 && (seen & aAttribute[iACode].iMask)==0; 668 695 while( isspace(z[i]) ){ z++; } ................................................................................ 797 824 while( p->nStack>i ){ 798 825 popStack(p); 799 826 } 800 827 } 801 828 802 829 /* 803 830 ** 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. 805 832 */ 806 833 static int findTagWithId(Renderer *p, int iTag, const char *zId){ 807 834 int i; 808 835 assert( zId!=0 ); 809 836 for(i=p->nStack-1; i>=0; i--){ 810 837 if( p->aStack[i].iCode!=iTag ) continue; 811 838 if( p->aStack[i].zId==0 ) continue; ................................................................................ 887 914 n = strlen(zTarget); 888 915 memcpy(zLower, zTarget, n+1); 889 916 canonical16(zLower, n+1); 890 917 memcpy(zUpper, zLower, n+1); 891 918 zUpper[n-1]++; 892 919 if( once ){ 893 920 const char *zClosedExpr = db_get("ticket-closed-expr", "status='Closed'"); 894 - db_static_prepare(&q, 921 + db_static_prepare(&q, 895 922 "SELECT %s FROM ticket " 896 923 " WHERE tkt_uuid>=:lwr AND tkt_uuid<:upr", 897 924 zClosedExpr 898 925 ); 899 926 once = 0; 900 927 } 901 928 db_bind_text(&q, ":lwr", zLower); ................................................................................ 925 952 const char *zTarget, /* Hyperlink traget; text within [...] */ 926 953 char *zClose, /* Write hyperlink closing text here */ 927 954 int nClose /* Bytes available in zClose[] */ 928 955 ){ 929 956 const char *zTerm = "</a>"; 930 957 assert( nClose>10 ); 931 958 932 - if( strncmp(zTarget, "http:", 5)==0 959 + if( strncmp(zTarget, "http:", 5)==0 933 960 || strncmp(zTarget, "https:", 6)==0 934 - || strncmp(zTarget, "ftp:", 4)==0 961 + || strncmp(zTarget, "ftp:", 4)==0 935 962 || strncmp(zTarget, "mailto:", 7)==0 936 963 ){ 937 964 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget); 938 965 }else if( zTarget[0]=='/' ){ 939 966 if( 1 /* g.okHistory */ ){ 940 967 blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zBaseURL, zTarget); 941 968 }else{ ................................................................................ 1020 1047 int n; 1021 1048 int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; 1022 1049 1023 1050 while( z[0] ){ 1024 1051 n = nextToken(z, p, &tokenType); 1025 1052 p->state &= ~(AT_NEWLINE|AT_PARAGRAPH); 1026 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 + } 1027 1063 case TOKEN_PARAGRAPH: { 1028 1064 if( inlineOnly ){ 1029 1065 /* blob_append(p->pOut, " ¶ ", -1); */ 1030 1066 blob_append(p->pOut, " ", -1); 1031 1067 }else{ 1032 1068 if( p->wikiList ){ 1033 1069 popStackToTag(p, p->wikiList); ................................................................................ 1141 1177 case TOKEN_MARKUP: { 1142 1178 const char *zId; 1143 1179 int iDiv; 1144 1180 parseMarkup(&markup, z); 1145 1181 1146 1182 /* Markup of the form </div id=ID> where there is a matching 1147 1183 ** 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 1149 1185 ** </div> 1150 1186 */ 1151 1187 if( markup.iCode==MARKUP_DIV && markup.endTag && 1152 1188 (zId = markupId(&markup))!=0 && 1153 1189 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0 1154 1190 ){ 1155 1191 if( p->inVerbatim ){ ................................................................................ 1165 1201 } 1166 1202 assert( p->nStack==iDiv+1 ); 1167 1203 p->nStack--; 1168 1204 }else 1169 1205 1170 1206 /* If within <verbatim id=ID> ignore everything other than 1171 1207 ** </verbatim id=ID> and the </dev id=ID2> above. 1172 - */ 1208 + */ 1173 1209 if( p->inVerbatim ){ 1174 1210 if( endVerbatim(p, &markup) ){ 1175 1211 p->inVerbatim = 0; 1176 1212 p->state = p->preVerbState; 1177 1213 blob_append(p->pOut, "</pre>", 6); 1178 1214 }else{ 1179 1215 unparseMarkup(&markup); ................................................................................ 1223 1259 if( markup.iCode==MARKUP_DIV ){ 1224 1260 pushStackWithId(p, markup.iCode, markupId(&markup), 1225 1261 (p->state & ALLOW_WIKI)!=0); 1226 1262 }else 1227 1263 1228 1264 /* Enter <verbatim> processing. With verbatim enabled, all other 1229 1265 ** markup other than the corresponding end-tag with the same ID is 1230 - ** ignored. 1266 + ** ignored. 1231 1267 */ 1232 1268 if( markup.iCode==MARKUP_VERBATIM ){ 1233 1269 if( markup.nAttr==1 ){ 1234 1270 p->zVerbatimId = markup.aAttr[0].zValue; 1235 1271 }else{ 1236 1272 p->zVerbatimId = 0; 1237 1273 } ................................................................................ 1296 1332 ** initialized. The output is merely appended to pOut. 1297 1333 ** If pOut is NULL, then the output is appended to the CGI 1298 1334 ** reply. 1299 1335 */ 1300 1336 void wiki_convert(Blob *pIn, Blob *pOut, int flags){ 1301 1337 char *z; 1302 1338 Renderer renderer; 1303 - 1339 + 1304 1340 memset(&renderer, 0, sizeof(renderer)); 1305 1341 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH; 1306 1342 if( flags & WIKI_NOBLOCK ){ 1307 1343 renderer.state |= INLINE_MARKUP_ONLY; 1308 1344 } 1309 1345 if( flags & WIKI_INLINE ){ 1310 1346 renderer.wantAutoParagraph = 0;