Fossil SCM

All markup of the form <verbatim-ID>...</verbatim> with an options "links" or "links=BOOLEAN" attribute. Improved TH1 tracing and error reporting capabilities. Improved documentation on how reports work.

drh 2012-11-23 15:57 UTC trunk
Commit 23c75abde4e26afd24715f69f69af05702e3f0b0
+4
--- src/main.c
+++ src/main.c
@@ -1850,10 +1850,14 @@
18501850
**
18511851
** COMMAND: test-http
18521852
** Works like the http command but gives setup permission to all users.
18531853
*/
18541854
void cmd_test_http(void){
1855
+ g.thTrace = find_option("th-trace", 0, 0)!=0;
1856
+ if( g.thTrace ){
1857
+ blob_zero(&g.thLog);
1858
+ }
18551859
login_set_capabilities("sx", 0);
18561860
g.useLocalauth = 1;
18571861
cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
18581862
g.httpIn = stdin;
18591863
g.httpOut = stdout;
18601864
--- src/main.c
+++ src/main.c
@@ -1850,10 +1850,14 @@
1850 **
1851 ** COMMAND: test-http
1852 ** Works like the http command but gives setup permission to all users.
1853 */
1854 void cmd_test_http(void){
 
 
 
 
1855 login_set_capabilities("sx", 0);
1856 g.useLocalauth = 1;
1857 cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
1858 g.httpIn = stdin;
1859 g.httpOut = stdout;
1860
--- src/main.c
+++ src/main.c
@@ -1850,10 +1850,14 @@
1850 **
1851 ** COMMAND: test-http
1852 ** Works like the http command but gives setup permission to all users.
1853 */
1854 void cmd_test_http(void){
1855 g.thTrace = find_option("th-trace", 0, 0)!=0;
1856 if( g.thTrace ){
1857 blob_zero(&g.thLog);
1858 }
1859 login_set_capabilities("sx", 0);
1860 g.useLocalauth = 1;
1861 cgi_set_parameter("REMOTE_ADDR", "127.0.0.1");
1862 g.httpIn = stdin;
1863 g.httpOut = stdout;
1864
+13 -5
--- src/report.c
+++ src/report.c
@@ -488,14 +488,21 @@
488488
@ is assumed to hold a ticket number. A hyperlink will be created from
489489
@ that column to a detailed view of the ticket.</p></li>
490490
@
491491
@ <li><p>If a column of the result set is named "bgcolor" then the content
492492
@ of that column determines the background color of the row.</p></li>
493
+ @
494
+ @ <li><p>The text of all columns prior to the first column whose name begins
495
+ @ with underscore ("_") is shown character-for-character as it appears in
496
+ @ the database. In other words, it is assumed to have a mimetype of
497
+ @ text/plain.
493498
@
494499
@ <li><p>The first column whose name begins with underscore ("_") and all
495
- @ subsequent columns are shown on their own rows in the table. This might
496
- @ be useful for displaying the description of tickets.
500
+ @ subsequent columns are shown on their own rows in the table and with
501
+ @ wiki formatting. In other words, such rows are shown with a mimetype
502
+ @ of text/x-fossil-wiki. This is recommended for the "description" field
503
+ @ of tickets.
497504
@ </p></li>
498505
@
499506
@ <li><p>The query can join other tables in the database besides TICKET.
500507
@ </p></li>
501508
@ </ul>
@@ -589,12 +596,12 @@
589596
@ sdate(changetime) AS 'Changed',
590597
@ assignedto AS 'Assigned',
591598
@ severity AS 'Svr',
592599
@ priority AS 'Pri',
593600
@ title AS 'Title',
594
- @ description AS '_Description', -- When the column name begins with '_'
595
- @ remarks AS '_Remarks' -- the data is shown on a separate row.
601
+ @ description AS '_Description', -- When the column name begins with '_'
602
+ @ remarks AS '_Remarks' -- content is rendered as wiki
596603
@ FROM ticket
597604
@ </pre></blockquote>
598605
@
599606
@ <p>Or, to see part of the description on the same row, use the
600607
@ <b>wiki()</b> function with some string manipulation. Using the
@@ -728,11 +735,12 @@
728735
@ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
729736
zTid = 0;
730737
}
731738
if( zData[0] ){
732739
Blob content;
733
- @ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
740
+ @ </tr>
741
+ @ <tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
734742
blob_init(&content, zData, -1);
735743
wiki_convert(&content, 0, WIKI_NOBADLINKS);
736744
blob_reset(&content);
737745
}
738746
}else if( azName[i][0]=='#' ){
739747
--- src/report.c
+++ src/report.c
@@ -488,14 +488,21 @@
488 @ is assumed to hold a ticket number. A hyperlink will be created from
489 @ that column to a detailed view of the ticket.</p></li>
490 @
491 @ <li><p>If a column of the result set is named "bgcolor" then the content
492 @ of that column determines the background color of the row.</p></li>
 
 
 
 
 
493 @
494 @ <li><p>The first column whose name begins with underscore ("_") and all
495 @ subsequent columns are shown on their own rows in the table. This might
496 @ be useful for displaying the description of tickets.
 
 
497 @ </p></li>
498 @
499 @ <li><p>The query can join other tables in the database besides TICKET.
500 @ </p></li>
501 @ </ul>
@@ -589,12 +596,12 @@
589 @ sdate(changetime) AS 'Changed',
590 @ assignedto AS 'Assigned',
591 @ severity AS 'Svr',
592 @ priority AS 'Pri',
593 @ title AS 'Title',
594 @ description AS '_Description', -- When the column name begins with '_'
595 @ remarks AS '_Remarks' -- the data is shown on a separate row.
596 @ FROM ticket
597 @ </pre></blockquote>
598 @
599 @ <p>Or, to see part of the description on the same row, use the
600 @ <b>wiki()</b> function with some string manipulation. Using the
@@ -728,11 +735,12 @@
728 @ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
729 zTid = 0;
730 }
731 if( zData[0] ){
732 Blob content;
733 @ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
 
734 blob_init(&content, zData, -1);
735 wiki_convert(&content, 0, WIKI_NOBADLINKS);
736 blob_reset(&content);
737 }
738 }else if( azName[i][0]=='#' ){
739
--- src/report.c
+++ src/report.c
@@ -488,14 +488,21 @@
488 @ is assumed to hold a ticket number. A hyperlink will be created from
489 @ that column to a detailed view of the ticket.</p></li>
490 @
491 @ <li><p>If a column of the result set is named "bgcolor" then the content
492 @ of that column determines the background color of the row.</p></li>
493 @
494 @ <li><p>The text of all columns prior to the first column whose name begins
495 @ with underscore ("_") is shown character-for-character as it appears in
496 @ the database. In other words, it is assumed to have a mimetype of
497 @ text/plain.
498 @
499 @ <li><p>The first column whose name begins with underscore ("_") and all
500 @ subsequent columns are shown on their own rows in the table and with
501 @ wiki formatting. In other words, such rows are shown with a mimetype
502 @ of text/x-fossil-wiki. This is recommended for the "description" field
503 @ of tickets.
504 @ </p></li>
505 @
506 @ <li><p>The query can join other tables in the database besides TICKET.
507 @ </p></li>
508 @ </ul>
@@ -589,12 +596,12 @@
596 @ sdate(changetime) AS 'Changed',
597 @ assignedto AS 'Assigned',
598 @ severity AS 'Svr',
599 @ priority AS 'Pri',
600 @ title AS 'Title',
601 @ description AS '_Description', -- When the column name begins with '_'
602 @ remarks AS '_Remarks' -- content is rendered as wiki
603 @ FROM ticket
604 @ </pre></blockquote>
605 @
606 @ <p>Or, to see part of the description on the same row, use the
607 @ <b>wiki()</b> function with some string manipulation. Using the
@@ -728,11 +735,12 @@
735 @ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
736 zTid = 0;
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
+14 -3
--- src/th_main.c
+++ src/th_main.c
@@ -72,14 +72,19 @@
7272
void *p,
7373
int argc,
7474
const char **argv,
7575
int *argl
7676
){
77
- if( argc!=2 ){
78
- return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
77
+ int rc;
78
+ if( argc<2 || argc>3 ){
79
+ return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN");
80
+ }
81
+ rc = Th_ToInt(interp, argv[argc-1], argl[argc-1], &enableOutput);
82
+ if( g.thTrace ){
83
+ Th_Trace("enable_output {%.*s} -> %d<br>\n", argl[1],argv[1],enableOutput);
7984
}
80
- return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
85
+ return rc;
8186
}
8287
8388
/*
8489
** Return a name for a TH1 return code.
8590
*/
@@ -119,16 +124,19 @@
119124
if( encode ) free((char*)z);
120125
}
121126
}
122127
123128
static void sendError(const char *z, int n, int forceCgi){
129
+ int savedEnable = enableOutput;
130
+ enableOutput = 1;
124131
if( forceCgi || g.cgiOutput ){
125132
sendText("<hr><p class=\"thmainError\">", -1, 0);
126133
}
127134
sendText("ERROR: ", -1, 0);
128135
sendText((char*)z, n, 1);
129136
sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
137
+ enableOutput = savedEnable;
130138
}
131139
132140
/*
133141
** TH command: puts STRING
134142
** TH command: html STRING
@@ -801,10 +809,13 @@
801809
sendText((char*)zResult, n, encode);
802810
}else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
803811
sendText(z, i, 0);
804812
z += i+5;
805813
for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
814
+ if( g.thTrace ){
815
+ Th_Trace("eval %d{<pre>%.*h</pre>}<br>", i, i, z);
816
+ }
806817
rc = Th_Eval(g.interp, 0, (const char*)z, i);
807818
if( rc!=TH_OK ) break;
808819
z += i;
809820
if( z[0] ){ z += 6; }
810821
i = 0;
811822
--- src/th_main.c
+++ src/th_main.c
@@ -72,14 +72,19 @@
72 void *p,
73 int argc,
74 const char **argv,
75 int *argl
76 ){
77 if( argc!=2 ){
78 return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
 
 
 
 
 
79 }
80 return Th_ToInt(interp, argv[1], argl[1], &enableOutput);
81 }
82
83 /*
84 ** Return a name for a TH1 return code.
85 */
@@ -119,16 +124,19 @@
119 if( encode ) free((char*)z);
120 }
121 }
122
123 static void sendError(const char *z, int n, int forceCgi){
 
 
124 if( forceCgi || g.cgiOutput ){
125 sendText("<hr><p class=\"thmainError\">", -1, 0);
126 }
127 sendText("ERROR: ", -1, 0);
128 sendText((char*)z, n, 1);
129 sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
 
130 }
131
132 /*
133 ** TH command: puts STRING
134 ** TH command: html STRING
@@ -801,10 +809,13 @@
801 sendText((char*)zResult, n, encode);
802 }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
803 sendText(z, i, 0);
804 z += i+5;
805 for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
 
 
 
806 rc = Th_Eval(g.interp, 0, (const char*)z, i);
807 if( rc!=TH_OK ) break;
808 z += i;
809 if( z[0] ){ z += 6; }
810 i = 0;
811
--- src/th_main.c
+++ src/th_main.c
@@ -72,14 +72,19 @@
72 void *p,
73 int argc,
74 const char **argv,
75 int *argl
76 ){
77 int rc;
78 if( argc<2 || argc>3 ){
79 return Th_WrongNumArgs(interp, "enable_output [LABEL] BOOLEAN");
80 }
81 rc = Th_ToInt(interp, argv[argc-1], argl[argc-1], &enableOutput);
82 if( g.thTrace ){
83 Th_Trace("enable_output {%.*s} -> %d<br>\n", argl[1],argv[1],enableOutput);
84 }
85 return rc;
86 }
87
88 /*
89 ** Return a name for a TH1 return code.
90 */
@@ -119,16 +124,19 @@
124 if( encode ) free((char*)z);
125 }
126 }
127
128 static void sendError(const char *z, int n, int forceCgi){
129 int savedEnable = enableOutput;
130 enableOutput = 1;
131 if( forceCgi || g.cgiOutput ){
132 sendText("<hr><p class=\"thmainError\">", -1, 0);
133 }
134 sendText("ERROR: ", -1, 0);
135 sendText((char*)z, n, 1);
136 sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
137 enableOutput = savedEnable;
138 }
139
140 /*
141 ** TH command: puts STRING
142 ** TH command: html STRING
@@ -801,10 +809,13 @@
809 sendText((char*)zResult, n, encode);
810 }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
811 sendText(z, i, 0);
812 z += i+5;
813 for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
814 if( g.thTrace ){
815 Th_Trace("eval %d{<pre>%.*h</pre>}<br>", i, i, z);
816 }
817 rc = Th_Eval(g.interp, 0, (const char*)z, i);
818 if( rc!=TH_OK ) break;
819 z += i;
820 if( z[0] ){ z += 6; }
821 i = 0;
822
+49 -37
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -51,22 +51,23 @@
5151
#define ATTR_FACE 12
5252
#define ATTR_HEIGHT 13
5353
#define ATTR_HREF 14
5454
#define ATTR_HSPACE 15
5555
#define ATTR_ID 16
56
-#define ATTR_NAME 17
57
-#define ATTR_ROWSPAN 18
58
-#define ATTR_SIZE 19
59
-#define ATTR_SRC 20
60
-#define ATTR_START 21
61
-#define ATTR_STYLE 22
62
-#define ATTR_TARGET 23
63
-#define ATTR_TYPE 24
64
-#define ATTR_VALIGN 25
65
-#define ATTR_VALUE 26
66
-#define ATTR_VSPACE 27
67
-#define ATTR_WIDTH 28
56
+#define ATTR_LINKS 17
57
+#define ATTR_NAME 18
58
+#define ATTR_ROWSPAN 19
59
+#define ATTR_SIZE 20
60
+#define ATTR_SRC 21
61
+#define ATTR_START 22
62
+#define ATTR_STYLE 23
63
+#define ATTR_TARGET 24
64
+#define ATTR_TYPE 25
65
+#define ATTR_VALIGN 26
66
+#define ATTR_VALUE 27
67
+#define ATTR_VSPACE 28
68
+#define ATTR_WIDTH 29
6869
#define AMSK_ALIGN 0x00000001
6970
#define AMSK_ALT 0x00000002
7071
#define AMSK_BGCOLOR 0x00000004
7172
#define AMSK_BORDER 0x00000008
7273
#define AMSK_CELLPADDING 0x00000010
@@ -79,22 +80,23 @@
7980
#define AMSK_FACE 0x00000800
8081
#define AMSK_HEIGHT 0x00001000
8182
#define AMSK_HREF 0x00002000
8283
#define AMSK_HSPACE 0x00004000
8384
#define AMSK_ID 0x00008000
84
-#define AMSK_NAME 0x00010000
85
-#define AMSK_ROWSPAN 0x00020000
86
-#define AMSK_SIZE 0x00040000
87
-#define AMSK_SRC 0x00080000
88
-#define AMSK_START 0x00100000
89
-#define AMSK_STYLE 0x00200000
90
-#define AMSK_TARGET 0x00400000
91
-#define AMSK_TYPE 0x00800000
92
-#define AMSK_VALIGN 0x01000000
93
-#define AMSK_VALUE 0x02000000
94
-#define AMSK_VSPACE 0x04000000
95
-#define AMSK_WIDTH 0x08000000
85
+#define AMSK_LINKS 0x00010000
86
+#define AMSK_NAME 0x00020000
87
+#define AMSK_ROWSPAN 0x00040000
88
+#define AMSK_SIZE 0x00080000
89
+#define AMSK_SRC 0x00100000
90
+#define AMSK_START 0x00200000
91
+#define AMSK_STYLE 0x00400000
92
+#define AMSK_TARGET 0x00800000
93
+#define AMSK_TYPE 0x01000000
94
+#define AMSK_VALIGN 0x02000000
95
+#define AMSK_VALUE 0x04000000
96
+#define AMSK_VSPACE 0x08000000
97
+#define AMSK_WIDTH 0x10000000
9698
9799
static const struct AllowedAttribute {
98100
const char *zName;
99101
unsigned int iMask;
100102
} aAttribute[] = {
@@ -113,10 +115,11 @@
113115
{ "face", AMSK_FACE, },
114116
{ "height", AMSK_HEIGHT, },
115117
{ "href", AMSK_HREF, },
116118
{ "hspace", AMSK_HSPACE, },
117119
{ "id", AMSK_ID, },
120
+ { "links", AMSK_LINKS, },
118121
{ "name", AMSK_NAME, },
119122
{ "rowspan", AMSK_ROWSPAN, },
120123
{ "size", AMSK_SIZE, },
121124
{ "src", AMSK_SRC, },
122125
{ "start", AMSK_START, },
@@ -438,11 +441,11 @@
438441
int n = 1;
439442
int inparen = 0;
440443
int c;
441444
if( z[n]=='/' ){ n++; }
442445
if( !fossil_isalpha(z[n]) ) return 0;
443
- while( fossil_isalnum(z[n]) ){ n++; }
446
+ while( fossil_isalnum(z[n]) || z[n]=='-' ){ n++; }
444447
c = z[n];
445448
if( c=='/' && z[n+1]=='>' ){ return n+2; }
446449
if( c!='>' && !fossil_isspace(c) ) return 0;
447450
while( (c = z[n])!=0 && (c!='>' || inparen) ){
448451
if( c==inparen ){
@@ -750,12 +753,23 @@
750753
}
751754
zTag[j] = 0;
752755
p->iCode = findTag(zTag);
753756
p->iType = aMarkup[p->iCode].iType;
754757
p->nAttr = 0;
758
+ c = 0;
759
+ if( z[i]=='-' ){
760
+ p->aAttr[0].iACode = iACode = ATTR_ID;
761
+ i++;
762
+ p->aAttr[0].zValue = &z[i];
763
+ while( fossil_isalnum(z[i]) ){ i++; }
764
+ p->aAttr[0].cTerm = c = z[i];
765
+ z[i++] = 0;
766
+ p->nAttr = 1;
767
+ if( c=='>' ) return;
768
+ }
755769
while( fossil_isspace(z[i]) ){ i++; }
756
- while( p->nAttr<8 && fossil_isalpha(z[i]) ){
770
+ while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){
757771
int attrOk; /* True to preserver attribute. False to ignore it */
758772
j = 0;
759773
while( fossil_isalnum(z[i]) ){
760774
if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]);
761775
i++;
@@ -1433,13 +1447,12 @@
14331447
const char *zId;
14341448
int iDiv;
14351449
parseMarkup(&markup, z);
14361450
14371451
/* Markup of the form </div id=ID> where there is a matching
1438
- ** ID somewhere on the stack. Exit the verbatim if were are in
1439
- ** it. Pop the stack up to the matching <div>. Discard the
1440
- ** </div>
1452
+ ** ID somewhere on the stack. Exit any contained verbatim.
1453
+ ** Pop the stack up to the matching <div>. Discard the </div>
14411454
*/
14421455
if( markup.iCode==MARKUP_DIV && markup.endTag &&
14431456
(zId = markupId(&markup))!=0 &&
14441457
(iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
14451458
){
@@ -1527,18 +1540,17 @@
15271540
p->preVerbState = p->state;
15281541
p->state &= ~ALLOW_WIKI;
15291542
for(ii=0; ii<markup.nAttr; ii++){
15301543
if( markup.aAttr[ii].iACode == ATTR_ID ){
15311544
p->zVerbatimId = markup.aAttr[ii].zValue;
1532
- }else if( markup.aAttr[ii].iACode == ATTR_TYPE ){
1533
- if( fossil_stricmp(markup.aAttr[ii].zValue, "allow-links")==0 ){
1534
- p->state |= ALLOW_LINKS;
1535
- }else{
1536
- blob_appendf(p->pOut, "<pre name='code' class='%s'>",
1537
- markup.aAttr[ii].zValue);
1538
- vAttrDidAppend=1;
1539
- }
1545
+ }else if( markup.aAttr[ii].iACode==ATTR_TYPE ){
1546
+ blob_appendf(p->pOut, "<pre name='code' class='%s'>",
1547
+ markup.aAttr[ii].zValue);
1548
+ vAttrDidAppend=1;
1549
+ }else if( markup.aAttr[ii].iACode==ATTR_LINKS
1550
+ && !is_false(markup.aAttr[ii].zValue) ){
1551
+ p->state |= ALLOW_LINKS;
15401552
}
15411553
}
15421554
if( !vAttrDidAppend ) {
15431555
endAutoParagraph(p);
15441556
blob_append(p->pOut, "<pre class='verbatim'>",-1);
15451557
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -51,22 +51,23 @@
51 #define ATTR_FACE 12
52 #define ATTR_HEIGHT 13
53 #define ATTR_HREF 14
54 #define ATTR_HSPACE 15
55 #define ATTR_ID 16
56 #define ATTR_NAME 17
57 #define ATTR_ROWSPAN 18
58 #define ATTR_SIZE 19
59 #define ATTR_SRC 20
60 #define ATTR_START 21
61 #define ATTR_STYLE 22
62 #define ATTR_TARGET 23
63 #define ATTR_TYPE 24
64 #define ATTR_VALIGN 25
65 #define ATTR_VALUE 26
66 #define ATTR_VSPACE 27
67 #define ATTR_WIDTH 28
 
68 #define AMSK_ALIGN 0x00000001
69 #define AMSK_ALT 0x00000002
70 #define AMSK_BGCOLOR 0x00000004
71 #define AMSK_BORDER 0x00000008
72 #define AMSK_CELLPADDING 0x00000010
@@ -79,22 +80,23 @@
79 #define AMSK_FACE 0x00000800
80 #define AMSK_HEIGHT 0x00001000
81 #define AMSK_HREF 0x00002000
82 #define AMSK_HSPACE 0x00004000
83 #define AMSK_ID 0x00008000
84 #define AMSK_NAME 0x00010000
85 #define AMSK_ROWSPAN 0x00020000
86 #define AMSK_SIZE 0x00040000
87 #define AMSK_SRC 0x00080000
88 #define AMSK_START 0x00100000
89 #define AMSK_STYLE 0x00200000
90 #define AMSK_TARGET 0x00400000
91 #define AMSK_TYPE 0x00800000
92 #define AMSK_VALIGN 0x01000000
93 #define AMSK_VALUE 0x02000000
94 #define AMSK_VSPACE 0x04000000
95 #define AMSK_WIDTH 0x08000000
 
96
97 static const struct AllowedAttribute {
98 const char *zName;
99 unsigned int iMask;
100 } aAttribute[] = {
@@ -113,10 +115,11 @@
113 { "face", AMSK_FACE, },
114 { "height", AMSK_HEIGHT, },
115 { "href", AMSK_HREF, },
116 { "hspace", AMSK_HSPACE, },
117 { "id", AMSK_ID, },
 
118 { "name", AMSK_NAME, },
119 { "rowspan", AMSK_ROWSPAN, },
120 { "size", AMSK_SIZE, },
121 { "src", AMSK_SRC, },
122 { "start", AMSK_START, },
@@ -438,11 +441,11 @@
438 int n = 1;
439 int inparen = 0;
440 int c;
441 if( z[n]=='/' ){ n++; }
442 if( !fossil_isalpha(z[n]) ) return 0;
443 while( fossil_isalnum(z[n]) ){ n++; }
444 c = z[n];
445 if( c=='/' && z[n+1]=='>' ){ return n+2; }
446 if( c!='>' && !fossil_isspace(c) ) return 0;
447 while( (c = z[n])!=0 && (c!='>' || inparen) ){
448 if( c==inparen ){
@@ -750,12 +753,23 @@
750 }
751 zTag[j] = 0;
752 p->iCode = findTag(zTag);
753 p->iType = aMarkup[p->iCode].iType;
754 p->nAttr = 0;
 
 
 
 
 
 
 
 
 
 
 
755 while( fossil_isspace(z[i]) ){ i++; }
756 while( p->nAttr<8 && fossil_isalpha(z[i]) ){
757 int attrOk; /* True to preserver attribute. False to ignore it */
758 j = 0;
759 while( fossil_isalnum(z[i]) ){
760 if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]);
761 i++;
@@ -1433,13 +1447,12 @@
1433 const char *zId;
1434 int iDiv;
1435 parseMarkup(&markup, z);
1436
1437 /* Markup of the form </div id=ID> where there is a matching
1438 ** ID somewhere on the stack. Exit the verbatim if were are in
1439 ** it. Pop the stack up to the matching <div>. Discard the
1440 ** </div>
1441 */
1442 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1443 (zId = markupId(&markup))!=0 &&
1444 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
1445 ){
@@ -1527,18 +1540,17 @@
1527 p->preVerbState = p->state;
1528 p->state &= ~ALLOW_WIKI;
1529 for(ii=0; ii<markup.nAttr; ii++){
1530 if( markup.aAttr[ii].iACode == ATTR_ID ){
1531 p->zVerbatimId = markup.aAttr[ii].zValue;
1532 }else if( markup.aAttr[ii].iACode == ATTR_TYPE ){
1533 if( fossil_stricmp(markup.aAttr[ii].zValue, "allow-links")==0 ){
1534 p->state |= ALLOW_LINKS;
1535 }else{
1536 blob_appendf(p->pOut, "<pre name='code' class='%s'>",
1537 markup.aAttr[ii].zValue);
1538 vAttrDidAppend=1;
1539 }
1540 }
1541 }
1542 if( !vAttrDidAppend ) {
1543 endAutoParagraph(p);
1544 blob_append(p->pOut, "<pre class='verbatim'>",-1);
1545
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -51,22 +51,23 @@
51 #define ATTR_FACE 12
52 #define ATTR_HEIGHT 13
53 #define ATTR_HREF 14
54 #define ATTR_HSPACE 15
55 #define ATTR_ID 16
56 #define ATTR_LINKS 17
57 #define ATTR_NAME 18
58 #define ATTR_ROWSPAN 19
59 #define ATTR_SIZE 20
60 #define ATTR_SRC 21
61 #define ATTR_START 22
62 #define ATTR_STYLE 23
63 #define ATTR_TARGET 24
64 #define ATTR_TYPE 25
65 #define ATTR_VALIGN 26
66 #define ATTR_VALUE 27
67 #define ATTR_VSPACE 28
68 #define ATTR_WIDTH 29
69 #define AMSK_ALIGN 0x00000001
70 #define AMSK_ALT 0x00000002
71 #define AMSK_BGCOLOR 0x00000004
72 #define AMSK_BORDER 0x00000008
73 #define AMSK_CELLPADDING 0x00000010
@@ -79,22 +80,23 @@
80 #define AMSK_FACE 0x00000800
81 #define AMSK_HEIGHT 0x00001000
82 #define AMSK_HREF 0x00002000
83 #define AMSK_HSPACE 0x00004000
84 #define AMSK_ID 0x00008000
85 #define AMSK_LINKS 0x00010000
86 #define AMSK_NAME 0x00020000
87 #define AMSK_ROWSPAN 0x00040000
88 #define AMSK_SIZE 0x00080000
89 #define AMSK_SRC 0x00100000
90 #define AMSK_START 0x00200000
91 #define AMSK_STYLE 0x00400000
92 #define AMSK_TARGET 0x00800000
93 #define AMSK_TYPE 0x01000000
94 #define AMSK_VALIGN 0x02000000
95 #define AMSK_VALUE 0x04000000
96 #define AMSK_VSPACE 0x08000000
97 #define AMSK_WIDTH 0x10000000
98
99 static const struct AllowedAttribute {
100 const char *zName;
101 unsigned int iMask;
102 } aAttribute[] = {
@@ -113,10 +115,11 @@
115 { "face", AMSK_FACE, },
116 { "height", AMSK_HEIGHT, },
117 { "href", AMSK_HREF, },
118 { "hspace", AMSK_HSPACE, },
119 { "id", AMSK_ID, },
120 { "links", AMSK_LINKS, },
121 { "name", AMSK_NAME, },
122 { "rowspan", AMSK_ROWSPAN, },
123 { "size", AMSK_SIZE, },
124 { "src", AMSK_SRC, },
125 { "start", AMSK_START, },
@@ -438,11 +441,11 @@
441 int n = 1;
442 int inparen = 0;
443 int c;
444 if( z[n]=='/' ){ n++; }
445 if( !fossil_isalpha(z[n]) ) return 0;
446 while( fossil_isalnum(z[n]) || z[n]=='-' ){ n++; }
447 c = z[n];
448 if( c=='/' && z[n+1]=='>' ){ return n+2; }
449 if( c!='>' && !fossil_isspace(c) ) return 0;
450 while( (c = z[n])!=0 && (c!='>' || inparen) ){
451 if( c==inparen ){
@@ -750,12 +753,23 @@
753 }
754 zTag[j] = 0;
755 p->iCode = findTag(zTag);
756 p->iType = aMarkup[p->iCode].iType;
757 p->nAttr = 0;
758 c = 0;
759 if( z[i]=='-' ){
760 p->aAttr[0].iACode = iACode = ATTR_ID;
761 i++;
762 p->aAttr[0].zValue = &z[i];
763 while( fossil_isalnum(z[i]) ){ i++; }
764 p->aAttr[0].cTerm = c = z[i];
765 z[i++] = 0;
766 p->nAttr = 1;
767 if( c=='>' ) return;
768 }
769 while( fossil_isspace(z[i]) ){ i++; }
770 while( c!='>' && p->nAttr<8 && fossil_isalpha(z[i]) ){
771 int attrOk; /* True to preserver attribute. False to ignore it */
772 j = 0;
773 while( fossil_isalnum(z[i]) ){
774 if( j<sizeof(zTag)-1 ) zTag[j++] = fossil_tolower(z[i]);
775 i++;
@@ -1433,13 +1447,12 @@
1447 const char *zId;
1448 int iDiv;
1449 parseMarkup(&markup, z);
1450
1451 /* Markup of the form </div id=ID> where there is a matching
1452 ** ID somewhere on the stack. Exit any contained verbatim.
1453 ** Pop the stack up to the matching <div>. Discard the </div>
 
1454 */
1455 if( markup.iCode==MARKUP_DIV && markup.endTag &&
1456 (zId = markupId(&markup))!=0 &&
1457 (iDiv = findTagWithId(p, MARKUP_DIV, zId))>=0
1458 ){
@@ -1527,18 +1540,17 @@
1540 p->preVerbState = p->state;
1541 p->state &= ~ALLOW_WIKI;
1542 for(ii=0; ii<markup.nAttr; ii++){
1543 if( markup.aAttr[ii].iACode == ATTR_ID ){
1544 p->zVerbatimId = markup.aAttr[ii].zValue;
1545 }else if( markup.aAttr[ii].iACode==ATTR_TYPE ){
1546 blob_appendf(p->pOut, "<pre name='code' class='%s'>",
1547 markup.aAttr[ii].zValue);
1548 vAttrDidAppend=1;
1549 }else if( markup.aAttr[ii].iACode==ATTR_LINKS
1550 && !is_false(markup.aAttr[ii].zValue) ){
1551 p->state |= ALLOW_LINKS;
 
1552 }
1553 }
1554 if( !vAttrDidAppend ) {
1555 endAutoParagraph(p);
1556 blob_append(p->pOut, "<pre class='verbatim'>",-1);
1557

Keyboard Shortcuts

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