Fossil SCM

Added pikchr CLI command to processes pikchr scripts, optionally with embedded TH1.

stephan 2020-09-14 00:42 trunk merge
Commit 5173701de4b4a3b75937225501a085584d61176097f6352b4359b89e214cd73d
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -165,5 +165,128 @@
165165
}
166166
builtin_emit_fossil_js_apis("page.pikchrshow", 0);
167167
builtin_fulfill_js_requests();
168168
style_footer();
169169
}
170
+
171
+/*
172
+** COMMAND: pikchr*
173
+**
174
+** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
175
+**
176
+** Accepts a pikchr script as input and outputs the rendered script as
177
+** an SVG graphic. The INFILE and OUTFILE options default to stdin
178
+** resp. stdout, and the names "-" can be used as aliases for those
179
+** streams.
180
+**
181
+** Options:
182
+**
183
+** -div On success, adds a DIV wrapper around the
184
+** resulting SVG output which limits its max-width to
185
+** its computed maximum ideal size, in order to mimic
186
+** how fossil's web-based components work.
187
+**
188
+** -th Process the input using TH1 before passing it to pikchr.
189
+**
190
+** -th-novar Disable $var and $<var> TH1 processing. Use this if the
191
+** pikchr script uses '$' for its own purposes and that
192
+** causes issues.
193
+**
194
+** -th-nosvg When using -th, output the post-TH1'd script
195
+** instead of the pikchr-rendered output.
196
+**
197
+** -th-trace Trace TH1 execution (for debugging purposes).
198
+**
199
+** TH1-related Notes and Caveats:
200
+**
201
+** If the -th flag is used, this command must open a fossil database
202
+** for certain functionality to work (via a checkout or the -R REPO
203
+** flag). If opening a db fails, execution will continue but any TH1
204
+** commands which require a db will trigger a fatal error.
205
+**
206
+** In Fossil skins, TH1 variables in the form $varName are expanded
207
+** as-is and those in the form $<varName> are htmlized in the
208
+** resulting output. This processor disables the htmlizing step, so $x
209
+** and $<x> are equivalent unless the TH1-processed pikchr script
210
+** invokes the TH1 command [enable_htmlify 1] to enable it. Normally
211
+** that option will interfere with pikchr output, however, e.g. by
212
+** HTML-encoding double-quotes.
213
+**
214
+** Many of the fossil-installed TH1 functions simply do not make any
215
+** sense for pikchr scripts.
216
+*/
217
+void pikchr_cmd(void){
218
+ Blob bIn = empty_blob;
219
+ Blob bOut = empty_blob;
220
+ const char * zInfile = "-";
221
+ const char * zOutfile = "-";
222
+ const int fWithDiv = find_option("div",0,0)!=0;
223
+ const int fTh1 = find_option("th",0,0)!=0;
224
+ const int fNosvg = find_option("th-nosvg",0,0)!=0;
225
+ int isErr = 0;
226
+ u32 fThFlags = TH_INIT_NO_ENCODE
227
+ | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
228
+
229
+ Th_InitTraceLog()/*processes -th-trace flag*/;
230
+ verify_all_options();
231
+ if(g.argc>4){
232
+ usage("?INFILE? ?OUTFILE?");
233
+ }
234
+ if(g.argc>2){
235
+ zInfile = g.argv[2];
236
+ }
237
+ if(g.argc>3){
238
+ zOutfile = g.argv[3];
239
+ }
240
+ blob_read_from_file(&bIn, zInfile, ExtFILE);
241
+ if(fTh1){
242
+ Blob out = empty_blob;
243
+ db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
244
+ /* ^^^ needed for certain TH1 functions to work */;
245
+ /*Th_FossilInit(fThFlags);*/
246
+ isErr = Th_RenderToBlob(blob_str(&bIn), &out, fThFlags)
247
+ ? 1 : 0;
248
+ if(isErr){
249
+ blob_reset(&bOut);
250
+ bOut = out;
251
+ }else{
252
+ blob_reset(&bIn);
253
+ bIn = out;
254
+ }
255
+ }
256
+ if(!isErr){
257
+ if(fTh1 && fNosvg){
258
+ assert(0==blob_size(&bOut));
259
+ bOut = bIn;
260
+ bIn = empty_blob;
261
+ }else{
262
+ int w = 0, h = 0;
263
+ const char * zContent = blob_str(&bIn);
264
+ char *zOut;
265
+
266
+ zOut = pikchr(zContent, "pikchr", 0, &w, &h);
267
+ if( w>0 && h>0 ){
268
+ if(fWithDiv){
269
+ blob_appendf(&bOut,"<div style='max-width:%dpx;'>\n", w);
270
+ }
271
+ blob_append(&bOut, zOut, -1);
272
+ if(fWithDiv){
273
+ blob_append(&bOut,"</div>\n", 7);
274
+ }
275
+ fossil_free(zOut);
276
+ }else{
277
+ isErr = 2;
278
+ blob_set_dynamic(&bOut, zOut);
279
+ }
280
+ }
281
+ }
282
+ if(isErr){
283
+ /*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
284
+ fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
285
+ &bOut);
286
+ }else{
287
+ blob_write_to_file(&bOut, zOutfile);
288
+ }
289
+ Th_PrintTraceLog();
290
+ blob_reset(&bIn);
291
+ blob_reset(&bOut);
292
+}
170293
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -165,5 +165,128 @@
165 }
166 builtin_emit_fossil_js_apis("page.pikchrshow", 0);
167 builtin_fulfill_js_requests();
168 style_footer();
169 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -165,5 +165,128 @@
165 }
166 builtin_emit_fossil_js_apis("page.pikchrshow", 0);
167 builtin_fulfill_js_requests();
168 style_footer();
169 }
170
171 /*
172 ** COMMAND: pikchr*
173 **
174 ** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
175 **
176 ** Accepts a pikchr script as input and outputs the rendered script as
177 ** an SVG graphic. The INFILE and OUTFILE options default to stdin
178 ** resp. stdout, and the names "-" can be used as aliases for those
179 ** streams.
180 **
181 ** Options:
182 **
183 ** -div On success, adds a DIV wrapper around the
184 ** resulting SVG output which limits its max-width to
185 ** its computed maximum ideal size, in order to mimic
186 ** how fossil's web-based components work.
187 **
188 ** -th Process the input using TH1 before passing it to pikchr.
189 **
190 ** -th-novar Disable $var and $<var> TH1 processing. Use this if the
191 ** pikchr script uses '$' for its own purposes and that
192 ** causes issues.
193 **
194 ** -th-nosvg When using -th, output the post-TH1'd script
195 ** instead of the pikchr-rendered output.
196 **
197 ** -th-trace Trace TH1 execution (for debugging purposes).
198 **
199 ** TH1-related Notes and Caveats:
200 **
201 ** If the -th flag is used, this command must open a fossil database
202 ** for certain functionality to work (via a checkout or the -R REPO
203 ** flag). If opening a db fails, execution will continue but any TH1
204 ** commands which require a db will trigger a fatal error.
205 **
206 ** In Fossil skins, TH1 variables in the form $varName are expanded
207 ** as-is and those in the form $<varName> are htmlized in the
208 ** resulting output. This processor disables the htmlizing step, so $x
209 ** and $<x> are equivalent unless the TH1-processed pikchr script
210 ** invokes the TH1 command [enable_htmlify 1] to enable it. Normally
211 ** that option will interfere with pikchr output, however, e.g. by
212 ** HTML-encoding double-quotes.
213 **
214 ** Many of the fossil-installed TH1 functions simply do not make any
215 ** sense for pikchr scripts.
216 */
217 void pikchr_cmd(void){
218 Blob bIn = empty_blob;
219 Blob bOut = empty_blob;
220 const char * zInfile = "-";
221 const char * zOutfile = "-";
222 const int fWithDiv = find_option("div",0,0)!=0;
223 const int fTh1 = find_option("th",0,0)!=0;
224 const int fNosvg = find_option("th-nosvg",0,0)!=0;
225 int isErr = 0;
226 u32 fThFlags = TH_INIT_NO_ENCODE
227 | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
228
229 Th_InitTraceLog()/*processes -th-trace flag*/;
230 verify_all_options();
231 if(g.argc>4){
232 usage("?INFILE? ?OUTFILE?");
233 }
234 if(g.argc>2){
235 zInfile = g.argv[2];
236 }
237 if(g.argc>3){
238 zOutfile = g.argv[3];
239 }
240 blob_read_from_file(&bIn, zInfile, ExtFILE);
241 if(fTh1){
242 Blob out = empty_blob;
243 db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
244 /* ^^^ needed for certain TH1 functions to work */;
245 /*Th_FossilInit(fThFlags);*/
246 isErr = Th_RenderToBlob(blob_str(&bIn), &out, fThFlags)
247 ? 1 : 0;
248 if(isErr){
249 blob_reset(&bOut);
250 bOut = out;
251 }else{
252 blob_reset(&bIn);
253 bIn = out;
254 }
255 }
256 if(!isErr){
257 if(fTh1 && fNosvg){
258 assert(0==blob_size(&bOut));
259 bOut = bIn;
260 bIn = empty_blob;
261 }else{
262 int w = 0, h = 0;
263 const char * zContent = blob_str(&bIn);
264 char *zOut;
265
266 zOut = pikchr(zContent, "pikchr", 0, &w, &h);
267 if( w>0 && h>0 ){
268 if(fWithDiv){
269 blob_appendf(&bOut,"<div style='max-width:%dpx;'>\n", w);
270 }
271 blob_append(&bOut, zOut, -1);
272 if(fWithDiv){
273 blob_append(&bOut,"</div>\n", 7);
274 }
275 fossil_free(zOut);
276 }else{
277 isErr = 2;
278 blob_set_dynamic(&bOut, zOut);
279 }
280 }
281 }
282 if(isErr){
283 /*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
284 fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
285 &bOut);
286 }else{
287 blob_write_to_file(&bOut, zOutfile);
288 }
289 Th_PrintTraceLog();
290 blob_reset(&bIn);
291 blob_reset(&bOut);
292 }
293
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -165,5 +165,128 @@
165165
}
166166
builtin_emit_fossil_js_apis("page.pikchrshow", 0);
167167
builtin_fulfill_js_requests();
168168
style_footer();
169169
}
170
+
171
+/*
172
+** COMMAND: pikchr*
173
+**
174
+** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
175
+**
176
+** Accepts a pikchr script as input and outputs the rendered script as
177
+** an SVG graphic. The INFILE and OUTFILE options default to stdin
178
+** resp. stdout, and the names "-" can be used as aliases for those
179
+** streams.
180
+**
181
+** Options:
182
+**
183
+** -div On success, adds a DIV wrapper around the
184
+** resulting SVG output which limits its max-width to
185
+** its computed maximum ideal size, in order to mimic
186
+** how fossil's web-based components work.
187
+**
188
+** -th Process the input using TH1 before passing it to pikchr.
189
+**
190
+** -th-novar Disable $var and $<var> TH1 processing. Use this if the
191
+** pikchr script uses '$' for its own purposes and that
192
+** causes issues.
193
+**
194
+** -th-nosvg When using -th, output the post-TH1'd script
195
+** instead of the pikchr-rendered output.
196
+**
197
+** -th-trace Trace TH1 execution (for debugging purposes).
198
+**
199
+** TH1-related Notes and Caveats:
200
+**
201
+** If the -th flag is used, this command must open a fossil database
202
+** for certain functionality to work (via a checkout or the -R REPO
203
+** flag). If opening a db fails, execution will continue but any TH1
204
+** commands which require a db will trigger a fatal error.
205
+**
206
+** In Fossil skins, TH1 variables in the form $varName are expanded
207
+** as-is and those in the form $<varName> are htmlized in the
208
+** resulting output. This processor disables the htmlizing step, so $x
209
+** and $<x> are equivalent unless the TH1-processed pikchr script
210
+** invokes the TH1 command [enable_htmlify 1] to enable it. Normally
211
+** that option will interfere with pikchr output, however, e.g. by
212
+** HTML-encoding double-quotes.
213
+**
214
+** Many of the fossil-installed TH1 functions simply do not make any
215
+** sense for pikchr scripts.
216
+*/
217
+void pikchr_cmd(void){
218
+ Blob bIn = empty_blob;
219
+ Blob bOut = empty_blob;
220
+ const char * zInfile = "-";
221
+ const char * zOutfile = "-";
222
+ const int fWithDiv = find_option("div",0,0)!=0;
223
+ const int fTh1 = find_option("th",0,0)!=0;
224
+ const int fNosvg = find_option("th-nosvg",0,0)!=0;
225
+ int isErr = 0;
226
+ u32 fThFlags = TH_INIT_NO_ENCODE
227
+ | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
228
+
229
+ Th_InitTraceLog()/*processes -th-trace flag*/;
230
+ verify_all_options();
231
+ if(g.argc>4){
232
+ usage("?INFILE? ?OUTFILE?");
233
+ }
234
+ if(g.argc>2){
235
+ zInfile = g.argv[2];
236
+ }
237
+ if(g.argc>3){
238
+ zOutfile = g.argv[3];
239
+ }
240
+ blob_read_from_file(&bIn, zInfile, ExtFILE);
241
+ if(fTh1){
242
+ Blob out = empty_blob;
243
+ db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
244
+ /* ^^^ needed for certain TH1 functions to work */;
245
+ /*Th_FossilInit(fThFlags);*/
246
+ isErr = Th_RenderToBlob(blob_str(&bIn), &out, fThFlags)
247
+ ? 1 : 0;
248
+ if(isErr){
249
+ blob_reset(&bOut);
250
+ bOut = out;
251
+ }else{
252
+ blob_reset(&bIn);
253
+ bIn = out;
254
+ }
255
+ }
256
+ if(!isErr){
257
+ if(fTh1 && fNosvg){
258
+ assert(0==blob_size(&bOut));
259
+ bOut = bIn;
260
+ bIn = empty_blob;
261
+ }else{
262
+ int w = 0, h = 0;
263
+ const char * zContent = blob_str(&bIn);
264
+ char *zOut;
265
+
266
+ zOut = pikchr(zContent, "pikchr", 0, &w, &h);
267
+ if( w>0 && h>0 ){
268
+ if(fWithDiv){
269
+ blob_appendf(&bOut,"<div style='max-width:%dpx;'>\n", w);
270
+ }
271
+ blob_append(&bOut, zOut, -1);
272
+ if(fWithDiv){
273
+ blob_append(&bOut,"</div>\n", 7);
274
+ }
275
+ fossil_free(zOut);
276
+ }else{
277
+ isErr = 2;
278
+ blob_set_dynamic(&bOut, zOut);
279
+ }
280
+ }
281
+ }
282
+ if(isErr){
283
+ /*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
284
+ fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
285
+ &bOut);
286
+ }else{
287
+ blob_write_to_file(&bOut, zOutfile);
288
+ }
289
+ Th_PrintTraceLog();
290
+ blob_reset(&bIn);
291
+ blob_reset(&bOut);
292
+}
170293
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -165,5 +165,128 @@
165 }
166 builtin_emit_fossil_js_apis("page.pikchrshow", 0);
167 builtin_fulfill_js_requests();
168 style_footer();
169 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -165,5 +165,128 @@
165 }
166 builtin_emit_fossil_js_apis("page.pikchrshow", 0);
167 builtin_fulfill_js_requests();
168 style_footer();
169 }
170
171 /*
172 ** COMMAND: pikchr*
173 **
174 ** Usage: %fossil pikchr [options] ?INFILE? ?OUTFILE?
175 **
176 ** Accepts a pikchr script as input and outputs the rendered script as
177 ** an SVG graphic. The INFILE and OUTFILE options default to stdin
178 ** resp. stdout, and the names "-" can be used as aliases for those
179 ** streams.
180 **
181 ** Options:
182 **
183 ** -div On success, adds a DIV wrapper around the
184 ** resulting SVG output which limits its max-width to
185 ** its computed maximum ideal size, in order to mimic
186 ** how fossil's web-based components work.
187 **
188 ** -th Process the input using TH1 before passing it to pikchr.
189 **
190 ** -th-novar Disable $var and $<var> TH1 processing. Use this if the
191 ** pikchr script uses '$' for its own purposes and that
192 ** causes issues.
193 **
194 ** -th-nosvg When using -th, output the post-TH1'd script
195 ** instead of the pikchr-rendered output.
196 **
197 ** -th-trace Trace TH1 execution (for debugging purposes).
198 **
199 ** TH1-related Notes and Caveats:
200 **
201 ** If the -th flag is used, this command must open a fossil database
202 ** for certain functionality to work (via a checkout or the -R REPO
203 ** flag). If opening a db fails, execution will continue but any TH1
204 ** commands which require a db will trigger a fatal error.
205 **
206 ** In Fossil skins, TH1 variables in the form $varName are expanded
207 ** as-is and those in the form $<varName> are htmlized in the
208 ** resulting output. This processor disables the htmlizing step, so $x
209 ** and $<x> are equivalent unless the TH1-processed pikchr script
210 ** invokes the TH1 command [enable_htmlify 1] to enable it. Normally
211 ** that option will interfere with pikchr output, however, e.g. by
212 ** HTML-encoding double-quotes.
213 **
214 ** Many of the fossil-installed TH1 functions simply do not make any
215 ** sense for pikchr scripts.
216 */
217 void pikchr_cmd(void){
218 Blob bIn = empty_blob;
219 Blob bOut = empty_blob;
220 const char * zInfile = "-";
221 const char * zOutfile = "-";
222 const int fWithDiv = find_option("div",0,0)!=0;
223 const int fTh1 = find_option("th",0,0)!=0;
224 const int fNosvg = find_option("th-nosvg",0,0)!=0;
225 int isErr = 0;
226 u32 fThFlags = TH_INIT_NO_ENCODE
227 | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
228
229 Th_InitTraceLog()/*processes -th-trace flag*/;
230 verify_all_options();
231 if(g.argc>4){
232 usage("?INFILE? ?OUTFILE?");
233 }
234 if(g.argc>2){
235 zInfile = g.argv[2];
236 }
237 if(g.argc>3){
238 zOutfile = g.argv[3];
239 }
240 blob_read_from_file(&bIn, zInfile, ExtFILE);
241 if(fTh1){
242 Blob out = empty_blob;
243 db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
244 /* ^^^ needed for certain TH1 functions to work */;
245 /*Th_FossilInit(fThFlags);*/
246 isErr = Th_RenderToBlob(blob_str(&bIn), &out, fThFlags)
247 ? 1 : 0;
248 if(isErr){
249 blob_reset(&bOut);
250 bOut = out;
251 }else{
252 blob_reset(&bIn);
253 bIn = out;
254 }
255 }
256 if(!isErr){
257 if(fTh1 && fNosvg){
258 assert(0==blob_size(&bOut));
259 bOut = bIn;
260 bIn = empty_blob;
261 }else{
262 int w = 0, h = 0;
263 const char * zContent = blob_str(&bIn);
264 char *zOut;
265
266 zOut = pikchr(zContent, "pikchr", 0, &w, &h);
267 if( w>0 && h>0 ){
268 if(fWithDiv){
269 blob_appendf(&bOut,"<div style='max-width:%dpx;'>\n", w);
270 }
271 blob_append(&bOut, zOut, -1);
272 if(fWithDiv){
273 blob_append(&bOut,"</div>\n", 7);
274 }
275 fossil_free(zOut);
276 }else{
277 isErr = 2;
278 blob_set_dynamic(&bOut, zOut);
279 }
280 }
281 }
282 if(isErr){
283 /*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
284 fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
285 &bOut);
286 }else{
287 blob_write_to_file(&bOut, zOutfile);
288 }
289 Th_PrintTraceLog();
290 blob_reset(&bIn);
291 blob_reset(&bOut);
292 }
293
+178 -42
--- src/th_main.c
+++ src/th_main.c
@@ -31,11 +31,12 @@
3131
#define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
3232
#define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */
3333
#define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
3434
#define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
3535
#define TH_INIT_NO_REPO ((u32)0x00000010) /* Skip opening repository. */
36
-#define TH_INIT_MASK ((u32)0x0000001F) /* All possible init flags. */
36
+#define TH_INIT_NO_ENCODE ((u32)0x00000020) /* Do not html-encode sentText() output. */
37
+#define TH_INIT_MASK ((u32)0x0000003F) /* All possible init flags. */
3738
3839
/*
3940
** Useful and/or "well-known" combinations of flag values.
4041
*/
4142
#define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */
@@ -288,10 +289,50 @@
288289
if( g.thTrace ){
289290
Th_Trace("enable_output {%.*s} -> %d<br />\n", argl[1],argv[1],enableOutput);
290291
}
291292
return rc;
292293
}
294
+
295
+/*
296
+** TH1 command: enable_htmlify ?BOOLEAN?
297
+**
298
+** Enable or disable the HTML escaping done by all output which
299
+** originates from TH1 (via sendText()).
300
+**
301
+** If passed no arguments it instead returns 0 or 1 to indicate the
302
+** current state.
303
+*/
304
+static int enableHtmlifyCmd(
305
+ Th_Interp *interp,
306
+ void *p,
307
+ int argc,
308
+ const char **argv,
309
+ int *argl
310
+){
311
+ int rc = 0, buul;
312
+ if( argc>3 ){
313
+ return Th_WrongNumArgs(interp,
314
+ "enable_htmlify [TRACE_LABEL] ?BOOLEAN?");
315
+ }
316
+ buul = (TH_INIT_NO_ENCODE & g.th1Flags) ? 0 : 1;
317
+ Th_SetResultInt(g.interp, buul);
318
+ if(argc>1){
319
+ if( g.thTrace ){
320
+ Th_Trace("enable_htmlify {%.*s} -> %d<br />\n",
321
+ argl[1],argv[1],buul);
322
+ }
323
+ rc = Th_ToInt(interp, argv[argc-1], argl[argc-1], &buul);
324
+ if(!rc){
325
+ if(buul){
326
+ g.th1Flags &= ~TH_INIT_NO_ENCODE;
327
+ }else{
328
+ g.th1Flags |= TH_INIT_NO_ENCODE;
329
+ }
330
+ }
331
+ }
332
+ return rc;
333
+}
293334
294335
/*
295336
** Returns a name for a TH1 return code.
296337
*/
297338
const char *Th_ReturnCodeName(int rc, int nullIfOk){
@@ -309,41 +350,72 @@
309350
}
310351
}
311352
return zRc;
312353
}
313354
355
+/* See Th_SetOutputBlob() */
356
+static Blob * pThOut = 0;
314357
/*
315
-** Send text to the appropriate output: Either to the console
316
-** or to the CGI reply buffer. Escape all characters with special
317
-** meaning to HTML if the encode parameter is true.
358
+** Sets the th1-internal output-redirection blob and returns the
359
+** previous value. That blob is used by certain output-generation
360
+** routines to emit its output. It returns the previous value so that
361
+** a routing can temporarily replace the buffer with its own and
362
+** restore it when it's done.
318363
*/
319
-static void sendText(const char *z, int n, int encode){
364
+Blob * Th_SetOutputBlob(Blob * pOut){
365
+ Blob * tmp = pThOut;
366
+ pThOut = pOut;
367
+ return tmp;
368
+}
369
+
370
+/*
371
+** Send text to the appropriate output: If pOut is not NULL, it is
372
+** appended there, else to the console or to the CGI reply buffer.
373
+** Escape all characters with special meaning to HTML if the encode
374
+** parameter is true, with the exception that that flag is ignored if
375
+** g.th1Flags has the TH_INIT_NO_ENCODE flag.
376
+**
377
+** If pOut is NULL and the global pThOut is not then that blob
378
+** is used for output.
379
+*/
380
+static void sendText(Blob * pOut, const char *z, int n, int encode){
381
+ if(0==pOut && pThOut!=0){
382
+ pOut = pThOut;
383
+ }
384
+ if(TH_INIT_NO_ENCODE & g.th1Flags){
385
+ encode = 0;
386
+ }
320387
if( enableOutput && n ){
321388
if( n<0 ) n = strlen(z);
322389
if( encode ){
323390
z = htmlize(z, n);
324391
n = strlen(z);
325392
}
326
- if( g.cgiOutput ){
393
+ if(pOut!=0){
394
+ blob_append(pOut, z, n);
395
+ }else if( g.cgiOutput ){
327396
cgi_append_content(z, n);
328397
}else{
329398
fwrite(z, 1, n, stdout);
330399
fflush(stdout);
331400
}
332401
if( encode ) free((char*)z);
333402
}
334403
}
335404
336
-static void sendError(const char *z, int n, int forceCgi){
405
+/*
406
+** error-reporting counterpart of sendText().
407
+*/
408
+static void sendError(Blob * pOut, const char *z, int n, int forceCgi){
337409
int savedEnable = enableOutput;
338410
enableOutput = 1;
339411
if( forceCgi || g.cgiOutput ){
340
- sendText("<hr /><p class=\"thmainError\">", -1, 0);
412
+ sendText(pOut, "<hr /><p class=\"thmainError\">", -1, 0);
341413
}
342
- sendText("ERROR: ", -1, 0);
343
- sendText((char*)z, n, 1);
344
- sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
414
+ sendText(pOut,"ERROR: ", -1, 0);
415
+ sendText(pOut,(char*)z, n, 1);
416
+ sendText(pOut,forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
345417
enableOutput = savedEnable;
346418
}
347419
348420
/*
349421
** Convert name to an rid. This function was copied from name_to_typed_rid()
@@ -450,11 +522,11 @@
450522
int *argl
451523
){
452524
if( argc!=2 ){
453525
return Th_WrongNumArgs(interp, "puts STRING");
454526
}
455
- sendText((char*)argv[1], argl[1], *(unsigned int*)pConvert);
527
+ sendText(0,(char*)argv[1], argl[1], *(unsigned int*)pConvert);
456528
return TH_OK;
457529
}
458530
459531
/*
460532
** TH1 command: redirect URL ?withMethod?
@@ -996,11 +1068,11 @@
9961068
blob_init(&name, (char*)argv[1], argl[1]);
9971069
zValue = Th_Fetch(blob_str(&name), &nValue);
9981070
zH = htmlize(blob_buffer(&name), blob_size(&name));
9991071
z = mprintf("<select id=\"%s\" name=\"%s\" size=\"%d\">", zH, zH, height);
10001072
free(zH);
1001
- sendText(z, -1, 0);
1073
+ sendText(0,z, -1, 0);
10021074
free(z);
10031075
blob_reset(&name);
10041076
for(i=0; i<nElem; i++){
10051077
zH = htmlize((char*)azElem[i], aszElem[i]);
10061078
if( zValue && aszElem[i]==nValue
@@ -1009,14 +1081,14 @@
10091081
zH, zH);
10101082
}else{
10111083
z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
10121084
}
10131085
free(zH);
1014
- sendText(z, -1, 0);
1086
+ sendText(0,z, -1, 0);
10151087
free(z);
10161088
}
1017
- sendText("</select>", -1, 0);
1089
+ sendText(0,"</select>", -1, 0);
10181090
Th_Free(interp, azElem);
10191091
}
10201092
return TH_OK;
10211093
}
10221094
@@ -1060,11 +1132,11 @@
10601132
if( Th_ToInt(interp, argv[4], argl[4], &copylength) ) return TH_ERROR;
10611133
}
10621134
zResult = style_copy_button(
10631135
/*bOutputCGI==*/0, /*TARGETID==*/(char*)argv[1],
10641136
flipped, copylength, "%h", /*TEXT==*/(char*)argv[3]);
1065
- sendText(zResult, -1, 0);
1137
+ sendText(0,zResult, -1, 0);
10661138
free(zResult);
10671139
}
10681140
return TH_OK;
10691141
}
10701142
@@ -2058,10 +2130,44 @@
20582130
"synchronous requests are not yet implemented", 0, 0);
20592131
blob_reset(&payload);
20602132
return TH_ERROR;
20612133
}
20622134
}
2135
+
2136
+/*
2137
+** TH1 command: captureTh1 STRING
2138
+**
2139
+** Evaluates the given string as TH1 code and captures any of its
2140
+** TH1-generated output as a string (instead of it being output),
2141
+** which becomes the result of the function.
2142
+*/
2143
+static int captureTh1Cmd(
2144
+ Th_Interp *interp,
2145
+ void *pConvert,
2146
+ int argc,
2147
+ const char **argv,
2148
+ int *argl
2149
+){
2150
+ Blob out = empty_blob;
2151
+ Blob * pOrig;
2152
+ const char * zStr;
2153
+ int nStr, rc;
2154
+ if( argc!=2 ){
2155
+ return Th_WrongNumArgs(interp, "captureTh1 STRING");
2156
+ }
2157
+ pOrig = Th_SetOutputBlob(&out);
2158
+ zStr = argv[1];
2159
+ nStr = argl[1];
2160
+ rc = Th_Eval(g.interp, 0, zStr, nStr);
2161
+ Th_SetOutputBlob(pOrig);
2162
+ if(0==rc){
2163
+ Th_SetResult(g.interp, blob_str(&out), blob_size(&out));
2164
+ }
2165
+ blob_reset(&out);
2166
+ return rc;
2167
+}
2168
+
20632169
20642170
/*
20652171
** Attempts to open the configuration ("user") database. Optionally, also
20662172
** attempts to try to find the repository and open it.
20672173
*/
@@ -2114,11 +2220,11 @@
21142220
int needConfig = flags & TH_INIT_NEED_CONFIG;
21152221
int forceReset = flags & TH_INIT_FORCE_RESET;
21162222
int forceTcl = flags & TH_INIT_FORCE_TCL;
21172223
int forceSetup = flags & TH_INIT_FORCE_SETUP;
21182224
int noRepo = flags & TH_INIT_NO_REPO;
2119
- static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY };
2225
+ static unsigned int aFlags[] = {0, 1, WIKI_LINKSONLY};
21202226
static int anonFlag = LOGIN_ANON;
21212227
static int zeroInt = 0;
21222228
static struct _Command {
21232229
const char *zName;
21242230
Th_CommandProc xProc;
@@ -2125,18 +2231,20 @@
21252231
void *pContext;
21262232
} aCommand[] = {
21272233
{"anoncap", hascapCmd, (void*)&anonFlag},
21282234
{"anycap", anycapCmd, 0},
21292235
{"artifact", artifactCmd, 0},
2236
+ {"captureTh1", captureTh1Cmd, 0},
21302237
{"cgiHeaderLine", cgiHeaderLineCmd, 0},
21312238
{"checkout", checkoutCmd, 0},
21322239
{"combobox", comboboxCmd, 0},
21332240
{"copybtn", copybtnCmd, 0},
21342241
{"date", dateCmd, 0},
21352242
{"decorate", wikiCmd, (void*)&aFlags[2]},
21362243
{"defHeader", defHeaderCmd, 0},
21372244
{"dir", dirCmd, 0},
2245
+ {"enable_htmlify",enableHtmlifyCmd, 0},
21382246
{"enable_output", enableOutputCmd, 0},
21392247
{"encode64", encode64Cmd, 0},
21402248
{"getParameter", getParameterCmd, 0},
21412249
{"glob_match", globMatchCmd, 0},
21422250
{"globalState", globalStateCmd, 0},
@@ -2221,11 +2329,11 @@
22212329
if( g.th1Setup ){
22222330
rc = Th_Eval(g.interp, 0, g.th1Setup, -1);
22232331
if( rc==TH_ERROR ){
22242332
int nResult = 0;
22252333
char *zResult = (char*)Th_GetResult(g.interp, &nResult);
2226
- sendError(zResult, nResult, 0);
2334
+ sendError(0,zResult, nResult, 0);
22272335
}
22282336
}
22292337
if( g.thTrace ){
22302338
Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
22312339
Th_ReturnCodeName(rc, 0));
@@ -2446,11 +2554,11 @@
24462554
/*
24472555
** Make sure that the TH1 script error was not caused by a "missing"
24482556
** command hook handler as that is not actually an error condition.
24492557
*/
24502558
if( memcmp(zResult, NO_COMMAND_HOOK_ERROR, nResult)!=0 ){
2451
- sendError(zResult, nResult, 0);
2559
+ sendError(0,zResult, nResult, 0);
24522560
}else{
24532561
/*
24542562
** There is no command hook handler "installed". This situation
24552563
** is NOT actually an error.
24562564
*/
@@ -2533,11 +2641,11 @@
25332641
/*
25342642
** Make sure that the TH1 script error was not caused by a "missing"
25352643
** webpage hook handler as that is not actually an error condition.
25362644
*/
25372645
if( memcmp(zResult, NO_WEBPAGE_HOOK_ERROR, nResult)!=0 ){
2538
- sendError(zResult, nResult, 1);
2646
+ sendError(0,zResult, nResult, 1);
25392647
}else{
25402648
/*
25412649
** There is no webpage hook handler "installed". This situation
25422650
** is NOT actually an error.
25432651
*/
@@ -2610,32 +2718,44 @@
26102718
return db_get_boolean("th1-docs", 0);
26112719
}
26122720
#endif
26132721
26142722
2723
+#if INTERFACE
2724
+/*
2725
+** Flags for use with Th_RenderToBlob. These must not overlap with
2726
+** TH_INIT_MASK.
2727
+*/
2728
+#define TH_R2B_MASK ((u32)0x0f000)
2729
+#define TH_R2B_NO_VARS ((u32)0x01000) /* Disables eval of $vars and $<vars> */
2730
+#endif
2731
+
26152732
/*
2616
-** The z[] input contains text mixed with TH1 scripts.
2617
-** The TH1 scripts are contained within <th1>...</th1>.
2618
-** TH1 variables are $aaa or $<aaa>. The first form of
2619
-** variable is literal. The second is run through htmlize
2620
-** before being inserted.
2621
-**
2622
-** This routine processes the template and writes the results
2623
-** on either stdout or into CGI.
2733
+** If pOut is NULL, this works identically to Th_Render(), else it
2734
+** works just like that function but appends any TH1-generated output
2735
+** to the given blob. A bitmask of TH_R2B_xxx and/or TH_INIT_xxx flags
2736
+** may be passed as the 3rd argument, or 0 for default options. Note
2737
+** that this function necessarily calls Th_FossilInit(), which may
2738
+** unset flags used on previous calls unless mFlags is explicitly
2739
+** passed in.
26242740
*/
2625
-int Th_Render(const char *z){
2741
+int Th_RenderToBlob(const char *z, Blob * pOut, u32 mFlags){
26262742
int i = 0;
26272743
int n;
26282744
int rc = TH_OK;
26292745
char *zResult;
2630
- Th_FossilInit(TH_INIT_DEFAULT);
2746
+ Blob * const origOut = Th_SetOutputBlob(pOut);
2747
+
2748
+ assert(0==(TH_R2B_MASK & TH_INIT_MASK) && "init/r2b mask conflict");
2749
+ Th_FossilInit(mFlags & TH_INIT_MASK);
26312750
while( z[i] ){
2632
- if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
2751
+ if( 0==(TH_R2B_NO_VARS & mFlags)
2752
+ && z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
26332753
const char *zVar;
26342754
int nVar;
26352755
int encode = 1;
2636
- sendText(z, i, 0);
2756
+ sendText(pOut,z, i, 0);
26372757
if( z[i+1]=='<' ){
26382758
/* Variables of the form $<aaa> are html escaped */
26392759
zVar = &z[i+2];
26402760
nVar = n-2;
26412761
}else{
@@ -2646,13 +2766,13 @@
26462766
}
26472767
rc = Th_GetVar(g.interp, (char*)zVar, nVar);
26482768
z += i+1+n;
26492769
i = 0;
26502770
zResult = (char*)Th_GetResult(g.interp, &n);
2651
- sendText((char*)zResult, n, encode);
2771
+ sendText(pOut,(char*)zResult, n, encode);
26522772
}else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
2653
- sendText(z, i, 0);
2773
+ sendText(pOut,z, i, 0);
26542774
z += i+5;
26552775
for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
26562776
if( g.thTrace ){
26572777
Th_Trace("render_eval {<pre>%#h</pre>}<br />\n", i, z);
26582778
}
@@ -2671,16 +2791,32 @@
26712791
i++;
26722792
}
26732793
}
26742794
if( rc==TH_ERROR ){
26752795
zResult = (char*)Th_GetResult(g.interp, &n);
2676
- sendError(zResult, n, 1);
2796
+ sendError(pOut,zResult, n, 1);
26772797
}else{
2678
- sendText(z, i, 0);
2798
+ sendText(pOut,z, i, 0);
26792799
}
2800
+ Th_SetOutputBlob(origOut);
26802801
return rc;
26812802
}
2803
+
2804
+/*
2805
+** The z[] input contains text mixed with TH1 scripts.
2806
+** The TH1 scripts are contained within <th1>...</th1>.
2807
+** TH1 variables are $aaa or $<aaa>. The first form of
2808
+** variable is literal. The second is run through htmlize
2809
+** before being inserted.
2810
+**
2811
+** This routine processes the template and writes the results to one
2812
+** of stdout, CGI, or an internal blob which was set up via a prior
2813
+** call to Th_SetOutputBlob().
2814
+*/
2815
+int Th_Render(const char *z){
2816
+ return Th_RenderToBlob(z, 0, 0);
2817
+}
26822818
26832819
/*
26842820
** COMMAND: test-th-render
26852821
**
26862822
** Usage: %fossil test-th-render FILE
@@ -2899,17 +3035,17 @@
28993035
fossil_fatal("Unknown TH1 hook %s", g.argv[2]);
29003036
}
29013037
if( g.interp ){
29023038
zResult = (char*)Th_GetResult(g.interp, &nResult);
29033039
}
2904
- sendText("RESULT (", -1, 0);
2905
- sendText(Th_ReturnCodeName(rc, 0), -1, 0);
2906
- sendText(")", -1, 0);
3040
+ sendText(0,"RESULT (", -1, 0);
3041
+ sendText(0,Th_ReturnCodeName(rc, 0), -1, 0);
3042
+ sendText(0,")", -1, 0);
29073043
if( zResult && nResult>0 ){
2908
- sendText(": ", -1, 0);
2909
- sendText(zResult, nResult, 0);
3044
+ sendText(0,": ", -1, 0);
3045
+ sendText(0,zResult, nResult, 0);
29103046
}
2911
- sendText("\n", -1, 0);
3047
+ sendText(0,"\n", -1, 0);
29123048
Th_PrintTraceLog();
29133049
if( forceCgi ) cgi_reply();
29143050
}
29153051
#endif
29163052
--- src/th_main.c
+++ src/th_main.c
@@ -31,11 +31,12 @@
31 #define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
32 #define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */
33 #define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
34 #define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
35 #define TH_INIT_NO_REPO ((u32)0x00000010) /* Skip opening repository. */
36 #define TH_INIT_MASK ((u32)0x0000001F) /* All possible init flags. */
 
37
38 /*
39 ** Useful and/or "well-known" combinations of flag values.
40 */
41 #define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */
@@ -288,10 +289,50 @@
288 if( g.thTrace ){
289 Th_Trace("enable_output {%.*s} -> %d<br />\n", argl[1],argv[1],enableOutput);
290 }
291 return rc;
292 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
294 /*
295 ** Returns a name for a TH1 return code.
296 */
297 const char *Th_ReturnCodeName(int rc, int nullIfOk){
@@ -309,41 +350,72 @@
309 }
310 }
311 return zRc;
312 }
313
 
 
314 /*
315 ** Send text to the appropriate output: Either to the console
316 ** or to the CGI reply buffer. Escape all characters with special
317 ** meaning to HTML if the encode parameter is true.
 
 
318 */
319 static void sendText(const char *z, int n, int encode){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320 if( enableOutput && n ){
321 if( n<0 ) n = strlen(z);
322 if( encode ){
323 z = htmlize(z, n);
324 n = strlen(z);
325 }
326 if( g.cgiOutput ){
 
 
327 cgi_append_content(z, n);
328 }else{
329 fwrite(z, 1, n, stdout);
330 fflush(stdout);
331 }
332 if( encode ) free((char*)z);
333 }
334 }
335
336 static void sendError(const char *z, int n, int forceCgi){
 
 
 
337 int savedEnable = enableOutput;
338 enableOutput = 1;
339 if( forceCgi || g.cgiOutput ){
340 sendText("<hr /><p class=\"thmainError\">", -1, 0);
341 }
342 sendText("ERROR: ", -1, 0);
343 sendText((char*)z, n, 1);
344 sendText(forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
345 enableOutput = savedEnable;
346 }
347
348 /*
349 ** Convert name to an rid. This function was copied from name_to_typed_rid()
@@ -450,11 +522,11 @@
450 int *argl
451 ){
452 if( argc!=2 ){
453 return Th_WrongNumArgs(interp, "puts STRING");
454 }
455 sendText((char*)argv[1], argl[1], *(unsigned int*)pConvert);
456 return TH_OK;
457 }
458
459 /*
460 ** TH1 command: redirect URL ?withMethod?
@@ -996,11 +1068,11 @@
996 blob_init(&name, (char*)argv[1], argl[1]);
997 zValue = Th_Fetch(blob_str(&name), &nValue);
998 zH = htmlize(blob_buffer(&name), blob_size(&name));
999 z = mprintf("<select id=\"%s\" name=\"%s\" size=\"%d\">", zH, zH, height);
1000 free(zH);
1001 sendText(z, -1, 0);
1002 free(z);
1003 blob_reset(&name);
1004 for(i=0; i<nElem; i++){
1005 zH = htmlize((char*)azElem[i], aszElem[i]);
1006 if( zValue && aszElem[i]==nValue
@@ -1009,14 +1081,14 @@
1009 zH, zH);
1010 }else{
1011 z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
1012 }
1013 free(zH);
1014 sendText(z, -1, 0);
1015 free(z);
1016 }
1017 sendText("</select>", -1, 0);
1018 Th_Free(interp, azElem);
1019 }
1020 return TH_OK;
1021 }
1022
@@ -1060,11 +1132,11 @@
1060 if( Th_ToInt(interp, argv[4], argl[4], &copylength) ) return TH_ERROR;
1061 }
1062 zResult = style_copy_button(
1063 /*bOutputCGI==*/0, /*TARGETID==*/(char*)argv[1],
1064 flipped, copylength, "%h", /*TEXT==*/(char*)argv[3]);
1065 sendText(zResult, -1, 0);
1066 free(zResult);
1067 }
1068 return TH_OK;
1069 }
1070
@@ -2058,10 +2130,44 @@
2058 "synchronous requests are not yet implemented", 0, 0);
2059 blob_reset(&payload);
2060 return TH_ERROR;
2061 }
2062 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2063
2064 /*
2065 ** Attempts to open the configuration ("user") database. Optionally, also
2066 ** attempts to try to find the repository and open it.
2067 */
@@ -2114,11 +2220,11 @@
2114 int needConfig = flags & TH_INIT_NEED_CONFIG;
2115 int forceReset = flags & TH_INIT_FORCE_RESET;
2116 int forceTcl = flags & TH_INIT_FORCE_TCL;
2117 int forceSetup = flags & TH_INIT_FORCE_SETUP;
2118 int noRepo = flags & TH_INIT_NO_REPO;
2119 static unsigned int aFlags[] = { 0, 1, WIKI_LINKSONLY };
2120 static int anonFlag = LOGIN_ANON;
2121 static int zeroInt = 0;
2122 static struct _Command {
2123 const char *zName;
2124 Th_CommandProc xProc;
@@ -2125,18 +2231,20 @@
2125 void *pContext;
2126 } aCommand[] = {
2127 {"anoncap", hascapCmd, (void*)&anonFlag},
2128 {"anycap", anycapCmd, 0},
2129 {"artifact", artifactCmd, 0},
 
2130 {"cgiHeaderLine", cgiHeaderLineCmd, 0},
2131 {"checkout", checkoutCmd, 0},
2132 {"combobox", comboboxCmd, 0},
2133 {"copybtn", copybtnCmd, 0},
2134 {"date", dateCmd, 0},
2135 {"decorate", wikiCmd, (void*)&aFlags[2]},
2136 {"defHeader", defHeaderCmd, 0},
2137 {"dir", dirCmd, 0},
 
2138 {"enable_output", enableOutputCmd, 0},
2139 {"encode64", encode64Cmd, 0},
2140 {"getParameter", getParameterCmd, 0},
2141 {"glob_match", globMatchCmd, 0},
2142 {"globalState", globalStateCmd, 0},
@@ -2221,11 +2329,11 @@
2221 if( g.th1Setup ){
2222 rc = Th_Eval(g.interp, 0, g.th1Setup, -1);
2223 if( rc==TH_ERROR ){
2224 int nResult = 0;
2225 char *zResult = (char*)Th_GetResult(g.interp, &nResult);
2226 sendError(zResult, nResult, 0);
2227 }
2228 }
2229 if( g.thTrace ){
2230 Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
2231 Th_ReturnCodeName(rc, 0));
@@ -2446,11 +2554,11 @@
2446 /*
2447 ** Make sure that the TH1 script error was not caused by a "missing"
2448 ** command hook handler as that is not actually an error condition.
2449 */
2450 if( memcmp(zResult, NO_COMMAND_HOOK_ERROR, nResult)!=0 ){
2451 sendError(zResult, nResult, 0);
2452 }else{
2453 /*
2454 ** There is no command hook handler "installed". This situation
2455 ** is NOT actually an error.
2456 */
@@ -2533,11 +2641,11 @@
2533 /*
2534 ** Make sure that the TH1 script error was not caused by a "missing"
2535 ** webpage hook handler as that is not actually an error condition.
2536 */
2537 if( memcmp(zResult, NO_WEBPAGE_HOOK_ERROR, nResult)!=0 ){
2538 sendError(zResult, nResult, 1);
2539 }else{
2540 /*
2541 ** There is no webpage hook handler "installed". This situation
2542 ** is NOT actually an error.
2543 */
@@ -2610,32 +2718,44 @@
2610 return db_get_boolean("th1-docs", 0);
2611 }
2612 #endif
2613
2614
 
 
 
 
 
 
 
 
 
2615 /*
2616 ** The z[] input contains text mixed with TH1 scripts.
2617 ** The TH1 scripts are contained within <th1>...</th1>.
2618 ** TH1 variables are $aaa or $<aaa>. The first form of
2619 ** variable is literal. The second is run through htmlize
2620 ** before being inserted.
2621 **
2622 ** This routine processes the template and writes the results
2623 ** on either stdout or into CGI.
2624 */
2625 int Th_Render(const char *z){
2626 int i = 0;
2627 int n;
2628 int rc = TH_OK;
2629 char *zResult;
2630 Th_FossilInit(TH_INIT_DEFAULT);
 
 
 
2631 while( z[i] ){
2632 if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
 
2633 const char *zVar;
2634 int nVar;
2635 int encode = 1;
2636 sendText(z, i, 0);
2637 if( z[i+1]=='<' ){
2638 /* Variables of the form $<aaa> are html escaped */
2639 zVar = &z[i+2];
2640 nVar = n-2;
2641 }else{
@@ -2646,13 +2766,13 @@
2646 }
2647 rc = Th_GetVar(g.interp, (char*)zVar, nVar);
2648 z += i+1+n;
2649 i = 0;
2650 zResult = (char*)Th_GetResult(g.interp, &n);
2651 sendText((char*)zResult, n, encode);
2652 }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
2653 sendText(z, i, 0);
2654 z += i+5;
2655 for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
2656 if( g.thTrace ){
2657 Th_Trace("render_eval {<pre>%#h</pre>}<br />\n", i, z);
2658 }
@@ -2671,16 +2791,32 @@
2671 i++;
2672 }
2673 }
2674 if( rc==TH_ERROR ){
2675 zResult = (char*)Th_GetResult(g.interp, &n);
2676 sendError(zResult, n, 1);
2677 }else{
2678 sendText(z, i, 0);
2679 }
 
2680 return rc;
2681 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2682
2683 /*
2684 ** COMMAND: test-th-render
2685 **
2686 ** Usage: %fossil test-th-render FILE
@@ -2899,17 +3035,17 @@
2899 fossil_fatal("Unknown TH1 hook %s", g.argv[2]);
2900 }
2901 if( g.interp ){
2902 zResult = (char*)Th_GetResult(g.interp, &nResult);
2903 }
2904 sendText("RESULT (", -1, 0);
2905 sendText(Th_ReturnCodeName(rc, 0), -1, 0);
2906 sendText(")", -1, 0);
2907 if( zResult && nResult>0 ){
2908 sendText(": ", -1, 0);
2909 sendText(zResult, nResult, 0);
2910 }
2911 sendText("\n", -1, 0);
2912 Th_PrintTraceLog();
2913 if( forceCgi ) cgi_reply();
2914 }
2915 #endif
2916
--- src/th_main.c
+++ src/th_main.c
@@ -31,11 +31,12 @@
31 #define TH_INIT_NEED_CONFIG ((u32)0x00000001) /* Open configuration first? */
32 #define TH_INIT_FORCE_TCL ((u32)0x00000002) /* Force Tcl to be enabled? */
33 #define TH_INIT_FORCE_RESET ((u32)0x00000004) /* Force TH1 commands re-added? */
34 #define TH_INIT_FORCE_SETUP ((u32)0x00000008) /* Force eval of setup script? */
35 #define TH_INIT_NO_REPO ((u32)0x00000010) /* Skip opening repository. */
36 #define TH_INIT_NO_ENCODE ((u32)0x00000020) /* Do not html-encode sentText() output. */
37 #define TH_INIT_MASK ((u32)0x0000003F) /* All possible init flags. */
38
39 /*
40 ** Useful and/or "well-known" combinations of flag values.
41 */
42 #define TH_INIT_DEFAULT (TH_INIT_NONE) /* Default flags. */
@@ -288,10 +289,50 @@
289 if( g.thTrace ){
290 Th_Trace("enable_output {%.*s} -> %d<br />\n", argl[1],argv[1],enableOutput);
291 }
292 return rc;
293 }
294
295 /*
296 ** TH1 command: enable_htmlify ?BOOLEAN?
297 **
298 ** Enable or disable the HTML escaping done by all output which
299 ** originates from TH1 (via sendText()).
300 **
301 ** If passed no arguments it instead returns 0 or 1 to indicate the
302 ** current state.
303 */
304 static int enableHtmlifyCmd(
305 Th_Interp *interp,
306 void *p,
307 int argc,
308 const char **argv,
309 int *argl
310 ){
311 int rc = 0, buul;
312 if( argc>3 ){
313 return Th_WrongNumArgs(interp,
314 "enable_htmlify [TRACE_LABEL] ?BOOLEAN?");
315 }
316 buul = (TH_INIT_NO_ENCODE & g.th1Flags) ? 0 : 1;
317 Th_SetResultInt(g.interp, buul);
318 if(argc>1){
319 if( g.thTrace ){
320 Th_Trace("enable_htmlify {%.*s} -> %d<br />\n",
321 argl[1],argv[1],buul);
322 }
323 rc = Th_ToInt(interp, argv[argc-1], argl[argc-1], &buul);
324 if(!rc){
325 if(buul){
326 g.th1Flags &= ~TH_INIT_NO_ENCODE;
327 }else{
328 g.th1Flags |= TH_INIT_NO_ENCODE;
329 }
330 }
331 }
332 return rc;
333 }
334
335 /*
336 ** Returns a name for a TH1 return code.
337 */
338 const char *Th_ReturnCodeName(int rc, int nullIfOk){
@@ -309,41 +350,72 @@
350 }
351 }
352 return zRc;
353 }
354
355 /* See Th_SetOutputBlob() */
356 static Blob * pThOut = 0;
357 /*
358 ** Sets the th1-internal output-redirection blob and returns the
359 ** previous value. That blob is used by certain output-generation
360 ** routines to emit its output. It returns the previous value so that
361 ** a routing can temporarily replace the buffer with its own and
362 ** restore it when it's done.
363 */
364 Blob * Th_SetOutputBlob(Blob * pOut){
365 Blob * tmp = pThOut;
366 pThOut = pOut;
367 return tmp;
368 }
369
370 /*
371 ** Send text to the appropriate output: If pOut is not NULL, it is
372 ** appended there, else to the console or to the CGI reply buffer.
373 ** Escape all characters with special meaning to HTML if the encode
374 ** parameter is true, with the exception that that flag is ignored if
375 ** g.th1Flags has the TH_INIT_NO_ENCODE flag.
376 **
377 ** If pOut is NULL and the global pThOut is not then that blob
378 ** is used for output.
379 */
380 static void sendText(Blob * pOut, const char *z, int n, int encode){
381 if(0==pOut && pThOut!=0){
382 pOut = pThOut;
383 }
384 if(TH_INIT_NO_ENCODE & g.th1Flags){
385 encode = 0;
386 }
387 if( enableOutput && n ){
388 if( n<0 ) n = strlen(z);
389 if( encode ){
390 z = htmlize(z, n);
391 n = strlen(z);
392 }
393 if(pOut!=0){
394 blob_append(pOut, z, n);
395 }else if( g.cgiOutput ){
396 cgi_append_content(z, n);
397 }else{
398 fwrite(z, 1, n, stdout);
399 fflush(stdout);
400 }
401 if( encode ) free((char*)z);
402 }
403 }
404
405 /*
406 ** error-reporting counterpart of sendText().
407 */
408 static void sendError(Blob * pOut, const char *z, int n, int forceCgi){
409 int savedEnable = enableOutput;
410 enableOutput = 1;
411 if( forceCgi || g.cgiOutput ){
412 sendText(pOut, "<hr /><p class=\"thmainError\">", -1, 0);
413 }
414 sendText(pOut,"ERROR: ", -1, 0);
415 sendText(pOut,(char*)z, n, 1);
416 sendText(pOut,forceCgi || g.cgiOutput ? "</p>" : "\n", -1, 0);
417 enableOutput = savedEnable;
418 }
419
420 /*
421 ** Convert name to an rid. This function was copied from name_to_typed_rid()
@@ -450,11 +522,11 @@
522 int *argl
523 ){
524 if( argc!=2 ){
525 return Th_WrongNumArgs(interp, "puts STRING");
526 }
527 sendText(0,(char*)argv[1], argl[1], *(unsigned int*)pConvert);
528 return TH_OK;
529 }
530
531 /*
532 ** TH1 command: redirect URL ?withMethod?
@@ -996,11 +1068,11 @@
1068 blob_init(&name, (char*)argv[1], argl[1]);
1069 zValue = Th_Fetch(blob_str(&name), &nValue);
1070 zH = htmlize(blob_buffer(&name), blob_size(&name));
1071 z = mprintf("<select id=\"%s\" name=\"%s\" size=\"%d\">", zH, zH, height);
1072 free(zH);
1073 sendText(0,z, -1, 0);
1074 free(z);
1075 blob_reset(&name);
1076 for(i=0; i<nElem; i++){
1077 zH = htmlize((char*)azElem[i], aszElem[i]);
1078 if( zValue && aszElem[i]==nValue
@@ -1009,14 +1081,14 @@
1081 zH, zH);
1082 }else{
1083 z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
1084 }
1085 free(zH);
1086 sendText(0,z, -1, 0);
1087 free(z);
1088 }
1089 sendText(0,"</select>", -1, 0);
1090 Th_Free(interp, azElem);
1091 }
1092 return TH_OK;
1093 }
1094
@@ -1060,11 +1132,11 @@
1132 if( Th_ToInt(interp, argv[4], argl[4], &copylength) ) return TH_ERROR;
1133 }
1134 zResult = style_copy_button(
1135 /*bOutputCGI==*/0, /*TARGETID==*/(char*)argv[1],
1136 flipped, copylength, "%h", /*TEXT==*/(char*)argv[3]);
1137 sendText(0,zResult, -1, 0);
1138 free(zResult);
1139 }
1140 return TH_OK;
1141 }
1142
@@ -2058,10 +2130,44 @@
2130 "synchronous requests are not yet implemented", 0, 0);
2131 blob_reset(&payload);
2132 return TH_ERROR;
2133 }
2134 }
2135
2136 /*
2137 ** TH1 command: captureTh1 STRING
2138 **
2139 ** Evaluates the given string as TH1 code and captures any of its
2140 ** TH1-generated output as a string (instead of it being output),
2141 ** which becomes the result of the function.
2142 */
2143 static int captureTh1Cmd(
2144 Th_Interp *interp,
2145 void *pConvert,
2146 int argc,
2147 const char **argv,
2148 int *argl
2149 ){
2150 Blob out = empty_blob;
2151 Blob * pOrig;
2152 const char * zStr;
2153 int nStr, rc;
2154 if( argc!=2 ){
2155 return Th_WrongNumArgs(interp, "captureTh1 STRING");
2156 }
2157 pOrig = Th_SetOutputBlob(&out);
2158 zStr = argv[1];
2159 nStr = argl[1];
2160 rc = Th_Eval(g.interp, 0, zStr, nStr);
2161 Th_SetOutputBlob(pOrig);
2162 if(0==rc){
2163 Th_SetResult(g.interp, blob_str(&out), blob_size(&out));
2164 }
2165 blob_reset(&out);
2166 return rc;
2167 }
2168
2169
2170 /*
2171 ** Attempts to open the configuration ("user") database. Optionally, also
2172 ** attempts to try to find the repository and open it.
2173 */
@@ -2114,11 +2220,11 @@
2220 int needConfig = flags & TH_INIT_NEED_CONFIG;
2221 int forceReset = flags & TH_INIT_FORCE_RESET;
2222 int forceTcl = flags & TH_INIT_FORCE_TCL;
2223 int forceSetup = flags & TH_INIT_FORCE_SETUP;
2224 int noRepo = flags & TH_INIT_NO_REPO;
2225 static unsigned int aFlags[] = {0, 1, WIKI_LINKSONLY};
2226 static int anonFlag = LOGIN_ANON;
2227 static int zeroInt = 0;
2228 static struct _Command {
2229 const char *zName;
2230 Th_CommandProc xProc;
@@ -2125,18 +2231,20 @@
2231 void *pContext;
2232 } aCommand[] = {
2233 {"anoncap", hascapCmd, (void*)&anonFlag},
2234 {"anycap", anycapCmd, 0},
2235 {"artifact", artifactCmd, 0},
2236 {"captureTh1", captureTh1Cmd, 0},
2237 {"cgiHeaderLine", cgiHeaderLineCmd, 0},
2238 {"checkout", checkoutCmd, 0},
2239 {"combobox", comboboxCmd, 0},
2240 {"copybtn", copybtnCmd, 0},
2241 {"date", dateCmd, 0},
2242 {"decorate", wikiCmd, (void*)&aFlags[2]},
2243 {"defHeader", defHeaderCmd, 0},
2244 {"dir", dirCmd, 0},
2245 {"enable_htmlify",enableHtmlifyCmd, 0},
2246 {"enable_output", enableOutputCmd, 0},
2247 {"encode64", encode64Cmd, 0},
2248 {"getParameter", getParameterCmd, 0},
2249 {"glob_match", globMatchCmd, 0},
2250 {"globalState", globalStateCmd, 0},
@@ -2221,11 +2329,11 @@
2329 if( g.th1Setup ){
2330 rc = Th_Eval(g.interp, 0, g.th1Setup, -1);
2331 if( rc==TH_ERROR ){
2332 int nResult = 0;
2333 char *zResult = (char*)Th_GetResult(g.interp, &nResult);
2334 sendError(0,zResult, nResult, 0);
2335 }
2336 }
2337 if( g.thTrace ){
2338 Th_Trace("th1-setup {%h} => %h<br />\n", g.th1Setup,
2339 Th_ReturnCodeName(rc, 0));
@@ -2446,11 +2554,11 @@
2554 /*
2555 ** Make sure that the TH1 script error was not caused by a "missing"
2556 ** command hook handler as that is not actually an error condition.
2557 */
2558 if( memcmp(zResult, NO_COMMAND_HOOK_ERROR, nResult)!=0 ){
2559 sendError(0,zResult, nResult, 0);
2560 }else{
2561 /*
2562 ** There is no command hook handler "installed". This situation
2563 ** is NOT actually an error.
2564 */
@@ -2533,11 +2641,11 @@
2641 /*
2642 ** Make sure that the TH1 script error was not caused by a "missing"
2643 ** webpage hook handler as that is not actually an error condition.
2644 */
2645 if( memcmp(zResult, NO_WEBPAGE_HOOK_ERROR, nResult)!=0 ){
2646 sendError(0,zResult, nResult, 1);
2647 }else{
2648 /*
2649 ** There is no webpage hook handler "installed". This situation
2650 ** is NOT actually an error.
2651 */
@@ -2610,32 +2718,44 @@
2718 return db_get_boolean("th1-docs", 0);
2719 }
2720 #endif
2721
2722
2723 #if INTERFACE
2724 /*
2725 ** Flags for use with Th_RenderToBlob. These must not overlap with
2726 ** TH_INIT_MASK.
2727 */
2728 #define TH_R2B_MASK ((u32)0x0f000)
2729 #define TH_R2B_NO_VARS ((u32)0x01000) /* Disables eval of $vars and $<vars> */
2730 #endif
2731
2732 /*
2733 ** If pOut is NULL, this works identically to Th_Render(), else it
2734 ** works just like that function but appends any TH1-generated output
2735 ** to the given blob. A bitmask of TH_R2B_xxx and/or TH_INIT_xxx flags
2736 ** may be passed as the 3rd argument, or 0 for default options. Note
2737 ** that this function necessarily calls Th_FossilInit(), which may
2738 ** unset flags used on previous calls unless mFlags is explicitly
2739 ** passed in.
 
2740 */
2741 int Th_RenderToBlob(const char *z, Blob * pOut, u32 mFlags){
2742 int i = 0;
2743 int n;
2744 int rc = TH_OK;
2745 char *zResult;
2746 Blob * const origOut = Th_SetOutputBlob(pOut);
2747
2748 assert(0==(TH_R2B_MASK & TH_INIT_MASK) && "init/r2b mask conflict");
2749 Th_FossilInit(mFlags & TH_INIT_MASK);
2750 while( z[i] ){
2751 if( 0==(TH_R2B_NO_VARS & mFlags)
2752 && z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
2753 const char *zVar;
2754 int nVar;
2755 int encode = 1;
2756 sendText(pOut,z, i, 0);
2757 if( z[i+1]=='<' ){
2758 /* Variables of the form $<aaa> are html escaped */
2759 zVar = &z[i+2];
2760 nVar = n-2;
2761 }else{
@@ -2646,13 +2766,13 @@
2766 }
2767 rc = Th_GetVar(g.interp, (char*)zVar, nVar);
2768 z += i+1+n;
2769 i = 0;
2770 zResult = (char*)Th_GetResult(g.interp, &n);
2771 sendText(pOut,(char*)zResult, n, encode);
2772 }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
2773 sendText(pOut,z, i, 0);
2774 z += i+5;
2775 for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
2776 if( g.thTrace ){
2777 Th_Trace("render_eval {<pre>%#h</pre>}<br />\n", i, z);
2778 }
@@ -2671,16 +2791,32 @@
2791 i++;
2792 }
2793 }
2794 if( rc==TH_ERROR ){
2795 zResult = (char*)Th_GetResult(g.interp, &n);
2796 sendError(pOut,zResult, n, 1);
2797 }else{
2798 sendText(pOut,z, i, 0);
2799 }
2800 Th_SetOutputBlob(origOut);
2801 return rc;
2802 }
2803
2804 /*
2805 ** The z[] input contains text mixed with TH1 scripts.
2806 ** The TH1 scripts are contained within <th1>...</th1>.
2807 ** TH1 variables are $aaa or $<aaa>. The first form of
2808 ** variable is literal. The second is run through htmlize
2809 ** before being inserted.
2810 **
2811 ** This routine processes the template and writes the results to one
2812 ** of stdout, CGI, or an internal blob which was set up via a prior
2813 ** call to Th_SetOutputBlob().
2814 */
2815 int Th_Render(const char *z){
2816 return Th_RenderToBlob(z, 0, 0);
2817 }
2818
2819 /*
2820 ** COMMAND: test-th-render
2821 **
2822 ** Usage: %fossil test-th-render FILE
@@ -2899,17 +3035,17 @@
3035 fossil_fatal("Unknown TH1 hook %s", g.argv[2]);
3036 }
3037 if( g.interp ){
3038 zResult = (char*)Th_GetResult(g.interp, &nResult);
3039 }
3040 sendText(0,"RESULT (", -1, 0);
3041 sendText(0,Th_ReturnCodeName(rc, 0), -1, 0);
3042 sendText(0,")", -1, 0);
3043 if( zResult && nResult>0 ){
3044 sendText(0,": ", -1, 0);
3045 sendText(0,zResult, nResult, 0);
3046 }
3047 sendText(0,"\n", -1, 0);
3048 Th_PrintTraceLog();
3049 if( forceCgi ) cgi_reply();
3050 }
3051 #endif
3052
+144 -111
--- www/th1.md
+++ www/th1.md
@@ -164,116 +164,130 @@
164164
---------------------
165165
166166
There are many new commands added to TH1 and used to access the special
167167
features of Fossil. The following is a summary of the extended commands:
168168
169
- * anoncap
170
- * anycap
171
- * artifact
172
- * cgiHeaderLine
173
- * checkout
174
- * combobox
175
- * copybtn
176
- * date
177
- * decorate
178
- * defHeader
179
- * dir
180
- * enable\_output
181
- * encode64
182
- * getParameter
183
- * glob\_match
184
- * globalState
185
- * hascap
186
- * hasfeature
187
- * html
188
- * htmlize
189
- * http
190
- * httpize
191
- * insertCsrf
192
- * linecount
193
- * markdown
194
- * nonce
195
- * puts
196
- * query
197
- * randhex
198
- * redirect
199
- * regexp
200
- * reinitialize
201
- * render
202
- * repository
203
- * searchable
204
- * setParameter
205
- * setting
206
- * stime
207
- * styleHeader
208
- * styleFooter
209
- * styleScript
210
- * tclEval
211
- * tclExpr
212
- * tclInvoke
213
- * tclIsSafe
214
- * tclMakeSafe
215
- * tclReady
216
- * trace
217
- * unversioned content
218
- * unversioned list
219
- * utime
220
- * verifyCsrf
221
- * verifyLogin
222
- * wiki
169
+ * [anoncap](#anoncap)
170
+ * [anycap](#anycap)
171
+ * [artifact](#artifact)
172
+ * [captureTh1](#captureTh1)
173
+ * [cgiHeaderLine](#cgiHeaderLine)
174
+ * [checkout](#checkout)
175
+ * [combobox](#combobox)
176
+ * [copybtn](#copybtn)
177
+ * [date](#date)
178
+ * [decorate](#decorate)
179
+ * [defHeader](#defHeader)
180
+ * [dir](#dir)
181
+ * [enable\_htmlify](#enable_htmlify)
182
+ * [enable\_output](#enable_output)
183
+ * [encode64](#encode64)
184
+ * [getParameter](#getParameter)
185
+ * [glob\_match](#glob_match)
186
+ * [globalState](#globalState)
187
+ * [hascap](#hascap)
188
+ * [hasfeature](#hasfeature)
189
+ * [html](#html)
190
+ * [htmlize](#htmlize)
191
+ * [http](#http)
192
+ * [httpize](#httpize)
193
+ * [insertCsrf](#insertCsrf)
194
+ * [linecount](#linecount)
195
+ * [markdown](#markdown)
196
+ * [nonce](#nonce)
197
+ * [puts](#puts)
198
+ * [query](#query)
199
+ * [randhex](#randhex)
200
+ * [redirect](#redirect)
201
+ * [regexp](#regexp)
202
+ * [reinitialize](#reinitialize)
203
+ * [render](#render)
204
+ * [repository](#repository)
205
+ * [searchable](#searchable)
206
+ * [setParameter](#setParameter)
207
+ * [setting](#setting)
208
+ * [stime](#stime)
209
+ * [styleHeader](#styleHeader)
210
+ * [styleFooter](#styleFooter)
211
+ * [styleScript](#styleScript)
212
+ * [tclEval](#tclEval)
213
+ * [tclExpr](#tclExpr)
214
+ * [tclInvoke](#tclInvoke)
215
+ * [tclIsSafe](#tclIsSafe)
216
+ * [tclMakeSafe](#tclMakeSafe)
217
+ * [tclReady](#tclReady)
218
+ * [trace](#trace)
219
+ * [unversioned content](#unversioned_content)
220
+ * [unversioned list](#unversioned_list)
221
+ * [utime](#utime)
222
+ * [verifyCsrf](#verifyCsrf)
223
+ * [verifyLogin](#verifyLogin)
224
+ * [wiki](#wiki)
223225
224226
Each of the commands above is documented by a block comment above their
225227
implementation in the th\_main.c or th\_tcl.c source files.
226228
227229
All commands starting with "tcl", with the exception of "tclReady",
228230
require the Tcl integration subsystem be included at compile-time.
229231
Additionally, the "tcl" repository setting must be enabled at runtime
230232
in order to successfully make use of these commands.
231233
232
-<a name="anoncap"></a>TH1 anoncap Command
234
+<a id="anoncap"></a>TH1 anoncap Command
233235
-----------------------------------------
234236
235237
* anoncap STRING...
236238
237239
Returns true if the anonymous user has all of the capabilities listed
238240
in STRING.
239241
240
-<a name="anycap"></a>TH1 anycap Command
242
+<a id="anycap"></a>TH1 anycap Command
241243
---------------------------------------
242244
243245
* anycap STRING
244246
245247
Returns true if the current user user has any one of the capabilities
246248
listed in STRING.
247249
248
-<a name="artifact"></a>TH1 artifact Command
250
+<a id="artifact"></a>TH1 artifact Command
249251
-------------------------------------------
250252
251253
* artifact ID ?FILENAME?
252254
253255
Attempts to locate the specified artifact and return its contents. An
254256
error is generated if the repository is not open or the artifact cannot
255257
be found.
256258
257
-<a name="cgiHeaderLine"></a>TH1 cgiHeaderLine Command
259
+<a id="captureTh1"></a>TH1 captureTh1 Command
260
+-----------------------------------------------------
261
+
262
+ * captureTh1 STRING
263
+
264
+Executes its single argument as TH1 code and captures any
265
+TH1-generated output as a string, which becomes the result of the
266
+function call. e.g. any `puts` calls made from that block will not
267
+generate any output, and instead their output will become part of the
268
+result string.
269
+
270
+
271
+<a id="cgiHeaderLine"></a>TH1 cgiHeaderLine Command
258272
-----------------------------------------------------
259273
260274
* cgiHeaderLine line
261275
262276
Adds the specified line to the CGI header.
263277
264
-<a name="checkout"></a>TH1 checkout Command
278
+<a id="checkout"></a>TH1 checkout Command
265279
-------------------------------------------
266280
267281
* checkout ?BOOLEAN?
268282
269283
Return the fully qualified directory name of the current checkout or an
270284
empty string if it is not available. Optionally, it will attempt to find
271285
the current checkout, opening the configuration ("user") database and the
272286
repository as necessary, if the boolean argument is non-zero.
273287
274
-<a name="combobox"></a>TH1 combobox Command
288
+<a id="combobox"></a>TH1 combobox Command
275289
-------------------------------------------
276290
277291
* combobox NAME TEXT-LIST NUMLINES
278292
279293
Generates and emits an HTML combobox. NAME is both the name of the
@@ -280,11 +294,11 @@
280294
CGI parameter and the name of a variable that contains the currently
281295
selected value. TEXT-LIST is a list of possible values for the
282296
combobox. NUMLINES is 1 for a true combobox. If NUMLINES is greater
283297
than one then the display is a listbox with the number of lines given.
284298
285
-<a name="copybtn"></a>TH1 copybtn Command
299
+<a id="copybtn"></a>TH1 copybtn Command
286300
-----------------------------------------
287301
288302
* copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
289303
290304
Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
@@ -302,34 +316,34 @@
302316
* >= 3: Truncate TEXT after COPYLENGTH (single-byte) characters.
303317
* 1: Use the "hash-digits" setting as the limit.
304318
* 2: Use the length appropriate for URLs as the limit (defined at
305319
compile-time by `FOSSIL_HASH_DIGITS_URL`, defaults to 16).
306320
307
-<a name="date"></a>TH1 date Command
321
+<a id="date"></a>TH1 date Command
308322
-----------------------------------
309323
310324
* date ?-local?
311325
312326
Return a strings which is the current time and date. If the -local
313327
option is used, the date appears using localtime instead of UTC.
314328
315
-<a name="decorate"></a>TH1 decorate Command
329
+<a id="decorate"></a>TH1 decorate Command
316330
-------------------------------------------
317331
318332
* decorate STRING
319333
320334
Renders STRING as wiki content; however, only links are handled. No
321335
other markup is processed.
322336
323
-<a name="defHeader"></a>TH1 defHeader Command
337
+<a id="defHeader"></a>TH1 defHeader Command
324338
---------------------------------------------
325339
326340
* defHeader
327341
328342
Returns the default page header.
329343
330
-<a name="dir"></a>TH1 dir Command
344
+<a id="dir"></a>TH1 dir Command
331345
---------------------------------
332346
333347
* dir CHECKIN ?GLOB? ?DETAILS?
334348
335349
Returns a list containing all files in CHECKIN. If GLOB is given only
@@ -337,42 +351,60 @@
337351
If DETAILS is non-zero, the result will be a list-of-lists, with each
338352
element containing at least three elements: the file name, the file
339353
size (in bytes), and the file last modification time (relative to the
340354
time zone configured for the repository).
341355
342
-<a name="enable_output"></a>TH1 enable\_output Command
356
+<a id="enable_htmlify"></a>TH1 enable\_htmlify Command
357
+------------------------------------------------------
358
+
359
+ * enable\_htmlify
360
+ * enable\_htmlify ?TRACE-LABEL? BOOLEAN
361
+
362
+By default, certain output from `puts` and similar commands is escaped
363
+for HTML. The first call form returns the current state of that
364
+feature: `1` for on and `0` for off. The second call form enables
365
+(non-0) or disables (0) that feature and returns the *pre-call* state
366
+of that feature (so that a second call can pass that value to restore
367
+it to its previous state). The optional `TRACE-LABEL` argument causes
368
+the TH1 tracing output (if enabled) to add a marker when the second
369
+form of this command is invoked, and includes that label and the
370
+boolean argument's value in the trace. If tracing is disabled, that
371
+argument has no effect.
372
+
373
+
374
+<a id="enable_output"></a>TH1 enable\_output Command
343375
------------------------------------------------------
344376
345377
* enable\_output BOOLEAN
346378
347379
Enable or disable sending output when the combobox, copybtn, puts, or wiki
348380
commands are used.
349381
350
-<a name="encode64"></a>TH1 encode64 Command
382
+<a id="encode64"></a>TH1 encode64 Command
351383
-------------------------------------------
352384
353385
* encode64 STRING
354386
355387
Encode the specified string using Base64 and return the result.
356388
357
-<a name="getParameter"></a>TH1 getParameter Command
389
+<a id="getParameter"></a>TH1 getParameter Command
358390
---------------------------------------------------
359391
360392
* getParameter NAME ?DEFAULT?
361393
362394
Returns the value of the specified query parameter or the specified
363395
default value when there is no matching query parameter.
364396
365
-<a name="glob_match"></a>TH1 glob\_match Command
397
+<a id="glob_match"></a>TH1 glob\_match Command
366398
------------------------------------------------
367399
368400
* glob\_match ?-one? ?--? patternList string
369401
370402
Checks the string against the specified glob pattern -OR- list of glob
371403
patterns and returns non-zero if there is a match.
372404
373
-<a name="globalState"></a>TH1 globalState Command
405
+<a id="globalState"></a>TH1 globalState Command
374406
-------------------------------------------------
375407
376408
* globalState NAME ?DEFAULT?
377409
378410
Returns a string containing the value of the specified global state
@@ -390,19 +422,19 @@
390422
391423
Attempts to query for unsupported global state variables will result
392424
in a script error. Additional global state variables may be exposed
393425
in the future.
394426
395
-<a name="hascap"></a>TH1 hascap Command
427
+<a id="hascap"></a>TH1 hascap Command
396428
---------------------------------------
397429
398430
* hascap STRING...
399431
400432
Returns true if the current user has all of the capabilities listed
401433
in STRING.
402434
403
-<a name="hasfeature"></a>TH1 hasfeature Command
435
+<a id="hasfeature"></a>TH1 hasfeature Command
404436
-----------------------------------------------
405437
406438
* hasfeature STRING
407439
408440
Returns true if the binary has the given compile-time feature enabled.
@@ -425,26 +457,26 @@
425457
1. **see** -- _Uses the SQLite Encryption Extension._
426458
427459
Specifying an unknown feature will return a value of false, it will not
428460
raise a script error.
429461
430
-<a name="html"></a>TH1 html Command
462
+<a id="html"></a>TH1 html Command
431463
-----------------------------------
432464
433465
* html STRING
434466
435467
Outputs the STRING escaped for HTML.
436468
437
-<a name="htmlize"></a>TH1 htmlize Command
469
+<a id="htmlize"></a>TH1 htmlize Command
438470
-----------------------------------------
439471
440472
* htmlize STRING
441473
442474
Escape all characters of STRING which have special meaning in HTML.
443475
Returns the escaped string.
444476
445
-<a name="http"></a>TH1 http Command
477
+<a id="http"></a>TH1 http Command
446478
-----------------------------------
447479
448480
* http ?-asynchronous? ?--? url ?payload?
449481
450482
Performs an HTTP or HTTPS request for the specified URL. If a
@@ -453,58 +485,59 @@
453485
be used. Upon success, if the -asynchronous option is used, an
454486
empty string is returned as the result; otherwise, the response
455487
from the server is returned as the result. Synchronous requests
456488
are not currently implemented.
457489
458
-<a name="httpize"></a>TH1 httpize Command
490
+<a id="httpize"></a>TH1 httpize Command
459491
-----------------------------------------
460492
461493
* httpize STRING
462494
463495
Escape all characters of STRING which have special meaning in URI
464496
components. Returns the escaped string.
465497
466
-<a name="insertCsrf"></a>TH1 insertCsrf Command
498
+<a id="insertCsrf"></a>TH1 insertCsrf Command
467499
-----------------------------------------------
468500
469501
* insertCsrf
470502
471503
While rendering a form, call this command to add the Anti-CSRF token
472504
as a hidden element of the form.
473505
474
-<a name="linecount"></a>TH1 linecount Command
506
+<a id="linecount"></a>TH1 linecount Command
475507
---------------------------------------------
476508
477509
* linecount STRING MAX MIN
478510
479511
Returns one more than the number of \n characters in STRING. But
480512
never returns less than MIN or more than MAX.
481513
482
-<a name="markdown"></a>TH1 markdown Command
514
+<a id="markdown"></a>TH1 markdown Command
483515
-------------------------------------------
484516
485517
* markdown STRING
486518
487519
Renders the input string as markdown. The result is a two-element list.
488520
The first element contains the body, rendered as HTML. The second element
489521
is the text-only title string.
490522
491
-<a name="nonce"></a>TH1 nonce Command
523
+<a id="nonce"></a>TH1 nonce Command
492524
-------------------------------------
493525
494526
* nonce
495527
496528
Returns the value of the cryptographic nonce for the request being processed.
497529
498
-<a name="puts"></a>TH1 puts Command
530
+<a id="puts"></a>TH1 puts Command
499531
-----------------------------------
500532
501533
* puts STRING
502534
503
-Outputs the STRING unchanged.
535
+Outputs the STRING unchanged, where "unchanged" might, depending on
536
+the context, mean "with some characters escaped for HTML."
504537
505
-<a name="query"></a>TH1 query Command
538
+<a id="query"></a>TH1 query Command
506539
-------------------------------------
507540
508541
* query ?-nocomplain? SQL CODE
509542
510543
Runs the SQL query given by the SQL argument. For each row in the result
@@ -512,19 +545,19 @@
512545
513546
In SQL, parameters such as $var are filled in using the value of variable
514547
"var". Result values are stored in variables with the column name prior
515548
to each invocation of CODE.
516549
517
-<a name="randhex"></a>TH1 randhex Command
550
+<a id="randhex"></a>TH1 randhex Command
518551
-----------------------------------------
519552
520553
* randhex N
521554
522555
Returns a string of N*2 random hexadecimal digits with N<50. If N is
523556
omitted, use a value of 10.
524557
525
-<a name="redirect"></a>TH1 redirect Command
558
+<a id="redirect"></a>TH1 redirect Command
526559
-------------------------------------------
527560
528561
* redirect URL ?withMethod?
529562
530563
Issues an HTTP redirect to the specified URL and then exits the process.
@@ -532,43 +565,43 @@
532565
argument is present and non-zero, an HTTP status code of 307 is used, which
533566
should force the user agent to preserve the original method for the request
534567
(e.g. GET, POST) instead of (possibly) forcing the user agent to change the
535568
method to GET.
536569
537
-<a name="regexp"></a>TH1 regexp Command
570
+<a id="regexp"></a>TH1 regexp Command
538571
---------------------------------------
539572
540573
* regexp ?-nocase? ?--? exp string
541574
542575
Checks the string against the specified regular expression and returns
543576
non-zero if it matches. If the regular expression is invalid or cannot
544577
be compiled, an error will be generated.
545578
546
-<a name="reinitialize"></a>TH1 reinitialize Command
579
+<a id="reinitialize"></a>TH1 reinitialize Command
547580
---------------------------------------------------
548581
549582
* reinitialize ?FLAGS?
550583
551584
Reinitializes the TH1 interpreter using the specified flags.
552585
553
-<a name="render"></a>TH1 render Command
586
+<a id="render"></a>TH1 render Command
554587
---------------------------------------
555588
556589
* render STRING
557590
558591
Renders the TH1 template and writes the results.
559592
560
-<a name="repository"></a>TH1 repository Command
593
+<a id="repository"></a>TH1 repository Command
561594
-----------------------------------------------
562595
563596
* repository ?BOOLEAN?
564597
565598
Returns the fully qualified file name of the open repository or an empty
566599
string if one is not currently open. Optionally, it will attempt to open
567600
the repository if the boolean argument is non-zero.
568601
569
-<a name="searchable"></a>TH1 searchable Command
602
+<a id="searchable"></a>TH1 searchable Command
570603
-----------------------------------------------
571604
572605
* searchable STRING...
573606
574607
Return true if searching in any of the document classes identified
@@ -593,54 +626,54 @@
593626
if {[searchable cdtw]} {...}
594627
595628
This command is useful for enabling or disabling a "Search" entry on the
596629
menu bar.
597630
598
-<a name="setParameter"></a>TH1 setParameter Command
631
+<a id="setParameter"></a>TH1 setParameter Command
599632
---------------------------------------------------
600633
601634
* setParameter NAME VALUE
602635
603636
Sets the value of the specified query parameter.
604637
605
-<a name="setting"></a>TH1 setting Command
638
+<a id="setting"></a>TH1 setting Command
606639
-----------------------------------------
607640
608641
* setting name
609642
610643
Gets and returns the value of the specified setting.
611644
612
-<a name="stime"></a>TH1 stime Command
645
+<a id="stime"></a>TH1 stime Command
613646
-------------------------------------
614647
615648
* stime
616649
617650
Returns the number of microseconds of CPU time consumed by the current
618651
process in system space.
619652
620
-<a name="styleHeader"></a>TH1 styleHeader Command
653
+<a id="styleHeader"></a>TH1 styleHeader Command
621654
-------------------------------------------------
622655
623656
* styleHeader TITLE
624657
625658
Render the configured style header for the selected skin.
626659
627
-<a name="styleFooter"></a>TH1 styleFooter Command
660
+<a id="styleFooter"></a>TH1 styleFooter Command
628661
-------------------------------------------------
629662
630663
* styleFooter
631664
632665
Render the configured style footer for the selected skin.
633666
634
-<a name="styleScript"></a>TH1 styleScript Command
667
+<a id="styleScript"></a>TH1 styleScript Command
635668
-------------------------------------------------
636669
637670
* styleScript
638671
639672
Render the configured JavaScript for the selected skin.
640673
641
-<a name="tclEval"></a>TH1 tclEval Command
674
+<a id="tclEval"></a>TH1 tclEval Command
642675
-----------------------------------------
643676
644677
**This command requires the Tcl integration feature.**
645678
646679
* tclEval arg ?arg ...?
@@ -647,11 +680,11 @@
647680
648681
Evaluates the Tcl script and returns its result verbatim. If a Tcl script
649682
error is generated, it will be transformed into a TH1 script error. The
650683
Tcl interpreter will be created automatically if it has not been already.
651684
652
-<a name="tclExpr"></a>TH1 tclExpr Command
685
+<a id="tclExpr"></a>TH1 tclExpr Command
653686
-----------------------------------------
654687
655688
**This command requires the Tcl integration feature.**
656689
657690
* tclExpr arg ?arg ...?
@@ -659,11 +692,11 @@
659692
Evaluates the Tcl expression and returns its result verbatim. If a Tcl
660693
script error is generated, it will be transformed into a TH1 script
661694
error. The Tcl interpreter will be created automatically if it has not
662695
been already.
663696
664
-<a name="tclInvoke"></a>TH1 tclInvoke Command
697
+<a id="tclInvoke"></a>TH1 tclInvoke Command
665698
---------------------------------------------
666699
667700
**This command requires the Tcl integration feature.**
668701
669702
* tclInvoke command ?arg ...?
@@ -670,21 +703,21 @@
670703
671704
Invokes the Tcl command using the supplied arguments. No additional
672705
substitutions are performed on the arguments. The Tcl interpreter
673706
will be created automatically if it has not been already.
674707
675
-<a name="tclIsSafe"></a>TH1 tclIsSafe Command
708
+<a id="tclIsSafe"></a>TH1 tclIsSafe Command
676709
---------------------------------------------
677710
678711
**This command requires the Tcl integration feature.**
679712
680713
* tclIsSafe
681714
682715
Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
683716
will be created automatically if it has not been already.
684717
685
-<a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
718
+<a id="tclMakeSafe"></a>TH1 tclMakeSafe Command
686719
-------------------------------------------------
687720
688721
**This command requires the Tcl integration feature.**
689722
690723
* tclMakeSafe
@@ -692,51 +725,51 @@
692725
Forces the Tcl interpreter into "safe" mode by removing all "unsafe"
693726
commands and variables. This operation cannot be undone. The Tcl
694727
interpreter will remain "safe" until the process terminates. The Tcl
695728
interpreter will be created automatically if it has not been already.
696729
697
-<a name="tclReady"></a>TH1 tclReady Command
730
+<a id="tclReady"></a>TH1 tclReady Command
698731
-------------------------------------------
699732
700733
* tclReady
701734
702735
Returns true if the binary has the Tcl integration feature enabled and it
703736
is currently available for use by TH1 scripts.
704737
705
-<a name="trace"></a>TH1 trace Command
738
+<a id="trace"></a>TH1 trace Command
706739
-------------------------------------
707740
708741
* trace STRING
709742
710743
Generates a TH1 trace message if TH1 tracing is enabled.
711744
712
-<a name="unversioned_content"></a>TH1 unversioned content Command
745
+<a id="unversioned_content"></a>TH1 unversioned content Command
713746
-----------------------------------------------------------------
714747
715748
* unversioned content FILENAME
716749
717750
Attempts to locate the specified unversioned file and return its contents.
718751
An error is generated if the repository is not open or the unversioned file
719752
cannot be found.
720753
721
-<a name="unversioned_list"></a>TH1 unversioned list Command
754
+<a id="unversioned_list"></a>TH1 unversioned list Command
722755
-----------------------------------------------------------
723756
724757
* unversioned list
725758
726759
Returns a list of the names of all unversioned files held in the local
727760
repository. An error is generated if the repository is not open.
728761
729
-<a name="utime"></a>TH1 utime Command
762
+<a id="utime"></a>TH1 utime Command
730763
-------------------------------------
731764
732765
* utime
733766
734767
Returns the number of microseconds of CPU time consumed by the current
735768
process in user space.
736769
737
-<a name="verifyCsrf"></a>TH1 verifyCsrf Command
770
+<a id="verifyCsrf"></a>TH1 verifyCsrf Command
738771
-----------------------------------------------
739772
740773
* verifyCsrf
741774
742775
Before using the results of a form, first call this command to verify
@@ -743,19 +776,19 @@
743776
that this Anti-CSRF token is present and is valid. If the Anti-CSRF token
744777
is missing or is incorrect, that indicates a cross-site scripting attack.
745778
If the event of an attack is detected, an error message is generated and
746779
all further processing is aborted.
747780
748
-<a name="verifyLogin"></a>TH1 verifyLogin Command
781
+<a id="verifyLogin"></a>TH1 verifyLogin Command
749782
-------------------------------------------------
750783
751784
* verifyLogin
752785
753786
Returns non-zero if the specified user name and password represent a
754787
valid login for the repository.
755788
756
-<a name="wiki"></a>TH1 wiki Command
789
+<a id="wiki"></a>TH1 wiki Command
757790
-----------------------------------
758791
759792
* wiki STRING
760793
761794
Renders STRING as wiki content.
@@ -769,24 +802,24 @@
769802
Tcl commands:
770803
771804
* th1Eval
772805
* th1Expr
773806
774
-<a name="th1Eval"></a>Tcl th1Eval Command
807
+<a id="th1Eval"></a>Tcl th1Eval Command
775808
-----------------------------------------
776809
777810
**This command requires the Tcl integration feature.**
778811
779812
* th1Eval arg
780813
781814
Evaluates the TH1 script and returns its result verbatim. If a TH1 script
782815
error is generated, it will be transformed into a Tcl script error.
783816
784
-<a name="th1Expr"></a>Tcl th1Expr Command
817
+<a id="th1Expr"></a>Tcl th1Expr Command
785818
-----------------------------------------
786819
787820
**This command requires the Tcl integration feature.**
788821
789822
* th1Expr arg
790823
791824
Evaluates the TH1 expression and returns its result verbatim. If a TH1
792825
script error is generated, it will be transformed into a Tcl script error.
793826
--- www/th1.md
+++ www/th1.md
@@ -164,116 +164,130 @@
164 ---------------------
165
166 There are many new commands added to TH1 and used to access the special
167 features of Fossil. The following is a summary of the extended commands:
168
169 * anoncap
170 * anycap
171 * artifact
172 * cgiHeaderLine
173 * checkout
174 * combobox
175 * copybtn
176 * date
177 * decorate
178 * defHeader
179 * dir
180 * enable\_output
181 * encode64
182 * getParameter
183 * glob\_match
184 * globalState
185 * hascap
186 * hasfeature
187 * html
188 * htmlize
189 * http
190 * httpize
191 * insertCsrf
192 * linecount
193 * markdown
194 * nonce
195 * puts
196 * query
197 * randhex
198 * redirect
199 * regexp
200 * reinitialize
201 * render
202 * repository
203 * searchable
204 * setParameter
205 * setting
206 * stime
207 * styleHeader
208 * styleFooter
209 * styleScript
210 * tclEval
211 * tclExpr
212 * tclInvoke
213 * tclIsSafe
214 * tclMakeSafe
215 * tclReady
216 * trace
217 * unversioned content
218 * unversioned list
219 * utime
220 * verifyCsrf
221 * verifyLogin
222 * wiki
 
 
223
224 Each of the commands above is documented by a block comment above their
225 implementation in the th\_main.c or th\_tcl.c source files.
226
227 All commands starting with "tcl", with the exception of "tclReady",
228 require the Tcl integration subsystem be included at compile-time.
229 Additionally, the "tcl" repository setting must be enabled at runtime
230 in order to successfully make use of these commands.
231
232 <a name="anoncap"></a>TH1 anoncap Command
233 -----------------------------------------
234
235 * anoncap STRING...
236
237 Returns true if the anonymous user has all of the capabilities listed
238 in STRING.
239
240 <a name="anycap"></a>TH1 anycap Command
241 ---------------------------------------
242
243 * anycap STRING
244
245 Returns true if the current user user has any one of the capabilities
246 listed in STRING.
247
248 <a name="artifact"></a>TH1 artifact Command
249 -------------------------------------------
250
251 * artifact ID ?FILENAME?
252
253 Attempts to locate the specified artifact and return its contents. An
254 error is generated if the repository is not open or the artifact cannot
255 be found.
256
257 <a name="cgiHeaderLine"></a>TH1 cgiHeaderLine Command
 
 
 
 
 
 
 
 
 
 
 
 
258 -----------------------------------------------------
259
260 * cgiHeaderLine line
261
262 Adds the specified line to the CGI header.
263
264 <a name="checkout"></a>TH1 checkout Command
265 -------------------------------------------
266
267 * checkout ?BOOLEAN?
268
269 Return the fully qualified directory name of the current checkout or an
270 empty string if it is not available. Optionally, it will attempt to find
271 the current checkout, opening the configuration ("user") database and the
272 repository as necessary, if the boolean argument is non-zero.
273
274 <a name="combobox"></a>TH1 combobox Command
275 -------------------------------------------
276
277 * combobox NAME TEXT-LIST NUMLINES
278
279 Generates and emits an HTML combobox. NAME is both the name of the
@@ -280,11 +294,11 @@
280 CGI parameter and the name of a variable that contains the currently
281 selected value. TEXT-LIST is a list of possible values for the
282 combobox. NUMLINES is 1 for a true combobox. If NUMLINES is greater
283 than one then the display is a listbox with the number of lines given.
284
285 <a name="copybtn"></a>TH1 copybtn Command
286 -----------------------------------------
287
288 * copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
289
290 Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
@@ -302,34 +316,34 @@
302 * >= 3: Truncate TEXT after COPYLENGTH (single-byte) characters.
303 * 1: Use the "hash-digits" setting as the limit.
304 * 2: Use the length appropriate for URLs as the limit (defined at
305 compile-time by `FOSSIL_HASH_DIGITS_URL`, defaults to 16).
306
307 <a name="date"></a>TH1 date Command
308 -----------------------------------
309
310 * date ?-local?
311
312 Return a strings which is the current time and date. If the -local
313 option is used, the date appears using localtime instead of UTC.
314
315 <a name="decorate"></a>TH1 decorate Command
316 -------------------------------------------
317
318 * decorate STRING
319
320 Renders STRING as wiki content; however, only links are handled. No
321 other markup is processed.
322
323 <a name="defHeader"></a>TH1 defHeader Command
324 ---------------------------------------------
325
326 * defHeader
327
328 Returns the default page header.
329
330 <a name="dir"></a>TH1 dir Command
331 ---------------------------------
332
333 * dir CHECKIN ?GLOB? ?DETAILS?
334
335 Returns a list containing all files in CHECKIN. If GLOB is given only
@@ -337,42 +351,60 @@
337 If DETAILS is non-zero, the result will be a list-of-lists, with each
338 element containing at least three elements: the file name, the file
339 size (in bytes), and the file last modification time (relative to the
340 time zone configured for the repository).
341
342 <a name="enable_output"></a>TH1 enable\_output Command
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343 ------------------------------------------------------
344
345 * enable\_output BOOLEAN
346
347 Enable or disable sending output when the combobox, copybtn, puts, or wiki
348 commands are used.
349
350 <a name="encode64"></a>TH1 encode64 Command
351 -------------------------------------------
352
353 * encode64 STRING
354
355 Encode the specified string using Base64 and return the result.
356
357 <a name="getParameter"></a>TH1 getParameter Command
358 ---------------------------------------------------
359
360 * getParameter NAME ?DEFAULT?
361
362 Returns the value of the specified query parameter or the specified
363 default value when there is no matching query parameter.
364
365 <a name="glob_match"></a>TH1 glob\_match Command
366 ------------------------------------------------
367
368 * glob\_match ?-one? ?--? patternList string
369
370 Checks the string against the specified glob pattern -OR- list of glob
371 patterns and returns non-zero if there is a match.
372
373 <a name="globalState"></a>TH1 globalState Command
374 -------------------------------------------------
375
376 * globalState NAME ?DEFAULT?
377
378 Returns a string containing the value of the specified global state
@@ -390,19 +422,19 @@
390
391 Attempts to query for unsupported global state variables will result
392 in a script error. Additional global state variables may be exposed
393 in the future.
394
395 <a name="hascap"></a>TH1 hascap Command
396 ---------------------------------------
397
398 * hascap STRING...
399
400 Returns true if the current user has all of the capabilities listed
401 in STRING.
402
403 <a name="hasfeature"></a>TH1 hasfeature Command
404 -----------------------------------------------
405
406 * hasfeature STRING
407
408 Returns true if the binary has the given compile-time feature enabled.
@@ -425,26 +457,26 @@
425 1. **see** -- _Uses the SQLite Encryption Extension._
426
427 Specifying an unknown feature will return a value of false, it will not
428 raise a script error.
429
430 <a name="html"></a>TH1 html Command
431 -----------------------------------
432
433 * html STRING
434
435 Outputs the STRING escaped for HTML.
436
437 <a name="htmlize"></a>TH1 htmlize Command
438 -----------------------------------------
439
440 * htmlize STRING
441
442 Escape all characters of STRING which have special meaning in HTML.
443 Returns the escaped string.
444
445 <a name="http"></a>TH1 http Command
446 -----------------------------------
447
448 * http ?-asynchronous? ?--? url ?payload?
449
450 Performs an HTTP or HTTPS request for the specified URL. If a
@@ -453,58 +485,59 @@
453 be used. Upon success, if the -asynchronous option is used, an
454 empty string is returned as the result; otherwise, the response
455 from the server is returned as the result. Synchronous requests
456 are not currently implemented.
457
458 <a name="httpize"></a>TH1 httpize Command
459 -----------------------------------------
460
461 * httpize STRING
462
463 Escape all characters of STRING which have special meaning in URI
464 components. Returns the escaped string.
465
466 <a name="insertCsrf"></a>TH1 insertCsrf Command
467 -----------------------------------------------
468
469 * insertCsrf
470
471 While rendering a form, call this command to add the Anti-CSRF token
472 as a hidden element of the form.
473
474 <a name="linecount"></a>TH1 linecount Command
475 ---------------------------------------------
476
477 * linecount STRING MAX MIN
478
479 Returns one more than the number of \n characters in STRING. But
480 never returns less than MIN or more than MAX.
481
482 <a name="markdown"></a>TH1 markdown Command
483 -------------------------------------------
484
485 * markdown STRING
486
487 Renders the input string as markdown. The result is a two-element list.
488 The first element contains the body, rendered as HTML. The second element
489 is the text-only title string.
490
491 <a name="nonce"></a>TH1 nonce Command
492 -------------------------------------
493
494 * nonce
495
496 Returns the value of the cryptographic nonce for the request being processed.
497
498 <a name="puts"></a>TH1 puts Command
499 -----------------------------------
500
501 * puts STRING
502
503 Outputs the STRING unchanged.
 
504
505 <a name="query"></a>TH1 query Command
506 -------------------------------------
507
508 * query ?-nocomplain? SQL CODE
509
510 Runs the SQL query given by the SQL argument. For each row in the result
@@ -512,19 +545,19 @@
512
513 In SQL, parameters such as $var are filled in using the value of variable
514 "var". Result values are stored in variables with the column name prior
515 to each invocation of CODE.
516
517 <a name="randhex"></a>TH1 randhex Command
518 -----------------------------------------
519
520 * randhex N
521
522 Returns a string of N*2 random hexadecimal digits with N<50. If N is
523 omitted, use a value of 10.
524
525 <a name="redirect"></a>TH1 redirect Command
526 -------------------------------------------
527
528 * redirect URL ?withMethod?
529
530 Issues an HTTP redirect to the specified URL and then exits the process.
@@ -532,43 +565,43 @@
532 argument is present and non-zero, an HTTP status code of 307 is used, which
533 should force the user agent to preserve the original method for the request
534 (e.g. GET, POST) instead of (possibly) forcing the user agent to change the
535 method to GET.
536
537 <a name="regexp"></a>TH1 regexp Command
538 ---------------------------------------
539
540 * regexp ?-nocase? ?--? exp string
541
542 Checks the string against the specified regular expression and returns
543 non-zero if it matches. If the regular expression is invalid or cannot
544 be compiled, an error will be generated.
545
546 <a name="reinitialize"></a>TH1 reinitialize Command
547 ---------------------------------------------------
548
549 * reinitialize ?FLAGS?
550
551 Reinitializes the TH1 interpreter using the specified flags.
552
553 <a name="render"></a>TH1 render Command
554 ---------------------------------------
555
556 * render STRING
557
558 Renders the TH1 template and writes the results.
559
560 <a name="repository"></a>TH1 repository Command
561 -----------------------------------------------
562
563 * repository ?BOOLEAN?
564
565 Returns the fully qualified file name of the open repository or an empty
566 string if one is not currently open. Optionally, it will attempt to open
567 the repository if the boolean argument is non-zero.
568
569 <a name="searchable"></a>TH1 searchable Command
570 -----------------------------------------------
571
572 * searchable STRING...
573
574 Return true if searching in any of the document classes identified
@@ -593,54 +626,54 @@
593 if {[searchable cdtw]} {...}
594
595 This command is useful for enabling or disabling a "Search" entry on the
596 menu bar.
597
598 <a name="setParameter"></a>TH1 setParameter Command
599 ---------------------------------------------------
600
601 * setParameter NAME VALUE
602
603 Sets the value of the specified query parameter.
604
605 <a name="setting"></a>TH1 setting Command
606 -----------------------------------------
607
608 * setting name
609
610 Gets and returns the value of the specified setting.
611
612 <a name="stime"></a>TH1 stime Command
613 -------------------------------------
614
615 * stime
616
617 Returns the number of microseconds of CPU time consumed by the current
618 process in system space.
619
620 <a name="styleHeader"></a>TH1 styleHeader Command
621 -------------------------------------------------
622
623 * styleHeader TITLE
624
625 Render the configured style header for the selected skin.
626
627 <a name="styleFooter"></a>TH1 styleFooter Command
628 -------------------------------------------------
629
630 * styleFooter
631
632 Render the configured style footer for the selected skin.
633
634 <a name="styleScript"></a>TH1 styleScript Command
635 -------------------------------------------------
636
637 * styleScript
638
639 Render the configured JavaScript for the selected skin.
640
641 <a name="tclEval"></a>TH1 tclEval Command
642 -----------------------------------------
643
644 **This command requires the Tcl integration feature.**
645
646 * tclEval arg ?arg ...?
@@ -647,11 +680,11 @@
647
648 Evaluates the Tcl script and returns its result verbatim. If a Tcl script
649 error is generated, it will be transformed into a TH1 script error. The
650 Tcl interpreter will be created automatically if it has not been already.
651
652 <a name="tclExpr"></a>TH1 tclExpr Command
653 -----------------------------------------
654
655 **This command requires the Tcl integration feature.**
656
657 * tclExpr arg ?arg ...?
@@ -659,11 +692,11 @@
659 Evaluates the Tcl expression and returns its result verbatim. If a Tcl
660 script error is generated, it will be transformed into a TH1 script
661 error. The Tcl interpreter will be created automatically if it has not
662 been already.
663
664 <a name="tclInvoke"></a>TH1 tclInvoke Command
665 ---------------------------------------------
666
667 **This command requires the Tcl integration feature.**
668
669 * tclInvoke command ?arg ...?
@@ -670,21 +703,21 @@
670
671 Invokes the Tcl command using the supplied arguments. No additional
672 substitutions are performed on the arguments. The Tcl interpreter
673 will be created automatically if it has not been already.
674
675 <a name="tclIsSafe"></a>TH1 tclIsSafe Command
676 ---------------------------------------------
677
678 **This command requires the Tcl integration feature.**
679
680 * tclIsSafe
681
682 Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
683 will be created automatically if it has not been already.
684
685 <a name="tclMakeSafe"></a>TH1 tclMakeSafe Command
686 -------------------------------------------------
687
688 **This command requires the Tcl integration feature.**
689
690 * tclMakeSafe
@@ -692,51 +725,51 @@
692 Forces the Tcl interpreter into "safe" mode by removing all "unsafe"
693 commands and variables. This operation cannot be undone. The Tcl
694 interpreter will remain "safe" until the process terminates. The Tcl
695 interpreter will be created automatically if it has not been already.
696
697 <a name="tclReady"></a>TH1 tclReady Command
698 -------------------------------------------
699
700 * tclReady
701
702 Returns true if the binary has the Tcl integration feature enabled and it
703 is currently available for use by TH1 scripts.
704
705 <a name="trace"></a>TH1 trace Command
706 -------------------------------------
707
708 * trace STRING
709
710 Generates a TH1 trace message if TH1 tracing is enabled.
711
712 <a name="unversioned_content"></a>TH1 unversioned content Command
713 -----------------------------------------------------------------
714
715 * unversioned content FILENAME
716
717 Attempts to locate the specified unversioned file and return its contents.
718 An error is generated if the repository is not open or the unversioned file
719 cannot be found.
720
721 <a name="unversioned_list"></a>TH1 unversioned list Command
722 -----------------------------------------------------------
723
724 * unversioned list
725
726 Returns a list of the names of all unversioned files held in the local
727 repository. An error is generated if the repository is not open.
728
729 <a name="utime"></a>TH1 utime Command
730 -------------------------------------
731
732 * utime
733
734 Returns the number of microseconds of CPU time consumed by the current
735 process in user space.
736
737 <a name="verifyCsrf"></a>TH1 verifyCsrf Command
738 -----------------------------------------------
739
740 * verifyCsrf
741
742 Before using the results of a form, first call this command to verify
@@ -743,19 +776,19 @@
743 that this Anti-CSRF token is present and is valid. If the Anti-CSRF token
744 is missing or is incorrect, that indicates a cross-site scripting attack.
745 If the event of an attack is detected, an error message is generated and
746 all further processing is aborted.
747
748 <a name="verifyLogin"></a>TH1 verifyLogin Command
749 -------------------------------------------------
750
751 * verifyLogin
752
753 Returns non-zero if the specified user name and password represent a
754 valid login for the repository.
755
756 <a name="wiki"></a>TH1 wiki Command
757 -----------------------------------
758
759 * wiki STRING
760
761 Renders STRING as wiki content.
@@ -769,24 +802,24 @@
769 Tcl commands:
770
771 * th1Eval
772 * th1Expr
773
774 <a name="th1Eval"></a>Tcl th1Eval Command
775 -----------------------------------------
776
777 **This command requires the Tcl integration feature.**
778
779 * th1Eval arg
780
781 Evaluates the TH1 script and returns its result verbatim. If a TH1 script
782 error is generated, it will be transformed into a Tcl script error.
783
784 <a name="th1Expr"></a>Tcl th1Expr Command
785 -----------------------------------------
786
787 **This command requires the Tcl integration feature.**
788
789 * th1Expr arg
790
791 Evaluates the TH1 expression and returns its result verbatim. If a TH1
792 script error is generated, it will be transformed into a Tcl script error.
793
--- www/th1.md
+++ www/th1.md
@@ -164,116 +164,130 @@
164 ---------------------
165
166 There are many new commands added to TH1 and used to access the special
167 features of Fossil. The following is a summary of the extended commands:
168
169 * [anoncap](#anoncap)
170 * [anycap](#anycap)
171 * [artifact](#artifact)
172 * [captureTh1](#captureTh1)
173 * [cgiHeaderLine](#cgiHeaderLine)
174 * [checkout](#checkout)
175 * [combobox](#combobox)
176 * [copybtn](#copybtn)
177 * [date](#date)
178 * [decorate](#decorate)
179 * [defHeader](#defHeader)
180 * [dir](#dir)
181 * [enable\_htmlify](#enable_htmlify)
182 * [enable\_output](#enable_output)
183 * [encode64](#encode64)
184 * [getParameter](#getParameter)
185 * [glob\_match](#glob_match)
186 * [globalState](#globalState)
187 * [hascap](#hascap)
188 * [hasfeature](#hasfeature)
189 * [html](#html)
190 * [htmlize](#htmlize)
191 * [http](#http)
192 * [httpize](#httpize)
193 * [insertCsrf](#insertCsrf)
194 * [linecount](#linecount)
195 * [markdown](#markdown)
196 * [nonce](#nonce)
197 * [puts](#puts)
198 * [query](#query)
199 * [randhex](#randhex)
200 * [redirect](#redirect)
201 * [regexp](#regexp)
202 * [reinitialize](#reinitialize)
203 * [render](#render)
204 * [repository](#repository)
205 * [searchable](#searchable)
206 * [setParameter](#setParameter)
207 * [setting](#setting)
208 * [stime](#stime)
209 * [styleHeader](#styleHeader)
210 * [styleFooter](#styleFooter)
211 * [styleScript](#styleScript)
212 * [tclEval](#tclEval)
213 * [tclExpr](#tclExpr)
214 * [tclInvoke](#tclInvoke)
215 * [tclIsSafe](#tclIsSafe)
216 * [tclMakeSafe](#tclMakeSafe)
217 * [tclReady](#tclReady)
218 * [trace](#trace)
219 * [unversioned content](#unversioned_content)
220 * [unversioned list](#unversioned_list)
221 * [utime](#utime)
222 * [verifyCsrf](#verifyCsrf)
223 * [verifyLogin](#verifyLogin)
224 * [wiki](#wiki)
225
226 Each of the commands above is documented by a block comment above their
227 implementation in the th\_main.c or th\_tcl.c source files.
228
229 All commands starting with "tcl", with the exception of "tclReady",
230 require the Tcl integration subsystem be included at compile-time.
231 Additionally, the "tcl" repository setting must be enabled at runtime
232 in order to successfully make use of these commands.
233
234 <a id="anoncap"></a>TH1 anoncap Command
235 -----------------------------------------
236
237 * anoncap STRING...
238
239 Returns true if the anonymous user has all of the capabilities listed
240 in STRING.
241
242 <a id="anycap"></a>TH1 anycap Command
243 ---------------------------------------
244
245 * anycap STRING
246
247 Returns true if the current user user has any one of the capabilities
248 listed in STRING.
249
250 <a id="artifact"></a>TH1 artifact Command
251 -------------------------------------------
252
253 * artifact ID ?FILENAME?
254
255 Attempts to locate the specified artifact and return its contents. An
256 error is generated if the repository is not open or the artifact cannot
257 be found.
258
259 <a id="captureTh1"></a>TH1 captureTh1 Command
260 -----------------------------------------------------
261
262 * captureTh1 STRING
263
264 Executes its single argument as TH1 code and captures any
265 TH1-generated output as a string, which becomes the result of the
266 function call. e.g. any `puts` calls made from that block will not
267 generate any output, and instead their output will become part of the
268 result string.
269
270
271 <a id="cgiHeaderLine"></a>TH1 cgiHeaderLine Command
272 -----------------------------------------------------
273
274 * cgiHeaderLine line
275
276 Adds the specified line to the CGI header.
277
278 <a id="checkout"></a>TH1 checkout Command
279 -------------------------------------------
280
281 * checkout ?BOOLEAN?
282
283 Return the fully qualified directory name of the current checkout or an
284 empty string if it is not available. Optionally, it will attempt to find
285 the current checkout, opening the configuration ("user") database and the
286 repository as necessary, if the boolean argument is non-zero.
287
288 <a id="combobox"></a>TH1 combobox Command
289 -------------------------------------------
290
291 * combobox NAME TEXT-LIST NUMLINES
292
293 Generates and emits an HTML combobox. NAME is both the name of the
@@ -280,11 +294,11 @@
294 CGI parameter and the name of a variable that contains the currently
295 selected value. TEXT-LIST is a list of possible values for the
296 combobox. NUMLINES is 1 for a true combobox. If NUMLINES is greater
297 than one then the display is a listbox with the number of lines given.
298
299 <a id="copybtn"></a>TH1 copybtn Command
300 -----------------------------------------
301
302 * copybtn TARGETID FLIPPED TEXT ?COPYLENGTH?
303
304 Output TEXT with a click-to-copy button next to it. Loads the copybtn.js
@@ -302,34 +316,34 @@
316 * >= 3: Truncate TEXT after COPYLENGTH (single-byte) characters.
317 * 1: Use the "hash-digits" setting as the limit.
318 * 2: Use the length appropriate for URLs as the limit (defined at
319 compile-time by `FOSSIL_HASH_DIGITS_URL`, defaults to 16).
320
321 <a id="date"></a>TH1 date Command
322 -----------------------------------
323
324 * date ?-local?
325
326 Return a strings which is the current time and date. If the -local
327 option is used, the date appears using localtime instead of UTC.
328
329 <a id="decorate"></a>TH1 decorate Command
330 -------------------------------------------
331
332 * decorate STRING
333
334 Renders STRING as wiki content; however, only links are handled. No
335 other markup is processed.
336
337 <a id="defHeader"></a>TH1 defHeader Command
338 ---------------------------------------------
339
340 * defHeader
341
342 Returns the default page header.
343
344 <a id="dir"></a>TH1 dir Command
345 ---------------------------------
346
347 * dir CHECKIN ?GLOB? ?DETAILS?
348
349 Returns a list containing all files in CHECKIN. If GLOB is given only
@@ -337,42 +351,60 @@
351 If DETAILS is non-zero, the result will be a list-of-lists, with each
352 element containing at least three elements: the file name, the file
353 size (in bytes), and the file last modification time (relative to the
354 time zone configured for the repository).
355
356 <a id="enable_htmlify"></a>TH1 enable\_htmlify Command
357 ------------------------------------------------------
358
359 * enable\_htmlify
360 * enable\_htmlify ?TRACE-LABEL? BOOLEAN
361
362 By default, certain output from `puts` and similar commands is escaped
363 for HTML. The first call form returns the current state of that
364 feature: `1` for on and `0` for off. The second call form enables
365 (non-0) or disables (0) that feature and returns the *pre-call* state
366 of that feature (so that a second call can pass that value to restore
367 it to its previous state). The optional `TRACE-LABEL` argument causes
368 the TH1 tracing output (if enabled) to add a marker when the second
369 form of this command is invoked, and includes that label and the
370 boolean argument's value in the trace. If tracing is disabled, that
371 argument has no effect.
372
373
374 <a id="enable_output"></a>TH1 enable\_output Command
375 ------------------------------------------------------
376
377 * enable\_output BOOLEAN
378
379 Enable or disable sending output when the combobox, copybtn, puts, or wiki
380 commands are used.
381
382 <a id="encode64"></a>TH1 encode64 Command
383 -------------------------------------------
384
385 * encode64 STRING
386
387 Encode the specified string using Base64 and return the result.
388
389 <a id="getParameter"></a>TH1 getParameter Command
390 ---------------------------------------------------
391
392 * getParameter NAME ?DEFAULT?
393
394 Returns the value of the specified query parameter or the specified
395 default value when there is no matching query parameter.
396
397 <a id="glob_match"></a>TH1 glob\_match Command
398 ------------------------------------------------
399
400 * glob\_match ?-one? ?--? patternList string
401
402 Checks the string against the specified glob pattern -OR- list of glob
403 patterns and returns non-zero if there is a match.
404
405 <a id="globalState"></a>TH1 globalState Command
406 -------------------------------------------------
407
408 * globalState NAME ?DEFAULT?
409
410 Returns a string containing the value of the specified global state
@@ -390,19 +422,19 @@
422
423 Attempts to query for unsupported global state variables will result
424 in a script error. Additional global state variables may be exposed
425 in the future.
426
427 <a id="hascap"></a>TH1 hascap Command
428 ---------------------------------------
429
430 * hascap STRING...
431
432 Returns true if the current user has all of the capabilities listed
433 in STRING.
434
435 <a id="hasfeature"></a>TH1 hasfeature Command
436 -----------------------------------------------
437
438 * hasfeature STRING
439
440 Returns true if the binary has the given compile-time feature enabled.
@@ -425,26 +457,26 @@
457 1. **see** -- _Uses the SQLite Encryption Extension._
458
459 Specifying an unknown feature will return a value of false, it will not
460 raise a script error.
461
462 <a id="html"></a>TH1 html Command
463 -----------------------------------
464
465 * html STRING
466
467 Outputs the STRING escaped for HTML.
468
469 <a id="htmlize"></a>TH1 htmlize Command
470 -----------------------------------------
471
472 * htmlize STRING
473
474 Escape all characters of STRING which have special meaning in HTML.
475 Returns the escaped string.
476
477 <a id="http"></a>TH1 http Command
478 -----------------------------------
479
480 * http ?-asynchronous? ?--? url ?payload?
481
482 Performs an HTTP or HTTPS request for the specified URL. If a
@@ -453,58 +485,59 @@
485 be used. Upon success, if the -asynchronous option is used, an
486 empty string is returned as the result; otherwise, the response
487 from the server is returned as the result. Synchronous requests
488 are not currently implemented.
489
490 <a id="httpize"></a>TH1 httpize Command
491 -----------------------------------------
492
493 * httpize STRING
494
495 Escape all characters of STRING which have special meaning in URI
496 components. Returns the escaped string.
497
498 <a id="insertCsrf"></a>TH1 insertCsrf Command
499 -----------------------------------------------
500
501 * insertCsrf
502
503 While rendering a form, call this command to add the Anti-CSRF token
504 as a hidden element of the form.
505
506 <a id="linecount"></a>TH1 linecount Command
507 ---------------------------------------------
508
509 * linecount STRING MAX MIN
510
511 Returns one more than the number of \n characters in STRING. But
512 never returns less than MIN or more than MAX.
513
514 <a id="markdown"></a>TH1 markdown Command
515 -------------------------------------------
516
517 * markdown STRING
518
519 Renders the input string as markdown. The result is a two-element list.
520 The first element contains the body, rendered as HTML. The second element
521 is the text-only title string.
522
523 <a id="nonce"></a>TH1 nonce Command
524 -------------------------------------
525
526 * nonce
527
528 Returns the value of the cryptographic nonce for the request being processed.
529
530 <a id="puts"></a>TH1 puts Command
531 -----------------------------------
532
533 * puts STRING
534
535 Outputs the STRING unchanged, where "unchanged" might, depending on
536 the context, mean "with some characters escaped for HTML."
537
538 <a id="query"></a>TH1 query Command
539 -------------------------------------
540
541 * query ?-nocomplain? SQL CODE
542
543 Runs the SQL query given by the SQL argument. For each row in the result
@@ -512,19 +545,19 @@
545
546 In SQL, parameters such as $var are filled in using the value of variable
547 "var". Result values are stored in variables with the column name prior
548 to each invocation of CODE.
549
550 <a id="randhex"></a>TH1 randhex Command
551 -----------------------------------------
552
553 * randhex N
554
555 Returns a string of N*2 random hexadecimal digits with N<50. If N is
556 omitted, use a value of 10.
557
558 <a id="redirect"></a>TH1 redirect Command
559 -------------------------------------------
560
561 * redirect URL ?withMethod?
562
563 Issues an HTTP redirect to the specified URL and then exits the process.
@@ -532,43 +565,43 @@
565 argument is present and non-zero, an HTTP status code of 307 is used, which
566 should force the user agent to preserve the original method for the request
567 (e.g. GET, POST) instead of (possibly) forcing the user agent to change the
568 method to GET.
569
570 <a id="regexp"></a>TH1 regexp Command
571 ---------------------------------------
572
573 * regexp ?-nocase? ?--? exp string
574
575 Checks the string against the specified regular expression and returns
576 non-zero if it matches. If the regular expression is invalid or cannot
577 be compiled, an error will be generated.
578
579 <a id="reinitialize"></a>TH1 reinitialize Command
580 ---------------------------------------------------
581
582 * reinitialize ?FLAGS?
583
584 Reinitializes the TH1 interpreter using the specified flags.
585
586 <a id="render"></a>TH1 render Command
587 ---------------------------------------
588
589 * render STRING
590
591 Renders the TH1 template and writes the results.
592
593 <a id="repository"></a>TH1 repository Command
594 -----------------------------------------------
595
596 * repository ?BOOLEAN?
597
598 Returns the fully qualified file name of the open repository or an empty
599 string if one is not currently open. Optionally, it will attempt to open
600 the repository if the boolean argument is non-zero.
601
602 <a id="searchable"></a>TH1 searchable Command
603 -----------------------------------------------
604
605 * searchable STRING...
606
607 Return true if searching in any of the document classes identified
@@ -593,54 +626,54 @@
626 if {[searchable cdtw]} {...}
627
628 This command is useful for enabling or disabling a "Search" entry on the
629 menu bar.
630
631 <a id="setParameter"></a>TH1 setParameter Command
632 ---------------------------------------------------
633
634 * setParameter NAME VALUE
635
636 Sets the value of the specified query parameter.
637
638 <a id="setting"></a>TH1 setting Command
639 -----------------------------------------
640
641 * setting name
642
643 Gets and returns the value of the specified setting.
644
645 <a id="stime"></a>TH1 stime Command
646 -------------------------------------
647
648 * stime
649
650 Returns the number of microseconds of CPU time consumed by the current
651 process in system space.
652
653 <a id="styleHeader"></a>TH1 styleHeader Command
654 -------------------------------------------------
655
656 * styleHeader TITLE
657
658 Render the configured style header for the selected skin.
659
660 <a id="styleFooter"></a>TH1 styleFooter Command
661 -------------------------------------------------
662
663 * styleFooter
664
665 Render the configured style footer for the selected skin.
666
667 <a id="styleScript"></a>TH1 styleScript Command
668 -------------------------------------------------
669
670 * styleScript
671
672 Render the configured JavaScript for the selected skin.
673
674 <a id="tclEval"></a>TH1 tclEval Command
675 -----------------------------------------
676
677 **This command requires the Tcl integration feature.**
678
679 * tclEval arg ?arg ...?
@@ -647,11 +680,11 @@
680
681 Evaluates the Tcl script and returns its result verbatim. If a Tcl script
682 error is generated, it will be transformed into a TH1 script error. The
683 Tcl interpreter will be created automatically if it has not been already.
684
685 <a id="tclExpr"></a>TH1 tclExpr Command
686 -----------------------------------------
687
688 **This command requires the Tcl integration feature.**
689
690 * tclExpr arg ?arg ...?
@@ -659,11 +692,11 @@
692 Evaluates the Tcl expression and returns its result verbatim. If a Tcl
693 script error is generated, it will be transformed into a TH1 script
694 error. The Tcl interpreter will be created automatically if it has not
695 been already.
696
697 <a id="tclInvoke"></a>TH1 tclInvoke Command
698 ---------------------------------------------
699
700 **This command requires the Tcl integration feature.**
701
702 * tclInvoke command ?arg ...?
@@ -670,21 +703,21 @@
703
704 Invokes the Tcl command using the supplied arguments. No additional
705 substitutions are performed on the arguments. The Tcl interpreter
706 will be created automatically if it has not been already.
707
708 <a id="tclIsSafe"></a>TH1 tclIsSafe Command
709 ---------------------------------------------
710
711 **This command requires the Tcl integration feature.**
712
713 * tclIsSafe
714
715 Returns non-zero if the Tcl interpreter is "safe". The Tcl interpreter
716 will be created automatically if it has not been already.
717
718 <a id="tclMakeSafe"></a>TH1 tclMakeSafe Command
719 -------------------------------------------------
720
721 **This command requires the Tcl integration feature.**
722
723 * tclMakeSafe
@@ -692,51 +725,51 @@
725 Forces the Tcl interpreter into "safe" mode by removing all "unsafe"
726 commands and variables. This operation cannot be undone. The Tcl
727 interpreter will remain "safe" until the process terminates. The Tcl
728 interpreter will be created automatically if it has not been already.
729
730 <a id="tclReady"></a>TH1 tclReady Command
731 -------------------------------------------
732
733 * tclReady
734
735 Returns true if the binary has the Tcl integration feature enabled and it
736 is currently available for use by TH1 scripts.
737
738 <a id="trace"></a>TH1 trace Command
739 -------------------------------------
740
741 * trace STRING
742
743 Generates a TH1 trace message if TH1 tracing is enabled.
744
745 <a id="unversioned_content"></a>TH1 unversioned content Command
746 -----------------------------------------------------------------
747
748 * unversioned content FILENAME
749
750 Attempts to locate the specified unversioned file and return its contents.
751 An error is generated if the repository is not open or the unversioned file
752 cannot be found.
753
754 <a id="unversioned_list"></a>TH1 unversioned list Command
755 -----------------------------------------------------------
756
757 * unversioned list
758
759 Returns a list of the names of all unversioned files held in the local
760 repository. An error is generated if the repository is not open.
761
762 <a id="utime"></a>TH1 utime Command
763 -------------------------------------
764
765 * utime
766
767 Returns the number of microseconds of CPU time consumed by the current
768 process in user space.
769
770 <a id="verifyCsrf"></a>TH1 verifyCsrf Command
771 -----------------------------------------------
772
773 * verifyCsrf
774
775 Before using the results of a form, first call this command to verify
@@ -743,19 +776,19 @@
776 that this Anti-CSRF token is present and is valid. If the Anti-CSRF token
777 is missing or is incorrect, that indicates a cross-site scripting attack.
778 If the event of an attack is detected, an error message is generated and
779 all further processing is aborted.
780
781 <a id="verifyLogin"></a>TH1 verifyLogin Command
782 -------------------------------------------------
783
784 * verifyLogin
785
786 Returns non-zero if the specified user name and password represent a
787 valid login for the repository.
788
789 <a id="wiki"></a>TH1 wiki Command
790 -----------------------------------
791
792 * wiki STRING
793
794 Renders STRING as wiki content.
@@ -769,24 +802,24 @@
802 Tcl commands:
803
804 * th1Eval
805 * th1Expr
806
807 <a id="th1Eval"></a>Tcl th1Eval Command
808 -----------------------------------------
809
810 **This command requires the Tcl integration feature.**
811
812 * th1Eval arg
813
814 Evaluates the TH1 script and returns its result verbatim. If a TH1 script
815 error is generated, it will be transformed into a Tcl script error.
816
817 <a id="th1Expr"></a>Tcl th1Expr Command
818 -----------------------------------------
819
820 **This command requires the Tcl integration feature.**
821
822 * th1Expr arg
823
824 Evaluates the TH1 expression and returns its result verbatim. If a TH1
825 script error is generated, it will be transformed into a Tcl script error.
826

Keyboard Shortcuts

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