summaryrefslogtreecommitdiff
path: root/web/src/cgi.tcl-1.10/doc/ref.txt
blob: 79ddd721fc6d24f4bbc525498c09d5431ee8fa0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
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
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
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
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
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
cgi.tcl - A Reference Manual (Draft)
by Don Libes

This document contains technical notes on using cgi.tcl.  This
document is a draft and has not been officially reviewed.

This document assumes that you have read the Tcl '96 paper "CGI
Scripting in Tcl".  That document will give you the feel for what this
code is all about.  In contrast, this document provides the details.

This document assumes you know HTML.  I'm not going to explain what
particular tags do or how to use them effectively, except as necessary
to understand the document.

Some of the commands may not work with all browsers.  For example, the
cgi_center command is generally understood only by some Netscape
browsers because it produces <center></center> tags which are not
commonly supported.  You'll have to use your judgement.  Remember:
Just because a command exists to produce the HTML doesn't mean your
browser will do anything meaningful with it.  In that sense, using
this code is no different than handcoding HTML.

**************************************************
A NOTE ABOUT PROCEDURE NAMES
**************************************************

All procedures are named cgi_XXX.  You can also call them without the
cgi_ prefix.  Using the cgi_XXX form is no big deal for rarely used
procedures, but the aliases are particularly convenient for things
like hr and br.  Aliases are suppressed if procedures exist by those
names already.  (Thus, cgi_eval cannot be invoked as "eval"!)
Similarly, you can overwrite the aliases with impunity.  Internally,
references are only made to the cgi_ names.

I'm still thinking about this.  If you have strong feelings about it,
let me know.

**************************************************
SECURITY
**************************************************

I frequently see statements saying that Tcl (and other interpretive
languages, for that matter) are insecure and should not be used for
writing CGI.

I disagree.  It is possible to use Tcl securely and it really isn't
very hard.  The key, of course, is to not blindly evaluate user input.
There really isn't much reason to.  For instance, this library itself
is pretty big and does lots of things, but nothing in it evaluates
user input.  (It does do a lot of evaluation of *programmer* input,
but that's quite acceptable.)

The two classes of commands you should pay close attention to are
commands that do eval operations and commands that invoke external
programs.  

**************************************************
GENERAL NOTES ABOUT PARAMETERS
**************************************************

** There are several basic styles of parameter passing.

-- Container commands (e.g., <body></body>, <div></div>, etc.)

The last argument is typically a block of code.  Other arguments
become attributes.  For example:

  cgi_body bgcolor=red background=white {
	h4 "hello"
  }

produces:

  <body bgcolor="red" background="white">
        <h4>hello</h4>
  </body>

-- Commands with required arguments

Some commands have required arguments.  Required arguments which are
relatively long, are passed *after* all others.  For example:

  cgi_h4 align=left "Foo's Bar & Grill"

Another example:

  cgi_body bgcolor=red background=white {
    cgi_h4 "Foo's Bar & Grill"
  }

Commands with relatively short arguments have the short arguments
passed *before* all others.  This avoids many redundant keywords.  In
the following example, the "img=" is omitted because it is already
implied by the command.  The "alt=" is not optional (although the
entire argument is).

  cgi_img foo.gif "alt=Foo's Bar & Grill"

Note the quotes around the alt argument.  This is only necessary if
the argument has whitespace in it - a consequence of Tcl's normal
scanning rules.  The resulting HTML automatically includes quotes
around the value attribute.  (See Case-sensitivity.)

** Case-sensitivity and Quotes and Whitespace

Attribute names are case sensitive.  Use lowercase names for "normal"
handling.  For example, values for attributes such as "url" and
"value" are quoted and encoded.  Use uppercase names to suppress the
usual processing.  (For example, you might want to test how a browser
responds to incorrect HTML.)

Consider:

  cgi_body bgcolor=#123456 {
    p [cgi_img foo.gif "alt=Foo's Bar & Grill"]
  }

This is translated to

  <body bgcolor="#123456">
    <p><img src="foo.gif" alt="Foo's Bar &amp; Grill"></p>
  </body>

Notice how the ampersand in the alt value has been encoded.  Also
notice how quotes have been added to the values of bgcolor, url, and
alt.  Thus you no longer have to add quotes all over the place (or
remember when you need to).

Embedded whitespace is protected by quoting in the usual Tcl fashion
rather than typical HTML fashion.

So instead of:
   img foo.gif alt="foo bar"
do this:
   img foo.gif "alt=foo bar"
which will return HTML that is properly quoted:
   <img src="foo.gif" alt="foo bar">

-- Name-value commands

Many commands produce tags that use "name" and "value" attributes.
Because these attributes are almost always used in such commands, the
first argument is always of the form name=value so the literal "name"
and "value" can be omitted.  For example:

  cgi_text color=Red size=5

produces:

  <input name="color" value="Red" size=5>

Reasonable defaults exist.  For example, if you don't need the value
of a submit button (but the user still needs to see it appear as the
label), omit the name:

  cgi_submit_button =Execute

If no "=" is present, the string is assumed to be the "name"
attribute.  For example:

  cgi_checkbox Vegies

produces a checkbox associated with the variable named "Vegies".
(With no specified value, it will be set to "on" if checked.)

Most of the commands have reasonable defaults.  For example, to
quickly script a submit button, the following suffices:

  cgi_submit_button

Certain constructions make no sense and are therefore disallowed.  For
example, a submit button with a name but no value makes no sense, so
cgi_submit_button doesn't allow it.  (In other words, if you provide
an argument, it has to have "=" in it.)

**************************************************
JAVASCRIPT ARGUMENTS
**************************************************

JavaScript event attributes such as onClick are handled just like any
other attributes in terms of quoting and case sensitivity.  Because
there are so many attributes on so many tags, they are not documented
explicitly in this manual.  However, they are all supported.  Here is
an example:

  cgi_text age=18 onChange=MinimumAge(this.form.age)

**************************************************
PROCEDURES TO ASSIST IN DEBUGGING
**************************************************

** User-id differences

You can interactively run and debug CGI scripts by simply running them
from the shell, or a Tcl or C debugger.  (For convenience, I use
Expect instead of tclsh just so that I get the debugger.)  In fact,
I've never had to resort to the C debugger.  However, simply watching
the raw output from a shell is very handy.  This catches the really
basic errors such as incorrect protections, incorrect #! line, etc.
Once your script is actually executing, you can rely on cgi_eval (see
below).

cgi_uid_check user

Typically, a CGI script is intended to run from a particular uid, such
as "nobody".  If you run such scripts interactively, you can end up
with conflicts.  For example, if the script creates files, files can
accidentally end up being owned by you.

cgi_uid_check is a convenient mechanism to warn against this problem.
Simply call cgi_uid_check in your script.  The argument is the uid
under which the script should be running.  If the given uid does
not match the actual uid, cgi_uid_check will generate an error.

** Trapping error messages

cgi_eval

cgi_eval is the primary error catching/reporting mechanism.  Execute
commands from cgi_eval so that errors can be caught and reported in a
nice way.  By default, errors are emailed back to the administrator.
"cgi_debug -on" makes errors be immediately viewable in the browser.

If an error is caught when debugging is enabled, the diagnostic is
anchored with #cgierror.  This is useful in scripts that produce
voluminous output.

cgi_error_occurred

cgi_error_occurred returns 1 if an error occurred and was caught by
cgi_eval.  This separate function simplifies exit handling - for
example, rather than always checking the return value of cgi_eval, an
app can just test this from a redefined exit.

cgi_admin_mail_addr addr

cgi_admin_mail_addr sets the administrator's email address.
Diagnostics are sent via email if a problem is encountered with the
script and debugging is not enabled.

cgi_name name

cgi_name defines a name for the service.  If called with no arguments,
the name is returned.  The name is currently used in the following
places:

  If email is sent, it comes from [cgi_name].
  If errors are emailed, the subject is "[cgi_name]: CGI problem"

** Generating debugging output and other commands

cgi_debug args

cgi_debug provides rudimentary support for generating debugging
messages.  Here are some example calls:

cgi_debug cmd
	If debugging is on, the command is evaluated.  For example:

	  cgi_debug {
	    h2 "completed initialization"
	  }
	or
	  cgi_debug {h2 "completed initialization"}

	Note this is more than simply calling h2.  Context is rewound
	or forwarded to get to a place where this is safe.  (And
	conversely, this call can suppress things such as header
	elements that haven't been processed yet.)  The flag
	"-noprint" suppresses this manipulation - this is useful for
	early code that causes no printing.

	The -- flag causes the next argument to treated as a command
	even if it looks like another flag.
cgi_debug -on
	Enables debugging messages.  This includes debugging messages
	generated by explicit calls to cgi_debug as well as implicit
	diagnostics, for example, that report on form input.
cgi_debug -temp text
	Enable debugging for this one line.
cgi_debug -off
	Disable debugging.

cgi_debug always returns the old setting ("-on" or "-off").  The
initial value is -off.


** Printing arrays

cgi_parray arrayname

cgi_parray prints out the elements of a Tcl array.  cgi_parray is just
like Tcl's parray except that its output is appropriately formatted
for a browser.

**************************************************
BASIC STRUCTURE OF A CGI SCRIPT
**************************************************

Typically, the basic structure of most CGI scripts is:

  package require cgi

  cgi_eval {
    cgi_http_head {cmds}
    cgi_html {
      cgi_head {cmds}
      cgi_body {cmds}
    }
  }

Much of this can be omitted, however.  In fact, a typical script looks
more like this:

  package require cgi

  cgi_eval {
    cgi_title "title"
    cgi_body {
      cmds
    }
  }

(If you're not using the Tcl package support, replace the 'package
require' command with a 'source' command of the specific file
containing the cgi.tcl source.)

(The "...." in the examples above should be replaced by the true path
to the cgi.tcl file.)

I'll now go through each of these in more detail as well as some other
possibilities for the overall structure.

**************************************************
HTTP HEADERS
**************************************************

cgi_http_head cmds

CGI scripts must produce various headers to explain how the remainder
of the output is to be interpreted.  No other output may preceed this!

With no argument, an HTML content type is produced if the script is
running in the CGI environment.  This means that most people need not
bother calling cgi_http_head.  However, if you want to see the HTTP
headers and you are not running in the CGI environment, you should
call cgi_http_head explicitly.  (Alternatively, you can make it appear
that you are in the CGI environment by defining the environment
variable REQUEST_METHOD.)

The remaining commands in this section may be used in cgi_http_head.
Most should be intuitively obvious and thus need no explanation.

cgi_content_type type
	Generates a "Content-type:" header.

With no argument, cgi_content_type generates a declaration for HTML.
If specified, the 'type' argument should be the full MIME-style
type/subtype declaration.  Any MIME-style parameters should be
included in the type argument.

cgi_redirect location
	Generates a redirect header (Status:/Location:/URI:)
cgi_target
	Generates a "Window-target:" header.
cgi_refresh seconds url
	Generates a "Refresh:" header.  The url argument is optional.
cgi_pragma pragma
	Generates a "Pragma:" header.
cgi_status number string
	Generates a "Status:" header.

** Cookies

cgi_cookie_set name=val args
	Define a cookie with given name, value, and other arguments.
	Cookie values are automatically encoded to protect odd characters.
	A couple expirations are predefined (with intuitive meaning):
	  expires=never
	  expires=now
	  expires=...actual date...

	Here are some examples:
	  cgi_cookie_set user=don domain=nist.gov expires=never
	  cgi_cookie_set user=don expires=now secure

cgi_export_cookie name args
	Export the named Tcl variable as a cookie.  Other arguments are
	processed as with cgi_cookie_set.

Cookies may be read only after calling cgi_input.  The following
routines read cookie names or specific cookies.

cgi_cookie_list
	Returns the list of all cookies supplied by the server.

cgi_cookie_get name
	Returns the value of the named cookie.  If multiple values exists
	the most specific path mapping is used.

	If the "-all" flag is used (before the cookie name), a list is
	returned containing all cookie values for the given name.  The
	list is ordered most-specific (path mapping) to least.  I.e.,
	the first value on the list is the same one returned by
	calling cgi_cookie get without a flag.

cgi_import_cookie name
	Define a Tcl variable with the value of the cookie of the same
	name.  For example, the following command retrieves the cookie
	named "Password" and stores it in the Tcl variable "Password".

	  cgi_import_cookie Password


**************************************************
GENERATING HTML
**************************************************

cgi_html

<html></html> tags can be generated using cgi_html.  An argument to
cgi_html is evaluated to produce the actual HTML code.

In practice, it is not necessary to use cgi_html.  CGI.tcl will
automatically generate the tags when appropriate.  (Oddly, modern HTML
specs don't require it and most if not all browsers never cared
anyway.)

cgi_doctype

cgi_doctype is a user-defined procedure that produces a SGML DOCTYPE
declaration.  If it exists, cgi_doctype is automatically invoked at
the beginning of cgi_html.  (This library does not automatically create
DOCTYPE declarations since the library is not restricted to generating
SGML for any single DTD.  Realistically, DOCTYPEs are pointless for
HTML generation since web browsers don't require DOCTYPE declarations.
However, if you are creating pages for some other purpose that
requires such a declaration, use cgi_doctype.)

cgi_head

<head></head> tags can be generated using cgi_head.  An argument to
cgi_head is evaluated to produce the actual headers.

In practice, it is not necessary to use cgi_head.  CGI.tcl will
automatically generate the tags when appropriate.  (Oddly, modern HTML
specs don't require it and most if not all browsers never cared
anyway.  So for example:

  cgi_head {
    cgi_title "my page"
  }

is equivalent to:

  cgi_title "my page"

Note that cgi_title will be called automatically if you omit
cgi_title, cgi_head, or call cgi_head with no arguments.

cgi_title title

cgi_title defines the title of a page.  It is called from within a
<head></head> pair.  If not called from within cgi_head, it implicitly
forces it to occur.

cgi_title always returns the title.  With no argument, cgi_title
returns the old title without changing it.

cgi_http_equiv

cgi_http_equiv is equivalent to cgi_http_head but from within
cgi_head.  This procedure is defined for completeness - there is no
reason to use it.  In fact, it doesn't allow all cgi_http_head
declarations, so it should be avoided.

cgi_meta

cgi_meta generates a <meta> tag.  You can do whatever you want with
these.  (Read some an HTML document for more info.)  For example:

  meta name=author {content="Don Libes"}

cgi_script cmd

cgi_script evaluates its arguments inside of <script></script> tags.
This is appropriate for putting in client-side scripting.  Optional
arguments are passed as attributes to the <script> tag.

Note that the cmd argument is a Tcl command, not a command in the
other scripting language.  So if all you want to do is print out some
script, use cgi_puts:

  cgi_script {
    cgi_puts {
      some scripting stuff
        in whatever weird funky
        language you want
    }
}

cgi_javascript cmd

cgi_javascript is a version of cgi_script specialized for javascript.
At present, all it does is add the comment hacks so that the
javascript can't be seen by old browsers.

cgi_noscript cmd

cgi_noscript evaluates its argument to generate code for browsers that
do not understand cgi_script or its variants.

cgi_body

<body></body> tags are generated using cgi_body.  An argument to
cgi_body is evaluated to produce the actual body.

Executing "return" from within cgi_body causes cgi_body to return.
This is useful if more code follows the cgi_body within the cgi_eval.
Compare to cgi_exit (see elsewhere).

cgi_body_args

Arguments to cgi_body_args are made available to cgi_body as if they
had been specified in the call to cgi_body.  This provides a
convenient way for using the same colors, backgrounds, etc, in a set
of pages.

cgi_exit

cgi_exit provides a fast way of cleanly exiting a CGI script without
having to manually unwind procedures.  In particular, cgi_exit forces
closure of all open tags.  It then calls exit.  This is useful if you
want to exit from a CGI script at any point and still have the HTML be
correct.

** Frames

cgi_frameset cmd

Instead of cgi_body, you can call cgi_frameset to create framed
documents.  This produces <frameset></frameset> tags with the content
filled by evaluation of cmd.  Optional arguments are passed on as
attributes.

cgi_frame name=url

cgi_frame defines a frame with the given name and url.  The argument
handling is the same as for other name-value commands (even though the
value here is a url).  The url is automatically double-quoted.  Other
optional arguments are passed on as attributes.

cgi_noframes cmd

cgi_noframes produces <noframes></noframes> tags with the content
filled evaluation of cmd.  Optional arguments are passed on as
attributes.

**************************************************
CONTAINER SUPPORT
**************************************************

cgi_division

cgi_division evaluates its last argument, grouping it together.  This
is useful for acting on a group of paragraphs, such as for alignment
purposes.

cgi_center

cgi_center is similar to "cgi_division align=center".

**************************************************
SINGLE PARAGRAPH SUPPORT
**************************************************

Everything in this section generates a single paragraph or line break.
Most of these take a string as the last argument which is
appropriately formatted.  Any other arguments are used as tag
attributes.

cgi_p
cgi_address
cgi_blockquote
cgi_h1 through h7

Most of these procedures should be intuitive.  They all take a string
and display it in the appropriate way.  For example, a level 2
heading:

  h2 "Paragraph Support"

Here's a paragraph with some formatting (see next section for more
info):

  p "I [bold love] Tcl but hate [blink "blinking text"]"

Note that some of these generate tags that are not supported by all
browsers.  See the format-tour.cgi script to see these in use.

cgi_br

cgi_br causes a paragraph break to be printed.  Additional arguments
are passed on as attributes.

To embed a paragraph break (rather than printing it), use cgi_nl.  In
the following example, it is much more convenient to call cgi_br than
cgi_nl:

  radio_button "version=1"
  br
  radio_button "version=2"

See cgi_nl for more info.

**************************************************
TEXT SUPPORT
**************************************************

The following procedures take a string and return an appropriately
formatted version.  The string is always the last argument.  Any other
arguments are used as tag attributes.

cgi_bold
cgi_italic
cgi_underline
cgi_strikeout
cgi_subscript
cgi_superscript
cgi_typewriter
cgi_blink
cgi_emphasis
cgi_strong
cgi_cite
cgi_sample
cgi_keyboard
cgi_variable
cgi_definition
cgi_big
cgi_small
cgi_font

  p "I [bold love] Tcl but hate [blink "blinking text"]"

Note that some of these generate tags that are not supported by all
browsers.  See the format-tour.cgi script to see these in use.

cgi_basefont

cgi_basefont defines the base font.

**************************************************
SPECIAL CHARACTERS OR CHARACTER SEQUENCES
**************************************************

The following procedures produce characters such that when interpreted
by a browser returns the indicated character.

                      	Returns
cgi_lt			<
cgi_gt			>
cgi_amp			&
cgi_quote		"
cgi_enspace		en space
cgi_emspace		em space
cgi_nbspace		nonbreaking space
cgi_tm			registered trademark
cgi_copyright		copyright
cgi_isochar n		ISO character #n

cgi_nl

cgi_nl returns a paragraph break string suitable for embedding in a
string just as you would embed a newline in a Tcl string via \n.

To print a paragraph break rather than returning it, use cgi_br.  In
the following example, it is much more convenient to call cgi_nl than
than cgi_br:

  h2 "This appears[nl]on two lines."

See cgi_br for more info.

cgi_breakable

cgi_breakable indicates a place in a word at which the browser can
break a string across two lines.

cgi_unbreakable cmd

cgi_unbreakable evaluates a cmd in such a way that the output will not
be broken across lines by the browser just because the screen width is
exceeded.  Instead a horizontal scrollbar will appear so that the
browser can be manually scrolled to see the long line.
n
cgi_unbreakable_string string

cgi_unbreakable_string returns its arguments so that it will not be
broken across lines by the browser just because the screen width is
exceeded.  Instead a horizontal scrollbar will appear so that the
browser can be manually scrolled to see the long line.

Notes:

- It is my assumption that cgi_unbreakable will be much more commonly
used than the _string version, hence the choice of names.  Feel free
to let me know what I'm wrong.

- I have seen browsers handle unbreakables incorrectly, particularly
in interaction with other features.  If you can't get your
unbreakables to behave correctly, consider alternative layouts or
alternative HTML.  For example, unbreakable table data should be done
using "table_data nowrap".  I have no idea why but it works whereas
unbreakable causes the table rows to overlap.  Clearly, this is a
browser bug.

**************************************************
FORMS
**************************************************

cgi_form action args cmd

cgi_form defines a form.  The form is populated by executing the
command (last argument of cgi_form).  action defines the url to
process the form.  Any other arguments are passed as attributes.
A typical call looks like this:

  cgi_form response {
    ....
  }

Here "response" names the URL to process the form.  If the URL does
not begin with a protocol name (such as "http:"), a common root is
prepended and ".cgi" is appended.  This can be changed by redefining
the procedure cgi_cgi.

cgi_root

cgi_root defines the common root used by cgi_form (see above).
For example:

  cgi_root "http://www.nist.gov/cgi-bin/cgi.tcl-examples"

With one argument, cgi_root returns the new root.  With no arguments,
cgi_root returns the old root.

cgi_suffix

cgi_suffix defines the common suffix used by cgi_cgi and anything that
uses it such as cgi_form.  The default suffix is ".cgi".

cgi_cgi
cgi_cgi_set

cgi_cgi controls exactly how cgi_form creates URLs from its action
argument.  By default, cgi_cgi takes an argument, prepends [cgi_root]
and appends [cgi_suffix].  The suffix can be overridden by using the
-suffix flag and an argument to be used instead of [cgi_suffix].

Any additional arguments are joined together in the style required for
a GET style request.  These arguments should be preformatted using
cgi_cgi_set to guarantee proper encoding.  For example:

  cgi_cgi myscript \
     [cgi_cgi_set owner "Don"] \
     [cgi_cgi_set color "black & white"]

generates: ....?owner=Don&color=black+%26+white

cgi_isindex

cgi_isindex generates an <isindex> tag.  Optional arguments are passed
on as attributes.  In the processing CGI script, the value of the
isindex query is found in the "anonymous" variable.

cgi_relationship rel url

cgi_relationship expresses a relationship between this document and
another.  For example, the following says that the url named by
homepage is the home document of the current document.

  cgi_relationship home $homepage

Optional arguments are passed on as additional attributes.  Here's an
example that references an external style sheet that is a CSS type
(cascading style sheet).

  cgi_relationship stylesheet basic.css type=text/css


**************************************************
INPUT
**************************************************

cgi_input

CGI input means "cookies, files, and get/post data".  cgi_input reads
in all input, decodes it, and makes it available to a variety of other
routines.

For debugging, cgi_input can be given arguments to fake input.  This
allows you to run your cgi_script interactively or under a debugger
(either Tcl or C debugger).  Provide GET/POST data as the first
argument.  Provide cookie data as the second argument.  The arguments
should be encoded (see cgi_cgi_set).  For example:

  cgi_input "name=libes&old=foo&new1=bar&new2=hello"

This is convenient because when you run into a misbehaving CGI script,
the first thing it does is tell you the input in exactly this format.
Simply cut and paste it into your program and you can then
interactively debug it without using the real form or the CGI server.

If cgi_input is invoked from the CGI environment, the fake inputs are
ignored.  (If you want to force fake inputs in the CGI environment,
unset env(REQUEST_METHOD).

Forms encoded as multipart/form-data are usually used to handle file
input.  Since file data usually implies a large amount of data, the
data is saved to /tmp/CGIdbg.[pid] if debugging is enabled.  This file
can be fed back to cgi_input by providing the filename as the first
argument of cgi_input.  In addition, env(CONTENT_TYPE) must be set to
the appropriate content type.  This can found in env(CONTENT_TYPE).
Removal of the debugging file is the responsibility of the script or
the script programmer.  (Typically, I examine the file after my CGI
script is over and then delete them by hand.)

Execs before cgi_input reads POST data should have standard input
redirected ("< /dev/null" for instance) so that the exec'd process
doesn't inherit the CGI script's standard input.

** Form elements that generate lists

Variable names should only end with "List" if they correspond to form
elements which generate multiple values (some but not all uses of
select, checkbox, etc).  List variables will be given Tcl-style list
values.

If cgi_input encounters multiple values for variables that do not end
with List, it will provide the values in a Tcl-style list.  However,
this leaves an ambiguity in the case of a single value that "looks"
like a list, such as "a b".  Although a form author can usually "know"
whether a string is a list or not, it is simpler to stick to the
convention stated earlier.

Here are examples:

  # pull-down menu
  cgi_select Foo {
    cgi_option "a"
    cgi_option "a b"
  }

  # scrolled list, allow multiple selections
  cgi_select FooList multiple {
    cgi_option "a"
    cgi_option "a b"
  }

** Getting at the input

Input is made available in two ways: variables, files, and cookies.

-- Variables and Cookies

cgi_import_list

cgi_import_list returns a list of variable names supplied as input to
the script.

cgi_cookie_list

cgi_cookie_list returns a list of cookie names supplied to the script.

cgi_import name

cgi_import retrieves the value of the named variable and places it in
a Tcl variable of the same name.  The value is also returned as the
return value.

cgi_import_as name tclvar

cgi_import_as is similar to cgi_import but the value is assigned to
the Tcl variable named by the second argument.

cgi_import_cookie name

cgi_import is similar to cgi_import, however if the cgi variable does
not exist, the value is fetched from the cookie by that name.  (This
allows the user to override a cookie if the form allows it.)

cgi_import_cookie_as name tclvar

cgi_import_cookie_as is similar to cgi_import_cookie but the value is
assigned to the Tcl variable named by the second argument.

cgi_cookie_get name

cgi_cookie_get returns the value of the named cookie.

-- Files

cgi_import_file -server name
cgi_import_file -client name
cgi_import_file -type name

cgi_import_file returns information about an uploaded file.  "name" is
the string from the original form.  The Content-type is returned via
-type.  (This may be empty or even undefined in which case
cgi_import_file should be caught.)

Uploaded files are saved on the CGI server.  To avoid collisions with
other file upload instances, files are not stored in their original
names.  The name of the file as it is stored on the CGI server is
retrieved using the "-server" flag.  The original name of the file as
it was stored on the user's host is retrieved using the "-client"
flag.

Uploaded files are the responsibility of the CGI programmer.  In
particular, if you do not delete them, they will remain until /tmp is
cleaned up in some other way.

If the user does not enter a filename, an empty file will be delivered
with a null remote filename.

cgi_file_limit files chars

cgi_file_limit establishes limits on the number of files and their
size.  This is provided to prevent denial of service attacks.  If the
limit is exceeded, an error is raised from within cgi_input.

Note that when the limit is exceeded, cgi_input fails immediately.  So
if you just want to check file sizes that are not security related -
for example, you just want to accept gifs under 10K - it's better to
accept the gifs and then check the size manually (i.e., [file size
...].  That way, cgi_input will completely read all the variables and
you can give more appropriate diagnostics.

The default limit is 10 100MB files.  If you were to set this
yourself, it would look this way:

cgi_file_limit 10 100000000


-- File example

The following code echos the contents of a file that was
uploaded using the variable "file":

  cgi_input
  cgi_body {
    set server [cgi_import_filename -server $v]
    set client [cgi_import_filename -client $v]
    if [string length $client] {
      h4 "Uploaded: $client, contents:"
      cgi_preformatted {puts [exec cat $server]}
    }
    file delete $server
  }

The present implementation supports binary upload if you are using Tcl
8.1 (or later) or if you are using the Expect extension.  If you are
using a version of Tcl earlier than 8.1 with Expect but want to
suppress binary loading, create the global variable
_cgi(no_binary_upload).  (The reason you might want to suppress binary
loading is that it is noticably slower.)

**************************************************
EXPORT
**************************************************

Form elements automatically export their values.  See FORM ELEMENTS
for more information.

cgi_export name=value

cgi_export makes the named variable available with the given value.
The "=value" is optional.  If not present, the value of the Tcl
variable by the same name is used.  

cgi_export is implemented with variables of type=hidden.

cgi_export is implemented as an all-or-nothing operation.  In
particular, no HTML is emitted if the variable does not exist.  That
means it is not necessary to test for existence in situations where
you would like to export a variable IF it exists.  Rather, it is
sufficient to embed cgi_export within a catch.  For example, the
following generates nothing if xyz doesn't exist and it generates the
appropriate HTML if xyz does exist.

  catch {cgi_export xyz}

** Cookies

cgi_export_cookie name

cgi_export_cookie is similar to cgi_export except that the value is
made available as a cookie.  Additional arguments are handled as with
cgi_cookie_set (see below).

cgi_cookie_set name=val

cgi_cookie_set sets the named cookie.  All optional arguments are
handled specially.  All arguments are encoded appropriately.  The
expires keyword is handled specially to simplify common cases.  In
particular, the values "now" and "never" produce appropriate GMT
values.

Here are some example of cgi_cookie_set:

  cgi_cookie_set user=don domain=nist.gov expires=never
  cgi_cookie_set user=don domain=nist.gov expires=now
  cgi_cookie_set user=don domain=nist.gov expires=...actual date...

Note that cookie setting must be done during http head generation.

**************************************************
URL/IMG DICTIONARY SUPPORT
**************************************************

cgi_link tag
cgi_link tag display url

cgi_link provides a convenient mechanism for maintaining and
referencing from a set of URLs.

cgi_link returns the string <A>...</A> corresponding to the given tag.
A tag is defined by calling cgi_link with the tag, the clickable text
that the use should see, and the url.

For example, suppose you want to produce the following (where _xyz_
indicates xyz is a hyperlink):

  I am married to _Don Libes_ who works in the _Manufacturing
  Collaboration Technologies Group_ at _NIST_.

Using cgi_link with appropriate link definitions, the scripting to
produce this is:

  p "I am married to [link Libes] who works in the [link MCTG]
  at [link NIST]."

This expands to:

  I am married to <A HREF="http://elib.cme.nist.gov/msid/staff
  /libes/ libes.don.html">Don Libes</A> who works in the <A
  HREF="http:// elib.cme.nist.gov/msid/groups/mctg.htm">
  Manufacturing Collaboration Technologies Group</A> at <A
  HREF="http:// www.nist.gov">NIST</A>.

The links themselves are defined thusly:

  link Libes "Don Libes"    http://www.cme.nist.gov/msid/staff/libes
  link MCTG  "$MCT Group"   http://www.cme.nist.gov/msid/mctg
  link NIST  "NIST"         http://www.nist.gov

Now if my home page ever changes, rather than updating every
occurrence, I just have to edit the one definition.

Tcl variables can further simplify updates.  For instance, URLs for
Libes and MCTG are in a common directory.  It makes sense to store
that in a single variable.  Rewritten this appears:

set MSID http://www.cme.nist.gov/msid

  link Libes "Don Libes"    $MSID/staff/libes
  link MCTG  "$MCT Group"   $MSID/mctg
  link NIST  "NIST"         http://www.nist.gov

Then if the MSID directory ever moves, only one line need be updated.
This may seem like no big deal here, but if you have many links and
many uses of them, this pays off handsomely.

Optional attributes can be provided as additional arguments (see IMG
example below).

An existing link can be given a different "display" temporarily by
calling cgi_link with the different display and omitting the url.

cgi_imglink 

imglink works similar to cgi_link (see that documentation for more
info) except that no display argument is used and the second argument
is assumed to be the image source.  Example:

  imglink taj tajmahal.gif

Other attributes can be provided as additional arguments.

  imglink taj tajmahal.gif "alt=The Taj Mahal"

cgi_url display href args

By using cgi_url, URLs can be generated immediately (without using
cgi_link first).  This is convenient when you need a URL that will
only appear once - so that there is no point in storing it in a
dictionary.  For example:

  cgi_li "[cgi_url "Plume" http://pastime.anu.edu.au/Plume]
      is a Tcl-based WWW browser written by Steve Ball,
      Australian National University.  Among its interesting
      features is the ability to execute Tcl applets and the
      ability to dynamically extend the browser at runtime."

cgi_img href args

cgi_img returns a formatted <img> tag.  It is useful for one-time tags.
Tags that are used multiple times should use cgi_imglink.  Example:

  cgi_img foo.gif "alt=Foo's Bar & Grill"

cgi_anchor_name name

cgi_anchor_name returns an anchor that can be used in an HTML body
that it can be linked to using the #name syntax.  For example, to make
a heading that you want to be able to link to:

  h2 "[cgi_anchor_name future]Future Improvements"

Then to reference the "future" tag:

  p "Look for [cgi_url "improvements" #future] in the future."

cgi_base args

cgi_base defines a base or window target for urls.

**************************************************
QUOTING
**************************************************

cgi_unquote_input string

cgi_unquote_input undoes "url-encoding" and returns the result.  This
is normally applied automatically to input sources including URLs and
cookies.  So you shouldn't have to call this manually.

cgi_quote_html string

cgi_quote_html returns the string but with any html-special characters
escaped.  For example, "<" is replaced by "\&lt".  This is useful for
displaying a literal "<" in the browser.

cgi_dquote_html string

cgi_dquote_html does the same thing as cgi_quote_html but also adds on
double quotes.  cgi_quote_html is called automatically for implicit
value attributes.

cgi_quote_url string

cgi_quote_url quotes strings appropriately to appear in a url, cookie,
etc.  This is useful if you want to publish a url by hand (and must do
the conversion manually that the client normally does for you).

If you are generating cgi-style URLs for forms, use cgi_cgi_set.

cgi_preformatted cmd

cgi_preformatted evaluates its last argument to produce fixed-width
preformatted output.  Optional arguments are passed as attributes to
the tags.

cgi_preformatted allows a subset of tags to be interpreted by the
browser.  For example, the <a> tag is interpreted but font change tags
are not.  To prevent all interpretation, use cgi_quote_html.  For
example, the following prints a file that might contain HTML but
without any risk to throwing off formatting.

  cgi_preformatted {
    puts [cgi_quote_html [read $fid]]
  }

**************************************************
LIST SUPPORT
**************************************************

** List elements

cgi_li string

cgi_li prints its string as a list element.  Optional arguments are
passed through as attributes.  cgi_li does not have to appear in a
list container, but it can.

cgi_term text
cgi_term_definition text

cgi_term and cgi_term_definition are usually paired up (although they
need not be) to creates terms and defintions.  They do not have to
appear in a list container, but usually appear in a cgi_definition_list.

** List containers

cgi_number_list cmd
cgi_bullet_list cmd

cgi_number_list and cgi_bullet_list take their cmd argument and
evaluate it in a list container context.  (I don't know about you but
I could never remember <ol>, <ul>, and all the other ones.  This names
seem much easier to remember.)

cgi_li is a typical command to call inside of a list container, but
you can use regular paragraphs (or anything else) as well.

cgi_definition_list

cgi_definition_list is the usual list container for cgi_term and
cgi_term_definition.  It may contain other things as well.

cgi_menu_list
cgi_directory_list

cgi_menu_list and cgi_directory are more list containers with the
obvious semantics.  Previous remarks about other list containers
apply.

**************************************************
TABLE
**************************************************

cgi_table cmd

cgi_table produces <table></table> tags with the content filled by
evaluation of cmd.  Optional arguments are passed on as attributes.

cgi_caption cmd

cgi_caption produces <caption></caption> tags with the content filled
by evaluation of cmd.  Optional arguments are passed on as attributes.

cgi_table_row cmd
cgi_table_head cmd
cgi_table_data cmd

These functions all produce the appropriate tags with the content
filled by evaluation of cmd.  Optional arguments are passed on as
attributes.

cgi_tr table_data
cgi_td table_data
cgi_th table_data

cgi_tr, cgi_td, and cgi_th are shortcuts for relatively simple rows.

cgi_td outputs a table element.  Unlike cgi_table_data, the argument
is not evalled.  This allows more terse specification of simple rows.
The following example produces a table with three elements, the last
of which is prevented from wrapping:

  table_row {td Don;td Steve;td nowrap "Really Long Name"}

As the example suggests, optional arguments are passed on as
data-specific attributes.

cgi_th is identical to cgi_td except that it produces table heading
elements.

cgi_tr outputs a row of elements without having to call cgi_td or
cgi_table_data.  As with td, eval is not called.  Data-specific
attributes cannot be provided.  All the elements are passed as a
single argument.  For example:

  tr {Don Steve {Really Long Name}}
or
  tr [list Don Steve $reallylongname]

Optional arguments are passed on as row-specific attributes.

**************************************************
BUTTON
**************************************************

cgi_submit_button name=value
cgi_radio_button name=value
cgi_image_button name=value

These procedure create buttons.  The first argument indicates the
variable name and value.  (See notes on "Name-value" commands earlier
to understand behavior of omitted names/values.)  Unless otherwise
mentioned below, additional arguments are passed on as attributes.

  cgi_submit_button "=Submit Form"
  cgi_submit_button "Action=Pay Raise"

  cgi_radio_button "version=1"
  cgi_radio_button "version=2" checked=1

  cgi_image_button "=http://www.cme.nist.gov/images/title.gif"
  cgi_image_button "Map=http://www.cme.nist.gov/images/msid3.gif"

Groups of radio buttons must share the same variable name.  To address
the obvious question: No, there is no single command to produce a
group of radio buttons because you might very well want to do
arbitrarily-complex calculations in between them.  And with a
long-enough line of buttons, the obvious behavior (laying them all out
in a line like CGI.pm does) makes it hard to tell at a glance if the
buttons associate with the label to the left or the right of them.
Anyway, you'll almost certainly want to write another procedure to
call cgi_radio_button and that can control the variable name.

The radio button argument "checked_if_equal=xxx" indicates that the
button should be shown selected if its associated value is xxx.  This
is handy if you are creating radio buttons by iterating over a list.

The radio button "checked=value" indicates that the button should be
shown selected if the value is a boolean of value true.

All other arguments are passed on as attributes.

cgi_file_button name

cgi_file_button provides a filename entry box.  When the form is
submitted, the file is "uploaded" (sent from the client to the
server).  The argument enctype=multipart/form-data must be given to
the cgi_form command when using cgi_file_button.

After uploading, the file is the responsibility of the CGI programmer.
In particular, if you do not delete it, it will remain until /tmp is
cleaned up in some other way.

For example, to upload a single file, the form might look like this:

  cgi_form upload height=3 enctype=multipart/form-data {
    cgi_file_button file
    cgi_submit_button =Upload
  }

Uploaded files are automatically made available to the CGI script
using cgi_import_filename.  (See elsewhere for more information.)

cgi_reset_button value

cgi_reset_button creates a a reset button.  An argument overrides the
default label.  For example:

  cgi_reset_button
  cgi_reset_button "Not the Default Reset Button"

cgi_map name cmd
cgi_area args

These procedures are used to specify client-side image maps.  The
first argument of cgi_map is the map name.  The last argument is
evaluated to fill the contents of <map></map> tags.  cgi_area's
arguments are embedded as arguments in an <area> tag.

Warning: These two commands will likely be redefined as I get more
familiar with how they are typically used.

**************************************************
CHECKBOX
**************************************************

cgi_checkbox name=value

cgi_checkbox is similar to cgi_radio_button (see above) except that
multiple values can be checked at the same time.  As explained
earlier, the variable name must end with "List" in order for it to
group all the values as a list in the resulting CGI script.

The argument "checked_if_equal=xxx" which indicates that the current
name should be shown selected if its associated value is xxx.  This is
handy if you are creating checkboxes by iterating over a list.

The argument "checked=value" indicates that the checkbox should be
shown selected if the value is a boolean of value true.

Other arguments are passed on as attributes.


**************************************************
TEXTENTRY AND TEXTAREA
**************************************************

cgi_text name=value

cgi_text provides a one-line text entry box.  It works similarly to
other form elements.  (Read "Name-value commands" elsewhere.)
Additional arguments are passed on as attributes.  Examples:

  cgi_text Foo
  cgi_text Foo=
  cgi_text Foo=value2
  cgi_text Foo=value2 size=5
  cgi_text Foo=value2 size=5 maxlength=10
  cgi_text Foo=value2 size=10 maxlength=5
  cgi_text Foo=value2 maxlength=5

cgi_textarea name=value

cgi_textarea provides a multiline text entry box.  It works similarly
to other form elements.  (Read "Name-value commands" elsewhere.)
Additional arguments are passed on as attributes.

  set value "A really long line so that we can compare the\
		effect of wrap options."

  cgi_textarea Foo
  cgi_textarea Foo=
  cgi_textarea Foo=$value
  cgi_textarea Foo=$value rows=3
  cgi_textarea Foo=$value rows=3 cols=7
  cgi_textarea Foo=$value rows=3 cols=7 wrap=virtual

**************************************************
SELECT
**************************************************

cgi_select name cmd

cgi_select can be used to produce pull-down menus and scrolled lists.
(And depending upon the future of HTML, I may provide better-named
commands to indicate this.)  Its behavior is controlled by additional
arguments which are simply the appropriate attributes.

cgi_select evaluates cmd which typically contains multiple calls to
cgi_option.

cgi_option string

cgi_option adds options to cgi_select.  By default, the string is
displayed and sent back as the value of the cgi_select variable.  The
value can be overridden by an explicit "value=" argument.  Additional
options are passed on as attributes, except for "selected_if_equal".

"selected_if_equal=xxx" indicates that the current option should be
shown selected if the value is equal to xxx.  This is useful if you
are generating cgi_options in a loop rather than manually.

Here are examples:

  # pull-down menu
  cgi_select Foo {
    cgi_option one selected
    cgi_option two
    cgi_option many value=hello
  }

  # scrolled list, allow multiple selections, show all elements
  cgi_select FooList multiple {
    cgi_option one selected
    cgi_option two selected
    cgi_option many 
  }

  # scrolled list, allow multiple selections, show 2 elements max
  cgi_select FooList multiple size=2 {
    cgi_option one selected
    cgi_option two selected
    cgi_option many 
  }

  # choose "selected" dynamically
  # example: list all Tcl command and select "exit" automatically
  cgi_select FooList multiple size=5 {
    foreach o [info comm] {
      cgi_option $o selected_if_equal=exit
    }
  }

Note: If both value= and selected_if_equal= appear, the test for
selection is made against the last value string (implicit or explicit)
that appears before the selected_if_equal argument.  In other words,
if you want selected_if_equal= to be tested against the explicit
value= argument, put the selected_if_equal= *after* the value=.

**************************************************
APPLET
**************************************************

cgi_applet parameters cmd

cgi_applet produces <applet></applet> tags such as for Java.

cgi_param name=value

cgi_param produces <param> tags for passing parameters to applets.

For example:

  cgi_applet "codebase=../" "code=some.class" width=640 height=480 {
     cgi_param parm=value
  }

**************************************************
PLUG-IN
**************************************************

cgi_embed src widthxheight

cgi_embed creates an <embed> tag.  The first argument is the source.
The second argument is the width and height in the style "WxH".
Optional arguments are passed on to the tag.  For example:

  cgi_embed myavi.avi 320x200 autostart=true

produces:

  <embed src="myavi.avi" width="320" height="200" autostart=true>

Notice the autostart value is unquoted because autostart is not
specifically defined by the spec.  The argument "-quote" causes all
remaining attributes to be url encoded and quoted.  For example:

  cgi_embed myavi.avi 320x200 a=b -quote c=d e=f

produces:

  <embed src="myavi.avi" width="320" height="200" a=b c="d" e="f">

**************************************************
MISC
**************************************************

cgi_hr

cgi_hr produces horizontal rules.  Optional arguments are passed on as
attributes.

**************************************************
COMMENTS
**************************************************

cgi_comment stuff

cgi_comment can comment out anything including blocks of code.

cgi_html_comment stuff

cgi_html_comment comments out things in such a way that the comment
appears in the final html itself.

**************************************************
OUTPUT
**************************************************

cgi_put string

cgi_put prints the string with no new terminating newline.  This is
simply a shorthand for puts -nonewline.

cgi_puts

Many routines in this library send output to the standard output by
default.  This is convenient for CGI scripts.  However, if you want to
generate multiple files, it is useful to be able to redirect output
dynamically.  Output can be redirected by redefining cgi_puts.  The
default definition of cgi_puts is:

  proc cgi_puts {args} {
    eval puts $args
  }

cgi_puts must allow for an optional -nonewline argument.  For example,
here is a definition that writes to a file identified by the global
"fd".

  proc cgi_puts {args} {
    global fd

    puts -nonewline $fd [lindex $args end]
    if {[llength $args] > 1} {
      puts $fd ""
    }
  }

cgi_buffer cmd

cgi_buffer evaluates its argument in such a way that output (through
explicit or implicit calls to cgi_puts) is not produced.  Instead, the
output is returned.

For example, the following cmd generates a link with the hyperlinked
portion being a header and two paragraphs.

  link tag [cgi_buffer {
    h3 "Level 3 header"
    p "New paragraph"
    p "Another paragraph"
  }] $URL

cgi_buffer can be called recursively.

cgi_buffer_nl string

By default, cgi_buffer generates newlines at the end of every line in
the style of puts.  It is occasionally useful to be able to disable
this - for example, when calling it inside cgi_preformatted.  The
newline definition can be changed via cgi_buffer_nl.  (There is no
point to redefining cgi_puts since cgi_buffer doesn't use it.)  A null
argument suppresses any newline.  For example:

  cgi_buffer_nl ""

cgi_buffer_nl returns the previous definition.

**************************************************
MAIL
**************************************************

Rudimentary email support is provided, in part, because it is useful
for trapping errors - if debugging is disabled (i.e., during actual
use) and an error is encountered, errors are emailed to the service
admin.

The current implementation only permits one email transaction at a
time.

cgi_mail_addr addr

cgi_mail_addr defines the email address that mail comes from.  Your
email system must allow this, of course.  (If your system doesn't
allow it, the request is usually ignored.)

cgi_mail_start addr

cgi_mail_start creates a mail message to be delivered the given addr.
cgi_mail_add should be used to provide a subject and body.

cgi_mail_add string

cgi_mail_add adds strings to the current mail message.  No argument
causes a blank line to be added.

cgi_mail_end

cgi_mail_end queues the the current mail message for delivery.

  cgi_mail_start libes@nist.gov
  cgi_mail_add "Subject: [cgi_name] request succeeded
  cgi_mail_add
  cgi_mail_add "Your request has been processed."
  cgi_mail_add "Thanks for using [cgi_name].
  cgi_mail_end

cgi_mail_relay host

cgi_mail_relay identifies a host to be used for mail relay services.
(This is currently only used when sendmail support is not available.)
If a relay is not defined, email is sent directly to the recipient.

**************************************************
INITIALIZATION
**************************************************

cgi_init

The package initializes itself upon initial loading, however it can be
explicitly initialized by calling cgi_init.  This is useful in
environments such as tclhttpd.