Fossil SCM

Consolidates pikchrshow page/pikchr command use of pikchr()/th1 into a shared routine (though /pikchrshow does not currently allow th1-processed scripts, it might be interesting to enable for users with edit/checkin (or admin) rights.

stephan 2020-09-15 07:51 trunk
Commit 893bf2a146be9e9c9910ba4e4f064dc7228e179a61e867d0197b70bcdea86dfd
1 file changed +130 -52
+130 -52
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -20,10 +20,118 @@
2020
#include "config.h"
2121
#include <assert.h>
2222
#include <ctype.h>
2323
#include "pikchrshow.h"
2424
25
+#ifdef INTERFACE
26
+/* These are described in pikchr_process()'s docs. */
27
+#define PIKCHR_PROCESS_TH1 0x01
28
+#define PIKCHR_PROCESS_TH1_NOSVG 0x02
29
+#define PIKCHR_PROCESS_DIV 0x04
30
+#define PIKCHR_PROCESS_NONCE 0x08
31
+#define PIKCHR_PROCESS_ERR_PRE 0x10
32
+#endif
33
+
34
+/*
35
+** Processes a pikchr script, optionally with embedded TH1. zIn is the
36
+** input script. pikFlags may be a bitmask of any of the
37
+** PIKCHR_PROCESS_xxx flags (see below). thFlags may be a bitmask of
38
+** any of the TH_INIT_xxx and/or TH_R2B_xxx flags. Output is sent to
39
+** pOut, appending to it without modifying any prior contents.
40
+**
41
+** Returns 0 on success, 1 if TH1 processing failed, or 2 if pikchr
42
+** processing failed. In either case, the error message (if any) from
43
+** TH1 or pikchr will be appended to pOut.
44
+**
45
+** pikFlags flag descriptions:
46
+**
47
+** - PIKCHR_PROCESS_TH1 means to run zIn through TH1, using the TH1
48
+** init flags specified in the 3rd argument. If thFlags is non-0 then
49
+** this flag is assumed even if it is not specified.
50
+**
51
+** - PIKCHR_PROCESS_TH1_NOSVG means that processing stops after the
52
+** TH1 step, thus the output will be (presumably) a
53
+** TH1-generated/processed pikchr script, and not an SVG. If this flag
54
+** is set, PIKCHR_PROCESS_TH1 is assumed even if it is not specified.
55
+** The remaining flags listed below are ignored if this flag is
56
+** specified.
57
+**
58
+** - PIKCHR_PROCESS_DIV: if set, the SVG result is wrapped in a DIV
59
+** element which specifies a max-width style value based on the SVG's
60
+** calculated size.
61
+**
62
+** - PIKCHR_PROCESS_NONCE: if set, the resulting SVG/DEV are wrapped
63
+** in "safe nonce" comments, which are a fossil-internal mechanism
64
+** which prevents the wiki/markdown processors from processing this
65
+** output.
66
+**
67
+** - PIKCHR_PROCESS_ERR_PRE: if set and pikchr() fails, the resulting
68
+** error report is wrapped in PRE element.
69
+*/
70
+int pikchr_process(const char * zIn, int pikFlags, int thFlags,
71
+ Blob * pOut){
72
+ Blob bIn = empty_blob;
73
+ int isErr = 0;
74
+
75
+ if(!(PIKCHR_PROCESS_TH1 & pikFlags)
76
+ && (PIKCHR_PROCESS_TH1_NOSVG & pikFlags || thFlags!=0)){
77
+ pikFlags |= PIKCHR_PROCESS_TH1;
78
+ }
79
+ if(PIKCHR_PROCESS_TH1 & pikFlags){
80
+ Blob out = empty_blob;
81
+ isErr = Th_RenderToBlob(zIn, &out, thFlags)
82
+ ? 1 : 0;
83
+ if(isErr){
84
+ blob_append(pOut, blob_str(&out), blob_size(&out));
85
+ blob_reset(&out);
86
+ }else{
87
+ bIn = out;
88
+ }
89
+ }else{
90
+ blob_init(&bIn, zIn, -1);
91
+ }
92
+ if(!isErr){
93
+ if(PIKCHR_PROCESS_TH1_NOSVG & pikFlags){
94
+ blob_append(pOut, blob_str(&bIn), blob_size(&bIn));
95
+ }else{
96
+ int w = 0, h = 0;
97
+ const char * zContent = blob_str(&bIn);
98
+ char *zOut;
99
+
100
+ zOut = pikchr(zContent, "pikchr", 0, &w, &h);
101
+ if( w>0 && h>0 ){
102
+ const char *zNonce = (PIKCHR_PROCESS_NONCE & pikFlags)
103
+ ? safe_html_nonce(1) : 0;
104
+ if(zNonce){
105
+ blob_append(pOut, zNonce, -1);
106
+ }
107
+ if(PIKCHR_PROCESS_DIV & pikFlags){
108
+ blob_appendf(pOut,"<div style='max-width:%dpx;'>\n", w);
109
+ }
110
+ blob_append(pOut, zOut, -1);
111
+ if(PIKCHR_PROCESS_DIV & pikFlags){
112
+ blob_append(pOut,"</div>\n", 7);
113
+ }
114
+ if(zNonce){
115
+ blob_append(pOut, zNonce, -1);
116
+ }
117
+ }else{
118
+ isErr = 2;
119
+ if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
120
+ blob_append(pOut, "<pre>\n", 6);
121
+ }
122
+ blob_append(pOut, zOut, -1);
123
+ if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
124
+ blob_append(pOut, "\n</pre>\n", 8);
125
+ }
126
+ }
127
+ fossil_free(zOut);
128
+ }
129
+ }
130
+ blob_reset(&bIn);
131
+ return isErr;
132
+}
25133
26134
/*
27135
** WEBPAGE: pikchrshow
28136
**
29137
** A pikchr code editor and previewer, allowing users to experiment
@@ -44,26 +152,25 @@
44152
zContent = PD("content",P("p"));
45153
if(P("ajax")!=0){
46154
/* Called from the JS-side preview updater. */
47155
cgi_set_content_type("text/html");
48156
if(zContent && *zContent){
49
- int w = 0, h = 0;
50
- char *zOut = pikchr(zContent, "pikchr", 0, &w, &h);
51
- if( w>0 && h>0 ){
52
- const char *zNonce = safe_html_nonce(1);
53
- CX("%s<div style='max-width:%dpx;'>\n%s</div>%s",
54
- zNonce, w, zOut, zNonce);
55
- }else{
56
- cgi_printf_header("x-pikchrshow-is-error: 1\r\n");
57
- CX("<pre>\n%s\n</pre>\n", zOut);
58
- }
59
- fossil_free(zOut);
157
+ Blob out = empty_blob;
158
+ const int isErr =
159
+ pikchr_process(zContent,
160
+ PIKCHR_PROCESS_DIV | PIKCHR_PROCESS_ERR_PRE,
161
+ 0, &out);
162
+ if(isErr){
163
+ cgi_printf_header("x-pikchrshow-is-error: %d\r\n", isErr);
164
+ }
165
+ CX("%b", &out);
166
+ blob_reset(&out);
60167
}else{
61168
CX("<pre>No content! Nothing to render</pre>");
62169
}
63170
return;
64
- }
171
+ }/*ajax response*/
65172
style_emit_noscript_for_js_page();
66173
isDark = skin_detail_boolean("white-foreground");
67174
if(!zContent){
68175
zContent = "arrow right 200% \"Markdown\" \"Source\"\n"
69176
"box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
@@ -231,10 +338,11 @@
231338
const char * zOutfile = "-";
232339
const int fWithDiv = find_option("div",0,0)!=0;
233340
const int fTh1 = find_option("th",0,0)!=0;
234341
const int fNosvg = find_option("th-nosvg",0,0)!=0;
235342
int isErr = 0;
343
+ int pikFlags = 0;
236344
u32 fThFlags = TH_INIT_NO_ENCODE
237345
| (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
238346
239347
Th_InitTraceLog()/*processes -th-trace flag*/;
240348
verify_all_options();
@@ -247,50 +355,20 @@
247355
if(g.argc>3){
248356
zOutfile = g.argv[3];
249357
}
250358
blob_read_from_file(&bIn, zInfile, ExtFILE);
251359
if(fTh1){
252
- Blob out = empty_blob;
253
- db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
254
- /* ^^^ needed for certain TH1 functions to work */;
255
- /*Th_FossilInit(fThFlags);*/
256
- isErr = Th_RenderToBlob(blob_str(&bIn), &out, fThFlags)
257
- ? 1 : 0;
258
- if(isErr){
259
- blob_reset(&bOut);
260
- bOut = out;
261
- }else{
262
- blob_reset(&bIn);
263
- bIn = out;
264
- }
265
- }
266
- if(!isErr){
267
- if(fTh1 && fNosvg){
268
- assert(0==blob_size(&bOut));
269
- bOut = bIn;
270
- bIn = empty_blob;
271
- }else{
272
- int w = 0, h = 0;
273
- const char * zContent = blob_str(&bIn);
274
- char *zOut;
275
-
276
- zOut = pikchr(zContent, "pikchr", 0, &w, &h);
277
- if( w>0 && h>0 ){
278
- if(fWithDiv){
279
- blob_appendf(&bOut,"<div style='max-width:%dpx;'>\n", w);
280
- }
281
- blob_append(&bOut, zOut, -1);
282
- if(fWithDiv){
283
- blob_append(&bOut,"</div>\n", 7);
284
- }
285
- fossil_free(zOut);
286
- }else{
287
- isErr = 2;
288
- blob_set_dynamic(&bOut, zOut);
289
- }
290
- }
291
- }
360
+ db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
361
+ /* ^^^ needed for certain TH1 functions to work */;;
362
+ pikFlags |= PIKCHR_PROCESS_TH1;
363
+ if(fNosvg) pikFlags |= PIKCHR_PROCESS_TH1_NOSVG;
364
+ }
365
+ if(fWithDiv){
366
+ pikFlags |= PIKCHR_PROCESS_DIV;
367
+ }
368
+ isErr = pikchr_process(blob_str(&bIn), pikFlags,
369
+ fTh1 ? fThFlags : 0, &bOut);
292370
if(isErr){
293371
/*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
294372
fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
295373
&bOut);
296374
}else{
297375
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -20,10 +20,118 @@
20 #include "config.h"
21 #include <assert.h>
22 #include <ctype.h>
23 #include "pikchrshow.h"
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
26 /*
27 ** WEBPAGE: pikchrshow
28 **
29 ** A pikchr code editor and previewer, allowing users to experiment
@@ -44,26 +152,25 @@
44 zContent = PD("content",P("p"));
45 if(P("ajax")!=0){
46 /* Called from the JS-side preview updater. */
47 cgi_set_content_type("text/html");
48 if(zContent && *zContent){
49 int w = 0, h = 0;
50 char *zOut = pikchr(zContent, "pikchr", 0, &w, &h);
51 if( w>0 && h>0 ){
52 const char *zNonce = safe_html_nonce(1);
53 CX("%s<div style='max-width:%dpx;'>\n%s</div>%s",
54 zNonce, w, zOut, zNonce);
55 }else{
56 cgi_printf_header("x-pikchrshow-is-error: 1\r\n");
57 CX("<pre>\n%s\n</pre>\n", zOut);
58 }
59 fossil_free(zOut);
60 }else{
61 CX("<pre>No content! Nothing to render</pre>");
62 }
63 return;
64 }
65 style_emit_noscript_for_js_page();
66 isDark = skin_detail_boolean("white-foreground");
67 if(!zContent){
68 zContent = "arrow right 200% \"Markdown\" \"Source\"\n"
69 "box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
@@ -231,10 +338,11 @@
231 const char * zOutfile = "-";
232 const int fWithDiv = find_option("div",0,0)!=0;
233 const int fTh1 = find_option("th",0,0)!=0;
234 const int fNosvg = find_option("th-nosvg",0,0)!=0;
235 int isErr = 0;
 
236 u32 fThFlags = TH_INIT_NO_ENCODE
237 | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
238
239 Th_InitTraceLog()/*processes -th-trace flag*/;
240 verify_all_options();
@@ -247,50 +355,20 @@
247 if(g.argc>3){
248 zOutfile = g.argv[3];
249 }
250 blob_read_from_file(&bIn, zInfile, ExtFILE);
251 if(fTh1){
252 Blob out = empty_blob;
253 db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
254 /* ^^^ needed for certain TH1 functions to work */;
255 /*Th_FossilInit(fThFlags);*/
256 isErr = Th_RenderToBlob(blob_str(&bIn), &out, fThFlags)
257 ? 1 : 0;
258 if(isErr){
259 blob_reset(&bOut);
260 bOut = out;
261 }else{
262 blob_reset(&bIn);
263 bIn = out;
264 }
265 }
266 if(!isErr){
267 if(fTh1 && fNosvg){
268 assert(0==blob_size(&bOut));
269 bOut = bIn;
270 bIn = empty_blob;
271 }else{
272 int w = 0, h = 0;
273 const char * zContent = blob_str(&bIn);
274 char *zOut;
275
276 zOut = pikchr(zContent, "pikchr", 0, &w, &h);
277 if( w>0 && h>0 ){
278 if(fWithDiv){
279 blob_appendf(&bOut,"<div style='max-width:%dpx;'>\n", w);
280 }
281 blob_append(&bOut, zOut, -1);
282 if(fWithDiv){
283 blob_append(&bOut,"</div>\n", 7);
284 }
285 fossil_free(zOut);
286 }else{
287 isErr = 2;
288 blob_set_dynamic(&bOut, zOut);
289 }
290 }
291 }
292 if(isErr){
293 /*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
294 fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
295 &bOut);
296 }else{
297
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -20,10 +20,118 @@
20 #include "config.h"
21 #include <assert.h>
22 #include <ctype.h>
23 #include "pikchrshow.h"
24
25 #ifdef INTERFACE
26 /* These are described in pikchr_process()'s docs. */
27 #define PIKCHR_PROCESS_TH1 0x01
28 #define PIKCHR_PROCESS_TH1_NOSVG 0x02
29 #define PIKCHR_PROCESS_DIV 0x04
30 #define PIKCHR_PROCESS_NONCE 0x08
31 #define PIKCHR_PROCESS_ERR_PRE 0x10
32 #endif
33
34 /*
35 ** Processes a pikchr script, optionally with embedded TH1. zIn is the
36 ** input script. pikFlags may be a bitmask of any of the
37 ** PIKCHR_PROCESS_xxx flags (see below). thFlags may be a bitmask of
38 ** any of the TH_INIT_xxx and/or TH_R2B_xxx flags. Output is sent to
39 ** pOut, appending to it without modifying any prior contents.
40 **
41 ** Returns 0 on success, 1 if TH1 processing failed, or 2 if pikchr
42 ** processing failed. In either case, the error message (if any) from
43 ** TH1 or pikchr will be appended to pOut.
44 **
45 ** pikFlags flag descriptions:
46 **
47 ** - PIKCHR_PROCESS_TH1 means to run zIn through TH1, using the TH1
48 ** init flags specified in the 3rd argument. If thFlags is non-0 then
49 ** this flag is assumed even if it is not specified.
50 **
51 ** - PIKCHR_PROCESS_TH1_NOSVG means that processing stops after the
52 ** TH1 step, thus the output will be (presumably) a
53 ** TH1-generated/processed pikchr script, and not an SVG. If this flag
54 ** is set, PIKCHR_PROCESS_TH1 is assumed even if it is not specified.
55 ** The remaining flags listed below are ignored if this flag is
56 ** specified.
57 **
58 ** - PIKCHR_PROCESS_DIV: if set, the SVG result is wrapped in a DIV
59 ** element which specifies a max-width style value based on the SVG's
60 ** calculated size.
61 **
62 ** - PIKCHR_PROCESS_NONCE: if set, the resulting SVG/DEV are wrapped
63 ** in "safe nonce" comments, which are a fossil-internal mechanism
64 ** which prevents the wiki/markdown processors from processing this
65 ** output.
66 **
67 ** - PIKCHR_PROCESS_ERR_PRE: if set and pikchr() fails, the resulting
68 ** error report is wrapped in PRE element.
69 */
70 int pikchr_process(const char * zIn, int pikFlags, int thFlags,
71 Blob * pOut){
72 Blob bIn = empty_blob;
73 int isErr = 0;
74
75 if(!(PIKCHR_PROCESS_TH1 & pikFlags)
76 && (PIKCHR_PROCESS_TH1_NOSVG & pikFlags || thFlags!=0)){
77 pikFlags |= PIKCHR_PROCESS_TH1;
78 }
79 if(PIKCHR_PROCESS_TH1 & pikFlags){
80 Blob out = empty_blob;
81 isErr = Th_RenderToBlob(zIn, &out, thFlags)
82 ? 1 : 0;
83 if(isErr){
84 blob_append(pOut, blob_str(&out), blob_size(&out));
85 blob_reset(&out);
86 }else{
87 bIn = out;
88 }
89 }else{
90 blob_init(&bIn, zIn, -1);
91 }
92 if(!isErr){
93 if(PIKCHR_PROCESS_TH1_NOSVG & pikFlags){
94 blob_append(pOut, blob_str(&bIn), blob_size(&bIn));
95 }else{
96 int w = 0, h = 0;
97 const char * zContent = blob_str(&bIn);
98 char *zOut;
99
100 zOut = pikchr(zContent, "pikchr", 0, &w, &h);
101 if( w>0 && h>0 ){
102 const char *zNonce = (PIKCHR_PROCESS_NONCE & pikFlags)
103 ? safe_html_nonce(1) : 0;
104 if(zNonce){
105 blob_append(pOut, zNonce, -1);
106 }
107 if(PIKCHR_PROCESS_DIV & pikFlags){
108 blob_appendf(pOut,"<div style='max-width:%dpx;'>\n", w);
109 }
110 blob_append(pOut, zOut, -1);
111 if(PIKCHR_PROCESS_DIV & pikFlags){
112 blob_append(pOut,"</div>\n", 7);
113 }
114 if(zNonce){
115 blob_append(pOut, zNonce, -1);
116 }
117 }else{
118 isErr = 2;
119 if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
120 blob_append(pOut, "<pre>\n", 6);
121 }
122 blob_append(pOut, zOut, -1);
123 if(PIKCHR_PROCESS_ERR_PRE & pikFlags){
124 blob_append(pOut, "\n</pre>\n", 8);
125 }
126 }
127 fossil_free(zOut);
128 }
129 }
130 blob_reset(&bIn);
131 return isErr;
132 }
133
134 /*
135 ** WEBPAGE: pikchrshow
136 **
137 ** A pikchr code editor and previewer, allowing users to experiment
@@ -44,26 +152,25 @@
152 zContent = PD("content",P("p"));
153 if(P("ajax")!=0){
154 /* Called from the JS-side preview updater. */
155 cgi_set_content_type("text/html");
156 if(zContent && *zContent){
157 Blob out = empty_blob;
158 const int isErr =
159 pikchr_process(zContent,
160 PIKCHR_PROCESS_DIV | PIKCHR_PROCESS_ERR_PRE,
161 0, &out);
162 if(isErr){
163 cgi_printf_header("x-pikchrshow-is-error: %d\r\n", isErr);
164 }
165 CX("%b", &out);
166 blob_reset(&out);
 
167 }else{
168 CX("<pre>No content! Nothing to render</pre>");
169 }
170 return;
171 }/*ajax response*/
172 style_emit_noscript_for_js_page();
173 isDark = skin_detail_boolean("white-foreground");
174 if(!zContent){
175 zContent = "arrow right 200% \"Markdown\" \"Source\"\n"
176 "box rad 10px \"Markdown\" \"Formatter\" \"(markdown.c)\" fit\n"
@@ -231,10 +338,11 @@
338 const char * zOutfile = "-";
339 const int fWithDiv = find_option("div",0,0)!=0;
340 const int fTh1 = find_option("th",0,0)!=0;
341 const int fNosvg = find_option("th-nosvg",0,0)!=0;
342 int isErr = 0;
343 int pikFlags = 0;
344 u32 fThFlags = TH_INIT_NO_ENCODE
345 | (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
346
347 Th_InitTraceLog()/*processes -th-trace flag*/;
348 verify_all_options();
@@ -247,50 +355,20 @@
355 if(g.argc>3){
356 zOutfile = g.argv[3];
357 }
358 blob_read_from_file(&bIn, zInfile, ExtFILE);
359 if(fTh1){
360 db_find_and_open_repository(OPEN_ANY_SCHEMA | OPEN_OK_NOT_FOUND, 0)
361 /* ^^^ needed for certain TH1 functions to work */;;
362 pikFlags |= PIKCHR_PROCESS_TH1;
363 if(fNosvg) pikFlags |= PIKCHR_PROCESS_TH1_NOSVG;
364 }
365 if(fWithDiv){
366 pikFlags |= PIKCHR_PROCESS_DIV;
367 }
368 isErr = pikchr_process(blob_str(&bIn), pikFlags,
369 fTh1 ? fThFlags : 0, &bOut);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370 if(isErr){
371 /*fossil_print("ERROR: raw input:\n%b\n", &bIn);*/
372 fossil_fatal("%s ERROR: %b", 1==isErr ? "TH1" : "pikchr",
373 &bOut);
374 }else{
375

Keyboard Shortcuts

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