Fossil SCM

Add support for magic conversion of /doc/$SELF/ URIs by expanding the $SELF to the version of the currently displayed document.

drh 2019-12-18 15:11 trunk
Commit 703e62a68e87aea76d753ffb0410ea2997f5b88dc7cb99191a40f78ffd099dcd
2 files changed +42 +49 -2
+42
--- src/doc.c
+++ src/doc.c
@@ -507,10 +507,39 @@
507507
if( rid && content_get(rid, pContent)==0 ){
508508
rid = 0;
509509
}
510510
return rid;
511511
}
512
+
513
+/*
514
+** Check to verify that z[i] is contained within HTML markup.
515
+**
516
+** This works by looking backwards in the string for the most recent
517
+** '<' or '>' character. If a '<' is found first, then we assume that
518
+** z[i] is within markup. If a '>' is seen or neither character is seen,
519
+** then z[i] is not within markup.
520
+*/
521
+static int isWithinHtmlMarkup(const char *z, int i){
522
+ while( i>=0 && z[i]!='>' && z[i]!='<' ){ i--; }
523
+ return z[i]=='<';
524
+}
525
+
526
+/*
527
+** Check to see if z[i] is contained within an href='...' of markup.
528
+*/
529
+static int isWithinHref(const char *z, int i){
530
+ while( i>5
531
+ && !fossil_isspace(z[i])
532
+ && z[i]!='\'' && z[i]!='"'
533
+ && z[i]!='>'
534
+ ){ i--; }
535
+ if( i<=6 ) return 0;
536
+ if( z[i]!='\'' && z[i]!='\"' ) return 0;
537
+ if( strncmp(&z[i-5],"href=",5)!=0 ) return 0;
538
+ if( !fossil_isspace(z[i-6]) ) return 0;
539
+ return 1;
540
+}
512541
513542
/*
514543
** Transfer content to the output. During the transfer, when text of
515544
** the following form is seen:
516545
**
@@ -529,14 +558,27 @@
529558
&& strncmp(&z[i],"$ROOT/", 6)==0
530559
&& (z[i-1]=='\'' || z[i-1]=='"')
531560
&& i-base>=9
532561
&& ((fossil_strnicmp(&z[i-6],"href=",5)==0 && fossil_isspace(z[i-7])) ||
533562
(fossil_strnicmp(&z[i-8],"action=",7)==0 && fossil_isspace(z[i-9])) )
563
+ && isWithinHtmlMarkup(z, i-6)
534564
){
535565
blob_append(cgi_output_blob(), &z[base], i-base);
536566
blob_appendf(cgi_output_blob(), "%R");
537567
base = i+5;
568
+ }else
569
+ if( z[i]=='$'
570
+ && strncmp(&z[i-5],"/doc/$SELF/", 11)==0
571
+ && isWithinHref(z,i-5)
572
+ && isWithinHtmlMarkup(z, i-5)
573
+ && strncmp(g.zPath, "doc/",4)==0
574
+ ){
575
+ int j;
576
+ for(j=4; g.zPath[j] && g.zPath[j]!='/'; j++){}
577
+ blob_append(cgi_output_blob(), &z[base], i-base);
578
+ blob_appendf(cgi_output_blob(), "%.*s", j-4, g.zPath+4);
579
+ base = i+5;
538580
}
539581
}
540582
blob_append(cgi_output_blob(), &z[base], i-base);
541583
}
542584
543585
--- src/doc.c
+++ src/doc.c
@@ -507,10 +507,39 @@
507 if( rid && content_get(rid, pContent)==0 ){
508 rid = 0;
509 }
510 return rid;
511 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
513 /*
514 ** Transfer content to the output. During the transfer, when text of
515 ** the following form is seen:
516 **
@@ -529,14 +558,27 @@
529 && strncmp(&z[i],"$ROOT/", 6)==0
530 && (z[i-1]=='\'' || z[i-1]=='"')
531 && i-base>=9
532 && ((fossil_strnicmp(&z[i-6],"href=",5)==0 && fossil_isspace(z[i-7])) ||
533 (fossil_strnicmp(&z[i-8],"action=",7)==0 && fossil_isspace(z[i-9])) )
 
534 ){
535 blob_append(cgi_output_blob(), &z[base], i-base);
536 blob_appendf(cgi_output_blob(), "%R");
537 base = i+5;
 
 
 
 
 
 
 
 
 
 
 
 
538 }
539 }
540 blob_append(cgi_output_blob(), &z[base], i-base);
541 }
542
543
--- src/doc.c
+++ src/doc.c
@@ -507,10 +507,39 @@
507 if( rid && content_get(rid, pContent)==0 ){
508 rid = 0;
509 }
510 return rid;
511 }
512
513 /*
514 ** Check to verify that z[i] is contained within HTML markup.
515 **
516 ** This works by looking backwards in the string for the most recent
517 ** '<' or '>' character. If a '<' is found first, then we assume that
518 ** z[i] is within markup. If a '>' is seen or neither character is seen,
519 ** then z[i] is not within markup.
520 */
521 static int isWithinHtmlMarkup(const char *z, int i){
522 while( i>=0 && z[i]!='>' && z[i]!='<' ){ i--; }
523 return z[i]=='<';
524 }
525
526 /*
527 ** Check to see if z[i] is contained within an href='...' of markup.
528 */
529 static int isWithinHref(const char *z, int i){
530 while( i>5
531 && !fossil_isspace(z[i])
532 && z[i]!='\'' && z[i]!='"'
533 && z[i]!='>'
534 ){ i--; }
535 if( i<=6 ) return 0;
536 if( z[i]!='\'' && z[i]!='\"' ) return 0;
537 if( strncmp(&z[i-5],"href=",5)!=0 ) return 0;
538 if( !fossil_isspace(z[i-6]) ) return 0;
539 return 1;
540 }
541
542 /*
543 ** Transfer content to the output. During the transfer, when text of
544 ** the following form is seen:
545 **
@@ -529,14 +558,27 @@
558 && strncmp(&z[i],"$ROOT/", 6)==0
559 && (z[i-1]=='\'' || z[i-1]=='"')
560 && i-base>=9
561 && ((fossil_strnicmp(&z[i-6],"href=",5)==0 && fossil_isspace(z[i-7])) ||
562 (fossil_strnicmp(&z[i-8],"action=",7)==0 && fossil_isspace(z[i-9])) )
563 && isWithinHtmlMarkup(z, i-6)
564 ){
565 blob_append(cgi_output_blob(), &z[base], i-base);
566 blob_appendf(cgi_output_blob(), "%R");
567 base = i+5;
568 }else
569 if( z[i]=='$'
570 && strncmp(&z[i-5],"/doc/$SELF/", 11)==0
571 && isWithinHref(z,i-5)
572 && isWithinHtmlMarkup(z, i-5)
573 && strncmp(g.zPath, "doc/",4)==0
574 ){
575 int j;
576 for(j=4; g.zPath[j] && g.zPath[j]!='/'; j++){}
577 blob_append(cgi_output_blob(), &z[base], i-base);
578 blob_appendf(cgi_output_blob(), "%.*s", j-4, g.zPath+4);
579 base = i+5;
580 }
581 }
582 blob_append(cgi_output_blob(), &z[base], i-base);
583 }
584
585
--- www/mdtest/test1.md
+++ www/mdtest/test1.md
@@ -1,12 +1,59 @@
11
# Markdown Link-test
22
3
-This document exist solely to test relative-path linking capabilities
4
-in markdown.
3
+This document exist solely as a test for some of the hyperlinking
4
+capabilities of Markdown as implemented by Fossil.
5
+
6
+## Relative-Path Links
57
68
* The index: [](../index.wiki)
79
810
* Load management: [](../loadmgmt.md)
911
1012
* Site-map: [](../../../../sitemap)
1113
1214
* Windows CGI: [](../server/windows/cgi.md)
15
+
16
+## The Magic $ROOT Path Prefix
17
+
18
+In text of the form `href="$ROOT/..."` in the HTML that markdown
19
+generates, the $ROOT is replaced by the complete URI for the root
20
+of the document tree.
21
+Note that the $ROOT translation only occurs within the `<a href="...">`
22
+element, not within the text of the hyperlink. So you should see the
23
+$ROOT text on this page, but if you mouse-over the hyperlink the $ROOT
24
+value should have been expanded to the actual document root.
25
+
26
+ * Timeline: []($ROOT/timeline)
27
+
28
+ * Site-map: []($ROOT/sitemap)
29
+
30
+The $ROOT prefix on markdown links is superfluous. The same link
31
+works without the $ROOT prefix. (Though: the $ROOT prefix is required
32
+for HTML documents.)
33
+
34
+ * Timeline: [](/timeline)
35
+
36
+ * Help: [](/help?cmd=help)
37
+
38
+ * Site-map: [](/sitemap)
39
+
40
+## The Magic $SELF Document Version Translation
41
+
42
+In URI text of the form `.../doc/$SELF/...` the
43
+$SELF value is converted to the version number of the document
44
+currently being displayed. This conversion happens after translation
45
+into HTML and only occurs on href='...' attributes so it does not occur
46
+for plain text.
47
+
48
+ * Document index: [](/doc/$SELF/www/index.wiki)
49
+
50
+Both the $ROOT and the $SELF conversions can occur on the same link.
51
+
52
+ * Document index: []($ROOT/doc/$SELF/www/index.wiki)
53
+
54
+The translations must be contained within HTML markup in order to work.
55
+They do not work for ordinary text that appears to be an href= attribute.
56
+
57
+ * `x href='$ROOT/timeline'`
58
+ * `x action="$ROOT/whatever"`
59
+ * `x href="https://some-other-site.com/doc/$SELF/tail"`
1360
--- www/mdtest/test1.md
+++ www/mdtest/test1.md
@@ -1,12 +1,59 @@
1 # Markdown Link-test
2
3 This document exist solely to test relative-path linking capabilities
4 in markdown.
 
 
5
6 * The index: [](../index.wiki)
7
8 * Load management: [](../loadmgmt.md)
9
10 * Site-map: [](../../../../sitemap)
11
12 * Windows CGI: [](../server/windows/cgi.md)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
--- www/mdtest/test1.md
+++ www/mdtest/test1.md
@@ -1,12 +1,59 @@
1 # Markdown Link-test
2
3 This document exist solely as a test for some of the hyperlinking
4 capabilities of Markdown as implemented by Fossil.
5
6 ## Relative-Path Links
7
8 * The index: [](../index.wiki)
9
10 * Load management: [](../loadmgmt.md)
11
12 * Site-map: [](../../../../sitemap)
13
14 * Windows CGI: [](../server/windows/cgi.md)
15
16 ## The Magic $ROOT Path Prefix
17
18 In text of the form `href="$ROOT/..."` in the HTML that markdown
19 generates, the $ROOT is replaced by the complete URI for the root
20 of the document tree.
21 Note that the $ROOT translation only occurs within the `<a href="...">`
22 element, not within the text of the hyperlink. So you should see the
23 $ROOT text on this page, but if you mouse-over the hyperlink the $ROOT
24 value should have been expanded to the actual document root.
25
26 * Timeline: []($ROOT/timeline)
27
28 * Site-map: []($ROOT/sitemap)
29
30 The $ROOT prefix on markdown links is superfluous. The same link
31 works without the $ROOT prefix. (Though: the $ROOT prefix is required
32 for HTML documents.)
33
34 * Timeline: [](/timeline)
35
36 * Help: [](/help?cmd=help)
37
38 * Site-map: [](/sitemap)
39
40 ## The Magic $SELF Document Version Translation
41
42 In URI text of the form `.../doc/$SELF/...` the
43 $SELF value is converted to the version number of the document
44 currently being displayed. This conversion happens after translation
45 into HTML and only occurs on href='...' attributes so it does not occur
46 for plain text.
47
48 * Document index: [](/doc/$SELF/www/index.wiki)
49
50 Both the $ROOT and the $SELF conversions can occur on the same link.
51
52 * Document index: []($ROOT/doc/$SELF/www/index.wiki)
53
54 The translations must be contained within HTML markup in order to work.
55 They do not work for ordinary text that appears to be an href= attribute.
56
57 * `x href='$ROOT/timeline'`
58 * `x action="$ROOT/whatever"`
59 * `x href="https://some-other-site.com/doc/$SELF/tail"`
60

Keyboard Shortcuts

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