31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
+
+
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
-
-
+
+
+
-
+
+
+
-
+
-
+
+
+
|
#define PIKCHR_PROCESS_SRC 0x10
#define PIKCHR_PROCESS_SRC_HIDDEN 0x20
#define PIKCHR_PROCESS_DIV 0x40
#define PIKCHR_PROCESS_DIV_INDENT 0x0100
#define PIKCHR_PROCESS_DIV_CENTER 0x0200
#define PIKCHR_PROCESS_DIV_FLOAT_LEFT 0x0400
#define PIKCHR_PROCESS_DIV_FLOAT_RIGHT 0x0800
#define PIKCHR_PROCESS_DIV_TOGGLE 0x1000
#define PIKCHR_PROCESS_DIV_SOURCE 0x2000
#endif
/*
** Processes a pikchr script, optionally with embedded TH1. zIn is the
** input script. pikFlags may be a bitmask of any of the
** PIKCHR_PROCESS_xxx flags (see below). thFlags may be a bitmask of
** any of the TH_INIT_xxx and/or TH_R2B_xxx flags. Output is sent to
** pOut, appending to it without modifying any prior contents.
** Processes a pikchr script, optionally with embedded TH1, and
** produces HTML code for it. zIn is the NUL-terminated input
** script. pikFlags may be a bitmask of any of the PIKCHR_PROCESS_xxx
** flags documented below. thFlags may be a bitmask of any of the
** TH_INIT_xxx and/or TH_R2B_xxx flags. Output is sent to pOut,
** appending to it without modifying any prior contents.
**
** Returns 0 on success, 1 if TH1 processing failed, or 2 if pikchr
** processing failed. In either case, the error message (if any) from
** TH1 or pikchr will be appended to pOut.
**
** pikFlags flag descriptions:
**
** - PIKCHR_PROCESS_TH1 means to run zIn through TH1, using the TH1
** init flags specified in the 3rd argument. If thFlags is non-0 then
** this flag is assumed even if it is not specified.
**
** - PIKCHR_PROCESS_TH1_NOSVG means that processing stops after the
** TH1 step, thus the output will be (presumably) a
** TH1 eval step, thus the output will be (presumably) a
** TH1-generated/processed pikchr script (or whatever else the TH1
** outputs). If this flag is set, PIKCHR_PROCESS_TH1 is assumed even
** if it is not specified.
**
** The remaining flags listed below are ignored if
** PIKCHR_PROCESS_TH1_NOSVG is specified:
** All of the remaining flags listed below are ignored if
** PIKCHR_PROCESS_TH1_NOSVG is specified!
**
** - PIKCHR_PROCESS_DIV: if set, the SVG result is wrapped in a DIV
** element which specifies a max-width style value based on the SVG's
** calculated size. This flag has multiple mutually exclusive forms:
**
** - PIKCHR_PROCESS_DIV uses default element alignment.
** - PIKCHR_PROCESS_DIV_INDENT indents the div.
** - PIKCHR_PROCESS_DIV_CENTER centers the div.
** - PIKCHR_PROCESS_DIV_FLOAT_LEFT floats the div left.
** - PIKCHR_PROCESS_DIV_FLOAT_RIGHT floats the div right.
**
** If more than one is specified, which one is used is undefined.
** If more than one is specified, which one is used is undefined. Those
** flags may be OR'd with one or both of the following:
**
** - PIKCHR_PROCESS_DIV_TOGGLE: adds the 'toggle' CSS class to the
** outer DIV so that event-handler code can install different
** toggling behaviour than the default. Default is ctrl-click, but
** this flag enables single-click toggling for the element.
**
** - PIKCHR_PROCESS_DIV_SOURCE: adds the 'source' CSS class to the
** outer DIV, which is a hint to the client-side renderer (see
** fossil.pikchr.js) that the pikchr should initially be rendered
** in source code form mode (the default is to hide the source and
** show the SVG).
**
** - PIKCHR_PROCESS_NONCE: if set, the resulting SVG/DIV are wrapped
** in "safe nonce" comments, which are a fossil-internal mechanism
** which prevents the wiki/markdown processors from re-processing this
** output.
** output. This is necessary when calling this routine in the context
** of wiki/embedded doc processing, but not (e.g.) when fetching
** an image for /pikchrpage.
**
** - PIKCHR_PROCESS_SRC: if set, a new TEXTAREA.pikchr-src element is injected
** adjacet to the SVG element which contains the HTML-escaped content of
** the input script.
** - PIKCHR_PROCESS_SRC: if set, a new PRE.pikchr-src element is
** injected adjacent to the SVG element which contains the
** HTML-escaped content of the input script.
**
** - PIKCHR_PROCESS_SRC_HIDDEN: exactly like PIKCHR_PROCESS_SRC but
** the .pikchr-src tag also gets the CSS class 'hidden' (which, in
** fossil's default CSS, will hide that element).
** fossil's default CSS, will hide that element). This is almost
** always what client code will want to do if it includes the source
** at all.
**
** - PIKCHR_PROCESS_ERR_PRE: if set and pikchr() fails, the resulting
** error report is wrapped in a PRE element, else it is retained
** as-is (intended for console output).
** as-is (intended only for console output).
*/
int pikchr_process(const char * zIn, int pikFlags, int thFlags,
Blob * pOut){
Blob * pOut){
Blob bIn = empty_blob;
int isErr = 0;
if(!(PIKCHR_PROCESS_DIV & pikFlags)
/* If any DIV_xxx flags are set, set DIV */
&& (PIKCHR_PROCESS_DIV_INDENT
| PIKCHR_PROCESS_DIV_CENTER
| PIKCHR_PROCESS_DIV_FLOAT_RIGHT
| PIKCHR_PROCESS_DIV_FLOAT_LEFT
| PIKCHR_PROCESS_DIV_SOURCE
| PIKCHR_PROCESS_DIV_TOGGLE
) & pikFlags){
pikFlags |= PIKCHR_PROCESS_DIV;
}
if(!(PIKCHR_PROCESS_TH1 & pikFlags)
/* If any TH1_xxx flags are set, set TH1 */
&& (PIKCHR_PROCESS_TH1_NOSVG & pikFlags || thFlags!=0)){
pikFlags |= PIKCHR_PROCESS_TH1;
|
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
+
+
+
+
+
+
+
+
-
+
+
+
+
-
-
-
+
+
|
}else{
int w = 0, h = 0;
const char * zContent = blob_str(&bIn);
char *zOut;
zOut = pikchr(zContent, "pikchr", 0, &w, &h);
if( w>0 && h>0 ){
const char * zClassToggle = "";
const char * zClassSource = "";
const char *zNonce = (PIKCHR_PROCESS_NONCE & pikFlags)
? safe_html_nonce(1) : 0;
if(zNonce){
blob_append(pOut, zNonce, -1);
}
if(PIKCHR_PROCESS_DIV & pikFlags){
Blob css = empty_blob;
blob_appendf(&css, "max-width:%dpx;", w);
if(PIKCHR_PROCESS_DIV_CENTER & pikFlags){
blob_append(&css, "display:block;margin-auto;", -1);
}else if(PIKCHR_PROCESS_DIV_INDENT & pikFlags){
blob_append(&css, "margin-left:4em", -1);
}else if(PIKCHR_PROCESS_DIV_FLOAT_LEFT & pikFlags){
blob_append(&css, "float:left;padding=4em;", -1);
}else if(PIKCHR_PROCESS_DIV_FLOAT_RIGHT & pikFlags){
blob_append(&css, "float:right;padding=4em;", -1);
}
if(PIKCHR_PROCESS_DIV_TOGGLE & pikFlags){
zClassToggle = " toggle";
}
if(PIKCHR_PROCESS_DIV_SOURCE & pikFlags){
zClassSource = " source";
}
blob_appendf(pOut,"<div class=\"pikchr\" style=\"%b\">\n", &css);
blob_appendf(pOut,"<div class=\"pikchr-svg%s%s\" "
"style=\"%b\">\n",
zClassToggle/*safe-for-%s*/,
zClassSource/*safe-for-%s*/, &css);
blob_reset(&css);
}
blob_append(pOut, zOut, -1);
if((PIKCHR_PROCESS_SRC & pikFlags)
|| (PIKCHR_PROCESS_SRC_HIDDEN & pikFlags)){
blob_appendf(pOut, "<textarea rows='10' readonly "
"class='pikchr-src%s'>"
"%h</textarea>\n",
blob_appendf(pOut, "<pre class='pikchr-src%s'>"
"%h</pre>\n",
(PIKCHR_PROCESS_SRC_HIDDEN & pikFlags)
? " hidden" : "",
blob_str(&bIn));
}
if(PIKCHR_PROCESS_DIV & pikFlags){
blob_append(pOut, "</div>\n", 7);
}
|
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
|
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
-
+
|
**
** -div-center Like -div but centers the div.
**
** -div-left Like -div but floats the div left.
**
** -div-right Like -div but floats the div right.
**
** -svg-src Stores the input pikchr's source code in the output as
** -src Stores the input pikchr's source code in the output as
** a separate element adjacent to the SVG one. The
** source element initially has the "hidden" CSS class.
**
** -th Process the input using TH1 before passing it to pikchr.
**
** -th-novar Disable $var and $<var> TH1 processing. Use this if the
** pikchr script uses '$' for its own purposes and that
|
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
|
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
|
-
+
+
+
+
+
+
+
|
Blob bIn = empty_blob;
Blob bOut = empty_blob;
const char * zInfile = "-";
const char * zOutfile = "-";
const int fTh1 = find_option("th",0,0)!=0;
const int fNosvg = find_option("th-nosvg",0,0)!=0;
int isErr = 0;
int pikFlags = find_option("svg-src",0,0)!=0
int pikFlags = find_option("src",0,0)!=0
? PIKCHR_PROCESS_SRC_HIDDEN : 0;
u32 fThFlags = TH_INIT_NO_ENCODE
| (find_option("th-novar",0,0)!=0 ? TH_R2B_NO_VARS : 0);
Th_InitTraceLog()/*processes -th-trace flag*/;
if(find_option("div",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV;
}else if(find_option("div-indent",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV_INDENT;
}else if(find_option("div-center",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV_CENTER;
}else if(find_option("div-float-left",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV_FLOAT_LEFT;
}else if(find_option("div-float-right",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV_FLOAT_RIGHT;
}
if(find_option("div-toggle",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV_TOGGLE;
}
if(find_option("div-source",0,0)!=0){
pikFlags |= PIKCHR_PROCESS_DIV_SOURCE;
}
verify_all_options();
if(g.argc>4){
usage("?INFILE? ?OUTFILE?");
}
if(g.argc>2){
zInfile = g.argv[2];
|