Fossil SCM

Proof-of-concept code that allows markdown-style hyperlinks to appear in check-in comments. Markdown-style hyperlinks are not allowed in ordinary text/x-fossil-wiki for backwards compatibility. This simply change reduces the need to provide full markdown support for check-in comments.

drh 2025-03-04 00:39 trunk
Commit e7bc33f0801e47ac9be846ed614d9c29ee850c9f1e2665b6915982055d6cb3da
+7 -1
--- src/backlink.c
+++ src/backlink.c
@@ -370,11 +370,17 @@
370370
assert( ValidBklnk(srctype) );
371371
assert( ValidMTC(mimetype) );
372372
bklnk.srctype = srctype;
373373
bklnk.mtime = mtime;
374374
if( mimetype==MT_NONE || mimetype==MT_WIKI ){
375
- wiki_extract_links(zSrc, &bklnk, srctype==BKLNK_COMMENT ? WIKI_INLINE : 0);
375
+ int flags;
376
+ if( srctype==BKLNK_COMMENT ){
377
+ flags = WIKI_INLINE | WIKI_MARKDOWN_LINK;
378
+ }else{
379
+ flags = 0;
380
+ }
381
+ wiki_extract_links(zSrc, &bklnk, flags);
376382
}else if( mimetype==MT_MARKDOWN ){
377383
markdown_extract_links(zSrc, &bklnk);
378384
}
379385
}
380386
381387
--- src/backlink.c
+++ src/backlink.c
@@ -370,11 +370,17 @@
370 assert( ValidBklnk(srctype) );
371 assert( ValidMTC(mimetype) );
372 bklnk.srctype = srctype;
373 bklnk.mtime = mtime;
374 if( mimetype==MT_NONE || mimetype==MT_WIKI ){
375 wiki_extract_links(zSrc, &bklnk, srctype==BKLNK_COMMENT ? WIKI_INLINE : 0);
 
 
 
 
 
 
376 }else if( mimetype==MT_MARKDOWN ){
377 markdown_extract_links(zSrc, &bklnk);
378 }
379 }
380
381
--- src/backlink.c
+++ src/backlink.c
@@ -370,11 +370,17 @@
370 assert( ValidBklnk(srctype) );
371 assert( ValidMTC(mimetype) );
372 bklnk.srctype = srctype;
373 bklnk.mtime = mtime;
374 if( mimetype==MT_NONE || mimetype==MT_WIKI ){
375 int flags;
376 if( srctype==BKLNK_COMMENT ){
377 flags = WIKI_INLINE | WIKI_MARKDOWN_LINK;
378 }else{
379 flags = 0;
380 }
381 wiki_extract_links(zSrc, &bklnk, flags);
382 }else if( mimetype==MT_MARKDOWN ){
383 markdown_extract_links(zSrc, &bklnk);
384 }
385 }
386
387
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -815,11 +815,11 @@
815815
if( zLink==0 || zLink[0]==0 ){
816816
zClose[0] = 0;
817817
}else{
818818
static const int flags =
819819
WIKI_NOBADLINKS |
820
- WIKI_MARKDOWNLINKS
820
+ WIKI_MARKDOWN_URL
821821
;
822822
wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
823823
}
824824
if( blob_size(content)==0 ){
825825
if( link ) blob_appendb(ob, link);
826826
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -815,11 +815,11 @@
815 if( zLink==0 || zLink[0]==0 ){
816 zClose[0] = 0;
817 }else{
818 static const int flags =
819 WIKI_NOBADLINKS |
820 WIKI_MARKDOWNLINKS
821 ;
822 wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
823 }
824 if( blob_size(content)==0 ){
825 if( link ) blob_appendb(ob, link);
826
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -815,11 +815,11 @@
815 if( zLink==0 || zLink[0]==0 ){
816 zClose[0] = 0;
817 }else{
818 static const int flags =
819 WIKI_NOBADLINKS |
820 WIKI_MARKDOWN_URL
821 ;
822 wiki_resolve_hyperlink(ob, flags, zLink, zClose, sizeof(zClose), 0, zTitle);
823 }
824 if( blob_size(content)==0 ){
825 if( link ) blob_appendb(ob, link);
826
--- src/printf.c
+++ src/printf.c
@@ -264,10 +264,11 @@
264264
wikiFlags |= WIKI_LINKSONLY;
265265
}
266266
if( db_get_boolean("timeline-hard-newlines", 0) ){
267267
wikiFlags |= WIKI_NEWLINE;
268268
}
269
+ wikiFlags |= WIKI_MARKDOWN_LINK;
269270
}
270271
if( altForm2 ){
271272
/* block markup (ex: <p>, <table>) allowed */
272273
return wikiFlags & ~WIKI_NOBLOCK;
273274
}else{
274275
--- src/printf.c
+++ src/printf.c
@@ -264,10 +264,11 @@
264 wikiFlags |= WIKI_LINKSONLY;
265 }
266 if( db_get_boolean("timeline-hard-newlines", 0) ){
267 wikiFlags |= WIKI_NEWLINE;
268 }
 
269 }
270 if( altForm2 ){
271 /* block markup (ex: <p>, <table>) allowed */
272 return wikiFlags & ~WIKI_NOBLOCK;
273 }else{
274
--- src/printf.c
+++ src/printf.c
@@ -264,10 +264,11 @@
264 wikiFlags |= WIKI_LINKSONLY;
265 }
266 if( db_get_boolean("timeline-hard-newlines", 0) ){
267 wikiFlags |= WIKI_NEWLINE;
268 }
269 wikiFlags |= WIKI_MARKDOWN_LINK;
270 }
271 if( altForm2 ){
272 /* block markup (ex: <p>, <table>) allowed */
273 return wikiFlags & ~WIKI_NOBLOCK;
274 }else{
275
+50 -17
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -30,14 +30,15 @@
3030
#define WIKI_NOBLOCK 0x004 /* No block markup of any kind */
3131
#define WIKI_BUTTONS 0x008 /* Allow sub-menu buttons */
3232
#define WIKI_NOBADLINKS 0x010 /* Ignore broken hyperlinks */
3333
#define WIKI_LINKSONLY 0x020 /* No markup. Only decorate links */
3434
#define WIKI_NEWLINE 0x040 /* Honor \n - break lines at each \n */
35
-#define WIKI_MARKDOWNLINKS 0x080 /* Resolve hyperlinks as in markdown */
35
+#define WIKI_MARKDOWN_URL 0x080 /* Hyperlink targets as in markdown */
3636
#define WIKI_SAFE 0x100 /* Make the result safe for embedding */
3737
#define WIKI_TARGET_BLANK 0x200 /* Hyperlinks go to a new window */
3838
#define WIKI_NOBRACKET 0x400 /* Omit extra [..] around hyperlinks */
39
+#define WIKI_MARKDOWN_LINK 0x800 /* Markdown link syntax: [display](URL) */
3940
#endif
4041
4142
4243
/*
4344
** These are the only markup attributes allowed.
@@ -1343,13 +1344,13 @@
13431344
}else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
13441345
&& db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
13451346
/* Dates or date-and-times in ISO8610 resolve to a link to the
13461347
** timeline for that date */
13471348
blob_appendf(pOut, "<a href=\"%R/timeline?c=%T\"%s>", zTarget, zExtra);
1348
- }else if( mFlags & WIKI_MARKDOWNLINKS ){
1349
- /* If none of the above, and if rendering links for markdown, then
1350
- ** create a link to the literal text of the target */
1349
+ }else if( mFlags & WIKI_MARKDOWN_URL ){
1350
+ /* If none of the above, and if rendering link references for markdown,
1351
+ ** then create a link to the literal text of the target */
13511352
blob_appendf(pOut, "<a href=\"%h\"%s>", zTarget, zExtra);
13521353
}else if( zOrig && zTarget>=&zOrig[2]
13531354
&& zTarget[-1]=='[' && !fossil_isspace(zTarget[-2]) ){
13541355
/* If the hyperlink markup is not preceded by whitespace, then it
13551356
** is probably a C-language subscript or similar, not really a
@@ -1574,25 +1575,43 @@
15741575
break;
15751576
}
15761577
case TOKEN_LINK: {
15771578
char *zTarget;
15781579
char *zDisplay = 0;
1580
+ char *zEnd;
15791581
int i, j;
15801582
int savedState;
15811583
char zClose[20];
15821584
char cS1 = 0;
15831585
int iS1 = 0;
15841586
15851587
startAutoParagraph(p);
1586
- zTarget = &z[1];
1587
- for(i=1; z[i] && z[i]!=']'; i++){
1588
- if( z[i]=='|' && zDisplay==0 ){
1589
- zDisplay = &z[i+1];
1590
- for(j=i; j>0 && fossil_isspace(z[j-1]); j--){}
1591
- iS1 = j;
1592
- cS1 = z[j];
1593
- z[j] = 0;
1588
+ if( z[n]=='('
1589
+ && (p->state & WIKI_MARKDOWN_LINK)!=0
1590
+ && (zEnd = strchr(z+n+1,')'))!=0
1591
+ ){
1592
+ /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
1593
+ if( n>2 ){
1594
+ zDisplay = &z[1];
1595
+ z[n] = 0;
1596
+ }else{
1597
+ zDisplay = 0;
1598
+ }
1599
+ zTarget = &z[n+1];
1600
+ for(i=n+1; z[i] && z[i]!=')' && z[i]!=' '; i++){}
1601
+ n = (int)(zEnd - z) + 1;
1602
+ }else{
1603
+ /* Wiki-style hyperlinks: [URL|display-text] or [URL] */
1604
+ zTarget = &z[1];
1605
+ for(i=1; z[i] && z[i]!=']'; i++){
1606
+ if( z[i]=='|' && zDisplay==0 ){
1607
+ zDisplay = &z[i+1];
1608
+ for(j=i; j>0 && fossil_isspace(z[j-1]); j--){}
1609
+ iS1 = j;
1610
+ cS1 = z[j];
1611
+ z[j] = 0;
1612
+ }
15941613
}
15951614
}
15961615
z[i] = 0;
15971616
if( zDisplay==0 ){
15981617
zDisplay = zTarget + interwiki_removable_prefix(zTarget);
@@ -1874,13 +1893,14 @@
18741893
** --buttons Set the WIKI_BUTTONS flag
18751894
** --dark-pikchr Render pikchrs in dark mode
18761895
** --htmlonly Set the WIKI_HTMLONLY flag
18771896
** --inline Set the WIKI_INLINE flag
18781897
** --linksonly Set the WIKI_LINKSONLY flag
1898
+** --md-links Allow markdown link syntax
18791899
** --nobadlinks Set the WIKI_NOBADLINKS flag
18801900
** --noblock Set the WIKI_NOBLOCK flag
1881
-** --text Run the output through html_to_plaintext().
1901
+** --text Run the output through html_to_plaintext().
18821902
*/
18831903
void test_wiki_render(void){
18841904
Blob in, out;
18851905
int flags = 0;
18861906
int bText;
@@ -1888,10 +1908,11 @@
18881908
if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY;
18891909
if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY;
18901910
if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS;
18911911
if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE;
18921912
if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK;
1913
+ if( find_option("md-links",0,0)!=0 ) flags |= WIKI_MARKDOWN_LINK;
18931914
if( find_option("dark-pikchr",0,0)!=0 ){
18941915
pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE );
18951916
}
18961917
bText = find_option("text",0,0)!=0;
18971918
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
@@ -2041,16 +2062,28 @@
20412062
}else{
20422063
n = nextWikiToken(z, &renderer, &tokenType);
20432064
}
20442065
switch( tokenType ){
20452066
case TOKEN_LINK: {
2046
- char *zTarget;
2067
+ char *zTarget, *zEnd;
20472068
int i;
20482069
2049
- zTarget = &z[1];
2050
- for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
2051
- while(i>1 && zTarget[i-1]==' '){ i--; }
2070
+ if( z[n]=='('
2071
+ && (flags & WIKI_MARKDOWN_LINK)!=0
2072
+ && (zEnd = strchr(z+n+1,')'))!=0
2073
+ ){
2074
+ /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
2075
+ z += n+1;
2076
+ zTarget = z;
2077
+ for(i=1; z[i] && z[i]!=')' && z[i]!=' '; i++){}
2078
+ n = (int)(zEnd - z) + 1;
2079
+ }else{
2080
+ /* Wiki-style hyperlinks: [URL|display-text] or [URL] */
2081
+ zTarget = &z[1];
2082
+ for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
2083
+ while(i>1 && zTarget[i-1]==' '){ i--; }
2084
+ }
20522085
backlink_create(pBklnk, zTarget, i);
20532086
break;
20542087
}
20552088
case TOKEN_MARKUP: {
20562089
const char *zId;
20572090
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -30,14 +30,15 @@
30 #define WIKI_NOBLOCK 0x004 /* No block markup of any kind */
31 #define WIKI_BUTTONS 0x008 /* Allow sub-menu buttons */
32 #define WIKI_NOBADLINKS 0x010 /* Ignore broken hyperlinks */
33 #define WIKI_LINKSONLY 0x020 /* No markup. Only decorate links */
34 #define WIKI_NEWLINE 0x040 /* Honor \n - break lines at each \n */
35 #define WIKI_MARKDOWNLINKS 0x080 /* Resolve hyperlinks as in markdown */
36 #define WIKI_SAFE 0x100 /* Make the result safe for embedding */
37 #define WIKI_TARGET_BLANK 0x200 /* Hyperlinks go to a new window */
38 #define WIKI_NOBRACKET 0x400 /* Omit extra [..] around hyperlinks */
 
39 #endif
40
41
42 /*
43 ** These are the only markup attributes allowed.
@@ -1343,13 +1344,13 @@
1343 }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1344 && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
1345 /* Dates or date-and-times in ISO8610 resolve to a link to the
1346 ** timeline for that date */
1347 blob_appendf(pOut, "<a href=\"%R/timeline?c=%T\"%s>", zTarget, zExtra);
1348 }else if( mFlags & WIKI_MARKDOWNLINKS ){
1349 /* If none of the above, and if rendering links for markdown, then
1350 ** create a link to the literal text of the target */
1351 blob_appendf(pOut, "<a href=\"%h\"%s>", zTarget, zExtra);
1352 }else if( zOrig && zTarget>=&zOrig[2]
1353 && zTarget[-1]=='[' && !fossil_isspace(zTarget[-2]) ){
1354 /* If the hyperlink markup is not preceded by whitespace, then it
1355 ** is probably a C-language subscript or similar, not really a
@@ -1574,25 +1575,43 @@
1574 break;
1575 }
1576 case TOKEN_LINK: {
1577 char *zTarget;
1578 char *zDisplay = 0;
 
1579 int i, j;
1580 int savedState;
1581 char zClose[20];
1582 char cS1 = 0;
1583 int iS1 = 0;
1584
1585 startAutoParagraph(p);
1586 zTarget = &z[1];
1587 for(i=1; z[i] && z[i]!=']'; i++){
1588 if( z[i]=='|' && zDisplay==0 ){
1589 zDisplay = &z[i+1];
1590 for(j=i; j>0 && fossil_isspace(z[j-1]); j--){}
1591 iS1 = j;
1592 cS1 = z[j];
1593 z[j] = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1594 }
1595 }
1596 z[i] = 0;
1597 if( zDisplay==0 ){
1598 zDisplay = zTarget + interwiki_removable_prefix(zTarget);
@@ -1874,13 +1893,14 @@
1874 ** --buttons Set the WIKI_BUTTONS flag
1875 ** --dark-pikchr Render pikchrs in dark mode
1876 ** --htmlonly Set the WIKI_HTMLONLY flag
1877 ** --inline Set the WIKI_INLINE flag
1878 ** --linksonly Set the WIKI_LINKSONLY flag
 
1879 ** --nobadlinks Set the WIKI_NOBADLINKS flag
1880 ** --noblock Set the WIKI_NOBLOCK flag
1881 ** --text Run the output through html_to_plaintext().
1882 */
1883 void test_wiki_render(void){
1884 Blob in, out;
1885 int flags = 0;
1886 int bText;
@@ -1888,10 +1908,11 @@
1888 if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY;
1889 if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY;
1890 if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS;
1891 if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE;
1892 if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK;
 
1893 if( find_option("dark-pikchr",0,0)!=0 ){
1894 pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE );
1895 }
1896 bText = find_option("text",0,0)!=0;
1897 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
@@ -2041,16 +2062,28 @@
2041 }else{
2042 n = nextWikiToken(z, &renderer, &tokenType);
2043 }
2044 switch( tokenType ){
2045 case TOKEN_LINK: {
2046 char *zTarget;
2047 int i;
2048
2049 zTarget = &z[1];
2050 for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
2051 while(i>1 && zTarget[i-1]==' '){ i--; }
 
 
 
 
 
 
 
 
 
 
 
 
2052 backlink_create(pBklnk, zTarget, i);
2053 break;
2054 }
2055 case TOKEN_MARKUP: {
2056 const char *zId;
2057
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -30,14 +30,15 @@
30 #define WIKI_NOBLOCK 0x004 /* No block markup of any kind */
31 #define WIKI_BUTTONS 0x008 /* Allow sub-menu buttons */
32 #define WIKI_NOBADLINKS 0x010 /* Ignore broken hyperlinks */
33 #define WIKI_LINKSONLY 0x020 /* No markup. Only decorate links */
34 #define WIKI_NEWLINE 0x040 /* Honor \n - break lines at each \n */
35 #define WIKI_MARKDOWN_URL 0x080 /* Hyperlink targets as in markdown */
36 #define WIKI_SAFE 0x100 /* Make the result safe for embedding */
37 #define WIKI_TARGET_BLANK 0x200 /* Hyperlinks go to a new window */
38 #define WIKI_NOBRACKET 0x400 /* Omit extra [..] around hyperlinks */
39 #define WIKI_MARKDOWN_LINK 0x800 /* Markdown link syntax: [display](URL) */
40 #endif
41
42
43 /*
44 ** These are the only markup attributes allowed.
@@ -1343,13 +1344,13 @@
1344 }else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
1345 && db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
1346 /* Dates or date-and-times in ISO8610 resolve to a link to the
1347 ** timeline for that date */
1348 blob_appendf(pOut, "<a href=\"%R/timeline?c=%T\"%s>", zTarget, zExtra);
1349 }else if( mFlags & WIKI_MARKDOWN_URL ){
1350 /* If none of the above, and if rendering link references for markdown,
1351 ** then create a link to the literal text of the target */
1352 blob_appendf(pOut, "<a href=\"%h\"%s>", zTarget, zExtra);
1353 }else if( zOrig && zTarget>=&zOrig[2]
1354 && zTarget[-1]=='[' && !fossil_isspace(zTarget[-2]) ){
1355 /* If the hyperlink markup is not preceded by whitespace, then it
1356 ** is probably a C-language subscript or similar, not really a
@@ -1574,25 +1575,43 @@
1575 break;
1576 }
1577 case TOKEN_LINK: {
1578 char *zTarget;
1579 char *zDisplay = 0;
1580 char *zEnd;
1581 int i, j;
1582 int savedState;
1583 char zClose[20];
1584 char cS1 = 0;
1585 int iS1 = 0;
1586
1587 startAutoParagraph(p);
1588 if( z[n]=='('
1589 && (p->state & WIKI_MARKDOWN_LINK)!=0
1590 && (zEnd = strchr(z+n+1,')'))!=0
1591 ){
1592 /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
1593 if( n>2 ){
1594 zDisplay = &z[1];
1595 z[n] = 0;
1596 }else{
1597 zDisplay = 0;
1598 }
1599 zTarget = &z[n+1];
1600 for(i=n+1; z[i] && z[i]!=')' && z[i]!=' '; i++){}
1601 n = (int)(zEnd - z) + 1;
1602 }else{
1603 /* Wiki-style hyperlinks: [URL|display-text] or [URL] */
1604 zTarget = &z[1];
1605 for(i=1; z[i] && z[i]!=']'; i++){
1606 if( z[i]=='|' && zDisplay==0 ){
1607 zDisplay = &z[i+1];
1608 for(j=i; j>0 && fossil_isspace(z[j-1]); j--){}
1609 iS1 = j;
1610 cS1 = z[j];
1611 z[j] = 0;
1612 }
1613 }
1614 }
1615 z[i] = 0;
1616 if( zDisplay==0 ){
1617 zDisplay = zTarget + interwiki_removable_prefix(zTarget);
@@ -1874,13 +1893,14 @@
1893 ** --buttons Set the WIKI_BUTTONS flag
1894 ** --dark-pikchr Render pikchrs in dark mode
1895 ** --htmlonly Set the WIKI_HTMLONLY flag
1896 ** --inline Set the WIKI_INLINE flag
1897 ** --linksonly Set the WIKI_LINKSONLY flag
1898 ** --md-links Allow markdown link syntax
1899 ** --nobadlinks Set the WIKI_NOBADLINKS flag
1900 ** --noblock Set the WIKI_NOBLOCK flag
1901 ** --text Run the output through html_to_plaintext().
1902 */
1903 void test_wiki_render(void){
1904 Blob in, out;
1905 int flags = 0;
1906 int bText;
@@ -1888,10 +1908,11 @@
1908 if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY;
1909 if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY;
1910 if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS;
1911 if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE;
1912 if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK;
1913 if( find_option("md-links",0,0)!=0 ) flags |= WIKI_MARKDOWN_LINK;
1914 if( find_option("dark-pikchr",0,0)!=0 ){
1915 pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE );
1916 }
1917 bText = find_option("text",0,0)!=0;
1918 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
@@ -2041,16 +2062,28 @@
2062 }else{
2063 n = nextWikiToken(z, &renderer, &tokenType);
2064 }
2065 switch( tokenType ){
2066 case TOKEN_LINK: {
2067 char *zTarget, *zEnd;
2068 int i;
2069
2070 if( z[n]=='('
2071 && (flags & WIKI_MARKDOWN_LINK)!=0
2072 && (zEnd = strchr(z+n+1,')'))!=0
2073 ){
2074 /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
2075 z += n+1;
2076 zTarget = z;
2077 for(i=1; z[i] && z[i]!=')' && z[i]!=' '; i++){}
2078 n = (int)(zEnd - z) + 1;
2079 }else{
2080 /* Wiki-style hyperlinks: [URL|display-text] or [URL] */
2081 zTarget = &z[1];
2082 for(i=0; zTarget[i] && zTarget[i]!='|' && zTarget[i]!=']'; i++){}
2083 while(i>1 && zTarget[i-1]==' '){ i--; }
2084 }
2085 backlink_create(pBklnk, zTarget, i);
2086 break;
2087 }
2088 case TOKEN_MARKUP: {
2089 const char *zId;
2090

Keyboard Shortcuts

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