Fossil SCM

Provide the ability to control markdown styling and markdown hyperlinks for check-in cmments separately and independently.

drh 2025-03-05 20:16 comment-markdown-links
Commit 34f36bc211906c9e45ccfd0b815d68879e66b40621a073f93053f5b0c7e172f5
+1 -1
--- src/backlink.c
+++ src/backlink.c
@@ -372,11 +372,11 @@
372372
bklnk.srctype = srctype;
373373
bklnk.mtime = mtime;
374374
if( mimetype==MT_NONE || mimetype==MT_WIKI ){
375375
int flags;
376376
if( srctype==BKLNK_COMMENT ){
377
- flags = WIKI_INLINE | WIKI_MARKDOWN_SPAN;
377
+ flags = WIKI_INLINE | WIKI_MARKDOWN_LINK;
378378
}else{
379379
flags = 0;
380380
}
381381
wiki_extract_links(zSrc, &bklnk, flags);
382382
}else if( mimetype==MT_MARKDOWN ){
383383
--- src/backlink.c
+++ src/backlink.c
@@ -372,11 +372,11 @@
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_SPAN;
378 }else{
379 flags = 0;
380 }
381 wiki_extract_links(zSrc, &bklnk, flags);
382 }else if( mimetype==MT_MARKDOWN ){
383
--- src/backlink.c
+++ src/backlink.c
@@ -372,11 +372,11 @@
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
+1 -1
--- src/configure.c
+++ src/configure.c
@@ -106,11 +106,11 @@
106106
{ "timeline-date-format", CONFIGSET_SKIN },
107107
{ "timeline-default-style", CONFIGSET_SKIN },
108108
{ "timeline-dwelltime", CONFIGSET_SKIN },
109109
{ "timeline-closetime", CONFIGSET_SKIN },
110110
{ "timeline-hard-newlines", CONFIGSET_SKIN },
111
- { "timeline-markdown-span", CONFIGSET_SKIN },
111
+ { "timeline-markdown", CONFIGSET_SKIN },
112112
{ "timeline-max-comment", CONFIGSET_SKIN },
113113
{ "timeline-plaintext", CONFIGSET_SKIN },
114114
{ "timeline-truncate-at-blank", CONFIGSET_SKIN },
115115
{ "timeline-tslink-info", CONFIGSET_SKIN },
116116
{ "timeline-utc", CONFIGSET_SKIN },
117117
--- src/configure.c
+++ src/configure.c
@@ -106,11 +106,11 @@
106 { "timeline-date-format", CONFIGSET_SKIN },
107 { "timeline-default-style", CONFIGSET_SKIN },
108 { "timeline-dwelltime", CONFIGSET_SKIN },
109 { "timeline-closetime", CONFIGSET_SKIN },
110 { "timeline-hard-newlines", CONFIGSET_SKIN },
111 { "timeline-markdown-span", CONFIGSET_SKIN },
112 { "timeline-max-comment", CONFIGSET_SKIN },
113 { "timeline-plaintext", CONFIGSET_SKIN },
114 { "timeline-truncate-at-blank", CONFIGSET_SKIN },
115 { "timeline-tslink-info", CONFIGSET_SKIN },
116 { "timeline-utc", CONFIGSET_SKIN },
117
--- src/configure.c
+++ src/configure.c
@@ -106,11 +106,11 @@
106 { "timeline-date-format", CONFIGSET_SKIN },
107 { "timeline-default-style", CONFIGSET_SKIN },
108 { "timeline-dwelltime", CONFIGSET_SKIN },
109 { "timeline-closetime", CONFIGSET_SKIN },
110 { "timeline-hard-newlines", CONFIGSET_SKIN },
111 { "timeline-markdown", CONFIGSET_SKIN },
112 { "timeline-max-comment", CONFIGSET_SKIN },
113 { "timeline-plaintext", CONFIGSET_SKIN },
114 { "timeline-truncate-at-blank", CONFIGSET_SKIN },
115 { "timeline-tslink-info", CONFIGSET_SKIN },
116 { "timeline-utc", CONFIGSET_SKIN },
117
+5 -4
--- src/printf.c
+++ src/printf.c
@@ -258,16 +258,17 @@
258258
if( db_get_boolean("timeline-block-markup", 0) ){
259259
wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
260260
}else{
261261
wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
262262
}
263
- if( db_get_boolean("timeline-markdown-span", 0) ){
264
- wikiFlags |= WIKI_MARKDOWN_SPAN;
265
- }
266263
if( db_get_boolean("timeline-plaintext", 0) ){
267264
wikiFlags |= WIKI_LINKSONLY;
268
- wikiFlags &= ~WIKI_MARKDOWN_SPAN;
265
+ wikiFlags &= ~WIKI_MARKDOWN_INLINE;
266
+ }else{
267
+ int x = db_get_boolean("timeline-markdown", 0);
268
+ if( x & 1 ) wikiFlags |= WIKI_MARKDOWN_LINK;
269
+ if( x & 2 ) wikiFlags |= WIKI_MARKDOWN_FONT;
269270
}
270271
if( db_get_boolean("timeline-hard-newlines", 0) ){
271272
wikiFlags |= WIKI_NEWLINE;
272273
}
273274
}
274275
--- src/printf.c
+++ src/printf.c
@@ -258,16 +258,17 @@
258 if( db_get_boolean("timeline-block-markup", 0) ){
259 wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
260 }else{
261 wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
262 }
263 if( db_get_boolean("timeline-markdown-span", 0) ){
264 wikiFlags |= WIKI_MARKDOWN_SPAN;
265 }
266 if( db_get_boolean("timeline-plaintext", 0) ){
267 wikiFlags |= WIKI_LINKSONLY;
268 wikiFlags &= ~WIKI_MARKDOWN_SPAN;
 
 
 
 
269 }
270 if( db_get_boolean("timeline-hard-newlines", 0) ){
271 wikiFlags |= WIKI_NEWLINE;
272 }
273 }
274
--- src/printf.c
+++ src/printf.c
@@ -258,16 +258,17 @@
258 if( db_get_boolean("timeline-block-markup", 0) ){
259 wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
260 }else{
261 wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
262 }
 
 
 
263 if( db_get_boolean("timeline-plaintext", 0) ){
264 wikiFlags |= WIKI_LINKSONLY;
265 wikiFlags &= ~WIKI_MARKDOWN_INLINE;
266 }else{
267 int x = db_get_boolean("timeline-markdown", 0);
268 if( x & 1 ) wikiFlags |= WIKI_MARKDOWN_LINK;
269 if( x & 2 ) wikiFlags |= WIKI_MARKDOWN_FONT;
270 }
271 if( db_get_boolean("timeline-hard-newlines", 0) ){
272 wikiFlags |= WIKI_NEWLINE;
273 }
274 }
275
+19 -9
--- src/setup.c
+++ src/setup.c
@@ -985,10 +985,16 @@
985985
"1", "HH:MM:SS",
986986
"2", "YYYY-MM-DD HH:MM",
987987
"3", "YYMMDD HH:MM",
988988
"4", "(off)"
989989
};
990
+ static const char *const azMarkdown[] = {
991
+ "0", "none",
992
+ "1", "hyperlinks only",
993
+ "2", "styling only",
994
+ "3", "links and styling",
995
+ };
990996
login_check_credentials();
991997
if( !g.perm.Admin ){
992998
login_needed(0);
993999
return;
9941000
}
@@ -1006,25 +1012,29 @@
10061012
@ <p>In timeline displays, check-in comments can be displayed with or
10071013
@ without block markup such as paragraphs, tables, etc.
10081014
@ (Property: "timeline-block-markup")</p>
10091015
10101016
@ <hr>
1011
- onoff_attribute("Allow markdown style span-markup in timeline",
1012
- "timeline-markdown-span", "tms", 0, 0);
1013
- @ <p>In timeline displays, intrepret <a href="%R/md_rules">markdown</a>
1014
- @ span markup (hyperlinks and emphasis marks such as "<tt>**bold**</tt>"
1015
- @ but not headers, paragraphs, tables, footnotes, etc.) in check-in
1016
- @ comments. Without this option, only <a href="%R/wiki_rules">Fossil Wiki</a>
1017
- @ formatting is allowed.
1018
- @ (Property: "timeline-markdown-span")</p>
1017
+ multiple_choice_attribute("Allow Markdown in timeline comments",
1018
+ "timeline-markdown", "tmkdn", "0",
1019
+ count(azMarkdown)/2, azMarkdown);
1020
+ @ <p>Allow or disallow a limited amount of Markdown-style format marks
1021
+ @ for check-in comments displayed in the timeline. Normally check-in
1022
+ @ comments use only <a href="%R/wiki_rules">Fossil Wiki</a>. This option
1023
+ @ allows some types of Markdown to be used as well:
1024
+ @ <ul><li>hyperlinks: <b>(</b><i>display</i><b>)[</b><i>target</i><b>]</b> \
1025
+ @ and <b>&lt;</b><i>URL</i><b>&gt;</b>.
1026
+ @ <li>styling: *<i>emphasis</i>*, **<b>bold</b>**, `<tt>literal</tt>`, \
1027
+ @ <b>\</b>-escapes</ul>
1028
+ @ (Property: "timeline-markdown")</p>
10191029
10201030
@ <hr>
10211031
onoff_attribute("Plaintext comments on timelines",
10221032
"timeline-plaintext", "tpt", 0, 0);
10231033
@ <p>In timeline displays, check-in comments are displayed literally,
10241034
@ without any wiki or HTML interpretation. This setting takes priority
1025
- @ over the timeline-block-markup and timeline-markdown-span settings
1035
+ @ over the timeline-block-markup and timeline-markdown settings
10261036
@ above.
10271037
@ (Property: "timeline-plaintext")</p>
10281038
10291039
@ <hr>
10301040
onoff_attribute("Truncate comment at first blank line (Git-style)",
10311041
--- src/setup.c
+++ src/setup.c
@@ -985,10 +985,16 @@
985 "1", "HH:MM:SS",
986 "2", "YYYY-MM-DD HH:MM",
987 "3", "YYMMDD HH:MM",
988 "4", "(off)"
989 };
 
 
 
 
 
 
990 login_check_credentials();
991 if( !g.perm.Admin ){
992 login_needed(0);
993 return;
994 }
@@ -1006,25 +1012,29 @@
1006 @ <p>In timeline displays, check-in comments can be displayed with or
1007 @ without block markup such as paragraphs, tables, etc.
1008 @ (Property: "timeline-block-markup")</p>
1009
1010 @ <hr>
1011 onoff_attribute("Allow markdown style span-markup in timeline",
1012 "timeline-markdown-span", "tms", 0, 0);
1013 @ <p>In timeline displays, intrepret <a href="%R/md_rules">markdown</a>
1014 @ span markup (hyperlinks and emphasis marks such as "<tt>**bold**</tt>"
1015 @ but not headers, paragraphs, tables, footnotes, etc.) in check-in
1016 @ comments. Without this option, only <a href="%R/wiki_rules">Fossil Wiki</a>
1017 @ formatting is allowed.
1018 @ (Property: "timeline-markdown-span")</p>
 
 
 
 
1019
1020 @ <hr>
1021 onoff_attribute("Plaintext comments on timelines",
1022 "timeline-plaintext", "tpt", 0, 0);
1023 @ <p>In timeline displays, check-in comments are displayed literally,
1024 @ without any wiki or HTML interpretation. This setting takes priority
1025 @ over the timeline-block-markup and timeline-markdown-span settings
1026 @ above.
1027 @ (Property: "timeline-plaintext")</p>
1028
1029 @ <hr>
1030 onoff_attribute("Truncate comment at first blank line (Git-style)",
1031
--- src/setup.c
+++ src/setup.c
@@ -985,10 +985,16 @@
985 "1", "HH:MM:SS",
986 "2", "YYYY-MM-DD HH:MM",
987 "3", "YYMMDD HH:MM",
988 "4", "(off)"
989 };
990 static const char *const azMarkdown[] = {
991 "0", "none",
992 "1", "hyperlinks only",
993 "2", "styling only",
994 "3", "links and styling",
995 };
996 login_check_credentials();
997 if( !g.perm.Admin ){
998 login_needed(0);
999 return;
1000 }
@@ -1006,25 +1012,29 @@
1012 @ <p>In timeline displays, check-in comments can be displayed with or
1013 @ without block markup such as paragraphs, tables, etc.
1014 @ (Property: "timeline-block-markup")</p>
1015
1016 @ <hr>
1017 multiple_choice_attribute("Allow Markdown in timeline comments",
1018 "timeline-markdown", "tmkdn", "0",
1019 count(azMarkdown)/2, azMarkdown);
1020 @ <p>Allow or disallow a limited amount of Markdown-style format marks
1021 @ for check-in comments displayed in the timeline. Normally check-in
1022 @ comments use only <a href="%R/wiki_rules">Fossil Wiki</a>. This option
1023 @ allows some types of Markdown to be used as well:
1024 @ <ul><li>hyperlinks: <b>(</b><i>display</i><b>)[</b><i>target</i><b>]</b> \
1025 @ and <b>&lt;</b><i>URL</i><b>&gt;</b>.
1026 @ <li>styling: *<i>emphasis</i>*, **<b>bold</b>**, `<tt>literal</tt>`, \
1027 @ <b>\</b>-escapes</ul>
1028 @ (Property: "timeline-markdown")</p>
1029
1030 @ <hr>
1031 onoff_attribute("Plaintext comments on timelines",
1032 "timeline-plaintext", "tpt", 0, 0);
1033 @ <p>In timeline displays, check-in comments are displayed literally,
1034 @ without any wiki or HTML interpretation. This setting takes priority
1035 @ over the timeline-block-markup and timeline-markdown settings
1036 @ above.
1037 @ (Property: "timeline-plaintext")</p>
1038
1039 @ <hr>
1040 onoff_attribute("Truncate comment at first blank line (Git-style)",
1041
+37 -31
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -23,22 +23,24 @@
2323
2424
#if INTERFACE
2525
/*
2626
** Allowed wiki transformation operations
2727
*/
28
-#define WIKI_HTMLONLY 0x001 /* HTML markup only. No wiki */
29
-#define WIKI_INLINE 0x002 /* Do not surround with <p>..</p> */
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_SPAN 0x800 /* Interpret span elements of markdown */
28
+#define WIKI_HTMLONLY 0x0001 /* HTML markup only. No wiki */
29
+#define WIKI_INLINE 0x0002 /* Do not surround with <p>..</p> */
30
+#define WIKI_NOBLOCK 0x0004 /* No block markup of any kind */
31
+#define WIKI_BUTTONS 0x0008 /* Allow sub-menu buttons */
32
+#define WIKI_NOBADLINKS 0x0010 /* Ignore broken hyperlinks */
33
+#define WIKI_LINKSONLY 0x0020 /* No markup. Only decorate links */
34
+#define WIKI_NEWLINE 0x0040 /* Honor \n - break lines at each \n */
35
+#define WIKI_SAFE 0x0080 /* Make the result safe for embedding */
36
+#define WIKI_TARGET_BLANK 0x0100 /* Hyperlinks go to a new window */
37
+#define WIKI_NOBRACKET 0x0200 /* Omit extra [..] around hyperlinks */
38
+#define WIKI_MARKDOWN_URL 0x0400 /* Process link targets as in markdown */
39
+#define WIKI_MARKDOWN_FONT 0x0800 /* Accept markdown font/style markup */
40
+#define WIKI_MARKDOWN_LINK 0x1000 /* Accept markdown hyperlinks */
41
+#define WIKI_MARKDOWN_INLINE 0x1800 /* Combo of _FONT and _LINK */
4042
#endif
4143
4244
4345
/*
4446
** These are the only markup attributes allowed.
@@ -569,21 +571,21 @@
569571
**
570572
** <
571573
** &
572574
** \n
573575
** [
574
-** _ * ` \ <-- WIKI_MARKDOWN_SPAN only.
576
+** _ * ` \ <-- WIKI_MARKDOWN_FONT only.
575577
**
576578
** The "[" is only considered if flags contain ALLOW_LINKS or ALLOW_WIKI.
577579
** The "\n" is only considered interesting if the flags constains ALLOW_WIKI.
578580
** The markdown span characters, _ * ` and \, are only considered if both
579
-** ALLOW_WIKI and WIKI_MARKDOWN_SPAN are set.
581
+** ALLOW_WIKI and WIKI_MARKDOWN_FONT are set.
580582
*/
581583
static int textLength(const char *z, int flags){
582584
const char *zReject;
583585
if( flags & ALLOW_WIKI ){
584
- if( flags & WIKI_MARKDOWN_SPAN ){
586
+ if( flags & WIKI_MARKDOWN_FONT ){
585587
zReject = "_*`\\\n[<&";
586588
}else{
587589
zReject = "\n[<&";
588590
}
589591
}else if( flags & ALLOW_LINKS ){
@@ -1675,11 +1677,11 @@
16751677
char cS1 = 0;
16761678
int iS1 = 0;
16771679
16781680
startAutoParagraph(p);
16791681
if( z[n]=='('
1680
- && (p->state & WIKI_MARKDOWN_SPAN)!=0
1682
+ && (p->state & WIKI_MARKDOWN_LINK)!=0
16811683
&& (zEnd = strchr(z+n+1,')'))!=0
16821684
){
16831685
/* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
16841686
if( n>2 ){
16851687
zDisplay = &z[1];
@@ -1727,21 +1729,21 @@
17271729
blob_append(p->pOut, zClose, -1);
17281730
}
17291731
break;
17301732
}
17311733
case TOKEN_BACKSLASH: {
1732
- if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1734
+ if( (p->state & WIKI_MARKDOWN_FONT)==0 ){
17331735
/* Ignore backslashes in traditional Wiki */
17341736
blob_append_char(p->pOut, '\\');
17351737
n = 1;
17361738
}else{
17371739
blob_append_char(p->pOut, z[1]);
17381740
}
17391741
break;
17401742
}
17411743
case TOKEN_MDCODE: {
1742
- if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1744
+ if( (p->state & WIKI_MARKDOWN_FONT)==0 ){
17431745
blob_append(p->pOut, z, n);
17441746
}else{
17451747
int x = verbatimLength(p, z+n, n);
17461748
if( x==0 ){
17471749
blob_append(p->pOut, z, n);
@@ -1787,17 +1789,17 @@
17871789
** Originally, Fossil-Wiki would just display this as literal
17881790
** text, but as of 2025-03-04, it actually inserts an <a>..</a>
17891791
** for the hyperlink. The <...> delimiters are retained, however.
17901792
** Except in markdown-span mode, the <...> delimiters are omitted.
17911793
*/
1792
- if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1794
+ if( (p->state & WIKI_MARKDOWN_LINK)==0 ){
17931795
blob_append(p->pOut, "&lt;", 4);
17941796
}
17951797
z[n-1] = 0;
17961798
blob_appendf(p->pOut, "<a href=\"%h\">%h</a>", z+1, z+1);
17971799
z[n-1] = '>';
1798
- if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1800
+ if( (p->state & WIKI_MARKDOWN_LINK)==0 ){
17991801
blob_append(p->pOut, "&gt;", 4);
18001802
}
18011803
break;
18021804
}
18031805
case TOKEN_MARKUP: {
@@ -2071,19 +2073,21 @@
20712073
** Translate the input FILE from Fossil-wiki into HTML and write
20722074
** the resulting HTML on standard output.
20732075
**
20742076
** Options:
20752077
** --buttons Set the WIKI_BUTTONS flag
2076
-** --dark-pikchr Render pikchrs in dark mode
2077
-** --htmlonly Set the WIKI_HTMLONLY flag
2078
-** --inline Set the WIKI_INLINE flag
2079
-** --linksonly Set the WIKI_LINKSONLY flag
2080
-** --md-span Allow markdown span syntax: links and emphasis marks
2081
-** --nobadlinks Set the WIKI_NOBADLINKS flag
2082
-** --noblock Set the WIKI_NOBLOCK flag
2083
-** --text Run the output through html_to_plaintext().
2084
-** --tokenize Output a tokenization of the input file
2078
+** --dark-pikchr Render pikchrs in dark mode
2079
+** --htmlonly Set the WIKI_HTMLONLY flag
2080
+** --inline Set the WIKI_INLINE flag
2081
+** --linksonly Set the WIKI_LINKSONLY flag
2082
+** --markdown Allow all in-line markdown syntax
2083
+** --markdown-link Allow markdown hyperlink syntax
2084
+** --markdown-style Allow markdown font and style markup
2085
+** --nobadlinks Set the WIKI_NOBADLINKS flag
2086
+** --noblock Set the WIKI_NOBLOCK flag
2087
+** --text Run the output through html_to_plaintext().
2088
+** --tokenize Output a tokenization of the input file
20852089
*/
20862090
void test_wiki_render(void){
20872091
Blob in, out;
20882092
int flags = 0;
20892093
int bText, bTokenize;
@@ -2091,11 +2095,13 @@
20912095
if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY;
20922096
if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY;
20932097
if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS;
20942098
if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE;
20952099
if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK;
2096
- if( find_option("md-span",0,0)!=0 ) flags |= WIKI_MARKDOWN_SPAN;
2100
+ if( find_option("markdown",0,0)!=0 ) flags |= WIKI_MARKDOWN_INLINE;
2101
+ if( find_option("markdown-style",0,0)!=0 ) flags |= WIKI_MARKDOWN_FONT;
2102
+ if( find_option("markdown-link",0,0)!=0 ) flags |= WIKI_MARKDOWN_LINK;
20972103
if( find_option("dark-pikchr",0,0)!=0 ){
20982104
pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE );
20992105
}
21002106
bText = find_option("text",0,0)!=0;
21012107
bTokenize = find_option("tokenize",0,0)!=0;
@@ -2254,11 +2260,11 @@
22542260
case TOKEN_LINK: {
22552261
char *zTarget, *zEnd;
22562262
int i;
22572263
22582264
if( z[n]=='('
2259
- && (flags & WIKI_MARKDOWN_SPAN)!=0
2265
+ && (flags & WIKI_MARKDOWN_LINK)!=0
22602266
&& (zEnd = strchr(z+n+1,')'))!=0
22612267
){
22622268
/* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
22632269
z += n+1;
22642270
zTarget = z;
22652271
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -23,22 +23,24 @@
23
24 #if INTERFACE
25 /*
26 ** Allowed wiki transformation operations
27 */
28 #define WIKI_HTMLONLY 0x001 /* HTML markup only. No wiki */
29 #define WIKI_INLINE 0x002 /* Do not surround with <p>..</p> */
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_SPAN 0x800 /* Interpret span elements of markdown */
 
 
40 #endif
41
42
43 /*
44 ** These are the only markup attributes allowed.
@@ -569,21 +571,21 @@
569 **
570 ** <
571 ** &
572 ** \n
573 ** [
574 ** _ * ` \ <-- WIKI_MARKDOWN_SPAN only.
575 **
576 ** The "[" is only considered if flags contain ALLOW_LINKS or ALLOW_WIKI.
577 ** The "\n" is only considered interesting if the flags constains ALLOW_WIKI.
578 ** The markdown span characters, _ * ` and \, are only considered if both
579 ** ALLOW_WIKI and WIKI_MARKDOWN_SPAN are set.
580 */
581 static int textLength(const char *z, int flags){
582 const char *zReject;
583 if( flags & ALLOW_WIKI ){
584 if( flags & WIKI_MARKDOWN_SPAN ){
585 zReject = "_*`\\\n[<&";
586 }else{
587 zReject = "\n[<&";
588 }
589 }else if( flags & ALLOW_LINKS ){
@@ -1675,11 +1677,11 @@
1675 char cS1 = 0;
1676 int iS1 = 0;
1677
1678 startAutoParagraph(p);
1679 if( z[n]=='('
1680 && (p->state & WIKI_MARKDOWN_SPAN)!=0
1681 && (zEnd = strchr(z+n+1,')'))!=0
1682 ){
1683 /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
1684 if( n>2 ){
1685 zDisplay = &z[1];
@@ -1727,21 +1729,21 @@
1727 blob_append(p->pOut, zClose, -1);
1728 }
1729 break;
1730 }
1731 case TOKEN_BACKSLASH: {
1732 if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1733 /* Ignore backslashes in traditional Wiki */
1734 blob_append_char(p->pOut, '\\');
1735 n = 1;
1736 }else{
1737 blob_append_char(p->pOut, z[1]);
1738 }
1739 break;
1740 }
1741 case TOKEN_MDCODE: {
1742 if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1743 blob_append(p->pOut, z, n);
1744 }else{
1745 int x = verbatimLength(p, z+n, n);
1746 if( x==0 ){
1747 blob_append(p->pOut, z, n);
@@ -1787,17 +1789,17 @@
1787 ** Originally, Fossil-Wiki would just display this as literal
1788 ** text, but as of 2025-03-04, it actually inserts an <a>..</a>
1789 ** for the hyperlink. The <...> delimiters are retained, however.
1790 ** Except in markdown-span mode, the <...> delimiters are omitted.
1791 */
1792 if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1793 blob_append(p->pOut, "&lt;", 4);
1794 }
1795 z[n-1] = 0;
1796 blob_appendf(p->pOut, "<a href=\"%h\">%h</a>", z+1, z+1);
1797 z[n-1] = '>';
1798 if( (p->state & WIKI_MARKDOWN_SPAN)==0 ){
1799 blob_append(p->pOut, "&gt;", 4);
1800 }
1801 break;
1802 }
1803 case TOKEN_MARKUP: {
@@ -2071,19 +2073,21 @@
2071 ** Translate the input FILE from Fossil-wiki into HTML and write
2072 ** the resulting HTML on standard output.
2073 **
2074 ** Options:
2075 ** --buttons Set the WIKI_BUTTONS flag
2076 ** --dark-pikchr Render pikchrs in dark mode
2077 ** --htmlonly Set the WIKI_HTMLONLY flag
2078 ** --inline Set the WIKI_INLINE flag
2079 ** --linksonly Set the WIKI_LINKSONLY flag
2080 ** --md-span Allow markdown span syntax: links and emphasis marks
2081 ** --nobadlinks Set the WIKI_NOBADLINKS flag
2082 ** --noblock Set the WIKI_NOBLOCK flag
2083 ** --text Run the output through html_to_plaintext().
2084 ** --tokenize Output a tokenization of the input file
 
 
2085 */
2086 void test_wiki_render(void){
2087 Blob in, out;
2088 int flags = 0;
2089 int bText, bTokenize;
@@ -2091,11 +2095,13 @@
2091 if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY;
2092 if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY;
2093 if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS;
2094 if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE;
2095 if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK;
2096 if( find_option("md-span",0,0)!=0 ) flags |= WIKI_MARKDOWN_SPAN;
 
 
2097 if( find_option("dark-pikchr",0,0)!=0 ){
2098 pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE );
2099 }
2100 bText = find_option("text",0,0)!=0;
2101 bTokenize = find_option("tokenize",0,0)!=0;
@@ -2254,11 +2260,11 @@
2254 case TOKEN_LINK: {
2255 char *zTarget, *zEnd;
2256 int i;
2257
2258 if( z[n]=='('
2259 && (flags & WIKI_MARKDOWN_SPAN)!=0
2260 && (zEnd = strchr(z+n+1,')'))!=0
2261 ){
2262 /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
2263 z += n+1;
2264 zTarget = z;
2265
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -23,22 +23,24 @@
23
24 #if INTERFACE
25 /*
26 ** Allowed wiki transformation operations
27 */
28 #define WIKI_HTMLONLY 0x0001 /* HTML markup only. No wiki */
29 #define WIKI_INLINE 0x0002 /* Do not surround with <p>..</p> */
30 #define WIKI_NOBLOCK 0x0004 /* No block markup of any kind */
31 #define WIKI_BUTTONS 0x0008 /* Allow sub-menu buttons */
32 #define WIKI_NOBADLINKS 0x0010 /* Ignore broken hyperlinks */
33 #define WIKI_LINKSONLY 0x0020 /* No markup. Only decorate links */
34 #define WIKI_NEWLINE 0x0040 /* Honor \n - break lines at each \n */
35 #define WIKI_SAFE 0x0080 /* Make the result safe for embedding */
36 #define WIKI_TARGET_BLANK 0x0100 /* Hyperlinks go to a new window */
37 #define WIKI_NOBRACKET 0x0200 /* Omit extra [..] around hyperlinks */
38 #define WIKI_MARKDOWN_URL 0x0400 /* Process link targets as in markdown */
39 #define WIKI_MARKDOWN_FONT 0x0800 /* Accept markdown font/style markup */
40 #define WIKI_MARKDOWN_LINK 0x1000 /* Accept markdown hyperlinks */
41 #define WIKI_MARKDOWN_INLINE 0x1800 /* Combo of _FONT and _LINK */
42 #endif
43
44
45 /*
46 ** These are the only markup attributes allowed.
@@ -569,21 +571,21 @@
571 **
572 ** <
573 ** &
574 ** \n
575 ** [
576 ** _ * ` \ <-- WIKI_MARKDOWN_FONT only.
577 **
578 ** The "[" is only considered if flags contain ALLOW_LINKS or ALLOW_WIKI.
579 ** The "\n" is only considered interesting if the flags constains ALLOW_WIKI.
580 ** The markdown span characters, _ * ` and \, are only considered if both
581 ** ALLOW_WIKI and WIKI_MARKDOWN_FONT are set.
582 */
583 static int textLength(const char *z, int flags){
584 const char *zReject;
585 if( flags & ALLOW_WIKI ){
586 if( flags & WIKI_MARKDOWN_FONT ){
587 zReject = "_*`\\\n[<&";
588 }else{
589 zReject = "\n[<&";
590 }
591 }else if( flags & ALLOW_LINKS ){
@@ -1675,11 +1677,11 @@
1677 char cS1 = 0;
1678 int iS1 = 0;
1679
1680 startAutoParagraph(p);
1681 if( z[n]=='('
1682 && (p->state & WIKI_MARKDOWN_LINK)!=0
1683 && (zEnd = strchr(z+n+1,')'))!=0
1684 ){
1685 /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
1686 if( n>2 ){
1687 zDisplay = &z[1];
@@ -1727,21 +1729,21 @@
1729 blob_append(p->pOut, zClose, -1);
1730 }
1731 break;
1732 }
1733 case TOKEN_BACKSLASH: {
1734 if( (p->state & WIKI_MARKDOWN_FONT)==0 ){
1735 /* Ignore backslashes in traditional Wiki */
1736 blob_append_char(p->pOut, '\\');
1737 n = 1;
1738 }else{
1739 blob_append_char(p->pOut, z[1]);
1740 }
1741 break;
1742 }
1743 case TOKEN_MDCODE: {
1744 if( (p->state & WIKI_MARKDOWN_FONT)==0 ){
1745 blob_append(p->pOut, z, n);
1746 }else{
1747 int x = verbatimLength(p, z+n, n);
1748 if( x==0 ){
1749 blob_append(p->pOut, z, n);
@@ -1787,17 +1789,17 @@
1789 ** Originally, Fossil-Wiki would just display this as literal
1790 ** text, but as of 2025-03-04, it actually inserts an <a>..</a>
1791 ** for the hyperlink. The <...> delimiters are retained, however.
1792 ** Except in markdown-span mode, the <...> delimiters are omitted.
1793 */
1794 if( (p->state & WIKI_MARKDOWN_LINK)==0 ){
1795 blob_append(p->pOut, "&lt;", 4);
1796 }
1797 z[n-1] = 0;
1798 blob_appendf(p->pOut, "<a href=\"%h\">%h</a>", z+1, z+1);
1799 z[n-1] = '>';
1800 if( (p->state & WIKI_MARKDOWN_LINK)==0 ){
1801 blob_append(p->pOut, "&gt;", 4);
1802 }
1803 break;
1804 }
1805 case TOKEN_MARKUP: {
@@ -2071,19 +2073,21 @@
2073 ** Translate the input FILE from Fossil-wiki into HTML and write
2074 ** the resulting HTML on standard output.
2075 **
2076 ** Options:
2077 ** --buttons Set the WIKI_BUTTONS flag
2078 ** --dark-pikchr Render pikchrs in dark mode
2079 ** --htmlonly Set the WIKI_HTMLONLY flag
2080 ** --inline Set the WIKI_INLINE flag
2081 ** --linksonly Set the WIKI_LINKSONLY flag
2082 ** --markdown Allow all in-line markdown syntax
2083 ** --markdown-link Allow markdown hyperlink syntax
2084 ** --markdown-style Allow markdown font and style markup
2085 ** --nobadlinks Set the WIKI_NOBADLINKS flag
2086 ** --noblock Set the WIKI_NOBLOCK flag
2087 ** --text Run the output through html_to_plaintext().
2088 ** --tokenize Output a tokenization of the input file
2089 */
2090 void test_wiki_render(void){
2091 Blob in, out;
2092 int flags = 0;
2093 int bText, bTokenize;
@@ -2091,11 +2095,13 @@
2095 if( find_option("htmlonly",0,0)!=0 ) flags |= WIKI_HTMLONLY;
2096 if( find_option("linksonly",0,0)!=0 ) flags |= WIKI_LINKSONLY;
2097 if( find_option("nobadlinks",0,0)!=0 ) flags |= WIKI_NOBADLINKS;
2098 if( find_option("inline",0,0)!=0 ) flags |= WIKI_INLINE;
2099 if( find_option("noblock",0,0)!=0 ) flags |= WIKI_NOBLOCK;
2100 if( find_option("markdown",0,0)!=0 ) flags |= WIKI_MARKDOWN_INLINE;
2101 if( find_option("markdown-style",0,0)!=0 ) flags |= WIKI_MARKDOWN_FONT;
2102 if( find_option("markdown-link",0,0)!=0 ) flags |= WIKI_MARKDOWN_LINK;
2103 if( find_option("dark-pikchr",0,0)!=0 ){
2104 pikchr_to_html_add_flags( PIKCHR_PROCESS_DARK_MODE );
2105 }
2106 bText = find_option("text",0,0)!=0;
2107 bTokenize = find_option("tokenize",0,0)!=0;
@@ -2254,11 +2260,11 @@
2260 case TOKEN_LINK: {
2261 char *zTarget, *zEnd;
2262 int i;
2263
2264 if( z[n]=='('
2265 && (flags & WIKI_MARKDOWN_LINK)!=0
2266 && (zEnd = strchr(z+n+1,')'))!=0
2267 ){
2268 /* Markdown-style hyperlinks: [display-text](URL) or [](URL) */
2269 z += n+1;
2270 zTarget = z;
2271

Keyboard Shortcuts

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