Fossil SCM

Provide extra buttons to get to "Plaintext" views of tickets and ticket artifacts. Invert the order of ticket history so that the oldest changes are on top and more recent changes are appended. Reject [...] style hyperlinks if they do not begin with ./ or ../.

drh 2012-11-24 01:01 UTC ticket-enhancements
Commit aaa8e45b3626bfeaf0764090749b8b8ee31a0f6d
+1 -1
--- src/info.c
+++ src/info.c
@@ -1755,11 +1755,11 @@
17551755
@ </blockquote>
17561756
}
17571757
17581758
@ <div class="section">Changes</div>
17591759
@ <p>
1760
- ticket_output_change_artifact(pTktChng);
1760
+ ticket_output_change_artifact(pTktChng, 0);
17611761
manifest_destroy(pTktChng);
17621762
style_footer();
17631763
}
17641764
17651765
17661766
--- src/info.c
+++ src/info.c
@@ -1755,11 +1755,11 @@
1755 @ </blockquote>
1756 }
1757
1758 @ <div class="section">Changes</div>
1759 @ <p>
1760 ticket_output_change_artifact(pTktChng);
1761 manifest_destroy(pTktChng);
1762 style_footer();
1763 }
1764
1765
1766
--- src/info.c
+++ src/info.c
@@ -1755,11 +1755,11 @@
1755 @ </blockquote>
1756 }
1757
1758 @ <div class="section">Changes</div>
1759 @ <p>
1760 ticket_output_change_artifact(pTktChng, 0);
1761 manifest_destroy(pTktChng);
1762 style_footer();
1763 }
1764
1765
1766
+19 -1
--- src/report.c
+++ src/report.c
@@ -626,10 +626,13 @@
626626
int nCount; /* Row number */
627627
int nCol; /* Number of columns */
628628
int isMultirow; /* True if multiple table rows per query result row */
629629
int iNewRow; /* Index of first column that goes on separate row */
630630
int iBg; /* Index of column that defines background color */
631
+ int wikiFlags; /* Flags passed into wiki_convert() */
632
+ const char *zWikiStart; /* HTML before display of multi-line wiki */
633
+ const char *zWikiEnd; /* HTML after display of multi-line wiki */
631634
};
632635
633636
/*
634637
** The callback function for db_query
635638
*/
@@ -670,10 +673,23 @@
670673
}
671674
if( !pState->isMultirow ){
672675
if( azName[i][0]=='_' ){
673676
pState->isMultirow = 1;
674677
pState->iNewRow = i;
678
+ pState->wikiFlags = WIKI_NOBADLINKS;
679
+ pState->zWikiStart = "";
680
+ pState->zWikiEnd = "";
681
+ if( P("plaintext") ){
682
+ pState->wikiFlags |= WIKI_LINKSONLY;
683
+ pState->zWikiStart = "<pre class='verbatim'>";
684
+ pState->zWikiEnd = "</pre>";
685
+ style_submenu_element("Formatted", "Formatted",
686
+ "%R/rptview?rn=%d", pState->rn);
687
+ }else{
688
+ style_submenu_element("Plaintext", "Plaintext",
689
+ "%R/rptview?rn=%d&plaintext", pState->rn);
690
+ }
675691
}else{
676692
pState->nCol++;
677693
}
678694
}
679695
}
@@ -737,13 +753,15 @@
737753
}
738754
if( zData[0] ){
739755
Blob content;
740756
@ </tr>
741757
@ <tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
758
+ @ %s(pState->zWikiStart)
742759
blob_init(&content, zData, -1);
743
- wiki_convert(&content, 0, WIKI_NOBADLINKS);
760
+ wiki_convert(&content, 0, pState->wikiFlags);
744761
blob_reset(&content);
762
+ @ %s(pState->zWikiEnd)
745763
}
746764
}else if( azName[i][0]=='#' ){
747765
zTid = zData;
748766
@ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td>
749767
}else if( zData[0]==0 ){
750768
--- src/report.c
+++ src/report.c
@@ -626,10 +626,13 @@
626 int nCount; /* Row number */
627 int nCol; /* Number of columns */
628 int isMultirow; /* True if multiple table rows per query result row */
629 int iNewRow; /* Index of first column that goes on separate row */
630 int iBg; /* Index of column that defines background color */
 
 
 
631 };
632
633 /*
634 ** The callback function for db_query
635 */
@@ -670,10 +673,23 @@
670 }
671 if( !pState->isMultirow ){
672 if( azName[i][0]=='_' ){
673 pState->isMultirow = 1;
674 pState->iNewRow = i;
 
 
 
 
 
 
 
 
 
 
 
 
 
675 }else{
676 pState->nCol++;
677 }
678 }
679 }
@@ -737,13 +753,15 @@
737 }
738 if( zData[0] ){
739 Blob content;
740 @ </tr>
741 @ <tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
 
742 blob_init(&content, zData, -1);
743 wiki_convert(&content, 0, WIKI_NOBADLINKS);
744 blob_reset(&content);
 
745 }
746 }else if( azName[i][0]=='#' ){
747 zTid = zData;
748 @ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td>
749 }else if( zData[0]==0 ){
750
--- src/report.c
+++ src/report.c
@@ -626,10 +626,13 @@
626 int nCount; /* Row number */
627 int nCol; /* Number of columns */
628 int isMultirow; /* True if multiple table rows per query result row */
629 int iNewRow; /* Index of first column that goes on separate row */
630 int iBg; /* Index of column that defines background color */
631 int wikiFlags; /* Flags passed into wiki_convert() */
632 const char *zWikiStart; /* HTML before display of multi-line wiki */
633 const char *zWikiEnd; /* HTML after display of multi-line wiki */
634 };
635
636 /*
637 ** The callback function for db_query
638 */
@@ -670,10 +673,23 @@
673 }
674 if( !pState->isMultirow ){
675 if( azName[i][0]=='_' ){
676 pState->isMultirow = 1;
677 pState->iNewRow = i;
678 pState->wikiFlags = WIKI_NOBADLINKS;
679 pState->zWikiStart = "";
680 pState->zWikiEnd = "";
681 if( P("plaintext") ){
682 pState->wikiFlags |= WIKI_LINKSONLY;
683 pState->zWikiStart = "<pre class='verbatim'>";
684 pState->zWikiEnd = "</pre>";
685 style_submenu_element("Formatted", "Formatted",
686 "%R/rptview?rn=%d", pState->rn);
687 }else{
688 style_submenu_element("Plaintext", "Plaintext",
689 "%R/rptview?rn=%d&plaintext", pState->rn);
690 }
691 }else{
692 pState->nCol++;
693 }
694 }
695 }
@@ -737,13 +753,15 @@
753 }
754 if( zData[0] ){
755 Blob content;
756 @ </tr>
757 @ <tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
758 @ %s(pState->zWikiStart)
759 blob_init(&content, zData, -1);
760 wiki_convert(&content, 0, pState->wikiFlags);
761 blob_reset(&content);
762 @ %s(pState->zWikiEnd)
763 }
764 }else if( azName[i][0]=='#' ){
765 zTid = zData;
766 @ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td>
767 }else if( zData[0]==0 ){
768
+27 -9
--- src/tkt.c
+++ src/tkt.c
@@ -322,10 +322,16 @@
322322
if( g.perm.ApndTkt && g.perm.Attach ){
323323
style_submenu_element("Attach", "Add An Attachment",
324324
"%s/attachadd?tkt=%T&from=%s/tktview/%t",
325325
g.zTop, zUuid, g.zTop, zUuid);
326326
}
327
+ if( P("plaintext") ){
328
+ style_submenu_element("Formatted", "Formatted", "%R/tktview/%S", zUuid);
329
+ }else{
330
+ style_submenu_element("Plaintext", "Plaintext",
331
+ "%R/tktview/%S?plaintext", zUuid);
332
+ }
327333
style_header("View Ticket");
328334
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
329335
ticket_init();
330336
initializeVariablesFromCGI();
331337
initializeVariablesFromDb();
@@ -735,10 +741,11 @@
735741
void tkthistory_page(void){
736742
Stmt q;
737743
char *zTitle;
738744
const char *zUuid;
739745
int tagid;
746
+ int nChng = 0;
740747
741748
login_check_credentials();
742749
if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
743750
zUuid = PD("name","");
744751
zTitle = mprintf("History Of Ticket %h", zUuid);
@@ -772,11 +779,11 @@
772779
" UNION "
773780
"SELECT datetime(mtime,'localtime'), attachid, uuid, src, filename, user"
774781
" FROM attachment, blob"
775782
" WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
776783
" AND blob.rid=attachid"
777
- " ORDER BY 1 DESC",
784
+ " ORDER BY 1",
778785
tagid, tagid
779786
);
780787
while( db_step(&q)==SQLITE_ROW ){
781788
Manifest *pTicket;
782789
char zShort[12];
@@ -784,40 +791,48 @@
784791
int rid = db_column_int(&q, 1);
785792
const char *zChngUuid = db_column_text(&q, 2);
786793
const char *zFile = db_column_text(&q, 4);
787794
memcpy(zShort, zChngUuid, 10);
788795
zShort[10] = 0;
796
+ if( nChng==0 ){
797
+ @ <ol>
798
+ }
799
+ nChng++;
789800
if( zFile!=0 ){
790801
const char *zSrc = db_column_text(&q, 3);
791802
const char *zUser = db_column_text(&q, 5);
792803
if( zSrc==0 || zSrc[0]==0 ){
793804
@
794
- @ <p>Delete attachment "%h(zFile)"
805
+ @ <li><p>Delete attachment "%h(zFile)"
795806
}else{
796807
@
797
- @ <p>Add attachment "%h(zFile)"
808
+ @ <li><p>Add attachment
809
+ @ "%z(href("%R/artifact/%S",zSrc))%h(zFile)</a>"
798810
}
799811
@ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
800812
@ (rid %d(rid)) by
801813
hyperlink_to_user(zUser,zDate," on");
802814
hyperlink_to_date(zDate, ".</p>");
803815
}else{
804816
pTicket = manifest_get(rid, CFTYPE_TICKET);
805817
if( pTicket ){
806818
@
807
- @ <p>Ticket change
819
+ @ <li><p>Ticket change
808820
@ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
809821
@ (rid %d(rid)) by
810822
hyperlink_to_user(pTicket->zUser,zDate," on");
811823
hyperlink_to_date(zDate, ":");
812824
@ </p>
813
- ticket_output_change_artifact(pTicket);
825
+ ticket_output_change_artifact(pTicket, "a");
814826
}
815827
manifest_destroy(pTicket);
816828
}
817829
}
818830
db_finalize(&q);
831
+ if( nChng ){
832
+ @ </ol>
833
+ }
819834
style_footer();
820835
}
821836
822837
/*
823838
** Return TRUE if the given BLOB contains a newline character.
@@ -833,21 +848,22 @@
833848
834849
/*
835850
** The pTkt object is a ticket change artifact. Output a detailed
836851
** description of this object.
837852
*/
838
-void ticket_output_change_artifact(Manifest *pTkt){
853
+void ticket_output_change_artifact(Manifest *pTkt, const char *zListType){
839854
int i;
840855
int wikiFlags = WIKI_NOBADLINKS;
841856
const char *zBlock = "<blockquote>";
842857
const char *zEnd = "</blockquote>";
843858
if( P("plaintext")!=0 ){
844859
wikiFlags |= WIKI_LINKSONLY;
845860
zBlock = "<blockquote><pre class='verbatim'>";
846861
zEnd = "</pre></blockquote>";
847862
}
848
- @ <ol>
863
+ if( zListType==0 ) zListType = "1";
864
+ @ <ol type="%s(zListType)">
849865
for(i=0; i<pTkt->nField; i++){
850866
Blob val;
851867
const char *z;
852868
z = pTkt->aField[i].zName;
853869
blob_set(&val, pTkt->aField[i].zValue);
@@ -1057,21 +1073,23 @@
10571073
int tagid;
10581074
10591075
if ( i != g.argc ){
10601076
fossil_fatal("no other parameters expected to %s!",g.argv[2]);
10611077
}
1062
- tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zTktUuid);
1078
+ tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
1079
+ zTktUuid);
10631080
if( tagid==0 ){
10641081
fossil_fatal("no such ticket %h", zTktUuid);
10651082
}
10661083
db_prepare(&q,
10671084
"SELECT datetime(mtime,'localtime'), objid, uuid, NULL, NULL, NULL"
10681085
" FROM event, blob"
10691086
" WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)"
10701087
" AND blob.rid=event.objid"
10711088
" UNION "
1072
- "SELECT datetime(mtime,'localtime'), attachid, uuid, src, filename, user"
1089
+ "SELECT datetime(mtime,'localtime'), attachid, uuid, src, "
1090
+ " filename, user"
10731091
" FROM attachment, blob"
10741092
" WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
10751093
" AND blob.rid=attachid"
10761094
" ORDER BY 1 DESC",
10771095
tagid, tagid
10781096
--- src/tkt.c
+++ src/tkt.c
@@ -322,10 +322,16 @@
322 if( g.perm.ApndTkt && g.perm.Attach ){
323 style_submenu_element("Attach", "Add An Attachment",
324 "%s/attachadd?tkt=%T&from=%s/tktview/%t",
325 g.zTop, zUuid, g.zTop, zUuid);
326 }
 
 
 
 
 
 
327 style_header("View Ticket");
328 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
329 ticket_init();
330 initializeVariablesFromCGI();
331 initializeVariablesFromDb();
@@ -735,10 +741,11 @@
735 void tkthistory_page(void){
736 Stmt q;
737 char *zTitle;
738 const char *zUuid;
739 int tagid;
 
740
741 login_check_credentials();
742 if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
743 zUuid = PD("name","");
744 zTitle = mprintf("History Of Ticket %h", zUuid);
@@ -772,11 +779,11 @@
772 " UNION "
773 "SELECT datetime(mtime,'localtime'), attachid, uuid, src, filename, user"
774 " FROM attachment, blob"
775 " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
776 " AND blob.rid=attachid"
777 " ORDER BY 1 DESC",
778 tagid, tagid
779 );
780 while( db_step(&q)==SQLITE_ROW ){
781 Manifest *pTicket;
782 char zShort[12];
@@ -784,40 +791,48 @@
784 int rid = db_column_int(&q, 1);
785 const char *zChngUuid = db_column_text(&q, 2);
786 const char *zFile = db_column_text(&q, 4);
787 memcpy(zShort, zChngUuid, 10);
788 zShort[10] = 0;
 
 
 
 
789 if( zFile!=0 ){
790 const char *zSrc = db_column_text(&q, 3);
791 const char *zUser = db_column_text(&q, 5);
792 if( zSrc==0 || zSrc[0]==0 ){
793 @
794 @ <p>Delete attachment "%h(zFile)"
795 }else{
796 @
797 @ <p>Add attachment "%h(zFile)"
 
798 }
799 @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
800 @ (rid %d(rid)) by
801 hyperlink_to_user(zUser,zDate," on");
802 hyperlink_to_date(zDate, ".</p>");
803 }else{
804 pTicket = manifest_get(rid, CFTYPE_TICKET);
805 if( pTicket ){
806 @
807 @ <p>Ticket change
808 @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
809 @ (rid %d(rid)) by
810 hyperlink_to_user(pTicket->zUser,zDate," on");
811 hyperlink_to_date(zDate, ":");
812 @ </p>
813 ticket_output_change_artifact(pTicket);
814 }
815 manifest_destroy(pTicket);
816 }
817 }
818 db_finalize(&q);
 
 
 
819 style_footer();
820 }
821
822 /*
823 ** Return TRUE if the given BLOB contains a newline character.
@@ -833,21 +848,22 @@
833
834 /*
835 ** The pTkt object is a ticket change artifact. Output a detailed
836 ** description of this object.
837 */
838 void ticket_output_change_artifact(Manifest *pTkt){
839 int i;
840 int wikiFlags = WIKI_NOBADLINKS;
841 const char *zBlock = "<blockquote>";
842 const char *zEnd = "</blockquote>";
843 if( P("plaintext")!=0 ){
844 wikiFlags |= WIKI_LINKSONLY;
845 zBlock = "<blockquote><pre class='verbatim'>";
846 zEnd = "</pre></blockquote>";
847 }
848 @ <ol>
 
849 for(i=0; i<pTkt->nField; i++){
850 Blob val;
851 const char *z;
852 z = pTkt->aField[i].zName;
853 blob_set(&val, pTkt->aField[i].zValue);
@@ -1057,21 +1073,23 @@
1057 int tagid;
1058
1059 if ( i != g.argc ){
1060 fossil_fatal("no other parameters expected to %s!",g.argv[2]);
1061 }
1062 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zTktUuid);
 
1063 if( tagid==0 ){
1064 fossil_fatal("no such ticket %h", zTktUuid);
1065 }
1066 db_prepare(&q,
1067 "SELECT datetime(mtime,'localtime'), objid, uuid, NULL, NULL, NULL"
1068 " FROM event, blob"
1069 " WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)"
1070 " AND blob.rid=event.objid"
1071 " UNION "
1072 "SELECT datetime(mtime,'localtime'), attachid, uuid, src, filename, user"
 
1073 " FROM attachment, blob"
1074 " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
1075 " AND blob.rid=attachid"
1076 " ORDER BY 1 DESC",
1077 tagid, tagid
1078
--- src/tkt.c
+++ src/tkt.c
@@ -322,10 +322,16 @@
322 if( g.perm.ApndTkt && g.perm.Attach ){
323 style_submenu_element("Attach", "Add An Attachment",
324 "%s/attachadd?tkt=%T&from=%s/tktview/%t",
325 g.zTop, zUuid, g.zTop, zUuid);
326 }
327 if( P("plaintext") ){
328 style_submenu_element("Formatted", "Formatted", "%R/tktview/%S", zUuid);
329 }else{
330 style_submenu_element("Plaintext", "Plaintext",
331 "%R/tktview/%S?plaintext", zUuid);
332 }
333 style_header("View Ticket");
334 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
335 ticket_init();
336 initializeVariablesFromCGI();
337 initializeVariablesFromDb();
@@ -735,10 +741,11 @@
741 void tkthistory_page(void){
742 Stmt q;
743 char *zTitle;
744 const char *zUuid;
745 int tagid;
746 int nChng = 0;
747
748 login_check_credentials();
749 if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
750 zUuid = PD("name","");
751 zTitle = mprintf("History Of Ticket %h", zUuid);
@@ -772,11 +779,11 @@
779 " UNION "
780 "SELECT datetime(mtime,'localtime'), attachid, uuid, src, filename, user"
781 " FROM attachment, blob"
782 " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
783 " AND blob.rid=attachid"
784 " ORDER BY 1",
785 tagid, tagid
786 );
787 while( db_step(&q)==SQLITE_ROW ){
788 Manifest *pTicket;
789 char zShort[12];
@@ -784,40 +791,48 @@
791 int rid = db_column_int(&q, 1);
792 const char *zChngUuid = db_column_text(&q, 2);
793 const char *zFile = db_column_text(&q, 4);
794 memcpy(zShort, zChngUuid, 10);
795 zShort[10] = 0;
796 if( nChng==0 ){
797 @ <ol>
798 }
799 nChng++;
800 if( zFile!=0 ){
801 const char *zSrc = db_column_text(&q, 3);
802 const char *zUser = db_column_text(&q, 5);
803 if( zSrc==0 || zSrc[0]==0 ){
804 @
805 @ <li><p>Delete attachment "%h(zFile)"
806 }else{
807 @
808 @ <li><p>Add attachment
809 @ "%z(href("%R/artifact/%S",zSrc))%h(zFile)</a>"
810 }
811 @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
812 @ (rid %d(rid)) by
813 hyperlink_to_user(zUser,zDate," on");
814 hyperlink_to_date(zDate, ".</p>");
815 }else{
816 pTicket = manifest_get(rid, CFTYPE_TICKET);
817 if( pTicket ){
818 @
819 @ <li><p>Ticket change
820 @ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
821 @ (rid %d(rid)) by
822 hyperlink_to_user(pTicket->zUser,zDate," on");
823 hyperlink_to_date(zDate, ":");
824 @ </p>
825 ticket_output_change_artifact(pTicket, "a");
826 }
827 manifest_destroy(pTicket);
828 }
829 }
830 db_finalize(&q);
831 if( nChng ){
832 @ </ol>
833 }
834 style_footer();
835 }
836
837 /*
838 ** Return TRUE if the given BLOB contains a newline character.
@@ -833,21 +848,22 @@
848
849 /*
850 ** The pTkt object is a ticket change artifact. Output a detailed
851 ** description of this object.
852 */
853 void ticket_output_change_artifact(Manifest *pTkt, const char *zListType){
854 int i;
855 int wikiFlags = WIKI_NOBADLINKS;
856 const char *zBlock = "<blockquote>";
857 const char *zEnd = "</blockquote>";
858 if( P("plaintext")!=0 ){
859 wikiFlags |= WIKI_LINKSONLY;
860 zBlock = "<blockquote><pre class='verbatim'>";
861 zEnd = "</pre></blockquote>";
862 }
863 if( zListType==0 ) zListType = "1";
864 @ <ol type="%s(zListType)">
865 for(i=0; i<pTkt->nField; i++){
866 Blob val;
867 const char *z;
868 z = pTkt->aField[i].zName;
869 blob_set(&val, pTkt->aField[i].zValue);
@@ -1057,21 +1073,23 @@
1073 int tagid;
1074
1075 if ( i != g.argc ){
1076 fossil_fatal("no other parameters expected to %s!",g.argv[2]);
1077 }
1078 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",
1079 zTktUuid);
1080 if( tagid==0 ){
1081 fossil_fatal("no such ticket %h", zTktUuid);
1082 }
1083 db_prepare(&q,
1084 "SELECT datetime(mtime,'localtime'), objid, uuid, NULL, NULL, NULL"
1085 " FROM event, blob"
1086 " WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)"
1087 " AND blob.rid=event.objid"
1088 " UNION "
1089 "SELECT datetime(mtime,'localtime'), attachid, uuid, src, "
1090 " filename, user"
1091 " FROM attachment, blob"
1092 " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
1093 " AND blob.rid=attachid"
1094 " ORDER BY 1 DESC",
1095 tagid, tagid
1096
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1175,11 +1175,15 @@
11751175
|| strncmp(zTarget, "mailto:", 7)==0
11761176
){
11771177
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
11781178
}else if( zTarget[0]=='/' ){
11791179
blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget);
1180
- }else if( zTarget[0]=='.' || zTarget[0]=='#' ){
1180
+ }else if( zTarget[0]=='.'
1181
+ && (zTarget[1]=='/' || (zTarget[1]=='.' && zTarget[2]=='/'))
1182
+ && (p->state & WIKI_LINKSONLY)==0 ){
1183
+ blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1184
+ }else if( zTarget[0]=='#' ){
11811185
blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
11821186
}else if( is_valid_uuid(zTarget) ){
11831187
int isClosed = 0;
11841188
if( is_ticket(zTarget, &isClosed) ){
11851189
/* Special display processing for tickets. Display the hyperlink
11861190
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1175,11 +1175,15 @@
1175 || strncmp(zTarget, "mailto:", 7)==0
1176 ){
1177 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
1178 }else if( zTarget[0]=='/' ){
1179 blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget);
1180 }else if( zTarget[0]=='.' || zTarget[0]=='#' ){
 
 
 
 
1181 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1182 }else if( is_valid_uuid(zTarget) ){
1183 int isClosed = 0;
1184 if( is_ticket(zTarget, &isClosed) ){
1185 /* Special display processing for tickets. Display the hyperlink
1186
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1175,11 +1175,15 @@
1175 || strncmp(zTarget, "mailto:", 7)==0
1176 ){
1177 blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
1178 }else if( zTarget[0]=='/' ){
1179 blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget);
1180 }else if( zTarget[0]=='.'
1181 && (zTarget[1]=='/' || (zTarget[1]=='.' && zTarget[2]=='/'))
1182 && (p->state & WIKI_LINKSONLY)==0 ){
1183 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1184 }else if( zTarget[0]=='#' ){
1185 blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
1186 }else if( is_valid_uuid(zTarget) ){
1187 int isClosed = 0;
1188 if( is_ticket(zTarget, &isClosed) ){
1189 /* Special display processing for tickets. Display the hyperlink
1190

Keyboard Shortcuts

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