Tcl Library Source Code

Check-in [43904ac14b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Bring md special-char/verbatim fixes to the devguide
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | doc-overhaul
Files: files | file ages | folders
SHA3-256: 43904ac14b981263ed849b9aa5f96c809e3e975e48a0801f2ba4b9d8f94aceff
User & Date: aku 2019-04-10 20:58:46.367
Original Comment: Bring md special-car/verbatim fixes to the devguide
Context
2019-04-10
21:06
Typo fixes check-in: f5da46e8f9 user: aku tags: doc-overhaul
20:58
Bring md special-char/verbatim fixes to the devguide check-in: 43904ac14b user: aku tags: doc-overhaul
20:46
Doctools: - Extended testsuite, markdown special character example. - Fixed issue in markdown engine with handling of its special characters in verbatim blocks. Should not emit them as quoted, they are not special in such blocks. Regenerated package docs (version bump & fixes making changes) Version bump - doctools 1.5.2 B (markdown) T (markdown) check-in: c74461e613 user: aku tags: trunk
2019-03-29
18:58
Fix old html links in the main index. Go markdown. check-in: 44c6bd8cc3 user: aku tags: doc-overhaul
Changes
Unified Diff Ignore Whitespace Patch
Changes to embedded/md/tcllib/files/apps/dtplite.md.
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
  - \[2\]

    The following directory structure is created when processing a single set of
    input documents\. The file extension used is for output in HTML, but that is
    not relevant to the structure and was just used to have proper file names\.

        output/
            toc\.html
            index\.html
            files/
                path/to/FOO\.html

    The last line in the example shows the document generated for a file FOO
    located at

        inputdirectory/path/to/FOO

  - \[3\]

    When merging many packages into a unified set of documents the generated
    directory structure is a bit deeper:

        output
            \.toc
            \.idx
            \.tocdoc
            \.idxdoc
            \.xrf
            toc\.html
            index\.html
            FOO1/
                \.\.\.
            FOO2/
                toc\.html
                files/
                    path/to/BAR\.html

    Each of the directories FOO1, \.\.\. contains the documents generated for the
    package FOO1, \.\.\. and follows the structure shown for use case \[2\]\. The only
    exception is that there is no per\-package index\.

    The files "\.toc", "\.idx", and "\.xrf" contain the internal status of the
    whole output and will be read and updated by the next invokation\. Their







|
|

|












|
|
|
|
|
|
|

|

|

|







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
  - \[2\]

    The following directory structure is created when processing a single set of
    input documents\. The file extension used is for output in HTML, but that is
    not relevant to the structure and was just used to have proper file names\.

        output/
            toc.html
            index.html
            files/
                path/to/FOO.html

    The last line in the example shows the document generated for a file FOO
    located at

        inputdirectory/path/to/FOO

  - \[3\]

    When merging many packages into a unified set of documents the generated
    directory structure is a bit deeper:

        output
            .toc
            .idx
            .tocdoc
            .idxdoc
            .xrf
            toc.html
            index.html
            FOO1/
                ...
            FOO2/
                toc.html
                files/
                    path/to/BAR.html

    Each of the directories FOO1, \.\.\. contains the documents generated for the
    package FOO1, \.\.\. and follows the structure shown for use case \[2\]\. The only
    exception is that there is no per\-package index\.

    The files "\.toc", "\.idx", and "\.xrf" contain the internal status of the
    whole output and will be read and updated by the next invokation\. Their
Changes to embedded/md/tcllib/files/apps/page.md.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
the plugin option they are associated with does not understand them, and was not
superceded by a plugin option coming after\.

Default options are used if and only if the command line did not contain any
options at all\. They will set the application up as a PEG\-based parser
generator\. The exact list of options is

    \-c peg

And now the recognized options and their arguments, if they have any:

  - __\-\-help__

  - __\-h__








|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
the plugin option they are associated with does not understand them, and was not
superceded by a plugin option coming after\.

Default options are used if and only if the command line did not contain any
options at all\. They will set the application up as a PEG\-based parser
generator\. The exact list of options is

    -c peg

And now the recognized options and their arguments, if they have any:

  - __\-\-help__

  - __\-h__

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

      * *peg*

        It sets the application up as a parser generator accepting parsing
        expression grammars and writing a packrat parser in Tcl\. The actual
        arguments it specifies are:

    \-\-reset
    \-\-append
    \-\-reader    peg
    \-\-transform reach
    \-\-transform use
    \-\-writer    me

  - __\-r__ *name*

    Readers\. The name of the package for the plugin *name* is
    "page::reader::*name*"\.

    We have five predefined plugins:







|
|
|
|
|
|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

      * *peg*

        It sets the application up as a parser generator accepting parsing
        expression grammars and writing a packrat parser in Tcl\. The actual
        arguments it specifies are:

    --reset
    --append
    --reader    peg
    --transform reach
    --transform use
    --writer    me

  - __\-r__ *name*

    Readers\. The name of the package for the plugin *name* is
    "page::reader::*name*"\.

    We have five predefined plugins:
Changes to embedded/md/tcllib/files/apps/pt.md.
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
In this section we are working a complete example, starting with a PEG grammar
and ending with running the parser generated from it over some input, following
the outline shown in the figure below:

![](\.\./\.\./\.\./image/flow\.png) Our grammar, assumed to the stored in the file
"calculator\.peg" is

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

From this we create a snit\-based parser via

    pt generate snit calculator\.tcl \-class calculator \-name calculator peg calculator\.peg

which leaves us with the parser package and class written to the file
"calculator\.tcl"\. Assuming that this package is then properly installed in a
place where Tcl can find it we can now use this class via a script like

    package require calculator

    lassign $argv input
    set channel \[open $input r\]

    set parser \[calculator\]
    set ast \[$parser parse $channel\]
    $parser destroy
    close $channel

    \.\.\. now process the returned abstract syntax tree \.\.\.

where the abstract syntax tree stored in the variable will look like

    set ast \{Expression 0 4
        \{Factor 0 4
            \{Term 0 2
                \{Number 0 2
                    \{Digit 0 0\}
                    \{Digit 1 1\}
                    \{Digit 2 2\}
                \}
            \}


            \{AddOp 3 3\}
            \{Term 4 4
                \{Number 4 4
                    \{Digit 4 4\}
                \}
            \}
        \}
    \}





assuming that the input file and channel contained the text

    120\+5

A more graphical representation of the tree would be

![](\.\./\.\./\.\./image/expr\_ast\.png) Regardless, at this point it is the user's
responsibility to work with the tree to reach whatever goal she desires\. I\.e\.
analyze it, transform it, etc\. The package
__[pt::ast](\.\./modules/pt/pt\_astree\.md)__ should be of help here,







|
|
|
|
|
|
|
|
|




|








|

|
|



|



|
|
|
|
|
|
|
<
<
>
>
|
|
|
|
<
<
<
<
|
>
>
>
>


|







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
In this section we are working a complete example, starting with a PEG grammar
and ending with running the parser generated from it over some input, following
the outline shown in the figure below:

![](\.\./\.\./\.\./image/flow\.png) Our grammar, assumed to the stored in the file
"calculator\.peg" is

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

From this we create a snit\-based parser via

    pt generate snit calculator.tcl -class calculator -name calculator peg calculator.peg

which leaves us with the parser package and class written to the file
"calculator\.tcl"\. Assuming that this package is then properly installed in a
place where Tcl can find it we can now use this class via a script like

    package require calculator

    lassign $argv input
    set channel [open $input r]

    set parser [calculator]
    set ast [$parser parse $channel]
    $parser destroy
    close $channel

    ... now process the returned abstract syntax tree ...

where the abstract syntax tree stored in the variable will look like

    set ast {Expression 0 4
        {Factor 0 4
            {Term 0 2
                {Number 0 2
                    {Digit 0 0}
                    {Digit 1 1}
                    {Digit 2 2}


                }
            }
            {AddOp 3 3}
            {Term 4 4
                {Number 4 4
                    {Digit 4 4}




                }
            }
        }
    }

assuming that the input file and channel contained the text

    120+5

A more graphical representation of the tree would be

![](\.\./\.\./\.\./image/expr\_ast\.png) Regardless, at this point it is the user's
responsibility to work with the tree to reach whatever goal she desires\. I\.e\.
analyze it, transform it, etc\. The package
__[pt::ast](\.\./modules/pt/pt\_astree\.md)__ should be of help here,
Changes to embedded/md/tcllib/files/devdoc/tcllib_devguide.md.
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

    If some other branch is desired as the starting point for the coming work
    replace *trunk* in the commands above with the name of that branch\.

    With the base line established we now have two ways of creating the new
    branch, with differing \(dis\)advantages\. The simpler way is to

        fossil branch new NAME\_OF\_NEW\_BRANCH

    and start developing\. The advantage here is that you cannot forget to create
    the branch\. The disadvantages are that we have a branch commit unchanged
    from where we branched from, and that we have to use high\-handed techniques
    like hiding or shunning to get rid of the commit should we decide to abandon
    the work before the first actual commit on the branch\.

    The other way of creating the branch is to start developing, and then on the
    first commit use the option __\-\-branch__ to tell __fossil__ that we
    are starting a branch now\. I\.e\. run

        fossil commit \-\-branch NAME\_OF\_NEW\_BRANCH \.\.\.

    where *\.\.\.* are any other options used to supply the commit message, files
    to commit, etc\.

    The \(dis\)advantages are now reversed\.

    We have no superflous commit, only what is actually developed\. The work is







|











|







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

    If some other branch is desired as the starting point for the coming work
    replace *trunk* in the commands above with the name of that branch\.

    With the base line established we now have two ways of creating the new
    branch, with differing \(dis\)advantages\. The simpler way is to

        fossil branch new NAME_OF_NEW_BRANCH

    and start developing\. The advantage here is that you cannot forget to create
    the branch\. The disadvantages are that we have a branch commit unchanged
    from where we branched from, and that we have to use high\-handed techniques
    like hiding or shunning to get rid of the commit should we decide to abandon
    the work before the first actual commit on the branch\.

    The other way of creating the branch is to start developing, and then on the
    first commit use the option __\-\-branch__ to tell __fossil__ that we
    are starting a branch now\. I\.e\. run

        fossil commit --branch NAME_OF_NEW_BRANCH ...

    where *\.\.\.* are any other options used to supply the commit message, files
    to commit, etc\.

    The \(dis\)advantages are now reversed\.

    We have no superflous commit, only what is actually developed\. The work is
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

      1. Validate the checkout again\. The incoming trunk changes may have broken
         something now\. Do any required fixes\.

      1. Now merge to the trunk using

             fossil update trunk
             fossil merge \-\-integrate YOU\_BRANCH

      1. At this point the checkout should be in the same state as at the end of
         point \(3\) above, because we resolved any issues with the trunk already\.
         Thus a simple

             fossil commit \.\.\.

         should be sufficient now to commit the merge back and close the branch
         \(due to the __\-\-integrate__ we used on the merge\)\.

         The more paranoid may validate the checkout a third time before
         commiting\.








|





|







411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

      1. Validate the checkout again\. The incoming trunk changes may have broken
         something now\. Do any required fixes\.

      1. Now merge to the trunk using

             fossil update trunk
             fossil merge --integrate YOU_BRANCH

      1. At this point the checkout should be in the same state as at the end of
         point \(3\) above, because we resolved any issues with the trunk already\.
         Thus a simple

             fossil commit ...

         should be sufficient now to commit the merge back and close the branch
         \(due to the __\-\-integrate__ we used on the merge\)\.

         The more paranoid may validate the checkout a third time before
         commiting\.

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

    Even if __fossil__ does not report any conflicts it is a good idea to
    check that the operation has not broken the new and/or changed functionality
    we are working on\.

    With the establishment of a good merge we then save the state with

        fossil commit \.\.\.

    before continuing development\.

## <a name='subsection7'></a>Version numbers

In Tcllib all changes to a package have to come with an increment of its version
number\. What part is incremented \(patchlevel, minor, major version\) depends on







|







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

    Even if __fossil__ does not report any conflicts it is a good idea to
    check that the operation has not broken the new and/or changed functionality
    we are working on\.

    With the establishment of a good merge we then save the state with

        fossil commit ...

    before continuing development\.

## <a name='subsection7'></a>Version numbers

In Tcllib all changes to a package have to come with an increment of its version
number\. What part is incremented \(patchlevel, minor, major version\) depends on
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

  1. The package documentation\.

The "sak\.tcl" command __validate version__ helps finding discrepancies
between the first two\. All the other __validate__ methods are also of
interest to any developer\. Invoke it with

    sak\.tcl help validate

to see their documentation\.

# <a name='section4'></a>Structural Overview

## <a name='subsection8'></a>Main Directories








|







533
534
535
536
537
538
539
540
541
542
543
544
545
546
547

  1. The package documentation\.

The "sak\.tcl" command __validate version__ helps finding discrepancies
between the first two\. All the other __validate__ methods are also of
interest to any developer\. Invoke it with

    sak.tcl help validate

to see their documentation\.

# <a name='section4'></a>Structural Overview

## <a name='subsection8'></a>Main Directories

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
providing management operations, for example setting a list of standard Tcl
shells to use\.

## <a name='subsection12'></a>Invoke the testsuites of a specific module

Invoke either

    \./sak\.tcl test run foo

or

    \./sak\.tcl test run modules/foo

to invoke the testsuites found in a specific module "foo"\.

## <a name='subsection13'></a>Invoke the testsuites of all modules

Invoke the tool without a module name, i\.e\.

    \./sak\.tcl test run

to invoke the testsuites of all modules\.

## <a name='subsection14'></a>Detailed Test Logs

In all the previous examples the test runner will write a combination of
progress display and testsuite log to the standard output, showing for each
module only the tests that passed or failed and how many of each in a summary at
the end\.

To get a detailed log, it is necessary to invoke the test runner with additional
options\.

For one:

    \./sak\.tcl test run \-\-log LOG foo

While this shows the same short log on the terminal as before, it also writes a
detailed log to the file "LOG\.log", and excerpts to other files \("LOG\.summary",
"LOG\.failures", etc\.\)\.

For two:

    \./sak\.tcl test run \-v foo

This writes the detailed log to the standard output, instead of the short log\.

Regardless of form, the detailed log contains a list of all test cases executed,
which failed, and how they failed \(expected versus actual results\)\.

## <a name='subsection15'></a>Shell Selection

By default the test runner will use all the Tcl shells specified via __test
add__ to invoke the specified testsuites, if any\. If no such are specified it
will fall back to the Tcl shell used to run the tool itself\.

Use option __\-\-shell__ to explicitly specify the Tcl shell to use, like

    \./sak\.tcl test run \-\-shell /path/to/tclsh \.\.\.

## <a name='subsection16'></a>Help

Invoke the tool as

    \./sak\.tcl help test

to see the detailed help for all methods of
__[test](\.\./\.\./\.\./index\.md\#test)__, and the associated options\.

# <a name='section6'></a>Documentation Tooling

The standard format used for documentation of packages and other things in
Tcllib is *[doctools](\.\./\.\./\.\./index\.md\#doctools)*\. Its supporting
packages are a part of Tcllib, see the directories "modules/doctools" and
"modules/dtplite"\. The latter is an application package, with the actual
application "apps/dtplite" a light wrapper around it\.

Tcllib developers gain access to these through the __doc__ method of the
"sak\.tcl" tool, another \(internal\) wrapper around the "modules/dtplite"
application package\.

## <a name='subsection17'></a>Generate documentation for a specific module

Invoke either

    \./sak\.tcl doc html foo

or

    \./sak\.tcl doc html modules/foo

to generate HTML for the documentation found in the module "foo"\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection18'></a>Generate documentation for all modules

Invoke the tool without a module name, i\.e\.

    \./sak\.tcl doc html

to generate HTML for the documentation found in all modules\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection19'></a>Available output formats, help

Invoke the tool as

    \./sak\.tcl help doc

to see the entire set of supported output formats which can be generated\.

## <a name='subsection20'></a>Validation without output

Note the special format __validate__\.

Using this value as the name of the format to generate forces the tool to simply
check that the documentation is syntactically correct, without generating actual
output\.

Invoke it as either

    \./sak\.tcl doc validate \(modules/\)foo

or

    \./sak\.tcl doc validate

to either check the packages of a specific module or check all of them\.

# <a name='section7'></a>Notes On Writing A Testsuite

While previous sections talked about running the testsuites for a module and the
packages therein, this has no meaning if the module in question has no







|



|







|















|







|














|





|




















|



|











|











|













|



|







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
providing management operations, for example setting a list of standard Tcl
shells to use\.

## <a name='subsection12'></a>Invoke the testsuites of a specific module

Invoke either

    ./sak.tcl test run foo

or

    ./sak.tcl test run modules/foo

to invoke the testsuites found in a specific module "foo"\.

## <a name='subsection13'></a>Invoke the testsuites of all modules

Invoke the tool without a module name, i\.e\.

    ./sak.tcl test run

to invoke the testsuites of all modules\.

## <a name='subsection14'></a>Detailed Test Logs

In all the previous examples the test runner will write a combination of
progress display and testsuite log to the standard output, showing for each
module only the tests that passed or failed and how many of each in a summary at
the end\.

To get a detailed log, it is necessary to invoke the test runner with additional
options\.

For one:

    ./sak.tcl test run --log LOG foo

While this shows the same short log on the terminal as before, it also writes a
detailed log to the file "LOG\.log", and excerpts to other files \("LOG\.summary",
"LOG\.failures", etc\.\)\.

For two:

    ./sak.tcl test run -v foo

This writes the detailed log to the standard output, instead of the short log\.

Regardless of form, the detailed log contains a list of all test cases executed,
which failed, and how they failed \(expected versus actual results\)\.

## <a name='subsection15'></a>Shell Selection

By default the test runner will use all the Tcl shells specified via __test
add__ to invoke the specified testsuites, if any\. If no such are specified it
will fall back to the Tcl shell used to run the tool itself\.

Use option __\-\-shell__ to explicitly specify the Tcl shell to use, like

    ./sak.tcl test run --shell /path/to/tclsh ...

## <a name='subsection16'></a>Help

Invoke the tool as

    ./sak.tcl help test

to see the detailed help for all methods of
__[test](\.\./\.\./\.\./index\.md\#test)__, and the associated options\.

# <a name='section6'></a>Documentation Tooling

The standard format used for documentation of packages and other things in
Tcllib is *[doctools](\.\./\.\./\.\./index\.md\#doctools)*\. Its supporting
packages are a part of Tcllib, see the directories "modules/doctools" and
"modules/dtplite"\. The latter is an application package, with the actual
application "apps/dtplite" a light wrapper around it\.

Tcllib developers gain access to these through the __doc__ method of the
"sak\.tcl" tool, another \(internal\) wrapper around the "modules/dtplite"
application package\.

## <a name='subsection17'></a>Generate documentation for a specific module

Invoke either

    ./sak.tcl doc html foo

or

    ./sak.tcl doc html modules/foo

to generate HTML for the documentation found in the module "foo"\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection18'></a>Generate documentation for all modules

Invoke the tool without a module name, i\.e\.

    ./sak.tcl doc html

to generate HTML for the documentation found in all modules\. Instead of
__html__ any other supported format can be used here, of course\.

The generated formatted documentation will be placed into a directory "doc" in
the current working directory\.

## <a name='subsection19'></a>Available output formats, help

Invoke the tool as

    ./sak.tcl help doc

to see the entire set of supported output formats which can be generated\.

## <a name='subsection20'></a>Validation without output

Note the special format __validate__\.

Using this value as the name of the format to generate forces the tool to simply
check that the documentation is syntactically correct, without generating actual
output\.

Invoke it as either

    ./sak.tcl doc validate (modules/)foo

or

    ./sak.tcl doc validate

to either check the packages of a specific module or check all of them\.

# <a name='section7'></a>Notes On Writing A Testsuite

While previous sections talked about running the testsuites for a module and the
packages therein, this has no meaning if the module in question has no
Changes to embedded/md/tcllib/files/devdoc/tcllib_installer.md.
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
\(*Windows*\)\.

## <a name='subsection3'></a>Installing on Unix

For *Unix*\-like environments Tcllib comes with the standard set of files to
make

    \./configure
    make install

a suitable way of installing it\. This is a standard non\-interactive install
automatically figuring out where to place everything, i\.e\. packages,
applications, and the manpages\.

To get a graphical installer invoke

    \./installer\.tcl

instead\.

## <a name='subsection4'></a>Installing on Windows

In a Windows environment we have the __installer\.tcl__ script to perform
installation\.

If the desired __tclsh__ is associated "\.tcl" files then double\-clicking /
opening the __installer\.tcl__ is enough to invoke it in graphical mode\. This
assumes that *[Tk](\.\./\.\./\.\./index\.md\#tk)* is installed and available as
well\.

Without *[Tk](\.\./\.\./\.\./index\.md\#tk)* the only way to invoke the installer
are to open a DOS window, i\.e\. __cmd\.exe__, and then to invoke

    \./installer\.tcl

inside it\.

## <a name='subsection5'></a>Critcl & Accelerators

While the majority of Tcllib consists of packages written in pure Tcl a number
of packages also have *accelerators* associated with them\. These are
__critcl__\-based C packages whose use will boost the performance of the
packages using them\. These accelerators are optional, and they are not installed
by default\.

To build the accelerators the normally optional dependency on __critcl__
becomes required\.

To build and install Tcllib with the accelerators in a Unix\-like environment
invoke:

    \./configure
    make critcl \# This builds the shared library holding
                \# the accelerators
    make install

The underlying tool is "sak\.tcl" in the toplevel directory of Tcllib and the
command __make critcl__ is just a wrapper around

    \./sak\.tcl critcl

Therefore in a Windows environment instead invoke

    \./sak\.tcl critcl
    \./installer\.tcl

from within a DOS window, i\.e\. __cmd\.exe__\.

## <a name='subsection6'></a>Tooling

The core of Tcllib's build system is the script "installer\.tcl" found in the
toplevel directory of a checkout or release\.

The

    configure ; make install

setup available to developers on Unix\-like systems is just a wrapper around it\.
To go beyond the standard embodied in the wrapper it is necessary to directly
invoke this script\.

On Windows system using it directly is the only way to invoke it\.

For basic help invoke it as

    \./installer\.tcl \-help

This will print a short list of all the available options to the standard output
channel\.

The commands associated with the various *install* targets in the
*Makefile\.in* for Unix can be used as additional examples on how to use this
tool as well\.







|








|
















|

















|
|
|





|



|
|




















|







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
\(*Windows*\)\.

## <a name='subsection3'></a>Installing on Unix

For *Unix*\-like environments Tcllib comes with the standard set of files to
make

    ./configure
    make install

a suitable way of installing it\. This is a standard non\-interactive install
automatically figuring out where to place everything, i\.e\. packages,
applications, and the manpages\.

To get a graphical installer invoke

    ./installer.tcl

instead\.

## <a name='subsection4'></a>Installing on Windows

In a Windows environment we have the __installer\.tcl__ script to perform
installation\.

If the desired __tclsh__ is associated "\.tcl" files then double\-clicking /
opening the __installer\.tcl__ is enough to invoke it in graphical mode\. This
assumes that *[Tk](\.\./\.\./\.\./index\.md\#tk)* is installed and available as
well\.

Without *[Tk](\.\./\.\./\.\./index\.md\#tk)* the only way to invoke the installer
are to open a DOS window, i\.e\. __cmd\.exe__, and then to invoke

    ./installer.tcl

inside it\.

## <a name='subsection5'></a>Critcl & Accelerators

While the majority of Tcllib consists of packages written in pure Tcl a number
of packages also have *accelerators* associated with them\. These are
__critcl__\-based C packages whose use will boost the performance of the
packages using them\. These accelerators are optional, and they are not installed
by default\.

To build the accelerators the normally optional dependency on __critcl__
becomes required\.

To build and install Tcllib with the accelerators in a Unix\-like environment
invoke:

    ./configure
    make critcl # This builds the shared library holding
                # the accelerators
    make install

The underlying tool is "sak\.tcl" in the toplevel directory of Tcllib and the
command __make critcl__ is just a wrapper around

    ./sak.tcl critcl

Therefore in a Windows environment instead invoke

    ./sak.tcl critcl
    ./installer.tcl

from within a DOS window, i\.e\. __cmd\.exe__\.

## <a name='subsection6'></a>Tooling

The core of Tcllib's build system is the script "installer\.tcl" found in the
toplevel directory of a checkout or release\.

The

    configure ; make install

setup available to developers on Unix\-like systems is just a wrapper around it\.
To go beyond the standard embodied in the wrapper it is necessary to directly
invoke this script\.

On Windows system using it directly is the only way to invoke it\.

For basic help invoke it as

    ./installer.tcl -help

This will print a short list of all the available options to the standard output
channel\.

The commands associated with the various *install* targets in the
*Makefile\.in* for Unix can be used as additional examples on how to use this
tool as well\.
Changes to embedded/md/tcllib/files/devdoc/tcllib_releasemgr.md.
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# <a name='section2'></a>Tools

The "sak\.tcl" script in the toplevel directory of a Tcllib checkout is the one
tool used by the release manager to perform its [Tasks](#section3)\.

The main commands to be used are

    sak\.tcl validate
    sak\.tcl test run
    sak\.tcl review
    sak\.tcl readme
    sak\.tcl localdoc
    sak\.tcl release

More detail will be provided in the explanations of the various
[Tasks](#section3)\.

# <a name='section3'></a>Tasks

## <a name='subsection1'></a>Start a release candidate







|
|
|
|
|
|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# <a name='section2'></a>Tools

The "sak\.tcl" script in the toplevel directory of a Tcllib checkout is the one
tool used by the release manager to perform its [Tasks](#section3)\.

The main commands to be used are

    sak.tcl validate
    sak.tcl test run
    sak.tcl review
    sak.tcl readme
    sak.tcl localdoc
    sak.tcl release

More detail will be provided in the explanations of the various
[Tasks](#section3)\.

# <a name='section3'></a>Tasks

## <a name='subsection1'></a>Start a release candidate
Changes to embedded/md/tcllib/files/devdoc/tcllib_sources.md.
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

For the curious \(or a developer\-to\-be\), the sources are managed by the [Fossil
SCM](http://www\.fossil\-scm\.org)\. Binaries for popular platforms can be found
directly at its [download page](http://www\.fossil\-scm\.org/download\.html)\.

With that tool available the full history can be retrieved via:

    fossil clone  http://core\.tcl\-lang\.org/tcllib  tcllib\.fossil

followed by

    mkdir tcllib
    cd tcllib
    fossil open \.\./tcllib\.fossil

to get a checkout of the head of the trunk\.







|





|


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

For the curious \(or a developer\-to\-be\), the sources are managed by the [Fossil
SCM](http://www\.fossil\-scm\.org)\. Binaries for popular platforms can be found
directly at its [download page](http://www\.fossil\-scm\.org/download\.html)\.

With that tool available the full history can be retrieved via:

    fossil clone  http://core.tcl-lang.org/tcllib  tcllib.fossil

followed by

    mkdir tcllib
    cd tcllib
    fossil open ../tcllib.fossil

to get a checkout of the head of the trunk\.
Changes to embedded/md/tcllib/files/modules/aes/aes.md.
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    randomly and transmitted as the first block of the output\. Errors in
    encryption affect the current block and the next block after which the
    cipher will correct itself\. CBC is the most commonly used mode in software
    encryption\. This is the default mode of operation for this module\.

# <a name='section5'></a>EXAMPLES

    % set nil\_block \[string repeat \\\\0 16\]
    % aes::aes \-hex \-mode cbc \-dir encrypt \-key $nil\_block $nil\_block
    66e94bd4ef8a2c3b884cfa59ca342b2e

    set Key \[aes::Init cbc $sixteen\_bytes\_key\_data $sixteen\_byte\_iv\]
    append ciphertext \[aes::Encrypt $Key $plaintext\]
    append ciphertext \[aes::Encrypt $Key $additional\_plaintext\]
    aes::Final $Key

# <a name='section6'></a>REFERENCES

  1. "Advanced Encryption Standard", Federal Information Processing Standards
     Publication 197, 2001
     \([http://csrc\.nist\.gov/publications/fips/fips197/fips\-197\.pdf](http://csrc\.nist\.gov/publications/fips/fips197/fips\-197\.pdf)\)







|
|


|
|
|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    randomly and transmitted as the first block of the output\. Errors in
    encryption affect the current block and the next block after which the
    cipher will correct itself\. CBC is the most commonly used mode in software
    encryption\. This is the default mode of operation for this module\.

# <a name='section5'></a>EXAMPLES

    % set nil_block [string repeat \\0 16]
    % aes::aes -hex -mode cbc -dir encrypt -key $nil_block $nil_block
    66e94bd4ef8a2c3b884cfa59ca342b2e

    set Key [aes::Init cbc $sixteen_bytes_key_data $sixteen_byte_iv]
    append ciphertext [aes::Encrypt $Key $plaintext]
    append ciphertext [aes::Encrypt $Key $additional_plaintext]
    aes::Final $Key

# <a name='section6'></a>REFERENCES

  1. "Advanced Encryption Standard", Federal Information Processing Standards
     Publication 197, 2001
     \([http://csrc\.nist\.gov/publications/fips/fips197/fips\-197\.pdf](http://csrc\.nist\.gov/publications/fips/fips197/fips\-197\.pdf)\)
Changes to embedded/md/tcllib/files/modules/amazon-s3/S3.md.
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
      * __\-prefix__

        This names the prefix that will be added to all resources\. That is, it
        is the remote equivalent of __\-directory__\. If it is not specified,
        the root of the bucket will be treated as the remote directory\. An
        example may clarify\.

            S3::Push \-bucket test \-directory /tmp/xyz \-prefix hello/world

        In this example, /tmp/xyz/pdq\.html will be stored as
        http://s3\.amazonaws\.com/test/hello/world/pdq\.html in Amazon's servers\.
        Also, /tmp/xyz/abc/def/Hello will be stored as
        http://s3\.amazonaws\.com/test/hello/world/abc/def/Hello in Amazon's
        servers\. Without the __\-prefix__ option, /tmp/xyz/pdq\.html would be
        stored as http://s3\.amazonaws\.com/test/pdq\.html\.







|







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
      * __\-prefix__

        This names the prefix that will be added to all resources\. That is, it
        is the remote equivalent of __\-directory__\. If it is not specified,
        the root of the bucket will be treated as the remote directory\. An
        example may clarify\.

            S3::Push -bucket test -directory /tmp/xyz -prefix hello/world

        In this example, /tmp/xyz/pdq\.html will be stored as
        http://s3\.amazonaws\.com/test/hello/world/pdq\.html in Amazon's servers\.
        Also, /tmp/xyz/abc/def/Hello will be stored as
        http://s3\.amazonaws\.com/test/hello/world/abc/def/Hello in Amazon's
        servers\. Without the __\-prefix__ option, /tmp/xyz/pdq\.html would be
        stored as http://s3\.amazonaws\.com/test/pdq\.html\.
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
    delete files that have been deleted from one place but not the other yet not
    copying changed files is untested\.

# <a name='section7'></a>USAGE SUGGESTIONS

To fetch a "directory" out of a bucket, make changes, and store it back:

    file mkdir \./tempfiles
    S3::Pull \-bucket sample \-prefix of/interest \-directory \./tempfiles \\
      \-timestamp aws
    do\_my\_process \./tempfiles other arguments
    S3::Push \-bucket sample \-prefix of/interest \-directory \./tempfiles \\
      \-compare newer \-delete true

To delete files locally that were deleted off of S3 but not otherwise update
files:

    S3::Pull \-bucket sample \-prefix of/interest \-directory \./myfiles \\
      \-compare never \-delete true

# <a name='section8'></a>FUTURE DEVELOPMENTS

The author intends to work on several additional projects related to this
package, in addition to finishing the unfinished features\.

First, a command\-line program allowing browsing of buckets and transfer of files







|
|
|
|
|
|




|
|







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
    delete files that have been deleted from one place but not the other yet not
    copying changed files is untested\.

# <a name='section7'></a>USAGE SUGGESTIONS

To fetch a "directory" out of a bucket, make changes, and store it back:

    file mkdir ./tempfiles
    S3::Pull -bucket sample -prefix of/interest -directory ./tempfiles \
      -timestamp aws
    do_my_process ./tempfiles other arguments
    S3::Push -bucket sample -prefix of/interest -directory ./tempfiles \
      -compare newer -delete true

To delete files locally that were deleted off of S3 but not otherwise update
files:

    S3::Pull -bucket sample -prefix of/interest -directory ./myfiles \
      -compare never -delete true

# <a name='section8'></a>FUTURE DEVELOPMENTS

The author intends to work on several additional projects related to this
package, in addition to finishing the unfinished features\.

First, a command\-line program allowing browsing of buckets and transfer of files
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section10'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *amazon\-s3* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|







1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section10'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *amazon\-s3* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/amazon-s3/xsxp.md.
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
      * %PCDATA?

        is like %PCDATA, but returns an empty string if no PCDATA is found\.

    For example, to fetch the first bold text from the fifth paragraph of the
    body of your HTML file,

        xsxp::fetch $pxml \{body p\#4 b\} %PCDATA

  - <a name='3'></a>__xsxp::fetchall__ *pxml\_list* *path* ?*part*?

    This iterates over each PXML in *pxml\_list* \(which must be a list of
    pxmls\) selecting the indicated path from it, building a new list with the
    selected data, and returning that new list\.








|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
      * %PCDATA?

        is like %PCDATA, but returns an empty string if no PCDATA is found\.

    For example, to fetch the first bold text from the fifth paragraph of the
    body of your HTML file,

        xsxp::fetch $pxml {body p#4 b} %PCDATA

  - <a name='3'></a>__xsxp::fetchall__ *pxml\_list* *path* ?*part*?

    This iterates over each PXML in *pxml\_list* \(which must be a list of
    pxmls\) selecting the indicated path from it, building a new list with the
    selected data, and returning that new list\.

Changes to embedded/md/tcllib/files/modules/base64/ascii85.md.
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

    Ascii85 decodes the given *string* and returns the binary data\. The
    decoder ignores whitespace in the string, as well as tabs and newlines\.

# <a name='section2'></a>EXAMPLES

    % ascii85::encode "Hello, world"
    87cURD\_\*\#TDfTZ\)

    % ascii85::encode \[string repeat xyz 24\]
    G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G
    ^4U\[H$X^\\H?a^\]
    % ascii85::encode \-wrapchar "" \[string repeat xyz 24\]
    G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]G^4U\[H$X^\\H?a^\]

    \# NOTE: ascii85 encodes BINARY strings\.
    % set chemical \[encoding convertto utf\-8 "C\\u2088H\\u2081\\u2080N\\u2084O\\u2082"\]
    % set encoded \[ascii85::encode $chemical\]
    6fN\]R8E,5Pidu\\UiduhZidua
    % set caffeine \[encoding convertfrom utf\-8 \[ascii85::decode $encoded\]\]

# <a name='section3'></a>References

  1. [http://en\.wikipedia\.org/wiki/Ascii85](http://en\.wikipedia\.org/wiki/Ascii85)

  1. Postscript Language Reference Manual, 3rd Edition, page 131\.
     [http://www\.adobe\.com/devnet/postscript/pdfs/PLRM\.pdf](http://www\.adobe\.com/devnet/postscript/pdfs/PLRM\.pdf)







|

|
|
|
|
|

|
|
|
|
|







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

    Ascii85 decodes the given *string* and returns the binary data\. The
    decoder ignores whitespace in the string, as well as tabs and newlines\.

# <a name='section2'></a>EXAMPLES

    % ascii85::encode "Hello, world"
    87cURD_*#TDfTZ)

    % ascii85::encode [string repeat xyz 24]
    G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G
    ^4U[H$X^\H?a^]
    % ascii85::encode -wrapchar "" [string repeat xyz 24]
    G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]G^4U[H$X^\H?a^]

    # NOTE: ascii85 encodes BINARY strings.
    % set chemical [encoding convertto utf-8 "C\u2088H\u2081\u2080N\u2084O\u2082"]
    % set encoded [ascii85::encode $chemical]
    6fN]R8E,5Pidu\UiduhZidua
    % set caffeine [encoding convertfrom utf-8 [ascii85::decode $encoded]]

# <a name='section3'></a>References

  1. [http://en\.wikipedia\.org/wiki/Ascii85](http://en\.wikipedia\.org/wiki/Ascii85)

  1. Postscript Language Reference Manual, 3rd Edition, page 131\.
     [http://www\.adobe\.com/devnet/postscript/pdfs/PLRM\.pdf](http://www\.adobe\.com/devnet/postscript/pdfs/PLRM\.pdf)
Changes to embedded/md/tcllib/files/modules/base64/base64.md.
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
    ignores whitespace in the string\.

# <a name='section2'></a>EXAMPLES

    % base64::encode "Hello, world"
    SGVsbG8sIHdvcmxk

    % base64::encode \[string repeat xyz 20\]
    eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6
    eHl6eHl6eHl6
    % base64::encode \-wrapchar "" \[string repeat xyz 20\]
    eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6

    \# NOTE: base64 encodes BINARY strings\.
    % set chemical \[encoding convertto utf\-8 "C\\u2088H\\u2081\\u2080N\\u2084O\\u2082"\]
    % set encoded \[base64::encode $chemical\]
    Q\+KCiEjigoHigoBO4oKET\+KCgg==
    % set caffeine \[encoding convertfrom utf\-8 \[base64::decode $encoded\]\]

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *base64* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|


|


|
|
|
|
|







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
    ignores whitespace in the string\.

# <a name='section2'></a>EXAMPLES

    % base64::encode "Hello, world"
    SGVsbG8sIHdvcmxk

    % base64::encode [string repeat xyz 20]
    eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6
    eHl6eHl6eHl6
    % base64::encode -wrapchar "" [string repeat xyz 20]
    eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6eHl6

    # NOTE: base64 encodes BINARY strings.
    % set chemical [encoding convertto utf-8 "C\u2088H\u2081\u2080N\u2084O\u2082"]
    % set encoded [base64::encode $chemical]
    Q+KCiEjigoHigoBO4oKET+KCgg==
    % set caffeine [encoding convertfrom utf-8 [base64::decode $encoded]]

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *base64* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/base64/uuencode.md.
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
    The uuencoded data header line contains a suggested permissions bit pattern
    expressed as an octal string\. To change the default of 0644 you can set this
    option\. For instance, 0755 would be suitable for an executable\. See
    __chmod\(1\)__\.

# <a name='section3'></a>EXAMPLES

    % set d \[uuencode::encode "Hello World\!"\]
    2&5L;&\\\\@5V\]R;&0A

    % uuencode::uudecode $d
    Hello World\!

    % set d \[uuencode::uuencode \-name hello\.txt "Hello World"\]
    begin 644 hello\.txt
    \+2&5L;&\\@5V\]R;&0\`
    \`

    end

    % uuencode::uudecode $d
    \{hello\.txt 644 \{Hello World\}\}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *base64* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|


|

|
|
|
<
>



|







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
    The uuencoded data header line contains a suggested permissions bit pattern
    expressed as an octal string\. To change the default of 0644 you can set this
    option\. For instance, 0755 would be suitable for an executable\. See
    __chmod\(1\)__\.

# <a name='section3'></a>EXAMPLES

    % set d [uuencode::encode "Hello World!"]
    2&5L;&\\@5V]R;&0A

    % uuencode::uudecode $d
    Hello World!

    % set d [uuencode::uuencode -name hello.txt "Hello World"]
    begin 644 hello.txt
    +2&5L;&\@5V]R;&0`

    `
    end

    % uuencode::uudecode $d
    {hello.txt 644 {Hello World}}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *base64* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/base64/yencode.md.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

  - \-crc32 boolean

    The yEnc specification recommends the inclusion of a cyclic redundancy check
    value in the footer\. Use this option to change the default from *true* to
    *false*\.

    % set d \[yencode::yencode \-file testfile\.txt\]
    =ybegin line=128 size=584 name=testfile\.txt
     \-o\- data not shown \-o\-
    =yend size=584 crc32=ded29f4f

# <a name='section3'></a>References

  1. [http://www\.yenc\.org/yenc\-draft\.1\.3\.txt](http://www\.yenc\.org/yenc\-draft\.1\.3\.txt)

# <a name='section4'></a>Bugs, Ideas, Feedback







|
|
|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

  - \-crc32 boolean

    The yEnc specification recommends the inclusion of a cyclic redundancy check
    value in the footer\. Use this option to change the default from *true* to
    *false*\.

    % set d [yencode::yencode -file testfile.txt]
    =ybegin line=128 size=584 name=testfile.txt
     -o- data not shown -o-
    =yend size=584 crc32=ded29f4f

# <a name='section3'></a>References

  1. [http://www\.yenc\.org/yenc\-draft\.1\.3\.txt](http://www\.yenc\.org/yenc\-draft\.1\.3\.txt)

# <a name='section4'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/bench/bench_lang_intro.md.
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
number of commands to support the declaration of benchmarks\. A document written
in this language is a Tcl script and has the same syntax\.

## <a name='subsection2'></a>Basics

One of the most simplest benchmarks which can be written in bench is

    bench \-desc LABEL \-body \{
        set a b
    \}


This code declares a benchmark named __LABEL__ which measures the time it
takes to assign a value to a variable\. The Tcl code doing this assignment is the
__\-body__ of the benchmark\.

## <a name='subsection3'></a>Pre\- and postprocessing

Our next example demonstrates how to declare *initialization* and
*[cleanup](\.\./\.\./\.\./\.\./index\.md\#cleanup)* code, i\.e\. code computing
information for the use of the __\-body__, and for releasing such resources
after the measurement is done\. They are the __\-pre__\- and the
__\-post__\-body, respectively\.

In our example, directly drawn from the benchmark suite of Tcllib's
__[aes](\.\./aes/aes\.md)__ package, the concrete initialization code
constructs the key schedule used by the encryption command whose speed we
measure, and the cleanup code releases any resources bound to that schedule\.

    bench \-desc "AES\-$\{len\} ECB encryption core" __\-pre__ \{
        set key \[aes::Init ecb $k $i\]
    \} \-body \{
        aes::Encrypt $key $p
    \} __\-post__ \{
        aes::Final $key
    \}


## <a name='subsection4'></a>Advanced pre\- and postprocessing

Our last example again deals with initialization and cleanup code\. To see the
difference to the regular initialization and cleanup discussed in the last
section it is necessary to know a bit more about how bench actually measures the
speed of the the __\-body__\.







|

<
>


















|
|
|

|

<
>







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
number of commands to support the declaration of benchmarks\. A document written
in this language is a Tcl script and has the same syntax\.

## <a name='subsection2'></a>Basics

One of the most simplest benchmarks which can be written in bench is

    bench -desc LABEL -body {
        set a b

    }

This code declares a benchmark named __LABEL__ which measures the time it
takes to assign a value to a variable\. The Tcl code doing this assignment is the
__\-body__ of the benchmark\.

## <a name='subsection3'></a>Pre\- and postprocessing

Our next example demonstrates how to declare *initialization* and
*[cleanup](\.\./\.\./\.\./\.\./index\.md\#cleanup)* code, i\.e\. code computing
information for the use of the __\-body__, and for releasing such resources
after the measurement is done\. They are the __\-pre__\- and the
__\-post__\-body, respectively\.

In our example, directly drawn from the benchmark suite of Tcllib's
__[aes](\.\./aes/aes\.md)__ package, the concrete initialization code
constructs the key schedule used by the encryption command whose speed we
measure, and the cleanup code releases any resources bound to that schedule\.

    bench -desc "AES-${len} ECB encryption core" __-pre__ {
        set key [aes::Init ecb $k $i]
    } -body {
        aes::Encrypt $key $p
    } __-post__ {
        aes::Final $key

    }

## <a name='subsection4'></a>Advanced pre\- and postprocessing

Our last example again deals with initialization and cleanup code\. To see the
difference to the regular initialization and cleanup discussed in the last
section it is necessary to know a bit more about how bench actually measures the
speed of the the __\-body__\.
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
example we used above to demonstrate the necessity for the advanced
initialization and cleanup\. Its concrete initialization code constructs a
variable refering to a set with specific properties \(The set has a string
representation, which is shared\) affecting the speed of the inclusion command,
and the cleanup code releases the temporary variables created by this
initialization\.

    bench \-desc "set include, missing <SC> x$times $n" __\-ipre__ \{
        set A $sx\($times,$n\)
        set B $A
    \} \-body \{
        struct::set include A x
    \} __\-ipost__ \{
        unset A B
    \}


# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of benchmarks, he should be fortified enough to be able to understand the formal
*bench language specfication*\. It will also serve as the detailed
specification and cheat sheet for all available commands and their syntax\.







|
|

|

|

<
>







127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
example we used above to demonstrate the necessity for the advanced
initialization and cleanup\. Its concrete initialization code constructs a
variable refering to a set with specific properties \(The set has a string
representation, which is shared\) affecting the speed of the inclusion command,
and the cleanup code releases the temporary variables created by this
initialization\.

    bench -desc "set include, missing <SC> x$times $n" __-ipre__ {
        set A $sx($times,$n)
        set B $A
    } -body {
        struct::set include A x
    } __-ipost__ {
        unset A B

    }

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of benchmarks, he should be fortified enough to be able to understand the formal
*bench language specfication*\. It will also serve as the detailed
specification and cheat sheet for all available commands and their syntax\.
Changes to embedded/md/tcllib/files/modules/blowfish/blowfish.md.
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    randomly and transmitted as the first block of the output\. Errors in
    encryption affect the current block and the next block after which the
    cipher will correct itself\. CBC is the most commonly used mode in software
    encryption\.

# <a name='section5'></a>EXAMPLES

    % blowfish::blowfish \-hex \-mode ecb \-dir encrypt \-key secret01 "hello, world\!"
    d0d8f27e7a374b9e2dbd9938dd04195a

    set Key \[blowfish::Init cbc $eight\_bytes\_key\_data $eight\_byte\_iv\]
    append ciphertext \[blowfish::Encrypt $Key $plaintext\]
    append ciphertext \[blowfish::Encrypt $Key $additional\_plaintext\]
    blowfish::Final $Key

# <a name='section6'></a>REFERENCES

  1. Schneier, B\. "Applied Cryptography, 2nd edition", 1996, ISBN 0\-471\-11709\-9,
     pub\. John Wiley & Sons\.








|


|
|
|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    randomly and transmitted as the first block of the output\. Errors in
    encryption affect the current block and the next block after which the
    cipher will correct itself\. CBC is the most commonly used mode in software
    encryption\.

# <a name='section5'></a>EXAMPLES

    % blowfish::blowfish -hex -mode ecb -dir encrypt -key secret01 "hello, world!"
    d0d8f27e7a374b9e2dbd9938dd04195a

    set Key [blowfish::Init cbc $eight_bytes_key_data $eight_byte_iv]
    append ciphertext [blowfish::Encrypt $Key $plaintext]
    append ciphertext [blowfish::Encrypt $Key $additional_plaintext]
    blowfish::Final $Key

# <a name='section6'></a>REFERENCES

  1. Schneier, B\. "Applied Cryptography, 2nd edition", 1996, ISBN 0\-471\-11709\-9,
     pub\. John Wiley & Sons\.

Changes to embedded/md/tcllib/files/modules/cmdline/cmdline.md.
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

Starting with version 1\.5 all errors thrown by the package have a proper
__::errorCode__ for use with Tcl's __[try](\.\./try/tcllib\_try\.md)__
command\. This code always has the word __CMDLINE__ as its first element\.

# <a name='section4'></a>EXAMPLES

            package require Tcl 8\.5
            package require try         ;\# Tcllib\.
            package require cmdline 1\.5 ;\# First version with proper error\-codes\.

            \# Notes:
            \# \- Tcl 8\.6\+ has 'try' as a builtin command and therefore does not
            \#   need the 'try' package\.
            \# \- Before Tcl 8\.5 we cannot support 'try' and have to use 'catch'\.
            \#   This then requires a dedicated test \(if\) on the contents of
            \#   ::errorCode to separate the CMDLINE USAGE signal from actual errors\.

            set options \{
                \{a          "set the atime only"\}
                \{m          "set the mtime only"\}
                \{c          "do not create non\-existent files"\}
                \{r\.arg  ""  "use time from ref\_file"\}
                \{t\.arg  \-1  "use specified time"\}
            \}

            set usage ": MyCommandName \\\[options\] filename \.\.\.\\noptions:"

            try \{
                array set params \[::cmdline::getoptions argv $options $usage\]
            \} trap \{CMDLINE USAGE\} \{msg o\} \{
                \# Trap the usage signal, print the message, and exit the application\.
                \# Note: Other errors are not caught and passed through to higher levels\!
    	    puts $msg
    	    exit 1
            \}

            if \{  $params\(a\) \} \{ set set\_atime "true" \}

            set has\_t \[expr \{$params\(t\) \!= \-1\}\]
            set has\_r \[expr \{\[string length $params\(r\)\] > 0\}\]
            if \{$has\_t && $has\_r\} \{
                return \-code error "Cannot specify both \-r and \-t"
            \} elseif \{$has\_t\} \{
    	    \.\.\.
            \}


This example, taken \(and slightly modified\) from the package
__[fileutil](\.\./fileutil/fileutil\.md)__, shows how to use cmdline\.
First, a list of options is created, then the 'args' list is passed to cmdline
for processing\. Subsequently, different options are checked to see if they have
been passed to the script, and what their value is\.








|
|
|

|
|
|
|
|
|

|
|
|
|
|
|
<
>
|

|
|
|
|
|


<
|
|
>
|
|
|
|
|
|
<
>







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

Starting with version 1\.5 all errors thrown by the package have a proper
__::errorCode__ for use with Tcl's __[try](\.\./try/tcllib\_try\.md)__
command\. This code always has the word __CMDLINE__ as its first element\.

# <a name='section4'></a>EXAMPLES

            package require Tcl 8.5
            package require try         ;# Tcllib.
            package require cmdline 1.5 ;# First version with proper error-codes.

            # Notes:
            # - Tcl 8.6+ has 'try' as a builtin command and therefore does not
            #   need the 'try' package.
            # - Before Tcl 8.5 we cannot support 'try' and have to use 'catch'.
            #   This then requires a dedicated test (if) on the contents of
            #   ::errorCode to separate the CMDLINE USAGE signal from actual errors.

            set options {
                {a          "set the atime only"}
                {m          "set the mtime only"}
                {c          "do not create non-existent files"}
                {r.arg  ""  "use time from ref_file"}
                {t.arg  -1  "use specified time"}

            }
            set usage ": MyCommandName \[options] filename ...\noptions:"

            try {
                array set params [::cmdline::getoptions argv $options $usage]
            } trap {CMDLINE USAGE} {msg o} {
                # Trap the usage signal, print the message, and exit the application.
                # Note: Other errors are not caught and passed through to higher levels!
    	    puts $msg
    	    exit 1

            }

            if {  $params(a) } { set set_atime "true" }
            set has_t [expr {$params(t) != -1}]
            set has_r [expr {[string length $params(r)] > 0}]
            if {$has_t && $has_r} {
                return -code error "Cannot specify both -r and -t"
            } elseif {$has_t} {
    	    ...

            }

This example, taken \(and slightly modified\) from the package
__[fileutil](\.\./fileutil/fileutil\.md)__, shows how to use cmdline\.
First, a list of options is created, then the 'args' list is passed to cmdline
for processing\. Subsequently, different options are checked to see if they have
been passed to the script, and what their value is\.

Changes to embedded/md/tcllib/files/modules/comm/comm.md.
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
server for the communication path\. As a result, __comm__ works with multiple
interpreters, works on Windows and Macintosh systems, and provides control over
the remote execution path\.

These commands work just like __[send](\.\./\.\./\.\./\.\./index\.md\#send)__ and
__winfo interps__ :

    ::comm::comm send ?\-async? id cmd ?arg arg \.\.\.?
    ::comm::comm interps

This is all that is really needed to know in order to use __comm__

## <a name='subsection1'></a>Commands

The package initializes __::comm::comm__ as the default *chan*\.







|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
server for the communication path\. As a result, __comm__ works with multiple
interpreters, works on Windows and Macintosh systems, and provides control over
the remote execution path\.

These commands work just like __[send](\.\./\.\./\.\./\.\./index\.md\#send)__ and
__winfo interps__ :

    ::comm::comm send ?-async? id cmd ?arg arg ...?
    ::comm::comm interps

This is all that is really needed to know in order to use __comm__

## <a name='subsection1'></a>Commands

The package initializes __::comm::comm__ as the default *chan*\.
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
If you find that __::comm::comm send__ doesn't work for a particular
command, try the same thing with Tk's send and see if the result is different\.
If there is a problem, please report it\. For instance, there was had one report
that this command produced an error\. Note that the equivalent
__[send](\.\./\.\./\.\./\.\./index\.md\#send)__ command also produces the same
error\.

    % ::comm::comm send id llength \{a b c\}
    wrong \# args: should be "llength list"
    % send name llength \{a b c\}
    wrong \# args: should be "llength list"

The __eval__ hook \(described below\) can be used to change from
__[send](\.\./\.\./\.\./\.\./index\.md\#send)__'s double eval semantics to single
eval semantics\.

## <a name='subsection3'></a>Multiple Channels








|
|
|
|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
If you find that __::comm::comm send__ doesn't work for a particular
command, try the same thing with Tk's send and see if the result is different\.
If there is a problem, please report it\. For instance, there was had one report
that this command produced an error\. Note that the equivalent
__[send](\.\./\.\./\.\./\.\./index\.md\#send)__ command also produces the same
error\.

    % ::comm::comm send id llength {a b c}
    wrong # args: should be "llength list"
    % send name llength {a b c}
    wrong # args: should be "llength list"

The __eval__ hook \(described below\) can be used to change from
__[send](\.\./\.\./\.\./\.\./index\.md\#send)__'s double eval semantics to single
eval semantics\.

## <a name='subsection3'></a>Multiple Channels

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

  - <a name='6'></a>__::comm::comm channels__

    This lists all the channels allocated in this Tcl interpreter\.

The default configuration parameters for a new channel are:

    "\-port 0 \-local 1 \-listen 0 \-silent 0"

The default channel __::comm::comm__ is created with:

    "::comm::comm new ::comm::comm \-port 0 \-local 1 \-listen 1 \-silent 0"

## <a name='subsection4'></a>Channel Configuration

The __config__ method acts similar to __fconfigure__ in that it sets or
queries configuration variables associated with a channel\.

  - <a name='7'></a>__::comm::comm config__







|



|







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

  - <a name='6'></a>__::comm::comm channels__

    This lists all the channels allocated in this Tcl interpreter\.

The default configuration parameters for a new channel are:

    "-port 0 -local 1 -listen 0 -silent 0"

The default channel __::comm::comm__ is created with:

    "::comm::comm new ::comm::comm -port 0 -local 1 -listen 1 -silent 0"

## <a name='subsection4'></a>Channel Configuration

The __config__ method acts similar to __fconfigure__ in that it sets or
queries configuration variables associated with a channel\.

  - <a name='7'></a>__::comm::comm config__
389
390
391
392
393
394
395
396
397
398
399
400


401
402
403
404
405
406
407
    Variables: __chan__, __id__

    This hook is invoked before making a connection to the remote named in
    *id*\. An error return \(via
    __[error](\.\./\.\./\.\./\.\./index\.md\#error)__\) will abort the connection
    attempt with the error\. Example:

    % ::comm::comm hook connecting \{
        if \{\[string match \{\*\[02468\]\} $id\]\} \{
            error "Can't connect to even ids"
        \}
    \}


    % ::comm::comm send 10000 puts ok
    Connect to remote failed: Can't connect to even ids
    %

  - __connected__

    Variables: __chan__, __fid__, __id__, __host__, and







|
|

<
<
>
>







389
390
391
392
393
394
395
396
397
398


399
400
401
402
403
404
405
406
407
    Variables: __chan__, __id__

    This hook is invoked before making a connection to the remote named in
    *id*\. An error return \(via
    __[error](\.\./\.\./\.\./\.\./index\.md\#error)__\) will abort the connection
    attempt with the error\. Example:

    % ::comm::comm hook connecting {
        if {[string match {*[02468]} $id]} {
            error "Can't connect to even ids"


        }
    }
    % ::comm::comm send 10000 puts ok
    Connect to remote failed: Can't connect to even ids
    %

  - __connected__

    Variables: __chan__, __fid__, __id__, __host__, and
420
421
422
423
424
425
426
427
428
429
430
431


432
433
434
435
436
437
438

    Hook invoked when receiving an incoming connection, allowing arbitrary
    authentication over socket named by *fid*\. An error return \(via
    __[error](\.\./\.\./\.\./\.\./index\.md\#error)__\) will close the connection
    with the error\. Note that the peer is named by *remport* and *addr* but
    that the remote *id* is still unknown\. Example:

    ::comm::comm hook incoming \{
        if \{\[string match 127\.0\.0\.1 $addr\]\} \{
            error "I don't talk to myself"
        \}
    \}



  - __eval__

    Variables: __chan__, __id__, __cmd__, and __buffer__\.

    This hook is invoked after collecting a complete script from a remote but
    *before* evaluating it\. This allows complete control over the processing







|
|

<
<
>
>







420
421
422
423
424
425
426
427
428
429


430
431
432
433
434
435
436
437
438

    Hook invoked when receiving an incoming connection, allowing arbitrary
    authentication over socket named by *fid*\. An error return \(via
    __[error](\.\./\.\./\.\./\.\./index\.md\#error)__\) will close the connection
    with the error\. Note that the peer is named by *remport* and *addr* but
    that the remote *id* is still unknown\. Example:

    ::comm::comm hook incoming {
        if {[string match 127.0.0.1 $addr]} {
            error "I don't talk to myself"


        }
    }

  - __eval__

    Variables: __chan__, __id__, __cmd__, and __buffer__\.

    This hook is invoked after collecting a complete script from a remote but
    *before* evaluating it\. This allows complete control over the processing
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
    __break__ and __return \-code break__ *result* is supported, acting
    similarly to __return \{\}__ and __return \-code return__ *result*\.

    Examples:

      1. augmenting a command

    % ::comm::comm send \[::comm::comm self\] pid
    5013
    % ::comm::comm hook eval \{puts "going to execute $buffer"\}
    % ::comm::comm send \[::comm::comm self\] pid
    going to execute pid
    5013

      1. short circuiting a command

    % ::comm::comm hook eval \{puts "would have executed $buffer"; return 0\}
    % ::comm::comm send \[::comm::comm self\] pid
    would have executed pid
    0

      1. Replacing double eval semantics

    % ::comm::comm send \[::comm::comm self\] llength \{a b c\}
    wrong \# args: should be "llength list"
    % ::comm::comm hook eval \{return \[uplevel \#0 $buffer\]\}
    return \[uplevel \#0 $buffer\]
    % ::comm::comm send \[::comm::comm self\] llength \{a b c\}
    3

      1. Using a slave interpreter

    % interp create foo
    % ::comm::comm hook eval \{return \[foo eval $buffer\]\}
    % ::comm::comm send \[::comm::comm self\] set myvar 123
    123
    % set myvar
    can't read "myvar": no such variable
    % foo eval set myvar
    123

      1. Using a slave interpreter \(double eval\)

    % ::comm::comm hook eval \{return \[eval foo eval $buffer\]\}

      1. Subverting the script to execute

    % ::comm::comm hook eval \{
        switch \-\- $buffer \{
            a \{return A\-OK\}
            b \{return B\-OK\}
            default \{error "$buffer is a no\-no"\}
        \}
    \}


    % ::comm::comm send \[::comm::comm self\] pid
    pid is a no\-no
    % ::comm::comm send \[::comm::comm self\] a
    A\-OK

  - __reply__

    Variables: __chan__, __id__, __buffer__, __ret__, and
    __return\(\)__\.

    This hook is invoked after collecting a complete reply script from a remote







|

|
|





|
|





|
|
|
|
|





|
|








|



|
|
|
|
|
<
<
>
>
|
|
|
|







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
    __break__ and __return \-code break__ *result* is supported, acting
    similarly to __return \{\}__ and __return \-code return__ *result*\.

    Examples:

      1. augmenting a command

    % ::comm::comm send [::comm::comm self] pid
    5013
    % ::comm::comm hook eval {puts "going to execute $buffer"}
    % ::comm::comm send [::comm::comm self] pid
    going to execute pid
    5013

      1. short circuiting a command

    % ::comm::comm hook eval {puts "would have executed $buffer"; return 0}
    % ::comm::comm send [::comm::comm self] pid
    would have executed pid
    0

      1. Replacing double eval semantics

    % ::comm::comm send [::comm::comm self] llength {a b c}
    wrong # args: should be "llength list"
    % ::comm::comm hook eval {return [uplevel #0 $buffer]}
    return [uplevel #0 $buffer]
    % ::comm::comm send [::comm::comm self] llength {a b c}
    3

      1. Using a slave interpreter

    % interp create foo
    % ::comm::comm hook eval {return [foo eval $buffer]}
    % ::comm::comm send [::comm::comm self] set myvar 123
    123
    % set myvar
    can't read "myvar": no such variable
    % foo eval set myvar
    123

      1. Using a slave interpreter \(double eval\)

    % ::comm::comm hook eval {return [eval foo eval $buffer]}

      1. Subverting the script to execute

    % ::comm::comm hook eval {
        switch -- $buffer {
            a {return A-OK}
            b {return B-OK}
            default {error "$buffer is a no-no"}


        }
    }
    % ::comm::comm send [::comm::comm self] pid
    pid is a no-no
    % ::comm::comm send [::comm::comm self] a
    A-OK

  - __reply__

    Variables: __chan__, __id__, __buffer__, __ret__, and
    __return\(\)__\.

    This hook is invoked after collecting a complete reply script from a remote
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

    Variables: __chan__, __id__, and __reason__\.

    This hook is invoked when the connection to __id__ is lost\. Return value
    \(or thrown error\) is ignored\. *reason* is an explanatory string indicating
    why the connection was lost\. Example:

    ::comm::comm hook lost \{
        global myvar
        if \{$myvar\(id\) == $id\} \{
            myfunc
            return
        \}
    \}



## <a name='subsection10'></a>Unsupported

These interfaces may change or go away in subsequence releases\.

  - <a name='14'></a>__::comm::comm remoteid__

    Returns the *id* of the sender of the last remote command executed on this
    channel\. If used by a proc being invoked remotely, it must be called before
    any events are processed\. Otherwise, another command may get invoked and
    change the value\.

  - <a name='15'></a>__::comm::comm\_send__

    Invoking this procedure will substitute the Tk
    __[send](\.\./\.\./\.\./\.\./index\.md\#send)__ and __winfo interps__
    commands with these equivalents that use __::comm::comm__\.

    proc send \{args\} \{
        eval ::comm::comm send $args
    \}

    rename winfo tk\_winfo
    proc winfo \{cmd args\} \{
        if \{\!\[string match in\* $cmd\]\} \{
            return \[eval \[list tk\_winfo $cmd\] $args\]
        \}

        return \[::comm::comm interps\]
    \}


## <a name='subsection11'></a>Security

Starting with version 4\.6 of the package an option __\-socketcmd__ is
supported, allowing the user of a comm channel to specify which command to use
when opening a socket\. Anything which is API\-compatible with the builtin
__::socket__ \(the default\) can be used\.

The envisioned main use is the specification of the __tls::socket__ command,
see package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__, to secure the
communication\.

    \# Load and initialize tls
    package require tls
    tls::init  \-cafile /path/to/ca/cert \-keyfile \.\.\.

    \# Create secured comm channel
    ::comm::comm new SECURE \-socketcmd tls::socket \-listen 1
    \.\.\.

The sections [Execution Environment](#subsection6) and
[Callbacks](#subsection9) are also relevant to the security of the system,
providing means to restrict the execution to a specific environment, perform
additional authentication, and the like\.

## <a name='subsection12'></a>Blocking Semantics







|

|


<
<
>
>


















|

<
>
|
|
|
|
<
>
|
<
>












|

|

|
|
|







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

    Variables: __chan__, __id__, and __reason__\.

    This hook is invoked when the connection to __id__ is lost\. Return value
    \(or thrown error\) is ignored\. *reason* is an explanatory string indicating
    why the connection was lost\. Example:

    ::comm::comm hook lost {
        global myvar
        if {$myvar(id) == $id} {
            myfunc
            return


        }
    }

## <a name='subsection10'></a>Unsupported

These interfaces may change or go away in subsequence releases\.

  - <a name='14'></a>__::comm::comm remoteid__

    Returns the *id* of the sender of the last remote command executed on this
    channel\. If used by a proc being invoked remotely, it must be called before
    any events are processed\. Otherwise, another command may get invoked and
    change the value\.

  - <a name='15'></a>__::comm::comm\_send__

    Invoking this procedure will substitute the Tk
    __[send](\.\./\.\./\.\./\.\./index\.md\#send)__ and __winfo interps__
    commands with these equivalents that use __::comm::comm__\.

    proc send {args} {
        eval ::comm::comm send $args

    }
    rename winfo tk_winfo
    proc winfo {cmd args} {
        if {![string match in* $cmd]} {
            return [eval [list tk_winfo $cmd] $args]

        }
        return [::comm::comm interps]

    }

## <a name='subsection11'></a>Security

Starting with version 4\.6 of the package an option __\-socketcmd__ is
supported, allowing the user of a comm channel to specify which command to use
when opening a socket\. Anything which is API\-compatible with the builtin
__::socket__ \(the default\) can be used\.

The envisioned main use is the specification of the __tls::socket__ command,
see package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__, to secure the
communication\.

    # Load and initialize tls
    package require tls
    tls::init  -cafile /path/to/ca/cert -keyfile ...

    # Create secured comm channel
    ::comm::comm new SECURE -socketcmd tls::socket -listen 1
    ...

The sections [Execution Environment](#subsection6) and
[Callbacks](#subsection9) are also relevant to the security of the system,
providing means to restrict the execution to a specific environment, perform
additional authentication, and the like\.

## <a name='subsection12'></a>Blocking Semantics
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
    being computed the future will not try to deliver the result it got, but
    just destroy itself\. The future can be configured with a command to call
    when the invoker is lost\. This enables the user to implement an early abort
    of the long\-running operation, should this be supported by it\.

    An example:

    \# Procedure invoked by remote clients to run database operations\.
    proc select \{sql\} \{
        \# Signal the async generation of the result

        set future \[::comm::comm return\_async\]

        \# Generate an async db operation and tell it where to deliver the result\.

        set query \[db query \-command \[list $future return\] $sql\]

        \# Tell the database system which query to cancel if the connection
        \# goes away while it is running\.

        $future configure \-command \[list db cancel $query\]

        \# Note: The above will work without problem only if the async
        \# query will nover run its completion callback immediately, but
        \# only from the eventloop\. Because otherwise the future we wish to
        \# configure may already be gone\. If that is possible use 'catch'
        \# to prevent the error from propagating\.
        return
    \}


    The API of a future object is:

      * <a name='17'></a>__$future__ __return__ ?__\-code__ *code*? ?*value*?

        Use this method to tell the future that long\-running operation has
        completed\. Arguments are an optional return value \(defaults to the empty







|
|
|

|

|

|

|
|

|

|
|
|
|
|

<
>







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
    being computed the future will not try to deliver the result it got, but
    just destroy itself\. The future can be configured with a command to call
    when the invoker is lost\. This enables the user to implement an early abort
    of the long\-running operation, should this be supported by it\.

    An example:

    # Procedure invoked by remote clients to run database operations.
    proc select {sql} {
        # Signal the async generation of the result

        set future [::comm::comm return_async]

        # Generate an async db operation and tell it where to deliver the result.

        set query [db query -command [list $future return] $sql]

        # Tell the database system which query to cancel if the connection
        # goes away while it is running.

        $future configure -command [list db cancel $query]

        # Note: The above will work without problem only if the async
        # query will nover run its completion callback immediately, but
        # only from the eventloop. Because otherwise the future we wish to
        # configure may already be gone. If that is possible use 'catch'
        # to prevent the error from propagating.
        return

    }

    The API of a future object is:

      * <a name='17'></a>__$future__ __return__ ?__\-code__ *code*? ?*value*?

        Use this method to tell the future that long\-running operation has
        completed\. Arguments are an optional return value \(defaults to the empty
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
    being returned correctly from __comm send__\. This has been fixed by
    removing the extra level of indirection into the internal procedure
    __commSend__\. Also added propagation of the *errorCode* variable\. This
    means that these commands return exactly as they would with
    __[send](\.\./\.\./\.\./\.\./index\.md\#send)__:

    comm send id break
    catch \{comm send id break\}
    comm send id expr 1 / 0

    Added a new hook for reply messages\. Reworked method invocation to avoid the
    use of comm:\* procedures; this also cut the invocation time down by 40%\.
    Documented __comm config__ \(as this manual page still listed the defunct
    __comm init__\!\)








|







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
    being returned correctly from __comm send__\. This has been fixed by
    removing the extra level of indirection into the internal procedure
    __commSend__\. Also added propagation of the *errorCode* variable\. This
    means that these commands return exactly as they would with
    __[send](\.\./\.\./\.\./\.\./index\.md\#send)__:

    comm send id break
    catch {comm send id break}
    comm send id expr 1 / 0

    Added a new hook for reply messages\. Reworked method invocation to avoid the
    use of comm:\* procedures; this also cut the invocation time down by 40%\.
    Documented __comm config__ \(as this manual page still listed the defunct
    __comm init__\!\)

984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section3'></a>Author

John LoVerso, John@LoVerso\.Southborough\.MA\.US

*http://www\.opengroup\.org/~loverso/tcl\-tk/\#comm*








|

|







984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section3'></a>Author

John LoVerso, John@LoVerso\.Southborough\.MA\.US

*http://www\.opengroup\.org/~loverso/tcl\-tk/\#comm*

Changes to embedded/md/tcllib/files/modules/comm/comm_wire.md.
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
    __concat__enated together by the server to form the full script to
    execute on the server side\. This emulates the Tcl "eval" semantics\. In most
    cases it is best to have only one word in the list, a list containing the
    exact command\.

    Examples:

        \(a\)     \{send 1 \{\{array get tcl\_platform\}\}\}
        \(b\)     \{send 1 \{array get tcl\_platform\}\}
        \(c\)     \{send 1 \{array \{get tcl\_platform\}\}\}

        are all valid representations of the same command\. They are
        generated via

        \(a'\)    send \{array get tcl\_platform\}
        \(b'\)    send array get tcl\_platform
        \(c'\)    send array \{get tcl\_platform\}

        respectively

    Note that \(a\), generated by \(a'\), is the usual form, if only single commands
    are sent by the client\. For example constructed using
    __[list](\.\./\.\./\.\./\.\./index\.md\#list)__, if the command contains
    variable arguments\. Like

        send \[list array get $the\_variable\]

    These three instructions all invoke the script on the server side\. Their
    difference is in the treatment of result values, and thus determines if a
    reply is expected\.

      * __send__








|
|
|

|


|
|
|








|







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
    __concat__enated together by the server to form the full script to
    execute on the server side\. This emulates the Tcl "eval" semantics\. In most
    cases it is best to have only one word in the list, a list containing the
    exact command\.

    Examples:

        (a)     {send 1 {{array get tcl_platform}}}
        (b)     {send 1 {array get tcl_platform}}
        (c)     {send 1 {array {get tcl_platform}}}

        are all valid representations of the same command. They are
        generated via

        (a')    send {array get tcl_platform}
        (b')    send array get tcl_platform
        (c')    send array {get tcl_platform}

        respectively

    Note that \(a\), generated by \(a'\), is the usual form, if only single commands
    are sent by the client\. For example constructed using
    __[list](\.\./\.\./\.\./\.\./index\.md\#list)__, if the command contains
    variable arguments\. Like

        send [list array get $the_variable]

    These three instructions all invoke the script on the server side\. Their
    difference is in the treatment of result values, and thus determines if a
    reply is expected\.

      * __send__

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    Like the previous three command, however the tcl script in the payload is
    highly restricted\. It has to be a syntactically valid Tcl
    __[return](\.\./\.\./\.\./\.\./index\.md\#return)__ command\. This contains
    result code, value, error code, and error info\.

    Examples:

        \{reply 1 \{return \-code 0 \{\}\}\}
        \{reply 1 \{return \-code 0 \{osVersion 2\.4\.21\-99\-default byteOrder littleEndian machine i686 platform unix os Linux user andreask wordSize 4\}\}\}

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *comm* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    Like the previous three command, however the tcl script in the payload is
    highly restricted\. It has to be a syntactically valid Tcl
    __[return](\.\./\.\./\.\./\.\./index\.md\#return)__ command\. This contains
    result code, value, error code, and error info\.

    Examples:

        {reply 1 {return -code 0 {}}}
        {reply 1 {return -code 0 {osVersion 2.4.21-99-default byteOrder littleEndian machine i686 platform unix os Linux user andreask wordSize 4}}}

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *comm* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/control/control.md.
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    that debugging efforts can be independently controlled module by module\.

        % package require control
        % control::control assert enabled 1
        % namespace eval one namespace import ::control::assert
        % control::control assert enabled 0
        % namespace eval two namespace import ::control::assert
        % one::assert \{1 == 0\}
        assertion failed: 1 == 0
        % two::assert \{1 == 0\}

  - <a name='3'></a>__control::do__ *body* ?*option test*?

    The __[do](\.\./\.\./\.\./\.\./index\.md\#do)__ command evaluates the script
    *body* repeatedly *until* the expression *test* becomes true or as
    long as \(*while*\) *test* is true, depending on the value of *option*
    being __until__ or __while__\. If *option* and *test* are omitted







|

|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    that debugging efforts can be independently controlled module by module\.

        % package require control
        % control::control assert enabled 1
        % namespace eval one namespace import ::control::assert
        % control::control assert enabled 0
        % namespace eval two namespace import ::control::assert
        % one::assert {1 == 0}
        assertion failed: 1 == 0
        % two::assert {1 == 0}

  - <a name='3'></a>__control::do__ *body* ?*option test*?

    The __[do](\.\./\.\./\.\./\.\./index\.md\#do)__ command evaluates the script
    *body* repeatedly *until* the expression *test* becomes true or as
    long as \(*while*\) *test* is true, depending on the value of *option*
    being __until__ or __while__\. If *option* and *test* are omitted
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
\-code $code__\] within one of those script arguments for any value of *$code*
other than *ok*\. In this way, the commands of the __control__ package are
limited as compared to Tcl's built\-in control flow commands \(such as __if__,
__while__, etc\.\) and those control flow commands that can be provided by
packages coded in C\. An example of this difference:

    % package require control
    % proc a \{\} \{while 1 \{return \-code error a\}\}
    % proc b \{\} \{control::do \{return \-code error b\} while 1\}
    % catch a
    1
    % catch b
    0

# <a name='section4'></a>Bugs, Ideas, Feedback








|
|







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
\-code $code__\] within one of those script arguments for any value of *$code*
other than *ok*\. In this way, the commands of the __control__ package are
limited as compared to Tcl's built\-in control flow commands \(such as __if__,
__while__, etc\.\) and those control flow commands that can be provided by
packages coded in C\. An example of this difference:

    % package require control
    % proc a {} {while 1 {return -code error a}}
    % proc b {} {control::do {return -code error b} while 1}
    % catch a
    1
    % catch b
    0

# <a name='section4'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/crc/cksum.md.
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

    Returns the checksum value and releases any resources held by this token\.
    Once this command completes the token will be invalid\. The result is a 32
    bit integer value\.

# <a name='section5'></a>EXAMPLES

    % crc::cksum "Hello, World\!"
    2609532967

    % crc::cksum \-format 0x%X "Hello, World\!"
    0x9B8A5027

    % crc::cksum \-file cksum\.tcl
    1828321145

    % set tok \[crc::CksumInit\]
    % crc::CksumUpdate $tok "Hello, "
    % crc::CksumUpdate $tok "World\!"
    % crc::CksumFinal $tok
    2609532967

# <a name='section6'></a>AUTHORS

Pat Thoyts








|


|


|


|

|







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

    Returns the checksum value and releases any resources held by this token\.
    Once this command completes the token will be invalid\. The result is a 32
    bit integer value\.

# <a name='section5'></a>EXAMPLES

    % crc::cksum "Hello, World!"
    2609532967

    % crc::cksum -format 0x%X "Hello, World!"
    0x9B8A5027

    % crc::cksum -file cksum.tcl
    1828321145

    % set tok [crc::CksumInit]
    % crc::CksumUpdate $tok "Hello, "
    % crc::CksumUpdate $tok "World!"
    % crc::CksumFinal $tok
    2609532967

# <a name='section6'></a>AUTHORS

Pat Thoyts

Changes to embedded/md/tcllib/files/modules/crc/crc16.md.
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    flag is important when processing data from parameters\. If the binary data
    looks like one of the options given above then the data will be read as an
    option if this marker is not included\. Always use the *\-\-* option
    termination flag before giving the data argument\.

# <a name='section4'></a>EXAMPLES

    % crc::crc16 \-\- "Hello, World\!"
    64077

    % crc::crc\-ccitt \-\- "Hello, World\!"
    26586

    % crc::crc16 \-format 0x%X \-\- "Hello, World\!"
    0xFA4D

    % crc::crc16 \-file crc16\.tcl
    51675

# <a name='section5'></a>AUTHORS

Pat Thoyts

# <a name='section6'></a>Bugs, Ideas, Feedback







|


|


|


|







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    flag is important when processing data from parameters\. If the binary data
    looks like one of the options given above then the data will be read as an
    option if this marker is not included\. Always use the *\-\-* option
    termination flag before giving the data argument\.

# <a name='section4'></a>EXAMPLES

    % crc::crc16 -- "Hello, World!"
    64077

    % crc::crc-ccitt -- "Hello, World!"
    26586

    % crc::crc16 -format 0x%X -- "Hello, World!"
    0xFA4D

    % crc::crc16 -file crc16.tcl
    51675

# <a name='section5'></a>AUTHORS

Pat Thoyts

# <a name='section6'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/crc/crc32.md.
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

    Returns the checksum value and releases any resources held by this token\.
    Once this command completes the token will be invalid\. The result is a 32
    bit integer value\.

# <a name='section5'></a>EXAMPLES

    % crc::crc32 "Hello, World\!"
    3964322768

    % crc::crc32 \-format 0x%X "Hello, World\!"
    0xEC4AC3D0

    % crc::crc32 \-file crc32\.tcl
    483919716

    % set tok \[crc::Crc32Init\]
    % crc::Crc32Update $tok "Hello, "
    % crc::Crc32Update $tok "World\!"
    % crc::Crc32Final $tok
    3964322768

# <a name='section6'></a>AUTHORS

Pat Thoyts








|


|


|


|

|







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

    Returns the checksum value and releases any resources held by this token\.
    Once this command completes the token will be invalid\. The result is a 32
    bit integer value\.

# <a name='section5'></a>EXAMPLES

    % crc::crc32 "Hello, World!"
    3964322768

    % crc::crc32 -format 0x%X "Hello, World!"
    0xEC4AC3D0

    % crc::crc32 -file crc32.tcl
    483919716

    % set tok [crc::Crc32Init]
    % crc::Crc32Update $tok "Hello, "
    % crc::Crc32Update $tok "World!"
    % crc::Crc32Final $tok
    3964322768

# <a name='section6'></a>AUTHORS

Pat Thoyts

Changes to embedded/md/tcllib/files/modules/crc/sum.md.
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

  - \-format *string*

    Return the checksum using an alternative format template\.

# <a name='section4'></a>EXAMPLES

    % crc::sum "Hello, World\!"
    37287

    % crc::sum \-format 0x%X "Hello, World\!"
    0x91A7

    % crc::sum \-file sum\.tcl
    13392

# <a name='section5'></a>AUTHORS

Pat Thoyts

# <a name='section6'></a>Bugs, Ideas, Feedback







|


|


|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

  - \-format *string*

    Return the checksum using an alternative format template\.

# <a name='section4'></a>EXAMPLES

    % crc::sum "Hello, World!"
    37287

    % crc::sum -format 0x%X "Hello, World!"
    0x91A7

    % crc::sum -file sum.tcl
    13392

# <a name='section5'></a>AUTHORS

Pat Thoyts

# <a name='section6'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/cron/cron.md.
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
    *timecode*\. If *timecode* is expressed as an integer, the timecode is
    assumed to be in unixtime\. All other inputs will be interpreted by __clock
    scan__ and converted to unix time\. This task can be modified by subsequent
    calls to this package's commands by referencing *processname*\. If
    *processname* exists, it will be replaced\. If *processname* is not
    given, one is generated and returned by the command\.

        ::cron::at start\_coffee \{Tomorrow at 9:00am\}  \{remote::exec::coffeepot power on\}
        ::cron::at shutdown\_coffee \{Tomorrow at 12:00pm\}  \{remote::exec::coffeepot power off\}

  - <a name='2'></a>__::cron::cancel__ *processname*

    This command unregisters the process *processname* and cancels any pending
    commands\. Note: processname can be a process created by either
    __::cron::at__ or __::cron::every__\.

        ::cron::cancel check\_mail

  - <a name='3'></a>__::cron::every__ *processname* *frequency* *command*

    This command registers a *command* to be called at the interval of
    *frequency*\. *frequency* is given in seconds\. This task can be modified
    by subsequent calls to this package's commands by referencing
    *processname*\. If *processname* exists, it will be replaced\.

        ::cron::every check\_mail 900  ::imap\_client::check\_mail
        ::cron::every backup\_db  3600 \{::backup\_procedure ::mydb\}

  - <a name='4'></a>__::cron::in__ *?processname?* *timecode* *command*

    This command registers a *command* to be called after a delay of time
    specified by *timecode*\. *timecode* is expressed as an seconds\. This
    task can be modified by subsequent calls to this package's commands by
    referencing *processname*\. If *processname* exists, it will be replaced\.







|
|







|








|
|







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
    *timecode*\. If *timecode* is expressed as an integer, the timecode is
    assumed to be in unixtime\. All other inputs will be interpreted by __clock
    scan__ and converted to unix time\. This task can be modified by subsequent
    calls to this package's commands by referencing *processname*\. If
    *processname* exists, it will be replaced\. If *processname* is not
    given, one is generated and returned by the command\.

        ::cron::at start_coffee {Tomorrow at 9:00am}  {remote::exec::coffeepot power on}
        ::cron::at shutdown_coffee {Tomorrow at 12:00pm}  {remote::exec::coffeepot power off}

  - <a name='2'></a>__::cron::cancel__ *processname*

    This command unregisters the process *processname* and cancels any pending
    commands\. Note: processname can be a process created by either
    __::cron::at__ or __::cron::every__\.

        ::cron::cancel check_mail

  - <a name='3'></a>__::cron::every__ *processname* *frequency* *command*

    This command registers a *command* to be called at the interval of
    *frequency*\. *frequency* is given in seconds\. This task can be modified
    by subsequent calls to this package's commands by referencing
    *processname*\. If *processname* exists, it will be replaced\.

        ::cron::every check_mail 900  ::imap_client::check_mail
        ::cron::every backup_db  3600 {::backup_procedure ::mydb}

  - <a name='4'></a>__::cron::in__ *?processname?* *timecode* *command*

    This command registers a *command* to be called after a delay of time
    specified by *timecode*\. *timecode* is expressed as an seconds\. This
    task can be modified by subsequent calls to this package's commands by
    referencing *processname*\. If *processname* exists, it will be replaced\.
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

    If the ::cron::time variable is > 0 this command will advance the internal
    time, 100ms at a time\.

    In all other cases this command will generate a fictious variable, generate
    an after call, and vwait the variable:

        set eventid \[incr ::cron::eventcount\]
        set var ::cron::event\_\#$eventid
        set $var 0
        ::after $ms "set $var 1"
        ::vwait $var
        ::unset $var

    Usage:








|
|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

    If the ::cron::time variable is > 0 this command will advance the internal
    time, 100ms at a time\.

    In all other cases this command will generate a fictious variable, generate
    an after call, and vwait the variable:

        set eventid [incr ::cron::eventcount]
        set var ::cron::event_#$eventid
        set $var 0
        ::after $ms "set $var 1"
        ::vwait $var
        ::unset $var

    Usage:

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
        does so\.

  - <a name='11'></a>__::cron::wake__ *?who?*

    Wake up cron, and arrange for its event loop to be run during the next Idle
    cycle\.

        ::cron::wake \{I just did something important\}

Several utility commands are provided that are used internally within cron and
for testing cron, but may or may not be useful in the general cases\.

  - <a name='12'></a>__::cron::clock\_step__ *milliseconds*

    Return a clock time absolute to the epoch which falls on the next border







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
        does so\.

  - <a name='11'></a>__::cron::wake__ *?who?*

    Wake up cron, and arrange for its event loop to be run during the next Idle
    cycle\.

        ::cron::wake {I just did something important}

Several utility commands are provided that are used internally within cron and
for testing cron, but may or may not be useful in the general cases\.

  - <a name='12'></a>__::cron::clock\_step__ *milliseconds*

    Return a clock time absolute to the epoch which falls on the next border
Changes to embedded/md/tcllib/files/modules/csv/csv.md.
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
The alternate format is activated through specification of the option
__\-alternate__ to the various split commands\.

# <a name='section4'></a>EXAMPLE

Using the regular format the record

    123,"123,521\.2","Mary says ""Hello, I am Mary""",""

is parsed into the items

    a\) 123
    b\) 123,521\.2
    c\) Mary says "Hello, I am Mary"
    d\) "

Using the alternate format the result is

    a\) 123
    b\) 123,521\.2
    c\) Mary says "Hello, I am Mary"
    d\) \(the empty string\)

instead\. As can be seen only item \(d\) is different, now the empty string instead
of a "\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and







|



|
|
|
|



|
|
|
|







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
The alternate format is activated through specification of the option
__\-alternate__ to the various split commands\.

# <a name='section4'></a>EXAMPLE

Using the regular format the record

    123,"123,521.2","Mary says ""Hello, I am Mary""",""

is parsed into the items

    a) 123
    b) 123,521.2
    c) Mary says "Hello, I am Mary"
    d) "

Using the alternate format the result is

    a) 123
    b) 123,521.2
    c) Mary says "Hello, I am Mary"
    d) (the empty string)

instead\. As can be seen only item \(d\) is different, now the empty string instead
of a "\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
Changes to embedded/md/tcllib/files/modules/defer/defer.md.
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    identifier returned by __::defer::defer__, __::defer::with__, or
    __::defer::autowith__\. Any number of arguments may be supplied, and all
    of the IDs supplied will be cancelled\.

# <a name='section3'></a>EXAMPLES

    package require defer 1
    apply \{\{\} \{
    	set fd \[open /dev/null\]
    	defer::defer close $fd
    \}\}

# <a name='section4'></a>REFERENCES

# <a name='section5'></a>AUTHORS

Roy Keene








|
|

|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    identifier returned by __::defer::defer__, __::defer::with__, or
    __::defer::autowith__\. Any number of arguments may be supplied, and all
    of the IDs supplied will be cancelled\.

# <a name='section3'></a>EXAMPLES

    package require defer 1
    apply {{} {
    	set fd [open /dev/null]
    	defer::defer close $fd
    }}

# <a name='section4'></a>REFERENCES

# <a name='section5'></a>AUTHORS

Roy Keene

Changes to embedded/md/tcllib/files/modules/des/des.md.
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

    OFB is similar to CFB except that the output of the cipher is fed back into
    the next round and not the xor'd plain text\. This means that errors only
    affect a single block but the cipher is more vulnerable to attack\.

# <a name='section5'></a>EXAMPLES

    % set ciphertext \[DES::des \-mode cbc \-dir encrypt \-key $secret $plaintext\]
    % set plaintext \[DES::des \-mode cbc \-dir decrypt \-key $secret $ciphertext\]

    set iv \[string repeat \\\\0 8\]
    set Key \[DES::Init cbc \\\\0\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7 $iv\]
    set ciphertext \[DES::Encrypt $Key "somedata"\]
    append ciphertext \[DES::Encrypt $Key "moredata"\]
    DES::Reset $Key $iv
    set plaintext \[DES::Decrypt $Key $ciphertext\]
    DES::Final $Key

# <a name='section6'></a>REFERENCES

  1. "Data Encryption Standard", Federal Information Processing Standards
     Publication 46\-3, 1999,
     \([http://csrc\.nist\.gov/publications/fips/fips46\-3/fips46\-3\.pdf](http://csrc\.nist\.gov/publications/fips/fips46\-3/fips46\-3\.pdf)\)







|
|

|
|
|
|

|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

    OFB is similar to CFB except that the output of the cipher is fed back into
    the next round and not the xor'd plain text\. This means that errors only
    affect a single block but the cipher is more vulnerable to attack\.

# <a name='section5'></a>EXAMPLES

    % set ciphertext [DES::des -mode cbc -dir encrypt -key $secret $plaintext]
    % set plaintext [DES::des -mode cbc -dir decrypt -key $secret $ciphertext]

    set iv [string repeat \\0 8]
    set Key [DES::Init cbc \\0\\1\\2\\3\\4\\5\\6\\7 $iv]
    set ciphertext [DES::Encrypt $Key "somedata"]
    append ciphertext [DES::Encrypt $Key "moredata"]
    DES::Reset $Key $iv
    set plaintext [DES::Decrypt $Key $ciphertext]
    DES::Final $Key

# <a name='section6'></a>REFERENCES

  1. "Data Encryption Standard", Federal Information Processing Standards
     Publication 46\-3, 1999,
     \([http://csrc\.nist\.gov/publications/fips/fips46\-3/fips46\-3\.pdf](http://csrc\.nist\.gov/publications/fips/fips46\-3/fips46\-3\.pdf)\)
Changes to embedded/md/tcllib/files/modules/dicttool/dicttool.md.
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
  - <a name='6'></a>__rmerge__ *args*

    Return a dict which is the product of a recursive merge of all of the
    arguments\. Unlike __dict merge__, this command descends into all of the
    levels of a dict\. Dict keys which end in a : indicate a leaf, which will be
    interpreted as a literal value, and not descended into further\.

        set items \[dict merge \{
          option \{color \{default: green\}\}
        \} \{
          option \{fruit \{default: mango\}\}
        \} \{
          option \{color \{default: blue\} fruit \{widget: select values: \{mango apple cherry grape\}\}\}
        \}\]
        puts \[dict print $items\]

    Prints the following result:

        option \{
          color \{
            default: blue
          \}

          fruit \{
            widget: select
            values: \{mango apple cherry grape\}
          \}
        \}



# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *dict* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|
|
|



|
|

<
>
|

|
<
<
>
>







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
  - <a name='6'></a>__rmerge__ *args*

    Return a dict which is the product of a recursive merge of all of the
    arguments\. Unlike __dict merge__, this command descends into all of the
    levels of a dict\. Dict keys which end in a : indicate a leaf, which will be
    interpreted as a literal value, and not descended into further\.

        set items [dict merge {
          option {color {default: green}}
        } {
          option {fruit {default: mango}}
        } {
          option {color {default: blue} fruit {widget: select values: {mango apple cherry grape}}}
        }]
        puts [dict print $items]

    Prints the following result:

        option {
          color {
            default: blue

          }
          fruit {
            widget: select
            values: {mango apple cherry grape}


          }
        }

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *dict* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/dns/tcllib_dns.md.
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
    users system\. On a unix machine this parses the /etc/resolv\.conf file for
    nameservers \(if it exists\) and on Windows systems we examine certain parts
    of the registry\. If no nameserver can be found then the loopback address
    \(127\.0\.0\.1\) is used as a default\.

# <a name='section3'></a>EXAMPLES

    % set tok \[dns::resolve www\.tcl\.tk\]
    ::dns::1
    % dns::status $tok
    ok
    % dns::address $tok
    199\.175\.6\.239
    % dns::name $tok
    www\.tcl\.tk
    % dns::cleanup $tok

Using DNS URIs as queries:

    % set tok \[dns::resolve "dns:tcl\.tk;type=MX"\]
    % set tok \[dns::resolve "dns://l\.root\-servers\.net/www\.tcl\.tk"\]

Reverse address lookup:

    % set tok \[dns::resolve 127\.0\.0\.1\]
    ::dns::1
    % dns::name $tok
    localhost
    % dns::cleanup $tok

Using DNS over TLS \(RFC 7858\):

    % set tok \[dns::resolve www\.tcl\.tk \-nameserver dns\-tls\.bitwiseshift\.net  \-usetls 1 \-cafile /etc/ssl/certs/ca\-certificates\.crt\]
    ::dns::12
    % dns::wait $tok
    ok
    % dns::address $tok
    104\.25\.119\.118 104\.25\.120\.118

# <a name='section4'></a>REFERENCES

  1. Mockapetris, P\., "Domain Names \- Concepts and Facilities", RFC 1034,
     November 1987\.
     \([http://www\.ietf\.org/rfc/rfc1034\.txt](http://www\.ietf\.org/rfc/rfc1034\.txt)\)








|




|

|




|
|



|







|




|







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
    users system\. On a unix machine this parses the /etc/resolv\.conf file for
    nameservers \(if it exists\) and on Windows systems we examine certain parts
    of the registry\. If no nameserver can be found then the loopback address
    \(127\.0\.0\.1\) is used as a default\.

# <a name='section3'></a>EXAMPLES

    % set tok [dns::resolve www.tcl.tk]
    ::dns::1
    % dns::status $tok
    ok
    % dns::address $tok
    199.175.6.239
    % dns::name $tok
    www.tcl.tk
    % dns::cleanup $tok

Using DNS URIs as queries:

    % set tok [dns::resolve "dns:tcl.tk;type=MX"]
    % set tok [dns::resolve "dns://l.root-servers.net/www.tcl.tk"]

Reverse address lookup:

    % set tok [dns::resolve 127.0.0.1]
    ::dns::1
    % dns::name $tok
    localhost
    % dns::cleanup $tok

Using DNS over TLS \(RFC 7858\):

    % set tok [dns::resolve www.tcl.tk -nameserver dns-tls.bitwiseshift.net  -usetls 1 -cafile /etc/ssl/certs/ca-certificates.crt]
    ::dns::12
    % dns::wait $tok
    ok
    % dns::address $tok
    104.25.119.118 104.25.120.118

# <a name='section4'></a>REFERENCES

  1. Mockapetris, P\., "Domain Names \- Concepts and Facilities", RFC 1034,
     November 1987\.
     \([http://www\.ietf\.org/rfc/rfc1034\.txt](http://www\.ietf\.org/rfc/rfc1034\.txt)\)

Changes to embedded/md/tcllib/files/modules/dns/tcllib_ip.md.
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
    suitable for displaying to users\.

  - <a name='6'></a>__::ip::distance__ *ipaddr1* *ipaddr2*

    This command computes the \(integer\) distance from IPv4 address *ipaddr1*
    to IPv4 address *ipaddr2*, i\.e\. "ipaddr2 \- ipaddr1"

        % ::ip::distance 1\.1\.1\.1  1\.1\.1\.5
        4

  - <a name='7'></a>__::ip::nextIp__ *ipaddr* ?*offset*?

    This command adds the integer *offset* to the IPv4 address *ipaddr* and
    returns the new IPv4 address\.

        % ::ip::distance 1\.1\.1\.1  4
        1\.1\.1\.5

  - <a name='8'></a>__::ip::prefix__ *address*

    Returns the address prefix generated by masking the address part with the
    mask if provided\. If there is no mask then it is equivalent to calling
    __normalize__

  - <a name='9'></a>__::ip::type__ *address*

  - <a name='10'></a>__::ip::mask__ *address*

    If the address supplied includes a mask then this is returned otherwise
    returns an empty string\.

  - <a name='11'></a>__::ip::prefixToNative__ *prefix*

    This command converts the string *prefix* from dotted form
    \(<ipaddr>/<mask> format\) to native \(hex\) form\. Returns a list containing two
    elements, ipaddress and mask, in this order, in hexadecimal notation\.

        % ip::prefixToNative 1\.1\.1\.0/24
        0x01010100 0xffffff00

  - <a name='12'></a>__::ip::nativeToPrefix__ *nativeList*&#124;*native* ?__\-ipv4__?

    This command converts from native \(hex\) form to dotted form\. It is the
    complement of __::ip::prefixToNative__\.

      * list *nativeList* \(in\)

        List of several ip addresses in native form\. The native form is a list
        as returned by __::ip::prefixToNative__\.

      * list *native* \(in\)

        A list as returned by __::ip::prefixToNative__\.

    The command returns a list of addresses in dotted form if it was called with
    a list of addresses\. Otherwise a single address in dotted form is returned\.

        % ip::nativeToPrefix \{0x01010100 0xffffff00\} \-ipv4
        1\.1\.1\.0/24

  - <a name='13'></a>__::ip::intToString__ *number* ?__\-ipv4__?

    This command converts from an ip address specified as integer number to
    dotted form\.

        ip::intToString 4294967295
        255\.255\.255\.255

  - <a name='14'></a>__::ip::toInteger__ *ipaddr*

    This command converts a dotted form ip into an integer number\.

        % ::ip::toInteger 1\.1\.1\.0
        16843008

  - <a name='15'></a>__::ip::toHex__ *ipaddr*

    This command converts dotted form ip into a hexadecimal number\.

        % ::ip::toHex 1\.1\.1\.0
        0x01010100

  - <a name='16'></a>__::ip::maskToInt__ *ipmask*

    This command convert an ipmask in either dotted \(255\.255\.255\.0\) form or mask
    length form \(24\) into an integer number\.

        ::ip::maskToInt 24
        4294967040

  - <a name='17'></a>__::ip::broadcastAddress__ *prefix* ?__\-ipv4__?

    This commands returns a broadcast address in dotted form for the given route
    *prefix*, either in the form "addr/mask", or in native form\. The result is
    in dotted form\.

        ::ip::broadcastAddress 1\.1\.1\.0/24
        1\.1\.1\.255

        ::ip::broadcastAddress \{0x01010100 0xffffff00\}
        0x010101ff

  - <a name='18'></a>__::ip::maskToLength__ *dottedMask*&#124;*integerMask*&#124;*hexMask* ?__\-ipv4__?

    This command converts the dotted or integer form of an ipmask to the mask
    length form\.

        ::ip::maskToLength 0xffffff00 \-ipv4
        24

        % ::ip::maskToLength 255\.255\.255\.0
        24

  - <a name='19'></a>__::ip::lengthToMask__ *maskLength* ?__\-ipv4__?

    This command converts an ipmask in mask length form to its dotted form\.

        ::ip::lengthToMask 24
        255\.255\.255\.0

  - <a name='20'></a>__::ip::nextNet__ *ipaddr* *ipmask* ?*count*? ?__\-ipv4__?

    This command returns an ipaddress in the same position in the *count* next
    network\. The default value for *count* is __1__\.

    The address can be specified as either integer number or in dotted form\. The
    mask can be specified as either integer number, dotted form, or mask length
    form\.

    The result is in hex form\.

  - <a name='21'></a>__::ip::isOverlap__ *prefix* *prefix*\.\.\.

    This command checks if the given ip prefixes overlap\. All arguments are in
    dotted "addr/mask" form\. All arguments after the first prefix are compared
    against the first prefix\. The result is a boolean value\. It is true if an
    overlap was found for any of the prefixes\.

        % ::ip::isOverlap 1\.1\.1\.0/24 2\.1\.0\.1/32
        0

        ::ip::isOverlap 1\.1\.1\.0/24 2\.1\.0\.1/32 1\.1\.1\.1/32
        1

  - <a name='22'></a>__::ip::isOverlapNative__ ?__\-all__? ?__\-inline__? ?__\-ipv4__? *hexipaddr* *hexipmask* *hexiplist*

    This command is similar to __::ip::isOverlap__, however the arguments
    are in the native form, and the form of the result is under greater control
    of the caller\. If the option __\-all__ is specified it checks all







|







|
|




















|



















|
|







|





|






|
















|
|

|







|


|







|



















|


|







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
    suitable for displaying to users\.

  - <a name='6'></a>__::ip::distance__ *ipaddr1* *ipaddr2*

    This command computes the \(integer\) distance from IPv4 address *ipaddr1*
    to IPv4 address *ipaddr2*, i\.e\. "ipaddr2 \- ipaddr1"

        % ::ip::distance 1.1.1.1  1.1.1.5
        4

  - <a name='7'></a>__::ip::nextIp__ *ipaddr* ?*offset*?

    This command adds the integer *offset* to the IPv4 address *ipaddr* and
    returns the new IPv4 address\.

        % ::ip::distance 1.1.1.1  4
        1.1.1.5

  - <a name='8'></a>__::ip::prefix__ *address*

    Returns the address prefix generated by masking the address part with the
    mask if provided\. If there is no mask then it is equivalent to calling
    __normalize__

  - <a name='9'></a>__::ip::type__ *address*

  - <a name='10'></a>__::ip::mask__ *address*

    If the address supplied includes a mask then this is returned otherwise
    returns an empty string\.

  - <a name='11'></a>__::ip::prefixToNative__ *prefix*

    This command converts the string *prefix* from dotted form
    \(<ipaddr>/<mask> format\) to native \(hex\) form\. Returns a list containing two
    elements, ipaddress and mask, in this order, in hexadecimal notation\.

        % ip::prefixToNative 1.1.1.0/24
        0x01010100 0xffffff00

  - <a name='12'></a>__::ip::nativeToPrefix__ *nativeList*&#124;*native* ?__\-ipv4__?

    This command converts from native \(hex\) form to dotted form\. It is the
    complement of __::ip::prefixToNative__\.

      * list *nativeList* \(in\)

        List of several ip addresses in native form\. The native form is a list
        as returned by __::ip::prefixToNative__\.

      * list *native* \(in\)

        A list as returned by __::ip::prefixToNative__\.

    The command returns a list of addresses in dotted form if it was called with
    a list of addresses\. Otherwise a single address in dotted form is returned\.

        % ip::nativeToPrefix {0x01010100 0xffffff00} -ipv4
        1.1.1.0/24

  - <a name='13'></a>__::ip::intToString__ *number* ?__\-ipv4__?

    This command converts from an ip address specified as integer number to
    dotted form\.

        ip::intToString 4294967295
        255.255.255.255

  - <a name='14'></a>__::ip::toInteger__ *ipaddr*

    This command converts a dotted form ip into an integer number\.

        % ::ip::toInteger 1.1.1.0
        16843008

  - <a name='15'></a>__::ip::toHex__ *ipaddr*

    This command converts dotted form ip into a hexadecimal number\.

        % ::ip::toHex 1.1.1.0
        0x01010100

  - <a name='16'></a>__::ip::maskToInt__ *ipmask*

    This command convert an ipmask in either dotted \(255\.255\.255\.0\) form or mask
    length form \(24\) into an integer number\.

        ::ip::maskToInt 24
        4294967040

  - <a name='17'></a>__::ip::broadcastAddress__ *prefix* ?__\-ipv4__?

    This commands returns a broadcast address in dotted form for the given route
    *prefix*, either in the form "addr/mask", or in native form\. The result is
    in dotted form\.

        ::ip::broadcastAddress 1.1.1.0/24
        1.1.1.255

        ::ip::broadcastAddress {0x01010100 0xffffff00}
        0x010101ff

  - <a name='18'></a>__::ip::maskToLength__ *dottedMask*&#124;*integerMask*&#124;*hexMask* ?__\-ipv4__?

    This command converts the dotted or integer form of an ipmask to the mask
    length form\.

        ::ip::maskToLength 0xffffff00 -ipv4
        24

        % ::ip::maskToLength 255.255.255.0
        24

  - <a name='19'></a>__::ip::lengthToMask__ *maskLength* ?__\-ipv4__?

    This command converts an ipmask in mask length form to its dotted form\.

        ::ip::lengthToMask 24
        255.255.255.0

  - <a name='20'></a>__::ip::nextNet__ *ipaddr* *ipmask* ?*count*? ?__\-ipv4__?

    This command returns an ipaddress in the same position in the *count* next
    network\. The default value for *count* is __1__\.

    The address can be specified as either integer number or in dotted form\. The
    mask can be specified as either integer number, dotted form, or mask length
    form\.

    The result is in hex form\.

  - <a name='21'></a>__::ip::isOverlap__ *prefix* *prefix*\.\.\.

    This command checks if the given ip prefixes overlap\. All arguments are in
    dotted "addr/mask" form\. All arguments after the first prefix are compared
    against the first prefix\. The result is a boolean value\. It is true if an
    overlap was found for any of the prefixes\.

        % ::ip::isOverlap 1.1.1.0/24 2.1.0.1/32
        0

        ::ip::isOverlap 1.1.1.0/24 2.1.0.1/32 1.1.1.1/32
        1

  - <a name='22'></a>__::ip::isOverlapNative__ ?__\-all__? ?__\-inline__? ?__\-ipv4__? *hexipaddr* *hexipmask* *hexiplist*

    This command is similar to __::ip::isOverlap__, however the arguments
    are in the native form, and the form of the result is under greater control
    of the caller\. If the option __\-all__ is specified it checks all
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
        The first overlapping prefix, or an empoty string if there is none\.

      * \-all \-inline

        A list containing the prefixes of all overlaps found, or an empty list
        if there are none\.

        % ::ip::isOverlapNative 0x01010100 0xffffff00 \{\{0x02010001 0xffffffff\}\}
        0

        % ::ip::isOverlapNative 0x01010100 0xffffff00 \{\{0x02010001 0xffffffff\} \{0x01010101 0xffffffff\}\}
        2

  - <a name='23'></a>__::ip::ipToLayer2Multicast__ *ipaddr*

    This command an converts ipv4 address in dotted form into a layer 2
    multicast address, also in dotted form\.

        % ::ip::ipToLayer2Multicast 224\.0\.0\.2
        01\.00\.5e\.00\.00\.02

  - <a name='24'></a>__::ip::ipHostFromPrefix__ *prefix* ?__\-exclude__ *prefixExcludeList*?

    This command returns a host address from a prefix in the form
    "ipaddr/masklen", also making sure that the result is not an address found
    in the *prefixExcludeList*\. The result is an ip address in dotted form\.

        %::ip::ipHostFromPrefix  1\.1\.1\.5/24
        1\.1\.1\.1

        %::ip::ipHostFromPrefix  1\.1\.1\.1/32
        1\.1\.1\.1

  - <a name='25'></a>__::ip::reduceToAggregates__ *prefixlist*

    This command finds nets that overlap and filters out the more specific nets\.
    The prefixes are in either addr/mask form or in native format\. The result is
    a list containing the non\-overlapping ip prefixes from the input\.

        % ::ip::reduceToAggregates \{1\.1\.1\.0/24 1\.1\.0\.0/8  2\.1\.1\.0/24 1\.1\.1\.1/32 \}
        1\.0\.0\.0/8 2\.1\.1\.0/24

  - <a name='26'></a>__::ip::longestPrefixMatch__ *ipaddr* *prefixlist* ?__\-ipv4__?

    This command finds longest prefix match from set of prefixes, given a
    specific host address\. The prefixes in the list are in either native or
    dotted form, whereas the host address is in either ipprefix format, dotted
    form, or integer form\. The result is the prefix which is the most specific
    match to the host address\.

        % ::ip::longestPrefixMatch 1\.1\.1\.1 \{1\.1\.1\.0/24 1\.0\.0\.0/8  2\.1\.1\.0/24 1\.1\.1\.0/28 \}
        1\.1\.1\.0/28

  - <a name='27'></a>__::ip::collapse__ *prefixlist*

    This commands takes a list of prefixes and returns a list prefixes with the
    largest possible subnet masks covering the input, in this manner collapsing
    adjacent prefixes into larger ranges\.

    This is different from __::ip::reduceToAggregates__ in that the latter
    only removes specific nets from a list when they are covered by other
    elements of the input whereas this command actively merges nets into larger
    ranges when they are adjacent to each other\.

        % ::ip::collapse \{1\.2\.2\.0/24 1\.2\.3\.0/24\}
        1\.2\.2\.0/23

  - <a name='28'></a>__::ip::subtract__ *prefixlist*

    This command takes a list of prefixes, some of which are prefixed by a dash\.
    These latter *negative* prefixes are used to punch holes into the ranges
    described by the other, *positive*, prefixes\. I\.e\. the negative prefixes
    are subtracted frrom the positive ones, resulting in a larger list of
    describes describing the covered ranges only as positives\.

# <a name='section3'></a>EXAMPLES

    % ip::version ::1
    6
    % ip::version 127\.0\.0\.1
    4

    % ip::normalize 127/8
    127\.0\.0\.0/8
    % ip::contract 192\.168\.0\.0
    192\.168
    %
    % ip::normalize fec0::1
    fec0:0000:0000:0000:0000:0000:0000:0001
    % ip::contract fec0:0000:0000:0000:0000:0000:0000:0001
    fec0::1

    % ip::equal 192\.168\.0\.4/16 192\.168\.0\.0/16
    1
    % ip::equal fec0::1/10 fec0::fe01/10
    1

# <a name='section4'></a>REFERENCES

  1. Postel, J\. "Internet Protocol\." RFC 791, September 1981,







|


|







|
|







|
|

|
|







|
|









|
|












|
|













|



|
|
|






|







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
        The first overlapping prefix, or an empoty string if there is none\.

      * \-all \-inline

        A list containing the prefixes of all overlaps found, or an empty list
        if there are none\.

        % ::ip::isOverlapNative 0x01010100 0xffffff00 {{0x02010001 0xffffffff}}
        0

        % ::ip::isOverlapNative 0x01010100 0xffffff00 {{0x02010001 0xffffffff} {0x01010101 0xffffffff}}
        2

  - <a name='23'></a>__::ip::ipToLayer2Multicast__ *ipaddr*

    This command an converts ipv4 address in dotted form into a layer 2
    multicast address, also in dotted form\.

        % ::ip::ipToLayer2Multicast 224.0.0.2
        01.00.5e.00.00.02

  - <a name='24'></a>__::ip::ipHostFromPrefix__ *prefix* ?__\-exclude__ *prefixExcludeList*?

    This command returns a host address from a prefix in the form
    "ipaddr/masklen", also making sure that the result is not an address found
    in the *prefixExcludeList*\. The result is an ip address in dotted form\.

        %::ip::ipHostFromPrefix  1.1.1.5/24
        1.1.1.1

        %::ip::ipHostFromPrefix  1.1.1.1/32
        1.1.1.1

  - <a name='25'></a>__::ip::reduceToAggregates__ *prefixlist*

    This command finds nets that overlap and filters out the more specific nets\.
    The prefixes are in either addr/mask form or in native format\. The result is
    a list containing the non\-overlapping ip prefixes from the input\.

        % ::ip::reduceToAggregates {1.1.1.0/24 1.1.0.0/8  2.1.1.0/24 1.1.1.1/32 }
        1.0.0.0/8 2.1.1.0/24

  - <a name='26'></a>__::ip::longestPrefixMatch__ *ipaddr* *prefixlist* ?__\-ipv4__?

    This command finds longest prefix match from set of prefixes, given a
    specific host address\. The prefixes in the list are in either native or
    dotted form, whereas the host address is in either ipprefix format, dotted
    form, or integer form\. The result is the prefix which is the most specific
    match to the host address\.

        % ::ip::longestPrefixMatch 1.1.1.1 {1.1.1.0/24 1.0.0.0/8  2.1.1.0/24 1.1.1.0/28 }
        1.1.1.0/28

  - <a name='27'></a>__::ip::collapse__ *prefixlist*

    This commands takes a list of prefixes and returns a list prefixes with the
    largest possible subnet masks covering the input, in this manner collapsing
    adjacent prefixes into larger ranges\.

    This is different from __::ip::reduceToAggregates__ in that the latter
    only removes specific nets from a list when they are covered by other
    elements of the input whereas this command actively merges nets into larger
    ranges when they are adjacent to each other\.

        % ::ip::collapse {1.2.2.0/24 1.2.3.0/24}
        1.2.2.0/23

  - <a name='28'></a>__::ip::subtract__ *prefixlist*

    This command takes a list of prefixes, some of which are prefixed by a dash\.
    These latter *negative* prefixes are used to punch holes into the ranges
    described by the other, *positive*, prefixes\. I\.e\. the negative prefixes
    are subtracted frrom the positive ones, resulting in a larger list of
    describes describing the covered ranges only as positives\.

# <a name='section3'></a>EXAMPLES

    % ip::version ::1
    6
    % ip::version 127.0.0.1
    4

    % ip::normalize 127/8
    127.0.0.0/8
    % ip::contract 192.168.0.0
    192.168
    %
    % ip::normalize fec0::1
    fec0:0000:0000:0000:0000:0000:0000:0001
    % ip::contract fec0:0000:0000:0000:0000:0000:0000:0001
    fec0::1

    % ip::equal 192.168.0.4/16 192.168.0.0/16
    1
    % ip::equal fec0::1/10 fec0::fe01/10
    1

# <a name='section4'></a>REFERENCES

  1. Postel, J\. "Internet Protocol\." RFC 791, September 1981,
Changes to embedded/md/tcllib/files/modules/docstrip/docstrip.md.
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

The basic unit __docstrip__ operates on are the *lines* of a master source
file\. Extraction consists of selecting some of these lines to be copied from
input text to output text\. The basic distinction is that between *code lines*
\(which are copied and do not begin with a percent character\) and *comment
lines* \(which begin with a percent character and are not copied\)\.

    docstrip::extract \[join \{
      \{% comment\}
      \{% more comment \!"\#$%&/\(\}
      \{some command\}
      \{ % blah $blah "Not a comment\."\}
      \{% abc; this is comment\}
      \{\# def; this is code\}
      \{ghi\}
      \{% jkl\}
    \} \\n\] \{\}

returns the same sequence of lines as

    join \{
      \{some command\}
      \{ % blah $blah "Not a comment\."\}
      \{\# def; this is code\}
      \{ghi\} ""
    \} \\n

It does not matter to __docstrip__ what format is used for the documentation
in the comment lines, but in order to do better than plain text comments, one
typically uses some markup language\. Most commonly LaTeX is used, as that is a
very established standard and also provides the best support for mathematical
formulae, but the __docstrip::util__ package also gives some support for
*[doctools](\.\./\.\./\.\./\.\./index\.md\#doctools)*\-like markup\.







|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|







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

The basic unit __docstrip__ operates on are the *lines* of a master source
file\. Extraction consists of selecting some of these lines to be copied from
input text to output text\. The basic distinction is that between *code lines*
\(which are copied and do not begin with a percent character\) and *comment
lines* \(which begin with a percent character and are not copied\)\.

    docstrip::extract [join {
      {% comment}
      {% more comment !"#$%&/(}
      {some command}
      { % blah $blah "Not a comment."}
      {% abc; this is comment}
      {# def; this is code}
      {ghi}
      {% jkl}
    } \n] {}

returns the same sequence of lines as

    join {
      {some command}
      { % blah $blah "Not a comment."}
      {# def; this is code}
      {ghi} ""
    } \n

It does not matter to __docstrip__ what format is used for the documentation
in the comment lines, but in order to do better than plain text comments, one
typically uses some markup language\. Most commonly LaTeX is used, as that is a
very established standard and also provides the best support for mathematical
formulae, but the __docstrip::util__ package also gives some support for
*[doctools](\.\./\.\./\.\./\.\./index\.md\#doctools)*\-like markup\.
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
line is one of

    '%' '<' STARSLASH EXPRESSION '>'
    '%' '<' PLUSMINUS EXPRESSION '>' CODE

where

    STARSLASH  ::=  '\*' &#124; '/'
    PLUSMINUS  ::=  &#124; '\+' &#124; '\-'
    EXPRESSION ::= SECONDARY &#124; SECONDARY ',' EXPRESSION
                 &#124; SECONDARY '&#124;' EXPRESSION
    SECONDARY  ::= PRIMARY &#124; PRIMARY '&' SECONDARY
    PRIMARY    ::= TERMINAL &#124; '\!' PRIMARY &#124; '\(' EXPRESSION '\)'
    CODE       ::= \{ any character except end\-of\-line \}

Comma and vertical bar both denote 'or'\. Ampersand denotes 'and'\. Exclamation
mark denotes 'not'\. A TERMINAL can be any nonempty string of characters not
containing '>', '&', '&#124;', comma, '\(', or '\)', although the __docstrip__
manual is a bit restrictive and only guarantees proper operation for strings of
letters \(although even the LaTeX core sources make heavy use also of digits in
TERMINALs\)\. The second argument of __docstrip::extract__ is the list of
those TERMINALs that should count as having the value 'true'; all other
TERMINALs count as being 'false' when guard expressions are evaluated\.

In the case of a '%<\**EXPRESSION*>' guard, the lines guarded are all lines up
to the next '%</*EXPRESSION*>' guard with the same *EXPRESSION* \(compared as
strings\)\. The blocks of code delimited by such '\*' and '/' guard lines must be
properly nested\.

    set text \[join \{
       \{begin\}
       \{%<\*foo>\}
       \{1\}
       \{%<\*bar>\}
       \{2\}
       \{%</bar>\}
       \{%<\*\!bar>\}
       \{3\}
       \{%</\!bar>\}
       \{4\}
       \{%</foo>\}
       \{5\}
       \{%<\*bar>\}
       \{6\}
       \{%</bar>\}
       \{end\}
    \} \\n\]
    set res \[docstrip::extract $text foo\]
    append res \[docstrip::extract $text \{foo bar\}\]
    append res \[docstrip::extract $text bar\]

sets $res to the result of

    join \{
       \{begin\}
       \{1\}
       \{3\}
       \{4\}
       \{5\}
       \{end\}
       \{begin\}
       \{1\}
       \{2\}
       \{4\}
       \{5\}
       \{6\}
       \{end\}
       \{begin\}
       \{5\}
       \{6\}
       \{end\} ""
    \} \\n

In guard lines without a '\*', '/', '\+', or '\-' modifier after the '%<', the
guard applies only to the CODE following the '>' on that single line\. A '\+'
modifier is equivalent to no modifier\. A '\-' modifier is like the case with no
modifier, but the expression is implicitly negated, i\.e\., the CODE of a '%<\-'
guard line is only included if the expression evaluates to false\.

Metacomment lines are "comment lines which should not be stripped away", but be
extracted like code lines; these are sometimes used for copyright notices and
similar material\. The '%%' prefix is however not kept, but substituted by the
current __\-metaprefix__, which is customarily set to some "comment until end
of line" character \(or character sequence\) of the language of the code being
extracted\.

    set text \[join \{
       \{begin\}
       \{%<foo> foo\}
       \{%<\+foo>plusfoo\}
       \{%<\-foo>minusfoo\}
       \{middle\}
       \{%% some metacomment\}
       \{%<\*foo>\}
       \{%%another metacomment\}
       \{%</foo>\}
       \{end\}
    \} \\n\]
    set res \[docstrip::extract $text foo \-metaprefix \{\# \}\]
    append res \[docstrip::extract $text bar \-metaprefix \{\#\}\]

sets $res to the result of

    join \{
       \{begin\}
       \{ foo\}
       \{plusfoo\}
       \{middle\}
       \{\#  some metacomment\}
       \{\# another metacomment\}
       \{end\}
       \{begin\}
       \{minusfoo\}
       \{middle\}
       \{\# some metacomment\}
       \{end\} ""
    \} \\n

Verbatim guards can be used to force code line interpretation of a block of
lines even if some of them happen to look like any other type of lines to
docstrip\. A verbatim guard has the form '%<<*END\-TAG*' and the verbatim block
is terminated by the first line that is exactly '%*END\-TAG*'\.

    set text \[join \{
       \{begin\}
       \{%<\*myblock>\}
       \{some stupid\(\)\}
       \{   \#computer<program>\}
       \{%<<QQQ\-98765\}
       \{% These three lines are copied verbatim \(including percents\}
       \{%% even if \-metaprefix is something different than %%\)\.\}
       \{%</myblock>\}
       \{%QQQ\-98765\}
       \{   using\*strange@programming<language>\}
       \{%</myblock>\}
       \{end\}
    \} \\n\]
    set res \[docstrip::extract $text myblock \-metaprefix \{\# \}\]
    append res \[docstrip::extract $text \{\}\]

sets $res to the result of

    join \{
       \{begin\}
       \{some stupid\(\)\}
       \{   \#computer<program>\}
       \{% These three lines are copied verbatim \(including percents\}
       \{%% even if \-metaprefix is something different than %%\)\.\}
       \{%</myblock>\}
       \{   using\*strange@programming<language>\}
       \{end\}
       \{begin\}
       \{end\} ""
    \} \\n

The processing of verbatim guards takes place also inside blocks of lines which
due to some outer block guard will not be copied\.

The final piece of __docstrip__ syntax is that extraction stops at a line
that is exactly "\\endinput"; this is often used to avoid copying random
whitespace at the end of a file\. In the unlikely case that one wants such a code







|
|
|
|
|
|
|















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|














|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|







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
line is one of

    '%' '<' STARSLASH EXPRESSION '>'
    '%' '<' PLUSMINUS EXPRESSION '>' CODE

where

    STARSLASH  ::=  '*' | '/'
    PLUSMINUS  ::=  | '+' | '-'
    EXPRESSION ::= SECONDARY | SECONDARY ',' EXPRESSION
                 | SECONDARY '|' EXPRESSION
    SECONDARY  ::= PRIMARY | PRIMARY '&' SECONDARY
    PRIMARY    ::= TERMINAL | '!' PRIMARY | '(' EXPRESSION ')'
    CODE       ::= { any character except end-of-line }

Comma and vertical bar both denote 'or'\. Ampersand denotes 'and'\. Exclamation
mark denotes 'not'\. A TERMINAL can be any nonempty string of characters not
containing '>', '&', '&#124;', comma, '\(', or '\)', although the __docstrip__
manual is a bit restrictive and only guarantees proper operation for strings of
letters \(although even the LaTeX core sources make heavy use also of digits in
TERMINALs\)\. The second argument of __docstrip::extract__ is the list of
those TERMINALs that should count as having the value 'true'; all other
TERMINALs count as being 'false' when guard expressions are evaluated\.

In the case of a '%<\**EXPRESSION*>' guard, the lines guarded are all lines up
to the next '%</*EXPRESSION*>' guard with the same *EXPRESSION* \(compared as
strings\)\. The blocks of code delimited by such '\*' and '/' guard lines must be
properly nested\.

    set text [join {
       {begin}
       {%<*foo>}
       {1}
       {%<*bar>}
       {2}
       {%</bar>}
       {%<*!bar>}
       {3}
       {%</!bar>}
       {4}
       {%</foo>}
       {5}
       {%<*bar>}
       {6}
       {%</bar>}
       {end}
    } \n]
    set res [docstrip::extract $text foo]
    append res [docstrip::extract $text {foo bar}]
    append res [docstrip::extract $text bar]

sets $res to the result of

    join {
       {begin}
       {1}
       {3}
       {4}
       {5}
       {end}
       {begin}
       {1}
       {2}
       {4}
       {5}
       {6}
       {end}
       {begin}
       {5}
       {6}
       {end} ""
    } \n

In guard lines without a '\*', '/', '\+', or '\-' modifier after the '%<', the
guard applies only to the CODE following the '>' on that single line\. A '\+'
modifier is equivalent to no modifier\. A '\-' modifier is like the case with no
modifier, but the expression is implicitly negated, i\.e\., the CODE of a '%<\-'
guard line is only included if the expression evaluates to false\.

Metacomment lines are "comment lines which should not be stripped away", but be
extracted like code lines; these are sometimes used for copyright notices and
similar material\. The '%%' prefix is however not kept, but substituted by the
current __\-metaprefix__, which is customarily set to some "comment until end
of line" character \(or character sequence\) of the language of the code being
extracted\.

    set text [join {
       {begin}
       {%<foo> foo}
       {%<+foo>plusfoo}
       {%<-foo>minusfoo}
       {middle}
       {%% some metacomment}
       {%<*foo>}
       {%%another metacomment}
       {%</foo>}
       {end}
    } \n]
    set res [docstrip::extract $text foo -metaprefix {# }]
    append res [docstrip::extract $text bar -metaprefix {#}]

sets $res to the result of

    join {
       {begin}
       { foo}
       {plusfoo}
       {middle}
       {#  some metacomment}
       {# another metacomment}
       {end}
       {begin}
       {minusfoo}
       {middle}
       {# some metacomment}
       {end} ""
    } \n

Verbatim guards can be used to force code line interpretation of a block of
lines even if some of them happen to look like any other type of lines to
docstrip\. A verbatim guard has the form '%<<*END\-TAG*' and the verbatim block
is terminated by the first line that is exactly '%*END\-TAG*'\.

    set text [join {
       {begin}
       {%<*myblock>}
       {some stupid()}
       {   #computer<program>}
       {%<<QQQ-98765}
       {% These three lines are copied verbatim (including percents}
       {%% even if -metaprefix is something different than %%).}
       {%</myblock>}
       {%QQQ-98765}
       {   using*strange@programming<language>}
       {%</myblock>}
       {end}
    } \n]
    set res [docstrip::extract $text myblock -metaprefix {# }]
    append res [docstrip::extract $text {}]

sets $res to the result of

    join {
       {begin}
       {some stupid()}
       {   #computer<program>}
       {% These three lines are copied verbatim (including percents}
       {%% even if -metaprefix is something different than %%).}
       {%</myblock>}
       {   using*strange@programming<language>}
       {end}
       {begin}
       {end} ""
    } \n

The processing of verbatim guards takes place also inside blocks of lines which
due to some outer block guard will not be copied\.

The final piece of __docstrip__ syntax is that extraction stops at a line
that is exactly "\\endinput"; this is often used to avoid copying random
whitespace at the end of a file\. In the unlikely case that one wants such a code
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
that files employing that document format are given the suffix "\.ddt", to
distinguish them from the more traditional LaTeX\-based "\.dtx" files\.

Master source files with "\.dtx" extension are usually set up so that they can be
typeset directly by __[latex](\.\./\.\./\.\./\.\./index\.md\#latex)__ without any
support from other files\. This is achieved by beginning the file with the lines

    % \\iffalse
    %<\*driver>
    \\documentclass\{tclldoc\}
    \\begin\{document\}
    \\DocInput\{*filename\.dtx*\}
    \\end\{document\}
    %</driver>
    % \\fi

or some variation thereof\. The trick is that the file gets read twice\. With
normal LaTeX reading rules, the first two lines are comments and therefore
ignored\. The third line is the document preamble, the fourth line begins the
document body, and the sixth line ends the document, so LaTeX stops there —
non\-comments below that point in the file are never subjected to the normal
LaTeX reading rules\. Before that, however, the \\DocInput command on the fifth







|
|
|
|
|
|

|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
that files employing that document format are given the suffix "\.ddt", to
distinguish them from the more traditional LaTeX\-based "\.dtx" files\.

Master source files with "\.dtx" extension are usually set up so that they can be
typeset directly by __[latex](\.\./\.\./\.\./\.\./index\.md\#latex)__ without any
support from other files\. This is achieved by beginning the file with the lines

    % \iffalse
    %<*driver>
    \documentclass{tclldoc}
    \begin{document}
    \DocInput{*filename.dtx*}
    \end{document}
    %</driver>
    % \fi

or some variation thereof\. The trick is that the file gets read twice\. With
normal LaTeX reading rules, the first two lines are comments and therefore
ignored\. The third line is the document preamble, the fourth line begins the
document body, and the sixth line ends the document, so LaTeX stops there —
non\-comments below that point in the file are never subjected to the normal
LaTeX reading rules\. Before that, however, the \\DocInput command on the fifth
Changes to embedded/md/tcllib/files/modules/docstrip/docstrip_util.md.
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
terminal '__docstrip\.tcl::catalogue__'\. This supports both the style of
collecting all catalogue lines in one place and the style of putting each
catalogue line in close proximity of the code that it declares\.

Putting catalogue entries next to the code they declare may look as follows

    %    First there's the catalogue entry
    %    \\begin\{tcl\}
    %<docstrip\.tcl::catalogue>pkgProvide foo::bar 1\.0 \{foobar load\}
    %    \\end\{tcl\}
    %    second a metacomment used to include a copyright message
    %    \\begin\{macrocode\}
    %<\*foobar>
    %% This file is placed in the public domain\.
    %    \\end\{macrocode\}
    %    third the package implementation
    %    \\begin\{tcl\}
    namespace eval foo::bar \{
       \# \.\.\. some clever piece of Tcl code elided \.\.\.
    %    \\end\{tcl\}
    %    which at some point may have variant code to make use of a
    %    &#124;load&#124;able extension
    %    \\begin\{tcl\}
    %<\*load>
       load \[file rootname \[info script\]\]\[info sharedlibextension\]
    %</load>
    %<\*\!load>
       \# \.\.\. even more clever scripted counterpart of the extension
       \# also elided \.\.\.
    %</\!load>
    \}

    %</foobar>
    %    \\end\{tcl\}
    %    and that's it\!

The corresponding set\-up with __pkgIndex__ would be

    %    First there's the catalogue entry
    %    \\begin\{tcl\}
    %<docstrip\.tcl::catalogue>pkgIndex foobar load
    %    \\end\{tcl\}
    %    second a metacomment used to include a copyright message
    %    \\begin\{tcl\}
    %<\*foobar>
    %% This file is placed in the public domain\.
    %    \\end\{tcl\}
    %    third the package implementation
    %    \\begin\{tcl\}
    package provide foo::bar 1\.0
    namespace eval foo::bar \{
       \# \.\.\. some clever piece of Tcl code elided \.\.\.
    %    \\end\{tcl\}
    %    which at some point may have variant code to make use of a
    %    &#124;load&#124;able extension
    %    \\begin\{tcl\}
    %<\*load>
       load \[file rootname \[info script\]\]\[info sharedlibextension\]
    %</load>
    %<\*\!load>
       \# \.\.\. even more clever scripted counterpart of the extension
       \# also elided \.\.\.
    %</\!load>
    \}

    %</foobar>
    %    \\end\{tcl\}
    %    and that's it\!

  - <a name='4'></a>__docstrip::util::index\_from\_catalogue__ *dir* *pattern* ?*option* *value* \.\.\.?

    This command is a sibling of the standard __pkg\_mkIndex__ command, in
    that it adds package entries to "pkgIndex\.tcl" files\. The difference is that
    it indexes __[docstrip](docstrip\.md)__\-style source files rather
    than raw "\.tcl" or loadable library files\. Only packages listed in the







|
|
|

|
|
|
|

|
|
|
|

|
|
|
|

|
|
|
|
<
>

|
|




|
|
|

|
|
|
|

|
|
|
|
|

|
|
|
|

|
|
|
|
<
>

|
|







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
terminal '__docstrip\.tcl::catalogue__'\. This supports both the style of
collecting all catalogue lines in one place and the style of putting each
catalogue line in close proximity of the code that it declares\.

Putting catalogue entries next to the code they declare may look as follows

    %    First there's the catalogue entry
    %    \begin{tcl}
    %<docstrip.tcl::catalogue>pkgProvide foo::bar 1.0 {foobar load}
    %    \end{tcl}
    %    second a metacomment used to include a copyright message
    %    \begin{macrocode}
    %<*foobar>
    %% This file is placed in the public domain.
    %    \end{macrocode}
    %    third the package implementation
    %    \begin{tcl}
    namespace eval foo::bar {
       # ... some clever piece of Tcl code elided ...
    %    \end{tcl}
    %    which at some point may have variant code to make use of a
    %    |load|able extension
    %    \begin{tcl}
    %<*load>
       load [file rootname [info script]][info sharedlibextension]
    %</load>
    %<*!load>
       # ... even more clever scripted counterpart of the extension
       # also elided ...
    %</!load>

    }
    %</foobar>
    %    \end{tcl}
    %    and that's it!

The corresponding set\-up with __pkgIndex__ would be

    %    First there's the catalogue entry
    %    \begin{tcl}
    %<docstrip.tcl::catalogue>pkgIndex foobar load
    %    \end{tcl}
    %    second a metacomment used to include a copyright message
    %    \begin{tcl}
    %<*foobar>
    %% This file is placed in the public domain.
    %    \end{tcl}
    %    third the package implementation
    %    \begin{tcl}
    package provide foo::bar 1.0
    namespace eval foo::bar {
       # ... some clever piece of Tcl code elided ...
    %    \end{tcl}
    %    which at some point may have variant code to make use of a
    %    |load|able extension
    %    \begin{tcl}
    %<*load>
       load [file rootname [info script]][info sharedlibextension]
    %</load>
    %<*!load>
       # ... even more clever scripted counterpart of the extension
       # also elided ...
    %</!load>

    }
    %</foobar>
    %    \end{tcl}
    %    and that's it!

  - <a name='4'></a>__docstrip::util::index\_from\_catalogue__ *dir* *pattern* ?*option* *value* \.\.\.?

    This command is a sibling of the standard __pkg\_mkIndex__ command, in
    that it adds package entries to "pkgIndex\.tcl" files\. The difference is that
    it indexes __[docstrip](docstrip\.md)__\-style source files rather
    than raw "\.tcl" or loadable library files\. Only packages listed in the
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
    An existing file of the same name as one to be created will be overwritten\.

  - <a name='6'></a>__docstrip::util::classical\_preamble__ *metaprefix* *message* *target* ?*source* *terminals* \.\.\.?

    This command returns a preamble in the classical
    __[docstrip](docstrip\.md)__ style

    \#\#
    \#\# This is \`TARGET',
    \#\# generated by the docstrip::util package\.
    \#\#
    \#\# The original source files were:
    \#\#
    \#\# SOURCE \(with options: \`foo,bar'\)
    \#\#
    \#\# Some message line 1
    \#\# line2
    \#\# line3

    if called as

    docstrip::util::classical\_preamble \{\#\#\}\\
      "\\nSome message line 1\\nline2\\nline3" TARGET SOURCE \{foo bar\}

    The command supports preambles for files generated from multiple sources,
    even though __modules\_from\_catalogue__ at present does not need that\.

  - <a name='7'></a>__docstrip::util::classical\_postamble__ *metaprefix* *message* *target* ?*source* *terminals* \.\.\.?

    This command returns a postamble in the classical
    __[docstrip](docstrip\.md)__ style

    \#\# Some message line 1
    \#\# line2
    \#\# line3
    \#\#
    \#\# End of file \`TARGET'\.

    if called as

    docstrip::util::classical\_postamble \{\#\#\}\\
      "Some message line 1\\nline2\\nline3" TARGET SOURCE \{foo bar\}

    In other words, the *source* and *terminals* arguments are ignored, but
    supported for symmetry with __classical\_preamble__\.

  - <a name='8'></a>__docstrip::util::packages\_provided__ *text* ?*setup\-script*?

    This command returns a list where every even index element is the name of a







|
|
|
|
|
|
|
|
|
|
|



|
|









|
|
|
|
|



|
|







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
    An existing file of the same name as one to be created will be overwritten\.

  - <a name='6'></a>__docstrip::util::classical\_preamble__ *metaprefix* *message* *target* ?*source* *terminals* \.\.\.?

    This command returns a preamble in the classical
    __[docstrip](docstrip\.md)__ style

    ##
    ## This is `TARGET',
    ## generated by the docstrip::util package.
    ##
    ## The original source files were:
    ##
    ## SOURCE (with options: `foo,bar')
    ##
    ## Some message line 1
    ## line2
    ## line3

    if called as

    docstrip::util::classical_preamble {##}\
      "\nSome message line 1\nline2\nline3" TARGET SOURCE {foo bar}

    The command supports preambles for files generated from multiple sources,
    even though __modules\_from\_catalogue__ at present does not need that\.

  - <a name='7'></a>__docstrip::util::classical\_postamble__ *metaprefix* *message* *target* ?*source* *terminals* \.\.\.?

    This command returns a postamble in the classical
    __[docstrip](docstrip\.md)__ style

    ## Some message line 1
    ## line2
    ## line3
    ##
    ## End of file `TARGET'.

    if called as

    docstrip::util::classical_postamble {##}\
      "Some message line 1\nline2\nline3" TARGET SOURCE {foo bar}

    In other words, the *source* and *terminals* arguments are ignored, but
    supported for symmetry with __classical\_preamble__\.

  - <a name='8'></a>__docstrip::util::packages\_provided__ *text* ?*setup\-script*?

    This command returns a list where every even index element is the name of a
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
    *setup\-script* is evaluated in the local context of the
    __packages\_provided__ procedure just before the *text* is processed\.
    At that time, the name of the slave command for the safe interpreter that
    will do this processing is kept in the local variable __c__\. To for
    example copy the contents of the __::env__ array to the safe
    interpreter, one might use a *setup\-script* of

    $c eval \[list array set env \[array get ::env\]\]

# <a name='section3'></a>Source processing commands

Unlike the previous group of commands, which would use __docstrip::extract__
to extract some code lines and then process those further, the following
commands operate on text consisting of all types of lines\.








|







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
    *setup\-script* is evaluated in the local context of the
    __packages\_provided__ procedure just before the *text* is processed\.
    At that time, the name of the slave command for the safe interpreter that
    will do this processing is kept in the local variable __c__\. To for
    example copy the contents of the __::env__ array to the safe
    interpreter, one might use a *setup\-script* of

    $c eval [list array set env [array get ::env]]

# <a name='section3'></a>Source processing commands

Unlike the previous group of commands, which would use __docstrip::extract__
to extract some code lines and then process those further, the following
commands operate on text consisting of all types of lines\.

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
        __emph__asised\.

    At the time of writing, no project has employed
    __[doctools](\.\./doctools/doctools\.md)__ markup in master source
    files, so experience of what works well is not available\. A source file
    could however look as follows

    % \[manpage\_begin gcd n 1\.0\]
    % \[keywords divisor\]
    % \[keywords math\]
    % \[moddesc \{Greatest Common Divisor\}\]
    % \[require gcd \[opt 1\.0\]\]
    % \[description\]
    %
    % \[list\_begin definitions\]
    % \[call \[cmd gcd\] \[arg a\] \[arg b\]\]
    %   The \[cmd gcd\] procedure takes two arguments \[arg a\] and \[arg b\] which
    %   must be integers and returns their greatest common divisor\.
    proc gcd \{a b\} \{
    %   The first step is to take the absolute values of the arguments\.
    %   This relieves us of having to worry about how signs will be treated
    %   by the remainder operation\.
       set a \[expr \{abs\($a\)\}\]
       set b \[expr \{abs\($b\)\}\]
    %   The next line does all of Euclid's algorithm\! We can make do
    %   without a temporary variable, since $a is substituted before the
    %   \[lb\]set a $b\[rb\] and thus continues to hold a reference to the
    %   "old" value of \[var a\]\.
       while \{$b>0\} \{ set b \[expr \{ $a % \[set a $b\] \}\] \}
    %   In Tcl 8\.3 we might want to use \[cmd set\] instead of \[cmd return\]
    %   to get the slight advantage of byte\-compilation\.
    %<tcl83>  set a
    %<\!tcl83>   return $a
    \}

    % \[list\_end\]
    %
    % \[manpage\_end\]

    If the above text is fed through __docstrip::util::ddt2man__ then the
    result will be a syntactically correct
    __[doctools](\.\./doctools/doctools\.md)__ manpage, even though its
    purpose is a bit different\.

    It is suggested that master source code files with







|
|
|
|
|
|

|
|
|
|
|
|

|
|
|
|

|
|
|
|
|

|
<
>
|

|







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
        __emph__asised\.

    At the time of writing, no project has employed
    __[doctools](\.\./doctools/doctools\.md)__ markup in master source
    files, so experience of what works well is not available\. A source file
    could however look as follows

    % [manpage_begin gcd n 1.0]
    % [keywords divisor]
    % [keywords math]
    % [moddesc {Greatest Common Divisor}]
    % [require gcd [opt 1.0]]
    % [description]
    %
    % [list_begin definitions]
    % [call [cmd gcd] [arg a] [arg b]]
    %   The [cmd gcd] procedure takes two arguments [arg a] and [arg b] which
    %   must be integers and returns their greatest common divisor.
    proc gcd {a b} {
    %   The first step is to take the absolute values of the arguments.
    %   This relieves us of having to worry about how signs will be treated
    %   by the remainder operation.
       set a [expr {abs($a)}]
       set b [expr {abs($b)}]
    %   The next line does all of Euclid's algorithm! We can make do
    %   without a temporary variable, since $a is substituted before the
    %   [lb]set a $b[rb] and thus continues to hold a reference to the
    %   "old" value of [var a].
       while {$b>0} { set b [expr { $a % [set a $b] }] }
    %   In Tcl 8.3 we might want to use [cmd set] instead of [cmd return]
    %   to get the slight advantage of byte-compilation.
    %<tcl83>  set a
    %<!tcl83>   return $a

    }
    % [list_end]
    %
    % [manpage_end]

    If the above text is fed through __docstrip::util::ddt2man__ then the
    result will be a syntactically correct
    __[doctools](\.\./doctools/doctools\.md)__ manpage, even though its
    purpose is a bit different\.

    It is suggested that master source code files with
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
    the header of each hunk specifies which case is at hand\. It is normally
    necessary to manually review both the return value from
    __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ and the patched text itself,
    as this command cannot adjust comment lines to match new content\.

    An example use would look like

    set sourceL \[split \[docstrip::util::thefile from\.dtx\] \\n\]
    set terminals \{foo bar baz\}
    set fromtext \[docstrip::util::thefile from\.tcl\]
    set difftext \[exec diff \-\-unified from\.tcl to\.tcl\]
    set leftover \[docstrip::util::patch sourceL $terminals $fromtext\\
      \[docstrip::util::import\_unidiff $difftext\] \-metaprefix \{\#\}\]
    set F \[open to\.dtx w\]; puts $F \[join $sourceL \\n\]; close $F
    return $leftover

    Here, "from\.dtx" was used as source for "from\.tcl", which someone modified
    into "to\.tcl"\. We're trying to construct a "to\.dtx" which can be used as
    source for "to\.tcl"\.

  - <a name='12'></a>__docstrip::util::thefile__ *filename* ?*option* *value* \.\.\.?







|
|
|
|
|
|
|







599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
    the header of each hunk specifies which case is at hand\. It is normally
    necessary to manually review both the return value from
    __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ and the patched text itself,
    as this command cannot adjust comment lines to match new content\.

    An example use would look like

    set sourceL [split [docstrip::util::thefile from.dtx] \n]
    set terminals {foo bar baz}
    set fromtext [docstrip::util::thefile from.tcl]
    set difftext [exec diff --unified from.tcl to.tcl]
    set leftover [docstrip::util::patch sourceL $terminals $fromtext\
      [docstrip::util::import_unidiff $difftext] -metaprefix {#}]
    set F [open to.dtx w]; puts $F [join $sourceL \n]; close $F
    return $leftover

    Here, "from\.dtx" was used as source for "from\.tcl", which someone modified
    into "to\.tcl"\. We're trying to construct a "to\.dtx" which can be used as
    source for "to\.tcl"\.

  - <a name='12'></a>__docstrip::util::thefile__ *filename* ?*option* *value* \.\.\.?
Changes to embedded/md/tcllib/files/modules/doctools/changelog.md.
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
    ChangeLog\. Each element/entry is then a list of three elements describing
    the date of the entry, its author, and the comments made, in this order\. The
    last item in each element/entry, the comments, is a list of sections\. Each
    section is described by a list containing two elements, a list of file
    names, and a string containing the true comment associated with the files of
    the section\.

            \{
        	\{


        	    date
        	    author
        	    \{
        		\{


        		    \{file \.\.\.\}
        		    commenttext
        		\}

        		\.\.\.
        	    \}
        	\}


        	\{\.\.\.\}
            \}


  - <a name='2'></a>__::doctools::changelog::flatten__ *entries*

    This command converts a list of entries as generated by __change::scan__
    above into a simpler list of plain text blocks each containing all the
    information of a single entry\.








<
<
>
>


<
<
>
>
|

<
>
|
<
<
>
>
|
<
>







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
    ChangeLog\. Each element/entry is then a list of three elements describing
    the date of the entry, its author, and the comments made, in this order\. The
    last item in each element/entry, the comments, is a list of sections\. Each
    section is described by a list containing two elements, a list of file
    names, and a string containing the true comment associated with the files of
    the section\.



            {
        	{
        	    date
        	    author


        	    {
        		{
        		    {file ...}
        		    commenttext

        		}
        		...


        	    }
        	}
        	{...}

            }

  - <a name='2'></a>__::doctools::changelog::flatten__ *entries*

    This command converts a list of entries as generated by __change::scan__
    above into a simpler list of plain text blocks each containing all the
    information of a single entry\.

Changes to embedded/md/tcllib/files/modules/doctools/docidx_lang_intro.md.
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
interspersed between them, except for whitespace\.

Each markup command is a Tcl command surrounded by a matching pair of __\[__
and __\]__\. Inside of these delimiters the usual rules for a Tcl command
apply with regard to word quotation, nested commands, continuation lines, etc\.
I\.e\.

    \.\.\. \[key \{markup language\}\] \.\.\.

    \.\.\. \[manpage thefile \\\\
            \{file description\}\] \.\.\.

## <a name='subsection2'></a>Basic structure

The most simple document which can be written in docidx is

    \[index\_begin GROUPTITLE TITLE\]
    \[index\_end\]

Not very useful, but valid\. This also shows us that all docidx documents consist
of only one part where we will list all keys and their references\.

A more useful index will contain at least keywords, or short 'keys', i\.e\. the
phrases which were indexed\. So:

    \[index\_begin GROUPTITLE TITLE\]
    \[__key markup__\]
    \[__key \{semantic markup\}\]__\]
    \[__key \{docidx markup\}__\]
    \[__key \{docidx language\}__\]
    \[__key \{docidx commands\}__\]
    \[index\_end\]

In the above example the command __key__ is used to declare the keyword
phrases we wish to be part of the index\.

However a truly useful index does not only list the keyword phrases, but will
also contain references to documents associated with the keywords\. Here is a
made\-up index for all the manpages in the module
*[base64](\.\./\.\./\.\./\.\./index\.md\#base64)*:

    \[index\_begin tcllib/base64 \{De\- & Encoding\}\]
    \[key base64\]
    \[__manpage base64__\]
    \[key encoding\]
    \[__manpage base64__\]
    \[__manpage uuencode__\]
    \[__manpage yencode__\]
    \[key uuencode\]
    \[__manpage uuencode__\]
    \[key yEnc\]
    \[__manpage yencode__\]
    \[key ydecode\]
    \[__manpage yencode__\]
    \[key yencode\]
    \[__manpage yencode__\]
    \[index\_end\]

In the above example the command
__[manpage](\.\./\.\./\.\./\.\./index\.md\#manpage)__ is used to insert references
to documents, using symbolic file names, with each command belonging to the last
__key__ command coming before it\.

The other command to insert references is







|

|
|





|
|







|
|
|
|
|
|
|









|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
interspersed between them, except for whitespace\.

Each markup command is a Tcl command surrounded by a matching pair of __\[__
and __\]__\. Inside of these delimiters the usual rules for a Tcl command
apply with regard to word quotation, nested commands, continuation lines, etc\.
I\.e\.

    ... [key {markup language}] ...

    ... [manpage thefile \\
            {file description}] ...

## <a name='subsection2'></a>Basic structure

The most simple document which can be written in docidx is

    [index_begin GROUPTITLE TITLE]
    [index_end]

Not very useful, but valid\. This also shows us that all docidx documents consist
of only one part where we will list all keys and their references\.

A more useful index will contain at least keywords, or short 'keys', i\.e\. the
phrases which were indexed\. So:

    [index_begin GROUPTITLE TITLE]
    [__key markup__]
    [__key {semantic markup}]__]
    [__key {docidx markup}__]
    [__key {docidx language}__]
    [__key {docidx commands}__]
    [index_end]

In the above example the command __key__ is used to declare the keyword
phrases we wish to be part of the index\.

However a truly useful index does not only list the keyword phrases, but will
also contain references to documents associated with the keywords\. Here is a
made\-up index for all the manpages in the module
*[base64](\.\./\.\./\.\./\.\./index\.md\#base64)*:

    [index_begin tcllib/base64 {De- & Encoding}]
    [key base64]
    [__manpage base64__]
    [key encoding]
    [__manpage base64__]
    [__manpage uuencode__]
    [__manpage yencode__]
    [key uuencode]
    [__manpage uuencode__]
    [key yEnc]
    [__manpage yencode__]
    [key ydecode]
    [__manpage yencode__]
    [key yencode]
    [__manpage yencode__]
    [index_end]

In the above example the command
__[manpage](\.\./\.\./\.\./\.\./index\.md\#manpage)__ is used to insert references
to documents, using symbolic file names, with each command belonging to the last
__key__ command coming before it\.

The other command to insert references is
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
to be used before the __index\_begin__ command opening the document\.

Instead of only whitespace the two templating commands __include__ and
__vset__ are also allowed, to enable the writer to either set and/or import
configuration settings relevant to the table of contents\. I\.e\. it is possible to
write

    \[__include FILE__\]
    \[__vset VAR VALUE__\]
    \[index\_begin GROUPTITLE TITLE\]
    \.\.\.
    \[index\_end\]

Even more important, these two commands are allowed anywhere where a markup
command is allowed, without regard for any other structure\.

    \[index\_begin GROUPTITLE TITLE\]
    \[__include FILE__\]
    \[__vset VAR VALUE__\]
    \.\.\.
    \[index\_end\]

The only restriction __include__ has to obey is that the contents of the
included file must be valid at the place of the inclusion\. I\.e\. a file included
before __index\_begin__ may contain only the templating commands __vset__
and __include__, a file included after a key may contain only manape or url
references, and other keys, etc\.

## <a name='subsection4'></a>Escapes

Beyond the 6 commands shown so far we have two more available\. However their
function is not the marking up of index structure, but the insertion of
characters, namely __\[__ and __\]__\. These commands, __lb__ and
__rb__ respectively, are required because our use of \[ and \] to bracket
markup commands makes it impossible to directly use \[ and \] within the text\.

Our example of their use are the sources of the last sentence in the previous
paragraph, with some highlighting added\.

    \.\.\.
    These commands, \[cmd lb\] and \[cmd lb\] respectively, are required
    because our use of \[__lb__\] and \[__rb__\] to bracket markup commands makes it
    impossible to directly use \[__lb__\] and \[__rb__\] within the text\.
    \.\.\.

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of documentation should be fortified enough to be able to understand the formal
*[docidx language syntax](docidx\_lang\_syntax\.md)* specification as well\.
From here on out the *[docidx language command







|
|
|
|
|




|
|
|
|
|


















|
|
|
|
|







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
to be used before the __index\_begin__ command opening the document\.

Instead of only whitespace the two templating commands __include__ and
__vset__ are also allowed, to enable the writer to either set and/or import
configuration settings relevant to the table of contents\. I\.e\. it is possible to
write

    [__include FILE__]
    [__vset VAR VALUE__]
    [index_begin GROUPTITLE TITLE]
    ...
    [index_end]

Even more important, these two commands are allowed anywhere where a markup
command is allowed, without regard for any other structure\.

    [index_begin GROUPTITLE TITLE]
    [__include FILE__]
    [__vset VAR VALUE__]
    ...
    [index_end]

The only restriction __include__ has to obey is that the contents of the
included file must be valid at the place of the inclusion\. I\.e\. a file included
before __index\_begin__ may contain only the templating commands __vset__
and __include__, a file included after a key may contain only manape or url
references, and other keys, etc\.

## <a name='subsection4'></a>Escapes

Beyond the 6 commands shown so far we have two more available\. However their
function is not the marking up of index structure, but the insertion of
characters, namely __\[__ and __\]__\. These commands, __lb__ and
__rb__ respectively, are required because our use of \[ and \] to bracket
markup commands makes it impossible to directly use \[ and \] within the text\.

Our example of their use are the sources of the last sentence in the previous
paragraph, with some highlighting added\.

    ...
    These commands, [cmd lb] and [cmd lb] respectively, are required
    because our use of [__lb__] and [__rb__] to bracket markup commands makes it
    impossible to directly use [__lb__] and [__rb__] within the text.
    ...

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of documentation should be fortified enough to be able to understand the formal
*[docidx language syntax](docidx\_lang\_syntax\.md)* specification as well\.
From here on out the *[docidx language command
Changes to embedded/md/tcllib/files/modules/doctools/docidx_lang_syntax.md.
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  1. The construct \{ X \} stands for zero or more occurrences of X\.

  1. The construct \[ X \] stands for zero or one occurrence of X\.

The syntax:

    index     = defs
                INDEX\_BEGIN
                \[ contents \]
                INDEX\_END
                \{ <WHITE> \}

    defs      = \{ INCLUDE &#124; VSET &#124; <WHITE> \}
    contents  = keyword \{ keyword \}

    keyword   = defs KEY ref \{ ref \}
    ref       = MANPAGE &#124; URL &#124; defs

At last a rule we were unable to capture in the EBNF syntax, as it is about the
arguments of the markup commands, something which is not modeled here\.

  1. The arguments of all markup commands have to be plain text, and/or text
     markup commands, i\.e\. one of








|
|
|
|

|
|

|
|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  1. The construct \{ X \} stands for zero or more occurrences of X\.

  1. The construct \[ X \] stands for zero or one occurrence of X\.

The syntax:

    index     = defs
                INDEX_BEGIN
                [ contents ]
                INDEX_END
                { <WHITE> }

    defs      = { INCLUDE | VSET | <WHITE> }
    contents  = keyword { keyword }

    keyword   = defs KEY ref { ref }
    ref       = MANPAGE | URL | defs

At last a rule we were unable to capture in the EBNF syntax, as it is about the
arguments of the markup commands, something which is not modeled here\.

  1. The arguments of all markup commands have to be plain text, and/or text
     markup commands, i\.e\. one of

Changes to embedded/md/tcllib/files/modules/doctools/docidx_plugin_apiref.md.
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
  1. initialize and shutdown each pass

  1. query and initialize engine parameters

After the plugin has been loaded and the frontend commands are established the
commands will be called in the following sequence:

    idx\_numpasses \-> n
    idx\_listvariables \-> vars

    idx\_varset var1 value1
    idx\_varset var2 value2
    \.\.\.
    idx\_varset varK valueK
    idx\_initialize
    idx\_setup 1
    \.\.\.
    idx\_setup 2
    \.\.\.
    \.\.\.
    idx\_setup n
    \.\.\.
    idx\_postprocess
    idx\_shutdown
    \.\.\.

I\.e\. first the number of passes and the set of available engine parameters is
established, followed by calls setting the parameters\. That second part is
optional\.

After that the plugin is initialized, the specified number of passes executed,
the final result run through a global post processing step and at last the







|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
  1. initialize and shutdown each pass

  1. query and initialize engine parameters

After the plugin has been loaded and the frontend commands are established the
commands will be called in the following sequence:

    idx_numpasses -> n
    idx_listvariables -> vars

    idx_varset var1 value1
    idx_varset var2 value2
    ...
    idx_varset varK valueK
    idx_initialize
    idx_setup 1
    ...
    idx_setup 2
    ...
    ...
    idx_setup n
    ...
    idx_postprocess
    idx_shutdown
    ...

I\.e\. first the number of passes and the set of available engine parameters is
established, followed by calls setting the parameters\. That second part is
optional\.

After that the plugin is initialized, the specified number of passes executed,
the final result run through a global post processing step and at last the
Changes to embedded/md/tcllib/files/modules/doctools/doctoc_lang_intro.md.
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
interspersed between them, except for whitespace\.

Each markup command is a Tcl command surrounded by a matching pair of __\[__
and __\]__\. Inside of these delimiters the usual rules for a Tcl command
apply with regard to word quotation, nested commands, continuation lines, etc\.
I\.e\.

    \.\.\. \[division\_start \{Appendix 1\}\] \.\.\.

    \.\.\. \[item thefile \\\\
            label \{file description\}\] \.\.\.

## <a name='subsection2'></a>Basic structure

The most simple document which can be written in doctoc is

    \[toc\_begin GROUPTITLE TITLE\]
    \[toc\_end\]

This also shows us that all doctoc documents consist of only one part where we
will list *items* and *divisions*\.

The user is free to mix these as she sees fit\. This is a change from version 1
of the language, which did not allow this mixing, but only the use of either a
series of items or a series of divisions\.







|

|
|





|
|







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
interspersed between them, except for whitespace\.

Each markup command is a Tcl command surrounded by a matching pair of __\[__
and __\]__\. Inside of these delimiters the usual rules for a Tcl command
apply with regard to word quotation, nested commands, continuation lines, etc\.
I\.e\.

    ... [division_start {Appendix 1}] ...

    ... [item thefile \\
            label {file description}] ...

## <a name='subsection2'></a>Basic structure

The most simple document which can be written in doctoc is

    [toc_begin GROUPTITLE TITLE]
    [toc_end]

This also shows us that all doctoc documents consist of only one part where we
will list *items* and *divisions*\.

The user is free to mix these as she sees fit\. This is a change from version 1
of the language, which did not allow this mixing, but only the use of either a
series of items or a series of divisions\.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Symbolic names are used to preserve the convertibility of this format to any
output format\. The actual name of any file will be inserted by the chosen
formatting engine when converting the input, based on a mapping from symbolic to
actual names given to the engine\.

Here a made up example for a table of contents of this document:

    \[toc\_begin Doctoc \{Language Introduction\}\]
    \[__item 1 DESCRIPTION__\]
    \[__item 1\.1 \{Basic structure\}__\]
    \[__item 1\.2 Items__\]
    \[__item 1\.3 Divisions__\]
    \[__item 2 \{FURTHER READING\}__\]
    \[toc\_end\]

## <a name='subsection4'></a>Divisions

One thing of notice in the last example in the previous section is that the
referenced sections actually had a nested structure, something which was
expressed in the item labels, by using a common prefix for all the sections
nested under section 1\.







|
|
|
|
|
|
|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
Symbolic names are used to preserve the convertibility of this format to any
output format\. The actual name of any file will be inserted by the chosen
formatting engine when converting the input, based on a mapping from symbolic to
actual names given to the engine\.

Here a made up example for a table of contents of this document:

    [toc_begin Doctoc {Language Introduction}]
    [__item 1 DESCRIPTION__]
    [__item 1.1 {Basic structure}__]
    [__item 1.2 Items__]
    [__item 1.3 Divisions__]
    [__item 2 {FURTHER READING}__]
    [toc_end]

## <a name='subsection4'></a>Divisions

One thing of notice in the last example in the previous section is that the
referenced sections actually had a nested structure, something which was
expressed in the item labels, by using a common prefix for all the sections
nested under section 1\.
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

  - __division\_end__

    This command closes the last opened and not yet closed division\.

Using this we can recast the last example like this

    \[toc\_begin Doctoc \{Language Introduction\}\]
    \[__division\_start DESCRIPTION__\]
    \[item 1 \{Basic structure\}\]
    \[item 2 Items\]
    \[item 3 Divisions\]
    \[__division\_end__\]
    \[__division\_start \{FURTHER READING\}__\]
    \[__division\_end__\]
    \[toc\_end\]

Or, to demonstrate deeper nesting

    \[toc\_begin Doctoc \{Language Introduction\}\]
    \[__division\_start DESCRIPTION__\]
    \[__division\_start \{Basic structure\}__\]
    \[item 1 Do\]
    \[item 2 Re\]
    \[__division\_end__\]
    \[__division\_start Items__\]
    \[item a Fi\]
    \[item b Fo\]
    \[item c Fa\]
    \[__division\_end__\]
    \[__division\_start Divisions__\]
    \[item 1 Sub\]
    \[item 1 Zero\]
    \[__division\_end__\]
    \[__division\_end__\]
    \[__division\_start \{FURTHER READING\}__\]
    \[__division\_end__\]
    \[toc\_end\]

And do not forget, it is possible to freely mix items and divisions, and to have
empty divisions\.

    \[toc\_begin Doctoc \{Language Introduction\}\]
    \[item 1 Do\]
    \[__division\_start DESCRIPTION__\]
    \[__division\_start \{Basic structure\}__\]
    \[item 2 Re\]
    \[__division\_end__\]
    \[item a Fi\]
    \[__division\_start Items__\]
    \[item b Fo\]
    \[item c Fa\]
    \[__division\_end__\]
    \[__division\_start Divisions__\]
    \[__division\_end__\]
    \[__division\_end__\]
    \[__division\_start \{FURTHER READING\}__\]
    \[__division\_end__\]
    \[toc\_end\]

## <a name='subsection5'></a>Advanced structure

In all previous examples we fudged a bit regarding the markup actually allowed
to be used before the __toc\_begin__ command opening the document\.

Instead of only whitespace the two templating commands __include__ and
__vset__ are also allowed, to enable the writer to either set and/or import
configuration settings relevant to the table of contents\. I\.e\. it is possible to
write

    \[__include FILE__\]
    \[__vset VAR VALUE__\]
    \[toc\_begin GROUPTITLE TITLE\]
    \.\.\.
    \[toc\_end\]

Even more important, these two commands are allowed anywhere where a markup
command is allowed, without regard for any other structure\.

    \[toc\_begin GROUPTITLE TITLE\]
    \[__include FILE__\]
    \[__vset VAR VALUE__\]
    \.\.\.
    \[toc\_end\]

The only restriction __include__ has to obey is that the contents of the
included file must be valid at the place of the inclusion\. I\.e\. a file included
before __toc\_begin__ may contain only the templating commands __vset__
and __include__, a file included in a division may contain only items or
divisions commands, etc\.

## <a name='subsection6'></a>Escapes

Beyond the 6 commands shown so far we have two more available\. However their
function is not the marking up of toc structure, but the insertion of
characters, namely __\[__ and __\]__\. These commands, __lb__ and
__rb__ respectively, are required because our use of \[ and \] to bracket
markup commands makes it impossible to directly use \[ and \] within the text\.

Our example of their use are the sources of the last sentence in the previous
paragraph, with some highlighting added\.

    \.\.\.
    These commands, \[cmd lb\] and \[cmd lb\] respectively, are required
    because our use of \[__lb__\] and \[__rb__\] to bracket markup commands makes it
    impossible to directly use \[__lb__\] and \[__rb__\] within the text\.
    \.\.\.

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of documentation should be fortified enough to be able to understand the formal
*[doctoc language syntax](doctoc\_lang\_syntax\.md)* specification as well\.
From here on out the *[doctoc language command







|
|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|











|
|
|
|
|




|
|
|
|
|


















|
|
|
|
|







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

  - __division\_end__

    This command closes the last opened and not yet closed division\.

Using this we can recast the last example like this

    [toc_begin Doctoc {Language Introduction}]
    [__division_start DESCRIPTION__]
    [item 1 {Basic structure}]
    [item 2 Items]
    [item 3 Divisions]
    [__division_end__]
    [__division_start {FURTHER READING}__]
    [__division_end__]
    [toc_end]

Or, to demonstrate deeper nesting

    [toc_begin Doctoc {Language Introduction}]
    [__division_start DESCRIPTION__]
    [__division_start {Basic structure}__]
    [item 1 Do]
    [item 2 Re]
    [__division_end__]
    [__division_start Items__]
    [item a Fi]
    [item b Fo]
    [item c Fa]
    [__division_end__]
    [__division_start Divisions__]
    [item 1 Sub]
    [item 1 Zero]
    [__division_end__]
    [__division_end__]
    [__division_start {FURTHER READING}__]
    [__division_end__]
    [toc_end]

And do not forget, it is possible to freely mix items and divisions, and to have
empty divisions\.

    [toc_begin Doctoc {Language Introduction}]
    [item 1 Do]
    [__division_start DESCRIPTION__]
    [__division_start {Basic structure}__]
    [item 2 Re]
    [__division_end__]
    [item a Fi]
    [__division_start Items__]
    [item b Fo]
    [item c Fa]
    [__division_end__]
    [__division_start Divisions__]
    [__division_end__]
    [__division_end__]
    [__division_start {FURTHER READING}__]
    [__division_end__]
    [toc_end]

## <a name='subsection5'></a>Advanced structure

In all previous examples we fudged a bit regarding the markup actually allowed
to be used before the __toc\_begin__ command opening the document\.

Instead of only whitespace the two templating commands __include__ and
__vset__ are also allowed, to enable the writer to either set and/or import
configuration settings relevant to the table of contents\. I\.e\. it is possible to
write

    [__include FILE__]
    [__vset VAR VALUE__]
    [toc_begin GROUPTITLE TITLE]
    ...
    [toc_end]

Even more important, these two commands are allowed anywhere where a markup
command is allowed, without regard for any other structure\.

    [toc_begin GROUPTITLE TITLE]
    [__include FILE__]
    [__vset VAR VALUE__]
    ...
    [toc_end]

The only restriction __include__ has to obey is that the contents of the
included file must be valid at the place of the inclusion\. I\.e\. a file included
before __toc\_begin__ may contain only the templating commands __vset__
and __include__, a file included in a division may contain only items or
divisions commands, etc\.

## <a name='subsection6'></a>Escapes

Beyond the 6 commands shown so far we have two more available\. However their
function is not the marking up of toc structure, but the insertion of
characters, namely __\[__ and __\]__\. These commands, __lb__ and
__rb__ respectively, are required because our use of \[ and \] to bracket
markup commands makes it impossible to directly use \[ and \] within the text\.

Our example of their use are the sources of the last sentence in the previous
paragraph, with some highlighting added\.

    ...
    These commands, [cmd lb] and [cmd lb] respectively, are required
    because our use of [__lb__] and [__rb__] to bracket markup commands makes it
    impossible to directly use [__lb__] and [__rb__] within the text.
    ...

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of documentation should be fortified enough to be able to understand the formal
*[doctoc language syntax](doctoc\_lang\_syntax\.md)* specification as well\.
From here on out the *[doctoc language command
Changes to embedded/md/tcllib/files/modules/doctools/doctoc_lang_syntax.md.
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
  1. The construct \{ X \} stands for zero or more occurrences of X\.

  1. The construct \[ X \] stands for zero or one occurrence of X\.

The syntax:

    toc       = defs
                TOC\_BEGIN
                contents
                TOC\_END
                \{ <WHITE> \}

    defs      = \{ INCLUDE &#124; VSET &#124; <WHITE> \}
    contents  = \{ defs entry \} \[ defs \]

    entry     = ITEM &#124; division

    division  = DIVISION\_START
                contents
                DIVISION\_END

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|
|

|
|

|

|

|







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
  1. The construct \{ X \} stands for zero or more occurrences of X\.

  1. The construct \[ X \] stands for zero or one occurrence of X\.

The syntax:

    toc       = defs
                TOC_BEGIN
                contents
                TOC_END
                { <WHITE> }

    defs      = { INCLUDE | VSET | <WHITE> }
    contents  = { defs entry } [ defs ]

    entry     = ITEM | division

    division  = DIVISION_START
                contents
                DIVISION_END

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/doctools/doctoc_plugin_apiref.md.
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
  1. initialize and shutdown each pass

  1. query and initialize engine parameters

After the plugin has been loaded and the frontend commands are established the
commands will be called in the following sequence:

    toc\_numpasses \-> n
    toc\_listvariables \-> vars

    toc\_varset var1 value1
    toc\_varset var2 value2
    \.\.\.
    toc\_varset varK valueK
    toc\_initialize
    toc\_setup 1
    \.\.\.
    toc\_setup 2
    \.\.\.
    \.\.\.
    toc\_setup n
    \.\.\.
    toc\_postprocess
    toc\_shutdown
    \.\.\.

I\.e\. first the number of passes and the set of available engine parameters is
established, followed by calls setting the parameters\. That second part is
optional\.

After that the plugin is initialized, the specified number of passes executed,
the final result run through a global post processing step and at last the







|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
  1. initialize and shutdown each pass

  1. query and initialize engine parameters

After the plugin has been loaded and the frontend commands are established the
commands will be called in the following sequence:

    toc_numpasses -> n
    toc_listvariables -> vars

    toc_varset var1 value1
    toc_varset var2 value2
    ...
    toc_varset varK valueK
    toc_initialize
    toc_setup 1
    ...
    toc_setup 2
    ...
    ...
    toc_setup n
    ...
    toc_postprocess
    toc_shutdown
    ...

I\.e\. first the number of passes and the set of available engine parameters is
established, followed by calls setting the parameters\. That second part is
optional\.

After that the plugin is initialized, the specified number of passes executed,
the final result run through a global post processing step and at last the
Changes to embedded/md/tcllib/files/modules/doctools/doctools.md.
1
2
3
4
5
6
7
8
9
10
11
12

[//000000001]: # (doctools \- Documentation tools)
[//000000002]: # (Generated from file 'doctools\.man' by tcllib/doctools with format 'markdown')
[//000000003]: # (Copyright &copy; 2003\-2019 Andreas Kupries <andreas\_kupries@users\.sourceforge\.net>)
[//000000004]: # (doctools\(n\) 1\.5\.1 tcllib "Documentation tools")

<hr> [ <a href="../../../../toc.md">Main Table Of Contents</a> &#124; <a
href="../../../toc.md">Table Of Contents</a> &#124; <a
href="../../../../index.md">Keyword Index</a> &#124; <a
href="../../../../toc0.md">Categories</a> &#124; <a
href="../../../../toc1.md">Modules</a> &#124; <a
href="../../../../toc2.md">Applications</a> ] <hr>




|







1
2
3
4
5
6
7
8
9
10
11
12

[//000000001]: # (doctools \- Documentation tools)
[//000000002]: # (Generated from file 'doctools\.man' by tcllib/doctools with format 'markdown')
[//000000003]: # (Copyright &copy; 2003\-2019 Andreas Kupries <andreas\_kupries@users\.sourceforge\.net>)
[//000000004]: # (doctools\(n\) 1\.5\.2 tcllib "Documentation tools")

<hr> [ <a href="../../../../toc.md">Main Table Of Contents</a> &#124; <a
href="../../../toc.md">Table Of Contents</a> &#124; <a
href="../../../../index.md">Keyword Index</a> &#124; <a
href="../../../../toc0.md">Categories</a> &#124; <a
href="../../../../toc1.md">Modules</a> &#124; <a
href="../../../../toc2.md">Applications</a> ] <hr>
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  - [Category](#category)

  - [Copyright](#copyright)

# <a name='synopsis'></a>SYNOPSIS

package require Tcl 8\.2  
package require doctools ?1\.5\.1?  

[__::doctools::new__ *objectName* ?*option value*\.\.\.?](#1)  
[__::doctools::help__](#2)  
[__::doctools::search__ *path*](#3)  
[__objectName__ __method__ ?*arg arg \.\.\.*?](#4)  
[*objectName* __configure__](#5)  
[*objectName* __configure__ *option*](#6)  







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  - [Category](#category)

  - [Copyright](#copyright)

# <a name='synopsis'></a>SYNOPSIS

package require Tcl 8\.2  
package require doctools ?1\.5\.2?  

[__::doctools::new__ *objectName* ?*option value*\.\.\.?](#1)  
[__::doctools::help__](#2)  
[__::doctools::search__ *path*](#3)  
[__objectName__ __method__ ?*arg arg \.\.\.*?](#4)  
[*objectName* __configure__](#5)  
[*objectName* __configure__ *option*](#6)  
Changes to embedded/md/tcllib/files/modules/doctools/doctools_lang_intro.md.
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
consists primarily of text, with markup commands embedded into it\.

Each markup command is a Tcl command surrounded by a matching pair of __\[__
and __\]__\. Inside of these delimiters the usual rules for a Tcl command
apply with regard to word quotation, nested commands, continuation lines, etc\.
I\.e\.

    \.\.\. \[list\_begin enumerated\] \.\.\.

    \.\.\. \[call \[cmd foo\] \\\\
            \[arg bar\]\] \.\.\.

    \.\.\. \[term \{complex concept\}\] \.\.\.

    \.\.\. \[opt "\[arg key\] \[arg value\]"\] \.\.\.

## <a name='subsection2'></a>Basic structure

The most simple document which can be written in doctools is

        \[manpage\_begin NAME SECTION VERSION\]
    \[see\_also doctools\_intro\]
    \[see\_also doctools\_lang\_cmdref\]
    \[see\_also doctools\_lang\_faq\]
    \[see\_also doctools\_lang\_syntax\]
    \[keywords \{doctools commands\}\]
    \[keywords \{doctools language\}\]
    \[keywords \{doctools markup\}\]
    \[keywords \{doctools syntax\}\]
    \[keywords markup\]
    \[keywords \{semantic markup\}\]
        \[description\]
        \[vset CATEGORY doctools\]
    \[include \.\./doctools2base/include/feedback\.inc\]
    \[manpage\_end\]

This also shows us that all doctools documents are split into two parts, the
*header* and the *body*\. Everything coming before \[__description__\]
belongs to the header, and everything coming after belongs to the body, with the
whole document bracketed by the two __manpage\_\*__ commands\. Before and after
these opening and closing commands we have only *whitespace*\.








|

|
|

|

|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
consists primarily of text, with markup commands embedded into it\.

Each markup command is a Tcl command surrounded by a matching pair of __\[__
and __\]__\. Inside of these delimiters the usual rules for a Tcl command
apply with regard to word quotation, nested commands, continuation lines, etc\.
I\.e\.

    ... [list_begin enumerated] ...

    ... [call [cmd foo] \\
            [arg bar]] ...

    ... [term {complex concept}] ...

    ... [opt "[arg key] [arg value]"] ...

## <a name='subsection2'></a>Basic structure

The most simple document which can be written in doctools is

        [manpage_begin NAME SECTION VERSION]
    [see_also doctools_intro]
    [see_also doctools_lang_cmdref]
    [see_also doctools_lang_faq]
    [see_also doctools_lang_syntax]
    [keywords {doctools commands}]
    [keywords {doctools language}]
    [keywords {doctools markup}]
    [keywords {doctools syntax}]
    [keywords markup]
    [keywords {semantic markup}]
        [description]
        [vset CATEGORY doctools]
    [include ../doctools2base/include/feedback.inc]
    [manpage_end]

This also shows us that all doctools documents are split into two parts, the
*header* and the *body*\. Everything coming before \[__description__\]
belongs to the header, and everything coming after belongs to the body, with the
whole document bracketed by the two __manpage\_\*__ commands\. Before and after
these opening and closing commands we have only *whitespace*\.

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
and they can be used in any order\. However for __titledesc__ and
__moddesc__ only the last occurrence is taken\. For the other two the
specified information is accumulated, in the given order\. Regular text is not
allowed within the header\.

Given the above a less minimal example of a document is

    \[manpage\_begin NAME SECTION VERSION\]
    \[__copyright \{YEAR AUTHOR\}__\]
    \[__titledesc TITLE__\]
    \[__moddesc   MODULE\_TITLE__\]
    \[__require   PACKAGE VERSION__\]
    \[__require   PACKAGE__\]
    \[description\]
    \[manpage\_end\]

Remember that the whitespace is optional\. The document

        \[manpage\_begin NAME SECTION VERSION\]
        \[copyright \{YEAR AUTHOR\}\]\[titledesc TITLE\]\[moddesc MODULE\_TITLE\]
        \[require PACKAGE VERSION\]\[require PACKAGE\]\[description\]
        \[vset CATEGORY doctools\]
    \[include \.\./doctools2base/include/feedback\.inc\]
    \[manpage\_end\]

has the same meaning as the example before\.

On the other hand, if *whitespace* is present it consists not only of any
sequence of characters containing the space character, horizontal and vertical
tabs, carriage return, and newline, but it may contain comment markup as well,
in the form of the __[comment](\.\./\.\./\.\./\.\./index\.md\#comment)__ command\.

    \[__comment \{ \.\.\. \}__\]
    \[manpage\_begin NAME SECTION VERSION\]
    \[copyright \{YEAR AUTHOR\}\]
    \[titledesc TITLE\]
    \[moddesc   MODULE\_TITLE\]\[__comment \{ \.\.\. \}__\]
    \[require   PACKAGE VERSION\]
    \[require   PACKAGE\]
    \[description\]
    \[manpage\_end\]
    \[__comment \{ \.\.\. \}__\]

## <a name='subsection3'></a>Advanced structure

In the simple examples of the last section we fudged a bit regarding the markup
actually allowed to be used before the __manpage\_begin__ command opening the
document\.

Instead of only whitespace the two templating commands __include__ and
__vset__ are also allowed, to enable the writer to either set and/or import
configuration settings relevant to the document\. I\.e\. it is possible to write

    \[__include FILE__\]
    \[__vset VAR VALUE__\]
    \[manpage\_begin NAME SECTION VERSION\]
    \[description\]
    \[manpage\_end\]

Even more important, these two commands are allowed anywhere where a markup
command is allowed, without regard for any other structure\. I\.e\. for example in
the header as well\.

    \[manpage\_begin NAME SECTION VERSION\]
    \[__include FILE__\]
    \[__vset VAR VALUE__\]
    \[description\]
    \[manpage\_end\]

The only restriction __include__ has to obey is that the contents of the
included file must be valid at the place of the inclusion\. I\.e\. a file included
before __manpage\_begin__ may contain only the templating commands
__vset__ and __include__, a file included in the header may contain only
header commands, etc\.








|
|
|
|
|
|
|
|



|
|
|
|
|
|








|
|
|
|
|
|
|
|
|
|











|
|
|
|
|





|
|
|
|
|







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
and they can be used in any order\. However for __titledesc__ and
__moddesc__ only the last occurrence is taken\. For the other two the
specified information is accumulated, in the given order\. Regular text is not
allowed within the header\.

Given the above a less minimal example of a document is

    [manpage_begin NAME SECTION VERSION]
    [__copyright {YEAR AUTHOR}__]
    [__titledesc TITLE__]
    [__moddesc   MODULE_TITLE__]
    [__require   PACKAGE VERSION__]
    [__require   PACKAGE__]
    [description]
    [manpage_end]

Remember that the whitespace is optional\. The document

        [manpage_begin NAME SECTION VERSION]
        [copyright {YEAR AUTHOR}][titledesc TITLE][moddesc MODULE_TITLE]
        [require PACKAGE VERSION][require PACKAGE][description]
        [vset CATEGORY doctools]
    [include ../doctools2base/include/feedback.inc]
    [manpage_end]

has the same meaning as the example before\.

On the other hand, if *whitespace* is present it consists not only of any
sequence of characters containing the space character, horizontal and vertical
tabs, carriage return, and newline, but it may contain comment markup as well,
in the form of the __[comment](\.\./\.\./\.\./\.\./index\.md\#comment)__ command\.

    [__comment { ... }__]
    [manpage_begin NAME SECTION VERSION]
    [copyright {YEAR AUTHOR}]
    [titledesc TITLE]
    [moddesc   MODULE_TITLE][__comment { ... }__]
    [require   PACKAGE VERSION]
    [require   PACKAGE]
    [description]
    [manpage_end]
    [__comment { ... }__]

## <a name='subsection3'></a>Advanced structure

In the simple examples of the last section we fudged a bit regarding the markup
actually allowed to be used before the __manpage\_begin__ command opening the
document\.

Instead of only whitespace the two templating commands __include__ and
__vset__ are also allowed, to enable the writer to either set and/or import
configuration settings relevant to the document\. I\.e\. it is possible to write

    [__include FILE__]
    [__vset VAR VALUE__]
    [manpage_begin NAME SECTION VERSION]
    [description]
    [manpage_end]

Even more important, these two commands are allowed anywhere where a markup
command is allowed, without regard for any other structure\. I\.e\. for example in
the header as well\.

    [manpage_begin NAME SECTION VERSION]
    [__include FILE__]
    [__vset VAR VALUE__]
    [description]
    [manpage_end]

The only restriction __include__ has to obey is that the contents of the
included file must be valid at the place of the inclusion\. I\.e\. a file included
before __manpage\_begin__ may contain only the templating commands
__vset__ and __include__, a file included in the header may contain only
header commands, etc\.

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
The simplest way of structuring the body is through the introduction of
paragraphs\. The command for doing so is __para__\. Each occurrence of this
command closes the previous paragraph and automatically opens the next\. The
first paragraph is automatically opened at the beginning of the body, by
__description__\. In the same manner the last paragraph automatically ends at
__manpage\_end__\.

    \[manpage\_begin NAME SECTION VERSION\]
    \[description\]
     \.\.\.
    \[__para__\]
     \.\.\.
    \[__para__\]
     \.\.\.
    \[manpage\_end\]

Empty paragraphs are ignored\.

A structure coarser than paragraphs are sections, which allow the writer to
split a document into larger, and labeled, pieces\. The command for doing so is
__section__\. Each occurrence of this command closes the previous section and
automatically opens the next, including its first paragraph\. The first section
is automatically opened at the beginning of the body, by __description__
\(This section is labeled "DESCRIPTION"\)\. In the same manner the last section
automatically ends at __manpage\_end__\.

Empty sections are *not* ignored\. We are free to \(not\) use paragraphs within
sections\.

    \[manpage\_begin NAME SECTION VERSION\]
    \[description\]
     \.\.\.
    \[__section \{Section A\}__\]
     \.\.\.
    \[para\]
     \.\.\.
    \[__section \{Section B\}__\]
     \.\.\.
    \[manpage\_end\]

Between sections and paragraphs we have subsections, to split sections\. The
command for doing so is __subsection__\. Each occurrence of this command
closes the previous subsection and automatically opens the next, including its
first paragraph\. A subsection is automatically opened at the beginning of the
body, by __description__, and at the beginning of each section\. In the same
manner the last subsection automatically ends at __manpage\_end__\.

Empty subsections are *not* ignored\. We are free to \(not\) use paragraphs
within subsections\.

    \[manpage\_begin NAME SECTION VERSION\]
    \[description\]
     \.\.\.
    \[section \{Section A\}\]
     \.\.\.
    \[__subsection \{Sub 1\}__\]
     \.\.\.
    \[para\]
     \.\.\.
    \[__subsection \{Sub 2\}__\]
     \.\.\.
    \[section \{Section B\}\]
     \.\.\.
    \[manpage\_end\]

## <a name='subsection5'></a>Text markup

Having handled the overall structure a writer can impose on the document we now
take a closer at the text in a paragraph\.

While most often this is just the unadorned content of the document we do have







|
|
|
|
|
|
|
|














|
|
|
|
|
|
|
|
|
|











|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
The simplest way of structuring the body is through the introduction of
paragraphs\. The command for doing so is __para__\. Each occurrence of this
command closes the previous paragraph and automatically opens the next\. The
first paragraph is automatically opened at the beginning of the body, by
__description__\. In the same manner the last paragraph automatically ends at
__manpage\_end__\.

    [manpage_begin NAME SECTION VERSION]
    [description]
     ...
    [__para__]
     ...
    [__para__]
     ...
    [manpage_end]

Empty paragraphs are ignored\.

A structure coarser than paragraphs are sections, which allow the writer to
split a document into larger, and labeled, pieces\. The command for doing so is
__section__\. Each occurrence of this command closes the previous section and
automatically opens the next, including its first paragraph\. The first section
is automatically opened at the beginning of the body, by __description__
\(This section is labeled "DESCRIPTION"\)\. In the same manner the last section
automatically ends at __manpage\_end__\.

Empty sections are *not* ignored\. We are free to \(not\) use paragraphs within
sections\.

    [manpage_begin NAME SECTION VERSION]
    [description]
     ...
    [__section {Section A}__]
     ...
    [para]
     ...
    [__section {Section B}__]
     ...
    [manpage_end]

Between sections and paragraphs we have subsections, to split sections\. The
command for doing so is __subsection__\. Each occurrence of this command
closes the previous subsection and automatically opens the next, including its
first paragraph\. A subsection is automatically opened at the beginning of the
body, by __description__, and at the beginning of each section\. In the same
manner the last subsection automatically ends at __manpage\_end__\.

Empty subsections are *not* ignored\. We are free to \(not\) use paragraphs
within subsections\.

    [manpage_begin NAME SECTION VERSION]
    [description]
     ...
    [section {Section A}]
     ...
    [__subsection {Sub 1}__]
     ...
    [para]
     ...
    [__subsection {Sub 2}__]
     ...
    [section {Section B}]
     ...
    [manpage_end]

## <a name='subsection5'></a>Text markup

Having handled the overall structure a writer can impose on the document we now
take a closer at the text in a paragraph\.

While most often this is just the unadorned content of the document we do have
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
    Its argument is a widget name\.

The example demonstrating the use of text markup is an excerpt from the
*[doctools language command reference](doctools\_lang\_cmdref\.md)*, with
some highlighting added\. It shows their use within a block of text, as the
arguments of a list item command \(__call__\), and our ability to nest them\.

    \.\.\.
    \[call \[__cmd arg\_def__\] \[__arg type__\] \[__arg name__\] \[__opt__ \[__arg mode__\]\]\]

    Text structure\. List element\. Argument list\. Automatically closes the
    previous list element\. Specifies the data\-\[__arg type__\] of the described
    argument of a command, its \[__arg name__\] and its i/o\-\[__arg mode__\]\. The
    latter is optional\.
    \.\.\.

## <a name='subsection6'></a>Escapes

Beyond the 20 commands for simple markup shown in the previous section we have
two more available which are technically simple markup\. However their function
is not the marking up of phrases as specific types of things, but the insertion
of characters, namely __\[__ and __\]__\. These commands, __lb__ and
__rb__ respectively, are required because our use of \[ and \] to bracket
markup commands makes it impossible to directly use \[ and \] within the text\.

Our example of their use are the sources of the last sentence in the previous
paragraph, with some highlighting added\.

    \.\.\.
    These commands, \[cmd lb\] and \[cmd lb\] respectively, are required
    because our use of \[__lb__\] and \[__rb__\] to bracket markup commands makes it
    impossible to directly use \[__lb__\] and \[__rb__\] within the text\.
    \.\.\.

## <a name='subsection7'></a>Cross\-references

The last two commands we have to discuss are for the declaration of
cross\-references between documents, explicit and implicit\. They are
__[keywords](\.\./\.\./\.\./\.\./index\.md\#keywords)__ and __see\_also__\. Both
take an arbitrary number of arguments, all of which have to be plain unmarked







|
|

|
|
|
|
|













|
|
|
|
|







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
    Its argument is a widget name\.

The example demonstrating the use of text markup is an excerpt from the
*[doctools language command reference](doctools\_lang\_cmdref\.md)*, with
some highlighting added\. It shows their use within a block of text, as the
arguments of a list item command \(__call__\), and our ability to nest them\.

    ...
    [call [__cmd arg_def__] [__arg type__] [__arg name__] [__opt__ [__arg mode__]]]

    Text structure. List element. Argument list. Automatically closes the
    previous list element. Specifies the data-[__arg type__] of the described
    argument of a command, its [__arg name__] and its i/o-[__arg mode__]. The
    latter is optional.
    ...

## <a name='subsection6'></a>Escapes

Beyond the 20 commands for simple markup shown in the previous section we have
two more available which are technically simple markup\. However their function
is not the marking up of phrases as specific types of things, but the insertion
of characters, namely __\[__ and __\]__\. These commands, __lb__ and
__rb__ respectively, are required because our use of \[ and \] to bracket
markup commands makes it impossible to directly use \[ and \] within the text\.

Our example of their use are the sources of the last sentence in the previous
paragraph, with some highlighting added\.

    ...
    These commands, [cmd lb] and [cmd lb] respectively, are required
    because our use of [__lb__] and [__rb__] to bracket markup commands makes it
    impossible to directly use [__lb__] and [__rb__] within the text.
    ...

## <a name='subsection7'></a>Cross\-references

The last two commands we have to discuss are for the declaration of
cross\-references between documents, explicit and implicit\. They are
__[keywords](\.\./\.\./\.\./\.\./index\.md\#keywords)__ and __see\_also__\. Both
take an arbitrary number of arguments, all of which have to be plain unmarked
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
whether she wants to have them at the beginning of the body, or at its end,
maybe near the place a keyword is actually defined by the main content, or
considers them as meta data which should be in the header, etc\.

Our example shows the sources for the cross\-references of this document, with
some highlighting added\. Incidentally they are found at the end of the body\.

    \.\.\.
    \[__see\_also doctools\_intro__\]
    \[__see\_also doctools\_lang\_syntax__\]
    \[__see\_also doctools\_lang\_cmdref__\]
    \[__keywords markup \{semantic markup\}__\]
    \[__keywords \{doctools markup\} \{doctools language\}__\]
    \[__keywords \{doctools syntax\} \{doctools commands\}__\]
    \[manpage\_end\]

## <a name='subsection8'></a>Examples

Where ever we can write plain text we can write examples too\. For simple
examples we have the command __example__ which takes a single argument, the
text of the argument\. The example text must not contain markup\. If we wish to
have markup within an example we have to use the 2\-command combination
__example\_begin__ / __example\_end__ instead\.

The first opens an example block, the other closes it, and in between we can
write plain text and use all the regular text markup commands\. Note that text
structure commands are not allowed\. This also means that it is not possible to
embed examples and lists within an example\. On the other hand, we *can* use
templating commands within example blocks to read their contents from a file
\(Remember section [Advanced structure](#subsection3)\)\.

The source for the very first example in this document \(see section
[Fundamentals](#subsection1)\), with some highlighting added, is

    \[__example__ \{
        \.\.\. \[list\_begin enumerated\] \.\.\.
      \}\]

Using __example\_begin__ / __example\_end__ this would look like

    \[__example\_begin__\]
        \.\.\. \[list\_begin enumerated\] \.\.\.
      \[__example\_end__\]

## <a name='subsection9'></a>Lists

Where ever we can write plain text we can write lists too\. The main commands are
__list\_begin__ to start a list, and __list\_end__ to close one\. The
opening command takes an argument specifying the type of list started it, and
this in turn determines which of the eight existing list item commands are







|
|
|
|
|
|
|
|



















|
|
|



|
|
|







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
whether she wants to have them at the beginning of the body, or at its end,
maybe near the place a keyword is actually defined by the main content, or
considers them as meta data which should be in the header, etc\.

Our example shows the sources for the cross\-references of this document, with
some highlighting added\. Incidentally they are found at the end of the body\.

    ...
    [__see_also doctools_intro__]
    [__see_also doctools_lang_syntax__]
    [__see_also doctools_lang_cmdref__]
    [__keywords markup {semantic markup}__]
    [__keywords {doctools markup} {doctools language}__]
    [__keywords {doctools syntax} {doctools commands}__]
    [manpage_end]

## <a name='subsection8'></a>Examples

Where ever we can write plain text we can write examples too\. For simple
examples we have the command __example__ which takes a single argument, the
text of the argument\. The example text must not contain markup\. If we wish to
have markup within an example we have to use the 2\-command combination
__example\_begin__ / __example\_end__ instead\.

The first opens an example block, the other closes it, and in between we can
write plain text and use all the regular text markup commands\. Note that text
structure commands are not allowed\. This also means that it is not possible to
embed examples and lists within an example\. On the other hand, we *can* use
templating commands within example blocks to read their contents from a file
\(Remember section [Advanced structure](#subsection3)\)\.

The source for the very first example in this document \(see section
[Fundamentals](#subsection1)\), with some highlighting added, is

    [__example__ {
        ... [list_begin enumerated] ...
      }]

Using __example\_begin__ / __example\_end__ this would look like

    [__example_begin__]
        ... [list_begin enumerated] ...
      [__example_end__]

## <a name='subsection9'></a>Lists

Where ever we can write plain text we can write lists too\. The main commands are
__list\_begin__ to start a list, and __list\_end__ to close one\. The
opening command takes an argument specifying the type of list started it, and
this in turn determines which of the eight existing list item commands are
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
    is a specialized form of a term definition list where the term is the name
    of a configuration option for a widget, with its name and class in the
    option database\.

Our example is the source of the definition list in the previous paragraph, with
most of the content in the middle removed\.

    \.\.\.
    \[__list\_begin__ definitions\]
    \[__def__ \[const arg\]\]

    \(\[cmd arg\_def\]\) This opens an argument \(declaration\) list\. It is a
    specialized form of a definition list where the term is an argument
    name, with its type and i/o\-mode\.

    \[__def__ \[const itemized\]\]

    \(\[cmd item\]\)
    This opens a general itemized list\.

    \.\.\.
    \[__def__ \[const tkoption\]\]

    \(\[cmd tkoption\_def\]\) This opens a widget option \(declaration\) list\. It
    is a specialized form of a definition list where the term is the name
    of a configuration option for a widget, with its name and class in the
    option database\.

    \[__list\_end__\]
    \.\.\.

Note that a list cannot begin in one \(sub\)section and end in another\.
Differently said, \(sub\)section breaks are not allowed within lists and list
items\. An example of this *illegal* construct is

    \.\.\.
    \[list\_begin itemized\]
    \[item\]
    \.\.\.
    \[__section \{ILLEGAL WITHIN THE LIST\}__\]
    \.\.\.
    \[list\_end\]
    \.\.\.

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of documentation should be fortified enough to be able to understand the formal
*[doctools language syntax](doctools\_lang\_syntax\.md)* specification as
well\. From here on out the *[doctools language command







|
|
|

|

|

|

|
|

|
|

|


|

|
|





|
|
|
|
|
|
|
|







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
    is a specialized form of a term definition list where the term is the name
    of a configuration option for a widget, with its name and class in the
    option database\.

Our example is the source of the definition list in the previous paragraph, with
most of the content in the middle removed\.

    ...
    [__list_begin__ definitions]
    [__def__ [const arg]]

    ([cmd arg_def]) This opens an argument (declaration) list. It is a
    specialized form of a definition list where the term is an argument
    name, with its type and i/o-mode.

    [__def__ [const itemized]]

    ([cmd item])
    This opens a general itemized list.

    ...
    [__def__ [const tkoption]]

    ([cmd tkoption_def]) This opens a widget option (declaration) list. It
    is a specialized form of a definition list where the term is the name
    of a configuration option for a widget, with its name and class in the
    option database.

    [__list_end__]
    ...

Note that a list cannot begin in one \(sub\)section and end in another\.
Differently said, \(sub\)section breaks are not allowed within lists and list
items\. An example of this *illegal* construct is

    ...
    [list_begin itemized]
    [item]
    ...
    [__section {ILLEGAL WITHIN THE LIST}__]
    ...
    [list_end]
    ...

# <a name='section2'></a>FURTHER READING

Now that this document has been digested the reader, assumed to be a *writer*
of documentation should be fortified enough to be able to understand the formal
*[doctools language syntax](doctools\_lang\_syntax\.md)* specification as
well\. From here on out the *[doctools language command
Changes to embedded/md/tcllib/files/modules/doctools/doctools_lang_syntax.md.
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

  1. The construct LIST\_BEGIN<X> stands for the markup command
     __list\_begin__ with __X__ as its type argument\.

The syntax:

    manpage = defs
              MANPAGE\_BEGIN
              header
              DESCRIPTION
              body
              MANPAGE\_END
              \{ <WHITE> \}

    defs    = \{ INCLUDE &#124; VSET &#124; <WHITE> \}

    header  = \{ TITLEDESC &#124; MODDESC &#124; COPYRIGHT &#124; REQUIRE &#124; defs &#124; xref \}

    xref    = KEYWORDS &#124; SEE\_ALSO &#124; CATEGORY

    body    = paras \{ SECTION    sbody  \}
    sbody   = paras \{ SUBSECTION ssbody \}
    ssbody  = paras

    paras   = tblock \{ \(PARA &#124; NL\) tblock \}

    tblock  = \{ <TEXT> &#124; defs &#124; markup &#124; xref &#124; an\_example &#124; a\_list \}

    markup  = ARG     &#124; CLASS &#124; CMD     &#124; CONST     &#124; EMPH   &#124; FILE
            &#124; FUN     &#124; LB    &#124; METHOD  &#124; NAMESPACE &#124; OPT    &#124; OPTION
            &#124; PACKAGE &#124; RB    &#124; SECTREF &#124; STRONG    &#124; SYSCMD &#124; TERM
            &#124; TYPE    &#124; URI   &#124; USAGE   &#124; VAR       &#124; WIDGET

    example = EXAMPLE
            &#124; EXAMPLE\_BEGIN extext EXAMPLE\_END

    extext  = \{ <TEXT> &#124; defs &#124; markup \}

    a\_list  = LIST\_BEGIN<arguments>   argd\_list   LIST\_END
            &#124; LIST\_BEGIN<commands>    cmdd\_list   LIST\_END
            &#124; LIST\_BEGIN<definitions> def\_list    LIST\_END
            &#124; LIST\_BEGIN<enumerated>  enum\_list   LIST\_END
            &#124; LIST\_BEGIN<itemized>    item\_list   LIST\_END
            &#124; LIST\_BEGIN<options>     optd\_list   LIST\_END
            &#124; LIST\_BEGIN<tkoptions>   tkoptd\_list LIST\_END

    argd\_list   = \[ <WHITE> \] \{ ARG\_DEF      paras \}
    cmdd\_list   = \[ <WHITE> \] \{ CMD\_DEF      paras \}
    def\_list    = \[ <WHITE> \] \{ \(DEF&#124;CALL\)   paras \}
    enum\_list   = \[ <WHITE> \] \{ ENUM         paras \}
    item\_list   = \[ <WHITE> \] \{ ITEM         paras \}
    optd\_list   = \[ <WHITE> \] \{ OPT\_DEF      paras \}
    tkoptd\_list = \[ <WHITE> \] \{ TKOPTION\_DEF paras \}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|
|

|

|

|

|
|


|

|

|
|
|
|


|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|







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

  1. The construct LIST\_BEGIN<X> stands for the markup command
     __list\_begin__ with __X__ as its type argument\.

The syntax:

    manpage = defs
              MANPAGE_BEGIN
              header
              DESCRIPTION
              body
              MANPAGE_END
              { <WHITE> }

    defs    = { INCLUDE | VSET | <WHITE> }

    header  = { TITLEDESC | MODDESC | COPYRIGHT | REQUIRE | defs | xref }

    xref    = KEYWORDS | SEE_ALSO | CATEGORY

    body    = paras { SECTION    sbody  }
    sbody   = paras { SUBSECTION ssbody }
    ssbody  = paras

    paras   = tblock { (PARA | NL) tblock }

    tblock  = { <TEXT> | defs | markup | xref | an_example | a_list }

    markup  = ARG     | CLASS | CMD     | CONST     | EMPH   | FILE
            | FUN     | LB    | METHOD  | NAMESPACE | OPT    | OPTION
            | PACKAGE | RB    | SECTREF | STRONG    | SYSCMD | TERM
            | TYPE    | URI   | USAGE   | VAR       | WIDGET

    example = EXAMPLE
            | EXAMPLE_BEGIN extext EXAMPLE_END

    extext  = { <TEXT> | defs | markup }

    a_list  = LIST_BEGIN<arguments>   argd_list   LIST_END
            | LIST_BEGIN<commands>    cmdd_list   LIST_END
            | LIST_BEGIN<definitions> def_list    LIST_END
            | LIST_BEGIN<enumerated>  enum_list   LIST_END
            | LIST_BEGIN<itemized>    item_list   LIST_END
            | LIST_BEGIN<options>     optd_list   LIST_END
            | LIST_BEGIN<tkoptions>   tkoptd_list LIST_END

    argd_list   = [ <WHITE> ] { ARG_DEF      paras }
    cmdd_list   = [ <WHITE> ] { CMD_DEF      paras }
    def_list    = [ <WHITE> ] { (DEF|CALL)   paras }
    enum_list   = [ <WHITE> ] { ENUM         paras }
    item_list   = [ <WHITE> ] { ITEM         paras }
    optd_list   = [ <WHITE> ] { OPT_DEF      paras }
    tkoptd_list = [ <WHITE> ] { TKOPTION_DEF paras }

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/doctools/doctools_plugin_apiref.md.
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
  1. initialize and shutdown each pass

  1. query and initialize engine parameters

After the plugin has been loaded and the frontend commands are established the
commands will be called in the following sequence:

    fmt\_numpasses \-> n
    fmt\_listvariables \-> vars

    fmt\_varset var1 value1
    fmt\_varset var2 value2
    \.\.\.
    fmt\_varset varK valueK
    fmt\_initialize
    fmt\_setup 1
    \.\.\.
    fmt\_setup 2
    \.\.\.
    \.\.\.
    fmt\_setup n
    \.\.\.
    fmt\_postprocess
    fmt\_shutdown
    \.\.\.

I\.e\. first the number of passes and the set of available engine parameters is
established, followed by calls setting the parameters\. That second part is
optional\.

After that the plugin is initialized, the specified number of passes executed,
the final result run through a global post processing step and at last the







|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
  1. initialize and shutdown each pass

  1. query and initialize engine parameters

After the plugin has been loaded and the frontend commands are established the
commands will be called in the following sequence:

    fmt_numpasses -> n
    fmt_listvariables -> vars

    fmt_varset var1 value1
    fmt_varset var2 value2
    ...
    fmt_varset varK valueK
    fmt_initialize
    fmt_setup 1
    ...
    fmt_setup 2
    ...
    ...
    fmt_setup n
    ...
    fmt_postprocess
    fmt_shutdown
    ...

I\.e\. first the number of passes and the set of available engine parameters is
established, followed by calls setting the parameters\. That second part is
optional\.

After that the plugin is initialized, the specified number of passes executed,
the final result run through a global post processing step and at last the
Changes to embedded/md/tcllib/files/modules/doctools2idx/idx_export_json.md.
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

# <a name='section3'></a>JSON notation of keyword indices

The JSON format used for keyword indices is a direct translation of the
[Keyword index serialization format](#section5), mapping Tcl dictionaries
as JSON objects and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::idx \{
    	label \{Keyword Index\}
    	keywords \{
    		changelog  \{changelog\.man cvs\.man\}
    		conversion \{doctools\.man docidx\.man doctoc\.man apps/dtplite\.man mpexpand\.man\}
    		cvs        cvs\.man
    	\}

    	references \{
    		apps/dtplite\.man \{manpage dtplite\}
    		changelog\.man    \{manpage doctools::changelog\}
    		cvs\.man          \{manpage doctools::cvs\}
    		docidx\.man       \{manpage doctools::idx\}
    		doctoc\.man       \{manpage doctools::toc\}
    		doctools\.man     \{manpage doctools\}
    		mpexpand\.man     \{manpage mpexpand\}
    	\}

    	title \{\}
    \}


is equivalent to the JSON string

    \{

        "doctools::idx" : \{
            "label"      : "Keyword Index",
            "keywords"   : \{
                "changelog"  : \["changelog\.man","cvs\.man"\],
                "conversion" : \["doctools\.man","docidx\.man","doctoc\.man","apps\\/dtplite\.man","mpexpand\.man"\],
                "cvs"        : \["cvs\.man"\],
            \},
            "references" : \{
                "apps\\/dtplite\.man" : \["manpage","dtplite"\],
                "changelog\.man"     : \["manpage","doctools::changelog"\],
                "cvs\.man"           : \["manpage","doctools::cvs"\],
                "docidx\.man"        : \["manpage","doctools::idx"\],
                "doctoc\.man"        : \["manpage","doctools::toc"\],
                "doctools\.man"      : \["manpage","doctools"\],
                "mpexpand\.man"      : \["manpage","mpexpand"\]
            \},
            "title"      : ""
        \}
    \}



# <a name='section4'></a>Configuration

The JSON export plugin recognizes the following configuration variables and
changes its behaviour as they specify\.

  - boolean *indented*







|
|
|
|
|
|
<
>
|
|
|
|
|
|
|
|
<
>
|
<
|
>


<
>
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

<
<
>
>







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

# <a name='section3'></a>JSON notation of keyword indices

The JSON format used for keyword indices is a direct translation of the
[Keyword index serialization format](#section5), mapping Tcl dictionaries
as JSON objects and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::idx {
    	label {Keyword Index}
    	keywords {
    		changelog  {changelog.man cvs.man}
    		conversion {doctools.man docidx.man doctoc.man apps/dtplite.man mpexpand.man}
    		cvs        cvs.man

    	}
    	references {
    		apps/dtplite.man {manpage dtplite}
    		changelog.man    {manpage doctools::changelog}
    		cvs.man          {manpage doctools::cvs}
    		docidx.man       {manpage doctools::idx}
    		doctoc.man       {manpage doctools::toc}
    		doctools.man     {manpage doctools}
    		mpexpand.man     {manpage mpexpand}

    	}
    	title {}

    }

is equivalent to the JSON string


    {
        "doctools::idx" : {
            "label"      : "Keyword Index",
            "keywords"   : {
                "changelog"  : ["changelog.man","cvs.man"],
                "conversion" : ["doctools.man","docidx.man","doctoc.man","apps\/dtplite.man","mpexpand.man"],
                "cvs"        : ["cvs.man"],
            },
            "references" : {
                "apps\/dtplite.man" : ["manpage","dtplite"],
                "changelog.man"     : ["manpage","doctools::changelog"],
                "cvs.man"           : ["manpage","doctools::cvs"],
                "docidx.man"        : ["manpage","doctools::idx"],
                "doctoc.man"        : ["manpage","doctools::toc"],
                "doctools.man"      : ["manpage","doctools"],
                "mpexpand.man"      : ["manpage","mpexpand"]
            },
            "title"      : ""


        }
    }

# <a name='section4'></a>Configuration

The JSON export plugin recognizes the following configuration variables and
changes its behaviour as they specify\.

  - boolean *indented*
Changes to embedded/md/tcllib/files/modules/doctools2idx/idx_import_json.md.
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

# <a name='section3'></a>JSON notation of keyword indices

The JSON format used for keyword indices is a direct translation of the
[Keyword index serialization format](#section4), mapping Tcl dictionaries
as JSON objects and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::idx \{
    	label \{Keyword Index\}
    	keywords \{
    		changelog  \{changelog\.man cvs\.man\}
    		conversion \{doctools\.man docidx\.man doctoc\.man apps/dtplite\.man mpexpand\.man\}
    		cvs        cvs\.man
    	\}

    	references \{
    		apps/dtplite\.man \{manpage dtplite\}
    		changelog\.man    \{manpage doctools::changelog\}
    		cvs\.man          \{manpage doctools::cvs\}
    		docidx\.man       \{manpage doctools::idx\}
    		doctoc\.man       \{manpage doctools::toc\}
    		doctools\.man     \{manpage doctools\}
    		mpexpand\.man     \{manpage mpexpand\}
    	\}

    	title \{\}
    \}


is equivalent to the JSON string

    \{

        "doctools::idx" : \{
            "label"      : "Keyword Index",
            "keywords"   : \{
                "changelog"  : \["changelog\.man","cvs\.man"\],
                "conversion" : \["doctools\.man","docidx\.man","doctoc\.man","apps\\/dtplite\.man","mpexpand\.man"\],
                "cvs"        : \["cvs\.man"\],
            \},
            "references" : \{
                "apps\\/dtplite\.man" : \["manpage","dtplite"\],
                "changelog\.man"     : \["manpage","doctools::changelog"\],
                "cvs\.man"           : \["manpage","doctools::cvs"\],
                "docidx\.man"        : \["manpage","doctools::idx"\],
                "doctoc\.man"        : \["manpage","doctools::toc"\],
                "doctools\.man"      : \["manpage","doctools"\],
                "mpexpand\.man"      : \["manpage","mpexpand"\]
            \},
            "title"      : ""
        \}
    \}



# <a name='section4'></a>Keyword index serialization format

Here we specify the format used by the doctools v2 packages to serialize keyword
indices as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
<
>
|
|
|
|
|
|
|
|
<
>
|
<
|
>


<
>
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

<
<
>
>







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

# <a name='section3'></a>JSON notation of keyword indices

The JSON format used for keyword indices is a direct translation of the
[Keyword index serialization format](#section4), mapping Tcl dictionaries
as JSON objects and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::idx {
    	label {Keyword Index}
    	keywords {
    		changelog  {changelog.man cvs.man}
    		conversion {doctools.man docidx.man doctoc.man apps/dtplite.man mpexpand.man}
    		cvs        cvs.man

    	}
    	references {
    		apps/dtplite.man {manpage dtplite}
    		changelog.man    {manpage doctools::changelog}
    		cvs.man          {manpage doctools::cvs}
    		docidx.man       {manpage doctools::idx}
    		doctoc.man       {manpage doctools::toc}
    		doctools.man     {manpage doctools}
    		mpexpand.man     {manpage mpexpand}

    	}
    	title {}

    }

is equivalent to the JSON string


    {
        "doctools::idx" : {
            "label"      : "Keyword Index",
            "keywords"   : {
                "changelog"  : ["changelog.man","cvs.man"],
                "conversion" : ["doctools.man","docidx.man","doctoc.man","apps\/dtplite.man","mpexpand.man"],
                "cvs"        : ["cvs.man"],
            },
            "references" : {
                "apps\/dtplite.man" : ["manpage","dtplite"],
                "changelog.man"     : ["manpage","doctools::changelog"],
                "cvs.man"           : ["manpage","doctools::cvs"],
                "docidx.man"        : ["manpage","doctools::idx"],
                "doctoc.man"        : ["manpage","doctools::toc"],
                "doctools.man"      : ["manpage","doctools"],
                "mpexpand.man"      : ["manpage","mpexpand"]
            },
            "title"      : ""


        }
    }

# <a name='section4'></a>Keyword index serialization format

Here we specify the format used by the doctools v2 packages to serialize keyword
indices as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
Changes to embedded/md/tcllib/files/modules/doctools2idx/idx_introduction.md.
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
markup of *tables of contents*, and of general documentation, respectively\.
They are described in their own sets of documents, starting at the *DocTools \-
Tables Of Contents* and the *DocTools \- General*, respectively\.

# <a name='section3'></a>Package Overview

                                        ~~~~~~~~~~~ doctools::idx ~~~~~~~~~~~
                                       ~~                   &#124;               ~~
                    doctools::idx::export ~~~~~~~~~~~~~~~~~ &#124; ~~~~~~~~~~~~~ doctools::idx::import
                            &#124;                               &#124;                       &#124;
            \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+     &#124;    \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+
            &#124;               &#124;                         &#124;     &#124;    &#124;                  &#124;               &#124;                       &#124;               &#124;
    doctools::config        =                         &#124;     &#124;    &#124;                  =       doctools::include       doctools::config doctools::paths
                            &#124;                         &#124;     &#124;    &#124;                  &#124;
                    doctools::idx::export::<\*>        &#124;     &#124;    &#124;          doctools::idx::import::<\*>
                            docidx                    &#124;     &#124;    &#124;                  docidx, json
                            json                      &#124;     &#124;    &#124;                  &#124;           \\\\
                            html                      &#124;     &#124;    &#124;          doctools::idx::parse \\\\
                            nroff                     &#124;     &#124;    &#124;                  &#124;             \\\\
                            wiki                      &#124;     &#124;    &#124;  \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+              json
                            text                      &#124;     &#124;    &#124;  &#124;               &#124;
                                                    doctools::idx::structure        &#124;
                                                                                    &#124;

                                                                            \+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+
                                                                            &#124;                       &#124;
              doctools::html  doctools::html::cssdefaults           doctools::tcl::parse    doctools::msgcat
                    &#124;                                                                               &#124;
              doctools::text  doctools::nroff::man\_macros                                           =
                                                                                                    &#124;

                                                                                            doctools::msgcat::idx::<\*>
                                                                                                    c, en, de, fr
                                                                                                    \(fr == en for now\)
            ~~      Interoperable objects, without actual package dependencies
            \-\-      Package dependency, higher requires lower package
            =       Dynamic dependency through plugin system
            <\*>     Multiple packages following the given form of naming\.

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|

|
|
<
>
|

|

|

|







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
markup of *tables of contents*, and of general documentation, respectively\.
They are described in their own sets of documents, starting at the *DocTools \-
Tables Of Contents* and the *DocTools \- General*, respectively\.

# <a name='section3'></a>Package Overview

                                        ~~~~~~~~~~~ doctools::idx ~~~~~~~~~~~
                                       ~~                   |               ~~
                    doctools::idx::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::idx::import
                            |                               |                       |
            +---------------+-------------------------+     |    +------------------+---------------+-----------------------+---------------+
            |               |                         |     |    |                  |               |                       |               |
    doctools::config        =                         |     |    |                  =       doctools::include       doctools::config doctools::paths
                            |                         |     |    |                  |
                    doctools::idx::export::<*>        |     |    |          doctools::idx::import::<*>
                            docidx                    |     |    |                  docidx, json
                            json                      |     |    |                  |           \\
                            html                      |     |    |          doctools::idx::parse \\
                            nroff                     |     |    |                  |             \\
                            wiki                      |     |    |  +---------------+              json
                            text                      |     |    |  |               |
                                                    doctools::idx::structure        |

                                                                                    |
                                                                            +-------+---------------+
                                                                            |                       |
              doctools::html  doctools::html::cssdefaults           doctools::tcl::parse    doctools::msgcat
                    |                                                                               |
              doctools::text  doctools::nroff::man_macros                                           =

                                                                                                    |
                                                                                            doctools::msgcat::idx::<*>
                                                                                                    c, en, de, fr
                                                                                                    (fr == en for now)
            ~~      Interoperable objects, without actual package dependencies
            --      Package dependency, higher requires lower package
            =       Dynamic dependency through plugin system
            <*>     Multiple packages following the given form of naming.

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/doctools2toc/toc_export_json.md.
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

# <a name='section3'></a>JSON notation of tables of contents

The JSON format used for tables of contents is a direct translation of the [ToC
serialization format](#section5), mapping Tcl dictionaries as JSON objects
and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::toc \{
        items \{
            \{reference \{
    	    desc \{DocTools \- Tables of Contents\}
    	     id introduction\.man
    	     label doctools::toc::introduction
    	\}\}
    	\{division \{
    	     id processing\.man
    	     items \{
    	         \{reference \{
    		     desc \{doctoc serialization utilities\}
    		     id structure\.man
    		     label doctools::toc::structure
    		 \}\}
    		 \{reference \{
    		     desc \{Parsing text in doctoc format\}
    		     id parse\.man
    		     label doctools::toc::parse
    		 \}\}
    	     \}

                 label Processing
            \}\}
        \}

        label \{Table of Contents\}
        title TOC
    \}


is equivalent to the JSON string

    \{

        "doctools::toc" : \{
            "items" : \[\{
                "reference" : \{
                    "desc"  : "DocTools \- Tables of Contents",
                    "id"    : "introduction\.man",
                    "label" : "doctools::toc::introduction"

                \}
            \},\{
                "division" : \{
                    "id"    : "processing\.man",
                    "items" : \[\{
                        "reference" : \{
                            "desc"  : "doctoc serialization utilities",
                            "id"    : "structure\.man",
                            "label" : "doctools::toc::structure"

                        \}
                    \},\{
                        "reference" : \{
                            "desc"  : "Parsing text in doctoc format",
                            "id"    : "parse\.man",
                            "label" : "doctools::toc::parse"

                        \}
                    \}\],
                    "label" : "Processing"

                \}
            \}\],
            "label" : "Table of Contents",
            "title" : "TOC"
        \}
    \}



# <a name='section4'></a>Configuration

The JSON export plugin recognizes the following configuration variables and
changes its behaviour as they specify\.

  - boolean *indented*







|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|

<
|
>

<
|
>
|

<
>



<
>
|
|
|
|
|

>
|
<
|
|
|
|

|

>
|
<
|

|

>
|
<

>
|
<


<
<
>
>







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

# <a name='section3'></a>JSON notation of tables of contents

The JSON format used for tables of contents is a direct translation of the [ToC
serialization format](#section5), mapping Tcl dictionaries as JSON objects
and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::toc {
        items {
            {reference {
    	    desc {DocTools - Tables of Contents}
    	     id introduction.man
    	     label doctools::toc::introduction
    	}}
    	{division {
    	     id processing.man
    	     items {
    	         {reference {
    		     desc {doctoc serialization utilities}
    		     id structure.man
    		     label doctools::toc::structure
    		 }}
    		 {reference {
    		     desc {Parsing text in doctoc format}
    		     id parse.man
    		     label doctools::toc::parse

    		 }}
    	     }
                 label Processing

            }}
        }
        label {Table of Contents}
        title TOC

    }

is equivalent to the JSON string


    {
        "doctools::toc" : {
            "items" : [{
                "reference" : {
                    "desc"  : "DocTools - Tables of Contents",
                    "id"    : "introduction.man",
                    "label" : "doctools::toc::introduction"
                }
            },{

                "division" : {
                    "id"    : "processing.man",
                    "items" : [{
                        "reference" : {
                            "desc"  : "doctoc serialization utilities",
                            "id"    : "structure.man",
                            "label" : "doctools::toc::structure"
                        }
                    },{

                        "reference" : {
                            "desc"  : "Parsing text in doctoc format",
                            "id"    : "parse.man",
                            "label" : "doctools::toc::parse"
                        }
                    }],

                    "label" : "Processing"
                }
            }],

            "label" : "Table of Contents",
            "title" : "TOC"


        }
    }

# <a name='section4'></a>Configuration

The JSON export plugin recognizes the following configuration variables and
changes its behaviour as they specify\.

  - boolean *indented*
Changes to embedded/md/tcllib/files/modules/doctools2toc/toc_import_json.md.
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

# <a name='section3'></a>JSON notation of tables of contents

The JSON format used for tables of contents is a direct translation of the [ToC
serialization format](#section4), mapping Tcl dictionaries as JSON objects
and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::toc \{
        items \{
            \{reference \{
    	    desc \{DocTools \- Tables of Contents\}
    	     id introduction\.man
    	     label doctools::toc::introduction
    	\}\}
    	\{division \{
    	     id processing\.man
    	     items \{
    	         \{reference \{
    		     desc \{doctoc serialization utilities\}
    		     id structure\.man
    		     label doctools::toc::structure
    		 \}\}
    		 \{reference \{
    		     desc \{Parsing text in doctoc format\}
    		     id parse\.man
    		     label doctools::toc::parse
    		 \}\}
    	     \}

                 label Processing
            \}\}
        \}

        label \{Table of Contents\}
        title TOC
    \}


is equivalent to the JSON string

    \{

        "doctools::toc" : \{
            "items" : \[\{
                "reference" : \{
                    "desc"  : "DocTools \- Tables of Contents",
                    "id"    : "introduction\.man",
                    "label" : "doctools::toc::introduction"

                \}
            \},\{
                "division" : \{
                    "id"    : "processing\.man",
                    "items" : \[\{
                        "reference" : \{
                            "desc"  : "doctoc serialization utilities",
                            "id"    : "structure\.man",
                            "label" : "doctools::toc::structure"

                        \}
                    \},\{
                        "reference" : \{
                            "desc"  : "Parsing text in doctoc format",
                            "id"    : "parse\.man",
                            "label" : "doctools::toc::parse"

                        \}
                    \}\],
                    "label" : "Processing"

                \}
            \}\],
            "label" : "Table of Contents",
            "title" : "TOC"
        \}
    \}



# <a name='section4'></a>ToC serialization format

Here we specify the format used by the doctools v2 packages to serialize tables
of contents as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|

<
|
>

<
|
>
|

<
>



<
>
|
|
|
|
|

>
|
<
|
|
|
|

|

>
|
<
|

|

>
|
<

>
|
<


<
<
>
>







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

# <a name='section3'></a>JSON notation of tables of contents

The JSON format used for tables of contents is a direct translation of the [ToC
serialization format](#section4), mapping Tcl dictionaries as JSON objects
and Tcl lists as JSON arrays\. For example, the Tcl serialization

    doctools::toc {
        items {
            {reference {
    	    desc {DocTools - Tables of Contents}
    	     id introduction.man
    	     label doctools::toc::introduction
    	}}
    	{division {
    	     id processing.man
    	     items {
    	         {reference {
    		     desc {doctoc serialization utilities}
    		     id structure.man
    		     label doctools::toc::structure
    		 }}
    		 {reference {
    		     desc {Parsing text in doctoc format}
    		     id parse.man
    		     label doctools::toc::parse

    		 }}
    	     }
                 label Processing

            }}
        }
        label {Table of Contents}
        title TOC

    }

is equivalent to the JSON string


    {
        "doctools::toc" : {
            "items" : [{
                "reference" : {
                    "desc"  : "DocTools - Tables of Contents",
                    "id"    : "introduction.man",
                    "label" : "doctools::toc::introduction"
                }
            },{

                "division" : {
                    "id"    : "processing.man",
                    "items" : [{
                        "reference" : {
                            "desc"  : "doctoc serialization utilities",
                            "id"    : "structure.man",
                            "label" : "doctools::toc::structure"
                        }
                    },{

                        "reference" : {
                            "desc"  : "Parsing text in doctoc format",
                            "id"    : "parse.man",
                            "label" : "doctools::toc::parse"
                        }
                    }],

                    "label" : "Processing"
                }
            }],

            "label" : "Table of Contents",
            "title" : "TOC"


        }
    }

# <a name='section4'></a>ToC serialization format

Here we specify the format used by the doctools v2 packages to serialize tables
of contents as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
Changes to embedded/md/tcllib/files/modules/doctools2toc/toc_introduction.md.
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
markup of *keyword indices*, and of general documentation, respectively\. They
are described in their own sets of documents, starting at the *DocTools \-
Keyword Indices* and the *DocTools \- General*, respectively\.

# <a name='section3'></a>Package Overview

                                        ~~~~~~~~~~~ doctools::toc ~~~~~~~~~~~
                                       ~~                   &#124;               ~~
                    doctools::toc::export ~~~~~~~~~~~~~~~~~ &#124; ~~~~~~~~~~~~~ doctools::toc::import
                            &#124;                               &#124;                       &#124;
            \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+     &#124;    \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+
            &#124;               &#124;                         &#124;     &#124;    &#124;                  &#124;               &#124;                       &#124;               &#124;
    doctools::config        =                         &#124;     &#124;    &#124;                  =       doctools::include       doctools::config doctools::paths
                            &#124;                         &#124;     &#124;    &#124;                  &#124;
                    doctools::toc::export::<\*>        &#124;     &#124;    &#124;          doctools::toc::import::<\*>
                            doctoc                    &#124;     &#124;    &#124;                  doctoc, json
                            json                      &#124;     &#124;    &#124;                  &#124;           \\\\
                            html                      &#124;     &#124;    &#124;          doctools::toc::parse \\\\
                            nroff                     &#124;     &#124;    &#124;                  &#124;             \\\\
                            wiki                      &#124;     &#124;    &#124;  \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+              json
                            text                      &#124;     &#124;    &#124;  &#124;               &#124;
                                                    doctools::toc::structure        &#124;
                                                                                    &#124;

                                                                            \+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+
                                                                            &#124;                       &#124;
              doctools::html  doctools::html::cssdefaults           doctools::tcl::parse    doctools::msgcat
                    &#124;                                                                               &#124;
              doctools::text  doctools::nroff::man\_macros                                           =
                                                                                                    &#124;

                                                                                            doctools::msgcat::toc::<\*>
                                                                                                    c, en, de, fr
                                                                                                    \(fr == en for now\)
            ~~      Interoperable objects, without actual package dependencies
            \-\-      Package dependency, higher requires lower package
            =       Dynamic dependency through plugin system
            <\*>     Multiple packages following the given form of naming\.

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
|

|
|
<
>
|

|

|

|







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
markup of *keyword indices*, and of general documentation, respectively\. They
are described in their own sets of documents, starting at the *DocTools \-
Keyword Indices* and the *DocTools \- General*, respectively\.

# <a name='section3'></a>Package Overview

                                        ~~~~~~~~~~~ doctools::toc ~~~~~~~~~~~
                                       ~~                   |               ~~
                    doctools::toc::export ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~ doctools::toc::import
                            |                               |                       |
            +---------------+-------------------------+     |    +------------------+---------------+-----------------------+---------------+
            |               |                         |     |    |                  |               |                       |               |
    doctools::config        =                         |     |    |                  =       doctools::include       doctools::config doctools::paths
                            |                         |     |    |                  |
                    doctools::toc::export::<*>        |     |    |          doctools::toc::import::<*>
                            doctoc                    |     |    |                  doctoc, json
                            json                      |     |    |                  |           \\
                            html                      |     |    |          doctools::toc::parse \\
                            nroff                     |     |    |                  |             \\
                            wiki                      |     |    |  +---------------+              json
                            text                      |     |    |  |               |
                                                    doctools::toc::structure        |

                                                                                    |
                                                                            +-------+---------------+
                                                                            |                       |
              doctools::html  doctools::html::cssdefaults           doctools::tcl::parse    doctools::msgcat
                    |                                                                               |
              doctools::text  doctools::nroff::man_macros                                           =

                                                                                                    |
                                                                                            doctools::msgcat::toc::<*>
                                                                                                    c, en, de, fr
                                                                                                    (fr == en for now)
            ~~      Interoperable objects, without actual package dependencies
            --      Package dependency, higher requires lower package
            =       Dynamic dependency through plugin system
            <*>     Multiple packages following the given form of naming.

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *doctools* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/dtplite/pkg_dtplite.md.
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
  - \[2\]

    The following directory structure is created when processing a single set of
    input documents\. The file extension used is for output in HTML, but that is
    not relevant to the structure and was just used to have proper file names\.

        output/
            toc\.html
            index\.html
            files/
                path/to/FOO\.html

    The last line in the example shows the document generated for a file FOO
    located at

        inputdirectory/path/to/FOO

  - \[3\]

    When merging many packages into a unified set of documents the generated
    directory structure is a bit deeper:

        output
            \.toc
            \.idx
            \.tocdoc
            \.idxdoc
            \.xrf
            toc\.html
            index\.html
            FOO1/
                \.\.\.
            FOO2/
                toc\.html
                files/
                    path/to/BAR\.html

    Each of the directories FOO1, \.\.\. contains the documents generated for the
    package FOO1, \.\.\. and follows the structure shown for use case \[2\]\. The only
    exception is that there is no per\-package index\.

    The files "\.toc", "\.idx", and "\.xrf" contain the internal status of the
    whole output and will be read and updated by the next invokation\. Their







|
|

|












|
|
|
|
|
|
|

|

|

|







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
  - \[2\]

    The following directory structure is created when processing a single set of
    input documents\. The file extension used is for output in HTML, but that is
    not relevant to the structure and was just used to have proper file names\.

        output/
            toc.html
            index.html
            files/
                path/to/FOO.html

    The last line in the example shows the document generated for a file FOO
    located at

        inputdirectory/path/to/FOO

  - \[3\]

    When merging many packages into a unified set of documents the generated
    directory structure is a bit deeper:

        output
            .toc
            .idx
            .tocdoc
            .idxdoc
            .xrf
            toc.html
            index.html
            FOO1/
                ...
            FOO2/
                toc.html
                files/
                    path/to/BAR.html

    Each of the directories FOO1, \.\.\. contains the documents generated for the
    package FOO1, \.\.\. and follows the structure shown for use case \[2\]\. The only
    exception is that there is no per\-package index\.

    The files "\.toc", "\.idx", and "\.xrf" contain the internal status of the
    whole output and will be read and updated by the next invokation\. Their
Changes to embedded/md/tcllib/files/modules/fileutil/fileutil.md.
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

    This command performs purely lexical normalization on the *path* and
    returns the changed path as its result\. Symbolic links in the path are
    *not* resolved\.

    Examples:

        fileutil::lexnormalize /foo/\./bar
        => /foo/bar

        fileutil::lexnormalize /foo/\.\./bar
        => /bar

  - <a name='2'></a>__::fileutil::fullnormalize__ *path*

    This command resolves all symbolic links in the *path* and returns the
    changed path as its result\. In contrast to the builtin __file
    normalize__ this command resolves a symbolic link in the last element of







|


|







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

    This command performs purely lexical normalization on the *path* and
    returns the changed path as its result\. Symbolic links in the path are
    *not* resolved\.

    Examples:

        fileutil::lexnormalize /foo/./bar
        => /foo/bar

        fileutil::lexnormalize /foo/../bar
        => /bar

  - <a name='2'></a>__::fileutil::fullnormalize__ *path*

    This command resolves all symbolic links in the *path* and returns the
    changed path as its result\. In contrast to the builtin __file
    normalize__ this command resolves a symbolic link in the last element of
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    joined it with the result of __pwd__ to get an absolute filename\.

    The result of *filtercmd* is a boolean value that indicates if the current
    file should be included in the list of interesting files\.

    Example:

        \# find \.tcl files
        package require fileutil
        proc is\_tcl \{name\} \{return \[string match \*\.tcl $name\]\}
        set tcl\_files \[fileutil::find \. is\_tcl\]

  - <a name='13'></a>__::fileutil::findByPattern__ *basedir* ?__\-regexp__&#124;__\-glob__? ?__\-\-__? *patterns*

    This command is based upon the __TclX__ command __recursive\_glob__,
    except that it doesn't allow recursion over more than one directory at a
    time\. It uses __::fileutil::find__ internally and is thus able to and
    does follow symbolic links, something the __TclX__ command does not do\.







|

|
|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    joined it with the result of __pwd__ to get an absolute filename\.

    The result of *filtercmd* is a boolean value that indicates if the current
    file should be included in the list of interesting files\.

    Example:

        # find .tcl files
        package require fileutil
        proc is_tcl {name} {return [string match *.tcl $name]}
        set tcl_files [fileutil::find . is_tcl]

  - <a name='13'></a>__::fileutil::findByPattern__ *basedir* ?__\-regexp__&#124;__\-glob__? ?__\-\-__? *patterns*

    This command is based upon the __TclX__ command __recursive\_glob__,
    except that it doesn't allow recursion over more than one directory at a
    time\. It uses __::fileutil::find__ internally and is thus able to and
    does follow symbolic links, something the __TclX__ command does not do\.
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

    A concrete example and extreme case is the "/sys" hierarchy under Linux
    where some hundred devices exist under both "/sys/devices" and "/sys/class"
    with the two sub\-hierarchies linking to the other, generating millions of
    legal paths to enumerate\. The structure, reduced to three devices, roughly
    looks like

        /sys/class/tty/tty0 \-\-> \.\./\.\./dev/tty0
        /sys/class/tty/tty1 \-\-> \.\./\.\./dev/tty1
        /sys/class/tty/tty2 \-\-> \.\./\.\./dev/tty1

        /sys/dev/tty0/bus
        /sys/dev/tty0/subsystem \-\-> \.\./\.\./class/tty
        /sys/dev/tty1/bus
        /sys/dev/tty1/subsystem \-\-> \.\./\.\./class/tty
        /sys/dev/tty2/bus
        /sys/dev/tty2/subsystem \-\-> \.\./\.\./class/tty

    The command __fileutil::find__ currently has no way to escape this\. When
    having to handle such a pathological hierarchy It is recommended to switch
    to package __fileutil::traverse__ and the same\-named command it
    provides, and then use the __\-prefilter__ option to prevent the
    traverser from following symbolic links, like so:

        package require fileutil::traverse

        proc NoLinks \{fileName\} \{
            if \{\[string equal \[file type $fileName\] link\]\} \{
                return 0
            \}

            return 1
        \}


        fileutil::traverse T /sys/devices \-prefilter NoLinks
        T foreach p \{
            puts $p
        \}

        T destroy

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *fileutil* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|
|
|


|

|

|









|
|

<
>

<
|
>
|
|

<
>







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

    A concrete example and extreme case is the "/sys" hierarchy under Linux
    where some hundred devices exist under both "/sys/devices" and "/sys/class"
    with the two sub\-hierarchies linking to the other, generating millions of
    legal paths to enumerate\. The structure, reduced to three devices, roughly
    looks like

        /sys/class/tty/tty0 --> ../../dev/tty0
        /sys/class/tty/tty1 --> ../../dev/tty1
        /sys/class/tty/tty2 --> ../../dev/tty1

        /sys/dev/tty0/bus
        /sys/dev/tty0/subsystem --> ../../class/tty
        /sys/dev/tty1/bus
        /sys/dev/tty1/subsystem --> ../../class/tty
        /sys/dev/tty2/bus
        /sys/dev/tty2/subsystem --> ../../class/tty

    The command __fileutil::find__ currently has no way to escape this\. When
    having to handle such a pathological hierarchy It is recommended to switch
    to package __fileutil::traverse__ and the same\-named command it
    provides, and then use the __\-prefilter__ option to prevent the
    traverser from following symbolic links, like so:

        package require fileutil::traverse

        proc NoLinks {fileName} {
            if {[string equal [file type $fileName] link]} {
                return 0

            }
            return 1

        }

        fileutil::traverse T /sys/devices -prefilter NoLinks
        T foreach p {
            puts $p

        }
        T destroy

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *fileutil* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/fileutil/multiop.md.
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
    Returns the current path type limiter\.

# <a name='section5'></a>EXAMPLES

The following examples assume that the variable __F__ contains a reference
to a multi\-file operation object\.

        $F do copy                       \\\\
    	the  \*\.dll                    \\\\
    	from c:/TDK/PrivateOpenSSL/bin \\\\
    	to   \[installdir\_of tls\]

        $F do move      \\\\
    	the  \*       \\\\
    	from /sources \\\\
    	into /scratch  \\\\
    	but not \*\.html

        \# Alternatively use 'except for \*\.html'\.

        $F do           \\\\
    	move         \\\\
    	the  index    \\\\
    	from /sources  \\\\
    	into /scratch   \\\\
    	as   pkgIndex\.tcl

        $F do         \\\\
    	remove     \\\\
    	the \*\.txt  \\\\
    	in /scratch

Note that the fact that most commands just modify the object state allows us to
use more off forms as specifications instead of just nearly\-natural language
sentences\. For example the second example in this section can re\-arranged into:

        $F do            \\\\
    	from /sources \\\\
    	into /scratch  \\\\
    	but not \*\.html \\\\
    	move           \\\\
    	the  \*

and the result is not only still a valid specification, but even stays
relatively readable\.

Further note that the information collected by the commands __but__,
__except__, and __as__ is automatically reset after the associated
__the__ was executed\. However no other state is reset in that manner,
allowing the user to avoid repetitions of unchanging information\. For example
the second and third examples of this section can be merged and rewritten into
the equivalent:

    $F do                   \\\\
        move                 \\\\
        the  \*                \\\\
        from /sources          \\\\
        into /scratch           \\\\
        but not \*\.html not index \\\\
        the  index               \\\\
        as   pkgIndex\.tcl

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *fileutil* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|

|
|
|
|
|

|

|
|
|
|
|
|

|
|
|






|
|
|
|
|
|











|
|
|
|
|
|
|
|







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
    Returns the current path type limiter\.

# <a name='section5'></a>EXAMPLES

The following examples assume that the variable __F__ contains a reference
to a multi\-file operation object\.

        $F do copy                       \\
    	the  *.dll                    \\
    	from c:/TDK/PrivateOpenSSL/bin \\
    	to   [installdir_of tls]

        $F do move      \\
    	the  *       \\
    	from /sources \\
    	into /scratch  \\
    	but not *.html

        # Alternatively use 'except for *.html'.

        $F do           \\
    	move         \\
    	the  index    \\
    	from /sources  \\
    	into /scratch   \\
    	as   pkgIndex.tcl

        $F do         \\
    	remove     \\
    	the *.txt  \\
    	in /scratch

Note that the fact that most commands just modify the object state allows us to
use more off forms as specifications instead of just nearly\-natural language
sentences\. For example the second example in this section can re\-arranged into:

        $F do            \\
    	from /sources \\
    	into /scratch  \\
    	but not *.html \\
    	move           \\
    	the  *

and the result is not only still a valid specification, but even stays
relatively readable\.

Further note that the information collected by the commands __but__,
__except__, and __as__ is automatically reset after the associated
__the__ was executed\. However no other state is reset in that manner,
allowing the user to avoid repetitions of unchanging information\. For example
the second and third examples of this section can be merged and rewritten into
the equivalent:

    $F do                   \\
        move                 \\
        the  *                \\
        from /sources          \\
        into /scratch           \\
        but not *.html not index \\
        the  index               \\
        as   pkgIndex.tcl

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *fileutil* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/fileutil/traverse.md.
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

    A concrete example and extreme case is the "/sys" hierarchy under Linux
    where some hundred devices exist under both "/sys/devices" and "/sys/class"
    with the two sub\-hierarchies linking to the other, generating millions of
    legal paths to enumerate\. The structure, reduced to three devices, roughly
    looks like

        /sys/class/tty/tty0 \-\-> \.\./\.\./dev/tty0
        /sys/class/tty/tty1 \-\-> \.\./\.\./dev/tty1
        /sys/class/tty/tty2 \-\-> \.\./\.\./dev/tty1

        /sys/dev/tty0/bus
        /sys/dev/tty0/subsystem \-\-> \.\./\.\./class/tty
        /sys/dev/tty1/bus
        /sys/dev/tty1/subsystem \-\-> \.\./\.\./class/tty
        /sys/dev/tty2/bus
        /sys/dev/tty2/subsystem \-\-> \.\./\.\./class/tty

    When having to handle such a pathological hierarchy it is recommended to use
    the __\-prefilter__ option to prevent the traverser from following
    symbolic links, like so:

        package require fileutil::traverse

        proc NoLinks \{fileName\} \{
            if \{\[string equal \[file type $fileName\] link\]\} \{
                return 0
            \}

            return 1
        \}


        fileutil::traverse T /sys/devices \-prefilter NoLinks
        T foreach p \{
            puts $p
        \}

        T destroy

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *fileutil* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|
|
|


|

|

|







|
|

<
>

<
|
>
|
|

<
>







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

    A concrete example and extreme case is the "/sys" hierarchy under Linux
    where some hundred devices exist under both "/sys/devices" and "/sys/class"
    with the two sub\-hierarchies linking to the other, generating millions of
    legal paths to enumerate\. The structure, reduced to three devices, roughly
    looks like

        /sys/class/tty/tty0 --> ../../dev/tty0
        /sys/class/tty/tty1 --> ../../dev/tty1
        /sys/class/tty/tty2 --> ../../dev/tty1

        /sys/dev/tty0/bus
        /sys/dev/tty0/subsystem --> ../../class/tty
        /sys/dev/tty1/bus
        /sys/dev/tty1/subsystem --> ../../class/tty
        /sys/dev/tty2/bus
        /sys/dev/tty2/subsystem --> ../../class/tty

    When having to handle such a pathological hierarchy it is recommended to use
    the __\-prefilter__ option to prevent the traverser from following
    symbolic links, like so:

        package require fileutil::traverse

        proc NoLinks {fileName} {
            if {[string equal [file type $fileName] link]} {
                return 0

            }
            return 1

        }

        fileutil::traverse T /sys/devices -prefilter NoLinks
        T foreach p {
            puts $p

        }
        T destroy

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *fileutil* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/fumagic/rtcore.md.
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    This command behaves mostly like __::fileutil::magic::rt::Nv__, except
    that it compares the fetched and masked value against *val* as specified
    with *comp* and returns the result of that comparison\.

    The argument *comp* has to contain one of Tcl's comparison operators, and
    the comparison made will be

        <val> <comp> <fetched\-and\-masked\-value>

    The special comparison operator __x__ signals that no comparison should
    be done, or, in other words, that the fetched value will always match
    *val*\.

  - <a name='12'></a>__::fileutil::magic::rt::Nvx__ *type* *offset* ?*qual*?








|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
    This command behaves mostly like __::fileutil::magic::rt::Nv__, except
    that it compares the fetched and masked value against *val* as specified
    with *comp* and returns the result of that comparison\.

    The argument *comp* has to contain one of Tcl's comparison operators, and
    the comparison made will be

        <val> <comp> <fetched-and-masked-value>

    The special comparison operator __x__ signals that no comparison should
    be done, or, in other words, that the fetched value will always match
    *val*\.

  - <a name='12'></a>__::fileutil::magic::rt::Nvx__ *type* *offset* ?*qual*?

Changes to embedded/md/tcllib/files/modules/generator/generator.md.
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
multiple return values and looping over multiple generators at once\. Writing a
generator is also a simple task, much like writing a normal procedure: simply
use the __define__ command to define the generator, and then call
__yield__ instead of __[return](\.\./\.\./\.\./\.\./index\.md\#return)__\. For
example, we can define a generator for looping through the integers in a
particular range:

    generator define range \{n m\} \{
        for \{set i $n\} \{$i <= $m\} \{incr i\} \{ generator yield $i \}
    \}

    generator foreach x \[range 1 10\] \{
        puts "x = $x"
    \}


The above example will print the numbers from 1 to 10 in sequence, as you would
expect\. The difference from a normal loop over a list is that the numbers are
only generated as they are needed\. If we insert a break into the loop then any
remaining numbers in the sequence would never be generated\. To illustrate, we
can define a generator that produces the sequence of natural numbers: an
infinite series\. A normal procedure would never return trying to produce this
series as a list\. By using a generator we only have to generate those values
which are actually used:

    generator define nats \{\} \{
        while 1 \{ generator yield \[incr nat\] \}
    \}

    generator foreach n \[nats\] \{
        if \{$n > 100\} \{ break \}
    \}


# <a name='section2'></a>COMMANDS

  - <a name='1'></a>__generator__ __define__ *name* *params* *body*

    Creates a new generator procedure\. The arguments to the command are
    identical to those for __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__: a







|
|
<
>
|

<
>










|
|
<
>
|
|
<
>







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
multiple return values and looping over multiple generators at once\. Writing a
generator is also a simple task, much like writing a normal procedure: simply
use the __define__ command to define the generator, and then call
__yield__ instead of __[return](\.\./\.\./\.\./\.\./index\.md\#return)__\. For
example, we can define a generator for looping through the integers in a
particular range:

    generator define range {n m} {
        for {set i $n} {$i <= $m} {incr i} { generator yield $i }

    }
    generator foreach x [range 1 10] {
        puts "x = $x"

    }

The above example will print the numbers from 1 to 10 in sequence, as you would
expect\. The difference from a normal loop over a list is that the numbers are
only generated as they are needed\. If we insert a break into the loop then any
remaining numbers in the sequence would never be generated\. To illustrate, we
can define a generator that produces the sequence of natural numbers: an
infinite series\. A normal procedure would never return trying to produce this
series as a list\. By using a generator we only have to generate those values
which are actually used:

    generator define nats {} {
        while 1 { generator yield [incr nat] }

    }
    generator foreach n [nats] {
        if {$n > 100} { break }

    }

# <a name='section2'></a>COMMANDS

  - <a name='1'></a>__generator__ __define__ *name* *params* *body*

    Creates a new generator procedure\. The arguments to the command are
    identical to those for __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__: a
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
    be used like a __finally__ block in the
    __[try](\.\./try/tcllib\_try\.md)__ command, except that it is tied to
    the life\-cycle of the generator rather than to a particular scope\. For
    example, if we create a generator to iterate over the lines in a text file,
    we can use __finally__ to ensure that the file is closed whenever the
    generator is destroyed:

    generator define lines file \{
        set in \[open $file\]
        \# Ensure file is always closed
        generator finally close $in
        while \{\[gets $in line\] >= 0\} \{
            generator yield $line
        \}
    \}


    generator foreach line \[lines /etc/passwd\] \{
        puts "\[incr count\]: $line"
        if \{$count > 10\} \{ break \}
    \}

    \# File will be closed even on early exit

    If you create a generator that consumes another generator \(such as the
    standard __map__ and __filter__ generators defined later\), then you
    should use a __finally__ command to ensure that this generator is
    destroyed when its parent is\. For example, the __map__ generator is
    defined as follows:

    generator define map \{f xs\} \{
        generator finally generator destroy $xs
        generator foreach x $xs \{ generator yield \[\{\*\}$f $x\] \}
    \}


  - <a name='9'></a>__generator__ __from__ *format* *value*

    Creates a generator from a data structure\. Currently, supported formats are
    __list__, __dict__, or __string__\. The list format yields each
    element in turn\. For dictionaries, each key and value are yielded
    separately\. Finally, strings are yielded a character at a time\.

  - <a name='10'></a>__generator__ __to__ *format* *generator*

    Converts a generator into a data structure\. This is the reverse operation of
    the __from__ command, and supports the same data structures\. The two
    operations obey the following identity laws \(where __=__ is interpreted
    appropriately\):

    \[generator to $fmt \[generator from $fmt $value\]\] = $value
    \[generator from $fmt \[generator to $fmt $gen\]\]   = $gen

# <a name='section3'></a>PRELUDE

The following commands are provided as a standard library of generator
combinators and functions that perform convenience operations on generators\. The
functions in this section are loosely modelled on the equivalent functions from
the Haskell Prelude\. *Warning:* most of the functions in this prelude destroy
any generator arguments they are passed as a side\-effect\. If you want to have
persistent generators, see the streams library\.

  - <a name='11'></a>__generator__ __map__ *function* *generator*

    Apply a function to every element of a generator, returning a new generator
    of the results\. This is the classic map function from functional
    programming, applied to generators\. For example, we can generate all the
    square numbers using the following code \(where __nats__ is defined as
    earlier\):

    proc square x \{ expr \{$x \* $x\} \}
    generator foreach n \[generator map square \[nats\]\] \{
        puts "n = $n"
        if \{$n > 1000\} \{ break \}
    \}


  - <a name='12'></a>__generator__ __filter__ *predicate* *generator*

    Another classic functional programming gem\. This command returns a generator
    that yields only those items from the argument generator that satisfy the
    predicate \(boolean function\)\. For example, if we had a generator
    __employees__ that returned a stream of dictionaries representing
    people, we could filter all those whose salaries are above 100,000 dollars
    \(or whichever currency you prefer\) using a simple filter:

    proc salary> \{amount person\} \{ expr \{\[dict get $person salary\] > $amount\} \}
    set fat\-cats \[generator filter \{salary> 100000\} $employees\]

  - <a name='13'></a>__generator__ __reduce__ *function* *zero* *generator*

    This is the classic left\-fold operation\. This command takes a function, an
    initial value, and a generator of values\. For each element in the generator
    it applies the function to the current accumulator value \(the *zero*
    argument initially\) and that element, and then uses the result as the new
    accumulator value\. This process is repeated through the entire generator
    \(eagerly\) and the final accumulator value is then returned\. If we consider
    the function to be a binary operator, and the zero argument to be the left
    identity element of that operation, then we can consider the __reduce__
    command as *folding* the operator between each successive pair of values
    in the generator in a left\-associative fashion\. For example, the sum of a
    sequence of numbers can be calculated by folding a __\+__ operator
    between them, with 0 as the identity:

    \# sum xs          = reduce \+ 0 xs
    \# sum \[range 1 5\] = reduce \+ 0 \[range 1 5\]
    \#                 = reduce \+ \[\+ 0 1\] \[range 2 5\]
    \#                 = reduce \+ \[\+ 1 2\] \[range 3 5\]
    \#                 = \.\.\.
    \#                 = reduce \+ \[\+ 10 5\] <empty>
    \#                 = \(\(\(\(0\+1\)\+2\)\+3\)\+4\)\+5
    \#                 = 15
    proc \+ \{a b\} \{ expr \{$a \+ $b\} \}
    proc sum gen \{ generator reduce \+ 0 $gen \}
    puts \[sum \[range 1 10\]\]

    The __reduce__ operation is an extremely useful one, and a great variety
    of different operations can be defined using it\. For example, we can define
    a factorial function as the product of a range using generators\. This
    definition is both very clear and also quite efficient \(in both memory and
    running time\):

    proc \* \{x y\} \{ expr \{$x \* $y\} \}
    proc prod gen \{ generator reduce \* 0 $gen \}
    proc fac n \{ prod \[range 1 $n\] \}

    However, while the __reduce__ operation is efficient for finite
    generators, care should be taken not to apply it to an infinite generator,
    as this will result in an infinite loop:

    sum \[nats\]; \# Never returns

  - <a name='14'></a>__generator__ __foldl__ *function* *zero* *generator*

    This is an alias for the __reduce__ command\.

  - <a name='15'></a>__generator__ __foldr__ *function* *zero* *generator*








|
|
|

|

<
<
>
>
|
|
|
<
>
|







|

|
<
>















|
|


















|
|

|
<
>










|
|
















|
|
|
|
|
|
|
|
|
|
|







|
|
|





|







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
    be used like a __finally__ block in the
    __[try](\.\./try/tcllib\_try\.md)__ command, except that it is tied to
    the life\-cycle of the generator rather than to a particular scope\. For
    example, if we create a generator to iterate over the lines in a text file,
    we can use __finally__ to ensure that the file is closed whenever the
    generator is destroyed:

    generator define lines file {
        set in [open $file]
        # Ensure file is always closed
        generator finally close $in
        while {[gets $in line] >= 0} {
            generator yield $line


        }
    }
    generator foreach line [lines /etc/passwd] {
        puts "[incr count]: $line"
        if {$count > 10} { break }

    }
    # File will be closed even on early exit

    If you create a generator that consumes another generator \(such as the
    standard __map__ and __filter__ generators defined later\), then you
    should use a __finally__ command to ensure that this generator is
    destroyed when its parent is\. For example, the __map__ generator is
    defined as follows:

    generator define map {f xs} {
        generator finally generator destroy $xs
        generator foreach x $xs { generator yield [{*}$f $x] }

    }

  - <a name='9'></a>__generator__ __from__ *format* *value*

    Creates a generator from a data structure\. Currently, supported formats are
    __list__, __dict__, or __string__\. The list format yields each
    element in turn\. For dictionaries, each key and value are yielded
    separately\. Finally, strings are yielded a character at a time\.

  - <a name='10'></a>__generator__ __to__ *format* *generator*

    Converts a generator into a data structure\. This is the reverse operation of
    the __from__ command, and supports the same data structures\. The two
    operations obey the following identity laws \(where __=__ is interpreted
    appropriately\):

    [generator to $fmt [generator from $fmt $value]] = $value
    [generator from $fmt [generator to $fmt $gen]]   = $gen

# <a name='section3'></a>PRELUDE

The following commands are provided as a standard library of generator
combinators and functions that perform convenience operations on generators\. The
functions in this section are loosely modelled on the equivalent functions from
the Haskell Prelude\. *Warning:* most of the functions in this prelude destroy
any generator arguments they are passed as a side\-effect\. If you want to have
persistent generators, see the streams library\.

  - <a name='11'></a>__generator__ __map__ *function* *generator*

    Apply a function to every element of a generator, returning a new generator
    of the results\. This is the classic map function from functional
    programming, applied to generators\. For example, we can generate all the
    square numbers using the following code \(where __nats__ is defined as
    earlier\):

    proc square x { expr {$x * $x} }
    generator foreach n [generator map square [nats]] {
        puts "n = $n"
        if {$n > 1000} { break }

    }

  - <a name='12'></a>__generator__ __filter__ *predicate* *generator*

    Another classic functional programming gem\. This command returns a generator
    that yields only those items from the argument generator that satisfy the
    predicate \(boolean function\)\. For example, if we had a generator
    __employees__ that returned a stream of dictionaries representing
    people, we could filter all those whose salaries are above 100,000 dollars
    \(or whichever currency you prefer\) using a simple filter:

    proc salary> {amount person} { expr {[dict get $person salary] > $amount} }
    set fat-cats [generator filter {salary> 100000} $employees]

  - <a name='13'></a>__generator__ __reduce__ *function* *zero* *generator*

    This is the classic left\-fold operation\. This command takes a function, an
    initial value, and a generator of values\. For each element in the generator
    it applies the function to the current accumulator value \(the *zero*
    argument initially\) and that element, and then uses the result as the new
    accumulator value\. This process is repeated through the entire generator
    \(eagerly\) and the final accumulator value is then returned\. If we consider
    the function to be a binary operator, and the zero argument to be the left
    identity element of that operation, then we can consider the __reduce__
    command as *folding* the operator between each successive pair of values
    in the generator in a left\-associative fashion\. For example, the sum of a
    sequence of numbers can be calculated by folding a __\+__ operator
    between them, with 0 as the identity:

    # sum xs          = reduce + 0 xs
    # sum [range 1 5] = reduce + 0 [range 1 5]
    #                 = reduce + [+ 0 1] [range 2 5]
    #                 = reduce + [+ 1 2] [range 3 5]
    #                 = ...
    #                 = reduce + [+ 10 5] <empty>
    #                 = ((((0+1)+2)+3)+4)+5
    #                 = 15
    proc + {a b} { expr {$a + $b} }
    proc sum gen { generator reduce + 0 $gen }
    puts [sum [range 1 10]]

    The __reduce__ operation is an extremely useful one, and a great variety
    of different operations can be defined using it\. For example, we can define
    a factorial function as the product of a range using generators\. This
    definition is both very clear and also quite efficient \(in both memory and
    running time\):

    proc * {x y} { expr {$x * $y} }
    proc prod gen { generator reduce * 0 $gen }
    proc fac n { prod [range 1 $n] }

    However, while the __reduce__ operation is efficient for finite
    generators, care should be taken not to apply it to an infinite generator,
    as this will result in an infinite loop:

    sum [nats]; # Never returns

  - <a name='14'></a>__generator__ __foldl__ *function* *zero* *generator*

    This is an alias for the __reduce__ command\.

  - <a name='15'></a>__generator__ __foldr__ *function* *zero* *generator*

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454

  - <a name='32'></a>__generator__ __iterate__ *function* *init*

    Returns an infinite generator formed by repeatedly applying the function to
    the initial argument\. For example, the Fibonacci numbers can be defined as
    follows:

    proc fst pair \{ lindex $pair 0 \}
    proc snd pair \{ lindex $pair 1 \}
    proc nextFib ab \{ list \[snd $ab\] \[expr \{\[fst $ab\] \+ \[snd $ab\]\}\] \}
    proc fibs \{\} \{ generator map fst \[generator iterate nextFib \{0 1\}\] \}

  - <a name='33'></a>__generator__ __last__ *generator*

    Returns the last element of the generator \(if it exists\)\.

  - <a name='34'></a>__generator__ __length__ *generator*








|
|
|
|







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454

  - <a name='32'></a>__generator__ __iterate__ *function* *init*

    Returns an infinite generator formed by repeatedly applying the function to
    the initial argument\. For example, the Fibonacci numbers can be defined as
    follows:

    proc fst pair { lindex $pair 0 }
    proc snd pair { lindex $pair 1 }
    proc nextFib ab { list [snd $ab] [expr {[fst $ab] + [snd $ab]}] }
    proc fibs {} { generator map fst [generator iterate nextFib {0 1}] }

  - <a name='33'></a>__generator__ __last__ *generator*

    Returns the last element of the generator \(if it exists\)\.

  - <a name='34'></a>__generator__ __length__ *generator*

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  - <a name='40'></a>__generator__ __splitWhen__ *predicate* *generator*

    Splits the generator into lists of elements using the predicate to identify
    delimiters\. The resulting lists are returned as a generator\. Elements
    matching the delimiter predicate are discarded\. For example, to split up a
    generator using the string "&#124;" as a delimiter:

    set xs \[generator from list \{a &#124; b &#124; c\}\]
    generator split \{string equal "&#124;"\} $xs ;\# returns a then b then c

  - <a name='41'></a>__generator__ __scanl__ *function* *zero* *generator*

    Similar to __foldl__, but returns a generator of all of the intermediate
    values for the accumulator argument\. The final element of this generator is
    equivalent to __foldl__ called on the same arguments\.








|
|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  - <a name='40'></a>__generator__ __splitWhen__ *predicate* *generator*

    Splits the generator into lists of elements using the predicate to identify
    delimiters\. The resulting lists are returned as a generator\. Elements
    matching the delimiter predicate are discarded\. For example, to split up a
    generator using the string "&#124;" as a delimiter:

    set xs [generator from list {a | b | c}]
    generator split {string equal "|"} $xs ;# returns a then b then c

  - <a name='41'></a>__generator__ __scanl__ *function* *zero* *generator*

    Similar to __foldl__, but returns a generator of all of the intermediate
    values for the accumulator argument\. The final element of this generator is
    equivalent to __foldl__ called on the same arguments\.

Changes to embedded/md/tcllib/files/modules/gpx/gpx.md.
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
    elements: *latitude*, *longitude* and *metadata dictionary*\.
    *Latitude* and *longitude* are decimal numbers\. The *metadata
    dictionary* format is described above\. For points in a track, typically
    there will always be ele \(elevation\) and time metadata keys\.

# <a name='section4'></a>EXAMPLE

    % set token \[::gpx::Create myGpxFile\.gpx\]
    % set version \[dict get \[::gpx::GetGPXMetadata $token\] version\]
    % set trackCnt \[::gpx::GetTrackCount $token\]
    % set firstPoint \[lindex \[::gpx::GetTrackPoints $token 1\] 0\]
    % lassign $firstPoint lat lon ptMetadata
    % puts "first point in the first track is at $lat, $lon"
    % if \{\[dict exists $ptMetadata ele\]\} \{
         puts "at elevation \[dict get $ptMetadata ele\] meters"
      \}

    % ::gpx::Cleanup $token

# <a name='section5'></a>REFERENCES

  1. GPX: the GPS Exchange Format
     \([http://www\.topografix\.com/gpx\.asp](http://www\.topografix\.com/gpx\.asp)\)








|
|
|
|


|
|
<
>







149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171
    elements: *latitude*, *longitude* and *metadata dictionary*\.
    *Latitude* and *longitude* are decimal numbers\. The *metadata
    dictionary* format is described above\. For points in a track, typically
    there will always be ele \(elevation\) and time metadata keys\.

# <a name='section4'></a>EXAMPLE

    % set token [::gpx::Create myGpxFile.gpx]
    % set version [dict get [::gpx::GetGPXMetadata $token] version]
    % set trackCnt [::gpx::GetTrackCount $token]
    % set firstPoint [lindex [::gpx::GetTrackPoints $token 1] 0]
    % lassign $firstPoint lat lon ptMetadata
    % puts "first point in the first track is at $lat, $lon"
    % if {[dict exists $ptMetadata ele]} {
         puts "at elevation [dict get $ptMetadata ele] meters"

      }
    % ::gpx::Cleanup $token

# <a name='section5'></a>REFERENCES

  1. GPX: the GPS Exchange Format
     \([http://www\.topografix\.com/gpx\.asp](http://www\.topografix\.com/gpx\.asp)\)

Changes to embedded/md/tcllib/files/modules/grammar_aycock/aycock.md.
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# <a name='section5'></a>EXAMPLE

The following code demonstrates a trivial desk calculator, admitting only
__\+__, __\*__ and parentheses as its operators\. It also shows the format
in which the lexical analyzer is expected to present terminal symbols to the
parser\.

    set p \[aycock::parser \{
        start ::= E \{\}
        E ::= E \+ T \{expr \{\[lindex $\_ 0\] \+ \[lindex $\_ 2\]\}\}
        E ::= T \{\}
        T ::= T \* F \{expr \{\[lindex $\_ 0\] \* \[lindex $\_ 2\]\}\}
        T ::= F \{\}
        F ::= NUMBER \{\}
        F ::= \( E \) \{lindex $\_ 1\}
    \}\]
    puts \[$p parse \{\(  NUMBER \+  NUMBER \)  \*  \( NUMBER \+  NUMBER \) \}  \{\{\} 2      \{\} 3      \{\} \{\} \{\} 7     \{\} 1      \{\}\}\]
    $p destroy

The example, when run, prints __40__\.

# <a name='section6'></a>KEYWORDS

Aycock, Earley, Horspool, parser, compiler







|
|
|
|
|
|
|
|
|
|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# <a name='section5'></a>EXAMPLE

The following code demonstrates a trivial desk calculator, admitting only
__\+__, __\*__ and parentheses as its operators\. It also shows the format
in which the lexical analyzer is expected to present terminal symbols to the
parser\.

    set p [aycock::parser {
        start ::= E {}
        E ::= E + T {expr {[lindex $_ 0] + [lindex $_ 2]}}
        E ::= T {}
        T ::= T * F {expr {[lindex $_ 0] * [lindex $_ 2]}}
        T ::= F {}
        F ::= NUMBER {}
        F ::= ( E ) {lindex $_ 1}
    }]
    puts [$p parse {(  NUMBER +  NUMBER )  *  ( NUMBER +  NUMBER ) }  {{} 2      {} 3      {} {} {} 7     {} 1      {}}]
    $p destroy

The example, when run, prints __40__\.

# <a name='section6'></a>KEYWORDS

Aycock, Earley, Horspool, parser, compiler
Changes to embedded/md/tcllib/files/modules/grammar_fa/fa.md.
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
    overwriting any existing definition\. This is the assignment operator for
    automatons\. It copies the automaton contained in the FA object *srcFA*
    over the automaton definition in *faName*\. The old contents of *faName*
    are deleted by this operation\.

    This operation is in effect equivalent to

        *faName* __deserialize__ \[*srcFA* __serialize__\]

  - <a name='6'></a>*faName* __\-\->__ *dstFA*

    This is the reverse assignment operator for automatons\. It copies the
    automation contained in the object *faName* over the automaton definition
    in the object *dstFA*\. The old contents of *dstFA* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *dstFA* __deserialize__ \[*faName* __serialize__\]

  - <a name='7'></a>*faName* __serialize__

    This method serializes the automaton stored in *faName*\. In other words it
    returns a tcl *value* completely describing that automaton\. This allows,
    for example, the transfer of automatons over arbitrary channels,
    persistence, etc\. This method is also the basis for both the copy







|










|







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
    overwriting any existing definition\. This is the assignment operator for
    automatons\. It copies the automaton contained in the FA object *srcFA*
    over the automaton definition in *faName*\. The old contents of *faName*
    are deleted by this operation\.

    This operation is in effect equivalent to

        *faName* __deserialize__ [*srcFA* __serialize__]

  - <a name='6'></a>*faName* __\-\->__ *dstFA*

    This is the reverse assignment operator for automatons\. It copies the
    automation contained in the object *faName* over the automaton definition
    in the object *dstFA*\. The old contents of *dstFA* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *dstFA* __deserialize__ [*faName* __serialize__]

  - <a name='7'></a>*faName* __serialize__

    This method serializes the automaton stored in *faName*\. In other words it
    returns a tcl *value* completely describing that automaton\. This allows,
    for example, the transfer of automatons over arbitrary channels,
    persistence, etc\. This method is also the basis for both the copy
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
           1) The last element is a dictionary describing the transitions for
              the state\. The keys are symbols \(or the empty string\), and the
              values are sets of successor states\.

    Assuming the following FA \(which describes the life of a truck driver in a
    very simple way :\)

        Drive \-\- yellow \-\-> Brake \-\- red \-\-> \(Stop\) \-\- red/yellow \-\-> Attention \-\- green \-\-> Drive
        \(\.\.\.\) is the start state\.

    a possible serialization is

        grammar::fa \\\\
        \{yellow red green red/yellow\} \\\\
        \{Drive     \{0 0 \{yellow     Brake\}\} \\\\
         Brake     \{0 0 \{red        Stop\}\} \\\\
         Stop      \{1 0 \{red/yellow Attention\}\} \\\\
         Attention \{0 0 \{green      Drive\}\}\}

    A possible one, because I did not care about creation order here

  - <a name='8'></a>*faName* __deserialize__ *serialization*

    This is the complement to __serialize__\. It replaces the automaton
    definition in *faName* with the automaton described by the







|
|



|
|
|
|
|
|







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
           1) The last element is a dictionary describing the transitions for
              the state\. The keys are symbols \(or the empty string\), and the
              values are sets of successor states\.

    Assuming the following FA \(which describes the life of a truck driver in a
    very simple way :\)

        Drive -- yellow --> Brake -- red --> (Stop) -- red/yellow --> Attention -- green --> Drive
        (...) is the start state.

    a possible serialization is

        grammar::fa \\
        {yellow red green red/yellow} \\
        {Drive     {0 0 {yellow     Brake}} \\
         Brake     {0 0 {red        Stop}} \\
         Stop      {1 0 {red/yellow Attention}} \\
         Attention {0 0 {green      Drive}}}

    A possible one, because I did not care about creation order here

  - <a name='8'></a>*faName* __deserialize__ *serialization*

    This is the complement to __serialize__\. It replaces the automaton
    definition in *faName* with the automaton described by the
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
    more transitions\.

  - <a name='39'></a>*faName* __unreachable\_states__

    Returns the set of states which are not reachable from any start state by
    any number of transitions\. This is

        \[faName states\] \- \[faName reachable\_states\]

  - <a name='40'></a>*faName* __reachable__ *s*

    A predicate\. It tests whether the state *s* in the FA *faName* can be
    reached from a start state by one or more transitions\. The result is a
    boolean value\. It will be set to __true__ if the state can be reached,
    and __false__ otherwise\.

  - <a name='41'></a>*faName* __useful\_states__

    Returns the set of states which are able to reach a final state by one or
    more transitions\.

  - <a name='42'></a>*faName* __unuseful\_states__

    Returns the set of states which are not able to reach a final state by any
    number of transitions\. This is

        \[faName states\] \- \[faName useful\_states\]

  - <a name='43'></a>*faName* __useful__ *s*

    A predicate\. It tests whether the state *s* in the FA *faName* is able
    to reach a final state by one or more transitions\. The result is a boolean
    value\. It will be set to __true__ if the state is useful, and
    __false__ otherwise\.







|


















|







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
    more transitions\.

  - <a name='39'></a>*faName* __unreachable\_states__

    Returns the set of states which are not reachable from any start state by
    any number of transitions\. This is

        [faName states] - [faName reachable_states]

  - <a name='40'></a>*faName* __reachable__ *s*

    A predicate\. It tests whether the state *s* in the FA *faName* can be
    reached from a start state by one or more transitions\. The result is a
    boolean value\. It will be set to __true__ if the state can be reached,
    and __false__ otherwise\.

  - <a name='41'></a>*faName* __useful\_states__

    Returns the set of states which are able to reach a final state by one or
    more transitions\.

  - <a name='42'></a>*faName* __unuseful\_states__

    Returns the set of states which are not able to reach a final state by any
    number of transitions\. This is

        [faName states] - [faName useful_states]

  - <a name='43'></a>*faName* __useful__ *s*

    A predicate\. It tests whether the state *s* in the FA *faName* is able
    to reach a final state by one or more transitions\. The result is a boolean
    value\. It will be set to __true__ if the state is useful, and
    __false__ otherwise\.
Changes to embedded/md/tcllib/files/modules/grammar_peg/peg.md.
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
one of the nonterminals N in the expression, and one of the alternative rules R
for N, and then replace the nonterminal in A with the RHS of the chosen rule\.
Here we can see why the terminal symbols are called such\. They cannot be
expanded any further, thus terminate the process of deriving new expressions\. An
example

    Rules
      \(1\)  A <\- a B c
      \(2a\) B <\- d B
      \(2b\) B <\- e

    Some derivations, using starting expression A\.

      A \-/1/\-> a B c \-/2a/\-> a d B c \-/2b/\-> a d e c

A derived expression containing only terminal symbols is a *sentence*\. The set
of all sentences which can be derived from the start expression is the
*language* of the grammar\.

Some definitions for nonterminals and expressions:








|
|
|

|

|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
one of the nonterminals N in the expression, and one of the alternative rules R
for N, and then replace the nonterminal in A with the RHS of the chosen rule\.
Here we can see why the terminal symbols are called such\. They cannot be
expanded any further, thus terminate the process of deriving new expressions\. An
example

    Rules
      (1)  A <- a B c
      (2a) B <- d B
      (2b) B <- e

    Some derivations, using starting expression A.

      A -/1/-> a B c -/2a/-> a d B c -/2b/-> a d e c

A derived expression containing only terminal symbols is a *sentence*\. The set
of all sentences which can be derived from the start expression is the
*language* of the grammar\.

Some definitions for nonterminals and expressions:

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
    overwriting any existing definition\. This is the assignment operator for
    grammars\. It copies the grammar contained in the grammar object *srcPEG*
    over the grammar definition in *pegName*\. The old contents of *pegName*
    are deleted by this operation\.

    This operation is in effect equivalent to

    *pegName* __deserialize__ \[*srcPEG* __serialize__\]

  - <a name='5'></a>*pegName* __\-\->__ *dstPEG*

    This is the reverse assignment operator for grammars\. It copies the
    automation contained in the object *pegName* over the grammar definition
    in the object *dstPEG*\. The old contents of *dstPEG* are deleted by this
    operation\.

    This operation is in effect equivalent to

    *dstPEG* __deserialize__ \[*pegName* __serialize__\]

  - <a name='6'></a>*pegName* __serialize__

    This method serializes the grammar stored in *pegName*\. In other words it
    returns a tcl *value* completely describing that grammar\. This allows, for
    example, the transfer of grammars over arbitrary channels, persistence, etc\.
    This method is also the basis for both the copy constructor and the







|










|







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
    overwriting any existing definition\. This is the assignment operator for
    grammars\. It copies the grammar contained in the grammar object *srcPEG*
    over the grammar definition in *pegName*\. The old contents of *pegName*
    are deleted by this operation\.

    This operation is in effect equivalent to

    *pegName* __deserialize__ [*srcPEG* __serialize__]

  - <a name='5'></a>*pegName* __\-\->__ *dstPEG*

    This is the reverse assignment operator for grammars\. It copies the
    automation contained in the object *pegName* over the grammar definition
    in the object *dstPEG*\. The old contents of *dstPEG* are deleted by this
    operation\.

    This operation is in effect equivalent to

    *dstPEG* __deserialize__ [*pegName* __serialize__]

  - <a name='6'></a>*pegName* __serialize__

    This method serializes the grammar stored in *pegName*\. In other words it
    returns a tcl *value* completely describing that grammar\. This allows, for
    example, the transfer of grammars over arbitrary channels, persistence, etc\.
    This method is also the basis for both the copy constructor and the
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
         values produced by the symbol\.

      1. The last item is a parsing expression, the *start expression* of the
         grammar\.

    Assuming the following PEG for simple mathematical expressions

    Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'
    Sign       <\- '\+' / '\-'
    Number     <\- Sign? Digit\+
    Expression <\- '\(' Expression '\)' / \(Factor \(MulOp Factor\)\*\)
    MulOp      <\- '\*' / '/'
    Factor     <\- Term \(AddOp Term\)\*
    AddOp      <\- '\+'/'\-'
    Term       <\- Number

    a possible serialization is

    grammar::peg \\\\
    \{Expression \{/ \{x \( Expression \)\} \{x Factor \{\* \{x MulOp Factor\}\}\}\} \\\\
     Factor     \{x Term \{\* \{x AddOp Term\}\}\} \\\\
     Term       Number \\\\
     MulOp      \{/ \* /\} \\\\
     AddOp      \{/ \+ \-\} \\\\
     Number     \{x \{? Sign\} \{\+ Digit\}\} \\\\
     Sign       \{/ \+ \-\} \\\\
     Digit      \{/ 0 1 2 3 4 5 6 7 8 9\} \\\\
    \} \\\\
    \{Expression value     Factor     value \\\\
     Term       value     MulOp      value \\\\
     AddOp      value     Number     value \\\\
     Sign       value     Digit      value \\\\
    \}

    Expression

    A possible one, because the order of the nonterminals in the dictionary is
    not relevant\.

  - <a name='7'></a>*pegName* __deserialize__ *serialization*








|
|
|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>







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
         values produced by the symbol\.

      1. The last item is a parsing expression, the *start expression* of the
         grammar\.

    Assuming the following PEG for simple mathematical expressions

    Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'
    Sign       <- '+' / '-'
    Number     <- Sign? Digit+
    Expression <- '(' Expression ')' / (Factor (MulOp Factor)*)
    MulOp      <- '*' / '/'
    Factor     <- Term (AddOp Term)*
    AddOp      <- '+'/'-'
    Term       <- Number

    a possible serialization is

    grammar::peg \\
    {Expression {/ {x ( Expression )} {x Factor {* {x MulOp Factor}}}} \\
     Factor     {x Term {* {x AddOp Term}}} \\
     Term       Number \\
     MulOp      {/ * /} \\
     AddOp      {/ + -} \\
     Number     {x {? Sign} {+ Digit}} \\
     Sign       {/ + -} \\
     Digit      {/ 0 1 2 3 4 5 6 7 8 9} \\
    } \\
    {Expression value     Factor     value \\
     Term       value     MulOp      value \\
     AddOp      value     Number     value \\
     Sign       value     Digit      value \\

    }
    Expression

    A possible one, because the order of the nonterminals in the dictionary is
    not relevant\.

  - <a name='7'></a>*pegName* __deserialize__ *serialization*

Changes to embedded/md/tcllib/files/modules/hook/hook.md.
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
change the model's data:

    hook call ::model <Update>

The __\.view__ megawidget displays the model state, and needs to know about
model updates\. Consequently, it subscribes to the ::model's <Update> hook\.

    hook bind ::model <Update> \.view \[list \.view ModelUpdate\]

When the __::model__ calls the hook, the __\.view__s ModelUpdate
subcommand will be called\.

Later the __\.view__ megawidget is destroyed\. In its destructor, it tells the
*[hook](\.\./\.\./\.\./\.\./index\.md\#hook)* that it no longer exists:

    hook forget \.view

All bindings involving __\.view__ are deleted\.

# <a name='section5'></a>Credits

Hook has been designed and implemented by William H\. Duquette\.








|







|







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
change the model's data:

    hook call ::model <Update>

The __\.view__ megawidget displays the model state, and needs to know about
model updates\. Consequently, it subscribes to the ::model's <Update> hook\.

    hook bind ::model <Update> .view [list .view ModelUpdate]

When the __::model__ calls the hook, the __\.view__s ModelUpdate
subcommand will be called\.

Later the __\.view__ megawidget is destroyed\. In its destructor, it tells the
*[hook](\.\./\.\./\.\./\.\./index\.md\#hook)* that it no longer exists:

    hook forget .view

All bindings involving __\.view__ are deleted\.

# <a name='section5'></a>Credits

Hook has been designed and implemented by William H\. Duquette\.

Changes to embedded/md/tcllib/files/modules/http/autoproxy.md.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section3'></a>COMMANDS

  - <a name='1'></a>__::autoproxy::init__

    Initialize the autoproxy package from system resources\. Under unix this
    means we look for environment variables\. Under windows we look for the same







|

|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section3'></a>COMMANDS

  - <a name='1'></a>__::autoproxy::init__

    Initialize the autoproxy package from system resources\. Under unix this
    means we look for environment variables\. Under windows we look for the same
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    The end\-of\-options indicator may be used alone to unset any authentication
    details currently enabled\.

# <a name='section6'></a>EXAMPLES

    package require autoproxy
    autoproxy::init
    autoproxy::configure \-basic \-username ME \-password SEKRET
    set tok \[http::geturl http://wiki\.tcl\.tk/\]
    http::data $tok

    package require http
    package require tls
    package require autoproxy
    autoproxy::init
    http::register https 443 autoproxy::tls\_socket
    set tok \[http::geturl https://www\.example\.com/\]

# <a name='section7'></a>REFERENCES

  1. Berners\-Lee, T\., Fielding R\. and Frystyk, H\. "Hypertext Transfer Protocol
     \-\- HTTP/1\.0", RFC 1945, May 1996,
     \([http://www\.rfc\-editor\.org/rfc/rfc1945\.txt](http://www\.rfc\-editor\.org/rfc/rfc1945\.txt)\)








|
|






|
|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    The end\-of\-options indicator may be used alone to unset any authentication
    details currently enabled\.

# <a name='section6'></a>EXAMPLES

    package require autoproxy
    autoproxy::init
    autoproxy::configure -basic -username ME -password SEKRET
    set tok [http::geturl http://wiki.tcl.tk/]
    http::data $tok

    package require http
    package require tls
    package require autoproxy
    autoproxy::init
    http::register https 443 autoproxy::tls_socket
    set tok [http::geturl https://www.example.com/]

# <a name='section7'></a>REFERENCES

  1. Berners\-Lee, T\., Fielding R\. and Frystyk, H\. "Hypertext Transfer Protocol
     \-\- HTTP/1\.0", RFC 1945, May 1996,
     \([http://www\.rfc\-editor\.org/rfc/rfc1945\.txt](http://www\.rfc\-editor\.org/rfc/rfc1945\.txt)\)

Changes to embedded/md/tcllib/files/modules/httpd/httpd.md.
141
142
143
144
145
146
147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
162
163

# <a name='section2'></a>Minimal Example

Starting a web service requires starting a class of type __httpd::server__,
and providing that server with one or more URIs to service, and
__httpd::reply__ derived classes to generate them\.

    tool::define ::reply\.hello \{
      method content \{\} \{
        my puts "<HTML><HEAD><TITLE>IRM Dispatch Server</TITLE></HEAD><BODY>"
        my puts "<h1>Hello World\!</h1>"
        my puts </BODY></HTML>
      \}
    \}


    ::docserver::server create HTTPD port 8015 myaddr 127\.0\.0\.1
    HTTPD add\_uri /\* \[list mixin reply\.hello\]

# <a name='section3'></a>Class ::httpd::server

This class is the root object of the webserver\. It is responsible for opening
the socket and providing the initial connection negotiation\.

  - <a name='1'></a>constructor ?port ?port?? ?myaddr ?ipaddr?&#124;all? ?server\_string ?string?? ?server\_name ?string??







|
|

|

<
<
>
>
|
|







141
142
143
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160
161
162
163

# <a name='section2'></a>Minimal Example

Starting a web service requires starting a class of type __httpd::server__,
and providing that server with one or more URIs to service, and
__httpd::reply__ derived classes to generate them\.

    tool::define ::reply.hello {
      method content {} {
        my puts "<HTML><HEAD><TITLE>IRM Dispatch Server</TITLE></HEAD><BODY>"
        my puts "<h1>Hello World!</h1>"
        my puts </BODY></HTML>


      }
    }
    ::docserver::server create HTTPD port 8015 myaddr 127.0.0.1
    HTTPD add_uri /* [list mixin reply.hello]

# <a name='section3'></a>Class ::httpd::server

This class is the root object of the webserver\. It is responsible for opening
the socket and providing the initial connection negotiation\.

  - <a name='1'></a>constructor ?port ?port?? ?myaddr ?ipaddr?&#124;all? ?server\_string ?string?? ?server\_name ?string??
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
    the __puts__ method of the reply, or simply populating the
    *reply\_body* variable of the object\. The information returned by the
    __content__ method is not interpreted in any way\. If an exception is
    thrown \(via the __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ command in
    Tcl, for example\) the caller will auto\-generate a 500 \{Internal Error\}
    message\. A typical implementation of __content__ look like:

    tool::define ::test::content\.file \{
    	superclass ::httpd::content\.file
    	\# Return a file
    	\# Note: this is using the content\.file mixin which looks for the reply\_file variable
    	\# and will auto\-compute the Content\-Type
    	method content \{\} \{
    	  my reset
        set doc\_root \[my http\_info get doc\_root\]
        my variable reply\_file
        set reply\_file \[file join $doc\_root index\.html\]
    	\}
    \}


    tool::define ::test::content\.time \{
      \# return the current system time
    	method content \{\} \{
    		my variable reply\_body
        my reply set Content\-Type text/plain
    		set reply\_body \[clock seconds\]
    	\}
    \}


    tool::define ::test::content\.echo \{
    	method content \{\} \{
    		my variable reply\_body
        my reply set Content\-Type \[my request get CONTENT\_TYPE\]
    		set reply\_body \[my PostData \[my request get CONTENT\_LENGTH\]\]
    	\}
    \}


    tool::define ::test::content\.form\_handler \{
    	method content \{\} \{
    	  set form \[my FormData\]
    	  my reply set Content\-Type \{text/html; charset=UTF\-8\}
        my puts \[my html header \{My Dynamic Page\}\]
        my puts "<BODY>"
        my puts "You Sent<p>"
        my puts "<TABLE>"
        foreach \{f v\} $form \{
          my puts "<TR><TH>$f</TH><TD><verbatim>$v</verbatim></TD>"
        \}

        my puts "</TABLE><p>"
        my puts "Send some info:<p>"
        my puts "<FORM action=/\[my http\_info get REQUEST\_PATH\] method POST>"
        my puts "<TABLE>"
        foreach field \{name rank serial\_number\} \{
          set line "<TR><TH>$field</TH><TD><input name=\\"$field\\" "
          if \{\[dict exists $form $field\]\} \{
            append line " value=\\"\[dict get $form $field\]\\"""
          \}

          append line " /></TD></TR>"
          my puts $line
        \}

        my puts "</TABLE>"
        my puts \[my html footer\]
    	\}
    \}



  - <a name='32'></a>method __EncodeStatus__ *status*

    Formulate a standard HTTP status header from he string provided\.

  - <a name='33'></a>method FormData








|
|
|
|
|
|

|
|
|
<
<
>
>
|
|
|
|
|
|
<
<
>
>
|
|
|
|
|
<
<
>
>
|
|
|
|
|



|

<
>


|

|
|
|
|
<
>


<
>

|
<
<
>
>







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
    the __puts__ method of the reply, or simply populating the
    *reply\_body* variable of the object\. The information returned by the
    __content__ method is not interpreted in any way\. If an exception is
    thrown \(via the __[error](\.\./\.\./\.\./\.\./index\.md\#error)__ command in
    Tcl, for example\) the caller will auto\-generate a 500 \{Internal Error\}
    message\. A typical implementation of __content__ look like:

    tool::define ::test::content.file {
    	superclass ::httpd::content.file
    	# Return a file
    	# Note: this is using the content.file mixin which looks for the reply_file variable
    	# and will auto-compute the Content-Type
    	method content {} {
    	  my reset
        set doc_root [my http_info get doc_root]
        my variable reply_file
        set reply_file [file join $doc_root index.html]


    	}
    }
    tool::define ::test::content.time {
      # return the current system time
    	method content {} {
    		my variable reply_body
        my reply set Content-Type text/plain
    		set reply_body [clock seconds]


    	}
    }
    tool::define ::test::content.echo {
    	method content {} {
    		my variable reply_body
        my reply set Content-Type [my request get CONTENT_TYPE]
    		set reply_body [my PostData [my request get CONTENT_LENGTH]]


    	}
    }
    tool::define ::test::content.form_handler {
    	method content {} {
    	  set form [my FormData]
    	  my reply set Content-Type {text/html; charset=UTF-8}
        my puts [my html header {My Dynamic Page}]
        my puts "<BODY>"
        my puts "You Sent<p>"
        my puts "<TABLE>"
        foreach {f v} $form {
          my puts "<TR><TH>$f</TH><TD><verbatim>$v</verbatim></TD>"

        }
        my puts "</TABLE><p>"
        my puts "Send some info:<p>"
        my puts "<FORM action=/[my http_info get REQUEST_PATH] method POST>"
        my puts "<TABLE>"
        foreach field {name rank serial_number} {
          set line "<TR><TH>$field</TH><TD><input name=\"$field\" "
          if {[dict exists $form $field]} {
            append line " value=\"[dict get $form $field]\"""

          }
          append line " /></TD></TR>"
          my puts $line

        }
        my puts "</TABLE>"
        my puts [my html footer]


    	}
    }

  - <a name='32'></a>method __EncodeStatus__ *status*

    Formulate a standard HTTP status header from he string provided\.

  - <a name='33'></a>method FormData

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
    %a, %d %b %Y %T %Z

  - <a name='41'></a>method __TransferComplete__ *args*

    Intended to be invoked from __chan copy__ as a callback\. This closes
    every channel fed to it on the command line, and then destroys the object\.

    \#\#\#
    \# Output the body
    \#\#\#
    chan configure $sock \-translation binary \-blocking 0 \-buffering full \-buffersize 4096
    chan configure $chan \-translation binary \-blocking 0 \-buffering full \-buffersize 4096
    if \{$length\} \{
      \#\#\#
      \# Send any POST/PUT/etc content
      \#\#\#
      chan copy $sock $chan \-size $SIZE \-command \[info coroutine\]
      yield
    \}

    catch \{close $sock\}
    chan flush $chan

  - <a name='42'></a>method __Url\_Decode__ *string*

    De\-httpizes a string\.

# <a name='section10'></a>Class ::httpd::content







|
|
|
|
|
|
|
|
|
|

<
>
|







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
    %a, %d %b %Y %T %Z

  - <a name='41'></a>method __TransferComplete__ *args*

    Intended to be invoked from __chan copy__ as a callback\. This closes
    every channel fed to it on the command line, and then destroys the object\.

    ###
    # Output the body
    ###
    chan configure $sock -translation binary -blocking 0 -buffering full -buffersize 4096
    chan configure $chan -translation binary -blocking 0 -buffering full -buffersize 4096
    if {$length} {
      ###
      # Send any POST/PUT/etc content
      ###
      chan copy $sock $chan -size $SIZE -command [info coroutine]
      yield

    }
    catch {close $sock}
    chan flush $chan

  - <a name='42'></a>method __Url\_Decode__ *string*

    De\-httpizes a string\.

# <a name='section10'></a>Class ::httpd::content
Changes to embedded/md/tcllib/files/modules/imap4/imap4.md.
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    The namespace variable __::imap4::use\_ssl__ can be used to establish to
    a secure connection via TSL/SSL if set to true\. In this case default
    connection port defaults to 993\.

    *Note:* For connecting via SSL the Tcl module *tls* must be already
    loaded otherwise an error is raised\.

        package require tls              ; \# must be loaded for TLS/SSL
        set ::imap4::use\_ssl 1           ; \# request a secure connection
        set chan \[::imap4::open $server\] ; \# default port is now 993

  - <a name='2'></a>__::imap4::starttls__ *chan*

    Use this when tasked with connecting to an unsecure port which must be
    changed to a secure port prior to user login\. This feature is known as
    *STARTTLS*\.








|
|
|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    The namespace variable __::imap4::use\_ssl__ can be used to establish to
    a secure connection via TSL/SSL if set to true\. In this case default
    connection port defaults to 993\.

    *Note:* For connecting via SSL the Tcl module *tls* must be already
    loaded otherwise an error is raised\.

        package require tls              ; # must be loaded for TLS/SSL
        set ::imap4::use_ssl 1           ; # request a secure connection
        set chan [::imap4::open $server] ; # default port is now 993

  - <a name='2'></a>__::imap4::starttls__ *chan*

    Use this when tasked with connecting to an unsecure port which must be
    changed to a secure port prior to user login\. This feature is known as
    *STARTTLS*\.

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

    *mboxname* \- mailbox name, defaults to "\*"

    If __\-inline__ is specified a compact folderlist is returned instead of
    the result code\. All flags are converted to lowercase and leading special
    characters are removed\.

        \{\{Arc08 noselect\} \{Arc08/Private \{noinferiors unmarked\}\} \{INBOX noinferiors\}\}

  - <a name='5'></a>__::imap4::select__ *chan* ?*mailbox*?

    Select a mailbox, 0 is returned on success\.

    *chan* \- imap channel








|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

    *mboxname* \- mailbox name, defaults to "\*"

    If __\-inline__ is specified a compact folderlist is returned instead of
    the result code\. All flags are converted to lowercase and leading special
    characters are removed\.

        {{Arc08 noselect} {Arc08/Private {noinferiors unmarked}} {INBOX noinferiors}}

  - <a name='5'></a>__::imap4::select__ *chan* ?*mailbox*?

    Select a mailbox, 0 is returned on success\.

    *chan* \- imap channel

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

    Currently supported options: *delim* \- hierarchy delimiter only, *match*
    \- ref and mbox search patterns \(see __::imap4::folders__\), *names* \-
    list of folder names only, *flags* \- list of folder names with flags in
    format *\{ \{name \{flags\}\} \.\.\. \}* \(see also compact format in function
    __::imap4::folders__\)\.

        \{\{Arc08 \{\{\\NoSelect\}\}\} \{Arc08/Private \{\{\\NoInferiors\} \{\\UnMarked\}\}\} \{INBOX \{\\NoInferiors\}\}\}

  - <a name='11'></a>__::imap4::msginfo__ *chan* *msgid* ?*info*? ?*defval*?

    Get information \(from previously collected using fetch\) from a given
    *msgid*\. If the 'info' argument is omitted or a null string, the list of
    available information options for the given message is returned\.








|







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

    Currently supported options: *delim* \- hierarchy delimiter only, *match*
    \- ref and mbox search patterns \(see __::imap4::folders__\), *names* \-
    list of folder names only, *flags* \- list of folder names with flags in
    format *\{ \{name \{flags\}\} \.\.\. \}* \(see also compact format in function
    __::imap4::folders__\)\.

        {{Arc08 {{\NoSelect}}} {Arc08/Private {{\NoInferiors} {\UnMarked}}} {INBOX {\NoInferiors}}}

  - <a name='11'></a>__::imap4::msginfo__ *chan* *msgid* ?*info*? ?*defval*?

    Get information \(from previously collected using fetch\) from a given
    *msgid*\. If the 'info' argument is omitted or a null string, the list of
    available information options for the given message is returned\.

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    'recent' flagged msgs\), *FLAGS*

    In conjunction with OK: *PERMFLAGS*, *UIDNEXT*, *UIDVAL*, *UNSEEN*

    Div\. states: *CURRENT*, *FOUND*, *PERM*\.

        ::imap4::select $chan INBOX
        puts "\[::imap4::mboxinfo $chan exists\] mails in INBOX"

  - <a name='13'></a>__::imap4::isableto__ *chan* ?*capability*?

    Test for capability\. It returns 1 if requested capability is supported, 0
    otherwise\. If *capability* is omitted all capability imap codes are
    retured as list\.








|







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    'recent' flagged msgs\), *FLAGS*

    In conjunction with OK: *PERMFLAGS*, *UIDNEXT*, *UIDVAL*, *UNSEEN*

    Div\. states: *CURRENT*, *FOUND*, *PERM*\.

        ::imap4::select $chan INBOX
        puts "[::imap4::mboxinfo $chan exists] mails in INBOX"

  - <a name='13'></a>__::imap4::isableto__ *chan* ?*capability*?

    Test for capability\. It returns 1 if requested capability is supported, 0
    otherwise\. If *capability* is omitted all capability imap codes are
    retured as list\.

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339

    *Imap conditional search flags:* SMALLER, LARGER, ON, SENTBEFORE, SENTON,
    SENTSINCE, SINCE, BEFORE \(not implemented\), UID \(not implemented\)

    *Logical search conditions:* OR, NOT

        ::imap4::search $chan larger 4000 seen
        puts "Found messages: \[::imap4::mboxinfo $chan found\]"
        Found messages: 1 3 6 7 8 9 13 14 15 19 20

  - <a name='20'></a>__::imap4::close__ *chan*

    Close the mailbox\. Permanently removes \\Deleted messages and return to the
    AUTH state\.








|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339

    *Imap conditional search flags:* SMALLER, LARGER, ON, SENTBEFORE, SENTON,
    SENTSINCE, SINCE, BEFORE \(not implemented\), UID \(not implemented\)

    *Logical search conditions:* OR, NOT

        ::imap4::search $chan larger 4000 seen
        puts "Found messages: [::imap4::mboxinfo $chan found]"
        Found messages: 1 3 6 7 8 9 13 14 15 19 20

  - <a name='20'></a>__::imap4::close__ *chan*

    Close the mailbox\. Permanently removes \\Deleted messages and return to the
    AUTH state\.

386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

      * \-FLAGS

        Remove the flags in *flaglist* to the existing flags for the message\.

    For example:

        ::imap4::store $chan $start\_msgid:$end\_msgid \+FLAGS "Deleted"

  - <a name='24'></a>__::imap4::expunge__ *chan*

    Permanently removes all messages that have the \\Deleted flag set from the
    currently selected mailbox, without the need to close the connection\.

    *chan* \- imap channel







|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

      * \-FLAGS

        Remove the flags in *flaglist* to the existing flags for the message\.

    For example:

        ::imap4::store $chan $start_msgid:$end_msgid +FLAGS "Deleted"

  - <a name='24'></a>__::imap4::expunge__ *chan*

    Permanently removes all messages that have the \\Deleted flag set from the
    currently selected mailbox, without the need to close the connection\.

    *chan* \- imap channel
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

    *chan* \- imap channel

# <a name='section3'></a>EXAMPLES

    set user myusername
    set pass xtremescrt
    set server imap\.test\.tld
    set FOLDER INBOX
    \# Connect to server
    set imap \[::imap4::open $server\]
    ::imap4::login $imap $user $pass
    ::imap4::select $imap $FOLDER
    \# Output all the information about that mailbox
    foreach info \[::imap4::mboxinfo $imap\] \{
        puts "$info \-> \[::imap4::mboxinfo $imap $info\]"
    \}

    \# fetch 3 records inline
    set fields \{from: to: subject: size\}
    foreach rec \[::imap4::fetch $imap :3 \-inline \{\*\}$fields\] \{
        puts \-nonewline "\#\[incr idx\]\)"
        for \{set j 0\} \{$j<\[llength $fields\]\} \{incr j\} \{
            puts "\\t\[lindex $fields $j\] \[lindex $rec $j\]"
        \}
    \}



    \# Show all the information available about the message ID 1
    puts "Available info about message 1: \[::imap4::msginfo $imap 1\]"

    \# Use the capability stuff
    puts "Capabilities: \[::imap4::isableto $imap\]"
    puts "Is able to imap4rev1? \[::imap4::isableto $imap imap4rev1\]"

    \# Cleanup
    ::imap4::cleanup $imap

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.








|

|
|


|
|
|
<
>
|
|
|
|
|
|
<
<
|
>
>
|
|

|
|
|

|







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

    *chan* \- imap channel

# <a name='section3'></a>EXAMPLES

    set user myusername
    set pass xtremescrt
    set server imap.test.tld
    set FOLDER INBOX
    # Connect to server
    set imap [::imap4::open $server]
    ::imap4::login $imap $user $pass
    ::imap4::select $imap $FOLDER
    # Output all the information about that mailbox
    foreach info [::imap4::mboxinfo $imap] {
        puts "$info -> [::imap4::mboxinfo $imap $info]"

    }
    # fetch 3 records inline
    set fields {from: to: subject: size}
    foreach rec [::imap4::fetch $imap :3 -inline {*}$fields] {
        puts -nonewline "#[incr idx])"
        for {set j 0} {$j<[llength $fields]} {incr j} {
            puts "\t[lindex $fields $j] [lindex $rec $j]"


        }
    }

    # Show all the information available about the message ID 1
    puts "Available info about message 1: [::imap4::msginfo $imap 1]"

    # Use the capability stuff
    puts "Capabilities: [::imap4::isableto $imap]"
    puts "Is able to imap4rev1? [::imap4::isableto $imap imap4rev1]"

    # Cleanup
    ::imap4::cleanup $imap

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section5'></a>REFERENCES

Mark R\. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL \- VERSION 4rev1", RFC 3501,
March 2003,
[http://www\.rfc\-editor\.org/rfc/rfc3501\.txt](http://www\.rfc\-editor\.org/rfc/rfc3501\.txt)








|

|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section5'></a>REFERENCES

Mark R\. Crispin, "INTERNET MESSAGE ACCESS PROTOCOL \- VERSION 4rev1", RFC 3501,
March 2003,
[http://www\.rfc\-editor\.org/rfc/rfc3501\.txt](http://www\.rfc\-editor\.org/rfc/rfc3501\.txt)

Changes to embedded/md/tcllib/files/modules/irc/picoirc.md.
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
    break error code to halt further processing\. In this way the application can
    override the default send via the callback procedure\.

# <a name='section3'></a>CALLBACK

The callback must look like:

    proc Callback \{context state args\} \{
    \}


where context is the irc context variable name \(in case you need to pass it back
to a picoirc procedure\)\. state is one of a number of states as described below\.

  - __init__

    called just before the socket is created







|
<
>







87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
    break error code to halt further processing\. In this way the application can
    override the default send via the callback procedure\.

# <a name='section3'></a>CALLBACK

The callback must look like:

    proc Callback {context state args} {

    }

where context is the irc context variable name \(in case you need to pass it back
to a picoirc procedure\)\. state is one of a number of states as described below\.

  - __init__

    called just before the socket is created
Changes to embedded/md/tcllib/files/modules/jpeg/jpeg.md.
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
    thumbnail is included in *file*, and the empty string otherwise\. Note that
    it is possible to include thumbnails in formats other than JPEG although
    that is not common\. The command finds thumbnails that are encoded in either
    the JFXX or EXIF segments of the JPEG information\. If both are present the
    EXIF thumbnail will take precedence\. Throws an error if *file* is not a
    JPEG image\.

        set fh \[open thumbnail\.jpg w\+\]
        fconfigure $fh \-translation binary \-encoding binary
        puts \-nonewline $fh \[::jpeg::getThumbnail photo\.jpg\]
        close $fh

  - <a name='5'></a>__::jpeg::getExif__ *file* ?*section*?

    *section* must be one of __main__ or __thumbnail__\. The default is
    __main__\. Returns a dictionary containing the EXIF information for the
    specified section\. For example:

            set exif \{
        	Make     Canon
        	Model    \{Canon DIGITAL IXUS\}
        	DateTime \{2001:06:09 15:17:32\}
            \}


    Throws an error if *file* is not a JPEG image\.

  - <a name='6'></a>__::jpeg::getExifFromChannel__ *channel* ?*section*?

    This command is as per __::jpeg::getExif__ except that it uses a
    previously opened channel\. *channel* should be a seekable channel and







|
|
|








|

|
|
<
>







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
    thumbnail is included in *file*, and the empty string otherwise\. Note that
    it is possible to include thumbnails in formats other than JPEG although
    that is not common\. The command finds thumbnails that are encoded in either
    the JFXX or EXIF segments of the JPEG information\. If both are present the
    EXIF thumbnail will take precedence\. Throws an error if *file* is not a
    JPEG image\.

        set fh [open thumbnail.jpg w+]
        fconfigure $fh -translation binary -encoding binary
        puts -nonewline $fh [::jpeg::getThumbnail photo.jpg]
        close $fh

  - <a name='5'></a>__::jpeg::getExif__ *file* ?*section*?

    *section* must be one of __main__ or __thumbnail__\. The default is
    __main__\. Returns a dictionary containing the EXIF information for the
    specified section\. For example:

            set exif {
        	Make     Canon
        	Model    {Canon DIGITAL IXUS}
        	DateTime {2001:06:09 15:17:32}

            }

    Throws an error if *file* is not a JPEG image\.

  - <a name='6'></a>__::jpeg::getExifFromChannel__ *channel* ?*section*?

    This command is as per __::jpeg::getExif__ except that it uses a
    previously opened channel\. *channel* should be a seekable channel and
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148

  - <a name='7'></a>__::jpeg::formatExif__ *keys*

    Takes a list of key\-value pairs as returned by __getExif__ and formats
    many of the values into a more human readable form\. As few as one key\-value
    may be passed in, the entire exif is not required\.

        foreach \{key val\} \[::jpeg::formatExif \[::jpeg::getExif photo\.jpg\]\] \{
            puts "$key: $val"
        \}


        array set exif \[::jpeg::getExif photo\.jpg\]
        puts "max f\-stop: \[::jpeg::formatExif \[list MaxAperture $exif\(MaxAperture\)\]\]

  - <a name='8'></a>__::jpeg::exifKeys__

    Returns a list of the EXIF keys which are currently understood\. There may be
    keys present in __getExif__ data that are not understood\. Those keys
    will appear in a 4 digit hexadecimal format\.








|

<
|
>
|
|







129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
145
146
147
148

  - <a name='7'></a>__::jpeg::formatExif__ *keys*

    Takes a list of key\-value pairs as returned by __getExif__ and formats
    many of the values into a more human readable form\. As few as one key\-value
    may be passed in, the entire exif is not required\.

        foreach {key val} [::jpeg::formatExif [::jpeg::getExif photo.jpg]] {
            puts "$key: $val"

        }

        array set exif [::jpeg::getExif photo.jpg]
        puts "max f-stop: [::jpeg::formatExif [list MaxAperture $exif(MaxAperture)]]

  - <a name='8'></a>__::jpeg::exifKeys__

    Returns a list of the EXIF keys which are currently understood\. There may be
    keys present in __getExif__ data that are not understood\. Those keys
    will appear in a 4 digit hexadecimal format\.

Changes to embedded/md/tcllib/files/modules/json/json.md.
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
    throw an error\.

# <a name='section3'></a>EXAMPLES

An example of a JSON array converted to Tcl\. A JSON array is returned as a
single item with multiple elements\.

    \[
        \{


           "precision": "zip",
           "Latitude":  37\.7668,
           "Longitude": \-122\.3959,
           "Address":   "",
           "City":      "SAN FRANCISCO",
           "State":     "CA",
           "Zip":       "94107",
           "Country":   "US"
        \},
        \{

           "precision": "zip",
           "Latitude":  37\.371991,
           "Longitude": \-122\.026020,
           "Address":   "",
           "City":      "SUNNYVALE",
           "State":     "CA",
           "Zip":       "94085",
           "Country":   "US"
        \}
    \]


    =>
    \{Country US Latitude 37\.7668 precision zip State CA City \{SAN FRANCISCO\} Address \{\} Zip 94107 Longitude \-122\.3959\} \{Country US Latitude 37\.371991 precision zip State CA City SUNNYVALE Address \{\} Zip 94085 Longitude \-122\.026020\}

An example of a JSON object converted to Tcl\. A JSON object is returned as a
multi\-element list \(a dict\)\.

    \{

        "Image": \{
            "Width":  800,
            "Height": 600,
            "Title":  "View from 15th Floor",
            "Thumbnail": \{
                "Url":    "http://www\.example\.com/image/481989943",
                "Height": 125,
                "Width":  "100"
            \},
            "IDs": \[116, 943, 234, 38793\]
        \}
    \}


    =>
    Image \{IDs \{116 943 234 38793\} Thumbnail \{Width 100 Height 125 Url http://www\.example\.com/image/481989943\} Width 800 Height 600 Title \{View from 15th Floor\}\}

# <a name='section4'></a>RELATED

To write json, instead of parsing it, see package
__[json::write](json\_write\.md)__\.

# <a name='section5'></a>Bugs, Ideas, Feedback







<
<
>
>

|
|





|
<
>

|
|





<
<
>
>

|




<
>
|



|
|


|
|
<
<
>
>

|







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
    throw an error\.

# <a name='section3'></a>EXAMPLES

An example of a JSON array converted to Tcl\. A JSON array is returned as a
single item with multiple elements\.



    [
        {
           "precision": "zip",
           "Latitude":  37.7668,
           "Longitude": -122.3959,
           "Address":   "",
           "City":      "SAN FRANCISCO",
           "State":     "CA",
           "Zip":       "94107",
           "Country":   "US"
        },

        {
           "precision": "zip",
           "Latitude":  37.371991,
           "Longitude": -122.026020,
           "Address":   "",
           "City":      "SUNNYVALE",
           "State":     "CA",
           "Zip":       "94085",
           "Country":   "US"


        }
    ]
    =>
    {Country US Latitude 37.7668 precision zip State CA City {SAN FRANCISCO} Address {} Zip 94107 Longitude -122.3959} {Country US Latitude 37.371991 precision zip State CA City SUNNYVALE Address {} Zip 94085 Longitude -122.026020}

An example of a JSON object converted to Tcl\. A JSON object is returned as a
multi\-element list \(a dict\)\.


    {
        "Image": {
            "Width":  800,
            "Height": 600,
            "Title":  "View from 15th Floor",
            "Thumbnail": {
                "Url":    "http://www.example.com/image/481989943",
                "Height": 125,
                "Width":  "100"
            },
            "IDs": [116, 943, 234, 38793]


        }
    }
    =>
    Image {IDs {116 943 234 38793} Thumbnail {Width 100 Height 125 Url http://www.example.com/image/481989943} Width 800 Height 600 Title {View from 15th Floor}}

# <a name='section4'></a>RELATED

To write json, instead of parsing it, see package
__[json::write](json\_write\.md)__\.

# <a name='section5'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/lambda/lambda.md.
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
# <a name='description'></a>DESCRIPTION

This package provides two convenience commands to make the writing of anonymous
procedures, i\.e\. lambdas more
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__\-like\. Instead of, for example, to
write

    set f \{::apply \{\{x\} \{
       \.\.\.\.
    \}\}\}

with its deep nesting of braces, or

    set f \[list ::apply \{\{x y\} \{
       \.\.\.\.
    \}\} $value\_for\_x\]

with a list command to insert some of the arguments of a partial application,
just write

    set f \[lambda \{x\} \{
       \.\.\.\.
    \}\]

and

    set f \[lambda \{x y\} \{
       \.\.\.\.
    \} $value\_for\_x\]

# <a name='section2'></a>COMMANDS

  - <a name='1'></a>__::lambda__ *arguments* *body* ?*arg*\.\.\.?

    The command constructs an anonymous procedure from the list of arguments,
    body script and \(optional\) predefined argument values and returns a command







|
|
|



|
|
|




|
|
|



|
|
|







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
# <a name='description'></a>DESCRIPTION

This package provides two convenience commands to make the writing of anonymous
procedures, i\.e\. lambdas more
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__\-like\. Instead of, for example, to
write

    set f {::apply {{x} {
       ....
    }}}

with its deep nesting of braces, or

    set f [list ::apply {{x y} {
       ....
    }} $value_for_x]

with a list command to insert some of the arguments of a partial application,
just write

    set f [lambda {x} {
       ....
    }]

and

    set f [lambda {x y} {
       ....
    } $value_for_x]

# <a name='section2'></a>COMMANDS

  - <a name='1'></a>__::lambda__ *arguments* *body* ?*arg*\.\.\.?

    The command constructs an anonymous procedure from the list of arguments,
    body script and \(optional\) predefined argument values and returns a command
Changes to embedded/md/tcllib/files/modules/lazyset/lazyset.md.
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
    boolean* is specified as true, then 2 arguments are appended corresponding
    to the name of the variable and the index, otherwise 1 argument is appended
    containing the name of variable\. The *commandPrefix* code is run in the
    same scope as the variable is read\.

# <a name='section3'></a>EXAMPLES

    ::lazyset::variable page \{apply \{\{name\} \{
    	package require http
    	set token \[http::geturl http://www\.tcl\.tk/\]
    	set data \[http::data $token\]
    	return $data
    \}\}\}

    puts $page

    ::lazyset::variable \-array true page \{apply \{\{name index\} \{
    	package require http
    	set token \[http::geturl $index\]
    	set data \[http::data $token\]
    	return $data
    \}\}\}

    puts $page\(http://www\.tcl\.tk/\)

    ::lazyset::variable \-appendArgs false simple \{
    	return \-level 0 42
    \}


    puts $simple

# <a name='section4'></a>AUTHORS

Roy Keene








|

|
|

|



|

|
|

|

|

|
|
<
>







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
    boolean* is specified as true, then 2 arguments are appended corresponding
    to the name of the variable and the index, otherwise 1 argument is appended
    containing the name of variable\. The *commandPrefix* code is run in the
    same scope as the variable is read\.

# <a name='section3'></a>EXAMPLES

    ::lazyset::variable page {apply {{name} {
    	package require http
    	set token [http::geturl http://www.tcl.tk/]
    	set data [http::data $token]
    	return $data
    }}}

    puts $page

    ::lazyset::variable -array true page {apply {{name index} {
    	package require http
    	set token [http::geturl $index]
    	set data [http::data $token]
    	return $data
    }}}

    puts $page(http://www.tcl.tk/)

    ::lazyset::variable -appendArgs false simple {
    	return -level 0 42

    }

    puts $simple

# <a name='section4'></a>AUTHORS

Roy Keene

Changes to embedded/md/tcllib/files/modules/ldap/ldap.md.
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section3'></a>COMMANDS

  - <a name='1'></a>__::ldap::connect__ *host* ?*port*?

    Opens a LDAPv3 connection to the specified *host*, at the given *port*,
    and returns a token for the connection\. This token is the *handle*







|

|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section3'></a>COMMANDS

  - <a name='1'></a>__::ldap::connect__ *host* ?*port*?

    Opens a LDAPv3 connection to the specified *host*, at the given *port*,
    and returns a token for the connection\. This token is the *handle*
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    If *verify\_cert* is set to 1, the default, this checks the server
    certificate against the known hosts\. If *sni\_servername* is set, the given
    hostname is used as the hostname for Server Name Indication in the TLS
    handshake\.

    Use __::tls::init__ to setup defaults for trusted certificates\.

    tls::init \-cadir /etc/ssl/certs/ca\-certificates\.crt

    TLS supports different protocol levels\. In common use are the versions 1\.0,
    1\.1 and 1\.2\. By default all those versions are offered\. If you need to
    modify the acceptable protocols, you can change the ::ldap::tlsProtocols
    list\.

  - <a name='3'></a>__::ldap::disconnect__ *handle*







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    If *verify\_cert* is set to 1, the default, this checks the server
    certificate against the known hosts\. If *sni\_servername* is set, the given
    hostname is used as the hostname for Server Name Indication in the TLS
    handshake\.

    Use __::tls::init__ to setup defaults for trusted certificates\.

    tls::init -cadir /etc/ssl/certs/ca-certificates.crt

    TLS supports different protocol levels\. In common use are the versions 1\.0,
    1\.1 and 1\.2\. By default all those versions are offered\. If you need to
    modify the acceptable protocols, you can change the ::ldap::tlsProtocols
    list\.

  - <a name='3'></a>__::ldap::disconnect__ *handle*
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
    *attributes* of all matching objects \(DNs\)\. If the list of *attributes*
    was empty all attributes are returned\. The command blocks until it has
    received all results\. The valid *options* are identical to the options
    listed for __::ldap::searchInit__\.

    An example of a search expression is

    set filterString "&#124;\(cn=Linus\*\)\(sn=Torvalds\*\)"

    The return value of the command is a list of nested dictionaries\. The first
    level keys are object identifiers \(DNs\), second levels keys are attribute
    names\. In other words, it is in the form

    \{dn1 \{attr1 \{val11 val12 \.\.\.\} attr2 \{val21\.\.\.\} \.\.\.\}\} \{dn2 \{a1 \{v11 \.\.\.\} \.\.\.\}\} \.\.\.

  - <a name='9'></a>__::ldap::searchInit__ *handle* *baseObject* *filterString* *attributes* *options*

    This command initiates a LDAP search below the *baseObject* tree using a
    complex LDAP search expression *filterString*\. The search gets the
    specified *attributes* of all matching objects \(DNs\)\. The command itself
    just starts the search, to retrieve the actual results, use
    __::ldap::searchNext__\. A search can be terminated at any time by
    __::ldap::searchEnd__\. This informs the server that no further results
    should be sent by sending and ABANDON message and cleans up the internal
    state of the search\. Only one __::ldap::search__ can be active at a
    given time, this includes the introspection commands __::ldap::info
    saslmechanisms__, __ldap::info control__ and __ldap::info
    extensions__, which invoke a search internally\. Error responses from the
    server due to wrong arguments or similar things are returned with the first
    __::ldap::searchNext__ call and should be checked and dealed with there\.
    If the list of requested *attributes* is empty all attributes will be
    returned\. The parameter *options* specifies the options to be used in the
    search, and has the following format:

    \{\-option1 value1 \-option2 value2 \.\.\. \}

    Following options are available:

      * __\-scope__ base one sub

        Control the scope of the search to be one of __base__, __one__,
        or __sub__, to specify a base object, one\-level or subtree search\.







|





|




















|







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
    *attributes* of all matching objects \(DNs\)\. If the list of *attributes*
    was empty all attributes are returned\. The command blocks until it has
    received all results\. The valid *options* are identical to the options
    listed for __::ldap::searchInit__\.

    An example of a search expression is

    set filterString "|(cn=Linus*)(sn=Torvalds*)"

    The return value of the command is a list of nested dictionaries\. The first
    level keys are object identifiers \(DNs\), second levels keys are attribute
    names\. In other words, it is in the form

    {dn1 {attr1 {val11 val12 ...} attr2 {val21...} ...}} {dn2 {a1 {v11 ...} ...}} ...

  - <a name='9'></a>__::ldap::searchInit__ *handle* *baseObject* *filterString* *attributes* *options*

    This command initiates a LDAP search below the *baseObject* tree using a
    complex LDAP search expression *filterString*\. The search gets the
    specified *attributes* of all matching objects \(DNs\)\. The command itself
    just starts the search, to retrieve the actual results, use
    __::ldap::searchNext__\. A search can be terminated at any time by
    __::ldap::searchEnd__\. This informs the server that no further results
    should be sent by sending and ABANDON message and cleans up the internal
    state of the search\. Only one __::ldap::search__ can be active at a
    given time, this includes the introspection commands __::ldap::info
    saslmechanisms__, __ldap::info control__ and __ldap::info
    extensions__, which invoke a search internally\. Error responses from the
    server due to wrong arguments or similar things are returned with the first
    __::ldap::searchNext__ call and should be checked and dealed with there\.
    If the list of requested *attributes* is empty all attributes will be
    returned\. The parameter *options* specifies the options to be used in the
    search, and has the following format:

    {-option1 value1 -option2 value2 ... }

    Following options are available:

      * __\-scope__ base one sub

        Control the scope of the search to be one of __base__, __one__,
        or __sub__, to specify a base object, one\-level or subtree search\.
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
    This command returns the next entry from a LDAP search initiated by
    __::ldap::searchInit__\. It returns only after a new result is received
    or when no further results are available, but takes care to keep the event
    loop alive\. The returned entry is a list with two elements: the first is the
    DN of the entry, the second is the list of attributes and values, under the
    format:

    dn \{attr1 \{val11 val12 \.\.\.\} attr2 \{val21\.\.\.\} \.\.\.\}

    The __::ldap::searchNext__ command returns an empty list at the end of
    the search\.

  - <a name='11'></a>__::ldap::searchEnd__ *handle*

    This command terminates a LDAP search initiated by







|







269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
    This command returns the next entry from a LDAP search initiated by
    __::ldap::searchInit__\. It returns only after a new result is received
    or when no further results are available, but takes care to keep the event
    loop alive\. The returned entry is a list with two elements: the first is the
    DN of the entry, the second is the list of attributes and values, under the
    format:

    dn {attr1 {val11 val12 ...} attr2 {val21...} ...}

    The __::ldap::searchNext__ command returns an empty list at the end of
    the search\.

  - <a name='11'></a>__::ldap::searchEnd__ *handle*

    This command terminates a LDAP search initiated by
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  - <a name='13'></a>__::ldap::modifyMulti__ *handle* *dn* *attrValToReplace* ?*attrValToDelete*? ?*attrValToAdd*?

    This command modifies the object *dn* on the ldap server we are connected
    to via *handle*\. It replaces attributes with new values, deletes
    attributes, and adds new attributes with new values\. All arguments are lists
    with the format:

    attr1 \{val11 val12 \.\.\.\} attr2 \{val21\.\.\.\} \.\.\.

    where each value list may be empty for deleting all attributes\. The optional
    arguments default to empty lists of attributes to delete and to add\.

      * list *attrValToReplace* \(in\)

        No attributes will be changed if this argument is empty\. The dictionary







|







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  - <a name='13'></a>__::ldap::modifyMulti__ *handle* *dn* *attrValToReplace* ?*attrValToDelete*? ?*attrValToAdd*?

    This command modifies the object *dn* on the ldap server we are connected
    to via *handle*\. It replaces attributes with new values, deletes
    attributes, and adds new attributes with new values\. All arguments are lists
    with the format:

    attr1 {val11 val12 ...} attr2 {val21...} ...

    where each value list may be empty for deleting all attributes\. The optional
    arguments default to empty lists of attributes to delete and to add\.

      * list *attrValToReplace* \(in\)

        No attributes will be changed if this argument is empty\. The dictionary
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

# <a name='section4'></a>EXAMPLES

A small example, extracted from the test application coming with this code\.

        package require ldap

        \# Connect, bind, add a new object, modify it in various ways

        set handle \[ldap::connect localhost 9009\]

        set dn "cn=Manager, o=University of Michigan, c=US"
        set pw secret

        ldap::bind $handle $dn $pw

        set dn "cn=Test User,ou=People,o=University of Michigan,c=US"

        ldap::add $handle $dn \{
    	objectClass     OpenLDAPperson
    	cn              \{Test User\}
    	mail            test\.user@google\.com
    	uid             testuid
    	sn              User
    	telephoneNumber \+31415926535
    	telephoneNumber \+27182818285
        \}


        set dn "cn=Another User,ou=People,o=University of Michigan,c=US"

        ldap::addMulti $handle $dn \{
    	objectClass     \{OpenLDAPperson\}
    	cn              \{\{Anotther User\}\}
    	mail            \{test\.user@google\.com\}
    	uid             \{testuid\}
    	sn              \{User\}
    	telephoneNumber \{\+31415926535 \+27182818285\}
        \}


        \# Replace all attributes
        ldap::modify $handle $dn \[list drink icetea uid JOLO\]

        \# Add some more
        ldap::modify $handle $dn \{\} \{\} \[list drink water  drink orangeJuice pager "\+1 313 555 7671"\]

        \# Delete
        ldap::modify $handle $dn \{\} \[list drink water  pager ""\]

        \# Move
        ldap::modifyDN $handle $dn "cn=Tester"

        \# Kill the test object, and shut the connection down\.
        set dn "cn=Tester,ou=People,o=University of Michigan,c=US"
        ldap::delete $handle $dn

        ldap::unbind     $handle
        ldap::disconnect $handle

And a another example, a simple query, and processing the results\.

        package require ldap
        set handle \[ldap::connect ldap\.acme\.com 389\]
        ldap::bind $handle
        set results \[ldap::search $handle "o=acme,dc=com" "\(uid=jdoe\)" \{\}\]
        foreach result $results \{
    	foreach \{object attributes\} $result break

    	\# The processing here is similar to what 'parray' does\.
    	\# I\.e\. finding the longest attribute name and then
    	\# generating properly aligned output listing all attributes
    	\# and their values\.

    	set width 0
    	set sortedAttribs \{\}
    	foreach \{type values\} $attributes \{
    	    if \{\[string length $type\] > $width\} \{
    		set width \[string length $type\]
    	    \}

    	    lappend sortedAttribs \[list $type $values\]
    	\}


    	puts "object='$object'"

    	foreach sortedAttrib  $sortedAttribs \{
    	    foreach \{type values\} $sortedAttrib break
    	    foreach value $values \{
    		regsub \-all "\\\[\\x01\-\\x1f\\\]" $value ? value
    		puts \[format "  %\-$\{width\}s %s" $type $value\]
    	    \}
    	\}


    	puts ""
        \}

        ldap::unbind $handle
        ldap::disconnect $handle

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *ldap* of the [Tcllib







|

|








|

|
|


|
|
<
|
>


|
|
|
|
|
|
|
<
|
>
|
|

|
|

|
|

|


|









|

|
|
|

|
|
|
|


|
|
|
|
<
>
|
<
|
>


|
|
|
|
|
<
<
>
>

<
>







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

# <a name='section4'></a>EXAMPLES

A small example, extracted from the test application coming with this code\.

        package require ldap

        # Connect, bind, add a new object, modify it in various ways

        set handle [ldap::connect localhost 9009]

        set dn "cn=Manager, o=University of Michigan, c=US"
        set pw secret

        ldap::bind $handle $dn $pw

        set dn "cn=Test User,ou=People,o=University of Michigan,c=US"

        ldap::add $handle $dn {
    	objectClass     OpenLDAPperson
    	cn              {Test User}
    	mail            [email protected]
    	uid             testuid
    	sn              User
    	telephoneNumber +31415926535
    	telephoneNumber +27182818285

        }

        set dn "cn=Another User,ou=People,o=University of Michigan,c=US"

        ldap::addMulti $handle $dn {
    	objectClass     {OpenLDAPperson}
    	cn              {{Anotther User}}
    	mail            {test.user@google.com}
    	uid             {testuid}
    	sn              {User}
    	telephoneNumber {+31415926535 +27182818285}

        }

        # Replace all attributes
        ldap::modify $handle $dn [list drink icetea uid JOLO]

        # Add some more
        ldap::modify $handle $dn {} {} [list drink water  drink orangeJuice pager "+1 313 555 7671"]

        # Delete
        ldap::modify $handle $dn {} [list drink water  pager ""]

        # Move
        ldap::modifyDN $handle $dn "cn=Tester"

        # Kill the test object, and shut the connection down.
        set dn "cn=Tester,ou=People,o=University of Michigan,c=US"
        ldap::delete $handle $dn

        ldap::unbind     $handle
        ldap::disconnect $handle

And a another example, a simple query, and processing the results\.

        package require ldap
        set handle [ldap::connect ldap.acme.com 389]
        ldap::bind $handle
        set results [ldap::search $handle "o=acme,dc=com" "(uid=jdoe)" {}]
        foreach result $results {
    	foreach {object attributes} $result break

    	# The processing here is similar to what 'parray' does.
    	# I.e. finding the longest attribute name and then
    	# generating properly aligned output listing all attributes
    	# and their values.

    	set width 0
    	set sortedAttribs {}
    	foreach {type values} $attributes {
    	    if {[string length $type] > $width} {
    		set width [string length $type]

    	    }
    	    lappend sortedAttribs [list $type $values]

    	}

    	puts "object='$object'"

    	foreach sortedAttrib  $sortedAttribs {
    	    foreach {type values} $sortedAttrib break
    	    foreach value $values {
    		regsub -all "\[\x01-\x1f\]" $value ? value
    		puts [format "  %-${width}s %s" $type $value]


    	    }
    	}
    	puts ""

        }
        ldap::unbind $handle
        ldap::disconnect $handle

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *ldap* of the [Tcllib
Changes to embedded/md/tcllib/files/modules/ldap/ldapx.md.
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
    difference is computed from the entry and its internal backup \(see section
    [OVERVIEW](#section2)\)\. Return value is the computed change list\.

## <a name='subsection6'></a>Entry Example

    package require ldapx

    \#

    \# Create an entry and fill it as a standard entry with
    \# attributes and values
    \#

    ::ldapx::entry create e
    e dn "uid=joe,ou=people,o=mycomp"
    e set1 "uid"             "joe"
    e set  "objectClass"     \{person anotherObjectClass\}
    e set1 "givenName"       "Joe"
    e set1 "sn"              "User"
    e set  "telephoneNumber" \{\+31415926535 \+2182818\}
    e set1 "anotherAttr"     "This is a beautiful day, isn't it?"

    puts stdout "e\\n\[e print\]"

    \#

    \# Create a second entry as a backup of the first, and
    \# make some changes on it\.
    \# Entry is named automatically by snit\.
    \#


    set b \[::ldapx::entry create %AUTO%\]
    e backup $b

    puts stdout "$b\\n\[$b print\]"

    $b del  "anotherAttr"
    $b del1 "objectClass" "anotherObjectClass"

    \#

    \# Create a change entry, a compute differences between first
    \# and second entry\.
    \#


    ::ldapx::entry create c
    c diff e $b

    puts stdout "$c\\n\[$c print\]"

    \#

    \# Apply changes to first entry\. It should be the same as the
    \# second entry, now\.
    \#


    e apply c

    ::ldapx::entry create nc
    nc diff e $b

    puts stdout "nc\\n\[nc print\]"

    \#

    \# Clean\-up
    \#


    e destroy
    $b destroy
    c destroy
    nc destroy

# <a name='section4'></a>LDAP CLASS







<
>
|
|
<
>



|


|


|

<
>
|
|
|
<
|
>
|


|




<
>
|
|
<
>




|

<
>
|
|
<
>






|

<
>
|
<
>







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
    difference is computed from the entry and its internal backup \(see section
    [OVERVIEW](#section2)\)\. Return value is the computed change list\.

## <a name='subsection6'></a>Entry Example

    package require ldapx


    #
    # Create an entry and fill it as a standard entry with
    # attributes and values

    #
    ::ldapx::entry create e
    e dn "uid=joe,ou=people,o=mycomp"
    e set1 "uid"             "joe"
    e set  "objectClass"     {person anotherObjectClass}
    e set1 "givenName"       "Joe"
    e set1 "sn"              "User"
    e set  "telephoneNumber" {+31415926535 +2182818}
    e set1 "anotherAttr"     "This is a beautiful day, isn't it?"

    puts stdout "e\n[e print]"


    #
    # Create a second entry as a backup of the first, and
    # make some changes on it.
    # Entry is named automatically by snit.

    #

    set b [::ldapx::entry create %AUTO%]
    e backup $b

    puts stdout "$b\n[$b print]"

    $b del  "anotherAttr"
    $b del1 "objectClass" "anotherObjectClass"


    #
    # Create a change entry, a compute differences between first
    # and second entry.

    #

    ::ldapx::entry create c
    c diff e $b

    puts stdout "$c\n[$c print]"


    #
    # Apply changes to first entry. It should be the same as the
    # second entry, now.

    #

    e apply c

    ::ldapx::entry create nc
    nc diff e $b

    puts stdout "nc\n[nc print]"


    #
    # Clean-up

    #

    e destroy
    $b destroy
    c destroy
    nc destroy

# <a name='section4'></a>LDAP CLASS
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
    Note: in the future, this method should use the LDAP transaction extension
    provided by OpenLDAP 2\.3 and later\.

## <a name='subsection10'></a>Ldap Example

        package require ldapx

        \#

        \# Connects to the LDAP directory
        \#


        ::ldapx::ldap create l
        set url "ldap://server\.mycomp\.com"
        if \{\! \[l connect $url "cn=admin,o=mycomp" "mypasswd"\]\} then \{
    	puts stderr "error: \[l error\]"
    	exit 1
        \}

        \#

        \# Search all entries matching some criterion
        \#


        l configure \-scope one
        ::ldapx::entry create e
        set n 0
        l traverse "ou=people,o=mycomp" "\(sn=Joe\*\)" \{sn givenName\} e \{
    	puts "dn: \[e dn\]"
    	puts "  sn:        \[e get1 sn\]"
    	puts "  givenName: \[e get1 givenName\]"
    	incr n
        \}

        puts "$n entries found"
        e destroy

        \#

        \# Add a telephone number to some entries
        \# Note this modification cannot be done in the "traverse" operation\.
        \#


        set lent \[l search "ou=people,o=mycomp" "\(sn=Joe\*\)" \{\}\]
        ::ldapx::entry create c
        foreach e $lent \{
    	$e backup
    	$e add1 "telephoneNumber" "\+31415926535"
    	c diff $e
    	if \{\! \[l commit c\]\} then \{
    	    puts stderr "error: \[l error\]"
    	    exit 1
    	\}

    	$e destroy
        \}

        c destroy

        l disconnect
        l destroy

# <a name='section5'></a>LDIF CLASS








<
>
|
<
|
>

|
|
|

<
|
|
>
|
<
|
>
|


|
|
|
|

<
>



<
>
|
|
<
|
>
|

|

|

|
|

<
>

<
>







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
    Note: in the future, this method should use the LDAP transaction extension
    provided by OpenLDAP 2\.3 and later\.

## <a name='subsection10'></a>Ldap Example

        package require ldapx


        #
        # Connects to the LDAP directory

        #

        ::ldapx::ldap create l
        set url "ldap://server.mycomp.com"
        if {! [l connect $url "cn=admin,o=mycomp" "mypasswd"]} then {
    	puts stderr "error: [l error]"
    	exit 1

        }

        #
        # Search all entries matching some criterion

        #

        l configure -scope one
        ::ldapx::entry create e
        set n 0
        l traverse "ou=people,o=mycomp" "(sn=Joe*)" {sn givenName} e {
    	puts "dn: [e dn]"
    	puts "  sn:        [e get1 sn]"
    	puts "  givenName: [e get1 givenName]"
    	incr n

        }
        puts "$n entries found"
        e destroy


        #
        # Add a telephone number to some entries
        # Note this modification cannot be done in the "traverse" operation.

        #

        set lent [l search "ou=people,o=mycomp" "(sn=Joe*)" {}]
        ::ldapx::entry create c
        foreach e $lent {
    	$e backup
    	$e add1 "telephoneNumber" "+31415926535"
    	c diff $e
    	if {! [l commit c]} then {
    	    puts stderr "error: [l error]"
    	    exit 1

    	}
    	$e destroy

        }
        c destroy

        l disconnect
        l destroy

# <a name='section5'></a>LDIF CLASS

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
    This method writes the entry given in the argument *entry* to the LDIF
    file\.

## <a name='subsection14'></a>Ldif Example

        package require ldapx

        \# This examples reads a LDIF file containing entries,
        \# compare them to a LDAP directory, and writes on standard
        \# output an LDIF file containing changes to apply to the
        \# LDAP directory to match exactly the LDIF file\.

        ::ldapx::ldif create liin
        liin channel stdin

        ::ldapx::ldif create liout
        liout channel stdout

        ::ldapx::ldap create la
        if \{\! \[la connect "ldap://server\.mycomp\.com"\]\} then \{
    	puts stderr "error: \[la error\]"
    	exit 1
        \}

        la configure \-scope one

        \# Reads LDIF file

        ::ldapx::entry create e1
        ::ldapx::entry create e2
        ::ldapx::entry create c

        while \{\[liin read e1\] \!= 0\} \{
    	set base \[e1 superior\]
    	set id \[e1 rdn\]
    	if \{\[la read $base "\($id\)" e2\] == 0\} then \{
    	    e2 reset
    	\}


    	c diff e1 e2
    	if \{\[llength \[c change\]\] \!= 0\} then \{
    	    liout write c
    	\}
        \}



        la disconnect
        la destroy
        e1 destroy
        e2 destroy
        c destroy
        liout destroy







|
|
|
|








|
|

<
>
|

|





|
|
|
|

<
|
>

|

<
<
>
>







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
    This method writes the entry given in the argument *entry* to the LDIF
    file\.

## <a name='subsection14'></a>Ldif Example

        package require ldapx

        # This examples reads a LDIF file containing entries,
        # compare them to a LDAP directory, and writes on standard
        # output an LDIF file containing changes to apply to the
        # LDAP directory to match exactly the LDIF file.

        ::ldapx::ldif create liin
        liin channel stdin

        ::ldapx::ldif create liout
        liout channel stdout

        ::ldapx::ldap create la
        if {! [la connect "ldap://server.mycomp.com"]} then {
    	puts stderr "error: [la error]"
    	exit 1

        }
        la configure -scope one

        # Reads LDIF file

        ::ldapx::entry create e1
        ::ldapx::entry create e2
        ::ldapx::entry create c

        while {[liin read e1] != 0} {
    	set base [e1 superior]
    	set id [e1 rdn]
    	if {[la read $base "($id)" e2] == 0} then {
    	    e2 reset

    	}

    	c diff e1 e2
    	if {[llength [c change]] != 0} then {
    	    liout write c


    	}
        }

        la disconnect
        la destroy
        e1 destroy
        e2 destroy
        c destroy
        liout destroy
Changes to embedded/md/tcllib/files/modules/log/log.md.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
a *level* determining the importance of the message\. The user can then select
which levels to log, what commands to use for the logging of each level and the
channel to write the message to\. In the following example the logging of all
message with level __debug__ is deactivated\.

    package require log
    log::lvSuppress debug
    log::log debug "Unseen message" ; \# No output

By default all messages associated with an error\-level \(__emergency__,
__alert__, __critical__, and __error__\) are written to
__stderr__\. Messages with any other level are written to __stdout__\. In
the following example the log module is reconfigured to write __debug__
messages to __stderr__ too\.








|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
a *level* determining the importance of the message\. The user can then select
which levels to log, what commands to use for the logging of each level and the
channel to write the message to\. In the following example the logging of all
message with level __debug__ is deactivated\.

    package require log
    log::lvSuppress debug
    log::log debug "Unseen message" ; # No output

By default all messages associated with an error\-level \(__emergency__,
__alert__, __critical__, and __error__\) are written to
__stderr__\. Messages with any other level are written to __stdout__\. In
the following example the log module is reconfigured to write __debug__
messages to __stderr__ too\.

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
log any message\. In the following example all messages of level __notice__
are given to the non\-standard command __toText__ for logging\. This disables
the channel setting for such messages, assuming that __toText__ does not use
it by itself\.

    package require log
    log::lvCmd notice toText
    log::log notice "Handled by \\"toText\\""

Another database maintained by this facility is a map from message levels to
colors\. The information in this database has *no* influence on the behaviour
of the module\. It is merely provided as a convenience and in anticipation of the
usage of this facility in __tk__\-based application which may want to
colorize message logs\.








|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
log any message\. In the following example all messages of level __notice__
are given to the non\-standard command __toText__ for logging\. This disables
the channel setting for such messages, assuming that __toText__ does not use
it by itself\.

    package require log
    log::lvCmd notice toText
    log::log notice "Handled by \"toText\""

Another database maintained by this facility is a map from message levels to
colors\. The information in this database has *no* influence on the behaviour
of the module\. It is merely provided as a convenience and in anticipation of the
usage of this facility in __tk__\-based application which may want to
colorize message logs\.

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    Like __::log::log__, but *msg* may contain substitutions and variable
    references, which are evaluated in the caller scope first\. The purpose of
    this command is to avoid overhead in the non\-logging case, if the log
    message building is expensive\. Any substitution errors raise an error in the
    command execution\. The following example shows an xml text representation,
    which is only generated in debug mode:

    log::logsubst debug \{XML of node $node is '\[$node toXml\]'\}

  - <a name='21'></a>__::log::logMsg__ *text*

    Convenience wrapper around __::log::log__\. Equivalent to __::log::log
    info text__\.

  - <a name='22'></a>__::log::logError__ *text*







|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    Like __::log::log__, but *msg* may contain substitutions and variable
    references, which are evaluated in the caller scope first\. The purpose of
    this command is to avoid overhead in the non\-logging case, if the log
    message building is expensive\. Any substitution errors raise an error in the
    command execution\. The following example shows an xml text representation,
    which is only generated in debug mode:

    log::logsubst debug {XML of node $node is '[$node toXml]'}

  - <a name='21'></a>__::log::logMsg__ *text*

    Convenience wrapper around __::log::log__\. Equivalent to __::log::log
    info text__\.

  - <a name='22'></a>__::log::logError__ *text*
Changes to embedded/md/tcllib/files/modules/log/logger.md.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

The __logger__ package provides a flexible system for logging messages from
different services, at priority levels, with different commands\.

To begin using the logger package, we do the following:

    package require logger
    set log \[logger::init myservice\]
    $\{log\}::notice "Initialized myservice logging"

    \.\.\. code \.\.\.

    $\{log\}::notice "Ending myservice logging"
    $\{log\}::delete

In the above code, after the package is loaded, the following things happen:

  - <a name='1'></a>__logger::init__ *service*

    Initializes the service *service* for logging\. The service names are
    actually Tcl namespace names, so they are separated with '::'\. The service







|
|

|

|
|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

The __logger__ package provides a flexible system for logging messages from
different services, at priority levels, with different commands\.

To begin using the logger package, we do the following:

    package require logger
    set log [logger::init myservice]
    ${log}::notice "Initialized myservice logging"

    ... code ...

    ${log}::notice "Ending myservice logging"
    ${log}::delete

In the above code, after the package is loaded, the following things happen:

  - <a name='1'></a>__logger::init__ *service*

    Initializes the service *service* for logging\. The service names are
    actually Tcl namespace names, so they are separated with '::'\. The service
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
    Set the script to call when the log instance in question changes its log
    level\. If called without a command it returns the currently registered
    command\. The command gets two arguments appended, the old and the new
    loglevel\. The callback is invoked after all changes have been done\. If child
    loggers are affected, their callbacks are called before their parents
    callback\.

    proc lvlcallback \{old new\} \{
        puts "Loglevel changed from $old to $new"
    \}

    $\{log\}::lvlchangeproc lvlcallback

  - <a name='23'></a>__$\{log\}::logproc__ *level*

  - <a name='24'></a>__$\{log\}::logproc__ *level* *command*

  - <a name='25'></a>__$\{log\}::logproc__ *level* *argname* *body*

    This command comes in three forms \- the third, older one is deprecated and
    may be removed from future versions of the logger package\. The current set
    version takes one argument, a command to be executed when the level is
    called\. The callback command takes on argument, the text to be logged\. If
    called only with a valid level __logproc__ returns the name of the
    command currently registered as callback command\. __logproc__ specifies
    which command will perform the actual logging for a given level\. The logger
    package ships with default commands for all log levels, but with
    __logproc__ it is possible to replace them with custom code\. This would
    let you send your logs over the network, to a database, or anything else\.
    For example:

    proc logtoserver \{txt\} \{
        variable socket
        puts $socket "Notice: $txt"
    \}


    $\{log\}::logproc notice logtoserver

    Trace logs are slightly different: instead of a plain text argument, the
    argument provided to the logproc is a dictionary consisting of the
    __enter__ or __leave__ keyword along with another dictionary of
    details about the trace\. These include:

      * __proc__ \- Name of the procedure being traced\.







|

<
>
|



















|


<
|
>
|







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
    Set the script to call when the log instance in question changes its log
    level\. If called without a command it returns the currently registered
    command\. The command gets two arguments appended, the old and the new
    loglevel\. The callback is invoked after all changes have been done\. If child
    loggers are affected, their callbacks are called before their parents
    callback\.

    proc lvlcallback {old new} {
        puts "Loglevel changed from $old to $new"

    }
    ${log}::lvlchangeproc lvlcallback

  - <a name='23'></a>__$\{log\}::logproc__ *level*

  - <a name='24'></a>__$\{log\}::logproc__ *level* *command*

  - <a name='25'></a>__$\{log\}::logproc__ *level* *argname* *body*

    This command comes in three forms \- the third, older one is deprecated and
    may be removed from future versions of the logger package\. The current set
    version takes one argument, a command to be executed when the level is
    called\. The callback command takes on argument, the text to be logged\. If
    called only with a valid level __logproc__ returns the name of the
    command currently registered as callback command\. __logproc__ specifies
    which command will perform the actual logging for a given level\. The logger
    package ships with default commands for all log levels, but with
    __logproc__ it is possible to replace them with custom code\. This would
    let you send your logs over the network, to a database, or anything else\.
    For example:

    proc logtoserver {txt} {
        variable socket
        puts $socket "Notice: $txt"

    }

    ${log}::logproc notice logtoserver

    Trace logs are slightly different: instead of a plain text argument, the
    argument provided to the logproc is a dictionary consisting of the
    __enter__ or __leave__ keyword along with another dictionary of
    details about the trace\. These include:

      * __proc__ \- Name of the procedure being traced\.
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

  - <a name='30'></a>__$\{log\}::delproc__

    Set the script to call when the log instance in question is deleted\. If
    called without a command it returns the currently registered command\. For
    example:

    $\{log\}::delproc \[list closesock $logsock\]

  - <a name='31'></a>__$\{log\}::delete__

    This command deletes a particular logging service, and its children\. You
    must call this to clean up the resources used by a service\.

  - <a name='32'></a>__$\{log\}::trace__ *command*

    This command controls logging of enter/leave traces for specified
    procedures\. It is used to enable and disable tracing, query tracing status,
    and specify procedures are to be traced\. Trace handlers are unregistered
    when tracing is disabled\. As a result, there is not performance impact to a
    library when tracing is disabled, just as with other log level commands\.

      proc tracecmd \{ dict \} \{
          puts $dict
      \}


      set log \[::logger::init example\]
      $\{log\}::logproc trace tracecmd

      proc foo \{ args \} \{
          puts "In foo"
          bar 1
          return "foo\_result"
      \}


      proc bar \{ x \} \{
          puts "In bar"
          return "bar\_result"
      \}


      $\{log\}::trace add foo bar
      $\{log\}::trace on

      foo

    \# Output:
    enter \{proc ::foo level 1 script \{\} caller \{\} procargs \{args \{\}\}\}
    In foo
    enter \{proc ::bar level 2 script \{\} caller ::foo procargs \{x 1\}\}
    In bar
    leave \{proc ::bar level 2 script \{\} caller ::foo status ok result bar\_result\}
    leave \{proc ::foo level 1 script \{\} caller \{\} status ok result foo\_result\}

  - <a name='33'></a>__$\{log\}::trace__ __on__

    Turns on trace logging for procedures registered through the
    __[trace](\.\./\.\./\.\./\.\./index\.md\#trace)__ __add__ command\. This is
    similar to the __enable__ command for other logging levels, but allows
    trace logging to take place at any level\. The trace logging mechanism takes







|














|

<
|
>
|
|

|


|
<
|
>
|

|
<
|
>
|
|



|
|

|

|
|







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

  - <a name='30'></a>__$\{log\}::delproc__

    Set the script to call when the log instance in question is deleted\. If
    called without a command it returns the currently registered command\. For
    example:

    ${log}::delproc [list closesock $logsock]

  - <a name='31'></a>__$\{log\}::delete__

    This command deletes a particular logging service, and its children\. You
    must call this to clean up the resources used by a service\.

  - <a name='32'></a>__$\{log\}::trace__ *command*

    This command controls logging of enter/leave traces for specified
    procedures\. It is used to enable and disable tracing, query tracing status,
    and specify procedures are to be traced\. Trace handlers are unregistered
    when tracing is disabled\. As a result, there is not performance impact to a
    library when tracing is disabled, just as with other log level commands\.

      proc tracecmd { dict } {
          puts $dict

      }

      set log [::logger::init example]
      ${log}::logproc trace tracecmd

      proc foo { args } {
          puts "In foo"
          bar 1
          return "foo_result"

      }

      proc bar { x } {
          puts "In bar"
          return "bar_result"

      }

      ${log}::trace add foo bar
      ${log}::trace on

      foo

    # Output:
    enter {proc ::foo level 1 script {} caller {} procargs {args {}}}
    In foo
    enter {proc ::bar level 2 script {} caller ::foo procargs {x 1}}
    In bar
    leave {proc ::bar level 2 script {} caller ::foo status ok result bar_result}
    leave {proc ::foo level 1 script {} caller {} status ok result foo_result}

  - <a name='33'></a>__$\{log\}::trace__ __on__

    Turns on trace logging for procedures registered through the
    __[trace](\.\./\.\./\.\./\.\./index\.md\#trace)__ __add__ command\. This is
    similar to the __enable__ command for other logging levels, but allows
    trace logging to take place at any level\. The trace logging mechanism takes
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
# <a name='section3'></a>Logprocs and Callstack

The logger package takes extra care to keep the logproc out of the call stack\.
This enables logprocs to execute code in the callers scope by using uplevel or
linking to local variables by using upvar\. This may fire traces with all usual
side effects\.

    \# Print caller and current vars in the calling proc
    proc log\_local\_var \{txt\} \{
         set caller \[info level \-1\]
         set vars \[uplevel 1 info vars\]
         foreach var \[lsort $vars\] \{
            if \{\[uplevel 1 \[list array exists $var\]\] == 1\} \{
            	lappend val $var <Array>
            \} else \{
            	lappend val $var \[uplevel 1 \[list set $var\]\]
            \}
         \}


         puts "$txt"
         puts "Caller: $caller"
         puts "Variables in callers scope:"
         foreach \{var value\} $val \{
         	puts "$var = $value"
         \}
    \}



    \# install as logproc
    $\{log\}::logproc debug log\_local\_var

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *logger* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|

|
|
<
<
>
>



|

<
<
|
>
>
|
|







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
# <a name='section3'></a>Logprocs and Callstack

The logger package takes extra care to keep the logproc out of the call stack\.
This enables logprocs to execute code in the callers scope by using uplevel or
linking to local variables by using upvar\. This may fire traces with all usual
side effects\.

    # Print caller and current vars in the calling proc
    proc log_local_var {txt} {
         set caller [info level -1]
         set vars [uplevel 1 info vars]
         foreach var [lsort $vars] {
            if {[uplevel 1 [list array exists $var]] == 1} {
            	lappend val $var <Array>
            } else {
            	lappend val $var [uplevel 1 [list set $var]]


            }
         }
         puts "$txt"
         puts "Caller: $caller"
         puts "Variables in callers scope:"
         foreach {var value} $val {
         	puts "$var = $value"


         }
    }

    # install as logproc
    ${log}::logproc debug log_local_var

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *logger* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/log/loggerUtils.md.
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
      * __\-appenderArgs__ appenderArgs

        Additional arguments to apply to the appender\. The argument of the
        option is a list of options and their arguments\.

        For example

            logger::utils::applyAppender \-serviceCmd $log \-appender console \-appenderArgs \{\-conversionPattern \{\\\[%M\\\] \\\[%p\\\] \- %m\}\}

        The usual Tcl quoting rules apply\.

      * __\-levels__ levelList

        The list of levels to apply this appender to\. If not specified all
        levels are assumed\.

    Example of usage:

        % set log \[logger::init testLog\]
        ::logger::tree::testLog
        % logger::utils::applyAppender \-appender console \-serviceCmd $log
        % $\{log\}::error "this is an error"
        \[2005/08/22 10:14:13\] \[testLog\] \[global\] \[error\] this is an error

  - <a name='4'></a>__::logger::utils::autoApplyAppender__ *command* *command\-string* *log* *op* *args*\.\.\.

    This command is designed to be added via __trace leave__ to calls of
    __logger::init__\. It will look at preconfigured state \(via
    __::logger::utils::applyAppender__\) to autocreate appenders for newly
    created logger instances\. It will return its argument *log*\.

    Example of usage:

        logger::utils::applyAppender \-appender console
        set log \[logger::init applyAppender\-3\]
        $\{log\}::error "this is an error"

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *logger* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|










|

|
|
|










|
|
|







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
      * __\-appenderArgs__ appenderArgs

        Additional arguments to apply to the appender\. The argument of the
        option is a list of options and their arguments\.

        For example

            logger::utils::applyAppender -serviceCmd $log -appender console -appenderArgs {-conversionPattern {\[%M\] \[%p\] - %m}}

        The usual Tcl quoting rules apply\.

      * __\-levels__ levelList

        The list of levels to apply this appender to\. If not specified all
        levels are assumed\.

    Example of usage:

        % set log [logger::init testLog]
        ::logger::tree::testLog
        % logger::utils::applyAppender -appender console -serviceCmd $log
        % ${log}::error "this is an error"
        [2005/08/22 10:14:13] [testLog] [global] [error] this is an error

  - <a name='4'></a>__::logger::utils::autoApplyAppender__ *command* *command\-string* *log* *op* *args*\.\.\.

    This command is designed to be added via __trace leave__ to calls of
    __logger::init__\. It will look at preconfigured state \(via
    __::logger::utils::applyAppender__\) to autocreate appenders for newly
    created logger instances\. It will return its argument *log*\.

    Example of usage:

        logger::utils::applyAppender -appender console
        set log [logger::init applyAppender-3]
        ${log}::error "this is an error"

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *logger* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/map/map_slippy.md.
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# <a name='section2'></a>API

  - <a name='1'></a>__::map::slippy__ __length__ *level*

    This method returns the width/height of a slippy\-based map at the specified
    zoom *level*, in pixels\. This is, in essence, the result of

        expr \{ \[tiles $level\] \* \[tile size\] \}

  - <a name='2'></a>__::map::slippy__ __tiles__ *level*

    This method returns the width/height of a slippy\-based map at the specified
    zoom *level*, in *tiles*\.

  - <a name='3'></a>__::map::slippy__ __tile size__







|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# <a name='section2'></a>API

  - <a name='1'></a>__::map::slippy__ __length__ *level*

    This method returns the width/height of a slippy\-based map at the specified
    zoom *level*, in pixels\. This is, in essence, the result of

        expr { [tiles $level] * [tile size] }

  - <a name='2'></a>__::map::slippy__ __tiles__ *level*

    This method returns the width/height of a slippy\-based map at the specified
    zoom *level*, in *tiles*\.

  - <a name='3'></a>__::map::slippy__ __tile size__
Changes to embedded/md/tcllib/files/modules/math/bigfloat.md.
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
    eventually a minus sign, it is considered as an integer\. Subsequently, no
    conversion is done at all\.

    *trailingZeros* \- the number of zeros to append at the end of the
    floating\-point number to get more precision\. It cannot be applied to an
    integer\.

        \# x and y are BigFloats : the first string contained a dot, and the second an e sign
        set x \[fromstr \-1\.000000\]
        set y \[fromstr 2000e30\]
        \# let's see how we get integers
        set t 20000000000000
        \# the old way \(package 1\.2\) is still supported for backwards compatibility :
        set m \[fromstr 10000000000\]
        \# but we do not need fromstr for integers anymore
        set n \-39
        \# t, m and n are integers

    The *number*'s last digit is considered by the procedure to be true at
    \+/\-1, For example, 1\.00 is the interval \[0\.99, 1\.01\], and 0\.43 the interval
    \[0\.42, 0\.44\]\. The Pi constant may be approximated by the number "3\.1415"\.
    This string could be considered as the interval \[3\.1414 , 3\.1416\] by
    __fromstr__\. So, when you mean 1\.0 as a double, you may have to write
    1\.000000 to get enough precision\. To learn more about this subject, see
    [PRECISION](#section7)\.

    For example :

        set x \[fromstr 1\.0000000000\]
        \# the next line does the same, but smarter
        set y \[fromstr 1\. 10\]

  - <a name='2'></a>__tostr__ ?__\-nosci__? *number*

    Returns a string form of a BigFloat, in which all digits are exacts\. *All
    exact digits* means a rounding may occur, for example to zero, if the
    uncertainty interval does not clearly show the true digits\. *number* may
    be an integer, causing the command to return exactly the input argument\.
    With the __\-nosci__ option, the number returned is never shown in
    scientific notation, i\.e\. not like '3\.4523e\+5' but like '345230\.'\.

        puts \[tostr \[fromstr 0\.99999\]\] ;\# 1\.0000
        puts \[tostr \[fromstr 1\.00001\]\] ;\# 1\.0000
        puts \[tostr \[fromstr 0\.002\]\] ;\# 0\.e\-2

    See [PRECISION](#section7) for that matter\. See also __iszero__ for
    how to detect zeros, which is useful when performing a division\.

  - <a name='3'></a>__fromdouble__ *double* ?*decimals*?

    Converts a double \(a simple floating\-point value\) to a BigFloat, with
    exactly *decimals* digits\. Without the *decimals* argument, it behaves
    like __fromstr__\. Here, the only important feature you might care of is
    the ability to create BigFloats with a fixed number of *decimals*\.

        tostr \[fromstr 1\.111 4\]
        \# returns : 1\.111000 \(3 zeros\)
        tostr \[fromdouble 1\.111 4\]
        \# returns : 1\.111

  - <a name='4'></a>__todouble__ *number*

    Returns a double, that may be used in *expr*, from a BigFloat\.

  - <a name='5'></a>__isInt__ *number*

    Returns 1 if *number* is an integer, 0 otherwise\.

  - <a name='6'></a>__isFloat__ *number*

    Returns 1 if *number* is a BigFloat, 0 otherwise\.

  - <a name='7'></a>__int2float__ *integer* ?*decimals*?

    Converts an integer to a BigFloat with *decimals* trailing zeros\. The
    default, and minimal, number of *decimals* is 1\. When converting back to
    string, one decimal is lost:

        set n 10
        set x \[int2float $n\]; \# like fromstr 10\.0
        puts \[tostr $x\]; \# prints "10\."
        set x \[int2float $n 3\]; \# like fromstr 10\.000
        puts \[tostr $x\]; \# prints "10\.00"

# <a name='section3'></a>ARITHMETICS

  - <a name='8'></a>__add__ *x* *y*

  - <a name='9'></a>__sub__ *x* *y*








|
|
|
|

|
|
|
|
|











|
|
|










|
|
|











|
|
|
|




















|
|
|
|







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
    eventually a minus sign, it is considered as an integer\. Subsequently, no
    conversion is done at all\.

    *trailingZeros* \- the number of zeros to append at the end of the
    floating\-point number to get more precision\. It cannot be applied to an
    integer\.

        # x and y are BigFloats : the first string contained a dot, and the second an e sign
        set x [fromstr -1.000000]
        set y [fromstr 2000e30]
        # let's see how we get integers
        set t 20000000000000
        # the old way (package 1.2) is still supported for backwards compatibility :
        set m [fromstr 10000000000]
        # but we do not need fromstr for integers anymore
        set n -39
        # t, m and n are integers

    The *number*'s last digit is considered by the procedure to be true at
    \+/\-1, For example, 1\.00 is the interval \[0\.99, 1\.01\], and 0\.43 the interval
    \[0\.42, 0\.44\]\. The Pi constant may be approximated by the number "3\.1415"\.
    This string could be considered as the interval \[3\.1414 , 3\.1416\] by
    __fromstr__\. So, when you mean 1\.0 as a double, you may have to write
    1\.000000 to get enough precision\. To learn more about this subject, see
    [PRECISION](#section7)\.

    For example :

        set x [fromstr 1.0000000000]
        # the next line does the same, but smarter
        set y [fromstr 1. 10]

  - <a name='2'></a>__tostr__ ?__\-nosci__? *number*

    Returns a string form of a BigFloat, in which all digits are exacts\. *All
    exact digits* means a rounding may occur, for example to zero, if the
    uncertainty interval does not clearly show the true digits\. *number* may
    be an integer, causing the command to return exactly the input argument\.
    With the __\-nosci__ option, the number returned is never shown in
    scientific notation, i\.e\. not like '3\.4523e\+5' but like '345230\.'\.

        puts [tostr [fromstr 0.99999]] ;# 1.0000
        puts [tostr [fromstr 1.00001]] ;# 1.0000
        puts [tostr [fromstr 0.002]] ;# 0.e-2

    See [PRECISION](#section7) for that matter\. See also __iszero__ for
    how to detect zeros, which is useful when performing a division\.

  - <a name='3'></a>__fromdouble__ *double* ?*decimals*?

    Converts a double \(a simple floating\-point value\) to a BigFloat, with
    exactly *decimals* digits\. Without the *decimals* argument, it behaves
    like __fromstr__\. Here, the only important feature you might care of is
    the ability to create BigFloats with a fixed number of *decimals*\.

        tostr [fromstr 1.111 4]
        # returns : 1.111000 (3 zeros)
        tostr [fromdouble 1.111 4]
        # returns : 1.111

  - <a name='4'></a>__todouble__ *number*

    Returns a double, that may be used in *expr*, from a BigFloat\.

  - <a name='5'></a>__isInt__ *number*

    Returns 1 if *number* is an integer, 0 otherwise\.

  - <a name='6'></a>__isFloat__ *number*

    Returns 1 if *number* is a BigFloat, 0 otherwise\.

  - <a name='7'></a>__int2float__ *integer* ?*decimals*?

    Converts an integer to a BigFloat with *decimals* trailing zeros\. The
    default, and minimal, number of *decimals* is 1\. When converting back to
    string, one decimal is lost:

        set n 10
        set x [int2float $n]; # like fromstr 10.0
        puts [tostr $x]; # prints "10."
        set x [int2float $n 3]; # like fromstr 10.000
        puts [tostr $x]; # prints "10.00"

# <a name='section3'></a>ARITHMETICS

  - <a name='8'></a>__add__ *x* *y*

  - <a name='9'></a>__sub__ *x* *y*

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

      * a BigFloat close enough to zero to raise "divide by zero"\.

      * the integer 0\.

    See here how numbers that are close to zero are converted to strings:

        tostr \[fromstr 0\.001\] ; \# \-> 0\.e\-2
        tostr \[fromstr 0\.000000\] ; \# \-> 0\.e\-5
        tostr \[fromstr \-0\.000001\] ; \# \-> 0\.e\-5
        tostr \[fromstr 0\.0\] ; \# \-> 0\.
        tostr \[fromstr 0\.002\] ; \# \-> 0\.e\-2

        set a \[fromstr 0\.002\] ; \# uncertainty interval : 0\.001, 0\.003
        tostr  $a ; \# 0\.e\-2
        iszero $a ; \# false

        set a \[fromstr 0\.001\] ; \# uncertainty interval : 0\.000, 0\.002
        tostr  $a ; \# 0\.e\-2
        iszero $a ; \# true

  - <a name='17'></a>__[equal](\.\./\.\./\.\./\.\./index\.md\#equal)__ *x* *y*

    Returns 1 if *x* and *y* are equal, 0 elsewhere\.

  - <a name='18'></a>__compare__ *x* *y*








|
|
|
|
|

|
|
|

|
|
|







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

      * a BigFloat close enough to zero to raise "divide by zero"\.

      * the integer 0\.

    See here how numbers that are close to zero are converted to strings:

        tostr [fromstr 0.001] ; # -> 0.e-2
        tostr [fromstr 0.000000] ; # -> 0.e-5
        tostr [fromstr -0.000001] ; # -> 0.e-5
        tostr [fromstr 0.0] ; # -> 0.
        tostr [fromstr 0.002] ; # -> 0.e-2

        set a [fromstr 0.002] ; # uncertainty interval : 0.001, 0.003
        tostr  $a ; # 0.e-2
        iszero $a ; # false

        set a [fromstr 0.001] ; # uncertainty interval : 0.000, 0.002
        tostr  $a ; # 0.e-2
        iszero $a ; # true

  - <a name='17'></a>__[equal](\.\./\.\./\.\./\.\./index\.md\#equal)__ *x* *y*

    Returns 1 if *x* and *y* are equal, 0 elsewhere\.

  - <a name='18'></a>__compare__ *x* *y*

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
internals of this library, the uncertainty interval may be slightly wider than
expected, but this should not cause false digits\.

Now you may ask this question : What precision am I going to get after calling
add, sub, mul or div? First you set a number from the string representation and,
by the way, its uncertainty is set:

    set a \[fromstr 1\.230\]
    \# $a belongs to \[1\.229, 1\.231\]
    set a \[fromstr 1\.000\]
    \# $a belongs to \[0\.999, 1\.001\]
    \# $a has a relative uncertainty of 0\.1% : 0\.001\(the uncertainty\)/1\.000\(the medium value\)

The uncertainty of the sum, or the difference, of two numbers, is the sum of
their respective uncertainties\.

    set a \[fromstr 1\.230\]
    set b \[fromstr 2\.340\]
    set sum \[add $a $b\]\]
    \# the result is : \[3\.568, 3\.572\] \(the last digit is known with an uncertainty of 2\)
    tostr $sum ; \# 3\.57

But when, for example, we add or substract an integer to a BigFloat, the
relative uncertainty of the result is unchanged\. So it is desirable not to
convert integers to BigFloats:

    set a \[fromstr 0\.999999999\]
    \# now something dangerous
    set b \[fromstr 2\.000\]
    \# the result has only 3 digits
    tostr \[add $a $b\]

    \# how to keep precision at its maximum
    puts \[tostr \[add $a 2\]\]

For multiplication and division, the relative uncertainties of the product or
the quotient, is the sum of the relative uncertainties of the operands\. Take
care of division by zero : check each divider with __iszero__\.

    set num \[fromstr 4\.00\]
    set denom \[fromstr 0\.01\]

    puts \[iszero $denom\];\# true
    set quotient \[div $num $denom\];\# error : divide by zero

    \# opposites of our operands
    puts \[compare $num \[opp $num\]\]; \# 1
    puts \[compare $denom \[opp $denom\]\]; \# 0 \!\!\!
    \# No suprise \! 0 and its opposite are the same\.\.\.

Effects of the precision of a number considered equal to zero to the cos
function:

    puts \[tostr \[cos \[fromstr 0\. 10\]\]\]; \# \-> 1\.000000000
    puts \[tostr \[cos \[fromstr 0\. 5\]\]\]; \# \-> 1\.0000
    puts \[tostr \[cos \[fromstr 0e\-10\]\]\]; \# \-> 1\.000000000
    puts \[tostr \[cos \[fromstr 1e\-10\]\]\]; \# \-> 1\.000000000

BigFloats with different internal representations may be converted to the same
string\.

For most analysis functions \(cosine, square root, logarithm, etc\.\), determining
the precision of the result is difficult\. It seems however that in many cases,
the loss of precision in the result is of one or two digits\. There are some
exceptions : for example,

    tostr \[exp \[fromstr 100\.0 10\]\]
    \# returns : 2\.688117142e\+43 which has only 10 digits of precision, although the entry
    \# has 14 digits of precision\.

# <a name='section8'></a>WHAT ABOUT TCL 8\.4 ?

If your setup do not provide Tcl 8\.5 but supports 8\.4, the package can still be
loaded, switching back to *math::bigfloat* 1\.2\. Indeed, an important function
introduced in Tcl 8\.5 is required \- the ability to handle bignums, that we can
do with __expr__\. Before 8\.5, this ability was provided by several packages,
including the pure\-Tcl *math::bignum* package provided by *tcllib*\. In this
case, all you need to know, is that arguments to the commands explained here,
are expected to be in their internal representation\. So even with integers, you
will need to call __fromstr__ and __tostr__ in order to convert them
between string and internal representations\.

    \#

    \# with Tcl 8\.5
    \# ============
    set a \[pi 20\]
    \# round returns an integer and 'everything is a string' applies to integers
    \# whatever big they are
    puts \[round \[mul $a 10000000000\]\]
    \#

    \# the same with Tcl 8\.4
    \# =====================
    set a \[pi 20\]
    \# bignums \(arbitrary length integers\) need a conversion hook
    set b \[fromstr 10000000000\]
    \# round returns a bignum:
    \# before printing it, we need to convert it with 'tostr'
    puts \[tostr \[round \[mul $a $b\]\]\]

# <a name='section9'></a>NAMESPACES AND OTHER PACKAGES

We have not yet discussed about namespaces because we assumed that you had
imported public commands into the global namespace, like this:

    namespace import ::math::bigfloat::\*

If you matter much about avoiding names conflicts, I considere it should be
resolved by the following :

    package require math::bigfloat
    \# beware: namespace ensembles are not available in Tcl 8\.4
    namespace eval ::math::bigfloat \{namespace ensemble create \-command ::bigfloat\}
    \# from now, the bigfloat command takes as subcommands all original math::bigfloat::\* commands
    set a \[bigfloat sub \[bigfloat fromstr 2\.000\] \[bigfloat fromstr 0\.530\]\]
    puts \[bigfloat tostr $a\]

# <a name='section10'></a>EXAMPLES

Guess what happens when you are doing some astronomy\. Here is an example :

    \# convert acurrate angles with a millisecond\-rated accuracy
    proc degree\-angle \{degrees minutes seconds milliseconds\} \{
        set result 0
        set div 1
        foreach factor \{1 1000 60 60\} var \[list $milliseconds $seconds $minutes $degrees\] \{
            \# we convert each entry var into milliseconds
            set div \[expr \{$div\*$factor\}\]
            incr result \[expr \{$var\*$div\}\]
        \}

        return \[div \[int2float $result\] $div\]
    \}

    \# load the package
    package require math::bigfloat
    namespace import ::math::bigfloat::\*
    \# work with angles : a standard formula for navigation \(taking bearings\)
    set angle1 \[deg2rad \[degree\-angle 20 30 40   0\]\]
    set angle2 \[deg2rad \[degree\-angle 21  0 50 500\]\]
    set opposite3 \[deg2rad \[degree\-angle 51  0 50 500\]\]
    set sinProduct \[mul \[sin $angle1\] \[sin $angle2\]\]
    set cosProduct \[mul \[cos $angle1\] \[cos $angle2\]\]
    set angle3 \[asin \[add \[mul $sinProduct \[cos $opposite3\]\] $cosProduct\]\]
    puts "angle3 : \[tostr \[rad2deg $angle3\]\]"

# <a name='section11'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: bignum :: float*
of the [Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also
report any ideas for enhancements you may have for either package and/or







|
|
|
|
|




|
|
|
|
|





|
|
|
|
|

|
|





|
|

|
|

|
|
|
|




|
|
|
|









|
|
|













<
>
|
|
|
|
|
|
<
>
|
|
|
|
|
|
|
|






|





|
|
|
|
|





|
|


|
|
|
|
<
>
|
<
>
|

|
|
|
|
|
|
|
|
|







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
internals of this library, the uncertainty interval may be slightly wider than
expected, but this should not cause false digits\.

Now you may ask this question : What precision am I going to get after calling
add, sub, mul or div? First you set a number from the string representation and,
by the way, its uncertainty is set:

    set a [fromstr 1.230]
    # $a belongs to [1.229, 1.231]
    set a [fromstr 1.000]
    # $a belongs to [0.999, 1.001]
    # $a has a relative uncertainty of 0.1% : 0.001(the uncertainty)/1.000(the medium value)

The uncertainty of the sum, or the difference, of two numbers, is the sum of
their respective uncertainties\.

    set a [fromstr 1.230]
    set b [fromstr 2.340]
    set sum [add $a $b]]
    # the result is : [3.568, 3.572] (the last digit is known with an uncertainty of 2)
    tostr $sum ; # 3.57

But when, for example, we add or substract an integer to a BigFloat, the
relative uncertainty of the result is unchanged\. So it is desirable not to
convert integers to BigFloats:

    set a [fromstr 0.999999999]
    # now something dangerous
    set b [fromstr 2.000]
    # the result has only 3 digits
    tostr [add $a $b]

    # how to keep precision at its maximum
    puts [tostr [add $a 2]]

For multiplication and division, the relative uncertainties of the product or
the quotient, is the sum of the relative uncertainties of the operands\. Take
care of division by zero : check each divider with __iszero__\.

    set num [fromstr 4.00]
    set denom [fromstr 0.01]

    puts [iszero $denom];# true
    set quotient [div $num $denom];# error : divide by zero

    # opposites of our operands
    puts [compare $num [opp $num]]; # 1
    puts [compare $denom [opp $denom]]; # 0 !!!
    # No suprise ! 0 and its opposite are the same...

Effects of the precision of a number considered equal to zero to the cos
function:

    puts [tostr [cos [fromstr 0. 10]]]; # -> 1.000000000
    puts [tostr [cos [fromstr 0. 5]]]; # -> 1.0000
    puts [tostr [cos [fromstr 0e-10]]]; # -> 1.000000000
    puts [tostr [cos [fromstr 1e-10]]]; # -> 1.000000000

BigFloats with different internal representations may be converted to the same
string\.

For most analysis functions \(cosine, square root, logarithm, etc\.\), determining
the precision of the result is difficult\. It seems however that in many cases,
the loss of precision in the result is of one or two digits\. There are some
exceptions : for example,

    tostr [exp [fromstr 100.0 10]]
    # returns : 2.688117142e+43 which has only 10 digits of precision, although the entry
    # has 14 digits of precision.

# <a name='section8'></a>WHAT ABOUT TCL 8\.4 ?

If your setup do not provide Tcl 8\.5 but supports 8\.4, the package can still be
loaded, switching back to *math::bigfloat* 1\.2\. Indeed, an important function
introduced in Tcl 8\.5 is required \- the ability to handle bignums, that we can
do with __expr__\. Before 8\.5, this ability was provided by several packages,
including the pure\-Tcl *math::bignum* package provided by *tcllib*\. In this
case, all you need to know, is that arguments to the commands explained here,
are expected to be in their internal representation\. So even with integers, you
will need to call __fromstr__ and __tostr__ in order to convert them
between string and internal representations\.


    #
    # with Tcl 8.5
    # ============
    set a [pi 20]
    # round returns an integer and 'everything is a string' applies to integers
    # whatever big they are
    puts [round [mul $a 10000000000]]

    #
    # the same with Tcl 8.4
    # =====================
    set a [pi 20]
    # bignums (arbitrary length integers) need a conversion hook
    set b [fromstr 10000000000]
    # round returns a bignum:
    # before printing it, we need to convert it with 'tostr'
    puts [tostr [round [mul $a $b]]]

# <a name='section9'></a>NAMESPACES AND OTHER PACKAGES

We have not yet discussed about namespaces because we assumed that you had
imported public commands into the global namespace, like this:

    namespace import ::math::bigfloat::*

If you matter much about avoiding names conflicts, I considere it should be
resolved by the following :

    package require math::bigfloat
    # beware: namespace ensembles are not available in Tcl 8.4
    namespace eval ::math::bigfloat {namespace ensemble create -command ::bigfloat}
    # from now, the bigfloat command takes as subcommands all original math::bigfloat::* commands
    set a [bigfloat sub [bigfloat fromstr 2.000] [bigfloat fromstr 0.530]]
    puts [bigfloat tostr $a]

# <a name='section10'></a>EXAMPLES

Guess what happens when you are doing some astronomy\. Here is an example :

    # convert acurrate angles with a millisecond-rated accuracy
    proc degree-angle {degrees minutes seconds milliseconds} {
        set result 0
        set div 1
        foreach factor {1 1000 60 60} var [list $milliseconds $seconds $minutes $degrees] {
            # we convert each entry var into milliseconds
            set div [expr {$div*$factor}]
            incr result [expr {$var*$div}]

        }
        return [div [int2float $result] $div]

    }
    # load the package
    package require math::bigfloat
    namespace import ::math::bigfloat::*
    # work with angles : a standard formula for navigation (taking bearings)
    set angle1 [deg2rad [degree-angle 20 30 40   0]]
    set angle2 [deg2rad [degree-angle 21  0 50 500]]
    set opposite3 [deg2rad [degree-angle 51  0 50 500]]
    set sinProduct [mul [sin $angle1] [sin $angle2]]
    set cosProduct [mul [cos $angle1] [cos $angle2]]
    set angle3 [asin [add [mul $sinProduct [cos $opposite3]] $cosProduct]]
    puts "angle3 : [tostr [rad2deg $angle3]]"

# <a name='section11'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: bignum :: float*
of the [Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also
report any ideas for enhancements you may have for either package and/or
Changes to embedded/md/tcllib/files/modules/math/bignum.md.
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
This section shows some simple example\. This library being just a way to perform
math operations, examples may be the simplest way to learn how to work with it\.
Consult the API section of this man page for information about individual
procedures\.

    package require math::bignum

    \# Multiplication of two bignums
    set a \[::math::bignum::fromstr 88888881111111\]
    set b \[::math::bignum::fromstr 22222220000000\]
    set c \[::math::bignum::mul $a $b\]
    puts \[::math::bignum::tostr $c\] ; \# => will output 1975308271604953086420000000
    set c \[::math::bignum::sqrt $c\]
    puts \[::math::bignum::tostr $c\] ; \# => will output 44444440277777

    \# From/To string conversion in different radix
    set a \[::math::bignum::fromstr 1100010101010111001001111010111 2\]
    puts \[::math::bignum::tostr $a 16\] ; \# => will output 62ab93d7

    \# Factorial example
    proc fact n \{
        \# fromstr is not needed for 0 and 1
        set z 1
        for \{set i 2\} \{$i <= $n\} \{incr i\} \{
            set z \[::math::bignum::mul $z \[::math::bignum::fromstr $i\]\]
        \}

        return $z
    \}


    puts \[::math::bignum::tostr \[fact 100\]\]

# <a name='section3'></a>API

  - <a name='1'></a>__::math::bignum::fromstr__ *string* ?*radix*?

    Convert *string* into a bignum\. If *radix* is omitted or zero, the
    string is interpreted in hex if prefixed with *0x*, in octal if prefixed







|
|
|
|
|
|
|

|
|
|

|
|
|

|
|
<
>

<
|
>
|







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
This section shows some simple example\. This library being just a way to perform
math operations, examples may be the simplest way to learn how to work with it\.
Consult the API section of this man page for information about individual
procedures\.

    package require math::bignum

    # Multiplication of two bignums
    set a [::math::bignum::fromstr 88888881111111]
    set b [::math::bignum::fromstr 22222220000000]
    set c [::math::bignum::mul $a $b]
    puts [::math::bignum::tostr $c] ; # => will output 1975308271604953086420000000
    set c [::math::bignum::sqrt $c]
    puts [::math::bignum::tostr $c] ; # => will output 44444440277777

    # From/To string conversion in different radix
    set a [::math::bignum::fromstr 1100010101010111001001111010111 2]
    puts [::math::bignum::tostr $a 16] ; # => will output 62ab93d7

    # Factorial example
    proc fact n {
        # fromstr is not needed for 0 and 1
        set z 1
        for {set i 2} {$i <= $n} {incr i} {
            set z [::math::bignum::mul $z [::math::bignum::fromstr $i]]

        }
        return $z

    }

    puts [::math::bignum::tostr [fact 100]]

# <a name='section3'></a>API

  - <a name='1'></a>__::math::bignum::fromstr__ *string* ?*radix*?

    Convert *string* into a bignum\. If *radix* is omitted or zero, the
    string is interpreted in hex if prefixed with *0x*, in octal if prefixed
Changes to embedded/md/tcllib/files/modules/math/calculus.md.
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

  - <a name='12'></a>__::math::calculus::boundaryValueSecondOrder__ *coeff\_func* *force\_func* *leftbnd* *rightbnd* *nostep*

    Solve a second order linear differential equation with boundary values at
    two sides\. The equation has to be of the form \(the "conservative" form\):

        d      dy     d
        \-\- A\(x\)\-\-  \+  \-\- B\(x\)y \+ C\(x\)y  =  D\(x\)
        dx     dx     dx

    Ordinarily, such an equation would be written as:

            d2y        dy
        a\(x\)\-\-\-  \+ b\(x\)\-\- \+ c\(x\) y  =  D\(x\)
            dx2        dx

    The first form is easier to discretise \(by integrating over a finite volume\)
    than the second form\. The relation between the two forms is fairly
    straightforward:

        A\(x\)  =  a\(x\)
        B\(x\)  =  b\(x\) \- a'\(x\)
        C\(x\)  =  c\(x\) \- B'\(x\)  =  c\(x\) \- b'\(x\) \+ a''\(x\)

    Because of the differentiation, however, it is much easier to ask the user
    to provide the functions A, B and C directly\.

      * *coeff\_func*

        Procedure returning the three coefficients \(A, B, C\) of the equation,







|





|






|
|
|







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

  - <a name='12'></a>__::math::calculus::boundaryValueSecondOrder__ *coeff\_func* *force\_func* *leftbnd* *rightbnd* *nostep*

    Solve a second order linear differential equation with boundary values at
    two sides\. The equation has to be of the form \(the "conservative" form\):

        d      dy     d
        -- A(x)--  +  -- B(x)y + C(x)y  =  D(x)
        dx     dx     dx

    Ordinarily, such an equation would be written as:

            d2y        dy
        a(x)---  + b(x)-- + c(x) y  =  D(x)
            dx2        dx

    The first form is easier to discretise \(by integrating over a finite volume\)
    than the second form\. The relation between the two forms is fairly
    straightforward:

        A(x)  =  a(x)
        B(x)  =  b(x) - a'(x)
        C(x)  =  c(x) - B'(x)  =  c(x) - b'(x) + a''(x)

    Because of the differentiation, however, it is much easier to ask the user
    to provide the functions A, B and C directly\.

      * *coeff\_func*

        Procedure returning the three coefficients \(A, B, C\) of the equation,
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

        List of values on the righthand\-side

  - <a name='14'></a>__::math::calculus::newtonRaphson__ *func* *deriv* *initval*

    Determine the root of an equation given by

        func\(x\) = 0

    using the method of Newton\-Raphson\. The procedure takes the following
    arguments:

      * *func*

        Procedure that returns the value the function at x







|







318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

        List of values on the righthand\-side

  - <a name='14'></a>__::math::calculus::newtonRaphson__ *func* *deriv* *initval*

    Determine the root of an equation given by

        func(x) = 0

    using the method of Newton\-Raphson\. The procedure takes the following
    arguments:

      * *func*

        Procedure that returns the value the function at x
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

Several of the above procedures take the *names* of procedures as arguments\.
To avoid problems with the *visibility* of these procedures, the
fully\-qualified name of these procedures is determined inside the calculus
routines\. For the user this has only one consequence: the named procedure must
be visible in the calling procedure\. For instance:

    namespace eval ::mySpace \{
       namespace export calcfunc
       proc calcfunc \{ x \} \{ return $x \}
    \}
    \#


    \# Use a fully\-qualified name
    \#

    namespace eval ::myCalc \{
       proc detIntegral \{ begin end \} \{
          return \[integral $begin $end 100 ::mySpace::calcfunc\]
       \}
    \}
    \#



    \# Import the name
    \#

    namespace eval ::myCalc \{
       namespace import ::mySpace::calcfunc
       proc detIntegral \{ begin end \} \{
          return \[integral $begin $end 100 calcfunc\]
       \}
    \}



Enhancements for the second\-order boundary value problem:

  - Other types of boundary conditions \(zero gradient, zero flux\)

  - Other schematisation of the first\-order term \(now central differences are
    used, but upstream differences might be useful too\)\.

# <a name='section3'></a>EXAMPLES

Let us take a few simple examples:

Integrate x over the interval \[0,100\] \(20 steps\):

    proc linear\_func \{ x \} \{ return $x \}
    puts "Integral: \[::math::calculus::integral 0 100 20 linear\_func\]"

For simple functions, the alternative could be:

    puts "Integral: \[::math::calculus::integralExpr 0 100 20 \{$x\}\]"

Do not forget the braces\!

The differential equation for a dampened oscillator:

    x'' \+ rx' \+ wx = 0

can be split into a system of first\-order equations:

    x' = y
    y' = \-ry \- wx

Then this system can be solved with code like this:

    proc dampened\_oscillator \{ t xvec \} \{
       set x  \[lindex $xvec 0\]
       set x1 \[lindex $xvec 1\]
       return \[list $x1 \[expr \{\-$x1\-$x\}\]\]
    \}


    set xvec   \{ 1\.0 0\.0 \}
    set t      0\.0
    set tstep  0\.1
    for \{ set i 0 \} \{ $i < 20 \} \{ incr i \} \{
       set result \[::math::calculus::eulerStep $t $tstep $xvec dampened\_oscillator\]
       puts "Result \($t\): $result"
       set t      \[expr \{$t\+$tstep\}\]
       set xvec   $result
    \}


Suppose we have the boundary value problem:

    Dy'' \+ ky = 0
    x = 0: y = 1
    x = L: y = 0

This boundary value problem could originate from the diffusion of a decaying
substance\.

It can be solved with the following fragment:

    proc coeffs \{ x \} \{ return \[list $::Diff 0\.0 $::decay\] \}
    proc force  \{ x \} \{ return 0\.0 \}

    set Diff   1\.0e\-2
    set decay  0\.0001
    set length 100\.0

    set y \[::math::calculus::boundaryValueSecondOrder \\
       coeffs force \{0\.0 1\.0\} \[list $length 0\.0\] 100\]

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: calculus* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.







|

|
<
<
>
>
|
<
>
|
|
|
<
<
<
>
>
>
|
<
>
|

|
|
<
<
>
>














|
|



|





|




|



|
|
|
|
<
|
>
|
|
|
|
|
|
|

<
>



|








|
|

|
|
|

|
|







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

Several of the above procedures take the *names* of procedures as arguments\.
To avoid problems with the *visibility* of these procedures, the
fully\-qualified name of these procedures is determined inside the calculus
routines\. For the user this has only one consequence: the named procedure must
be visible in the calling procedure\. For instance:

    namespace eval ::mySpace {
       namespace export calcfunc
       proc calcfunc { x } { return $x }


    }
    #
    # Use a fully-qualified name

    #
    namespace eval ::myCalc {
       proc detIntegral { begin end } {
          return [integral $begin $end 100 ::mySpace::calcfunc]



       }
    }
    #
    # Import the name

    #
    namespace eval ::myCalc {
       namespace import ::mySpace::calcfunc
       proc detIntegral { begin end } {
          return [integral $begin $end 100 calcfunc]


       }
    }

Enhancements for the second\-order boundary value problem:

  - Other types of boundary conditions \(zero gradient, zero flux\)

  - Other schematisation of the first\-order term \(now central differences are
    used, but upstream differences might be useful too\)\.

# <a name='section3'></a>EXAMPLES

Let us take a few simple examples:

Integrate x over the interval \[0,100\] \(20 steps\):

    proc linear_func { x } { return $x }
    puts "Integral: [::math::calculus::integral 0 100 20 linear_func]"

For simple functions, the alternative could be:

    puts "Integral: [::math::calculus::integralExpr 0 100 20 {$x}]"

Do not forget the braces\!

The differential equation for a dampened oscillator:

    x'' + rx' + wx = 0

can be split into a system of first\-order equations:

    x' = y
    y' = -ry - wx

Then this system can be solved with code like this:

    proc dampened_oscillator { t xvec } {
       set x  [lindex $xvec 0]
       set x1 [lindex $xvec 1]
       return [list $x1 [expr {-$x1-$x}]]

    }

    set xvec   { 1.0 0.0 }
    set t      0.0
    set tstep  0.1
    for { set i 0 } { $i < 20 } { incr i } {
       set result [::math::calculus::eulerStep $t $tstep $xvec dampened_oscillator]
       puts "Result ($t): $result"
       set t      [expr {$t+$tstep}]
       set xvec   $result

    }

Suppose we have the boundary value problem:

    Dy'' + ky = 0
    x = 0: y = 1
    x = L: y = 0

This boundary value problem could originate from the diffusion of a decaying
substance\.

It can be solved with the following fragment:

    proc coeffs { x } { return [list $::Diff 0.0 $::decay] }
    proc force  { x } { return 0.0 }

    set Diff   1.0e-2
    set decay  0.0001
    set length 100.0

    set y [::math::calculus::boundaryValueSecondOrder \
       coeffs force {0.0 1.0} [list $length 0.0] 100]

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: calculus* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/math/combinatorics.md.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  - <a name='1'></a>__::math::ln\_Gamma__ *z*

    Returns the natural logarithm of the Gamma function for the argument *z*\.

    The Gamma function is defined as the improper integral from zero to positive
    infinity of

        t\*\*\(x\-1\)\*exp\(\-t\) dt

    The approximation used in the Tcl Math Library is from Lanczos, *ISIAM J\.
    Numerical Analysis, series B,* volume 1, p\. 86\. For "__x__ > 1", the
    absolute error of the result is claimed to be smaller than 5\.5\*10\*\*\-10 \-\-
    that is, the resulting value of Gamma when

        exp\( ln\_Gamma\( x\) \)

    is computed is expected to be precise to better than nine significant
    figures\.

  - <a name='2'></a>__::math::factorial__ *x*

    Returns the factorial of the argument *x*\.







|






|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  - <a name='1'></a>__::math::ln\_Gamma__ *z*

    Returns the natural logarithm of the Gamma function for the argument *z*\.

    The Gamma function is defined as the improper integral from zero to positive
    infinity of

        t**(x-1)*exp(-t) dt

    The approximation used in the Tcl Math Library is from Lanczos, *ISIAM J\.
    Numerical Analysis, series B,* volume 1, p\. 86\. For "__x__ > 1", the
    absolute error of the result is claimed to be smaller than 5\.5\*10\*\*\-10 \-\-
    that is, the resulting value of Gamma when

        exp( ln_Gamma( x) )

    is computed is expected to be precise to better than nine significant
    figures\.

  - <a name='2'></a>__::math::factorial__ *x*

    Returns the factorial of the argument *x*\.
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
    It is an error to present *x* <= \-1 or *x* > 170, or a value of *x*
    that is not numeric\.

  - <a name='3'></a>__::math::choose__ *n k*

    Returns the binomial coefficient *C\(n, k\)*

        C\(n,k\) = n\! / k\! \(n\-k\)\!

    If both parameters are integers and the result fits in 32 bits, the result
    is rounded to an integer\.

    Integer results are exact up to at least *n* = 34\. Floating point results
    are precise to better than nine significant figures\.

  - <a name='4'></a>__::math::Beta__ *z w*

    Returns the Beta function of the parameters *z* and *w*\.

        Beta\(z,w\) = Beta\(w,z\) = Gamma\(z\) \* Gamma\(w\) / Gamma\(z\+w\)

    Results are returned as a floating point number precise to better than nine
    significant digits provided that *w* and *z* are both at least 1\.

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and







|











|







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
    It is an error to present *x* <= \-1 or *x* > 170, or a value of *x*
    that is not numeric\.

  - <a name='3'></a>__::math::choose__ *n k*

    Returns the binomial coefficient *C\(n, k\)*

        C(n,k) = n! / k! (n-k)!

    If both parameters are integers and the result fits in 32 bits, the result
    is rounded to an integer\.

    Integer results are exact up to at least *n* = 34\. Floating point results
    are precise to better than nine significant figures\.

  - <a name='4'></a>__::math::Beta__ *z w*

    Returns the Beta function of the parameters *z* and *w*\.

        Beta(z,w) = Beta(w,z) = Gamma(z) * Gamma(w) / Gamma(z+w)

    Results are returned as a floating point number precise to better than nine
    significant digits provided that *w* and *z* are both at least 1\.

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
Changes to embedded/md/tcllib/files/modules/math/constants.md.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  - One for reporting which constants are defined and what values they actually
    have\.

The motivation for this package is that quite often, with \(mathematical\)
computations, you need a good approximation to, say, the ratio of degrees to
radians\. You can, of course, define this like:

    variable radtodeg \[expr \{180\.0/\(4\.0\*atan\(1\.0\)\)\}\]

and use the variable radtodeg whenever you need the conversion\.

This has two drawbacks:

  - You need to remember the proper formula or value and that is error\-prone\.








|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
  - One for reporting which constants are defined and what values they actually
    have\.

The motivation for this package is that quite often, with \(mathematical\)
computations, you need a good approximation to, say, the ratio of degrees to
radians\. You can, of course, define this like:

    variable radtodeg [expr {180.0/(4.0*atan(1.0))}]

and use the variable radtodeg whenever you need the conversion\.

This has two drawbacks:

  - You need to remember the proper formula or value and that is error\-prone\.

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  - basic constants like pi, e, gamma \(Euler's constant\)

  - derived values like ln\(10\) and sqrt\(2\)

  - purely numerical values such as 1/3 that are included for convenience and
    for the fact that certain seemingly trivial computations like:

    set value \[expr \{3\.0\*$onethird\}\]

    give *exactly* the value you expect \(if IEEE arithmetic is available\)\.

The full set of named constants is listed in section
[Constants](#section3)\.

# <a name='section2'></a>PROCEDURES







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  - basic constants like pi, e, gamma \(Euler's constant\)

  - derived values like ln\(10\) and sqrt\(2\)

  - purely numerical values such as 1/3 that are included for convenience and
    for the fact that certain seemingly trivial computations like:

    set value [expr {3.0*$onethird}]

    give *exactly* the value you expect \(if IEEE arithmetic is available\)\.

The full set of named constants is listed in section
[Constants](#section3)\.

# <a name='section2'></a>PROCEDURES
Changes to embedded/md/tcllib/files/modules/math/decimal.md.
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
perform decimal math operations, examples may be the simplest way to learn how
to work with it and to see the difference between using this package and
sticking with expr\. Consult the API section of this man page for information
about individual procedures\.

    package require math::decimal

    \# Various operations on two numbers\.
    \# We first convert them to decimal format\.
    set a \[::math::decimal::fromstr 8\.2\]
    set b \[::math::decimal::fromstr \.2\]

    \# Then we perform our operations\. Here we add
    set c \[::math::decimal::\+ $a $b\]

    \# Finally we convert back to string format for presentation to the user\.
    puts \[::math::decimal::tostr $c\] ; \# => will output 8\.4

    \# Other examples
    \#

    \# Subtraction
    set c \[::math::decimal::\- $a $b\]
    puts \[::math::decimal::tostr $c\] ; \# => will output 8\.0

    \# Why bother using this instead of simply expr?
    puts \[expr \{8\.2 \+ \.2\}\] ; \# => will output 8\.399999999999999
    puts \[expr \{8\.2 \- \.2\}\] ; \# => will output 7\.999999999999999
    \# See http://speleotrove\.com/decimal to learn more about why this happens\.

# <a name='section3'></a>API

  - <a name='1'></a>__::math::decimal::fromstr__ *string*

    Convert *string* into a decimal\.








|
|
|
|

|
|

|
|

|
<
>
|
|
|

|
|
|
|







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
perform decimal math operations, examples may be the simplest way to learn how
to work with it and to see the difference between using this package and
sticking with expr\. Consult the API section of this man page for information
about individual procedures\.

    package require math::decimal

    # Various operations on two numbers.
    # We first convert them to decimal format.
    set a [::math::decimal::fromstr 8.2]
    set b [::math::decimal::fromstr .2]

    # Then we perform our operations. Here we add
    set c [::math::decimal::+ $a $b]

    # Finally we convert back to string format for presentation to the user.
    puts [::math::decimal::tostr $c] ; # => will output 8.4

    # Other examples

    #
    # Subtraction
    set c [::math::decimal::- $a $b]
    puts [::math::decimal::tostr $c] ; # => will output 8.0

    # Why bother using this instead of simply expr?
    puts [expr {8.2 + .2}] ; # => will output 8.399999999999999
    puts [expr {8.2 - .2}] ; # => will output 7.999999999999999
    # See http://speleotrove.com/decimal to learn more about why this happens.

# <a name='section3'></a>API

  - <a name='1'></a>__::math::decimal::fromstr__ *string*

    Convert *string* into a decimal\.

Changes to embedded/md/tcllib/files/modules/math/exact.md.
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

The __math::exact::exactexpr__ command provides a system that performs exact
arithmetic over computable real numbers, representing the numbers as algorithms
for successive approximation\. An example, which implements the high\-school
quadratic formula, is shown below\.

    namespace import math::exact::exactexpr
    proc exactquad \{a b c\} \{
        set d \[\[exactexpr \{sqrt\($b\*$b \- 4\*$a\*$c\)\}\] ref\]
        set r0 \[\[exactexpr \{\(\-$b \- $d\) / \(2 \* $a\)\}\] ref\]
        set r1 \[\[exactexpr \{\(\-$b \+ $d\) / \(2 \* $a\)\}\] ref\]
        $d unref
        return \[list $r0 $r1\]
    \}


    set a \[\[exactexpr 1\] ref\]
    set b \[\[exactexpr 200\] ref\]
    set c \[\[exactexpr \{\(\-3/2\) \* 10\*\*\-12\}\] ref\]
    lassign \[exactquad $a $b $c\] r0 r1
    $a unref; $b unref; $c unref
    puts \[list \[$r0 asFloat 70\] \[$r1 asFloat 110\]\]
    $r0 unref; $r1 unref

The program prints the result:

    \-2\.000000000000000075e2 7\.499999999999999719e\-15

Note that if IEEE\-754 floating point had been used, a catastrophic roundoff
error would yield a smaller root that is a factor of two too high:

    \-200\.0 1\.4210854715202004e\-14

The invocations of __exactexpr__ should be fairly self\-explanatory\. The
other commands of note are __ref__ and __unref__\. It is necessary for
the caller to keep track of references to exact expressions \- to call
__ref__ every time an exact expression is stored in a variable and
__unref__ every time the variable goes out of scope or is overwritten\. The
__asFloat__ method emits decimal digits as long as the requested precision







|
|
|
|

|
<
|
>
|
|
|
|

|




|




|







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

The __math::exact::exactexpr__ command provides a system that performs exact
arithmetic over computable real numbers, representing the numbers as algorithms
for successive approximation\. An example, which implements the high\-school
quadratic formula, is shown below\.

    namespace import math::exact::exactexpr
    proc exactquad {a b c} {
        set d [[exactexpr {sqrt($b*$b - 4*$a*$c)}] ref]
        set r0 [[exactexpr {(-$b - $d) / (2 * $a)}] ref]
        set r1 [[exactexpr {(-$b + $d) / (2 * $a)}] ref]
        $d unref
        return [list $r0 $r1]

    }

    set a [[exactexpr 1] ref]
    set b [[exactexpr 200] ref]
    set c [[exactexpr {(-3/2) * 10**-12}] ref]
    lassign [exactquad $a $b $c] r0 r1
    $a unref; $b unref; $c unref
    puts [list [$r0 asFloat 70] [$r1 asFloat 110]]
    $r0 unref; $r1 unref

The program prints the result:

    -2.000000000000000075e2 7.499999999999999719e-15

Note that if IEEE\-754 floating point had been used, a catastrophic roundoff
error would yield a smaller root that is a factor of two too high:

    -200.0 1.4210854715202004e-14

The invocations of __exactexpr__ should be fairly self\-explanatory\. The
other commands of note are __ref__ and __unref__\. It is necessary for
the caller to keep track of references to exact expressions \- to call
__ref__ every time an exact expression is stored in a variable and
__unref__ every time the variable goes out of scope or is overwritten\. The
__asFloat__ method emits decimal digits as long as the requested precision
Changes to embedded/md/tcllib/files/modules/math/fourier.md.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

If the input length N is a power of two then these procedures will utilize the
O\(N log N\) Fast Fourier Transform algorithm\. If input length is not a power of
two then the DFT will instead be computed using a the naive quadratic algorithm\.

Some examples:

    % dft \{1 2 3 4\}
    \{10 0\.0\} \{\-2\.0 2\.0\} \{\-2 0\.0\} \{\-2\.0 \-2\.0\}
    % inverse\_dft \{\{10 0\.0\} \{\-2\.0 2\.0\} \{\-2 0\.0\} \{\-2\.0 \-2\.0\}\}
    \{1\.0 0\.0\} \{2\.0 0\.0\} \{3\.0 0\.0\} \{4\.0 0\.0\}
    % dft \{1 2 3 4 5\}
    \{15\.0 0\.0\} \{\-2\.5 3\.44095480118\} \{\-2\.5 0\.812299240582\} \{\-2\.5 \-0\.812299240582\} \{\-2\.5 \-3\.44095480118\}
    % inverse\_dft \{\{15\.0 0\.0\} \{\-2\.5 3\.44095480118\} \{\-2\.5 0\.812299240582\} \{\-2\.5 \-0\.812299240582\} \{\-2\.5 \-3\.44095480118\}\}
    \{1\.0 0\.0\} \{2\.0 8\.881784197e\-17\} \{3\.0 4\.4408920985e\-17\} \{4\.0 4\.4408920985e\-17\} \{5\.0 \-8\.881784197e\-17\}

In the last case, the imaginary parts <1e\-16 would have been zero in exact
arithmetic, but aren't here due to rounding errors\.

Internally, the procedures use a flat list format where every even index element
of a list is a real part and every odd index element is an imaginary part\. This
is reflected in the variable names by Re\_ and Im\_ prefixes\.







|
|
|
|
|
|
|
|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

If the input length N is a power of two then these procedures will utilize the
O\(N log N\) Fast Fourier Transform algorithm\. If input length is not a power of
two then the DFT will instead be computed using a the naive quadratic algorithm\.

Some examples:

    % dft {1 2 3 4}
    {10 0.0} {-2.0 2.0} {-2 0.0} {-2.0 -2.0}
    % inverse_dft {{10 0.0} {-2.0 2.0} {-2 0.0} {-2.0 -2.0}}
    {1.0 0.0} {2.0 0.0} {3.0 0.0} {4.0 0.0}
    % dft {1 2 3 4 5}
    {15.0 0.0} {-2.5 3.44095480118} {-2.5 0.812299240582} {-2.5 -0.812299240582} {-2.5 -3.44095480118}
    % inverse_dft {{15.0 0.0} {-2.5 3.44095480118} {-2.5 0.812299240582} {-2.5 -0.812299240582} {-2.5 -3.44095480118}}
    {1.0 0.0} {2.0 8.881784197e-17} {3.0 4.4408920985e-17} {4.0 4.4408920985e-17} {5.0 -8.881784197e-17}

In the last case, the imaginary parts <1e\-16 would have been zero in exact
arithmetic, but aren't here due to rounding errors\.

Internally, the procedures use a flat list format where every even index element
of a list is a real part and every odd index element is an imaginary part\. This
is reflected in the variable names by Re\_ and Im\_ prefixes\.
Changes to embedded/md/tcllib/files/modules/math/fuzzy.md.
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
  - <a name='10'></a>__::math::fuzzy::troundn__ *value* *ndigits*

    Rounds the floating\-point number off to the specified number of decimals
    \(Pro memorie\)\.

Usage:

    if \{ \[teq $x $y\] \} \{ puts "x == y" \}
    if \{ \[tne $x $y\] \} \{ puts "x \!= y" \}
    if \{ \[tge $x $y\] \} \{ puts "x >= y" \}
    if \{ \[tgt $x $y\] \} \{ puts "x > y" \}
    if \{ \[tlt $x $y\] \} \{ puts "x < y" \}
    if \{ \[tle $x $y\] \} \{ puts "x <= y" \}

    set fx      \[tfloor $x\]
    set fc      \[tceil  $x\]
    set rounded \[tround $x\]
    set roundn  \[troundn $x $nodigits\]

# <a name='section3'></a>TEST CASES

The problems that can occur with floating\-point numbers are illustrated by the
test cases in the file "fuzzy\.test":

  - Several test case use the ordinary comparisons, and they fail invariably to







|
|
|
|
|
|

|
|
|
|







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
  - <a name='10'></a>__::math::fuzzy::troundn__ *value* *ndigits*

    Rounds the floating\-point number off to the specified number of decimals
    \(Pro memorie\)\.

Usage:

    if { [teq $x $y] } { puts "x == y" }
    if { [tne $x $y] } { puts "x != y" }
    if { [tge $x $y] } { puts "x >= y" }
    if { [tgt $x $y] } { puts "x > y" }
    if { [tlt $x $y] } { puts "x < y" }
    if { [tle $x $y] } { puts "x <= y" }

    set fx      [tfloor $x]
    set fc      [tceil  $x]
    set rounded [tround $x]
    set roundn  [troundn $x $nodigits]

# <a name='section3'></a>TEST CASES

The problems that can occur with floating\-point numbers are illustrated by the
test cases in the file "fuzzy\.test":

  - Several test case use the ordinary comparisons, and they fail invariably to
Changes to embedded/md/tcllib/files/modules/math/interpolate.md.
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
  - <a name='8'></a>__::math::interpolate::interp\-spatial__ *xyvalues* *coord*

    Use a straightforward interpolation method with weights as function of the
    inverse distance to interpolate in 2D and N\-dimensional space

    The list xyvalues is a list of lists:

            \{   \{x1 y1 z1 \{v11 v12 v13 v14\}\}
        	\{x2 y2 z2 \{v21 v22 v23 v24\}\}
        	\.\.\.
            \}


    The last element of each inner list is either a single number or a list in
    itself\. In the latter case the return value is a list with the same number
    of elements\.

    The method is influenced by the search radius and the power of the inverse
    distance







|
|
|
<
>







208
209
210
211
212
213
214
215
216
217

218
219
220
221
222
223
224
225
  - <a name='8'></a>__::math::interpolate::interp\-spatial__ *xyvalues* *coord*

    Use a straightforward interpolation method with weights as function of the
    inverse distance to interpolate in 2D and N\-dimensional space

    The list xyvalues is a list of lists:

            {   {x1 y1 z1 {v11 v12 v13 v14}}
        	{x2 y2 z2 {v21 v22 v23 v24}}
        	...

            }

    The last element of each inner list is either a single number or a list in
    itself\. In the latter case the return value is a list with the same number
    of elements\.

    The method is influenced by the search radius and the power of the inverse
    distance
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
# <a name='section4'></a>EXAMPLES

*Example of using one\-dimensional tables:*

Suppose you have several tabulated functions of one variable:

      x     y1     y2
    0\.0    0\.0    0\.0
    1\.0    1\.0    1\.0
    2\.0    4\.0    8\.0
    3\.0    9\.0   27\.0
    4\.0   16\.0   64\.0

Then to estimate the values at 0\.5, 1\.5, 2\.5 and 3\.5, you can use:

    set table \[::math::interpolate::defineTable table1  \{x y1 y2\} \{   \-      1      2
                    0\.0    0\.0    0\.0
                    1\.0    1\.0    1\.0
                    2\.0    4\.0    8\.0
                    3\.0    9\.0   27\.0
                    4\.0   16\.0   64\.0\}\]
    foreach x \{0\.5 1\.5 2\.5 3\.5\} \{
        puts "$x: \[::math::interpolate::interp\-1d\-table $table $x\]"
    \}


For one\-dimensional tables the first row is not used\. For two\-dimensional
tables, the first row represents the values for the second independent variable\.

*Example of using the cubic splines:*

Suppose the following values are given:

      x       y
    0\.1     1\.0
    0\.3     2\.1
    0\.4     2\.2
    0\.8     4\.11
    1\.0     4\.12

Then to estimate the values at 0\.1, 0\.2, 0\.3, \.\.\. 1\.0, you can use:

    set coeffs \[::math::interpolate::prepare\-cubic\-splines  \{0\.1 0\.3 0\.4 0\.8  1\.0\}  \{1\.0 2\.1 2\.2 4\.11 4\.12\}\]
    foreach x \{0\.1 0\.2 0\.3 0\.4 0\.5 0\.6 0\.7 0\.8 0\.9 1\.0\} \{
       puts "$x: \[::math::interpolate::interp\-cubic\-splines $coeffs $x\]"
    \}


to get the following output:

    0\.1: 1\.0
    0\.2: 1\.68044117647
    0\.3: 2\.1
    0\.4: 2\.2
    0\.5: 3\.11221507353
    0\.6: 4\.25242647059
    0\.7: 5\.41804227941
    0\.8: 4\.11
    0\.9: 3\.95675857843
    1\.0: 4\.12

As you can see, the values at the abscissae are reproduced perfectly\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: interpolate* of







|
|
|
|
|



|
|
|
|
|
|
|
|
<
>









|
|
|
|
|



|
|
|
<
|
>


|
|
|
|
|
|
|
|
|
|







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
# <a name='section4'></a>EXAMPLES

*Example of using one\-dimensional tables:*

Suppose you have several tabulated functions of one variable:

      x     y1     y2
    0.0    0.0    0.0
    1.0    1.0    1.0
    2.0    4.0    8.0
    3.0    9.0   27.0
    4.0   16.0   64.0

Then to estimate the values at 0\.5, 1\.5, 2\.5 and 3\.5, you can use:

    set table [::math::interpolate::defineTable table1  {x y1 y2} {   -      1      2
                    0.0    0.0    0.0
                    1.0    1.0    1.0
                    2.0    4.0    8.0
                    3.0    9.0   27.0
                    4.0   16.0   64.0}]
    foreach x {0.5 1.5 2.5 3.5} {
        puts "$x: [::math::interpolate::interp-1d-table $table $x]"

    }

For one\-dimensional tables the first row is not used\. For two\-dimensional
tables, the first row represents the values for the second independent variable\.

*Example of using the cubic splines:*

Suppose the following values are given:

      x       y
    0.1     1.0
    0.3     2.1
    0.4     2.2
    0.8     4.11
    1.0     4.12

Then to estimate the values at 0\.1, 0\.2, 0\.3, \.\.\. 1\.0, you can use:

    set coeffs [::math::interpolate::prepare-cubic-splines  {0.1 0.3 0.4 0.8  1.0}  {1.0 2.1 2.2 4.11 4.12}]
    foreach x {0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0} {
       puts "$x: [::math::interpolate::interp-cubic-splines $coeffs $x]"

    }

to get the following output:

    0.1: 1.0
    0.2: 1.68044117647
    0.3: 2.1
    0.4: 2.2
    0.5: 3.11221507353
    0.6: 4.25242647059
    0.7: 5.41804227941
    0.8: 4.11
    0.9: 3.95675857843
    1.0: 4.12

As you can see, the values at the abscissae are reproduced perfectly\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: interpolate* of
Changes to embedded/md/tcllib/files/modules/math/linalg.md.
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  - <a name='59'></a>__::math::linearalgebra::dgetrf__ *matrix*

    Computes an LU factorization of a general matrix, using partial, pivoting
    with row interchanges\. Returns the permutation vector\.

    The factorization has the form

        P \* A = L \* U

    where P is a permutation matrix, L is lower triangular with unit diagonal
    elements, and U is upper triangular\. Returns the permutation vector, as a
    list of length n\-1\. The last entry of the permutation is not stored, since
    it is implicitely known, with value n \(the last row is not swapped with any
    other row\)\. At index \#i of the permutation is stored the index of the row \#j
    which is swapped with row \#i at step \#i\. That means that each index of the







|







995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  - <a name='59'></a>__::math::linearalgebra::dgetrf__ *matrix*

    Computes an LU factorization of a general matrix, using partial, pivoting
    with row interchanges\. Returns the permutation vector\.

    The factorization has the form

        P * A = L * U

    where P is a permutation matrix, L is lower triangular with unit diagonal
    elements, and U is upper triangular\. Returns the permutation vector, as a
    list of length n\-1\. The last entry of the permutation is not stored, since
    it is implicitely known, with value n \(the last row is not swapped with any
    other row\)\. At index \#i of the permutation is stored the index of the row \#j
    which is swapped with row \#i at step \#i\. That means that each index of the
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
    off\-diagonal and the main diagonal\) and n rows\.

  - Element i,j \(i = \-m,\.\.\.,m; j =1,\.\.\.,n\) of "B" corresponds to element k,j of
    "A" where k = M\+i\-1 and M is at least \(\!\) n, the number of rows in "B"\.

  - To set element \(i,j\) of matrix "B" use:

        setelem B $j \[expr \{$N\+$i\-1\}\] $value

\(There is no convenience procedure for this yet\)

# <a name='section4'></a>REMARKS ON THE IMPLEMENTATION

There is a difference between the original LA package by Hume and the current
implementation\. Whereas the LA package uses a linear list, the current package







|







1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
    off\-diagonal and the main diagonal\) and n rows\.

  - Element i,j \(i = \-m,\.\.\.,m; j =1,\.\.\.,n\) of "B" corresponds to element k,j of
    "A" where k = M\+i\-1 and M is at least \(\!\) n, the number of rows in "B"\.

  - To set element \(i,j\) of matrix "B" use:

        setelem B $j [expr {$N+$i-1}] $value

\(There is no convenience procedure for this yet\)

# <a name='section4'></a>REMARKS ON THE IMPLEMENTATION

There is a difference between the original LA package by Hume and the current
implementation\. Whereas the LA package uses a linear list, the current package
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
    namespace import ::math::linearalgebra

results in an error message about "scale"\. This is due to the fact that Tk
defines all its commands in the global namespace\. The solution is to import the
linear algebra commands in a namespace that is not the global one:

    package require math::linearalgebra
    namespace eval compute \{
        namespace import ::math::linearalgebra::\*
        \.\.\. use the linear algebra version of scale \.\.\.
    \}


To use Tk's scale command in that same namespace you can rename it:

    namespace eval compute \{
        rename ::scale scaleTk
        scaleTk \.scale \.\.\.
    \}


# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: linearalgebra* of
the [Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also
report any ideas for enhancements you may have for either package and/or







|
|
|
<
>



|

|
<
>







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
    namespace import ::math::linearalgebra

results in an error message about "scale"\. This is due to the fact that Tk
defines all its commands in the global namespace\. The solution is to import the
linear algebra commands in a namespace that is not the global one:

    package require math::linearalgebra
    namespace eval compute {
        namespace import ::math::linearalgebra::*
        ... use the linear algebra version of scale ...

    }

To use Tk's scale command in that same namespace you can rename it:

    namespace eval compute {
        rename ::scale scaleTk
        scaleTk .scale ...

    }

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: linearalgebra* of
the [Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also
report any ideas for enhancements you may have for either package and/or
Changes to embedded/md/tcllib/files/modules/math/machineparameters.md.
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

# <a name='description'></a>DESCRIPTION

The *math::machineparameters* package is the Tcl equivalent of the DLAMCH
LAPACK function\. In floating point systems, a floating point number is
represented by

    x = \+/\- d1 d2 \.\.\. dt basis^e

where digits satisfy

    0 <= di <= basis \- 1, i = 1, t

with the convention :

  - t is the size of the mantissa

  - basis is the basis \(the "radix"\)

The __compute__ method computes all machine parameters\. Then, the
__get__ method can be used to get each parameter\. The __print__ method
prints a report on standard output\.

# <a name='section2'></a>EXAMPLE

In the following example, one compute the parameters of a desktop under Linux
with the following Tcl 8\.4\.19 properties :

    % parray tcl\_platform
    tcl\_platform\(byteOrder\) = littleEndian
    tcl\_platform\(machine\)   = i686
    tcl\_platform\(os\)        = Linux
    tcl\_platform\(osVersion\) = 2\.6\.24\-19\-generic
    tcl\_platform\(platform\)  = unix
    tcl\_platform\(tip,268\)   = 1
    tcl\_platform\(tip,280\)   = 1
    tcl\_platform\(user\)      = <username>
    tcl\_platform\(wordSize\)  = 4

The following example creates a machineparameters object, computes the
properties and displays it\.

    set pp \[machineparameters create %AUTO%\]
    $pp compute
    $pp print
    $pp destroy

This prints out :

    Machine parameters
    Epsilon : 1\.11022302463e\-16
    Beta : 2
    Rounding : proper
    Mantissa : 53
    Maximum exponent : 1024
    Minimum exponent : \-1021
    Overflow threshold : 8\.98846567431e\+307
    Underflow threshold : 2\.22507385851e\-308

That compares well with the results produced by Lapack 3\.1\.1 :

    Epsilon                      =   1\.11022302462515654E\-016
    Safe minimum                 =   2\.22507385850720138E\-308
    Base                         =    2\.0000000000000000
    Precision                    =   2\.22044604925031308E\-016
    Number of digits in mantissa =    53\.000000000000000
    Rounding mode                =   1\.00000000000000000
    Minimum exponent             =   \-1021\.0000000000000
    Underflow threshold          =   2\.22507385850720138E\-308
    Largest exponent             =    1024\.0000000000000
    Overflow threshold           =   1\.79769313486231571E\+308
    Reciprocal of safe minimum   =   4\.49423283715578977E\+307

The following example creates a machineparameters object, computes the
properties and gets the epsilon for the machine\.

    set pp \[machineparameters create %AUTO%\]
    $pp compute
    set eps \[$pp get \-epsilon\]
    $pp destroy

# <a name='section3'></a>REFERENCES

  - "Algorithms to Reveal Properties of Floating\-Point Arithmetic", Michael A\.
    Malcolm, Stanford University, Communications of the ACM, Volume 15 , Issue
    11 \(November 1972\), Pages: 949 \- 951







|



|
















|
|
|
|
|
|
|
|
|
|




|







|




|
|
|



|
|
|
|
|
|
|
|
|
|
|




|

|







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

# <a name='description'></a>DESCRIPTION

The *math::machineparameters* package is the Tcl equivalent of the DLAMCH
LAPACK function\. In floating point systems, a floating point number is
represented by

    x = +/- d1 d2 ... dt basis^e

where digits satisfy

    0 <= di <= basis - 1, i = 1, t

with the convention :

  - t is the size of the mantissa

  - basis is the basis \(the "radix"\)

The __compute__ method computes all machine parameters\. Then, the
__get__ method can be used to get each parameter\. The __print__ method
prints a report on standard output\.

# <a name='section2'></a>EXAMPLE

In the following example, one compute the parameters of a desktop under Linux
with the following Tcl 8\.4\.19 properties :

    % parray tcl_platform
    tcl_platform(byteOrder) = littleEndian
    tcl_platform(machine)   = i686
    tcl_platform(os)        = Linux
    tcl_platform(osVersion) = 2.6.24-19-generic
    tcl_platform(platform)  = unix
    tcl_platform(tip,268)   = 1
    tcl_platform(tip,280)   = 1
    tcl_platform(user)      = <username>
    tcl_platform(wordSize)  = 4

The following example creates a machineparameters object, computes the
properties and displays it\.

    set pp [machineparameters create %AUTO%]
    $pp compute
    $pp print
    $pp destroy

This prints out :

    Machine parameters
    Epsilon : 1.11022302463e-16
    Beta : 2
    Rounding : proper
    Mantissa : 53
    Maximum exponent : 1024
    Minimum exponent : -1021
    Overflow threshold : 8.98846567431e+307
    Underflow threshold : 2.22507385851e-308

That compares well with the results produced by Lapack 3\.1\.1 :

    Epsilon                      =   1.11022302462515654E-016
    Safe minimum                 =   2.22507385850720138E-308
    Base                         =    2.0000000000000000
    Precision                    =   2.22044604925031308E-016
    Number of digits in mantissa =    53.000000000000000
    Rounding mode                =   1.00000000000000000
    Minimum exponent             =   -1021.0000000000000
    Underflow threshold          =   2.22507385850720138E-308
    Largest exponent             =    1024.0000000000000
    Overflow threshold           =   1.79769313486231571E+308
    Reciprocal of safe minimum   =   4.49423283715578977E+307

The following example creates a machineparameters object, computes the
properties and gets the epsilon for the machine\.

    set pp [machineparameters create %AUTO%]
    $pp compute
    set eps [$pp get -epsilon]
    $pp destroy

# <a name='section3'></a>REFERENCES

  - "Algorithms to Reveal Properties of Floating\-Point Arithmetic", Michael A\.
    Malcolm, Stanford University, Communications of the ACM, Volume 15 , Issue
    11 \(November 1972\), Pages: 949 \- 951
Changes to embedded/md/tcllib/files/modules/math/math_geometry.md.
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    command\.

  - <a name='4'></a>__::math::geometry::distance__ *point1* *point2*

    Compute the distance between the two points and return it as the result of
    the command\. This is in essence the same as

        math::geometry::length \[math::geomtry::\- point1 point2\]

  - <a name='5'></a>__::math::geometry::length__ *point*

    Compute the length of the vector and return it as the result of the command\.

  - <a name='6'></a>__::math::geometry::s\*__ *factor* *point*








|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    command\.

  - <a name='4'></a>__::math::geometry::distance__ *point1* *point2*

    Compute the distance between the two points and return it as the result of
    the command\. This is in essence the same as

        math::geometry::length [math::geomtry::- point1 point2]

  - <a name='5'></a>__::math::geometry::length__ *point*

    Compute the length of the vector and return it as the result of the command\.

  - <a name='6'></a>__::math::geometry::s\*__ *factor* *point*

Changes to embedded/md/tcllib/files/modules/math/optimize.md.
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

Several of the above procedures take the *names* of procedures as arguments\.
To avoid problems with the *visibility* of these procedures, the
fully\-qualified name of these procedures is determined inside the optimize
routines\. For the user this has only one consequence: the named procedure must
be visible in the calling procedure\. For instance:

    namespace eval ::mySpace \{
       namespace export calcfunc
       proc calcfunc \{ x \} \{ return $x \}
    \}
    \#


    \# Use a fully\-qualified name
    \#

    namespace eval ::myCalc \{
       puts \[min\_bound\_1d ::myCalc::calcfunc $begin $end\]
    \}
    \#


    \# Import the name
    \#

    namespace eval ::myCalc \{
       namespace import ::mySpace::calcfunc
       puts \[min\_bound\_1d calcfunc $begin $end\]
    \}


The simple procedures *minimum* and *maximum* have been deprecated: the
alternatives are much more flexible, robust and require less function
evaluations\.

# <a name='section4'></a>EXAMPLES

Let us take a few simple examples:

Determine the maximum of f\(x\) = x^3 exp\(\-3x\), on the interval \(0,10\):

    proc efunc \{ x \} \{ expr \{$x\*$x\*$x \* exp\(\-3\.0\*$x\)\} \}
    puts "Maximum at: \[::math::optimize::max\_bound\_1d efunc 0\.0 10\.0\]"

The maximum allowed error determines the number of steps taken \(with each step
in the iteration the interval is reduced with a factor 1/2\)\. Hence, a maximum
error of 0\.0001 is achieved in approximately 14 steps\.

An example of a *linear program* is:

Optimise the expression 3x\+2y, where:

    x >= 0 and y >= 0 \(implicit constraints, part of the
                      definition of linear programs\)

    x \+ y   <= 1      \(constraints specific to the problem\)
    2x \+ 5y <= 10

This problem can be solved as follows:

    set solution \[::math::optimize::solveLinearProgram  \{ 3\.0   2\.0 \}  \{ \{ 1\.0   1\.0   1\.0 \}
         \{ 2\.0   5\.0  10\.0 \} \} \]

Note, that a constraint like:

    x \+ y >= 1

can be turned into standard form using:

    \-x  \-y <= \-1

The theory of linear programming is the subject of many a text book and the
Simplex algorithm that is implemented here is the best\-known method to solve
this type of problems, but it is not the only one\.

# <a name='section5'></a>Bugs, Ideas, Feedback








|

|
<
<
>
>
|
<
>
|
|
<
<
>
>
|
<
>
|

|
<
>











|
|









|
|

|
|



|
|



|



|







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

Several of the above procedures take the *names* of procedures as arguments\.
To avoid problems with the *visibility* of these procedures, the
fully\-qualified name of these procedures is determined inside the optimize
routines\. For the user this has only one consequence: the named procedure must
be visible in the calling procedure\. For instance:

    namespace eval ::mySpace {
       namespace export calcfunc
       proc calcfunc { x } { return $x }


    }
    #
    # Use a fully-qualified name

    #
    namespace eval ::myCalc {
       puts [min_bound_1d ::myCalc::calcfunc $begin $end]


    }
    #
    # Import the name

    #
    namespace eval ::myCalc {
       namespace import ::mySpace::calcfunc
       puts [min_bound_1d calcfunc $begin $end]

    }

The simple procedures *minimum* and *maximum* have been deprecated: the
alternatives are much more flexible, robust and require less function
evaluations\.

# <a name='section4'></a>EXAMPLES

Let us take a few simple examples:

Determine the maximum of f\(x\) = x^3 exp\(\-3x\), on the interval \(0,10\):

    proc efunc { x } { expr {$x*$x*$x * exp(-3.0*$x)} }
    puts "Maximum at: [::math::optimize::max_bound_1d efunc 0.0 10.0]"

The maximum allowed error determines the number of steps taken \(with each step
in the iteration the interval is reduced with a factor 1/2\)\. Hence, a maximum
error of 0\.0001 is achieved in approximately 14 steps\.

An example of a *linear program* is:

Optimise the expression 3x\+2y, where:

    x >= 0 and y >= 0 (implicit constraints, part of the
                      definition of linear programs)

    x + y   <= 1      (constraints specific to the problem)
    2x + 5y <= 10

This problem can be solved as follows:

    set solution [::math::optimize::solveLinearProgram  { 3.0   2.0 }  { { 1.0   1.0   1.0 }
         { 2.0   5.0  10.0 } } ]

Note, that a constraint like:

    x + y >= 1

can be turned into standard form using:

    -x  -y <= -1

The theory of linear programming is the subject of many a text book and the
Simplex algorithm that is implemented here is the best\-known method to solve
this type of problems, but it is not the only one\.

# <a name='section5'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/math/polynomials.md.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

The package defines the following public procedures:

  - <a name='1'></a>__::math::polynomials::polynomial__ *coeffs*

    Return an \(encoded\) list that defines the polynomial\. A polynomial

        f\(x\) = a \+ b\.x \+ c\.x\*\*2 \+ d\.x\*\*3

    can be defined via:

        set f \[::math::polynomials::polynomial \[list $a $b $c $d\]

      * list *coeffs*

        Coefficients of the polynomial \(in ascending order\)

  - <a name='2'></a>__::math::polynomials::polynCmd__ *coeffs*








|



|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

The package defines the following public procedures:

  - <a name='1'></a>__::math::polynomials::polynomial__ *coeffs*

    Return an \(encoded\) list that defines the polynomial\. A polynomial

        f(x) = a + b.x + c.x**2 + d.x**3

    can be defined via:

        set f [::math::polynomials::polynomial [list $a $b $c $d]

      * list *coeffs*

        Coefficients of the polynomial \(in ascending order\)

  - <a name='2'></a>__::math::polynomials::polynCmd__ *coeffs*

Changes to embedded/md/tcllib/files/modules/math/qcomplex.md.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
valid \(representations of\) "complex numbers", that is, lists of two numbers
defining the real and imaginary part of a complex number \(though this is a mere
detail: rely on the *complex* command to construct a valid number\.\)

Most procedures implement the basic arithmetic operations or elementary
functions whereas several others convert to and from different representations:

    set z \[complex 0 1\]
    puts "z = \[tostring $z\]"
    puts "z\*\*2 = \[\* $z $z\]

would result in:

    z = i
    z\*\*2 = \-1

# <a name='section2'></a>AVAILABLE PROCEDURES

The package implements all or most basic operations and elementary functions\.

*The arithmetic operations are:*








|
|
|




|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
valid \(representations of\) "complex numbers", that is, lists of two numbers
defining the real and imaginary part of a complex number \(though this is a mere
detail: rely on the *complex* command to construct a valid number\.\)

Most procedures implement the basic arithmetic operations or elementary
functions whereas several others convert to and from different representations:

    set z [complex 0 1]
    puts "z = [tostring $z]"
    puts "z**2 = [* $z $z]

would result in:

    z = i
    z**2 = -1

# <a name='section2'></a>AVAILABLE PROCEDURES

The package implements all or most basic operations and elementary functions\.

*The arithmetic operations are:*

Changes to embedded/md/tcllib/files/modules/math/rational_funcs.md.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
The package defines the following public procedures:

  - <a name='1'></a>__::math::rationalfunctions::rationalFunction__ *num* *den*

    Return an \(encoded\) list that defines the rational function\. A rational
    function

                  1 \+ x^3
        f\(x\) = \-\-\-\-\-\-\-\-\-\-\-\-
               1 \+ 2x \+ x^2

    can be defined via:

        set f \[::math::rationalfunctions::rationalFunction \[list 1 0 0 1\]  \[list 1 2 1\]\]

      * list *num*

        Coefficients of the numerator of the rational function \(in ascending
        order\)

      * list *den*







|
|
|



|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
The package defines the following public procedures:

  - <a name='1'></a>__::math::rationalfunctions::rationalFunction__ *num* *den*

    Return an \(encoded\) list that defines the rational function\. A rational
    function

                  1 + x^3
        f(x) = ------------
               1 + 2x + x^2

    can be defined via:

        set f [::math::rationalfunctions::rationalFunction [list 1 0 0 1]  [list 1 2 1]]

      * list *num*

        Coefficients of the numerator of the rational function \(in ascending
        order\)

      * list *den*
Changes to embedded/md/tcllib/files/modules/math/romberg.md.
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
dx/sqrt\(1\-x\*\*2\) maps to du\. Choosing x=sin\(u\), we can find that dx=cos\(u\)\*du,
and sqrt\(1\-x\*\*2\)=cos\(u\)\. The integral from a to b of f\(x\) is the integral from
asin\(a\) to asin\(b\) of f\(sin\(u\)\)\*cos\(u\)\.

We can make a function __g__ that accepts an arbitrary function __f__
and the parameter u, and computes this new integrand\.

    proc g \{ f u \} \{
        set x \[expr \{ sin\($u\) \}\]
        set cmd $f; lappend cmd $x; set y \[eval $cmd\]
        return \[expr \{ $y / cos\($u\) \}\]
    \}


Now integrating __f__ from *a* to *b* is the same as integrating
__g__ from *asin\(a\)* to *asin\(b\)*\. It's a little tricky to get __f__
consistently evaluated in the caller's scope; the following procedure does it\.

    proc romberg\_sine \{ f a b args \} \{
        set f \[lreplace $f 0 0 \[uplevel 1 \[list namespace which \[lindex $f 0\]\]\]\]
        set f \[list g $f\]
        return \[eval \[linsert $args 0 romberg $f \[expr \{ asin\($a\) \}\] \[expr \{ asin\($b\) \}\]\]\]
    \}


This __romberg\_sine__ procedure will do any function with sqrt\(1\-x\*x\) in the
denominator\. Our sample function is f\(x\)=exp\(x\)/sqrt\(1\-x\*x\):

    proc f \{ x \} \{
        expr \{ exp\($x\) / sqrt\( 1\. \- $x\*$x \) \}
    \}


Integrating it is a matter of applying __romberg\_sine__ as we would any of
the other __romberg__ procedures:

    foreach \{ value error \} \[romberg\_sine f \-1\.0 1\.0\] break
    puts \[format "integral is %\.6g \+/\- %\.6g" $value $error\]

    integral is 3\.97746 \+/\- 2\.3557e\-010

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: calculus* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.







|
|
|
|
<
>





|
|
|
|
<
>




|
|
<
>




|
|

|







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
dx/sqrt\(1\-x\*\*2\) maps to du\. Choosing x=sin\(u\), we can find that dx=cos\(u\)\*du,
and sqrt\(1\-x\*\*2\)=cos\(u\)\. The integral from a to b of f\(x\) is the integral from
asin\(a\) to asin\(b\) of f\(sin\(u\)\)\*cos\(u\)\.

We can make a function __g__ that accepts an arbitrary function __f__
and the parameter u, and computes this new integrand\.

    proc g { f u } {
        set x [expr { sin($u) }]
        set cmd $f; lappend cmd $x; set y [eval $cmd]
        return [expr { $y / cos($u) }]

    }

Now integrating __f__ from *a* to *b* is the same as integrating
__g__ from *asin\(a\)* to *asin\(b\)*\. It's a little tricky to get __f__
consistently evaluated in the caller's scope; the following procedure does it\.

    proc romberg_sine { f a b args } {
        set f [lreplace $f 0 0 [uplevel 1 [list namespace which [lindex $f 0]]]]
        set f [list g $f]
        return [eval [linsert $args 0 romberg $f [expr { asin($a) }] [expr { asin($b) }]]]

    }

This __romberg\_sine__ procedure will do any function with sqrt\(1\-x\*x\) in the
denominator\. Our sample function is f\(x\)=exp\(x\)/sqrt\(1\-x\*x\):

    proc f { x } {
        expr { exp($x) / sqrt( 1. - $x*$x ) }

    }

Integrating it is a matter of applying __romberg\_sine__ as we would any of
the other __romberg__ procedures:

    foreach { value error } [romberg_sine f -1.0 1.0] break
    puts [format "integral is %.6g +/- %.6g" $value $error]

    integral is 3.97746 +/- 2.3557e-010

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: calculus* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/math/special.md.
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

# <a name='section2'></a>OVERVIEW

In the following table several characteristics of the functions in this package
are summarized: the domain for the argument, the values for the parameters and
error bounds\.

    Family       &#124; Function    &#124; Domain x    &#124; Parameter   &#124; Error bound
    \-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    Bessel       &#124; J0, J1,     &#124; all of R    &#124; n = integer &#124;   < 1\.0e\-8
                 &#124; Jn          &#124;             &#124;             &#124;  \(&#124;x&#124;<20, n<20\)
    Bessel       &#124; J1/2, J\-1/2,&#124;  x > 0      &#124; n = integer &#124;   exact
    Bessel       &#124; I\_n         &#124; all of R    &#124; n = integer &#124;   < 1\.0e\-6
                 &#124;             &#124;             &#124;             &#124;
    Elliptic     &#124; cn          &#124; 0 <= x <= 1 &#124;     \-\-      &#124;   < 1\.0e\-10
    functions    &#124; dn          &#124; 0 <= x <= 1 &#124;     \-\-      &#124;   < 1\.0e\-10
                 &#124; sn          &#124; 0 <= x <= 1 &#124;     \-\-      &#124;   < 1\.0e\-10
    Elliptic     &#124; K           &#124; 0 <= x < 1  &#124;     \-\-      &#124;   < 1\.0e\-6
    integrals    &#124; E           &#124; 0 <= x < 1  &#124;     \-\-      &#124;   < 1\.0e\-6
                 &#124;             &#124;             &#124;             &#124;
    Error        &#124; erf         &#124;             &#124;     \-\-      &#124;
    functions    &#124; erfc        &#124;             &#124;             &#124;
                 &#124;             &#124;             &#124;             &#124;
    Inverse      &#124; invnorm     &#124; 0 < x < 1   &#124;     \-\-      &#124;   < 1\.2e\-9
    normal       &#124;             &#124;             &#124;             &#124;
    distribution &#124;             &#124;             &#124;             &#124;
                 &#124;             &#124;             &#124;             &#124;
    Exponential  &#124; Ei          &#124;  x \!= 0     &#124;     \-\-      &#124;   < 1\.0e\-10 \(relative\)
    integrals    &#124; En          &#124;  x >  0     &#124;     \-\-      &#124;   as Ei
                 &#124; li          &#124;  x > 0      &#124;     \-\-      &#124;   as Ei
                 &#124; Chi         &#124;  x > 0      &#124;     \-\-      &#124;   < 1\.0e\-8
                 &#124; Shi         &#124;  x > 0      &#124;     \-\-      &#124;   < 1\.0e\-8
                 &#124; Ci          &#124;  x > 0      &#124;     \-\-      &#124;   < 2\.0e\-4
                 &#124; Si          &#124;  x > 0      &#124;     \-\-      &#124;   < 2\.0e\-4
                 &#124;             &#124;             &#124;             &#124;
    Fresnel      &#124; C           &#124;  all of R   &#124;     \-\-      &#124;   < 2\.0e\-3
    integrals    &#124; S           &#124;  all of R   &#124;     \-\-      &#124;   < 2\.0e\-3
                 &#124;             &#124;             &#124;             &#124;
    general      &#124; Beta        &#124; \(see Gamma\) &#124;     \-\-      &#124;   < 1\.0e\-9
                 &#124; Gamma       &#124;  x \!= 0,\-1, &#124;     \-\-      &#124;   < 1\.0e\-9
                 &#124;             &#124;  \-2, \.\.\.    &#124;             &#124;
                 &#124; sinc        &#124;  all of R   &#124;     \-\-      &#124;   exact
                 &#124;             &#124;             &#124;             &#124;
    orthogonal   &#124; Legendre    &#124;  all of R   &#124; n = 0,1,\.\.\. &#124;   exact
    polynomials  &#124; Chebyshev   &#124;  all of R   &#124; n = 0,1,\.\.\. &#124;   exact
                 &#124; Laguerre    &#124;  all of R   &#124; n = 0,1,\.\.\. &#124;   exact
                 &#124;             &#124;             &#124; alpha el\. R &#124;
                 &#124; Hermite     &#124;  all of R   &#124; n = 0,1,\.\.\. &#124;   exact

*Note:* Some of the error bounds are estimated, as no "formal" bounds were
available with the implemented approximation method, others hold for the
auxiliary functions used for estimating the primary functions\.

The following well\-known functions are currently missing from the package:








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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

# <a name='section2'></a>OVERVIEW

In the following table several characteristics of the functions in this package
are summarized: the domain for the argument, the values for the parameters and
error bounds\.

    Family       | Function    | Domain x    | Parameter   | Error bound
    -------------+-------------+-------------+-------------+--------------
    Bessel       | J0, J1,     | all of R    | n = integer |   < 1.0e-8
                 | Jn          |             |             |  (|x|<20, n<20)
    Bessel       | J1/2, J-1/2,|  x > 0      | n = integer |   exact
    Bessel       | I_n         | all of R    | n = integer |   < 1.0e-6
                 |             |             |             |
    Elliptic     | cn          | 0 <= x <= 1 |     --      |   < 1.0e-10
    functions    | dn          | 0 <= x <= 1 |     --      |   < 1.0e-10
                 | sn          | 0 <= x <= 1 |     --      |   < 1.0e-10
    Elliptic     | K           | 0 <= x < 1  |     --      |   < 1.0e-6
    integrals    | E           | 0 <= x < 1  |     --      |   < 1.0e-6
                 |             |             |             |
    Error        | erf         |             |     --      |
    functions    | erfc        |             |             |
                 |             |             |             |
    Inverse      | invnorm     | 0 < x < 1   |     --      |   < 1.2e-9
    normal       |             |             |             |
    distribution |             |             |             |
                 |             |             |             |
    Exponential  | Ei          |  x != 0     |     --      |   < 1.0e-10 (relative)
    integrals    | En          |  x >  0     |     --      |   as Ei
                 | li          |  x > 0      |     --      |   as Ei
                 | Chi         |  x > 0      |     --      |   < 1.0e-8
                 | Shi         |  x > 0      |     --      |   < 1.0e-8
                 | Ci          |  x > 0      |     --      |   < 2.0e-4
                 | Si          |  x > 0      |     --      |   < 2.0e-4
                 |             |             |             |
    Fresnel      | C           |  all of R   |     --      |   < 2.0e-3
    integrals    | S           |  all of R   |     --      |   < 2.0e-3
                 |             |             |             |
    general      | Beta        | (see Gamma) |     --      |   < 1.0e-9
                 | Gamma       |  x != 0,-1, |     --      |   < 1.0e-9
                 |             |  -2, ...    |             |
                 | sinc        |  all of R   |     --      |   exact
                 |             |             |             |
    orthogonal   | Legendre    |  all of R   | n = 0,1,... |   exact
    polynomials  | Chebyshev   |  all of R   | n = 0,1,... |   exact
                 | Laguerre    |  all of R   | n = 0,1,... |   exact
                 |             |             | alpha el. R |
                 | Hermite     |  all of R   | n = 0,1,... |   exact

*Note:* Some of the error bounds are estimated, as no "formal" bounds were
available with the implemented approximation method, others hold for the
auxiliary functions used for estimating the primary functions\.

The following well\-known functions are currently missing from the package:

459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

# <a name='section4'></a>THE ORTHOGONAL POLYNOMIALS

For dealing with the classical families of orthogonal polynomials, the package
relies on the *math::polynomials* package\. To evaluate the polynomial at some
coordinate, use the *evalPolyn* command:

    set leg2 \[::math::special::legendre 2\]
    puts "Value at x=$x: \[::math::polynomials::evalPolyn $leg2 $x\]"

The return value from the *legendre* and other commands is actually the
definition of the corresponding polynomial as used in that package\.

# <a name='section5'></a>REMARKS ON THE IMPLEMENTATION

It should be noted, that the actual implementation of J0 and J1 depends on







|
|







459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

# <a name='section4'></a>THE ORTHOGONAL POLYNOMIALS

For dealing with the classical families of orthogonal polynomials, the package
relies on the *math::polynomials* package\. To evaluate the polynomial at some
coordinate, use the *evalPolyn* command:

    set leg2 [::math::special::legendre 2]
    puts "Value at x=$x: [::math::polynomials::evalPolyn $leg2 $x]"

The return value from the *legendre* and other commands is actually the
definition of the corresponding polynomial as used in that package\.

# <a name='section5'></a>REMARKS ON THE IMPLEMENTATION

It should be noted, that the actual implementation of J0 and J1 depends on
Changes to embedded/md/tcllib/files/modules/math/statistics.md.
430
431
432
433
434
435
436
437
438

439
440

441
442
443
444
445
446
447
448
    are\. This is a one\-way ANOVA test\. The groups may also be stored in a nested
    list: The procedure returns a list of the comparison results for each pair
    of groups\. Each element of this list contains: the index of the first group
    and that of the second group, whether the means are likely to be different
    \(1\) or not \(0\) and the confidence interval the conclusion is based on\. The
    groups may also be stored in a nested list:

        test\-anova\-F 0\.05 $A $B $C
        \#

        \# Or equivalently:
        \#

        test\-anova\-F 0\.05 \[list $A $B $C\]

      * float *alpha*

        \- Significance level

      * list *args*








|
<
>
|
<
>
|







430
431
432
433
434
435
436
437

438
439

440
441
442
443
444
445
446
447
448
    are\. This is a one\-way ANOVA test\. The groups may also be stored in a nested
    list: The procedure returns a list of the comparison results for each pair
    of groups\. Each element of this list contains: the index of the first group
    and that of the second group, whether the means are likely to be different
    \(1\) or not \(0\) and the confidence interval the conclusion is based on\. The
    groups may also be stored in a nested list:

        test-anova-F 0.05 $A $B $C

        #
        # Or equivalently:

        #
        test-anova-F 0.05 [list $A $B $C]

      * float *alpha*

        \- Significance level

      * list *args*

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    this list contains: whether the means are likely to be different \(1\) or not
    \(0\) and the confidence interval the conclusion is based on\. The groups may
    also be stored in a nested list, just as with the ANOVA test\.

    Note: some care is required if there is only one group to compare the
    control with:

        test\-Dunnett\-F 0\.05 $control \[list $A\]

    Otherwise the group A is split up into groups of one element \- this is due
    to an ambiguity\.

      * float *alpha*

        \- Significance level \- either 0\.05 or 0\.01







|







475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    this list contains: whether the means are likely to be different \(1\) or not
    \(0\) and the confidence interval the conclusion is based on\. The groups may
    also be stored in a nested list, just as with the ANOVA test\.

    Note: some care is required if there is only one group to compare the
    control with:

        test-Dunnett-F 0.05 $control [list $A]

    Otherwise the group A is split up into groups of one element \- this is due
    to an ambiguity\.

      * float *alpha*

        \- Significance level \- either 0\.05 or 0\.01
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

*Description of the procedures*

  - <a name='48'></a>__::math::statistics::tstat__ *dof* ?alpha?

    Returns the value of the t\-distribution t\* satisfying

        P\(t\*\)  =  1 \- alpha/2
        P\(\-t\*\) =  alpha/2

    for the number of degrees of freedom dof\.

    Given a sample of normally\-distributed data x, with an estimate xbar for the
    mean and sbar for the standard deviation, the alpha confidence interval for
    the estimate of the mean can be calculated as

        \( xbar \- t\* sbar , xbar \+ t\* sbar\)

    The return values from this procedure can be compared to an estimated
    t\-statistic to determine whether the estimated value of a parameter is
    significantly different from zero at the given confidence level\.

      * int *dof*

        Number of degrees of freedom

      * float *alpha*

        Confidence level of the t\-distribution\. Defaults to 0\.05\.

  - <a name='49'></a>__::math::statistics::mv\-wls__ *wt1* *weights\_and\_values*

    Carries out a weighted least squares linear regression for the data points
    provided, with weights assigned to each point\.

    The linear model is of the form

        y = b0 \+ b1 \* x1 \+ b2 \* x2 \.\.\. \+ bN \* xN \+ error

    and each point satisfies

        yi = b0 \+ b1 \* xi1 \+ b2 \* xi2 \+ \.\.\. \+ bN \* xiN \+ Residual\_i

    The procedure returns a list with the following elements:

      * The r\-squared statistic

      * The adjusted r\-squared statistic








|
|







|




















|



|







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

*Description of the procedures*

  - <a name='48'></a>__::math::statistics::tstat__ *dof* ?alpha?

    Returns the value of the t\-distribution t\* satisfying

        P(t*)  =  1 - alpha/2
        P(-t*) =  alpha/2

    for the number of degrees of freedom dof\.

    Given a sample of normally\-distributed data x, with an estimate xbar for the
    mean and sbar for the standard deviation, the alpha confidence interval for
    the estimate of the mean can be calculated as

        ( xbar - t* sbar , xbar + t* sbar)

    The return values from this procedure can be compared to an estimated
    t\-statistic to determine whether the estimated value of a parameter is
    significantly different from zero at the given confidence level\.

      * int *dof*

        Number of degrees of freedom

      * float *alpha*

        Confidence level of the t\-distribution\. Defaults to 0\.05\.

  - <a name='49'></a>__::math::statistics::mv\-wls__ *wt1* *weights\_and\_values*

    Carries out a weighted least squares linear regression for the data points
    provided, with weights assigned to each point\.

    The linear model is of the form

        y = b0 + b1 * x1 + b2 * x2 ... + bN * xN + error

    and each point satisfies

        yi = b0 + b1 * xi1 + b2 * xi2 + ... + bN * xiN + Residual_i

    The procedure returns a list with the following elements:

      * The r\-squared statistic

      * The adjusted r\-squared statistic

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
    provided\.

    This procedure simply calls ::mvlinreg::wls with the weights set to 1\.0, and
    returns the same information\.

*Example of the use:*

    \# Store the value of the unicode value for the "\+/\-" character
    set pm "\\u00B1"

    \# Provide some data
    set data \{\{  \-\.67  14\.18  60\.03 \-7\.5  \}
              \{ 36\.97  15\.52  34\.24 14\.61 \}
              \{\-29\.57  21\.85  83\.36 \-7\.   \}
              \{\-16\.9   11\.79  51\.67 \-6\.56 \}
              \{ 14\.09  16\.24  36\.97 \-12\.84\}
              \{ 31\.52  20\.93  45\.99 \-25\.4 \}
              \{ 24\.05  20\.69  50\.27  17\.27\}
              \{ 22\.23  16\.91  45\.07  \-4\.3 \}
              \{ 40\.79  20\.49  38\.92  \-\.73 \}
              \{\-10\.35  17\.24  58\.77  18\.78\}\}

    \# Call the ols routine
    set results \[::math::statistics::mv\-ols $data\]

    \# Pretty\-print the results
    puts "R\-squared: \[lindex $results 0\]"
    puts "Adj R\-squared: \[lindex $results 1\]"
    puts "Coefficients $pm s\.e\. \-\- \\\[95% confidence interval\\\]:"
    foreach val \[lindex $results 2\] se \[lindex $results 3\] bounds \[lindex $results 4\] \{
        set lb \[lindex $bounds 0\]
        set ub \[lindex $bounds 1\]
        puts "   $val $pm $se \-\- \\\[$lb to $ub\\\]"
    \}


# <a name='section4'></a>STATISTICAL DISTRIBUTIONS

In the literature a large number of probability distributions can be found\. The
statistics package supports:

  - The normal or Gaussian distribution as well as the log\-normal distribution







|
|

|
|
|
|
|
|
|
|
|
|
|

|
|

|
|
|
|
|
|
|
|
<
>







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
    provided\.

    This procedure simply calls ::mvlinreg::wls with the weights set to 1\.0, and
    returns the same information\.

*Example of the use:*

    # Store the value of the unicode value for the "+/-" character
    set pm "\u00B1"

    # Provide some data
    set data {{  -.67  14.18  60.03 -7.5  }
              { 36.97  15.52  34.24 14.61 }
              {-29.57  21.85  83.36 -7.   }
              {-16.9   11.79  51.67 -6.56 }
              { 14.09  16.24  36.97 -12.84}
              { 31.52  20.93  45.99 -25.4 }
              { 24.05  20.69  50.27  17.27}
              { 22.23  16.91  45.07  -4.3 }
              { 40.79  20.49  38.92  -.73 }
              {-10.35  17.24  58.77  18.78}}

    # Call the ols routine
    set results [::math::statistics::mv-ols $data]

    # Pretty-print the results
    puts "R-squared: [lindex $results 0]"
    puts "Adj R-squared: [lindex $results 1]"
    puts "Coefficients $pm s.e. -- \[95% confidence interval\]:"
    foreach val [lindex $results 2] se [lindex $results 3] bounds [lindex $results 4] {
        set lb [lindex $bounds 0]
        set ub [lindex $bounds 1]
        puts "   $val $pm $se -- \[$lb to $ub\]"

    }

# <a name='section4'></a>STATISTICAL DISTRIBUTIONS

In the literature a large number of probability distributions can be found\. The
statistics package supports:

  - The normal or Gaussian distribution as well as the log\-normal distribution
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817

        \- Total number of "observations" in the histogram

  - <a name='93'></a>__::math::statistics::incompleteGamma__ *x* *p* ?tol?

    Evaluate the incomplete Gamma integral

                  1       / x               p\-1
    P\(p,x\) =  \-\-\-\-\-\-\-\-   &#124;   dt exp\(\-t\) \* t
              Gamma\(p\)  / 0

      * float *x*

        \- Value of x \(limit of the integral\)

      * float *p*








|
|
|







1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817

        \- Total number of "observations" in the histogram

  - <a name='93'></a>__::math::statistics::incompleteGamma__ *x* *p* ?tol?

    Evaluate the incomplete Gamma integral

                  1       / x               p-1
    P(p,x) =  --------   |   dt exp(-t) * t
              Gamma(p)  / 0

      * float *x*

        \- Value of x \(limit of the integral\)

      * float *p*

2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082

2083
2084
2085

2086
2087

2088
2089
2090
2091
2092
2093

2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104


2105

2106
2107

2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119

2120
2121
2122
2123

2124
2125

2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139

2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192

  - subdivide

# <a name='section8'></a>EXAMPLES

The code below is a small example of how you can examine a set of data:

    \# Simple example:
    \# \- Generate data \(as a cheap way of getting some\)
    \# \- Perform statistical analysis to describe the data
    \#

    package require math::statistics

    \#

    \# Two auxiliary procs
    \#

    proc pause \{time\} \{
       set wait 0
       after \[expr \{$time\*1000\}\] \{set ::wait 1\}
       vwait wait
    \}


    proc print\-histogram \{counts limits\} \{
       foreach count $counts limit $limits \{
          if \{ $limit \!= \{\} \} \{
             puts \[format "<%12\.4g\\t%d" $limit $count\]
             set prev\_limit $limit
          \} else \{
             puts \[format ">%12\.4g\\t%d" $prev\_limit $count\]
          \}
       \}
    \}



    \#

    \# Our source of arbitrary data
    \#

    proc generateData \{ data1 data2 \} \{
       upvar 1 $data1 \_data1
       upvar 1 $data2 \_data2

       set d1 0\.0
       set d2 0\.0
       for \{ set i 0 \} \{ $i < 100 \} \{ incr i \} \{
          set d1 \[expr \{10\.0\-2\.0\*cos\(2\.0\*3\.1415926\*$i/24\.0\)\+3\.5\*rand\(\)\}\]
          set d2 \[expr \{0\.7\*$d2\+0\.3\*$d1\+0\.7\*rand\(\)\}\]
          lappend \_data1 $d1
          lappend \_data2 $d2
       \}

       return \{\}
    \}

    \#

    \# The analysis session
    \#

    package require Tk
    console show
    canvas \.plot1
    canvas \.plot2
    pack   \.plot1 \.plot2 \-fill both \-side top

    generateData data1 data2

    puts "Basic statistics:"
    set b1 \[::math::statistics::basic\-stats $data1\]
    set b2 \[::math::statistics::basic\-stats $data2\]
    foreach label \{mean min max number stdev var\} v1 $b1 v2 $b2 \{
       puts "$label\\t$v1\\t$v2"
    \}

    puts "Plot the data as function of \\"time\\" and against each other"
    ::math::statistics::plot\-scale \.plot1  0 100  0 20
    ::math::statistics::plot\-scale \.plot2  0 20   0 20
    ::math::statistics::plot\-tline \.plot1 $data1
    ::math::statistics::plot\-tline \.plot1 $data2
    ::math::statistics::plot\-xydata \.plot2 $data1 $data2

    puts "Correlation coefficient:"
    puts \[::math::statistics::corr $data1 $data2\]

    pause 2
    puts "Plot histograms"
    \.plot2 delete all
    ::math::statistics::plot\-scale \.plot2  0 20 0 100
    set limits         \[::math::statistics::minmax\-histogram\-limits 7 16\]
    set histogram\_data \[::math::statistics::histogram $limits $data1\]
    ::math::statistics::plot\-histogram \.plot2 $histogram\_data $limits

    puts "First series:"
    print\-histogram $histogram\_data $limits

    pause 2
    set limits         \[::math::statistics::minmax\-histogram\-limits 0 15 10\]
    set histogram\_data \[::math::statistics::histogram $limits $data2\]
    ::math::statistics::plot\-histogram \.plot2 $histogram\_data $limits d2
    \.plot2 itemconfigure d2 \-fill red

    puts "Second series:"
    print\-histogram $histogram\_data $limits

    puts "Autocorrelation function:"
    set  autoc \[::math::statistics::autocorr $data1\]
    puts \[::math::statistics::map $autoc \{\[format "%\.2f" $x\]\}\]
    puts "Cross\-correlation function:"
    set  crossc \[::math::statistics::crosscorr $data1 $data2\]
    puts \[::math::statistics::map $crossc \{\[format "%\.2f" $x\]\}\]

    ::math::statistics::plot\-scale \.plot1  0 100 \-1  4
    ::math::statistics::plot\-tline \.plot1  $autoc "autoc"
    ::math::statistics::plot\-tline \.plot1  $crossc "crossc"
    \.plot1 itemconfigure autoc  \-fill green
    \.plot1 itemconfigure crossc \-fill yellow

    puts "Quantiles: 0\.1, 0\.2, 0\.5, 0\.8, 0\.9"
    puts "First:  \[::math::statistics::quantiles $data1 \{0\.1 0\.2 0\.5 0\.8 0\.9\}\]"
    puts "Second: \[::math::statistics::quantiles $data2 \{0\.1 0\.2 0\.5 0\.8 0\.9\}\]"

If you run this example, then the following should be clear:

  - There is a strong correlation between two time series, as displayed by the
    raw data and especially by the correlation functions\.

  - Both time series show a significant periodic component







|
|
|
<
>


<
>
|
<
>
|

|

<
|
>
|
|
|
|
|
|
|
<
<
<
|
>
>
|
>
|
<
>
|
|
|

|
|
|
|
|
|
|
<
>
|
<
|
|
>
|
<
>


|
|
|




|
|
|
|
<
>
|
|
|
|
|
|


|



|
|
|
|
|


|


|
|
|
|


|


|
|
|
|
|

|
|
|
|
|

|
|
|







2072
2073
2074
2075
2076
2077
2078
2079
2080
2081

2082
2083
2084

2085
2086

2087
2088
2089
2090
2091

2092
2093
2094
2095
2096
2097
2098
2099
2100



2101
2102
2103
2104
2105
2106

2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118

2119
2120

2121
2122
2123
2124

2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138

2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192

  - subdivide

# <a name='section8'></a>EXAMPLES

The code below is a small example of how you can examine a set of data:

    # Simple example:
    # - Generate data (as a cheap way of getting some)
    # - Perform statistical analysis to describe the data

    #
    package require math::statistics


    #
    # Two auxiliary procs

    #
    proc pause {time} {
       set wait 0
       after [expr {$time*1000}] {set ::wait 1}
       vwait wait

    }

    proc print-histogram {counts limits} {
       foreach count $counts limit $limits {
          if { $limit != {} } {
             puts [format "<%12.4g\t%d" $limit $count]
             set prev_limit $limit
          } else {
             puts [format ">%12.4g\t%d" $prev_limit $count]



          }
       }
    }

    #
    # Our source of arbitrary data

    #
    proc generateData { data1 data2 } {
       upvar 1 $data1 _data1
       upvar 1 $data2 _data2

       set d1 0.0
       set d2 0.0
       for { set i 0 } { $i < 100 } { incr i } {
          set d1 [expr {10.0-2.0*cos(2.0*3.1415926*$i/24.0)+3.5*rand()}]
          set d2 [expr {0.7*$d2+0.3*$d1+0.7*rand()}]
          lappend _data1 $d1
          lappend _data2 $d2

       }
       return {}

    }

    #
    # The analysis session

    #
    package require Tk
    console show
    canvas .plot1
    canvas .plot2
    pack   .plot1 .plot2 -fill both -side top

    generateData data1 data2

    puts "Basic statistics:"
    set b1 [::math::statistics::basic-stats $data1]
    set b2 [::math::statistics::basic-stats $data2]
    foreach label {mean min max number stdev var} v1 $b1 v2 $b2 {
       puts "$label\t$v1\t$v2"

    }
    puts "Plot the data as function of \"time\" and against each other"
    ::math::statistics::plot-scale .plot1  0 100  0 20
    ::math::statistics::plot-scale .plot2  0 20   0 20
    ::math::statistics::plot-tline .plot1 $data1
    ::math::statistics::plot-tline .plot1 $data2
    ::math::statistics::plot-xydata .plot2 $data1 $data2

    puts "Correlation coefficient:"
    puts [::math::statistics::corr $data1 $data2]

    pause 2
    puts "Plot histograms"
    .plot2 delete all
    ::math::statistics::plot-scale .plot2  0 20 0 100
    set limits         [::math::statistics::minmax-histogram-limits 7 16]
    set histogram_data [::math::statistics::histogram $limits $data1]
    ::math::statistics::plot-histogram .plot2 $histogram_data $limits

    puts "First series:"
    print-histogram $histogram_data $limits

    pause 2
    set limits         [::math::statistics::minmax-histogram-limits 0 15 10]
    set histogram_data [::math::statistics::histogram $limits $data2]
    ::math::statistics::plot-histogram .plot2 $histogram_data $limits d2
    .plot2 itemconfigure d2 -fill red

    puts "Second series:"
    print-histogram $histogram_data $limits

    puts "Autocorrelation function:"
    set  autoc [::math::statistics::autocorr $data1]
    puts [::math::statistics::map $autoc {[format "%.2f" $x]}]
    puts "Cross-correlation function:"
    set  crossc [::math::statistics::crosscorr $data1 $data2]
    puts [::math::statistics::map $crossc {[format "%.2f" $x]}]

    ::math::statistics::plot-scale .plot1  0 100 -1  4
    ::math::statistics::plot-tline .plot1  $autoc "autoc"
    ::math::statistics::plot-tline .plot1  $crossc "crossc"
    .plot1 itemconfigure autoc  -fill green
    .plot1 itemconfigure crossc -fill yellow

    puts "Quantiles: 0.1, 0.2, 0.5, 0.8, 0.9"
    puts "First:  [::math::statistics::quantiles $data1 {0.1 0.2 0.5 0.8 0.9}]"
    puts "Second: [::math::statistics::quantiles $data2 {0.1 0.2 0.5 0.8 0.9}]"

If you run this example, then the following should be clear:

  - There is a strong correlation between two time series, as displayed by the
    raw data and especially by the correlation functions\.

  - Both time series show a significant periodic component
Changes to embedded/md/tcllib/files/modules/math/symdiff.md.
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    __sinh__\. __sqrt__, __tan__, and __tanh__\.

Command substitution, backslash substitution, and argument expansion are not
accepted\.

# <a name='section4'></a>Examples

    math::calculus::symdiff::symdiff \{\($a\*$x\+$b\)\*\($c\*$x\+$d\)\} x
    ==> \(\($c \* \(\($a \* $x\) \+ $b\)\) \+ \($a \* \(\($c \* $x\) \+ $d\)\)\)
    math::calculus::symdiff::jacobian \{x \{$a \* $x \+ $b \* $y\}
                             y \{$c \* $x \+ $d \* $y\}\}
    ==> \{\{$a\} \{$b\}\} \{\{$c\} \{$d\}\}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: calculus* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.







|
|
|
|
|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    __sinh__\. __sqrt__, __tan__, and __tanh__\.

Command substitution, backslash substitution, and argument expansion are not
accepted\.

# <a name='section4'></a>Examples

    math::calculus::symdiff::symdiff {($a*$x+$b)*($c*$x+$d)} x
    ==> (($c * (($a * $x) + $b)) + ($a * (($c * $x) + $d)))
    math::calculus::symdiff::jacobian {x {$a * $x + $b * $y}
                             y {$c * $x + $d * $y}}
    ==> {{$a} {$b}} {{$c} {$d}}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *math :: calculus* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/md4/md4.md.
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

  - <a name='8'></a>__::md4::HMACFinal__ *token*

    These commands are identical to the MD4 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % md4::md4 \-hex "Tcl does MD4"
    858da9b31f57648a032230447bd15f25

    % md4::hmac \-hex \-key Sekret "Tcl does MD4"
    c324088e5752872689caedf2a0464758

    % set tok \[md4::MD4Init\]
    ::md4::1
    % md4::MD4Update $tok "Tcl "
    % md4::MD4Update $tok "does "
    % md4::MD4Update $tok "MD4"
    % md4::Hex \[md4::MD4Final $tok\]
    858da9b31f57648a032230447bd15f25

# <a name='section5'></a>REFERENCES

  1. Rivest, R\., "The MD4 Message Digest Algorithm", RFC 1320, MIT, April 1992\.
     \([http://www\.rfc\-editor\.org/rfc/rfc1320\.txt](http://www\.rfc\-editor\.org/rfc/rfc1320\.txt)\)








|


|


|




|







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

  - <a name='8'></a>__::md4::HMACFinal__ *token*

    These commands are identical to the MD4 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % md4::md4 -hex "Tcl does MD4"
    858da9b31f57648a032230447bd15f25

    % md4::hmac -hex -key Sekret "Tcl does MD4"
    c324088e5752872689caedf2a0464758

    % set tok [md4::MD4Init]
    ::md4::1
    % md4::MD4Update $tok "Tcl "
    % md4::MD4Update $tok "does "
    % md4::MD4Update $tok "MD4"
    % md4::Hex [md4::MD4Final $tok]
    858da9b31f57648a032230447bd15f25

# <a name='section5'></a>REFERENCES

  1. Rivest, R\., "The MD4 Message Digest Algorithm", RFC 1320, MIT, April 1992\.
     \([http://www\.rfc\-editor\.org/rfc/rfc1320\.txt](http://www\.rfc\-editor\.org/rfc/rfc1320\.txt)\)

Changes to embedded/md/tcllib/files/modules/md5/md5.md.
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

  - <a name='8'></a>__::md5::HMACFinal__ *token*

    These commands are identical to the MD5 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % md5::md5 \-hex "Tcl does MD5"
    8AAC1EE01E20BB347104FABB90310433

    % md5::hmac \-hex \-key Sekret "Tcl does MD5"
    35BBA244FD56D3EDF5F3C47474DACB5D

    % set tok \[md5::MD5Init\]
    ::md5::1
    % md5::MD5Update $tok "Tcl "
    % md5::MD5Update $tok "does "
    % md5::MD5Update $tok "MD5"
    % md5::Hex \[md5::MD5Final $tok\]
    8AAC1EE01E20BB347104FABB90310433

# <a name='section5'></a>REFERENCES

  1. Rivest, R\., "The MD5 Message\-Digest Algorithm", RFC 1321, MIT and RSA Data
     Security, Inc, April 1992\.
     \([http://www\.rfc\-editor\.org/rfc/rfc1321\.txt](http://www\.rfc\-editor\.org/rfc/rfc1321\.txt)\)







|


|


|




|







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

  - <a name='8'></a>__::md5::HMACFinal__ *token*

    These commands are identical to the MD5 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % md5::md5 -hex "Tcl does MD5"
    8AAC1EE01E20BB347104FABB90310433

    % md5::hmac -hex -key Sekret "Tcl does MD5"
    35BBA244FD56D3EDF5F3C47474DACB5D

    % set tok [md5::MD5Init]
    ::md5::1
    % md5::MD5Update $tok "Tcl "
    % md5::MD5Update $tok "does "
    % md5::MD5Update $tok "MD5"
    % md5::Hex [md5::MD5Final $tok]
    8AAC1EE01E20BB347104FABB90310433

# <a name='section5'></a>REFERENCES

  1. Rivest, R\., "The MD5 Message\-Digest Algorithm", RFC 1321, MIT and RSA Data
     Security, Inc, April 1992\.
     \([http://www\.rfc\-editor\.org/rfc/rfc1321\.txt](http://www\.rfc\-editor\.org/rfc/rfc1321\.txt)\)
Changes to embedded/md/tcllib/files/modules/md5crypt/md5crypt.md.
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

    % md5crypt::md5crypt password 01234567
    $1$01234567$b5lh2mHyD2PdJjFfALlEz1

    % md5crypt::aprcrypt password 01234567
    $apr1$01234567$IXBaQywhAhc0d75ZbaSDp/

    % md5crypt::md5crypt password \[md5crypt::salt\]
    $1$dFmvyRmO$T\.V3OmzqeEf3hqJp2WFcb\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *md5crypt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

    % md5crypt::md5crypt password 01234567
    $1$01234567$b5lh2mHyD2PdJjFfALlEz1

    % md5crypt::aprcrypt password 01234567
    $apr1$01234567$IXBaQywhAhc0d75ZbaSDp/

    % md5crypt::md5crypt password [md5crypt::salt]
    $1$dFmvyRmO$T.V3OmzqeEf3hqJp2WFcb.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *md5crypt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/mime/mime.md.
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

    This command returns a string containing the body of the leaf MIME part
    represented by *token* in canonical form\.

    If the __\-command__ option is present, then it is repeatedly invoked
    with a fragment of the body as this:

        uplevel \#0 $callback \[list "data" $fragment\]

    \(The __\-blocksize__ option, if present, specifies the maximum size of
    each fragment passed to the callback\.\)

    When the end of the body is reached, the callback is invoked as:

        uplevel \#0 $callback "end"

    Alternatively, if an error occurs, the callback is invoked as:

        uplevel \#0 $callback \[list "error" reason\]

    Regardless, the return value of the final invocation of the callback is
    propagated upwards by __::mime::getbody__\.

    If the __\-command__ option is absent, then the return value of
    __::mime::getbody__ is a string containing the MIME part's entire body\.








|






|



|







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

    This command returns a string containing the body of the leaf MIME part
    represented by *token* in canonical form\.

    If the __\-command__ option is present, then it is repeatedly invoked
    with a fragment of the body as this:

        uplevel #0 $callback [list "data" $fragment]

    \(The __\-blocksize__ option, if present, specifies the maximum size of
    each fragment passed to the callback\.\)

    When the end of the body is reached, the callback is invoked as:

        uplevel #0 $callback "end"

    Alternatively, if an error occurs, the callback is invoked as:

        uplevel #0 $callback [list "error" reason]

    Regardless, the return value of the final invocation of the callback is
    propagated upwards by __::mime::getbody__\.

    If the __\-command__ option is absent, then the return value of
    __::mime::getbody__ is a string containing the MIME part's entire body\.

Changes to embedded/md/tcllib/files/modules/mime/smtp.md.
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
__sasl__ depends on a lot of the cryptographic \(secure\) hashes, i\.e\. all of
__[md5](\.\./md5/md5\.md)__, __[otp](\.\./otp/otp\.md)__,
__[md4](\.\./md4/md4\.md)__, __[sha1](\.\./sha1/sha1\.md)__, and
__[ripemd160](\.\./ripemd/ripemd160\.md)__\.

# <a name='section3'></a>EXAMPLE

    proc send\_simple\_message \{recipient email\_server subject body\} \{
        package require smtp
        package require mime

        set token \[mime::initialize \-canonical text/plain \\\\
    	\-string $body\]
        mime::setheader $token Subject $subject
        smtp::sendmessage $token \\\\
    	\-recipients $recipient \-servers $email\_server
        mime::finalize $token
    \}


    send\_simple\_message someone@somewhere\.com localhost \\\\
        "This is the subject\." "This is the message\."

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use







|



|
|

|
|

<
|
>
|
|







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
__sasl__ depends on a lot of the cryptographic \(secure\) hashes, i\.e\. all of
__[md5](\.\./md5/md5\.md)__, __[otp](\.\./otp/otp\.md)__,
__[md4](\.\./md4/md4\.md)__, __[sha1](\.\./sha1/sha1\.md)__, and
__[ripemd160](\.\./ripemd/ripemd160\.md)__\.

# <a name='section3'></a>EXAMPLE

    proc send_simple_message {recipient email_server subject body} {
        package require smtp
        package require mime

        set token [mime::initialize -canonical text/plain \\
    	-string $body]
        mime::setheader $token Subject $subject
        smtp::sendmessage $token \\
    	-recipients $recipient -servers $email_server
        mime::finalize $token

    }

    send_simple_message [email protected] localhost \\
        "This is the subject." "This is the message."

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section5'></a>REFERENCES

  1. Jonathan B\. Postel, "SIMPLE MAIL TRANSFER PROTOCOL", RFC 821, August 1982\.
     \([http://www\.rfc\-editor\.org/rfc/rfc821\.txt](http://www\.rfc\-editor\.org/rfc/rfc821\.txt)\)

  1. J\. Klensin, "Simple Mail Transfer Protocol", RFC 2821, April 2001\.







|

|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section5'></a>REFERENCES

  1. Jonathan B\. Postel, "SIMPLE MAIL TRANSFER PROTOCOL", RFC 821, August 1982\.
     \([http://www\.rfc\-editor\.org/rfc/rfc821\.txt](http://www\.rfc\-editor\.org/rfc/rfc821\.txt)\)

  1. J\. Klensin, "Simple Mail Transfer Protocol", RFC 2821, April 2001\.
Changes to embedded/md/tcllib/files/modules/multiplexer/multiplexer.md.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
It is possible to have different multiplexers running concurrently\.

  - <a name='1'></a>__::multiplexer::create__

    The __create__ command creates a new multiplexer 'instance'\. For
    example:

        set mp \[::multiplexer::create\]

    This instance can then be manipulated like so:

        $\{mp\}::Init 35100

  - <a name='2'></a>__$\{multiplexer\_instance\}::Init__ *port*

    This starts the multiplexer listening on the specified port\.

  - <a name='3'></a>__$\{multiplexer\_instance\}::Config__ *key* *value*








|



|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
It is possible to have different multiplexers running concurrently\.

  - <a name='1'></a>__::multiplexer::create__

    The __create__ command creates a new multiplexer 'instance'\. For
    example:

        set mp [::multiplexer::create]

    This instance can then be manipulated like so:

        ${mp}::Init 35100

  - <a name='2'></a>__$\{multiplexer\_instance\}::Init__ *port*

    This starts the multiplexer listening on the specified port\.

  - <a name='3'></a>__$\{multiplexer\_instance\}::Config__ *key* *value*

Changes to embedded/md/tcllib/files/modules/ncgi/ncgi.md.
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

# <a name='section2'></a>EXAMPLES

Uploading a file

    HTML:
    <html>
    <form action="/cgi\-bin/upload\.cgi" method="POST" enctype="multipart/form\-data">
    Path: <input type="file" name="filedata"><br>
    Name: <input type="text" name="filedesc"><br>
    <input type="submit">
    </form>
    </html>

    TCL: upload\.cgi
    \#\!/usr/local/bin/tclsh

    ::ncgi::parse
    set filedata \[::ncgi::value filedata\]
    set filedesc \[::ncgi::value filedesc\]

    puts "<html> File uploaded at <a href=\\"/images/$filedesc\\">$filedesc</a> </html>"

    set filename /www/images/$filedesc

    set fh \[open $filename w\]
    puts \-nonewline $fh $filedata
    close $fh

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *ncgi* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|






|
|


|
|

|



|
|







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

# <a name='section2'></a>EXAMPLES

Uploading a file

    HTML:
    <html>
    <form action="/cgi-bin/upload.cgi" method="POST" enctype="multipart/form-data">
    Path: <input type="file" name="filedata"><br>
    Name: <input type="text" name="filedesc"><br>
    <input type="submit">
    </form>
    </html>

    TCL: upload.cgi
    #!/usr/local/bin/tclsh

    ::ncgi::parse
    set filedata [::ncgi::value filedata]
    set filedesc [::ncgi::value filedesc]

    puts "<html> File uploaded at <a href=\"/images/$filedesc\">$filedesc</a> </html>"

    set filename /www/images/$filedesc

    set fh [open $filename w]
    puts -nonewline $fh $filedata
    close $fh

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *ncgi* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/nmea/nmea.md.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

  - <a name='1'></a>__::nmea::input__ *sentence*

    Processes and dispatches the supplied sentence\. If *sentence* contains no
    commas it is treated as a Tcl list, otherwise it must be standard comma
    delimited NMEA data, with an optional checksum and leading __$__\.

        nmea::input \{$GPGSA,A,3,04,05,,09,12,,,24,,,,,2\.5,1\.3,2\.1\*39\}
        nmea::input \[list GPGSA A 3 04 05  09 12 "" "" 24 "" "" ""  2\.5 1\.3 2\.1\]

  - <a name='2'></a>__::nmea::open\_port__ *port* ?speed?

    Open the specified COM port and read NMEA sentences when available\. Port
    speed is set to 4800bps by default or to *speed*\.

  - <a name='3'></a>__::nmea::close\_port__







|
|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

  - <a name='1'></a>__::nmea::input__ *sentence*

    Processes and dispatches the supplied sentence\. If *sentence* contains no
    commas it is treated as a Tcl list, otherwise it must be standard comma
    delimited NMEA data, with an optional checksum and leading __$__\.

        nmea::input {$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39}
        nmea::input [list GPGSA A 3 04 05  09 12 "" "" 24 "" "" ""  2.5 1.3 2.1]

  - <a name='2'></a>__::nmea::open\_port__ *port* ?speed?

    Open the specified COM port and read NMEA sentences when available\. Port
    speed is set to 4800bps by default or to *speed*\.

  - <a name='3'></a>__::nmea::close\_port__
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155

156
157
158
159
160
161
162
    EOF handler is invoked when End Of File is reached on the open file or port\.

    The handler procedures, with the exception of the builtin types,must take
    exactly one argument, which is a list of the data values\. The DEFAULT
    handler should have two arguments, the sentence type and the data values\.
    The EOF handler has no arguments\.

        nmea::event gpgsa parse\_sat\_detail
        nmea::event default handle\_unknown

        proc parse\_sat\_detail \{data\} \{
            puts \[lindex $data 1\]
        \}

        proc handle\_unknown \{name data\} \{

            puts "unknown data type $name"
        \}


# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *nmea* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|

|
|
<
|
|
>

<
>







139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154

155
156
157
158
159
160
161
162
    EOF handler is invoked when End Of File is reached on the open file or port\.

    The handler procedures, with the exception of the builtin types,must take
    exactly one argument, which is a list of the data values\. The DEFAULT
    handler should have two arguments, the sentence type and the data values\.
    The EOF handler has no arguments\.

        nmea::event gpgsa parse_sat_detail
        nmea::event default handle_unknown

        proc parse_sat_detail {data} {
            puts [lindex $data 1]

        }

        proc handle_unknown {name data} {
            puts "unknown data type $name"

        }

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *nmea* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/nntp/nntp.md.
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
        *msgid2*\) are queried\.

# <a name='section3'></a>EXAMPLE

A bigger example for posting a single article\.

    package require nntp
    set n \[nntp::nntp NNTP\_SERVER\]
    $n post "From: USER@DOMAIN\.EXT \(USER\_FULL\)
    Path: COMPUTERNAME\!USERNAME
    Newsgroups: alt\.test
    Subject: Tcl test post \-ignore
    Message\-ID: <\[pid\]\[clock seconds\]
    @COMPUTERNAME>
    Date: \[clock format \[clock seconds\] \-format "%a, %d %
    b %y %H:%M:%S GMT" \-gmt true\]

    Test message body"

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *nntp* of the [Tcllib







|
|
|
|
|
|

|
|







348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
        *msgid2*\) are queried\.

# <a name='section3'></a>EXAMPLE

A bigger example for posting a single article\.

    package require nntp
    set n [nntp::nntp NNTP_SERVER]
    $n post "From: [email protected] (USER_FULL)
    Path: COMPUTERNAME!USERNAME
    Newsgroups: alt.test
    Subject: Tcl test post -ignore
    Message-ID: <[pid][clock seconds]
    @COMPUTERNAME>
    Date: [clock format [clock seconds] -format "%a, %d %
    b %y %H:%M:%S GMT" -gmt true]

    Test message body"

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *nntp* of the [Tcllib
Changes to embedded/md/tcllib/files/modules/ntp/ntp_time.md.
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

    Wait for a query to complete and return the status upon completion\.

  - <a name='10'></a>__::time::cleanup__ *token*

    Remove all state variables associated with the request\.

    % set tok \[::time::gettime ntp2a\.mcc\.ac\.uk\]
    % set t \[::time::unixtime $tok\]
    % ::time::cleanup $tok

    % set tok \[::time::getsntp pool\.ntp\.org\]
    % set t \[::time::unixtime $tok\]
    % ::time::cleanup $tok

    proc on\_time \{token\} \{
       if \{\[time::status $token\] eq "ok"\} \{
          puts \[clock format \[time::unixtime $token\]\]
       \} else \{
          puts \[time::error $token\]
       \}

       time::cleanup $token
    \}

    time::getsntp \-command on\_time pool\.ntp\.org

# <a name='section3'></a>AUTHORS

Pat Thoyts

# <a name='section4'></a>Bugs, Ideas, Feedback








|
|


|
|


|
|
|
|
|
<
>

<
>
|







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

    Wait for a query to complete and return the status upon completion\.

  - <a name='10'></a>__::time::cleanup__ *token*

    Remove all state variables associated with the request\.

    % set tok [::time::gettime ntp2a.mcc.ac.uk]
    % set t [::time::unixtime $tok]
    % ::time::cleanup $tok

    % set tok [::time::getsntp pool.ntp.org]
    % set t [::time::unixtime $tok]
    % ::time::cleanup $tok

    proc on_time {token} {
       if {[time::status $token] eq "ok"} {
          puts [clock format [time::unixtime $token]]
       } else {
          puts [time::error $token]

       }
       time::cleanup $token

    }
    time::getsntp -command on_time pool.ntp.org

# <a name='section3'></a>AUTHORS

Pat Thoyts

# <a name='section4'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/oauth/oauth.md.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section3'></a>Commands

  - <a name='1'></a>__::oauth::config__

    When this command is invoked without arguments it returns a dictionary
    containing the current values of all options\.







|

|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section3'></a>Commands

  - <a name='1'></a>__::oauth::config__

    When this command is invoked without arguments it returns a dictionary
    containing the current values of all options\.
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

      * url *baseURL*

        This argument is the URI path to the OAuth API server\. If you plan send
        a GET query, you should provide a full path\.

    HTTP GET
    ::oauth::header \{https://api\.twitter\.com/1\.1/users/lookup\.json?screen\_name=AbiertaMente\}

      * url\-encoded\-string *postQuery*

        When you have to send a header in POST format, you have to put the query
        string into this argument\.

    ::oauth::header \{https://api\.twitter\.com/1\.1/friendships/create\.json\} \{user\_id=158812437&follow=true\}

  - <a name='4'></a>__::oauth::query__ *baseURL* ?*postQuery*?

    This procedure will use the settings made with __::oauth::config__ to
    create the basic authentication and then send the command to the server API\.
    It takes the same arguments as __::oauth::header__\.

    The returned result will be a list containing 2 elements\. The first element
    will be a dictionary containing the HTTP header data response\. This allows
    you, for example, to check the X\-Rate\-Limit from OAuth\. The second element
    will be the raw data returned from API server\. This string is usually a json
    object which can be further decoded with the functions of package
    __[json](\.\./json/json\.md)__, or any other json\-parser for Tcl\.

    Here is an example of how it would work in Twitter\. Do not forget to replace
    the placeholder tokens and keys of the example with your own tokens and keys
    when trying it out\.

    % package require oauth
    % package require json
    % oauth::config \-consumerkey \{your\_consumer\_key\} \-consumersecret \{your\_consumer\_key\_secret\} \-accesstoken \{your\_access\_token\} \-accesstokensecret \{your\_access\_token\_secret\}

    % set response \[oauth::query https://api\.twitter\.com/1\.1/users/lookup\.json?screen\_name=AbiertaMente\]
    % set jsondata \[lindex $response 1\]
    % set data \[json::json2dict $jsondata\]
    $ set data \[lindex $data 0\]
    % dict for \{key val\} $data \{puts "$key => $val"\}
    id => 158812437
    id\_str => 158812437
    name => Un Librepensador
    screen\_name => AbiertaMente
    location => Explico mis tuits ahí →
    description => 160Caracteres para un SMS y contaba mi vida entera sin recortar vocales\. Ahora en Twitter, podemos usar hasta 140 y a mí me sobrarían 20 para contaros todo lo q
    url => http://t\.co/SGs3k9odBn
    entities => url \{urls \{\{url http://t\.co/SGs3k9odBn expanded\_url http://librepensamiento\.es display\_url librepensamiento\.es indices \{0 22\}\}\}\} description \{urls \{\}\}
    protected => false
    followers\_count => 72705
    friends\_count => 53099
    listed\_count => 258
    created\_at => Wed Jun 23 18:29:58 \+0000 2010
    favourites\_count => 297
    utc\_offset => 7200
    time\_zone => Madrid
    geo\_enabled => false
    verified => false
    statuses\_count => 8996
    lang => es
    status => created\_at \{Sun Oct 12 08:02:38 \+0000 2014\} id 521209314087018496 id\_str 521209314087018496 text \{@thesamethanhim http://t\.co/WFoXOAofCt\} source \{<a href="http://twitter\.com" rel="nofollow">Twitter Web Client</a>\} truncated false in\_reply\_to\_status\_id 521076457490350081 in\_reply\_to\_status\_id\_str 521076457490350081 in\_reply\_to\_user\_id 2282730867 in\_reply\_to\_user\_id\_str 2282730867 in\_reply\_to\_screen\_name thesamethanhim geo null coordinates null place null contributors null retweet\_count 0 favorite\_count 0 entities \{hashtags \{\} symbols \{\} urls \{\{url http://t\.co/WFoXOAofCt expanded\_url http://www\.elmundo\.es/internacional/2014/03/05/53173dc1268e3e3f238b458a\.html display\_url elmundo\.es/internacional/… indices \{16 38\}\}\} user\_mentions \{\{screen\_name thesamethanhim name Ἑλένη id 2282730867 id\_str 2282730867 indices \{0 15\}\}\}\} favorited false retweeted false possibly\_sensitive false lang und
    contributors\_enabled => false
    is\_translator => true
    is\_translation\_enabled => false
    profile\_background\_color => 709397
    profile\_background\_image\_url => http://pbs\.twimg\.com/profile\_background\_images/704065051/9309c02aa2728bdf543505ddbd408e2e\.jpeg
    profile\_background\_image\_url\_https => https://pbs\.twimg\.com/profile\_background\_images/704065051/9309c02aa2728bdf543505ddbd408e2e\.jpeg
    profile\_background\_tile => true
    profile\_image\_url => http://pbs\.twimg\.com/profile\_images/2629816665/8035fb81919b840c5cc149755d3d7b0b\_normal\.jpeg
    profile\_image\_url\_https => https://pbs\.twimg\.com/profile\_images/2629816665/8035fb81919b840c5cc149755d3d7b0b\_normal\.jpeg
    profile\_banner\_url => https://pbs\.twimg\.com/profile\_banners/158812437/1400828874
    profile\_link\_color => FF3300
    profile\_sidebar\_border\_color => FFFFFF
    profile\_sidebar\_fill\_color => A0C5C7
    profile\_text\_color => 333333
    profile\_use\_background\_image => true
    default\_profile => false
    default\_profile\_image => false
    following => true
    follow\_request\_sent => false
    notifications => false

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *oauth* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|






|




















|

|
|
|
|
|

|

|

|
|
|

|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|







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

      * url *baseURL*

        This argument is the URI path to the OAuth API server\. If you plan send
        a GET query, you should provide a full path\.

    HTTP GET
    ::oauth::header {https://api.twitter.com/1.1/users/lookup.json?screen_name=AbiertaMente}

      * url\-encoded\-string *postQuery*

        When you have to send a header in POST format, you have to put the query
        string into this argument\.

    ::oauth::header {https://api.twitter.com/1.1/friendships/create.json} {user_id=158812437&follow=true}

  - <a name='4'></a>__::oauth::query__ *baseURL* ?*postQuery*?

    This procedure will use the settings made with __::oauth::config__ to
    create the basic authentication and then send the command to the server API\.
    It takes the same arguments as __::oauth::header__\.

    The returned result will be a list containing 2 elements\. The first element
    will be a dictionary containing the HTTP header data response\. This allows
    you, for example, to check the X\-Rate\-Limit from OAuth\. The second element
    will be the raw data returned from API server\. This string is usually a json
    object which can be further decoded with the functions of package
    __[json](\.\./json/json\.md)__, or any other json\-parser for Tcl\.

    Here is an example of how it would work in Twitter\. Do not forget to replace
    the placeholder tokens and keys of the example with your own tokens and keys
    when trying it out\.

    % package require oauth
    % package require json
    % oauth::config -consumerkey {your_consumer_key} -consumersecret {your_consumer_key_secret} -accesstoken {your_access_token} -accesstokensecret {your_access_token_secret}

    % set response [oauth::query https://api.twitter.com/1.1/users/lookup.json?screen_name=AbiertaMente]
    % set jsondata [lindex $response 1]
    % set data [json::json2dict $jsondata]
    $ set data [lindex $data 0]
    % dict for {key val} $data {puts "$key => $val"}
    id => 158812437
    id_str => 158812437
    name => Un Librepensador
    screen_name => AbiertaMente
    location => Explico mis tuits ahí →
    description => 160Caracteres para un SMS y contaba mi vida entera sin recortar vocales. Ahora en Twitter, podemos usar hasta 140 y a mí me sobrarían 20 para contaros todo lo q
    url => http://t.co/SGs3k9odBn
    entities => url {urls {{url http://t.co/SGs3k9odBn expanded_url http://librepensamiento.es display_url librepensamiento.es indices {0 22}}}} description {urls {}}
    protected => false
    followers_count => 72705
    friends_count => 53099
    listed_count => 258
    created_at => Wed Jun 23 18:29:58 +0000 2010
    favourites_count => 297
    utc_offset => 7200
    time_zone => Madrid
    geo_enabled => false
    verified => false
    statuses_count => 8996
    lang => es
    status => created_at {Sun Oct 12 08:02:38 +0000 2014} id 521209314087018496 id_str 521209314087018496 text {@thesamethanhim http://t.co/WFoXOAofCt} source {<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>} truncated false in_reply_to_status_id 521076457490350081 in_reply_to_status_id_str 521076457490350081 in_reply_to_user_id 2282730867 in_reply_to_user_id_str 2282730867 in_reply_to_screen_name thesamethanhim geo null coordinates null place null contributors null retweet_count 0 favorite_count 0 entities {hashtags {} symbols {} urls {{url http://t.co/WFoXOAofCt expanded_url http://www.elmundo.es/internacional/2014/03/05/53173dc1268e3e3f238b458a.html display_url elmundo.es/internacional/… indices {16 38}}} user_mentions {{screen_name thesamethanhim name Ἑλένη id 2282730867 id_str 2282730867 indices {0 15}}}} favorited false retweeted false possibly_sensitive false lang und
    contributors_enabled => false
    is_translator => true
    is_translation_enabled => false
    profile_background_color => 709397
    profile_background_image_url => http://pbs.twimg.com/profile_background_images/704065051/9309c02aa2728bdf543505ddbd408e2e.jpeg
    profile_background_image_url_https => https://pbs.twimg.com/profile_background_images/704065051/9309c02aa2728bdf543505ddbd408e2e.jpeg
    profile_background_tile => true
    profile_image_url => http://pbs.twimg.com/profile_images/2629816665/8035fb81919b840c5cc149755d3d7b0b_normal.jpeg
    profile_image_url_https => https://pbs.twimg.com/profile_images/2629816665/8035fb81919b840c5cc149755d3d7b0b_normal.jpeg
    profile_banner_url => https://pbs.twimg.com/profile_banners/158812437/1400828874
    profile_link_color => FF3300
    profile_sidebar_border_color => FFFFFF
    profile_sidebar_fill_color => A0C5C7
    profile_text_color => 333333
    profile_use_background_image => true
    default_profile => false
    default_profile_image => false
    following => true
    follow_request_sent => false
    notifications => false

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *oauth* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/oometa/oometa.md.
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

# <a name='description'></a>DESCRIPTION

The __oo::meta__ package provides a data registry service for TclOO classes\.

# <a name='section2'></a>Usage

    oo::class create animal \{
      meta set biodata animal: 1
    \}

    oo::class create mammal \{
      superclass animal
      meta set biodata mammal: 1
    \}

    oo::class create cat \{
      superclass mammal
      meta set biodata diet: carnivore
    \}


    cat create felix
    puts \[felix meta dump biodata\]
    > animal: 1 mammal: 1 diet: carnivore

    felix meta set biodata likes: \{birds mice\}
    puts \[felix meta get biodata\]
    > animal: 1 mammal: 1 diet: carnivore likes: \{bird mice\}

    \# Modify a class
    mammal meta set biodata metabolism: warm\-blooded
    puts \[felix meta get biodata\]
    > animal: 1 mammal: 1 metabolism: warm\-blooded diet: carnivore likes: \{birds mice\}

    \# Overwrite class info
    felix meta set biodata mammal: yes
    puts \[felix meta get biodata\]
    > animal: 1 mammal: yes metabolism: warm\-blooded diet: carnivore likes: \{birds mice\}

# <a name='section3'></a>Concept

The concept behind __oo::meta__ is that each class contributes a snippet of
*local* data\. When __oo::meta::metadata__ is called, the system walks
through the linear ancestry produced by __oo::meta::ancestors__, and
recursively combines all of that local data for all of a class' ancestors into a







|

<
>
|


<
>
|


<
|
>

|


|
|
|

|
|
|
|

|

|
|







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

# <a name='description'></a>DESCRIPTION

The __oo::meta__ package provides a data registry service for TclOO classes\.

# <a name='section2'></a>Usage

    oo::class create animal {
      meta set biodata animal: 1

    }
    oo::class create mammal {
      superclass animal
      meta set biodata mammal: 1

    }
    oo::class create cat {
      superclass mammal
      meta set biodata diet: carnivore

    }

    cat create felix
    puts [felix meta dump biodata]
    > animal: 1 mammal: 1 diet: carnivore

    felix meta set biodata likes: {birds mice}
    puts [felix meta get biodata]
    > animal: 1 mammal: 1 diet: carnivore likes: {bird mice}

    # Modify a class
    mammal meta set biodata metabolism: warm-blooded
    puts [felix meta get biodata]
    > animal: 1 mammal: 1 metabolism: warm-blooded diet: carnivore likes: {birds mice}

    # Overwrite class info
    felix meta set biodata mammal: yes
    puts [felix meta get biodata]
    > animal: 1 mammal: yes metabolism: warm-blooded diet: carnivore likes: {birds mice}

# <a name='section3'></a>Concept

The concept behind __oo::meta__ is that each class contributes a snippet of
*local* data\. When __oo::meta::metadata__ is called, the system walks
through the linear ancestry produced by __oo::meta::ancestors__, and
recursively combines all of that local data for all of a class' ancestors into a
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
    following:

  - <a name='2'></a>__oo::meta::info branchget__ ?*key*? ?\.\.\.?

    Returns a dict representation of the element at *args*, but with any
    trailing : removed from field names\.

    ::oo::meta::info $myclass set option color \{default: green widget: colorselect\}
    puts \[::oo::meta::info $myclass get option color\]
    > \{default: green widget: color\}
    puts \[::oo::meta::info $myclass branchget option color\]
    > \{default green widget color\}

  - <a name='3'></a>__oo::meta::info branchset__ ?*key\.\.\.*? *key* *value*

    Merges *dict* with any other information contaned at node ?*key\.\.\.*?,
    and adding a trailing : to all field names\.

    ::oo::meta::info $myclass branchset option color \{default green widget colorselect\}
    puts \[::oo::meta::info $myclass get option color\]
    > \{default: green widget: color\}

  - <a name='4'></a>__oo::meta::info dump__ *class*

    Returns the complete snapshot of a class metadata, as producted by
    __oo::meta::metadata__

  - <a name='5'></a>__oo::meta::info__ *class* __is__ *type* ?*args*?

    Returns a boolean true or false if the element ?*args*? would match
    __string is__ *type* *value*

    ::oo::meta::info $myclass set constant mammal 1
    puts \[::oo::meta::info $myclass is true constant mammal\]
    > 1

  - <a name='6'></a>__oo::meta::info__ *class* __[merge](\.\./\.\./\.\./\.\./index\.md\#merge)__ ?*dict*? ?*dict*? ?*\.\.\.*?

    Combines all of the arguments into a single dict, which is then stored as
    the new local representation for this class\.








|
|
|
|
|






|
|
|












|







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
    following:

  - <a name='2'></a>__oo::meta::info branchget__ ?*key*? ?\.\.\.?

    Returns a dict representation of the element at *args*, but with any
    trailing : removed from field names\.

    ::oo::meta::info $myclass set option color {default: green widget: colorselect}
    puts [::oo::meta::info $myclass get option color]
    > {default: green widget: color}
    puts [::oo::meta::info $myclass branchget option color]
    > {default green widget color}

  - <a name='3'></a>__oo::meta::info branchset__ ?*key\.\.\.*? *key* *value*

    Merges *dict* with any other information contaned at node ?*key\.\.\.*?,
    and adding a trailing : to all field names\.

    ::oo::meta::info $myclass branchset option color {default green widget colorselect}
    puts [::oo::meta::info $myclass get option color]
    > {default: green widget: color}

  - <a name='4'></a>__oo::meta::info dump__ *class*

    Returns the complete snapshot of a class metadata, as producted by
    __oo::meta::metadata__

  - <a name='5'></a>__oo::meta::info__ *class* __is__ *type* ?*args*?

    Returns a boolean true or false if the element ?*args*? would match
    __string is__ *type* *value*

    ::oo::meta::info $myclass set constant mammal 1
    puts [::oo::meta::info $myclass is true constant mammal]
    > 1

  - <a name='6'></a>__oo::meta::info__ *class* __[merge](\.\./\.\./\.\./\.\./index\.md\#merge)__ ?*dict*? ?*dict*? ?*\.\.\.*?

    Combines all of the arguments into a single dict, which is then stored as
    the new local representation for this class\.

157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173

  - <a name='9'></a>__oo::define meta__

    The package injects a command __oo::define::meta__ which works to
    provide a class in the process of definition access to
    __oo::meta::info__, but without having to look the name up\.

    oo::define myclass \{
      meta set foo bar: baz
    \}


  - <a name='10'></a>__oo::class method meta__

    The package injects a new method __meta__ into __oo::class__ which
    works to provide a class instance access to __oo::meta::info__\.

  - <a name='11'></a>__oo::object method meta__







|

<
>







157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173

  - <a name='9'></a>__oo::define meta__

    The package injects a command __oo::define::meta__ which works to
    provide a class in the process of definition access to
    __oo::meta::info__, but without having to look the name up\.

    oo::define myclass {
      meta set foo bar: baz

    }

  - <a name='10'></a>__oo::class method meta__

    The package injects a new method __meta__ into __oo::class__ which
    works to provide a class instance access to __oo::meta::info__\.

  - <a name='11'></a>__oo::object method meta__
Changes to embedded/md/tcllib/files/modules/ooutil/ooutil.md.
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
    available to a user of the class and of derived classes\.

    Note: The command is equivalent to the command __typemethod__ provided
    by the OO package __[snit](\.\./snit/snit\.md)__ for the same purpose\.

    Example

        oo::class create ActiveRecord \{
            classmethod find args \{ puts "\[self\] called with arguments: $args" \}
        \}

        oo::class create Table \{
            superclass ActiveRecord
        \}

        puts \[Table find foo bar\]
        \# ======
        \# which will write
        \# ======
        \# ::Table called with arguments: foo bar

  - <a name='3'></a>__classvariable__ ?*arg*\.\.\.?

    This command is available within instance methods\. It takes a series of
    variable names and makes them available in the method's scope\. The
    originating scope for the variables is the class \(instance\) the object
    instance belongs to\. In other words, the referenced variables are shared
    between all instances of their class\.

    Note: The command is roughly equivalent to the command __typevariable__
    provided by the OO package __[snit](\.\./snit/snit\.md)__ for the same
    purpose\. The difference is that it cannot be used in the class definition
    itself\.

    Example:

        % oo::class create Foo \{
            method bar \{z\} \{
                classvariable x y
                return \[incr x $z\],\[incr y\]
            \}
        \}


        ::Foo
        % Foo create a
        ::a
        % Foo create b
        ::b
        % a bar 2
        2,1
        % a bar 3
        5,2
        % b bar 7
        12,3
        % b bar \-1
        11,4
        % a bar 0
        11,5

  - <a name='4'></a>__link__ *method*\.\.\.

  - <a name='5'></a>__link__ \{*alias* *method*\}\.\.\.

    This command is available within instance methods\. It takes a list of method
    names and/or pairs of alias\- and method\-name and makes the named methods
    available to all instance methods without requiring the __my__ command\.

    The alias name under which the method becomes available defaults to the
    method name, except where explicitly specified through an alias/method pair\.

    Examples:

        link foo
        \# The method foo is now directly accessible as foo instead of my foo\.

        link \{bar foo\}
        \# The method foo is now directly accessible as bar\.

        link a b c
        \# The methods a, b, and c all become directly acessible under their
        \# own names\.

    The main use of this command is expected to be in instance constructors, for
    convenience, or to set up some methods for use in a mini DSL\.

  - <a name='6'></a>__ooutil::singleton__ ?*arg*\.\.\.?

    This command is a meta\-class, i\.e\. a variant of the builtin
    __oo::class__ which ensures that it creates only a single instance of
    the classes defined with it\.

    Syntax and results are like for __oo::class__\.

    Example:

        % oo::class create example \{
           self mixin singleton
           method foo \{\} \{self\}
        \}

        ::example
        % \[example new\] foo
        ::oo::Obj22
        % \[example new\] foo
        ::oo::Obj22

# <a name='section3'></a>AUTHORS

Donal Fellows, Andreas Kupries

# <a name='section4'></a>Bugs, Ideas, Feedback







|
|
<
>
|

<
>
|
|
|
|
|
















|
|

|
<
<
>
>











|


















|

|
|


|
|














|

|
<
>

|

|







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
    available to a user of the class and of derived classes\.

    Note: The command is equivalent to the command __typemethod__ provided
    by the OO package __[snit](\.\./snit/snit\.md)__ for the same purpose\.

    Example

        oo::class create ActiveRecord {
            classmethod find args { puts "[self] called with arguments: $args" }

        }
        oo::class create Table {
            superclass ActiveRecord

        }
        puts [Table find foo bar]
        # ======
        # which will write
        # ======
        # ::Table called with arguments: foo bar

  - <a name='3'></a>__classvariable__ ?*arg*\.\.\.?

    This command is available within instance methods\. It takes a series of
    variable names and makes them available in the method's scope\. The
    originating scope for the variables is the class \(instance\) the object
    instance belongs to\. In other words, the referenced variables are shared
    between all instances of their class\.

    Note: The command is roughly equivalent to the command __typevariable__
    provided by the OO package __[snit](\.\./snit/snit\.md)__ for the same
    purpose\. The difference is that it cannot be used in the class definition
    itself\.

    Example:

        % oo::class create Foo {
            method bar {z} {
                classvariable x y
                return [incr x $z],[incr y]


            }
        }
        ::Foo
        % Foo create a
        ::a
        % Foo create b
        ::b
        % a bar 2
        2,1
        % a bar 3
        5,2
        % b bar 7
        12,3
        % b bar -1
        11,4
        % a bar 0
        11,5

  - <a name='4'></a>__link__ *method*\.\.\.

  - <a name='5'></a>__link__ \{*alias* *method*\}\.\.\.

    This command is available within instance methods\. It takes a list of method
    names and/or pairs of alias\- and method\-name and makes the named methods
    available to all instance methods without requiring the __my__ command\.

    The alias name under which the method becomes available defaults to the
    method name, except where explicitly specified through an alias/method pair\.

    Examples:

        link foo
        # The method foo is now directly accessible as foo instead of my foo.

        link {bar foo}
        # The method foo is now directly accessible as bar.

        link a b c
        # The methods a, b, and c all become directly acessible under their
        # own names.

    The main use of this command is expected to be in instance constructors, for
    convenience, or to set up some methods for use in a mini DSL\.

  - <a name='6'></a>__ooutil::singleton__ ?*arg*\.\.\.?

    This command is a meta\-class, i\.e\. a variant of the builtin
    __oo::class__ which ensures that it creates only a single instance of
    the classes defined with it\.

    Syntax and results are like for __oo::class__\.

    Example:

        % oo::class create example {
           self mixin singleton
           method foo {} {self}

        }
        ::example
        % [example new] foo
        ::oo::Obj22
        % [example new] foo
        ::oo::Obj22

# <a name='section3'></a>AUTHORS

Donal Fellows, Andreas Kupries

# <a name='section4'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/otp/otp.md.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

  - <a name='3'></a>__::otp::otp\-sha1__ ?*\-hex*? ?*\-words*? *\-seed seed* *\-count count* *data*

  - <a name='4'></a>__::otp::otp\-rmd160__ ?*\-hex*? ?*\-words*? *\-seed seed* *\-count count* *data*

# <a name='section3'></a>EXAMPLES

    % otp::otp\-md5 \-count 99 \-seed host67821 "My Secret Pass Phrase"
    \(binary gibberish\)
    % otp::otp\-md5 \-words \-count 99 \-seed host67821 "My Secret Pass Phrase"
    SOON ARAB BURG LIMB FILE WAD
    % otp::otp\-md5 \-hex \-count 99 \-seed host67821 "My Secret Pass Phrase"
    e249b58257c80087

# <a name='section4'></a>REFERENCES

  1. Haller, N\. et al\., "A One\-Time Password System", RFC 2289, February 1998\.
     [http://www\.rfc\-editor\.org/rfc/rfc2289\.txt](http://www\.rfc\-editor\.org/rfc/rfc2289\.txt)








|
|
|

|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

  - <a name='3'></a>__::otp::otp\-sha1__ ?*\-hex*? ?*\-words*? *\-seed seed* *\-count count* *data*

  - <a name='4'></a>__::otp::otp\-rmd160__ ?*\-hex*? ?*\-words*? *\-seed seed* *\-count count* *data*

# <a name='section3'></a>EXAMPLES

    % otp::otp-md5 -count 99 -seed host67821 "My Secret Pass Phrase"
    (binary gibberish)
    % otp::otp-md5 -words -count 99 -seed host67821 "My Secret Pass Phrase"
    SOON ARAB BURG LIMB FILE WAD
    % otp::otp-md5 -hex -count 99 -seed host67821 "My Secret Pass Phrase"
    e249b58257c80087

# <a name='section4'></a>REFERENCES

  1. Haller, N\. et al\., "A One\-Time Password System", RFC 2289, February 1998\.
     [http://www\.rfc\-editor\.org/rfc/rfc2289\.txt](http://www\.rfc\-editor\.org/rfc/rfc2289\.txt)

Changes to embedded/md/tcllib/files/modules/page/page_util_peg.md.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
    more users\.

        A used by B and C,
        B is reachable,
        C is not,

        so A now loses the node in the expression for C calling it,
        or rather, not calling it anymore\.

    This command updates the cross\-references and which nonterminals are now
    undefined\.

  - <a name='4'></a>__::page::util::peg::flatten__ *treequery* *tree*

    This commands flattens nested sequence and choice operators in the AST







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
    more users\.

        A used by B and C,
        B is reachable,
        C is not,

        so A now loses the node in the expression for C calling it,
        or rather, not calling it anymore.

    This command updates the cross\-references and which nonterminals are now
    undefined\.

  - <a name='4'></a>__::page::util::peg::flatten__ *treequery* *tree*

    This commands flattens nested sequence and choice operators in the AST
Changes to embedded/md/tcllib/files/modules/pluginmgr/pluginmgr.md.
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
    \(underscore for environment variables, backslash for registry entries, and /
    for directories\)\.

    Examples:

        ::pluginmgr::paths ::obj docidx

        => env  DOCIDX\_PLUGINS
           reg  HKEY\_LOCAL\_MACHINE\\SOFTWARE\\docidx\\PLUGINS
           reg  HKEY\_CURRENT\_USER\\SOFTWARE\\docidx\\PLUGINS
           path ~/\.docidx/plugins

        ::pluginmgr::paths ::obj doctools::idx

        => env  DOCTOOLS\_PLUGINS
           env  DOCTOOLS\_IDX\_PLUGINS
           reg  HKEY\_LOCAL\_MACHINE\\SOFTWARE\\doctools\\PLUGINS
           reg  HKEY\_LOCAL\_MACHINE\\SOFTWARE\\doctools\\idx\\PLUGINS
           reg  HKEY\_CURRENT\_USER\\SOFTWARE\\doctools\\PLUGINS
           reg  HKEY\_CURRENT\_USER\\SOFTWARE\\doctools\\idx\\PLUGINS
           path ~/\.doctools/plugin
           path ~/\.doctools/idx/plugin

## <a name='subsection2'></a>OBJECT COMMAND

All commands created by the command __::pluginmgr__ \(See section [PACKAGE
COMMANDS](#subsection1)\) have the following general form and may be used to
invoke various operations on their plugin manager object\.








|
|
|
|



|
|
|
|
|
|
|
|







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
    \(underscore for environment variables, backslash for registry entries, and /
    for directories\)\.

    Examples:

        ::pluginmgr::paths ::obj docidx

        => env  DOCIDX_PLUGINS
           reg  HKEY_LOCAL_MACHINE\SOFTWARE\docidx\PLUGINS
           reg  HKEY_CURRENT_USER\SOFTWARE\docidx\PLUGINS
           path ~/.docidx/plugins

        ::pluginmgr::paths ::obj doctools::idx

        => env  DOCTOOLS_PLUGINS
           env  DOCTOOLS_IDX_PLUGINS
           reg  HKEY_LOCAL_MACHINE\SOFTWARE\doctools\PLUGINS
           reg  HKEY_LOCAL_MACHINE\SOFTWARE\doctools\idx\PLUGINS
           reg  HKEY_CURRENT_USER\SOFTWARE\doctools\PLUGINS
           reg  HKEY_CURRENT_USER\SOFTWARE\doctools\idx\PLUGINS
           path ~/.doctools/plugin
           path ~/.doctools/idx/plugin

## <a name='subsection2'></a>OBJECT COMMAND

All commands created by the command __::pluginmgr__ \(See section [PACKAGE
COMMANDS](#subsection1)\) have the following general form and may be used to
invoke various operations on their plugin manager object\.

Changes to embedded/md/tcllib/files/modules/pop3/pop3.md.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section3'></a>API

  - <a name='1'></a>__::pop3::open__ ?__\-msex__ 0&#124;1? ?__\-retr\-mode__ retr&#124;list&#124;slow? ?__\-socketcmd__ cmdprefix? ?__\-stls__ 0&#124;1? ?__\-tls\-callback__ stls\-callback\-command? *host username password* ?*port*?

    Open a socket connection to the server specified by *host*, transmit the
    *username* and *password* as login information to the server\. The







|

|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section3'></a>API

  - <a name='1'></a>__::pop3::open__ ?__\-msex__ 0&#124;1? ?__\-retr\-mode__ retr&#124;list&#124;slow? ?__\-socketcmd__ cmdprefix? ?__\-stls__ 0&#124;1? ?__\-tls\-callback__ stls\-callback\-command? *host username password* ?*port*?

    Open a socket connection to the server specified by *host*, transmit the
    *username* and *password* as login information to the server\. The
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
__\-socketcmd__ or the option __\-stls__ of the command
__pop3::open__\. The first method, option __\-socketcmd__, will force the
use of the __tls::socket__ command when opening the connection\. This is
suitable for POP3 servers which expect SSL connections only\. These will
generally be listening on port 995\.

    package require tls
    tls::init \-cafile /path/to/ca/cert \-keyfile \.\.\.

    \# Create secured pop3 channel
    pop3::open \-socketcmd tls::socket \\\\
    	$thehost $theuser $thepassword

    \.\.\.

The second method, option __\-stls__, will connect to the standard POP3 port
and then perform an STARTTLS handshake\. This will only work for POP3 servers
which have this capability\. The package will confirm that the server supports
STARTTLS and the handshake was performed correctly before proceeding with
authentication\.

    package require tls
    tls::init \-cafile /path/to/ca/cert \-keyfile \.\.\.

    \# Create secured pop3 channel
    pop3::open \-stls 1 \\\\
    	$thehost $theuser $thepassword

    \.\.\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pop3* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|
|


|








|

|
|


|







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
__\-socketcmd__ or the option __\-stls__ of the command
__pop3::open__\. The first method, option __\-socketcmd__, will force the
use of the __tls::socket__ command when opening the connection\. This is
suitable for POP3 servers which expect SSL connections only\. These will
generally be listening on port 995\.

    package require tls
    tls::init -cafile /path/to/ca/cert -keyfile ...

    # Create secured pop3 channel
    pop3::open -socketcmd tls::socket \\
    	$thehost $theuser $thepassword

    ...

The second method, option __\-stls__, will connect to the standard POP3 port
and then perform an STARTTLS handshake\. This will only work for POP3 servers
which have this capability\. The package will confirm that the server supports
STARTTLS and the handshake was performed correctly before proceeding with
authentication\.

    package require tls
    tls::init -cafile /path/to/ca/cert -keyfile ...

    # Create secured pop3 channel
    pop3::open -stls 1 \\
    	$thehost $theuser $thepassword

    ...

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pop3* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pop3d/pop3d.md.
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

The option __\-socket__ \(see [Options](#section2)\) enables users of the
package to override how the server opens its listening socket\. The envisioned
main use is the specification of the __tls::socket__ command, see package
__[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__, to secure the communication\.

    package require tls
    tls::init \\\\
    	\.\.\.

    pop3d::new S \-socket tls::socket
    \.\.\.

# <a name='section6'></a>References

  1. [RFC 1939](http://www\.rfc\-editor\.org/rfc/rfc1939\.txt)

  1. [RFC 2449](http://www\.rfc\-editor\.org/rfc/rfc2449\.txt)








|
|

|
|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

The option __\-socket__ \(see [Options](#section2)\) enables users of the
package to override how the server opens its listening socket\. The envisioned
main use is the specification of the __tls::socket__ command, see package
__[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__, to secure the communication\.

    package require tls
    tls::init \\
    	...

    pop3d::new S -socket tls::socket
    ...

# <a name='section6'></a>References

  1. [RFC 1939](http://www\.rfc\-editor\.org/rfc/rfc1939\.txt)

  1. [RFC 2449](http://www\.rfc\-editor\.org/rfc/rfc2449\.txt)

Changes to embedded/md/tcllib/files/modules/pt/pt_astree.md.
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
      1. The string representation of the value is the canonical representation
         of a pure Tcl list\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the parsing expression grammar below

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

and the input string

    120\+5

then a parser should deliver the abstract syntax tree below \(except for
whitespace\)

    set ast \{Expression 0 4
        \{Factor 0 4
            \{Term 0 2
                \{Number 0 2
                    \{Digit 0 0\}
                    \{Digit 1 1\}
                    \{Digit 2 2\}
                \}
            \}


            \{AddOp 3 3\}
            \{Term 4 4
                \{Number 4 4
                    \{Digit 4 4\}
                \}
            \}
        \}
    \}





Or, more graphical

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png)

# <a name='section4'></a>Bugs, Ideas, Feedback








|
|
|
|
|
|
|
|
|




|




|
|
|
|
|
|
|
<
<
>
>
|
|
|
|
<
<
<
<
>
>
>
>







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
      1. The string representation of the value is the canonical representation
         of a pure Tcl list\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the parsing expression grammar below

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

and the input string

    120+5

then a parser should deliver the abstract syntax tree below \(except for
whitespace\)

    set ast {Expression 0 4
        {Factor 0 4
            {Term 0 2
                {Number 0 2
                    {Digit 0 0}
                    {Digit 1 1}
                    {Digit 2 2}


                }
            }
            {AddOp 3 3}
            {Term 4 4
                {Number 4 4
                    {Digit 4 4}




                }
            }
        }
    }

Or, more graphical

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png)

# <a name='section4'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/pt/pt_from_api.md.
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
     the plugin in a state where another usage cycle can be run without
     problems\.

# <a name='section4'></a>Usage

To use a converter do

    \# Get the converter \(single command here, not class\)
    package require the\-converter\-package

    \# Perform the conversion
    set serial \[theconverter convert $thegrammartext\]

    \.\.\. process the result \.\.\.

To use a plugin __FOO__ do

    \# Get an import plugin manager
    package require pt::peg::import
    pt::peg::import I

    \# Run the plugin, and the converter inside\.
    set serial \[I import serial $thegrammartext FOO\]

    \.\.\. process the result \.\.\.

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG







|
|

|
|

|



|



|
|

|







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
     the plugin in a state where another usage cycle can be run without
     problems\.

# <a name='section4'></a>Usage

To use a converter do

    # Get the converter (single command here, not class)
    package require the-converter-package

    # Perform the conversion
    set serial [theconverter convert $thegrammartext]

    ... process the result ...

To use a plugin __FOO__ do

    # Get an import plugin manager
    package require pt::peg::import
    pt::peg::import I

    # Run the plugin, and the converter inside.
    set serial [I import serial $thegrammartext FOO]

    ... process the result ...

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_json_language.md.
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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

a JSON serialization for it is

    \{

        "pt::grammar::peg" : \{
            "rules" : \{
                "AddOp"     : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Digit"     : \{
                    "is"   : "\\/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}",
                    "mode" : "value"
                \},
                "Expression" : \{
                    "is"   : "\\/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}",
                    "mode" : "value"
                \},
                "Factor"    : \{
                    "is"   : "x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}",
                    "mode" : "value"
                \},
                "MulOp"     : \{
                    "is"   : "\\/ \{t \*\} \{t \\/\}",
                    "mode" : "value"
                \},
                "Number"    : \{
                    "is"   : "x \{? \{n Sign\}\} \{\+ \{n Digit\}\}",
                    "mode" : "value"
                \},
                "Sign"      : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Term"      : \{
                    "is"   : "n Number",
                    "mode" : "value"
                \}

            \},
            "start" : "n Expression"
        \}
    \}



and a Tcl serialization of the same is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


The similarity of the latter to the JSON should be quite obvious\.

# <a name='section2'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.







|
|
|
|
|
|
|
|
|




<
>
|
|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|


<
>
|

<
<
|
>
>


|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

a JSON serialization for it is


    {
        "pt::grammar::peg" : {
            "rules" : {
                "AddOp"     : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Digit"     : {
                    "is"   : "\/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}",
                    "mode" : "value"
                },
                "Expression" : {
                    "is"   : "\/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}",
                    "mode" : "value"
                },
                "Factor"    : {
                    "is"   : "x {n Term} {* {x {n AddOp} {n Term}}}",
                    "mode" : "value"
                },
                "MulOp"     : {
                    "is"   : "\/ {t *} {t \/}",
                    "mode" : "value"
                },
                "Number"    : {
                    "is"   : "x {? {n Sign}} {+ {n Digit}}",
                    "mode" : "value"
                },
                "Sign"      : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Term"      : {
                    "is"   : "n Number",
                    "mode" : "value"

                }
            },
            "start" : "n Expression"


        }
    }

and a Tcl serialization of the same is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

The similarity of the latter to the JSON should be quite obvious\.

# <a name='section2'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section3'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section3'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_param.md.
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
__[pt::rde](pt\_rdengine\.md)__, is not only coded in Tcl, but also relies
on Tcl commands to provide it with control flow \(instructions\)\.

# <a name='section4'></a>Interaction of the Instructions with the Architectural State

    Instruction		Inputs				Outputs
    ======================= =======================		====================
    ast\_pop\_discard		AS			\->	AS
    ast\_pop\_rewind		AS			\->	AS, ARS
    ast\_push		ARS, AS			\->	AS
    ast\_value\_push		SV, ARS			\->	ARS
    ======================= =======================		====================
    error\_clear		\-			\->	ER
    error\_nonterminal sym	ER, LS			\->	ER
    error\_pop\_merge   	ES, ER			\->	ER
    error\_push		ES, ER			\->	ES
    ======================= =======================		====================
    input\_next msg		IN			\->	TC, CL, CC, ST, ER
    ======================= =======================		====================
    loc\_pop\_discard		LS			\->	LS
    loc\_pop\_rewind		LS			\->	LS, CL
    loc\_push		CL, LS			\->	LS
    ======================= =======================		====================
    status\_fail		\-			\->	ST
    status\_negate		ST			\->	ST
    status\_ok		\-			\->	ST
    ======================= =======================		====================
    symbol\_restore sym	NC			\->	CL, ST, ER, SV
    symbol\_save    sym	CL, ST, ER, SV LS	\->	NC
    ======================= =======================		====================
    test\_alnum  		CC			\->	ST, ER
    test\_alpha		CC			\->	ST, ER
    test\_ascii		CC			\->	ST, ER
    test\_char char		CC			\->	ST, ER
    test\_ddigit		CC			\->	ST, ER
    test\_digit		CC			\->	ST, ER
    test\_graph		CC			\->	ST, ER
    test\_lower		CC			\->	ST, ER
    test\_print		CC			\->	ST, ER
    test\_punct		CC			\->	ST, ER
    test\_range chars chare	CC			\->	ST, ER
    test\_space		CC			\->	ST, ER
    test\_upper		CC			\->	ST, ER
    test\_wordchar		CC			\->	ST, ER
    test\_xdigit		CC			\->	ST, ER
    ======================= =======================		====================
    value\_clear		\-			\->	SV
    value\_leaf symbol	LS, CL			\->	SV
    value\_reduce symbol	ARS, LS, CL		\->	SV
    ======================= =======================		====================

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|
|
|
|

|
|
|
|

|

|
|
|

|
|
|

|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|







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
__[pt::rde](pt\_rdengine\.md)__, is not only coded in Tcl, but also relies
on Tcl commands to provide it with control flow \(instructions\)\.

# <a name='section4'></a>Interaction of the Instructions with the Architectural State

    Instruction		Inputs				Outputs
    ======================= =======================		====================
    ast_pop_discard		AS			->	AS
    ast_pop_rewind		AS			->	AS, ARS
    ast_push		ARS, AS			->	AS
    ast_value_push		SV, ARS			->	ARS
    ======================= =======================		====================
    error_clear		-			->	ER
    error_nonterminal sym	ER, LS			->	ER
    error_pop_merge   	ES, ER			->	ER
    error_push		ES, ER			->	ES
    ======================= =======================		====================
    input_next msg		IN			->	TC, CL, CC, ST, ER
    ======================= =======================		====================
    loc_pop_discard		LS			->	LS
    loc_pop_rewind		LS			->	LS, CL
    loc_push		CL, LS			->	LS
    ======================= =======================		====================
    status_fail		-			->	ST
    status_negate		ST			->	ST
    status_ok		-			->	ST
    ======================= =======================		====================
    symbol_restore sym	NC			->	CL, ST, ER, SV
    symbol_save    sym	CL, ST, ER, SV LS	->	NC
    ======================= =======================		====================
    test_alnum  		CC			->	ST, ER
    test_alpha		CC			->	ST, ER
    test_ascii		CC			->	ST, ER
    test_char char		CC			->	ST, ER
    test_ddigit		CC			->	ST, ER
    test_digit		CC			->	ST, ER
    test_graph		CC			->	ST, ER
    test_lower		CC			->	ST, ER
    test_print		CC			->	ST, ER
    test_punct		CC			->	ST, ER
    test_range chars chare	CC			->	ST, ER
    test_space		CC			->	ST, ER
    test_upper		CC			->	ST, ER
    test_wordchar		CC			->	ST, ER
    test_xdigit		CC			->	ST, ER
    ======================= =======================		====================
    value_clear		-			->	SV
    value_leaf symbol	LS, CL			->	SV
    value_reduce symbol	ARS, LS, CL		->	SV
    ======================= =======================		====================

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/pt/pt_parser_api.md.
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
    This method runs the parser using the string in *text* as input\. In all
    other ways it behaves like the method __parse__, shown above\.

# <a name='section4'></a>Usage

A generated parser is used like this

    package require the\-parser\-package ;\# Generated by result\-formats 'critcl', 'snit' or 'oo' of 'pt'\.
    set parser \[the\-parser\-class\]

    set ast \[$parser parse $channel\]
    \.\.\. process the abstract syntax tree \.\.\.

When using a grammar interpreter for parsing some differences creep in

    package require the\-grammar\-package ;\# Generated by result\-format 'container' of 'pt'\.
    set grammar \[the\-grammar\-class\]

    package require pt::peg::interp
    set parser \[pt::peg::interp\]

    $parser use $grammar

    set ast \[$parser parse $channel\]
    $parser destroy

    \.\.\. process the abstract syntax tree \.\.\.

# <a name='section5'></a>AST serialization format

Here we specify the format used by the Parser Tools to serialize Abstract Syntax
Trees \(ASTs\) as immutable values for transport, comparison, etc\.

Each node in an AST represents a nonterminal symbol of a grammar, and the range







|
|

|
|



|
|


|



|


|







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
    This method runs the parser using the string in *text* as input\. In all
    other ways it behaves like the method __parse__, shown above\.

# <a name='section4'></a>Usage

A generated parser is used like this

    package require the-parser-package ;# Generated by result-formats 'critcl', 'snit' or 'oo' of 'pt'.
    set parser [the-parser-class]

    set ast [$parser parse $channel]
    ... process the abstract syntax tree ...

When using a grammar interpreter for parsing some differences creep in

    package require the-grammar-package ;# Generated by result-format 'container' of 'pt'.
    set grammar [the-grammar-class]

    package require pt::peg::interp
    set parser [pt::peg::interp]

    $parser use $grammar

    set ast [$parser parse $channel]
    $parser destroy

    ... process the abstract syntax tree ...

# <a name='section5'></a>AST serialization format

Here we specify the format used by the Parser Tools to serialize Abstract Syntax
Trees \(ASTs\) as immutable values for transport, comparison, etc\.

Each node in an AST represents a nonterminal symbol of a grammar, and the range
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
      1. The string representation of the value is the canonical representation
         of a pure Tcl list\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the parsing expression grammar below

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

and the input string

    120\+5

then a parser should deliver the abstract syntax tree below \(except for
whitespace\)

    set ast \{Expression 0 4
        \{Factor 0 4
            \{Term 0 2
                \{Number 0 2
                    \{Digit 0 0\}
                    \{Digit 1 1\}
                    \{Digit 2 2\}
                \}
            \}


            \{AddOp 3 3\}
            \{Term 4 4
                \{Number 4 4
                    \{Digit 4 4\}
                \}
            \}
        \}
    \}





Or, more graphical

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png)

# <a name='section6'></a>PE serialization format








|
|
|
|
|
|
|
|
|




|




|
|
|
|
|
|
|
<
<
>
>
|
|
|
|
<
<
<
<
>
>
>
>







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
      1. The string representation of the value is the canonical representation
         of a pure Tcl list\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the parsing expression grammar below

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

and the input string

    120+5

then a parser should deliver the abstract syntax tree below \(except for
whitespace\)

    set ast {Expression 0 4
        {Factor 0 4
            {Term 0 2
                {Number 0 2
                    {Digit 0 0}
                    {Digit 1 1}
                    {Digit 2 2}


                }
            }
            {AddOp 3 3}
            {Term 4 4
                {Number 4 4
                    {Digit 4 4}




                }
            }
        }
    }

Or, more graphical

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png)

# <a name='section6'></a>PE serialization format

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_container.md.
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

    This method assigns the contents of the PEG object *source* to ourselves,
    overwriting the existing definition\. This is the assignment operator for
    grammars\.

    This operation is in effect equivalent to

        *objectName* __deserialize =__ \[*source* __serialize__\]

  - <a name='9'></a>*objectName* __\-\->__ *destination*

    This method assigns our contents to the PEG object *destination*,
    overwriting the existing definition\. This is the reverse assignment operator
    for grammars\.

    This operation is in effect equivalent to

        *destination* __deserialize =__ \[*objectName* __serialize__\]

  - <a name='10'></a>*objectName* __serialize__ ?*format*?

    This method returns our grammar in some textual form usable for transfer,
    persistent storage, etc\. If no *format* is not specified the returned
    result is the canonical serialization of the grammar, as specified in the
    section [PEG serialization format](#section2)\.







|









|







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

    This method assigns the contents of the PEG object *source* to ourselves,
    overwriting the existing definition\. This is the assignment operator for
    grammars\.

    This operation is in effect equivalent to

        *objectName* __deserialize =__ [*source* __serialize__]

  - <a name='9'></a>*objectName* __\-\->__ *destination*

    This method assigns our contents to the PEG object *destination*,
    overwriting the existing definition\. This is the reverse assignment operator
    for grammars\.

    This operation is in effect equivalent to

        *destination* __deserialize =__ [*objectName* __serialize__]

  - <a name='10'></a>*objectName* __serialize__ ?*format*?

    This method returns our grammar in some textual form usable for transfer,
    persistent storage, etc\. If no *format* is not specified the returned
    result is the canonical serialization of the grammar, as specified in the
    section [PEG serialization format](#section2)\.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection3'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section3'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection3'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section3'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection4'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection4'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_export.md.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection4'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section4'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection4'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section4'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection5'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection5'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_export_container.md.
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

It has no direct formal specification beyond what was said above\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

one possible CONTAINER serialization for it is

    snit::type a\_pe\_grammar \{
        constructor \{\} \{
            install myg using pt::peg::container $\{selfns\}::G
            $myg start \{n Expression\}
            $myg add   AddOp Digit Expression Factor MulOp Number Sign Term
            $myg modes \{
                AddOp      value
                Digit      value
                Expression value
                Factor     value
                MulOp      value
                Number     value
                Sign       value
                Term       value
            \}

            $myg rules \{
                AddOp      \{/ \{t \-\} \{t \+\}\}
                Digit      \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}
                Expression \{/ \{x \{t \\50\} \{n Expression\} \{t \\51\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}\}
                Factor     \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}
                MulOp      \{/ \{t \*\} \{t /\}\}
                Number     \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}
                Sign       \{/ \{t \-\} \{t \+\}\}
                Term       \{n Number\}
            \}

            return
        \}


        component myg
        delegate method \* to myg
    \}


# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG







|
|
|
|
|
|
|
|
|




|
|
|
|

|








<
>
|
|
|
|
|
|
|
|
|
<
>

<
|
>

|
<
>







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

It has no direct formal specification beyond what was said above\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

one possible CONTAINER serialization for it is

    snit::type a_pe_grammar {
        constructor {} {
            install myg using pt::peg::container ${selfns}::G
            $myg start {n Expression}
            $myg add   AddOp Digit Expression Factor MulOp Number Sign Term
            $myg modes {
                AddOp      value
                Digit      value
                Expression value
                Factor     value
                MulOp      value
                Number     value
                Sign       value
                Term       value

            }
            $myg rules {
                AddOp      {/ {t -} {t +}}
                Digit      {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}
                Expression {/ {x {t \50} {n Expression} {t \51}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}}
                Factor     {x {n Term} {* {x {n AddOp} {n Term}}}}
                MulOp      {/ {t *} {t /}}
                Number     {x {? {n Sign}} {+ {n Digit}}}
                Sign       {/ {t -} {t +}}
                Term       {n Number}

            }
            return

        }

        component myg
        delegate method * to myg

    }

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_export_json.md.
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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

a JSON serialization for it is

    \{

        "pt::grammar::peg" : \{
            "rules" : \{
                "AddOp"     : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Digit"     : \{
                    "is"   : "\\/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}",
                    "mode" : "value"
                \},
                "Expression" : \{
                    "is"   : "\\/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}",
                    "mode" : "value"
                \},
                "Factor"    : \{
                    "is"   : "x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}",
                    "mode" : "value"
                \},
                "MulOp"     : \{
                    "is"   : "\\/ \{t \*\} \{t \\/\}",
                    "mode" : "value"
                \},
                "Number"    : \{
                    "is"   : "x \{? \{n Sign\}\} \{\+ \{n Digit\}\}",
                    "mode" : "value"
                \},
                "Sign"      : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Term"      : \{
                    "is"   : "n Number",
                    "mode" : "value"
                \}

            \},
            "start" : "n Expression"
        \}
    \}



and a Tcl serialization of the same is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


The similarity of the latter to the JSON should be quite obvious\.

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.







|
|
|
|
|
|
|
|
|




<
>
|
|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|


<
>
|

<
<
|
>
>


|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

a JSON serialization for it is


    {
        "pt::grammar::peg" : {
            "rules" : {
                "AddOp"     : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Digit"     : {
                    "is"   : "\/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}",
                    "mode" : "value"
                },
                "Expression" : {
                    "is"   : "\/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}",
                    "mode" : "value"
                },
                "Factor"    : {
                    "is"   : "x {n Term} {* {x {n AddOp} {n Term}}}",
                    "mode" : "value"
                },
                "MulOp"     : {
                    "is"   : "\/ {t *} {t \/}",
                    "mode" : "value"
                },
                "Number"    : {
                    "is"   : "x {? {n Sign}} {+ {n Digit}}",
                    "mode" : "value"
                },
                "Sign"      : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Term"      : {
                    "is"   : "n Number",
                    "mode" : "value"

                }
            },
            "start" : "n Expression"


        }
    }

and a Tcl serialization of the same is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

The similarity of the latter to the JSON should be quite obvious\.

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_export_peg.md.
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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe\-grammar\-for\-peg \(Grammar\)

    	\# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Syntactical constructs

            Grammar         <\- WHITESPACE Header Definition\* Final EOF ;

            Header          <\- PEG Identifier StartExpr ;
            Definition      <\- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <\- \(VOID / LEAF\) COLON ;
            Expression      <\- Sequence \(SLASH Sequence\)\* ;
            Sequence        <\- Prefix\+ ;
            Prefix          <\- \(AND / NOT\)? Suffix ;
            Suffix          <\- Primary \(QUESTION / STAR / PLUS\)? ;
            Primary         <\- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <\- APOSTROPH  \(\!APOSTROPH  Char\)\* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH \(\!DAPOSTROPH Char\)\* DAPOSTROPH WHITESPACE ;
            Class           <\- OPENB \(\!CLOSEB Range\)\* CLOSEB WHITESPACE ;
            Range           <\- Char TO Char / Char ;

            StartExpr       <\- OPEN Expression CLOSE ;
    void:   Final           <\- "END" WHITESPACE SEMICOLON WHITESPACE ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Lexing constructs

            Identifier      <\- Ident WHITESPACE ;
    leaf:   Ident           <\- \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\* ;
            Char            <\- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <\- "\\\\" \[nrt'"\\\[\\\]\\\\\] ;
    leaf:   CharOctalFull   <\- "\\\\" \[0\-2\]\[0\-7\]\[0\-7\] ;
    leaf:   CharOctalPart   <\- "\\\\" \[0\-7\]\[0\-7\]? ;
    leaf:   CharUnicode     <\- "\\\\" 'u' HexDigit \(HexDigit \(HexDigit HexDigit?\)?\)? ;
    leaf:   CharUnescaped   <\- \!"\\\\" \. ;

    void:   HexDigit        <\- \[0\-9a\-fA\-F\] ;

    void:   TO              <\- '\-'           ;
    void:   OPENB           <\- "\["           ;
    void:   CLOSEB          <\- "\]"           ;
    void:   APOSTROPH       <\- "'"           ;
    void:   DAPOSTROPH      <\- '"'           ;
    void:   PEG             <\- "PEG" \!\(\[\_:\] / <alnum>\) WHITESPACE ;
    void:   IS              <\- "<\-"    WHITESPACE ;
    leaf:   VOID            <\- "void"  WHITESPACE ; \# Implies that definition has no semantic value\.
    leaf:   LEAF            <\- "leaf"  WHITESPACE ; \# Implies that definition has no terminals\.
    void:   SEMICOLON       <\- ";"     WHITESPACE ;
    void:   COLON           <\- ":"     WHITESPACE ;
    void:   SLASH           <\- "/"     WHITESPACE ;
    leaf:   AND             <\- "&"     WHITESPACE ;
    leaf:   NOT             <\- "\!"     WHITESPACE ;
    leaf:   QUESTION        <\- "?"     WHITESPACE ;
    leaf:   STAR            <\- "\*"     WHITESPACE ;
    leaf:   PLUS            <\- "\+"     WHITESPACE ;
    void:   OPEN            <\- "\("     WHITESPACE ;
    void:   CLOSE           <\- "\)"     WHITESPACE ;
    leaf:   DOT             <\- "\."     WHITESPACE ;

    leaf:   ALNUM           <\- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <\- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <\- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <\- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <\- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <\- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <\- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <\- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <\- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <\- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <\- "<space>"    WHITESPACE ;
    leaf:   UPPER           <\- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <\- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <\- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <\- \(" " / "\\t" / EOL / COMMENT\)\* ;
    void:   COMMENT         <\- '\#' \(\!EOL \.\)\* EOL ;
    void:   EOL             <\- "\\n\\r" / "\\n" / "\\r" ;
    void:   EOF             <\- \!\. ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator \(Expression\)
        Sign       <\- \[\-\+\] 						;
        Number     <\- Sign? <ddigit>\+				;
        Expression <\- '\(' Expression '\)' / \(Factor \(MulOp Factor\)\*\)	;
        MulOp      <\- \[\*/\]						;
        Factor     <\- Term \(AddOp Term\)\*				;
        AddOp      <\- \[\-\+\]						;
        Term       <\- Number					;
    END;

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.








|

|
|

|

|
|
|
|
|
|
|
|








|
|
|
|

|
|

|
|

|
|
|



|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|






|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|







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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe-grammar-for-peg (Grammar)

    	# --------------------------------------------------------------------
            # Syntactical constructs

            Grammar         <- WHITESPACE Header Definition* Final EOF ;

            Header          <- PEG Identifier StartExpr ;
            Definition      <- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <- (VOID / LEAF) COLON ;
            Expression      <- Sequence (SLASH Sequence)* ;
            Sequence        <- Prefix+ ;
            Prefix          <- (AND / NOT)? Suffix ;
            Suffix          <- Primary (QUESTION / STAR / PLUS)? ;
            Primary         <- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH WHITESPACE ;
            Class           <- OPENB (!CLOSEB Range)* CLOSEB WHITESPACE ;
            Range           <- Char TO Char / Char ;

            StartExpr       <- OPEN Expression CLOSE ;
    void:   Final           <- "END" WHITESPACE SEMICOLON WHITESPACE ;

            # --------------------------------------------------------------------
            # Lexing constructs

            Identifier      <- Ident WHITESPACE ;
    leaf:   Ident           <- ([_:] / <alpha>) ([_:] / <alnum>)* ;
            Char            <- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <- "\\" [nrt'"\[\]\\] ;
    leaf:   CharOctalFull   <- "\\" [0-2][0-7][0-7] ;
    leaf:   CharOctalPart   <- "\\" [0-7][0-7]? ;
    leaf:   CharUnicode     <- "\\" 'u' HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
    leaf:   CharUnescaped   <- !"\\" . ;

    void:   HexDigit        <- [0-9a-fA-F] ;

    void:   TO              <- '-'           ;
    void:   OPENB           <- "["           ;
    void:   CLOSEB          <- "]"           ;
    void:   APOSTROPH       <- "'"           ;
    void:   DAPOSTROPH      <- '"'           ;
    void:   PEG             <- "PEG" !([_:] / <alnum>) WHITESPACE ;
    void:   IS              <- "<-"    WHITESPACE ;
    leaf:   VOID            <- "void"  WHITESPACE ; # Implies that definition has no semantic value.
    leaf:   LEAF            <- "leaf"  WHITESPACE ; # Implies that definition has no terminals.
    void:   SEMICOLON       <- ";"     WHITESPACE ;
    void:   COLON           <- ":"     WHITESPACE ;
    void:   SLASH           <- "/"     WHITESPACE ;
    leaf:   AND             <- "&"     WHITESPACE ;
    leaf:   NOT             <- "!"     WHITESPACE ;
    leaf:   QUESTION        <- "?"     WHITESPACE ;
    leaf:   STAR            <- "*"     WHITESPACE ;
    leaf:   PLUS            <- "+"     WHITESPACE ;
    void:   OPEN            <- "("     WHITESPACE ;
    void:   CLOSE           <- ")"     WHITESPACE ;
    leaf:   DOT             <- "."     WHITESPACE ;

    leaf:   ALNUM           <- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <- "<space>"    WHITESPACE ;
    leaf:   UPPER           <- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <- (" " / "\t" / EOL / COMMENT)* ;
    void:   COMMENT         <- '#' (!EOL .)* EOL ;
    void:   EOL             <- "\n\r" / "\n" / "\r" ;
    void:   EOF             <- !. ;

            # --------------------------------------------------------------------
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator (Expression)
        Sign       <- [-+] 						;
        Number     <- Sign? <ddigit>+				;
        Expression <- '(' Expression ')' / (Factor (MulOp Factor)*)	;
        MulOp      <- [*/]						;
        Factor     <- Term (AddOp Term)*				;
        AddOp      <- [-+]						;
        Term       <- Number					;
    END;

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_from_json.md.
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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

a JSON serialization for it is

    \{

        "pt::grammar::peg" : \{
            "rules" : \{
                "AddOp"     : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Digit"     : \{
                    "is"   : "\\/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}",
                    "mode" : "value"
                \},
                "Expression" : \{
                    "is"   : "\\/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}",
                    "mode" : "value"
                \},
                "Factor"    : \{
                    "is"   : "x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}",
                    "mode" : "value"
                \},
                "MulOp"     : \{
                    "is"   : "\\/ \{t \*\} \{t \\/\}",
                    "mode" : "value"
                \},
                "Number"    : \{
                    "is"   : "x \{? \{n Sign\}\} \{\+ \{n Digit\}\}",
                    "mode" : "value"
                \},
                "Sign"      : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Term"      : \{
                    "is"   : "n Number",
                    "mode" : "value"
                \}

            \},
            "start" : "n Expression"
        \}
    \}



and a Tcl serialization of the same is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


The similarity of the latter to the JSON should be quite obvious\.

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.







|
|
|
|
|
|
|
|
|




<
>
|
|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|


<
>
|

<
<
|
>
>


|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

a JSON serialization for it is


    {
        "pt::grammar::peg" : {
            "rules" : {
                "AddOp"     : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Digit"     : {
                    "is"   : "\/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}",
                    "mode" : "value"
                },
                "Expression" : {
                    "is"   : "\/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}",
                    "mode" : "value"
                },
                "Factor"    : {
                    "is"   : "x {n Term} {* {x {n AddOp} {n Term}}}",
                    "mode" : "value"
                },
                "MulOp"     : {
                    "is"   : "\/ {t *} {t \/}",
                    "mode" : "value"
                },
                "Number"    : {
                    "is"   : "x {? {n Sign}} {+ {n Digit}}",
                    "mode" : "value"
                },
                "Sign"      : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Term"      : {
                    "is"   : "n Number",
                    "mode" : "value"

                }
            },
            "start" : "n Expression"


        }
    }

and a Tcl serialization of the same is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

The similarity of the latter to the JSON should be quite obvious\.

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_from_peg.md.
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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe\-grammar\-for\-peg \(Grammar\)

    	\# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Syntactical constructs

            Grammar         <\- WHITESPACE Header Definition\* Final EOF ;

            Header          <\- PEG Identifier StartExpr ;
            Definition      <\- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <\- \(VOID / LEAF\) COLON ;
            Expression      <\- Sequence \(SLASH Sequence\)\* ;
            Sequence        <\- Prefix\+ ;
            Prefix          <\- \(AND / NOT\)? Suffix ;
            Suffix          <\- Primary \(QUESTION / STAR / PLUS\)? ;
            Primary         <\- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <\- APOSTROPH  \(\!APOSTROPH  Char\)\* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH \(\!DAPOSTROPH Char\)\* DAPOSTROPH WHITESPACE ;
            Class           <\- OPENB \(\!CLOSEB Range\)\* CLOSEB WHITESPACE ;
            Range           <\- Char TO Char / Char ;

            StartExpr       <\- OPEN Expression CLOSE ;
    void:   Final           <\- "END" WHITESPACE SEMICOLON WHITESPACE ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Lexing constructs

            Identifier      <\- Ident WHITESPACE ;
    leaf:   Ident           <\- \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\* ;
            Char            <\- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <\- "\\\\" \[nrt'"\\\[\\\]\\\\\] ;
    leaf:   CharOctalFull   <\- "\\\\" \[0\-2\]\[0\-7\]\[0\-7\] ;
    leaf:   CharOctalPart   <\- "\\\\" \[0\-7\]\[0\-7\]? ;
    leaf:   CharUnicode     <\- "\\\\" 'u' HexDigit \(HexDigit \(HexDigit HexDigit?\)?\)? ;
    leaf:   CharUnescaped   <\- \!"\\\\" \. ;

    void:   HexDigit        <\- \[0\-9a\-fA\-F\] ;

    void:   TO              <\- '\-'           ;
    void:   OPENB           <\- "\["           ;
    void:   CLOSEB          <\- "\]"           ;
    void:   APOSTROPH       <\- "'"           ;
    void:   DAPOSTROPH      <\- '"'           ;
    void:   PEG             <\- "PEG" \!\(\[\_:\] / <alnum>\) WHITESPACE ;
    void:   IS              <\- "<\-"    WHITESPACE ;
    leaf:   VOID            <\- "void"  WHITESPACE ; \# Implies that definition has no semantic value\.
    leaf:   LEAF            <\- "leaf"  WHITESPACE ; \# Implies that definition has no terminals\.
    void:   SEMICOLON       <\- ";"     WHITESPACE ;
    void:   COLON           <\- ":"     WHITESPACE ;
    void:   SLASH           <\- "/"     WHITESPACE ;
    leaf:   AND             <\- "&"     WHITESPACE ;
    leaf:   NOT             <\- "\!"     WHITESPACE ;
    leaf:   QUESTION        <\- "?"     WHITESPACE ;
    leaf:   STAR            <\- "\*"     WHITESPACE ;
    leaf:   PLUS            <\- "\+"     WHITESPACE ;
    void:   OPEN            <\- "\("     WHITESPACE ;
    void:   CLOSE           <\- "\)"     WHITESPACE ;
    leaf:   DOT             <\- "\."     WHITESPACE ;

    leaf:   ALNUM           <\- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <\- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <\- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <\- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <\- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <\- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <\- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <\- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <\- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <\- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <\- "<space>"    WHITESPACE ;
    leaf:   UPPER           <\- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <\- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <\- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <\- \(" " / "\\t" / EOL / COMMENT\)\* ;
    void:   COMMENT         <\- '\#' \(\!EOL \.\)\* EOL ;
    void:   EOL             <\- "\\n\\r" / "\\n" / "\\r" ;
    void:   EOF             <\- \!\. ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator \(Expression\)
        Sign       <\- \[\-\+\] 						;
        Number     <\- Sign? <ddigit>\+				;
        Expression <\- '\(' Expression '\)' / \(Factor \(MulOp Factor\)\*\)	;
        MulOp      <\- \[\*/\]						;
        Factor     <\- Term \(AddOp Term\)\*				;
        AddOp      <\- \[\-\+\]						;
        Term       <\- Number					;
    END;

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.








|

|
|

|

|
|
|
|
|
|
|
|








|
|
|
|

|
|

|
|

|
|
|



|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|






|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|







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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe-grammar-for-peg (Grammar)

    	# --------------------------------------------------------------------
            # Syntactical constructs

            Grammar         <- WHITESPACE Header Definition* Final EOF ;

            Header          <- PEG Identifier StartExpr ;
            Definition      <- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <- (VOID / LEAF) COLON ;
            Expression      <- Sequence (SLASH Sequence)* ;
            Sequence        <- Prefix+ ;
            Prefix          <- (AND / NOT)? Suffix ;
            Suffix          <- Primary (QUESTION / STAR / PLUS)? ;
            Primary         <- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH WHITESPACE ;
            Class           <- OPENB (!CLOSEB Range)* CLOSEB WHITESPACE ;
            Range           <- Char TO Char / Char ;

            StartExpr       <- OPEN Expression CLOSE ;
    void:   Final           <- "END" WHITESPACE SEMICOLON WHITESPACE ;

            # --------------------------------------------------------------------
            # Lexing constructs

            Identifier      <- Ident WHITESPACE ;
    leaf:   Ident           <- ([_:] / <alpha>) ([_:] / <alnum>)* ;
            Char            <- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <- "\\" [nrt'"\[\]\\] ;
    leaf:   CharOctalFull   <- "\\" [0-2][0-7][0-7] ;
    leaf:   CharOctalPart   <- "\\" [0-7][0-7]? ;
    leaf:   CharUnicode     <- "\\" 'u' HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
    leaf:   CharUnescaped   <- !"\\" . ;

    void:   HexDigit        <- [0-9a-fA-F] ;

    void:   TO              <- '-'           ;
    void:   OPENB           <- "["           ;
    void:   CLOSEB          <- "]"           ;
    void:   APOSTROPH       <- "'"           ;
    void:   DAPOSTROPH      <- '"'           ;
    void:   PEG             <- "PEG" !([_:] / <alnum>) WHITESPACE ;
    void:   IS              <- "<-"    WHITESPACE ;
    leaf:   VOID            <- "void"  WHITESPACE ; # Implies that definition has no semantic value.
    leaf:   LEAF            <- "leaf"  WHITESPACE ; # Implies that definition has no terminals.
    void:   SEMICOLON       <- ";"     WHITESPACE ;
    void:   COLON           <- ":"     WHITESPACE ;
    void:   SLASH           <- "/"     WHITESPACE ;
    leaf:   AND             <- "&"     WHITESPACE ;
    leaf:   NOT             <- "!"     WHITESPACE ;
    leaf:   QUESTION        <- "?"     WHITESPACE ;
    leaf:   STAR            <- "*"     WHITESPACE ;
    leaf:   PLUS            <- "+"     WHITESPACE ;
    void:   OPEN            <- "("     WHITESPACE ;
    void:   CLOSE           <- ")"     WHITESPACE ;
    leaf:   DOT             <- "."     WHITESPACE ;

    leaf:   ALNUM           <- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <- "<space>"    WHITESPACE ;
    leaf:   UPPER           <- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <- (" " / "\t" / EOL / COMMENT)* ;
    void:   COMMENT         <- '#' (!EOL .)* EOL ;
    void:   EOL             <- "\n\r" / "\n" / "\r" ;
    void:   EOF             <- !. ;

            # --------------------------------------------------------------------
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator (Expression)
        Sign       <- [-+] 						;
        Number     <- Sign? <ddigit>+				;
        Expression <- '(' Expression ')' / (Factor (MulOp Factor)*)	;
        MulOp      <- [*/]						;
        Factor     <- Term (AddOp Term)*				;
        AddOp      <- [-+]						;
        Term       <- Number					;
    END;

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_import.md.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection4'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section4'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection4'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section4'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection5'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection5'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_import_json.md.
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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

a JSON serialization for it is

    \{

        "pt::grammar::peg" : \{
            "rules" : \{
                "AddOp"     : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Digit"     : \{
                    "is"   : "\\/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}",
                    "mode" : "value"
                \},
                "Expression" : \{
                    "is"   : "\\/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}",
                    "mode" : "value"
                \},
                "Factor"    : \{
                    "is"   : "x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}",
                    "mode" : "value"
                \},
                "MulOp"     : \{
                    "is"   : "\\/ \{t \*\} \{t \\/\}",
                    "mode" : "value"
                \},
                "Number"    : \{
                    "is"   : "x \{? \{n Sign\}\} \{\+ \{n Digit\}\}",
                    "mode" : "value"
                \},
                "Sign"      : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Term"      : \{
                    "is"   : "n Number",
                    "mode" : "value"
                \}

            \},
            "start" : "n Expression"
        \}
    \}



and a Tcl serialization of the same is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


The similarity of the latter to the JSON should be quite obvious\.

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.







|
|
|
|
|
|
|
|
|




<
>
|
|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|


<
>
|

<
<
|
>
>


|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

a JSON serialization for it is


    {
        "pt::grammar::peg" : {
            "rules" : {
                "AddOp"     : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Digit"     : {
                    "is"   : "\/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}",
                    "mode" : "value"
                },
                "Expression" : {
                    "is"   : "\/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}",
                    "mode" : "value"
                },
                "Factor"    : {
                    "is"   : "x {n Term} {* {x {n AddOp} {n Term}}}",
                    "mode" : "value"
                },
                "MulOp"     : {
                    "is"   : "\/ {t *} {t \/}",
                    "mode" : "value"
                },
                "Number"    : {
                    "is"   : "x {? {n Sign}} {+ {n Digit}}",
                    "mode" : "value"
                },
                "Sign"      : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Term"      : {
                    "is"   : "n Number",
                    "mode" : "value"

                }
            },
            "start" : "n Expression"


        }
    }

and a Tcl serialization of the same is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

The similarity of the latter to the JSON should be quite obvious\.

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_import_peg.md.
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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe\-grammar\-for\-peg \(Grammar\)

    	\# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Syntactical constructs

            Grammar         <\- WHITESPACE Header Definition\* Final EOF ;

            Header          <\- PEG Identifier StartExpr ;
            Definition      <\- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <\- \(VOID / LEAF\) COLON ;
            Expression      <\- Sequence \(SLASH Sequence\)\* ;
            Sequence        <\- Prefix\+ ;
            Prefix          <\- \(AND / NOT\)? Suffix ;
            Suffix          <\- Primary \(QUESTION / STAR / PLUS\)? ;
            Primary         <\- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <\- APOSTROPH  \(\!APOSTROPH  Char\)\* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH \(\!DAPOSTROPH Char\)\* DAPOSTROPH WHITESPACE ;
            Class           <\- OPENB \(\!CLOSEB Range\)\* CLOSEB WHITESPACE ;
            Range           <\- Char TO Char / Char ;

            StartExpr       <\- OPEN Expression CLOSE ;
    void:   Final           <\- "END" WHITESPACE SEMICOLON WHITESPACE ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Lexing constructs

            Identifier      <\- Ident WHITESPACE ;
    leaf:   Ident           <\- \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\* ;
            Char            <\- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <\- "\\\\" \[nrt'"\\\[\\\]\\\\\] ;
    leaf:   CharOctalFull   <\- "\\\\" \[0\-2\]\[0\-7\]\[0\-7\] ;
    leaf:   CharOctalPart   <\- "\\\\" \[0\-7\]\[0\-7\]? ;
    leaf:   CharUnicode     <\- "\\\\" 'u' HexDigit \(HexDigit \(HexDigit HexDigit?\)?\)? ;
    leaf:   CharUnescaped   <\- \!"\\\\" \. ;

    void:   HexDigit        <\- \[0\-9a\-fA\-F\] ;

    void:   TO              <\- '\-'           ;
    void:   OPENB           <\- "\["           ;
    void:   CLOSEB          <\- "\]"           ;
    void:   APOSTROPH       <\- "'"           ;
    void:   DAPOSTROPH      <\- '"'           ;
    void:   PEG             <\- "PEG" \!\(\[\_:\] / <alnum>\) WHITESPACE ;
    void:   IS              <\- "<\-"    WHITESPACE ;
    leaf:   VOID            <\- "void"  WHITESPACE ; \# Implies that definition has no semantic value\.
    leaf:   LEAF            <\- "leaf"  WHITESPACE ; \# Implies that definition has no terminals\.
    void:   SEMICOLON       <\- ";"     WHITESPACE ;
    void:   COLON           <\- ":"     WHITESPACE ;
    void:   SLASH           <\- "/"     WHITESPACE ;
    leaf:   AND             <\- "&"     WHITESPACE ;
    leaf:   NOT             <\- "\!"     WHITESPACE ;
    leaf:   QUESTION        <\- "?"     WHITESPACE ;
    leaf:   STAR            <\- "\*"     WHITESPACE ;
    leaf:   PLUS            <\- "\+"     WHITESPACE ;
    void:   OPEN            <\- "\("     WHITESPACE ;
    void:   CLOSE           <\- "\)"     WHITESPACE ;
    leaf:   DOT             <\- "\."     WHITESPACE ;

    leaf:   ALNUM           <\- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <\- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <\- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <\- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <\- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <\- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <\- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <\- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <\- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <\- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <\- "<space>"    WHITESPACE ;
    leaf:   UPPER           <\- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <\- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <\- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <\- \(" " / "\\t" / EOL / COMMENT\)\* ;
    void:   COMMENT         <\- '\#' \(\!EOL \.\)\* EOL ;
    void:   EOL             <\- "\\n\\r" / "\\n" / "\\r" ;
    void:   EOF             <\- \!\. ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator \(Expression\)
        Sign       <\- \[\-\+\] 						;
        Number     <\- Sign? <ddigit>\+				;
        Expression <\- '\(' Expression '\)' / \(Factor \(MulOp Factor\)\*\)	;
        MulOp      <\- \[\*/\]						;
        Factor     <\- Term \(AddOp Term\)\*				;
        AddOp      <\- \[\-\+\]						;
        Term       <\- Number					;
    END;

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.








|

|
|

|

|
|
|
|
|
|
|
|








|
|
|
|

|
|

|
|

|
|
|



|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|






|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|







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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe-grammar-for-peg (Grammar)

    	# --------------------------------------------------------------------
            # Syntactical constructs

            Grammar         <- WHITESPACE Header Definition* Final EOF ;

            Header          <- PEG Identifier StartExpr ;
            Definition      <- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <- (VOID / LEAF) COLON ;
            Expression      <- Sequence (SLASH Sequence)* ;
            Sequence        <- Prefix+ ;
            Prefix          <- (AND / NOT)? Suffix ;
            Suffix          <- Primary (QUESTION / STAR / PLUS)? ;
            Primary         <- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH WHITESPACE ;
            Class           <- OPENB (!CLOSEB Range)* CLOSEB WHITESPACE ;
            Range           <- Char TO Char / Char ;

            StartExpr       <- OPEN Expression CLOSE ;
    void:   Final           <- "END" WHITESPACE SEMICOLON WHITESPACE ;

            # --------------------------------------------------------------------
            # Lexing constructs

            Identifier      <- Ident WHITESPACE ;
    leaf:   Ident           <- ([_:] / <alpha>) ([_:] / <alnum>)* ;
            Char            <- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <- "\\" [nrt'"\[\]\\] ;
    leaf:   CharOctalFull   <- "\\" [0-2][0-7][0-7] ;
    leaf:   CharOctalPart   <- "\\" [0-7][0-7]? ;
    leaf:   CharUnicode     <- "\\" 'u' HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
    leaf:   CharUnescaped   <- !"\\" . ;

    void:   HexDigit        <- [0-9a-fA-F] ;

    void:   TO              <- '-'           ;
    void:   OPENB           <- "["           ;
    void:   CLOSEB          <- "]"           ;
    void:   APOSTROPH       <- "'"           ;
    void:   DAPOSTROPH      <- '"'           ;
    void:   PEG             <- "PEG" !([_:] / <alnum>) WHITESPACE ;
    void:   IS              <- "<-"    WHITESPACE ;
    leaf:   VOID            <- "void"  WHITESPACE ; # Implies that definition has no semantic value.
    leaf:   LEAF            <- "leaf"  WHITESPACE ; # Implies that definition has no terminals.
    void:   SEMICOLON       <- ";"     WHITESPACE ;
    void:   COLON           <- ":"     WHITESPACE ;
    void:   SLASH           <- "/"     WHITESPACE ;
    leaf:   AND             <- "&"     WHITESPACE ;
    leaf:   NOT             <- "!"     WHITESPACE ;
    leaf:   QUESTION        <- "?"     WHITESPACE ;
    leaf:   STAR            <- "*"     WHITESPACE ;
    leaf:   PLUS            <- "+"     WHITESPACE ;
    void:   OPEN            <- "("     WHITESPACE ;
    void:   CLOSE           <- ")"     WHITESPACE ;
    leaf:   DOT             <- "."     WHITESPACE ;

    leaf:   ALNUM           <- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <- "<space>"    WHITESPACE ;
    leaf:   UPPER           <- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <- (" " / "\t" / EOL / COMMENT)* ;
    void:   COMMENT         <- '#' (!EOL .)* EOL ;
    void:   EOL             <- "\n\r" / "\n" / "\r" ;
    void:   EOF             <- !. ;

            # --------------------------------------------------------------------
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator (Expression)
        Sign       <- [-+] 						;
        Number     <- Sign? <ddigit>+				;
        Expression <- '(' Expression ')' / (Factor (MulOp Factor)*)	;
        MulOp      <- [*/]						;
        Factor     <- Term (AddOp Term)*				;
        AddOp      <- [-+]						;
        Term       <- Number					;
    END;

# <a name='section4'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section5'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_interp.md.
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
      1. The string representation of the value is the canonical representation
         of a pure Tcl list\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection3'></a>Example

Assuming the parsing expression grammar below

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

and the input string

    120\+5

then a parser should deliver the abstract syntax tree below \(except for
whitespace\)

    set ast \{Expression 0 4
        \{Factor 0 4
            \{Term 0 2
                \{Number 0 2
                    \{Digit 0 0\}
                    \{Digit 1 1\}
                    \{Digit 2 2\}
                \}
            \}


            \{AddOp 3 3\}
            \{Term 4 4
                \{Number 4 4
                    \{Digit 4 4\}
                \}
            \}
        \}
    \}





Or, more graphical

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png)

# <a name='section3'></a>PE serialization format








|
|
|
|
|
|
|
|
|




|




|
|
|
|
|
|
|
<
<
>
>
|
|
|
|
<
<
<
<
>
>
>
>







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
      1. The string representation of the value is the canonical representation
         of a pure Tcl list\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection3'></a>Example

Assuming the parsing expression grammar below

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

and the input string

    120+5

then a parser should deliver the abstract syntax tree below \(except for
whitespace\)

    set ast {Expression 0 4
        {Factor 0 4
            {Term 0 2
                {Number 0 2
                    {Digit 0 0}
                    {Digit 1 1}
                    {Digit 2 2}


                }
            }
            {AddOp 3 3}
            {Term 4 4
                {Number 4 4
                    {Digit 4 4}




                }
            }
        }
    }

Or, more graphical

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png)

# <a name='section3'></a>PE serialization format

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection4'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection4'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_language.md.
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

# <a name='section3'></a>The elements of the language

## <a name='subsection1'></a>Basic structure

The general outline of a textual PEG is

    PEG <<name>> \(<<start\-expression>>\)
       <<rules>>
    END;

*Note*: We are using text in double angle\-brackets as place\-holders for things
not yet explained\.

## <a name='subsection2'></a>Names







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

# <a name='section3'></a>The elements of the language

## <a name='subsection1'></a>Basic structure

The general outline of a textual PEG is

    PEG <<name>> (<<start-expression>>)
       <<rules>>
    END;

*Note*: We are using text in double angle\-brackets as place\-holders for things
not yet explained\.

## <a name='subsection2'></a>Names
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

  1. It begins with a letter, underscore, or colon, followed by

  1. zero or more letters, digits, underscores, or colons\.

Or, in formal textual notation:

    \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\*

Examples of names:

    Hello
    ::world
    \_:submarine55\_

Examples of text which are *not* names:

    12
    \.bogus
    0wrong
    @location

## <a name='subsection3'></a>Rules

The main body of the text of a grammar specification is taken up by the rules\.
Each rule defines the sentence structure of one nonterminal symbol\. Their basic
structure is

    <<name>>  <\-  <<expression>> ;

The <name> specifies the nonterminal symbol to be defined, the <expression>
after the arrow \(<\-\) then declares its structure\.

Note that each rule ends in a single semicolon, even the last\. I\.e\. the
semicolon is a rule *terminator*, not a separator\.








|





|




|









|







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

  1. It begins with a letter, underscore, or colon, followed by

  1. zero or more letters, digits, underscores, or colons\.

Or, in formal textual notation:

    ([_:] / <alpha>) ([_:] / <alnum>)*

Examples of names:

    Hello
    ::world
    _:submarine55_

Examples of text which are *not* names:

    12
    .bogus
    0wrong
    @location

## <a name='subsection3'></a>Rules

The main body of the text of a grammar specification is taken up by the rules\.
Each rule defines the sentence structure of one nonterminal symbol\. Their basic
structure is

    <<name>>  <-  <<expression>> ;

The <name> specifies the nonterminal symbol to be defined, the <expression>
after the arrow \(<\-\) then declares its structure\.

Note that each rule ends in a single semicolon, even the last\. I\.e\. the
semicolon is a rule *terminator*, not a separator\.

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
of parts, and for look\-ahead constraints\. There is no explicit operator for the
sequencing \(also known as *concatenation*\) of parts however\. This is specified
by simply placing the parts adjacent to each other\.

Here are the operators, from highest to lowest priority \(i\.e\. strength of
binding\):

    \# Binary operators\.

    <<expression\-1>>     <<expression\-2>>  \# sequence\. parse 1, then 2\.
    <<expression\-1>>  /  <<expression\-2>>  \# alternative\. try to parse 1, and parse 2 if 1 failed to parse\.

    \# Prefix operators\. Lookahead constraints\. Same priority\.

    & <<expression>>  \# Parse expression, ok on successful parse\.
    \! <<expression>>  \# Ditto, except ok on failure to parse\.

    \# Suffix operators\. Repetition\. Same priority\.

    <<expression>> ?  \# Parse expression none, or once \(repeat 0 or 1\)\.
    <<expression>> \*  \# Parse expression zero or more times\.
    <<expression>> \+  \# Parse expression one or more times\.

    \# Expression nesting

    \( <<expression>> \) \# Put an expression in parens to change its priority\.

With this we can now deconstruct the formal expression for names given in
section [Names](#subsection2):

    \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\*

It is a sequence of two parts,

    \[\_:\] / <alpha>

and

    \(\[\_:\] / <alnum>\)\*

The parentheses around the parts kept their inner alternatives bound together
against the normally higher priority of the sequence\. Each of the two parts is
an alternative, with the second part additionally repeated zero or more times,
leaving us with the three atomic expressions

    \[\_:\]
    <alpha>
    <alnum>

And *atomic expressions* are our next topic\. They fall into three classes:

  1. names, i\.e\. nonterminal symbols,








|

|
|

|

|
|

|

|
|
|

|

|




|



|



|






|







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
of parts, and for look\-ahead constraints\. There is no explicit operator for the
sequencing \(also known as *concatenation*\) of parts however\. This is specified
by simply placing the parts adjacent to each other\.

Here are the operators, from highest to lowest priority \(i\.e\. strength of
binding\):

    # Binary operators.

    <<expression-1>>     <<expression-2>>  # sequence. parse 1, then 2.
    <<expression-1>>  /  <<expression-2>>  # alternative. try to parse 1, and parse 2 if 1 failed to parse.

    # Prefix operators. Lookahead constraints. Same priority.

    & <<expression>>  # Parse expression, ok on successful parse.
    ! <<expression>>  # Ditto, except ok on failure to parse.

    # Suffix operators. Repetition. Same priority.

    <<expression>> ?  # Parse expression none, or once (repeat 0 or 1).
    <<expression>> *  # Parse expression zero or more times.
    <<expression>> +  # Parse expression one or more times.

    # Expression nesting

    ( <<expression>> ) # Put an expression in parens to change its priority.

With this we can now deconstruct the formal expression for names given in
section [Names](#subsection2):

    ([_:] / <alpha>) ([_:] / <alnum>)*

It is a sequence of two parts,

    [_:] / <alpha>

and

    ([_:] / <alnum>)*

The parentheses around the parts kept their inner alternatives bound together
against the normally higher priority of the sequence\. Each of the two parts is
an alternative, with the second part additionally repeated zero or more times,
leaving us with the three atomic expressions

    [_:]
    <alpha>
    <alnum>

And *atomic expressions* are our next topic\. They fall into three classes:

  1. names, i\.e\. nonterminal symbols,

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

The last two examples show how to place any of the delimiters into a string\.

For the last, but not least of our atomic expressions, character classes, we
have a number of predefined classes, shown below, and the ability to construct
or own\. The predefined classes are:

    <alnum>    \# Any unicode alphabet or digit character \(string is alnum\)\.
    <alpha>    \# Any unicode alphabet character \(string is alpha\)\.
    <ascii>    \# Any unicode character below codepoint 0x80 \(string is ascii\)\.
    <control>  \# Any unicode control character \(string is control\)\.
    <ddigit>   \# The digit characters \[0\-9\]\.
    <digit>    \# Any unicode digit character \(string is digit\)\.
    <graph>    \# Any unicode printing character, except space \(string is graph\)\.
    <lower>    \# Any unicode lower\-case alphabet character \(string is lower\)\.
    <print>    \# Any unicode printing character, incl\. space \(string is print\)\.
    <punct>    \# Any unicode punctuation character \(string is punct\)\.
    <space>    \# Any unicode space character \(string is space\)\.
    <upper>    \# Any unicode upper\-case alphabet character \(string is upper\)\.
    <wordchar> \# Any unicode word character \(string is wordchar\)\.
    <xdigit>   \# The hexadecimal digit characters \[0\-9a\-fA\-F\]\.
    \.          \# Any character, except end of input\.

And the syntax of custom\-defined character classes is

    \[ <<range>>\* \]

where each range is either a single character, or of the form

    <<character>> \- <character>>

Examples for character classes we have seen already in the course of this
introduction are

    \[\_:\]
    \[0\-9\]
    \[0\-9a\-fA\-F\]

We are nearly done with expressions\. The only piece left is to tell how the
characters in character classes and string literals are specified\.

Basically characters in the input stand for themselves, and in addition to that
we several types of escape syntax to to repesent control characters, or
characters outside of the encoding the text is in\.

All the escaped forms are started with a backslash character \('\\', unicode
codepoint 0x5C\)\. This is then followed by a series of octal digits, or 'u' and
hexedecimal digits, or a regular character from a fixed set for various control
characters\. Some examples:

    \\n \\r \\t \\' \\" \\\[ \\\] \\\\ \#
    \\000 up to \\277         \# octal escape, all ascii character, leading 0's can be removed\.
    \\u2CA7                  \# hexadecimal escape, all unicode characters\.
    \#                       \# Here 2ca7 <=> Koptic Small Letter Tau

## <a name='subsection5'></a>Whitespace and comments

One issue not touched upon so far is whitespace and comments\.

Whitespace is any unicode space character, i\.e\. anything in the character class
<space>, and comments\. The latter are sequences of characters starting with a
'\#' \(hash, unicode codepoint 0x23\) and ending at the next end\-of\-line\.

Whitespace can be freely used between all syntactical elements of a grammar
specification\. It cannot be used inside of syntactical elements, like names,
string literals, predefined character classes, etc\.

## <a name='subsection6'></a>Nonterminal attributes

Lastly, a more advanced topic\. In the section [Rules](#subsection3) we gave
the structure of a rule as

    <<name>>  <\-  <<expression>> ;

This is not quite true\. It is possible to associate a semantic mode with the
nonterminal in the rule, by writing it before the name, separated from it by a
colon, i\.e\. writing

    <<mode>> : <<name>>  <\-  <<expression>> ;

is also allowed\. This mode is optional\. The known modes and their meanings are:

  - __value__

    The semantic value of the nonterminal symbol is an abstract syntax tree
    consisting of a single node node for the nonterminal itself, which has the







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



|



|




|
|
|













|
|
|
|


















|





|







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

The last two examples show how to place any of the delimiters into a string\.

For the last, but not least of our atomic expressions, character classes, we
have a number of predefined classes, shown below, and the ability to construct
or own\. The predefined classes are:

    <alnum>    # Any unicode alphabet or digit character (string is alnum).
    <alpha>    # Any unicode alphabet character (string is alpha).
    <ascii>    # Any unicode character below codepoint 0x80 (string is ascii).
    <control>  # Any unicode control character (string is control).
    <ddigit>   # The digit characters [0-9].
    <digit>    # Any unicode digit character (string is digit).
    <graph>    # Any unicode printing character, except space (string is graph).
    <lower>    # Any unicode lower-case alphabet character (string is lower).
    <print>    # Any unicode printing character, incl. space (string is print).
    <punct>    # Any unicode punctuation character (string is punct).
    <space>    # Any unicode space character (string is space).
    <upper>    # Any unicode upper-case alphabet character (string is upper).
    <wordchar> # Any unicode word character (string is wordchar).
    <xdigit>   # The hexadecimal digit characters [0-9a-fA-F].
    .          # Any character, except end of input.

And the syntax of custom\-defined character classes is

    [ <<range>>* ]

where each range is either a single character, or of the form

    <<character>> - <character>>

Examples for character classes we have seen already in the course of this
introduction are

    [_:]
    [0-9]
    [0-9a-fA-F]

We are nearly done with expressions\. The only piece left is to tell how the
characters in character classes and string literals are specified\.

Basically characters in the input stand for themselves, and in addition to that
we several types of escape syntax to to repesent control characters, or
characters outside of the encoding the text is in\.

All the escaped forms are started with a backslash character \('\\', unicode
codepoint 0x5C\)\. This is then followed by a series of octal digits, or 'u' and
hexedecimal digits, or a regular character from a fixed set for various control
characters\. Some examples:

    \n \r \t \' \" \[ \] \\ #
    \000 up to \277         # octal escape, all ascii character, leading 0's can be removed.
    \u2CA7                  # hexadecimal escape, all unicode characters.
    #                       # Here 2ca7 <=> Koptic Small Letter Tau

## <a name='subsection5'></a>Whitespace and comments

One issue not touched upon so far is whitespace and comments\.

Whitespace is any unicode space character, i\.e\. anything in the character class
<space>, and comments\. The latter are sequences of characters starting with a
'\#' \(hash, unicode codepoint 0x23\) and ending at the next end\-of\-line\.

Whitespace can be freely used between all syntactical elements of a grammar
specification\. It cannot be used inside of syntactical elements, like names,
string literals, predefined character classes, etc\.

## <a name='subsection6'></a>Nonterminal attributes

Lastly, a more advanced topic\. In the section [Rules](#subsection3) we gave
the structure of a rule as

    <<name>>  <-  <<expression>> ;

This is not quite true\. It is possible to associate a semantic mode with the
nonterminal in the rule, by writing it before the name, separated from it by a
colon, i\.e\. writing

    <<mode>> : <<name>>  <-  <<expression>> ;

is also allowed\. This mode is optional\. The known modes and their meanings are:

  - __value__

    The semantic value of the nonterminal symbol is an abstract syntax tree
    consisting of a single node node for the nonterminal itself, which has the
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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *PEG Language
Tutorial*\.

    PEG pe\-grammar\-for\-peg \(Grammar\)

    	\# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Syntactical constructs

            Grammar         <\- WHITESPACE Header Definition\* Final EOF ;

            Header          <\- PEG Identifier StartExpr ;
            Definition      <\- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <\- \(VOID / LEAF\) COLON ;
            Expression      <\- Sequence \(SLASH Sequence\)\* ;
            Sequence        <\- Prefix\+ ;
            Prefix          <\- \(AND / NOT\)? Suffix ;
            Suffix          <\- Primary \(QUESTION / STAR / PLUS\)? ;
            Primary         <\- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <\- APOSTROPH  \(\!APOSTROPH  Char\)\* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH \(\!DAPOSTROPH Char\)\* DAPOSTROPH WHITESPACE ;
            Class           <\- OPENB \(\!CLOSEB Range\)\* CLOSEB WHITESPACE ;
            Range           <\- Char TO Char / Char ;

            StartExpr       <\- OPEN Expression CLOSE ;
    void:   Final           <\- "END" WHITESPACE SEMICOLON WHITESPACE ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Lexing constructs

            Identifier      <\- Ident WHITESPACE ;
    leaf:   Ident           <\- \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\* ;
            Char            <\- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <\- "\\\\" \[nrt'"\\\[\\\]\\\\\] ;
    leaf:   CharOctalFull   <\- "\\\\" \[0\-2\]\[0\-7\]\[0\-7\] ;
    leaf:   CharOctalPart   <\- "\\\\" \[0\-7\]\[0\-7\]? ;
    leaf:   CharUnicode     <\- "\\\\" 'u' HexDigit \(HexDigit \(HexDigit HexDigit?\)?\)? ;
    leaf:   CharUnescaped   <\- \!"\\\\" \. ;

    void:   HexDigit        <\- \[0\-9a\-fA\-F\] ;

    void:   TO              <\- '\-'           ;
    void:   OPENB           <\- "\["           ;
    void:   CLOSEB          <\- "\]"           ;
    void:   APOSTROPH       <\- "'"           ;
    void:   DAPOSTROPH      <\- '"'           ;
    void:   PEG             <\- "PEG" \!\(\[\_:\] / <alnum>\) WHITESPACE ;
    void:   IS              <\- "<\-"    WHITESPACE ;
    leaf:   VOID            <\- "void"  WHITESPACE ; \# Implies that definition has no semantic value\.
    leaf:   LEAF            <\- "leaf"  WHITESPACE ; \# Implies that definition has no terminals\.
    void:   SEMICOLON       <\- ";"     WHITESPACE ;
    void:   COLON           <\- ":"     WHITESPACE ;
    void:   SLASH           <\- "/"     WHITESPACE ;
    leaf:   AND             <\- "&"     WHITESPACE ;
    leaf:   NOT             <\- "\!"     WHITESPACE ;
    leaf:   QUESTION        <\- "?"     WHITESPACE ;
    leaf:   STAR            <\- "\*"     WHITESPACE ;
    leaf:   PLUS            <\- "\+"     WHITESPACE ;
    void:   OPEN            <\- "\("     WHITESPACE ;
    void:   CLOSE           <\- "\)"     WHITESPACE ;
    leaf:   DOT             <\- "\."     WHITESPACE ;

    leaf:   ALNUM           <\- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <\- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <\- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <\- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <\- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <\- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <\- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <\- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <\- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <\- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <\- "<space>"    WHITESPACE ;
    leaf:   UPPER           <\- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <\- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <\- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <\- \(" " / "\\t" / EOL / COMMENT\)\* ;
    void:   COMMENT         <\- '\#' \(\!EOL \.\)\* EOL ;
    void:   EOL             <\- "\\n\\r" / "\\n" / "\\r" ;
    void:   EOF             <\- \!\. ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    END;

## <a name='subsection7'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator \(Expression\)
        Sign       <\- \[\-\+\] 						;
        Number     <\- Sign? <ddigit>\+				;
        Expression <\- '\(' Expression '\)' / \(Factor \(MulOp Factor\)\*\)	;
        MulOp      <\- \[\*/\]						;
        Factor     <\- Term \(AddOp Term\)\*				;
        AddOp      <\- \[\-\+\]						;
        Term       <\- Number					;
    END;

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|

|
|

|

|
|
|
|
|
|
|
|








|
|
|
|

|
|

|
|

|
|
|



|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|






|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|







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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *PEG Language
Tutorial*\.

    PEG pe-grammar-for-peg (Grammar)

    	# --------------------------------------------------------------------
            # Syntactical constructs

            Grammar         <- WHITESPACE Header Definition* Final EOF ;

            Header          <- PEG Identifier StartExpr ;
            Definition      <- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <- (VOID / LEAF) COLON ;
            Expression      <- Sequence (SLASH Sequence)* ;
            Sequence        <- Prefix+ ;
            Prefix          <- (AND / NOT)? Suffix ;
            Suffix          <- Primary (QUESTION / STAR / PLUS)? ;
            Primary         <- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH WHITESPACE ;
            Class           <- OPENB (!CLOSEB Range)* CLOSEB WHITESPACE ;
            Range           <- Char TO Char / Char ;

            StartExpr       <- OPEN Expression CLOSE ;
    void:   Final           <- "END" WHITESPACE SEMICOLON WHITESPACE ;

            # --------------------------------------------------------------------
            # Lexing constructs

            Identifier      <- Ident WHITESPACE ;
    leaf:   Ident           <- ([_:] / <alpha>) ([_:] / <alnum>)* ;
            Char            <- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <- "\\" [nrt'"\[\]\\] ;
    leaf:   CharOctalFull   <- "\\" [0-2][0-7][0-7] ;
    leaf:   CharOctalPart   <- "\\" [0-7][0-7]? ;
    leaf:   CharUnicode     <- "\\" 'u' HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
    leaf:   CharUnescaped   <- !"\\" . ;

    void:   HexDigit        <- [0-9a-fA-F] ;

    void:   TO              <- '-'           ;
    void:   OPENB           <- "["           ;
    void:   CLOSEB          <- "]"           ;
    void:   APOSTROPH       <- "'"           ;
    void:   DAPOSTROPH      <- '"'           ;
    void:   PEG             <- "PEG" !([_:] / <alnum>) WHITESPACE ;
    void:   IS              <- "<-"    WHITESPACE ;
    leaf:   VOID            <- "void"  WHITESPACE ; # Implies that definition has no semantic value.
    leaf:   LEAF            <- "leaf"  WHITESPACE ; # Implies that definition has no terminals.
    void:   SEMICOLON       <- ";"     WHITESPACE ;
    void:   COLON           <- ":"     WHITESPACE ;
    void:   SLASH           <- "/"     WHITESPACE ;
    leaf:   AND             <- "&"     WHITESPACE ;
    leaf:   NOT             <- "!"     WHITESPACE ;
    leaf:   QUESTION        <- "?"     WHITESPACE ;
    leaf:   STAR            <- "*"     WHITESPACE ;
    leaf:   PLUS            <- "+"     WHITESPACE ;
    void:   OPEN            <- "("     WHITESPACE ;
    void:   CLOSE           <- ")"     WHITESPACE ;
    leaf:   DOT             <- "."     WHITESPACE ;

    leaf:   ALNUM           <- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <- "<space>"    WHITESPACE ;
    leaf:   UPPER           <- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <- (" " / "\t" / EOL / COMMENT)* ;
    void:   COMMENT         <- '#' (!EOL .)* EOL ;
    void:   EOL             <- "\n\r" / "\n" / "\r" ;
    void:   EOF             <- !. ;

            # --------------------------------------------------------------------
    END;

## <a name='subsection7'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator (Expression)
        Sign       <- [-+] 						;
        Number     <- Sign? <ddigit>+				;
        Expression <- '(' Expression ')' / (Factor (MulOp Factor)*)	;
        MulOp      <- [*/]						;
        Factor     <- Term (AddOp Term)*				;
        AddOp      <- [-+]						;
        Term       <- Number					;
    END;

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_op.md.
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

  - <a name='2'></a>__::peg::peg::op__ __dechain__ *container*

    This command simplifies all symbols which just chain to a different symbol
    by inlining the right hand side of the called symbol in its callers\. This
    works if and only the modes match properly, per the decision table below\.

        caller called &#124; dechain &#124; notes
        \-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
        value  value  &#124;  yes    &#124;  value is passed
        value  leaf   &#124;  yes    &#124;  value is passed
        value  void   &#124;  yes    &#124;  caller is implied void
        leaf   value  &#124;  no     &#124;  generated value was discarded, inlined would not\. called may be implied void\.
        leaf   leaf   &#124;  no     &#124;  s\.a\.
        leaf   void   &#124;  no     &#124;  s\.a\.
        void   value  &#124;  no     &#124;  caller drops value, inlined would not\.
        void   leaf   &#124;  no     &#124;  s\.a\.
        void   void   &#124;  yes    &#124;

    The result of the command is the empty string\.

    The grammar in the container is directly modified\. If that is not wanted, a
    copy of the original container has to be used\.

    The *container* instance has to expose a method API as is provided by the







|
|
|
|
|
|
|
|
|
|
|







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

  - <a name='2'></a>__::peg::peg::op__ __dechain__ *container*

    This command simplifies all symbols which just chain to a different symbol
    by inlining the right hand side of the called symbol in its callers\. This
    works if and only the modes match properly, per the decision table below\.

        caller called | dechain | notes
        --------------+---------+-----------------------
        value  value  |  yes    |  value is passed
        value  leaf   |  yes    |  value is passed
        value  void   |  yes    |  caller is implied void
        leaf   value  |  no     |  generated value was discarded, inlined would not. called may be implied void.
        leaf   leaf   |  no     |  s.a.
        leaf   void   |  no     |  s.a.
        void   value  |  no     |  caller drops value, inlined would not.
        void   leaf   |  no     |  s.a.
        void   void   |  yes    |

    The result of the command is the empty string\.

    The grammar in the container is directly modified\. If that is not wanted, a
    copy of the original container has to be used\.

    The *container* instance has to expose a method API as is provided by the
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_to_container.md.
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

It has no direct formal specification beyond what was said above\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

one possible CONTAINER serialization for it is

    snit::type a\_pe\_grammar \{
        constructor \{\} \{
            install myg using pt::peg::container $\{selfns\}::G
            $myg start \{n Expression\}
            $myg add   AddOp Digit Expression Factor MulOp Number Sign Term
            $myg modes \{
                AddOp      value
                Digit      value
                Expression value
                Factor     value
                MulOp      value
                Number     value
                Sign       value
                Term       value
            \}

            $myg rules \{
                AddOp      \{/ \{t \-\} \{t \+\}\}
                Digit      \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}
                Expression \{/ \{x \{t \\50\} \{n Expression\} \{t \\51\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}\}
                Factor     \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}
                MulOp      \{/ \{t \*\} \{t /\}\}
                Number     \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}
                Sign       \{/ \{t \-\} \{t \+\}\}
                Term       \{n Number\}
            \}

            return
        \}


        component myg
        delegate method \* to myg
    \}


# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG







|
|
|
|
|
|
|
|
|




|
|
|
|

|








<
>
|
|
|
|
|
|
|
|
|
<
>

<
|
>

|
<
>







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

It has no direct formal specification beyond what was said above\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

one possible CONTAINER serialization for it is

    snit::type a_pe_grammar {
        constructor {} {
            install myg using pt::peg::container ${selfns}::G
            $myg start {n Expression}
            $myg add   AddOp Digit Expression Factor MulOp Number Sign Term
            $myg modes {
                AddOp      value
                Digit      value
                Expression value
                Factor     value
                MulOp      value
                Number     value
                Sign       value
                Term       value

            }
            $myg rules {
                AddOp      {/ {t -} {t +}}
                Digit      {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}
                Expression {/ {x {t \50} {n Expression} {t \51}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}}
                Factor     {x {n Term} {* {x {n AddOp} {n Term}}}}
                MulOp      {/ {t *} {t /}}
                Number     {x {? {n Sign}} {+ {n Digit}}}
                Sign       {/ {t -} {t +}}
                Term       {n Number}

            }
            return

        }

        component myg
        delegate method * to myg

    }

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_to_cparam.md.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_to_json.md.
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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

a JSON serialization for it is

    \{

        "pt::grammar::peg" : \{
            "rules" : \{
                "AddOp"     : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Digit"     : \{
                    "is"   : "\\/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}",
                    "mode" : "value"
                \},
                "Expression" : \{
                    "is"   : "\\/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}",
                    "mode" : "value"
                \},
                "Factor"    : \{
                    "is"   : "x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}",
                    "mode" : "value"
                \},
                "MulOp"     : \{
                    "is"   : "\\/ \{t \*\} \{t \\/\}",
                    "mode" : "value"
                \},
                "Number"    : \{
                    "is"   : "x \{? \{n Sign\}\} \{\+ \{n Digit\}\}",
                    "mode" : "value"
                \},
                "Sign"      : \{
                    "is"   : "\\/ \{t \-\} \{t \+\}",
                    "mode" : "value"
                \},
                "Term"      : \{
                    "is"   : "n Number",
                    "mode" : "value"
                \}

            \},
            "start" : "n Expression"
        \}
    \}



and a Tcl serialization of the same is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


The similarity of the latter to the JSON should be quite obvious\.

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.







|
|
|
|
|
|
|
|
|




<
>
|
|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|
|

|
|


<
>
|

<
<
|
>
>


|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
themselves are not translated further, but kept as JSON strings containing a
nested Tcl list, and there is no concept of canonicity for the JSON either\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

a JSON serialization for it is


    {
        "pt::grammar::peg" : {
            "rules" : {
                "AddOp"     : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Digit"     : {
                    "is"   : "\/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}",
                    "mode" : "value"
                },
                "Expression" : {
                    "is"   : "\/ {x {t (} {n Expression} {t )}} {x {n Factor} {* {x {n MulOp} {n Factor}}}}",
                    "mode" : "value"
                },
                "Factor"    : {
                    "is"   : "x {n Term} {* {x {n AddOp} {n Term}}}",
                    "mode" : "value"
                },
                "MulOp"     : {
                    "is"   : "\/ {t *} {t \/}",
                    "mode" : "value"
                },
                "Number"    : {
                    "is"   : "x {? {n Sign}} {+ {n Digit}}",
                    "mode" : "value"
                },
                "Sign"      : {
                    "is"   : "\/ {t -} {t +}",
                    "mode" : "value"
                },
                "Term"      : {
                    "is"   : "n Number",
                    "mode" : "value"

                }
            },
            "start" : "n Expression"


        }
    }

and a Tcl serialization of the same is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

The similarity of the latter to the JSON should be quite obvious\.

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_to_param.md.
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

It has no direct formal specification beyond what was said above\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

one possible PARAM serialization for it is

    \# \-\*\- text \-\*\-
    \# Parsing Expression Grammar 'TEMPLATE'\.
    \# Generated for unknown, from file 'TEST'

    \#

    \# Grammar Start Expression
    \#


    <<MAIN>>:
             call              sym\_Expression
             halt

    \#

    \# value Symbol 'AddOp'
    \#


    sym\_AddOp:
    \# /
    \#     '\-'
    \#     '\+'

             symbol\_restore    AddOp
      found\! jump              found\_7
             loc\_push

             call              choice\_5

       fail\! value\_clear
         ok\! value\_leaf        AddOp
             symbol\_save       AddOp
             error\_nonterminal AddOp
             loc\_pop\_discard

    found\_7:
         ok\! ast\_value\_push
             return

    choice\_5:
    \# /
    \#     '\-'
    \#     '\+'

             error\_clear

             loc\_push
             error\_push

             input\_next        "t \-"
         ok\! test\_char         "\-"

             error\_pop\_merge
         ok\! jump              oknoast\_4

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t \+"
         ok\! test\_char         "\+"

             error\_pop\_merge
         ok\! jump              oknoast\_4

             loc\_pop\_rewind
             status\_fail
             return

    oknoast\_4:
             loc\_pop\_discard
             return
    \#

    \# value Symbol 'Digit'
    \#


    sym\_Digit:
    \# /
    \#     '0'
    \#     '1'
    \#     '2'
    \#     '3'
    \#     '4'
    \#     '5'
    \#     '6'
    \#     '7'
    \#     '8'
    \#     '9'

             symbol\_restore    Digit
      found\! jump              found\_22
             loc\_push

             call              choice\_20

       fail\! value\_clear
         ok\! value\_leaf        Digit
             symbol\_save       Digit
             error\_nonterminal Digit
             loc\_pop\_discard

    found\_22:
         ok\! ast\_value\_push
             return

    choice\_20:
    \# /
    \#     '0'
    \#     '1'
    \#     '2'
    \#     '3'
    \#     '4'
    \#     '5'
    \#     '6'
    \#     '7'
    \#     '8'
    \#     '9'

             error\_clear

             loc\_push
             error\_push

             input\_next        "t 0"
         ok\! test\_char         "0"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 1"
         ok\! test\_char         "1"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 2"
         ok\! test\_char         "2"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 3"
         ok\! test\_char         "3"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 4"
         ok\! test\_char         "4"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 5"
         ok\! test\_char         "5"


             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 6"
         ok\! test\_char         "6"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 7"
         ok\! test\_char         "7"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 8"
         ok\! test\_char         "8"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t 9"
         ok\! test\_char         "9"

             error\_pop\_merge
         ok\! jump              oknoast\_19

             loc\_pop\_rewind
             status\_fail
             return

    oknoast\_19:
             loc\_pop\_discard
             return
    \#

    \# value Symbol 'Expression'
    \#


    sym\_Expression:
    \# /
    \#     x
    \#         '\\\('
    \#         \(Expression\)
    \#         '\\\)'
    \#     x
    \#         \(Factor\)
    \#         \*
    \#             x
    \#                 \(MulOp\)
    \#                 \(Factor\)

             symbol\_restore    Expression
      found\! jump              found\_46
             loc\_push
             ast\_push

             call              choice\_44

       fail\! value\_clear
         ok\! value\_reduce      Expression
             symbol\_save       Expression
             error\_nonterminal Expression
             ast\_pop\_rewind
             loc\_pop\_discard

    found\_46:
         ok\! ast\_value\_push
             return

    choice\_44:
    \# /
    \#     x
    \#         '\\\('
    \#         \(Expression\)
    \#         '\\\)'
    \#     x
    \#         \(Factor\)
    \#         \*
    \#             x
    \#                 \(MulOp\)
    \#                 \(Factor\)

             error\_clear

             ast\_push
             loc\_push
             error\_push

             call              sequence\_27

             error\_pop\_merge
         ok\! jump              ok\_43

             ast\_pop\_rewind
             loc\_pop\_rewind
             ast\_push
             loc\_push
             error\_push

             call              sequence\_40


             error\_pop\_merge
         ok\! jump              ok\_43

             ast\_pop\_rewind
             loc\_pop\_rewind
             status\_fail
             return

    ok\_43:
             ast\_pop\_discard
             loc\_pop\_discard
             return

    sequence\_27:
    \# x
    \#     '\\\('
    \#     \(Expression\)
    \#     '\\\)'

             loc\_push
             error\_clear

             error\_push

             input\_next        "t \("
         ok\! test\_char         "\("

             error\_pop\_merge
       fail\! jump              failednoast\_29
             ast\_push
             error\_push

             call              sym\_Expression

             error\_pop\_merge
       fail\! jump              failed\_28
             error\_push

             input\_next        "t \)"
         ok\! test\_char         "\)"

             error\_pop\_merge
       fail\! jump              failed\_28

             ast\_pop\_discard
             loc\_pop\_discard
             return

    failed\_28:
             ast\_pop\_rewind

    failednoast\_29:
             loc\_pop\_rewind
             return

    sequence\_40:
    \# x
    \#     \(Factor\)
    \#     \*
    \#         x
    \#             \(MulOp\)
    \#             \(Factor\)

             ast\_push
             loc\_push
             error\_clear

             error\_push

             call              sym\_Factor

             error\_pop\_merge
       fail\! jump              failed\_41
             error\_push

             call              kleene\_37

             error\_pop\_merge
       fail\! jump              failed\_41

             ast\_pop\_discard
             loc\_pop\_discard
             return

    failed\_41:
             ast\_pop\_rewind
             loc\_pop\_rewind
             return

    kleene\_37:
    \# \*
    \#     x
    \#         \(MulOp\)
    \#         \(Factor\)

             loc\_push
             error\_push

             call              sequence\_34

             error\_pop\_merge
       fail\! jump              failed\_38
             loc\_pop\_discard
             jump              kleene\_37

    failed\_38:
             loc\_pop\_rewind
             status\_ok
             return

    sequence\_34:
    \# x
    \#     \(MulOp\)
    \#     \(Factor\)

             ast\_push



             loc\_push
             error\_clear

             error\_push

             call              sym\_MulOp

             error\_pop\_merge
       fail\! jump              failed\_35
             error\_push

             call              sym\_Factor

             error\_pop\_merge
       fail\! jump              failed\_35

             ast\_pop\_discard
             loc\_pop\_discard
             return

    failed\_35:
             ast\_pop\_rewind
             loc\_pop\_rewind
             return





    \#
    \# value Symbol 'Factor'
    \#

    sym\_Factor:
    \# x
    \#     \(Term\)
    \#     \*
    \#         x
    \#             \(AddOp\)
    \#             \(Term\)

             symbol\_restore    Factor
      found\! jump              found\_60
             loc\_push
             ast\_push

             call              sequence\_57

       fail\! value\_clear
         ok\! value\_reduce      Factor
             symbol\_save       Factor
             error\_nonterminal Factor
             ast\_pop\_rewind
             loc\_pop\_discard

    found\_60:
         ok\! ast\_value\_push
             return

    sequence\_57:
    \# x
    \#     \(Term\)
    \#     \*
    \#         x
    \#             \(AddOp\)
    \#             \(Term\)

             ast\_push
             loc\_push
             error\_clear

             error\_push

             call              sym\_Term

             error\_pop\_merge
       fail\! jump              failed\_58


             error\_push

             call              kleene\_54

             error\_pop\_merge
       fail\! jump              failed\_58

             ast\_pop\_discard
             loc\_pop\_discard
             return

    failed\_58:
             ast\_pop\_rewind
             loc\_pop\_rewind
             return

    kleene\_54:
    \# \*
    \#     x
    \#         \(AddOp\)
    \#         \(Term\)

             loc\_push
             error\_push

             call              sequence\_51

             error\_pop\_merge
       fail\! jump              failed\_55
             loc\_pop\_discard
             jump              kleene\_54

    failed\_55:
             loc\_pop\_rewind
             status\_ok
             return

    sequence\_51:
    \# x
    \#     \(AddOp\)
    \#     \(Term\)

             ast\_push
             loc\_push
             error\_clear

             error\_push

             call              sym\_AddOp

             error\_pop\_merge
       fail\! jump              failed\_52
             error\_push

             call              sym\_Term

             error\_pop\_merge
       fail\! jump              failed\_52

             ast\_pop\_discard
             loc\_pop\_discard
             return

    failed\_52:
             ast\_pop\_rewind
             loc\_pop\_rewind
             return
    \#
    \# value Symbol 'MulOp'
    \#




    sym\_MulOp:
    \# /
    \#     '\*'
    \#     '/'

             symbol\_restore    MulOp
      found\! jump              found\_67
             loc\_push

             call              choice\_65

       fail\! value\_clear
         ok\! value\_leaf        MulOp
             symbol\_save       MulOp
             error\_nonterminal MulOp
             loc\_pop\_discard

    found\_67:
         ok\! ast\_value\_push
             return

    choice\_65:
    \# /
    \#     '\*'
    \#     '/'

             error\_clear

             loc\_push
             error\_push

             input\_next        "t \*"
         ok\! test\_char         "\*"

             error\_pop\_merge
         ok\! jump              oknoast\_64

             loc\_pop\_rewind
             loc\_push
             error\_push

             input\_next        "t /"
         ok\! test\_char         "/"

             error\_pop\_merge
         ok\! jump              oknoast\_64

             loc\_pop\_rewind
             status\_fail
             return

    oknoast\_64:
             loc\_pop\_discard
             return
    \#

    \# value Symbol 'Number'
    \#


    sym\_Number:
    \# x
    \#     ?
    \#         \(Sign\)
    \#     \+
    \#         \(Digit\)

             symbol\_restore    Number
      found\! jump              found\_80
             loc\_push
             ast\_push

             call              sequence\_77

       fail\! value\_clear
         ok\! value\_reduce      Number
             symbol\_save       Number
             error\_nonterminal Number
             ast\_pop\_rewind
             loc\_pop\_discard

    found\_80:
         ok\! ast\_value\_push
             return

    sequence\_77:
    \# x
    \#     ?
    \#         \(Sign\)
    \#     \+
    \#         \(Digit\)

             ast\_push
             loc\_push
             error\_clear

             error\_push

             call              optional\_70

             error\_pop\_merge
       fail\! jump              failed\_78
             error\_push

             call              poskleene\_73

             error\_pop\_merge
       fail\! jump              failed\_78

             ast\_pop\_discard
             loc\_pop\_discard
             return

    failed\_78:
             ast\_pop\_rewind
             loc\_pop\_rewind
             return

    optional\_70:
    \# ?
    \#     \(Sign\)

             loc\_push
             error\_push

             call              sym\_Sign

             error\_pop\_merge
       fail\! loc\_pop\_rewind
         ok\! loc\_pop\_discard
             status\_ok
             return

    poskleene\_73:
    \# \+
    \#     \(Digit\)

             loc\_push

             call              sym\_Digit

       fail\! jump              failed\_74

    loop\_75:
             loc\_pop\_discard
             loc\_push
             error\_push

             call              sym\_Digit

             error\_pop\_merge
         ok\! jump              loop\_75
             status\_ok

    failed\_74:
             loc\_pop\_rewind
             return
    \#

    \# value Symbol 'Sign'
    \#


    sym\_Sign:
    \# /
    \#     '\-'
    \#     '\+'

             symbol\_restore    Sign
      found\! jump              found\_86
             loc\_push

             call              choice\_5

       fail\! value\_clear
         ok\! value\_leaf        Sign
             symbol\_save       Sign
             error\_nonterminal Sign
             loc\_pop\_discard

    found\_86:
         ok\! ast\_value\_push
             return
    \#

    \# value Symbol 'Term'
    \#


    sym\_Term:
    \# \(Number\)

             symbol\_restore    Term
      found\! jump              found\_89
             loc\_push
             ast\_push

             call              sym\_Number

       fail\! value\_clear
         ok\! value\_reduce      Term
             symbol\_save       Term
             error\_nonterminal Term
             ast\_pop\_rewind
             loc\_pop\_discard

    found\_89:
         ok\! ast\_value\_push
             return

    \#
    \#



# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG







|
|
|
|
|
|
|
|
|




|
|
|

<
>
|
<
|
>

|


<
>
|
<
|
>
|
|
|
|

|
|
|

|

|
|
|
|
|

|
|


|
|
|
|

|

|
|

|
|

|
|

|
|
|

|
|

|
|

|
|


|
|

<
>
|
<
|
>
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|

|
|
|
|
|

|
|


|
|
|
|
|
|
|
|
|
|
|
|

|

|
|

|
|

|
|

|
|
|

|
|

|
|

|
|
|

|
|

|
|

|
|
|

|
|

|
|

|
|
|

|
|

|
|

|
|
|

|
|
>
|
<
|

|
|
|

|
|

|
|

|
|
|

|
|

|
|

|
|
|

|
|

|
|

|
|
|

|
|

|
|

|
|


|
|

<
>
|
<
|
>
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|

|
|
|
|
|
|

|
|


|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|

|

|
|

|
|
|
|
|

|
>
|
<
|

|
|
|


|
|
|


|
|
|
|
|

|
|

|

|
|

|
|
|
|

|

|
|
|

|
|

|
|

|
|


|
|

|
|


|
|
|
|
|
|
|

|
|
|

|

|

|
|
|

|

|
|

|
|


|
|
|


|
|
|
|
|

|
|

|

|
|
|
|

|
|
|


|
|
|
|

|
>
>
>
|
<

<
<
|

|
|
|

|

|
|

|
|


|
|
|

>
>
>
>
>
<
<
<
<
<
|
|
|
|
|
|

|
|
|
|

|

|
|
|
|
|
|

|
|


|
|
|
|
|
|
|

|
|
|

|

|

<
<
>
>
|

|

|
|

|
|


|
|
|


|
|
|
|
|

|
|

|

|
|
|
|

|
|
|


|
|
|
|

|
|
|

|

|

|
|
|

|

|
|

|
|


|
|
|

<
<
<
|
>
>
>
|
|
|
|

|
|
|

|

|
|
|
|
|

|
|


|
|
|
|

|

|
|

|
|

|
|

|
|
|

|
|

|
|

|
|


|
|

<
>
|
<
|
>
|
|
|
|
|
|

|
|
|
|

|

|
|
|
|
|
|

|
|


|
|
|
|
|
|

|
|
|

|

|

|
|
|

|

|
|

|
|


|
|
|


|
|
|

|
|

|

|
|
|
|


|
|
|

|

|

|

|
|
|
|

|

|
|
|

|
|

<
>
|
<
|
>
|
|
|
|

|
|
|

|

|
|
|
|
|

|
|

<
>
|
<
>

|
|

|
|
|
|

|

|
|
|
|
|
|

|
|


<
<
>
>







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

It has no direct formal specification beyond what was said above\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

one possible PARAM serialization for it is

    # -*- text -*-
    # Parsing Expression Grammar 'TEMPLATE'.
    # Generated for unknown, from file 'TEST'


    #
    # Grammar Start Expression

    #

    <<MAIN>>:
             call              sym_Expression
             halt


    #
    # value Symbol 'AddOp'

    #

    sym_AddOp:
    # /
    #     '-'
    #     '+'

             symbol_restore    AddOp
      found! jump              found_7
             loc_push

             call              choice_5

       fail! value_clear
         ok! value_leaf        AddOp
             symbol_save       AddOp
             error_nonterminal AddOp
             loc_pop_discard

    found_7:
         ok! ast_value_push
             return

    choice_5:
    # /
    #     '-'
    #     '+'

             error_clear

             loc_push
             error_push

             input_next        "t -"
         ok! test_char         "-"

             error_pop_merge
         ok! jump              oknoast_4

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t +"
         ok! test_char         "+"

             error_pop_merge
         ok! jump              oknoast_4

             loc_pop_rewind
             status_fail
             return

    oknoast_4:
             loc_pop_discard
             return

    #
    # value Symbol 'Digit'

    #

    sym_Digit:
    # /
    #     '0'
    #     '1'
    #     '2'
    #     '3'
    #     '4'
    #     '5'
    #     '6'
    #     '7'
    #     '8'
    #     '9'

             symbol_restore    Digit
      found! jump              found_22
             loc_push

             call              choice_20

       fail! value_clear
         ok! value_leaf        Digit
             symbol_save       Digit
             error_nonterminal Digit
             loc_pop_discard

    found_22:
         ok! ast_value_push
             return

    choice_20:
    # /
    #     '0'
    #     '1'
    #     '2'
    #     '3'
    #     '4'
    #     '5'
    #     '6'
    #     '7'
    #     '8'
    #     '9'

             error_clear

             loc_push
             error_push

             input_next        "t 0"
         ok! test_char         "0"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 1"
         ok! test_char         "1"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 2"
         ok! test_char         "2"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 3"
         ok! test_char         "3"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 4"
         ok! test_char         "4"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 5"
         ok! test_char         "5"

             error_pop_merge

         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 6"
         ok! test_char         "6"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 7"
         ok! test_char         "7"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 8"
         ok! test_char         "8"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t 9"
         ok! test_char         "9"

             error_pop_merge
         ok! jump              oknoast_19

             loc_pop_rewind
             status_fail
             return

    oknoast_19:
             loc_pop_discard
             return

    #
    # value Symbol 'Expression'

    #

    sym_Expression:
    # /
    #     x
    #         '\('
    #         (Expression)
    #         '\)'
    #     x
    #         (Factor)
    #         *
    #             x
    #                 (MulOp)
    #                 (Factor)

             symbol_restore    Expression
      found! jump              found_46
             loc_push
             ast_push

             call              choice_44

       fail! value_clear
         ok! value_reduce      Expression
             symbol_save       Expression
             error_nonterminal Expression
             ast_pop_rewind
             loc_pop_discard

    found_46:
         ok! ast_value_push
             return

    choice_44:
    # /
    #     x
    #         '\('
    #         (Expression)
    #         '\)'
    #     x
    #         (Factor)
    #         *
    #             x
    #                 (MulOp)
    #                 (Factor)

             error_clear

             ast_push
             loc_push
             error_push

             call              sequence_27

             error_pop_merge
         ok! jump              ok_43

             ast_pop_rewind
             loc_pop_rewind
             ast_push
             loc_push
             error_push

             call              sequence_40

             error_pop_merge

         ok! jump              ok_43

             ast_pop_rewind
             loc_pop_rewind
             status_fail
             return

    ok_43:
             ast_pop_discard
             loc_pop_discard
             return

    sequence_27:
    # x
    #     '\('
    #     (Expression)
    #     '\)'

             loc_push
             error_clear

             error_push

             input_next        "t ("
         ok! test_char         "("

             error_pop_merge
       fail! jump              failednoast_29
             ast_push
             error_push

             call              sym_Expression

             error_pop_merge
       fail! jump              failed_28
             error_push

             input_next        "t )"
         ok! test_char         ")"

             error_pop_merge
       fail! jump              failed_28

             ast_pop_discard
             loc_pop_discard
             return

    failed_28:
             ast_pop_rewind

    failednoast_29:
             loc_pop_rewind
             return

    sequence_40:
    # x
    #     (Factor)
    #     *
    #         x
    #             (MulOp)
    #             (Factor)

             ast_push
             loc_push
             error_clear

             error_push

             call              sym_Factor

             error_pop_merge
       fail! jump              failed_41
             error_push

             call              kleene_37

             error_pop_merge
       fail! jump              failed_41

             ast_pop_discard
             loc_pop_discard
             return

    failed_41:
             ast_pop_rewind
             loc_pop_rewind
             return

    kleene_37:
    # *
    #     x
    #         (MulOp)
    #         (Factor)

             loc_push
             error_push

             call              sequence_34

             error_pop_merge
       fail! jump              failed_38
             loc_pop_discard
             jump              kleene_37

    failed_38:
             loc_pop_rewind
             status_ok
             return

    sequence_34:
    # x
    #     (MulOp)
    #     (Factor)

             ast_push
             loc_push
             error_clear

             error_push




             call              sym_MulOp

             error_pop_merge
       fail! jump              failed_35
             error_push

             call              sym_Factor

             error_pop_merge
       fail! jump              failed_35

             ast_pop_discard
             loc_pop_discard
             return

    failed_35:
             ast_pop_rewind
             loc_pop_rewind
             return
    #
    # value Symbol 'Factor'
    #

    sym_Factor:





    # x
    #     (Term)
    #     *
    #         x
    #             (AddOp)
    #             (Term)

             symbol_restore    Factor
      found! jump              found_60
             loc_push
             ast_push

             call              sequence_57

       fail! value_clear
         ok! value_reduce      Factor
             symbol_save       Factor
             error_nonterminal Factor
             ast_pop_rewind
             loc_pop_discard

    found_60:
         ok! ast_value_push
             return

    sequence_57:
    # x
    #     (Term)
    #     *
    #         x
    #             (AddOp)
    #             (Term)

             ast_push
             loc_push
             error_clear

             error_push

             call              sym_Term



             error_pop_merge
       fail! jump              failed_58
             error_push

             call              kleene_54

             error_pop_merge
       fail! jump              failed_58

             ast_pop_discard
             loc_pop_discard
             return

    failed_58:
             ast_pop_rewind
             loc_pop_rewind
             return

    kleene_54:
    # *
    #     x
    #         (AddOp)
    #         (Term)

             loc_push
             error_push

             call              sequence_51

             error_pop_merge
       fail! jump              failed_55
             loc_pop_discard
             jump              kleene_54

    failed_55:
             loc_pop_rewind
             status_ok
             return

    sequence_51:
    # x
    #     (AddOp)
    #     (Term)

             ast_push
             loc_push
             error_clear

             error_push

             call              sym_AddOp

             error_pop_merge
       fail! jump              failed_52
             error_push

             call              sym_Term

             error_pop_merge
       fail! jump              failed_52

             ast_pop_discard
             loc_pop_discard
             return

    failed_52:
             ast_pop_rewind
             loc_pop_rewind
             return



    #
    # value Symbol 'MulOp'
    #

    sym_MulOp:
    # /
    #     '*'
    #     '/'

             symbol_restore    MulOp
      found! jump              found_67
             loc_push

             call              choice_65

       fail! value_clear
         ok! value_leaf        MulOp
             symbol_save       MulOp
             error_nonterminal MulOp
             loc_pop_discard

    found_67:
         ok! ast_value_push
             return

    choice_65:
    # /
    #     '*'
    #     '/'

             error_clear

             loc_push
             error_push

             input_next        "t *"
         ok! test_char         "*"

             error_pop_merge
         ok! jump              oknoast_64

             loc_pop_rewind
             loc_push
             error_push

             input_next        "t /"
         ok! test_char         "/"

             error_pop_merge
         ok! jump              oknoast_64

             loc_pop_rewind
             status_fail
             return

    oknoast_64:
             loc_pop_discard
             return

    #
    # value Symbol 'Number'

    #

    sym_Number:
    # x
    #     ?
    #         (Sign)
    #     +
    #         (Digit)

             symbol_restore    Number
      found! jump              found_80
             loc_push
             ast_push

             call              sequence_77

       fail! value_clear
         ok! value_reduce      Number
             symbol_save       Number
             error_nonterminal Number
             ast_pop_rewind
             loc_pop_discard

    found_80:
         ok! ast_value_push
             return

    sequence_77:
    # x
    #     ?
    #         (Sign)
    #     +
    #         (Digit)

             ast_push
             loc_push
             error_clear

             error_push

             call              optional_70

             error_pop_merge
       fail! jump              failed_78
             error_push

             call              poskleene_73

             error_pop_merge
       fail! jump              failed_78

             ast_pop_discard
             loc_pop_discard
             return

    failed_78:
             ast_pop_rewind
             loc_pop_rewind
             return

    optional_70:
    # ?
    #     (Sign)

             loc_push
             error_push

             call              sym_Sign

             error_pop_merge
       fail! loc_pop_rewind
         ok! loc_pop_discard
             status_ok
             return

    poskleene_73:
    # +
    #     (Digit)

             loc_push

             call              sym_Digit

       fail! jump              failed_74

    loop_75:
             loc_pop_discard
             loc_push
             error_push

             call              sym_Digit

             error_pop_merge
         ok! jump              loop_75
             status_ok

    failed_74:
             loc_pop_rewind
             return

    #
    # value Symbol 'Sign'

    #

    sym_Sign:
    # /
    #     '-'
    #     '+'

             symbol_restore    Sign
      found! jump              found_86
             loc_push

             call              choice_5

       fail! value_clear
         ok! value_leaf        Sign
             symbol_save       Sign
             error_nonterminal Sign
             loc_pop_discard

    found_86:
         ok! ast_value_push
             return

    #
    # value Symbol 'Term'

    #

    sym_Term:
    # (Number)

             symbol_restore    Term
      found! jump              found_89
             loc_push
             ast_push

             call              sym_Number

       fail! value_clear
         ok! value_reduce      Term
             symbol_save       Term
             error_nonterminal Term
             ast_pop_rewind
             loc_pop_discard

    found_89:
         ok! ast_value_push
             return



    #
    #

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_to_peg.md.
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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe\-grammar\-for\-peg \(Grammar\)

    	\# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Syntactical constructs

            Grammar         <\- WHITESPACE Header Definition\* Final EOF ;

            Header          <\- PEG Identifier StartExpr ;
            Definition      <\- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <\- \(VOID / LEAF\) COLON ;
            Expression      <\- Sequence \(SLASH Sequence\)\* ;
            Sequence        <\- Prefix\+ ;
            Prefix          <\- \(AND / NOT\)? Suffix ;
            Suffix          <\- Primary \(QUESTION / STAR / PLUS\)? ;
            Primary         <\- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <\- APOSTROPH  \(\!APOSTROPH  Char\)\* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH \(\!DAPOSTROPH Char\)\* DAPOSTROPH WHITESPACE ;
            Class           <\- OPENB \(\!CLOSEB Range\)\* CLOSEB WHITESPACE ;
            Range           <\- Char TO Char / Char ;

            StartExpr       <\- OPEN Expression CLOSE ;
    void:   Final           <\- "END" WHITESPACE SEMICOLON WHITESPACE ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
            \# Lexing constructs

            Identifier      <\- Ident WHITESPACE ;
    leaf:   Ident           <\- \(\[\_:\] / <alpha>\) \(\[\_:\] / <alnum>\)\* ;
            Char            <\- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <\- "\\\\" \[nrt'"\\\[\\\]\\\\\] ;
    leaf:   CharOctalFull   <\- "\\\\" \[0\-2\]\[0\-7\]\[0\-7\] ;
    leaf:   CharOctalPart   <\- "\\\\" \[0\-7\]\[0\-7\]? ;
    leaf:   CharUnicode     <\- "\\\\" 'u' HexDigit \(HexDigit \(HexDigit HexDigit?\)?\)? ;
    leaf:   CharUnescaped   <\- \!"\\\\" \. ;

    void:   HexDigit        <\- \[0\-9a\-fA\-F\] ;

    void:   TO              <\- '\-'           ;
    void:   OPENB           <\- "\["           ;
    void:   CLOSEB          <\- "\]"           ;
    void:   APOSTROPH       <\- "'"           ;
    void:   DAPOSTROPH      <\- '"'           ;
    void:   PEG             <\- "PEG" \!\(\[\_:\] / <alnum>\) WHITESPACE ;
    void:   IS              <\- "<\-"    WHITESPACE ;
    leaf:   VOID            <\- "void"  WHITESPACE ; \# Implies that definition has no semantic value\.
    leaf:   LEAF            <\- "leaf"  WHITESPACE ; \# Implies that definition has no terminals\.
    void:   SEMICOLON       <\- ";"     WHITESPACE ;
    void:   COLON           <\- ":"     WHITESPACE ;
    void:   SLASH           <\- "/"     WHITESPACE ;
    leaf:   AND             <\- "&"     WHITESPACE ;
    leaf:   NOT             <\- "\!"     WHITESPACE ;
    leaf:   QUESTION        <\- "?"     WHITESPACE ;
    leaf:   STAR            <\- "\*"     WHITESPACE ;
    leaf:   PLUS            <\- "\+"     WHITESPACE ;
    void:   OPEN            <\- "\("     WHITESPACE ;
    void:   CLOSE           <\- "\)"     WHITESPACE ;
    leaf:   DOT             <\- "\."     WHITESPACE ;

    leaf:   ALNUM           <\- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <\- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <\- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <\- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <\- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <\- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <\- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <\- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <\- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <\- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <\- "<space>"    WHITESPACE ;
    leaf:   UPPER           <\- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <\- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <\- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <\- \(" " / "\\t" / EOL / COMMENT\)\* ;
    void:   COMMENT         <\- '\#' \(\!EOL \.\)\* EOL ;
    void:   EOL             <\- "\\n\\r" / "\\n" / "\\r" ;
    void:   EOF             <\- \!\. ;

            \# \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator \(Expression\)
        Sign       <\- \[\-\+\] 						;
        Number     <\- Sign? <ddigit>\+				;
        Expression <\- '\(' Expression '\)' / \(Factor \(MulOp Factor\)\*\)	;
        MulOp      <\- \[\*/\]						;
        Factor     <\- Term \(AddOp Term\)\*				;
        AddOp      <\- \[\-\+\]						;
        Term       <\- Number					;
    END;

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.








|

|
|

|

|
|
|
|
|
|
|
|








|
|
|
|

|
|

|
|

|
|
|



|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|






|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|







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
writing the specification of a grammar easy, something the other formats found
in the Parser Tools do not lend themselves too\.

It is formally specified by the grammar shown below, written in itself\. For a
tutorial / introduction to the language please go and read the *[PEG Language
Tutorial](pt\_peg\_language\.md)*\.

    PEG pe-grammar-for-peg (Grammar)

    	# --------------------------------------------------------------------
            # Syntactical constructs

            Grammar         <- WHITESPACE Header Definition* Final EOF ;

            Header          <- PEG Identifier StartExpr ;
            Definition      <- Attribute? Identifier IS Expression SEMICOLON ;
            Attribute       <- (VOID / LEAF) COLON ;
            Expression      <- Sequence (SLASH Sequence)* ;
            Sequence        <- Prefix+ ;
            Prefix          <- (AND / NOT)? Suffix ;
            Suffix          <- Primary (QUESTION / STAR / PLUS)? ;
            Primary         <- ALNUM / ALPHA / ASCII / CONTROL / DDIGIT / DIGIT
                            /  GRAPH / LOWER / PRINTABLE / PUNCT / SPACE / UPPER
                            /  WORDCHAR / XDIGIT
                            / Identifier
                            /  OPEN Expression CLOSE
                            /  Literal
                            /  Class
                            /  DOT
                            ;
            Literal         <- APOSTROPH  (!APOSTROPH  Char)* APOSTROPH  WHITESPACE
                            /  DAPOSTROPH (!DAPOSTROPH Char)* DAPOSTROPH WHITESPACE ;
            Class           <- OPENB (!CLOSEB Range)* CLOSEB WHITESPACE ;
            Range           <- Char TO Char / Char ;

            StartExpr       <- OPEN Expression CLOSE ;
    void:   Final           <- "END" WHITESPACE SEMICOLON WHITESPACE ;

            # --------------------------------------------------------------------
            # Lexing constructs

            Identifier      <- Ident WHITESPACE ;
    leaf:   Ident           <- ([_:] / <alpha>) ([_:] / <alnum>)* ;
            Char            <- CharSpecial / CharOctalFull / CharOctalPart
                            /  CharUnicode / CharUnescaped
                            ;

    leaf:   CharSpecial     <- "\\" [nrt'"\[\]\\] ;
    leaf:   CharOctalFull   <- "\\" [0-2][0-7][0-7] ;
    leaf:   CharOctalPart   <- "\\" [0-7][0-7]? ;
    leaf:   CharUnicode     <- "\\" 'u' HexDigit (HexDigit (HexDigit HexDigit?)?)? ;
    leaf:   CharUnescaped   <- !"\\" . ;

    void:   HexDigit        <- [0-9a-fA-F] ;

    void:   TO              <- '-'           ;
    void:   OPENB           <- "["           ;
    void:   CLOSEB          <- "]"           ;
    void:   APOSTROPH       <- "'"           ;
    void:   DAPOSTROPH      <- '"'           ;
    void:   PEG             <- "PEG" !([_:] / <alnum>) WHITESPACE ;
    void:   IS              <- "<-"    WHITESPACE ;
    leaf:   VOID            <- "void"  WHITESPACE ; # Implies that definition has no semantic value.
    leaf:   LEAF            <- "leaf"  WHITESPACE ; # Implies that definition has no terminals.
    void:   SEMICOLON       <- ";"     WHITESPACE ;
    void:   COLON           <- ":"     WHITESPACE ;
    void:   SLASH           <- "/"     WHITESPACE ;
    leaf:   AND             <- "&"     WHITESPACE ;
    leaf:   NOT             <- "!"     WHITESPACE ;
    leaf:   QUESTION        <- "?"     WHITESPACE ;
    leaf:   STAR            <- "*"     WHITESPACE ;
    leaf:   PLUS            <- "+"     WHITESPACE ;
    void:   OPEN            <- "("     WHITESPACE ;
    void:   CLOSE           <- ")"     WHITESPACE ;
    leaf:   DOT             <- "."     WHITESPACE ;

    leaf:   ALNUM           <- "<alnum>"    WHITESPACE ;
    leaf:   ALPHA           <- "<alpha>"    WHITESPACE ;
    leaf:   ASCII           <- "<ascii>"    WHITESPACE ;
    leaf:   CONTROL         <- "<control>"  WHITESPACE ;
    leaf:   DDIGIT          <- "<ddigit>"   WHITESPACE ;
    leaf:   DIGIT           <- "<digit>"    WHITESPACE ;
    leaf:   GRAPH           <- "<graph>"    WHITESPACE ;
    leaf:   LOWER           <- "<lower>"    WHITESPACE ;
    leaf:   PRINTABLE       <- "<print>"    WHITESPACE ;
    leaf:   PUNCT           <- "<punct>"    WHITESPACE ;
    leaf:   SPACE           <- "<space>"    WHITESPACE ;
    leaf:   UPPER           <- "<upper>"    WHITESPACE ;
    leaf:   WORDCHAR        <- "<wordchar>" WHITESPACE ;
    leaf:   XDIGIT          <- "<xdigit>"   WHITESPACE ;

    void:   WHITESPACE      <- (" " / "\t" / EOL / COMMENT)* ;
    void:   COMMENT         <- '#' (!EOL .)* EOL ;
    void:   EOL             <- "\n\r" / "\n" / "\r" ;
    void:   EOF             <- !. ;

            # --------------------------------------------------------------------
    END;

## <a name='subsection1'></a>Example

Our example specifies the grammar for a basic 4\-operation calculator\.

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

Using higher\-level features of the notation, i\.e\. the character classes
\(predefined and custom\), this example can be rewritten as

    PEG calculator (Expression)
        Sign       <- [-+] 						;
        Number     <- Sign? <ddigit>+				;
        Expression <- '(' Expression ')' / (Factor (MulOp Factor)*)	;
        MulOp      <- [*/]						;
        Factor     <- Term (AddOp Term)*				;
        AddOp      <- [-+]						;
        Term       <- Number					;
    END;

# <a name='section5'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection2'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection3'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_peg_to_tclparam.md.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section6'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section7'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_pegrammar.md.
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section4'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section4'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_pexpr_op.md.
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection1'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection1'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_pexpression.md.
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection1'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection1'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/pt/pt_pgen.md.
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
In this section we are working a complete example, starting with a PEG grammar
and ending with running the parser generated from it over some input, following
the outline shown in the figure below:

![](\.\./\.\./\.\./\.\./image/flow\.png) Our grammar, assumed to the stored in the
file "calculator\.peg" is

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

From this we create a snit\-based parser using the script "gen"

    package require Tcl 8\.5
    package require fileutil
    package require pt::pgen

    lassign $argv name
    set grammar \[fileutil::cat $name\.peg\]
    set pclass  \[pt::pgen peg $gr snit \-class $name \-file  $name\.peg \-name  $name\]
    fileutil::writeFile $name\.tcl $pclass
    exit 0

calling it like

    tclsh8\.5 gen calculator

which leaves us with the parser package and class written to the file
"calculator\.tcl"\. Assuming that this package is then properly installed in a
place where Tcl can find it we can now use this class via a script like

    package require calculator

    lassign $argv input
    set channel \[open $input r\]

    set parser \[calculator\]
    set ast \[$parser parse $channel\]
    $parser destroy
    close $channel

    \.\.\. now process the returned abstract syntax tree \.\.\.

where the abstract syntax tree stored in the variable will look like

    set ast \{Expression 0 4
        \{Factor 0 4
            \{Term 0 2
                \{Number 0 2
                    \{Digit 0 0\}
                    \{Digit 1 1\}
                    \{Digit 2 2\}
                \}
            \}


            \{AddOp 3 3\}
            \{Term 4 4
                \{Number 4 4
                    \{Digit 4 4\}
                \}
            \}
        \}
    \}





assuming that the input file and channel contained the text

    120\+5

A more graphical representation of the tree would be

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png) Regardless, at this point it is the
user's responsibility to work with the tree to reach whatever goal she desires\.
I\.e\. analyze it, transform it, etc\. The package
__[pt::ast](pt\_astree\.md)__ should be of help here, providing commands







|
|
|
|
|
|
|
|
|




|




|
|
|




|








|

|
|



|



|
|
|
|
|
|
|
<
<
>
>
|
|
|
|
<
<
<
<
|
>
>
>
>


|







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
In this section we are working a complete example, starting with a PEG grammar
and ending with running the parser generated from it over some input, following
the outline shown in the figure below:

![](\.\./\.\./\.\./\.\./image/flow\.png) Our grammar, assumed to the stored in the
file "calculator\.peg" is

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

From this we create a snit\-based parser using the script "gen"

    package require Tcl 8.5
    package require fileutil
    package require pt::pgen

    lassign $argv name
    set grammar [fileutil::cat $name.peg]
    set pclass  [pt::pgen peg $gr snit -class $name -file  $name.peg -name  $name]
    fileutil::writeFile $name.tcl $pclass
    exit 0

calling it like

    tclsh8.5 gen calculator

which leaves us with the parser package and class written to the file
"calculator\.tcl"\. Assuming that this package is then properly installed in a
place where Tcl can find it we can now use this class via a script like

    package require calculator

    lassign $argv input
    set channel [open $input r]

    set parser [calculator]
    set ast [$parser parse $channel]
    $parser destroy
    close $channel

    ... now process the returned abstract syntax tree ...

where the abstract syntax tree stored in the variable will look like

    set ast {Expression 0 4
        {Factor 0 4
            {Term 0 2
                {Number 0 2
                    {Digit 0 0}
                    {Digit 1 1}
                    {Digit 2 2}


                }
            }
            {AddOp 3 3}
            {Term 4 4
                {Number 4 4
                    {Digit 4 4}




                }
            }
        }
    }

assuming that the input file and channel contained the text

    120+5

A more graphical representation of the tree would be

![](\.\./\.\./\.\./\.\./image/expr\_ast\.png) Regardless, at this point it is the
user's responsibility to work with the tree to reach whatever goal she desires\.
I\.e\. analyze it, transform it, etc\. The package
__[pt::ast](pt\_astree\.md)__ should be of help here, providing commands
Changes to embedded/md/tcllib/files/modules/pt/pt_rdengine.md.
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
     runtime internals are accessible to all instructions folded into the
     sequence\.

  - <a name='66'></a>*objectName* __si:void\_state\_push__

    This method combines

        i\_loc\_push
        i\_error\_clear
        i\_error\_push

    Parsers use it at the beginning of *void* sequences and choices with a
    *void* initial branch\.

  - <a name='67'></a>*objectName* __si:void2\_state\_push__

    This method combines

        i\_loc\_push
        i\_error\_clear
        i\_error\_push

    Parsers use it at the beginning of optional and repeated expressions\.

  - <a name='68'></a>*objectName* __si:value\_state\_push__

    This method combines

        i\_ast\_push
        i\_loc\_push
        i\_error\_clear
        i\_error\_push

    Parsers use it at the beginning of sequences generating an AST and choices
    with an initial branch generating an AST\.

  - <a name='69'></a>*objectName* __si:void\_state\_merge__

    This method combines

        i\_error\_pop\_merge
        i\_loc\_pop\_rewind/discard

    Parsers use it at the end of void sequences and choices whose last branch is
    void\.

  - <a name='70'></a>*objectName* __si:void\_state\_merge\_ok__

    This method combines

        i\_error\_pop\_merge
        i\_loc\_pop\_rewind/discard
        i\_status\_ok

    Parsers use it at the end of optional expressions

  - <a name='71'></a>*objectName* __si:value\_state\_merge__

    This method combines

        i\_error\_pop\_merge
        i\_ast\_pop\_rewind/discard
        i\_loc\_pop\_rewind/discard

    Parsers use it at the end of sequences generating ASTs and choices whose
    last branch generates an AST

  - <a name='72'></a>*objectName* __si:value\_notahead\_start__

    This method combines

        i\_loc\_push
        i\_ast\_push

    Parsers use it at the beginning of negative lookahead predicates which
    generate ASTs\.

  - <a name='73'></a>*objectName* __si:void\_notahead\_exit__

    This method combines

        i\_loc\_pop\_rewind
        i\_status\_negate

    Parsers use it at the end of void negative lookahead predicates\.

  - <a name='74'></a>*objectName* __si:value\_notahead\_exit__

    This method combines

        i\_ast\_pop\_discard/rewind
        i\_loc\_pop\_rewind
        i\_status\_negate

    Parsers use it at the end of negative lookahead predicates which generate
    ASTs\.

  - <a name='75'></a>*objectName* __si:kleene\_abort__

    This method combines

        i\_loc\_pop\_rewind/discard
        i:fail\_return

    Parsers use it to stop a positive repetition when its first, required,
    expression fails\.

  - <a name='76'></a>*objectName* __si:kleene\_close__

    This method combines

        i\_error\_pop\_merge
        i\_loc\_pop\_rewind/discard
        i:fail\_status\_ok
        i:fail\_return

    Parsers use it at the end of repetitions\.

  - <a name='77'></a>*objectName* __si:voidvoid\_branch__

    This method combines

        i\_error\_pop\_merge
        i:ok\_loc\_pop\_discard
        i:ok\_return
        i\_loc\_rewind
        i\_error\_push

    Parsers use it when transiting between branches of a choice when both are
    void\.

  - <a name='78'></a>*objectName* __si:voidvalue\_branch__

    This method combines

        i\_error\_pop\_merge
        i:ok\_loc\_pop\_discard
        i:ok\_return
        i\_ast\_push
        i\_loc\_rewind
        i\_error\_push

    Parsers use it when transiting between branches of a choice when the failing
    branch is void, and the next to test generates an AST\.

  - <a name='79'></a>*objectName* __si:valuevoid\_branch__

    This method combines

        i\_error\_pop\_merge
        i\_ast\_pop\_rewind/discard
        i:ok\_loc\_pop\_discard
        i:ok\_return
        i\_loc\_rewind
        i\_error\_push

    Parsers use it when transiting between branches of a choice when the failing
    branch generates an AST, and the next to test is void\.

  - <a name='80'></a>*objectName* __si:valuevalue\_branch__

    This method combines

        i\_error\_pop\_merge
        i\_ast\_pop\_discard
        i:ok\_loc\_pop\_discard
        i:ok\_return
        i\_ast\_rewind
        i\_loc\_rewind
        i\_error\_push

    Parsers use it when transiting between branches of a choice when both
    generate ASTs\.

  - <a name='81'></a>*objectName* __si:voidvoid\_part__

    This method combines

        i\_error\_pop\_merge
        i:fail\_loc\_pop\_rewind
        i:fail\_return
        i\_error\_push

    Parsers use it when transiting between parts of a sequence and both are
    void\.

  - <a name='82'></a>*objectName* __si:voidvalue\_part__

    This method combines

        i\_error\_pop\_merge
        i:fail\_loc\_pop\_rewind
        i:fail\_return
        i\_ast\_push
        i\_error\_push

    Parsers use it when transiting between parts of a sequence and the
    sucessfully matched part is void, and after it an AST is generated\.

  - <a name='83'></a>*objectName* __si:valuevalue\_part__

    This method combines

        i\_error\_pop\_merge
        i:fail\_ast\_pop\_rewind
        i:fail\_loc\_pop\_rewind
        i:fail\_return
        i\_error\_push

    Parsers use it when transiting between parts of a sequence and both parts
    generate ASTs\.

  - <a name='84'></a>*objectName* __si:value\_symbol\_start__ *symbol*

    This method combines

        if/found? i\_symbol\_restore $symbol
        i:found:ok\_ast\_value\_push
        i:found\_return
        i\_loc\_push
        i\_ast\_push

    Parsers use it at the beginning of a nonterminal symbol generating an AST,
    whose right\-hand side may have generated an AST as well\.

  - <a name='85'></a>*objectName* __si:value\_void\_symbol\_start__ *symbol*

    This method combines

        if/found? i\_symbol\_restore $symbol
        i:found:ok\_ast\_value\_push
        i:found\_return
        i\_loc\_push
        i\_ast\_push

    Parsers use it at the beginning of a void nonterminal symbol whose
    right\-hand side may generate an AST\.

  - <a name='86'></a>*objectName* __si:void\_symbol\_start__ *symbol*

    This method combines

        if/found? i\_symbol\_restore $symbol
        i:found\_return
        i\_loc\_push
        i\_ast\_push

    Parsers use it at the beginning of a nonterminal symbol generating an AST
    whose right\-hand side is void\.

  - <a name='87'></a>*objectName* __si:void\_void\_symbol\_start__ *symbol*

    This method combines

        if/found? i\_symbol\_restore $symbol
        i:found\_return
        i\_loc\_push

    Parsers use it at the beginning of a void nonterminal symbol whose
    right\-hand side is void as well\.

  - <a name='88'></a>*objectName* __si:reduce\_symbol\_end__ *symbol*

    This method combines

        i\_value\_clear/reduce $symbol
        i\_symbol\_save        $symbol
        i\_error\_nonterminal  $symbol
        i\_ast\_pop\_rewind
        i\_loc\_pop\_discard
        i:ok\_ast\_value\_push

    Parsers use it at the end of a non\-terminal symbol generating an AST using
    the AST generated by the right\-hand side as child\.

  - <a name='89'></a>*objectName* __si:void\_leaf\_symbol\_end__ *symbol*

    This method combines

        i\_value\_clear/leaf  $symbol
        i\_symbol\_save       $symbol
        i\_error\_nonterminal $symbol
        i\_loc\_pop\_discard
        i:ok\_ast\_value\_push

    Parsers use it at the end of a non\-terminal symbol generating an AST whose
    right\-hand side is void\.

  - <a name='90'></a>*objectName* __si:value\_leaf\_symbol\_end__ *symbol*

    This method combines

        i\_value\_clear/leaf  $symbol
        i\_symbol\_save       $symbol
        i\_error\_nonterminal $symbol
        i\_loc\_pop\_discard
        i\_ast\_pop\_rewind
        i:ok\_ast\_value\_push

    Parsers use it at the end of a non\-terminal symbol generating an AST
    discarding the AST generated by the right\-hand side\.

  - <a name='91'></a>*objectName* __si:value\_clear\_symbol\_end__ *symbol*

    This method combines

        i\_value\_clear
        i\_symbol\_save       $symbol
        i\_error\_nonterminal $symbol
        i\_loc\_pop\_discard
        i\_ast\_pop\_rewind

    Parsers use it at the end of a void non\-terminal symbol, discarding the AST
    generated by the right\-hand side\.

  - <a name='92'></a>*objectName* __si:void\_clear\_symbol\_end__ *symbol*

    This method combines

        i\_value\_clear
        i\_symbol\_save       $symbol
        i\_error\_nonterminal $symbol
        i\_loc\_pop\_discard

    Parsers use it at the end of a void non\-terminal symbol with a void
    right\-hand side\.

  - <a name='93'></a>*objectName* __si:next\_char__ *tok*

  - <a name='94'></a>*objectName* __si:next\_range__ *toks* *toke*







|
|
|








|
|
|







|
|
|
|








|
|








|
|
|







|
|
|








|
|








|
|







|
|
|








|
|








|
|
|
|







|
|
|
|
|








|
|
|
|
|
|








|
|
|
|
|
|








|
|
|
|
|
|
|








|
|
|
|








|
|
|
|
|








|
|
|
|
|








|
|
|
|
|








|
|
|
|
|








|
|
|
|








|
|
|








|
|
|
|
|
|








|
|
|
|
|








|
|
|
|
|
|








|
|
|
|
|








|
|
|
|







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
     runtime internals are accessible to all instructions folded into the
     sequence\.

  - <a name='66'></a>*objectName* __si:void\_state\_push__

    This method combines

        i_loc_push
        i_error_clear
        i_error_push

    Parsers use it at the beginning of *void* sequences and choices with a
    *void* initial branch\.

  - <a name='67'></a>*objectName* __si:void2\_state\_push__

    This method combines

        i_loc_push
        i_error_clear
        i_error_push

    Parsers use it at the beginning of optional and repeated expressions\.

  - <a name='68'></a>*objectName* __si:value\_state\_push__

    This method combines

        i_ast_push
        i_loc_push
        i_error_clear
        i_error_push

    Parsers use it at the beginning of sequences generating an AST and choices
    with an initial branch generating an AST\.

  - <a name='69'></a>*objectName* __si:void\_state\_merge__

    This method combines

        i_error_pop_merge
        i_loc_pop_rewind/discard

    Parsers use it at the end of void sequences and choices whose last branch is
    void\.

  - <a name='70'></a>*objectName* __si:void\_state\_merge\_ok__

    This method combines

        i_error_pop_merge
        i_loc_pop_rewind/discard
        i_status_ok

    Parsers use it at the end of optional expressions

  - <a name='71'></a>*objectName* __si:value\_state\_merge__

    This method combines

        i_error_pop_merge
        i_ast_pop_rewind/discard
        i_loc_pop_rewind/discard

    Parsers use it at the end of sequences generating ASTs and choices whose
    last branch generates an AST

  - <a name='72'></a>*objectName* __si:value\_notahead\_start__

    This method combines

        i_loc_push
        i_ast_push

    Parsers use it at the beginning of negative lookahead predicates which
    generate ASTs\.

  - <a name='73'></a>*objectName* __si:void\_notahead\_exit__

    This method combines

        i_loc_pop_rewind
        i_status_negate

    Parsers use it at the end of void negative lookahead predicates\.

  - <a name='74'></a>*objectName* __si:value\_notahead\_exit__

    This method combines

        i_ast_pop_discard/rewind
        i_loc_pop_rewind
        i_status_negate

    Parsers use it at the end of negative lookahead predicates which generate
    ASTs\.

  - <a name='75'></a>*objectName* __si:kleene\_abort__

    This method combines

        i_loc_pop_rewind/discard
        i:fail_return

    Parsers use it to stop a positive repetition when its first, required,
    expression fails\.

  - <a name='76'></a>*objectName* __si:kleene\_close__

    This method combines

        i_error_pop_merge
        i_loc_pop_rewind/discard
        i:fail_status_ok
        i:fail_return

    Parsers use it at the end of repetitions\.

  - <a name='77'></a>*objectName* __si:voidvoid\_branch__

    This method combines

        i_error_pop_merge
        i:ok_loc_pop_discard
        i:ok_return
        i_loc_rewind
        i_error_push

    Parsers use it when transiting between branches of a choice when both are
    void\.

  - <a name='78'></a>*objectName* __si:voidvalue\_branch__

    This method combines

        i_error_pop_merge
        i:ok_loc_pop_discard
        i:ok_return
        i_ast_push
        i_loc_rewind
        i_error_push

    Parsers use it when transiting between branches of a choice when the failing
    branch is void, and the next to test generates an AST\.

  - <a name='79'></a>*objectName* __si:valuevoid\_branch__

    This method combines

        i_error_pop_merge
        i_ast_pop_rewind/discard
        i:ok_loc_pop_discard
        i:ok_return
        i_loc_rewind
        i_error_push

    Parsers use it when transiting between branches of a choice when the failing
    branch generates an AST, and the next to test is void\.

  - <a name='80'></a>*objectName* __si:valuevalue\_branch__

    This method combines

        i_error_pop_merge
        i_ast_pop_discard
        i:ok_loc_pop_discard
        i:ok_return
        i_ast_rewind
        i_loc_rewind
        i_error_push

    Parsers use it when transiting between branches of a choice when both
    generate ASTs\.

  - <a name='81'></a>*objectName* __si:voidvoid\_part__

    This method combines

        i_error_pop_merge
        i:fail_loc_pop_rewind
        i:fail_return
        i_error_push

    Parsers use it when transiting between parts of a sequence and both are
    void\.

  - <a name='82'></a>*objectName* __si:voidvalue\_part__

    This method combines

        i_error_pop_merge
        i:fail_loc_pop_rewind
        i:fail_return
        i_ast_push
        i_error_push

    Parsers use it when transiting between parts of a sequence and the
    sucessfully matched part is void, and after it an AST is generated\.

  - <a name='83'></a>*objectName* __si:valuevalue\_part__

    This method combines

        i_error_pop_merge
        i:fail_ast_pop_rewind
        i:fail_loc_pop_rewind
        i:fail_return
        i_error_push

    Parsers use it when transiting between parts of a sequence and both parts
    generate ASTs\.

  - <a name='84'></a>*objectName* __si:value\_symbol\_start__ *symbol*

    This method combines

        if/found? i_symbol_restore $symbol
        i:found:ok_ast_value_push
        i:found_return
        i_loc_push
        i_ast_push

    Parsers use it at the beginning of a nonterminal symbol generating an AST,
    whose right\-hand side may have generated an AST as well\.

  - <a name='85'></a>*objectName* __si:value\_void\_symbol\_start__ *symbol*

    This method combines

        if/found? i_symbol_restore $symbol
        i:found:ok_ast_value_push
        i:found_return
        i_loc_push
        i_ast_push

    Parsers use it at the beginning of a void nonterminal symbol whose
    right\-hand side may generate an AST\.

  - <a name='86'></a>*objectName* __si:void\_symbol\_start__ *symbol*

    This method combines

        if/found? i_symbol_restore $symbol
        i:found_return
        i_loc_push
        i_ast_push

    Parsers use it at the beginning of a nonterminal symbol generating an AST
    whose right\-hand side is void\.

  - <a name='87'></a>*objectName* __si:void\_void\_symbol\_start__ *symbol*

    This method combines

        if/found? i_symbol_restore $symbol
        i:found_return
        i_loc_push

    Parsers use it at the beginning of a void nonterminal symbol whose
    right\-hand side is void as well\.

  - <a name='88'></a>*objectName* __si:reduce\_symbol\_end__ *symbol*

    This method combines

        i_value_clear/reduce $symbol
        i_symbol_save        $symbol
        i_error_nonterminal  $symbol
        i_ast_pop_rewind
        i_loc_pop_discard
        i:ok_ast_value_push

    Parsers use it at the end of a non\-terminal symbol generating an AST using
    the AST generated by the right\-hand side as child\.

  - <a name='89'></a>*objectName* __si:void\_leaf\_symbol\_end__ *symbol*

    This method combines

        i_value_clear/leaf  $symbol
        i_symbol_save       $symbol
        i_error_nonterminal $symbol
        i_loc_pop_discard
        i:ok_ast_value_push

    Parsers use it at the end of a non\-terminal symbol generating an AST whose
    right\-hand side is void\.

  - <a name='90'></a>*objectName* __si:value\_leaf\_symbol\_end__ *symbol*

    This method combines

        i_value_clear/leaf  $symbol
        i_symbol_save       $symbol
        i_error_nonterminal $symbol
        i_loc_pop_discard
        i_ast_pop_rewind
        i:ok_ast_value_push

    Parsers use it at the end of a non\-terminal symbol generating an AST
    discarding the AST generated by the right\-hand side\.

  - <a name='91'></a>*objectName* __si:value\_clear\_symbol\_end__ *symbol*

    This method combines

        i_value_clear
        i_symbol_save       $symbol
        i_error_nonterminal $symbol
        i_loc_pop_discard
        i_ast_pop_rewind

    Parsers use it at the end of a void non\-terminal symbol, discarding the AST
    generated by the right\-hand side\.

  - <a name='92'></a>*objectName* __si:void\_clear\_symbol\_end__ *symbol*

    This method combines

        i_value_clear
        i_symbol_save       $symbol
        i_error_nonterminal $symbol
        i_loc_pop_discard

    Parsers use it at the end of a void non\-terminal symbol with a void
    right\-hand side\.

  - <a name='93'></a>*objectName* __si:next\_char__ *tok*

  - <a name='94'></a>*objectName* __si:next\_range__ *toks* *toke*
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912

  - <a name='106'></a>*objectName* __si:next\_wordchar__

  - <a name='107'></a>*objectName* __si:next\_xdigit__

    These methods all combine

        i\_input\_next $msg
        i:fail\_return

    with the appropriate __i\_test\_xxx__ instruction\. Parsers use them for
    handling atomic expressions\.

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and







|
|







897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912

  - <a name='106'></a>*objectName* __si:next\_wordchar__

  - <a name='107'></a>*objectName* __si:next\_xdigit__

    These methods all combine

        i_input_next $msg
        i:fail_return

    with the appropriate __i\_test\_xxx__ instruction\. Parsers use them for
    handling atomic expressions\.

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
Changes to embedded/md/tcllib/files/modules/pt/pt_to_api.md.
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
    The value of this option is the name of the user for which the command is
    run\. The default value is __unknown__\.

# <a name='section5'></a>Usage

To use a converter do

    \# Get the converter \(single command here, not class\)
    package require the\-converter\-package

    \# Provide a configuration
    theconverter configure \.\.\.

    \# Perform the conversion
    set result \[theconverter convert $thegrammarserial\]

    \.\.\. process the result \.\.\.

To use a plugin __FOO__ do

    \# Get an export plugin manager
    package require pt::peg::export
    pt::peg::export E

    \# Provide a configuration
    E configuration set \.\.\.

    \# Run the plugin, and the converter inside\.
    set result \[E export serial $grammarserial FOO\]

    \.\.\. process the result \.\.\.

# <a name='section6'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG







|
|

|
|

|
|

|



|



|
|

|
|

|







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
    The value of this option is the name of the user for which the command is
    run\. The default value is __unknown__\.

# <a name='section5'></a>Usage

To use a converter do

    # Get the converter (single command here, not class)
    package require the-converter-package

    # Provide a configuration
    theconverter configure ...

    # Perform the conversion
    set result [theconverter convert $thegrammarserial]

    ... process the result ...

To use a plugin __FOO__ do

    # Get an export plugin manager
    package require pt::peg::export
    pt::peg::export E

    # Provide a configuration
    E configuration set ...

    # Run the plugin, and the converter inside.
    set result [E export serial $grammarserial FOO]

    ... process the result ...

# <a name='section6'></a>PEG serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expression Grammars as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a PEG
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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator \(Expression\)
        Digit      <\- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <\- '\-' / '\+'                                     ;
        Number     <\- Sign? Digit\+                                  ;
        Expression <\- Term \(AddOp Term\)\*                            ;
        MulOp      <\- '\*' / '/'                                     ;
        Term       <\- Factor \(MulOp Factor\)\*                        ;
        AddOp      <\- '\+'/'\-'                                       ;
        Factor     <\- '\(' Expression '\)' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg \{
        rules \{
            AddOp      \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Digit      \{is \{/ \{t 0\} \{t 1\} \{t 2\} \{t 3\} \{t 4\} \{t 5\} \{t 6\} \{t 7\} \{t 8\} \{t 9\}\}                mode value\}
            Expression \{is \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}                                        mode value\}
            Factor     \{is \{/ \{x \{t \(\} \{n Expression\} \{t \)\}\} \{n Number\}\}                                  mode value\}
            MulOp      \{is \{/ \{t \*\} \{t /\}\}                                                                mode value\}
            Number     \{is \{x \{? \{n Sign\}\} \{\+ \{n Digit\}\}\}                                                 mode value\}
            Sign       \{is \{/ \{t \-\} \{t \+\}\}                                                                mode value\}
            Term       \{is \{x \{n Factor\} \{\* \{x \{n MulOp\} \{n Factor\}\}\}\}                                    mode value\}
        \}

        start \{n Expression\}
    \}


# <a name='section7'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a







|
|
|
|
|
|
|
|
|




|
|
|
|
|
|
|
|
|
|
<
>
|
<
>







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
      1. The string representation of the value is the canonical representation
         of a Tcl dictionary\. I\.e\. it does not contain superfluous whitespace\.

## <a name='subsection1'></a>Example

Assuming the following PEG for simple mathematical expressions

    PEG calculator (Expression)
        Digit      <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9'       ;
        Sign       <- '-' / '+'                                     ;
        Number     <- Sign? Digit+                                  ;
        Expression <- Term (AddOp Term)*                            ;
        MulOp      <- '*' / '/'                                     ;
        Term       <- Factor (MulOp Factor)*                        ;
        AddOp      <- '+'/'-'                                       ;
        Factor     <- '(' Expression ')' / Number                   ;
    END;

then its canonical serialization \(except for whitespace\) is

    pt::grammar::peg {
        rules {
            AddOp      {is {/ {t -} {t +}}                                                                mode value}
            Digit      {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}}                mode value}
            Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}}                                        mode value}
            Factor     {is {/ {x {t (} {n Expression} {t )}} {n Number}}                                  mode value}
            MulOp      {is {/ {t *} {t /}}                                                                mode value}
            Number     {is {x {? {n Sign}} {+ {n Digit}}}                                                 mode value}
            Sign       {is {/ {t -} {t +}}                                                                mode value}
            Term       {is {x {n Factor} {* {x {n MulOp} {n Factor}}}}                                    mode value}

        }
        start {n Expression}

    }

# <a name='section7'></a>PE serialization format

Here we specify the format used by the Parser Tools to serialize Parsing
Expressions as immutable values for transport, comparison, etc\.

We distinguish between *regular* and *canonical* serializations\. While a
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <\- Term \(AddOp Term\)\*

then its canonical serialization \(except for whitespace\) is

    \{x \{n Term\} \{\* \{x \{n AddOp\} \{n Term\}\}\}\}

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|



|







480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
      1. Terminals are *not* encoded as ranges \(where start and end of the
         range are identical\)\.

## <a name='subsection2'></a>Example

Assuming the parsing expression shown on the right\-hand side of the rule

    Expression <- Term (AddOp Term)*

then its canonical serialization \(except for whitespace\) is

    {x {n Term} {* {x {n AddOp} {n Term}}}}

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *pt* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/rc4/rc4.md.
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
  - <a name='4'></a>__::rc4::RC4Final__ *Key*

    This should be called to clean up resources associated with *Key*\. Once
    this function has been called the key is destroyed\.

# <a name='section4'></a>EXAMPLES

    % set keydata \[binary format H\* 0123456789abcdef\]
    % rc4::rc4 \-hex \-key $keydata HelloWorld
    3cf1ae8b7f1c670b612f
    % rc4::rc4 \-hex \-key $keydata \[binary format H\* 3cf1ae8b7f1c670b612f\]
    HelloWorld

    set Key \[rc4::RC4Init "key data"\]
    append ciphertext \[rc4::RC4 $Key $plaintext\]
    append ciphertext \[rc4::RC4 $Key $additional\_plaintext\]
    rc4::RC4Final $Key

    proc ::Finish \{myState data\} \{
        DoStuffWith $myState $data
    \}

    rc4::rc4 \-in $socket \-command \[list ::Finish $ApplicationState\]

# <a name='section5'></a>AUTHORS

Pat Thoyts

# <a name='section6'></a>Bugs, Ideas, Feedback








|
|

|


|
|
|


|

<
>
|







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
  - <a name='4'></a>__::rc4::RC4Final__ *Key*

    This should be called to clean up resources associated with *Key*\. Once
    this function has been called the key is destroyed\.

# <a name='section4'></a>EXAMPLES

    % set keydata [binary format H* 0123456789abcdef]
    % rc4::rc4 -hex -key $keydata HelloWorld
    3cf1ae8b7f1c670b612f
    % rc4::rc4 -hex -key $keydata [binary format H* 3cf1ae8b7f1c670b612f]
    HelloWorld

    set Key [rc4::RC4Init "key data"]
    append ciphertext [rc4::RC4 $Key $plaintext]
    append ciphertext [rc4::RC4 $Key $additional_plaintext]
    rc4::RC4Final $Key

    proc ::Finish {myState data} {
        DoStuffWith $myState $data

    }
    rc4::rc4 -in $socket -command [list ::Finish $ApplicationState]

# <a name='section5'></a>AUTHORS

Pat Thoyts

# <a name='section6'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/rcs/rcs.md.
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

    Hello World,
    how are you ?
    Fine, and you ?

for example can be represented by

    \{\{1 \{Hello World,\}\} \{2 \{how are you ?\}\} \{3 \{Fine, and you ?\}\}\}

or

    \{\{5 \{Hello World,\}\} \{8 \{how are you ?\}\} \{9 \{Fine, and you ?\}\}\}

or

    \{\{\-1 \{Hello World,
    how are you ?\}\} \{4 \{Fine, and you ?\}\}\}

The first dictionary is the *canonical* representation of the text, with line
numbers starting at __1__, increasing in steps of __1__ and without
gaps, and each value representing exactly one physical line\.

All the commands creating dictionaries from text will return the canonical
representation of their input text\. The commands taking a dictionary and







|



|



|
|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

    Hello World,
    how are you ?
    Fine, and you ?

for example can be represented by

    {{1 {Hello World,}} {2 {how are you ?}} {3 {Fine, and you ?}}}

or

    {{5 {Hello World,}} {8 {how are you ?}} {9 {Fine, and you ?}}}

or

    {{-1 {Hello World,
    how are you ?}} {4 {Fine, and you ?}}}

The first dictionary is the *canonical* representation of the text, with line
numbers starting at __1__, increasing in steps of __1__ and without
gaps, and each value representing exactly one physical line\.

All the commands creating dictionaries from text will return the canonical
representation of their input text\. The commands taking a dictionary and
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
at the functional level\.

And example of a RCS patch is

    d1 2
    d4 1
    a4 2
    The named is the mother of all things\.

    a11 3
    They both may be called deep and profound\.
    Deeper and more profound,
    The door of all subtleties\!

# <a name='section5'></a>RCS PATCH COMMAND LIST

Patch command lists \(sort: PCL's\) are the data structures generated by patch
decoder command and accepted by the patch encoder and applicator commands\. They
represent RCS patches in the form of Tcl data structures\.








|


|

|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
at the functional level\.

And example of a RCS patch is

    d1 2
    d4 1
    a4 2
    The named is the mother of all things.

    a11 3
    They both may be called deep and profound.
    Deeper and more profound,
    The door of all subtleties!

# <a name='section5'></a>RCS PATCH COMMAND LIST

Patch command lists \(sort: PCL's\) are the data structures generated by patch
decoder command and accepted by the patch encoder and applicator commands\. They
represent RCS patches in the form of Tcl data structures\.

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

This is the format returned by the patch decoder command and accepted as input
by the patch encoder and applicator commands\.

An example for a patch command is shown below, it represents the example RCS
patch found in section [RCS PATCH FORMAT](#section4)\.

    \{\{d 1 2\} \{d 4 1\} \{a 4 \{The named is the mother of all things\.

    \}\} \{a 11 \{They both may be called deep and profound\.
    Deeper and more profound,
    The door of all subtleties\!\}\}\}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *rcs* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|

|







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

This is the format returned by the patch decoder command and accepted as input
by the patch encoder and applicator commands\.

An example for a patch command is shown below, it represents the example RCS
patch found in section [RCS PATCH FORMAT](#section4)\.

    {{d 1 2} {d 4 1} {a 4 {The named is the mother of all things.

    }} {a 11 {They both may be called deep and profound.
    Deeper and more profound,
    The door of all subtleties!}}}

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *rcs* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/report/report.md.
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
# <a name='section7'></a>EXAMPLES

Our examples define some generally useful report styles\.

A simple table with lines surrounding all information and vertical separators,
but without internal horizontal separators\.

        ::report::defstyle simpletable \{\} \{
    	data	set \[split "\[string repeat "&#124; "   \[columns\]\]&#124;"\]
    	top	set \[split "\[string repeat "\+ \- " \[columns\]\]\+"\]
    	bottom	set \[top get\]
    	top	enable
    	bottom	enable
        \}


An extension of a __simpletable__, see above, with a title area\.

        ::report::defstyle captionedtable \{\{n 1\}\} \{
    	simpletable
    	topdata   set \[data get\]
    	topcapsep set \[top get\]
    	topcapsep enable
    	tcaption $n
        \}


Given the definitions above now an example which actually formats a matrix into
a tabular report\. It assumes that the matrix actually contains useful data\.

    % ::struct::matrix m
    % \# \.\.\. fill m with data, assume 5 columns
    % ::report::report r 5 style captionedtable 1
    % r printmatrix m
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    &#124;000&#124;VERSIONS:          &#124;2:8\.4a3&#124;1:8\.4a3&#124;1:8\.4a3%&#124;
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    &#124;001&#124;CATCH return ok    &#124;7      &#124;13     &#124;53\.85   &#124;
    &#124;002&#124;CATCH return error &#124;68     &#124;91     &#124;74\.73   &#124;
    &#124;003&#124;CATCH no catch used&#124;7      &#124;14     &#124;50\.00   &#124;
    &#124;004&#124;IF if true numeric &#124;12     &#124;33     &#124;36\.36   &#124;
    &#124;005&#124;IF elseif          &#124;15     &#124;47     &#124;31\.91   &#124;
    &#124;   &#124;true numeric       &#124;       &#124;       &#124;        &#124;
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    %
    % \# alternate way of doing the above
    % m format 2string r

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *report* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|
|
|
|


<
>



|

|
|


<
>





|


|
|
|
|
|
|
|
|
|
|

|







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
# <a name='section7'></a>EXAMPLES

Our examples define some generally useful report styles\.

A simple table with lines surrounding all information and vertical separators,
but without internal horizontal separators\.

        ::report::defstyle simpletable {} {
    	data	set [split "[string repeat "| "   [columns]]|"]
    	top	set [split "[string repeat "+ - " [columns]]+"]
    	bottom	set [top get]
    	top	enable
    	bottom	enable

        }

An extension of a __simpletable__, see above, with a title area\.

        ::report::defstyle captionedtable {{n 1}} {
    	simpletable
    	topdata   set [data get]
    	topcapsep set [top get]
    	topcapsep enable
    	tcaption $n

        }

Given the definitions above now an example which actually formats a matrix into
a tabular report\. It assumes that the matrix actually contains useful data\.

    % ::struct::matrix m
    % # ... fill m with data, assume 5 columns
    % ::report::report r 5 style captionedtable 1
    % r printmatrix m
    +---+-------------------+-------+-------+--------+
    |000|VERSIONS:          |2:8.4a3|1:8.4a3|1:8.4a3%|
    +---+-------------------+-------+-------+--------+
    |001|CATCH return ok    |7      |13     |53.85   |
    |002|CATCH return error |68     |91     |74.73   |
    |003|CATCH no catch used|7      |14     |50.00   |
    |004|IF if true numeric |12     |33     |36.36   |
    |005|IF elseif          |15     |47     |31.91   |
    |   |true numeric       |       |       |        |
    +---+-------------------+-------+-------+--------+
    %
    % # alternate way of doing the above
    % m format 2string r

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *report* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/rest/rest.md.
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

    Two quick examples:

    Example 1, Yahoo Boss:

        set appid APPID
        set search tcl
        set res \[rest::get http://boss\.yahooapis\.com/ysearch/web/v1/$search \[list appid $appid\]\]
        set res \[rest::format\_json $res\]

    Example 2, Twitter:

        set url   http://twitter\.com/statuses/update\.json
        set query \[list status $text\]
        set res \[rest::simple $url $query \{
            method post
            auth   \{basic user password\}
            format json
        \}\]

# <a name='section3'></a>Interface usage

An interface to a REST API consists of a series of definitions of REST calls
contained in an array\. The name of that array becomes a namespace containing the
defined commands\. Each key of the array specifies the name of the call, with the
associated configuration a dictionary, i\.e\. key/value pairs\. The acceptable
keys, i\.e\. legal configuration options are described below\. After creating the
definitions in the array simply calling __rest::create\_interface__ with the
array as argument will then create the desired commands\.

Example, Yahoo Weather:

    package require rest

    set yweather\(forecast\) \{
       url      http://weather\.yahooapis\.com/forecastrss
       req\_args \{ p: \}
       opt\_args \{ u: \}
    \}

    rest::create\_interface yweather
    puts \[yweather::forecast \-p 94089\]

  - <a name='8'></a>__::rest::save__ *name* *file*

    This command saves a copy of the dynamically created procedures for all the
    API calls specified in the array variable *name* to the *file*, for
    later loading\.








|
|



|
|
|

|

|















|
|
|
|
<
>
|
|







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

    Two quick examples:

    Example 1, Yahoo Boss:

        set appid APPID
        set search tcl
        set res [rest::get http://boss.yahooapis.com/ysearch/web/v1/$search [list appid $appid]]
        set res [rest::format_json $res]

    Example 2, Twitter:

        set url   http://twitter.com/statuses/update.json
        set query [list status $text]
        set res [rest::simple $url $query {
            method post
            auth   {basic user password}
            format json
        }]

# <a name='section3'></a>Interface usage

An interface to a REST API consists of a series of definitions of REST calls
contained in an array\. The name of that array becomes a namespace containing the
defined commands\. Each key of the array specifies the name of the call, with the
associated configuration a dictionary, i\.e\. key/value pairs\. The acceptable
keys, i\.e\. legal configuration options are described below\. After creating the
definitions in the array simply calling __rest::create\_interface__ with the
array as argument will then create the desired commands\.

Example, Yahoo Weather:

    package require rest

    set yweather(forecast) {
       url      http://weather.yahooapis.com/forecastrss
       req_args { p: }
       opt_args { u: }

    }
    rest::create_interface yweather
    puts [yweather::forecast -p 94089]

  - <a name='8'></a>__::rest::save__ *name* *file*

    This command saves a copy of the dynamically created procedures for all the
    API calls specified in the array variable *name* to the *file*, for
    later loading\.

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

        See __callback__ above for more information\.

# <a name='section4'></a>Examples

Yahoo Geo:

    set ygeo\(parse\) \{
        url http://wherein\.yahooapis\.com/v1/document
        method post
        body \{ arg documentContent \}
    \}

    ygeo::parse "san jose ca"
    \# "san jose ca" will be interpreted as if it were specified as the \-documentContent option

Google Docs:

    set gdocs\(upload\) \{
        url http://docs\.google\.com/feeds/default/private/full
        body mime\_multipart
    \}

    gdocs::upload \[list \{Content\-Type application/atom\+xml\} $xml\] \[list \{Content\-Type image/jpeg\} $filedata\]

Delicious:

    set delicious\(updated\) \{
        url https://api\.del\.icio\.us/v1/posts/update
        auth basic
    \}


    rest::create\_interface flickr

    flickr::basic\_auth username password

Flickr:

    set flickr\(auth\.getToken\) \{
       url http://api\.flickr\.com/services/rest/
       req\_args \{ api\_key: secret: \}
       auth \{ sign do\_signature \}
    \}


    rest::create\_interface flickr

    proc ::flickr::do\_signature \{query\} \{
        \# perform some operations on the query here
        return $query
    \}


# <a name='section5'></a>INCLUDED

The package provides functional but incomplete implementations for the following
services:

  - __del\.icio\.us__







|
|

|
<
>

|



|
|
|
<
>
|



|
|

<
|
>
|

|



|
|
|
|
<
|
>
|

|
|

<
>







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

        See __callback__ above for more information\.

# <a name='section4'></a>Examples

Yahoo Geo:

    set ygeo(parse) {
        url http://wherein.yahooapis.com/v1/document
        method post
        body { arg documentContent }

    }
    ygeo::parse "san jose ca"
    # "san jose ca" will be interpreted as if it were specified as the -documentContent option

Google Docs:

    set gdocs(upload) {
        url http://docs.google.com/feeds/default/private/full
        body mime_multipart

    }
    gdocs::upload [list {Content-Type application/atom+xml} $xml] [list {Content-Type image/jpeg} $filedata]

Delicious:

    set delicious(updated) {
        url https://api.del.icio.us/v1/posts/update
        auth basic

    }

    rest::create_interface flickr

    flickr::basic_auth username password

Flickr:

    set flickr(auth.getToken) {
       url http://api.flickr.com/services/rest/
       req_args { api_key: secret: }
       auth { sign do_signature }

    }

    rest::create_interface flickr

    proc ::flickr::do_signature {query} {
        # perform some operations on the query here
        return $query

    }

# <a name='section5'></a>INCLUDED

The package provides functional but incomplete implementations for the following
services:

  - __del\.icio\.us__
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *rest* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|







555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section8'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *rest* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/ripemd/ripemd128.md.
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

  - <a name='8'></a>__::ripemd::RIPEHMAC128Final__ *token*

    These commands are identical to the RIPEMD128 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % ripemd::ripemd128 \-hex "Tcl does RIPEMD\-128"
    3cab177bae65205d81e7978f63556c63

    % ripemd::hmac128 \-hex \-key Sekret "Tcl does RIPEMD\-128"
    b359dc5971a05beea0be7b106b30e389

    % set tok \[ripemd::RIPEMD128Init\]
    ::ripemd::1
    % ripemd::RIPEMD128Update $tok "Tcl "
    % ripemd::RIPEMD128Update $tok "does "
    % ripemd::RIPEMD128Update $tok "RIPEMD\-128"
    % ripemd::Hex \[ripemd::RIPEMD128Final $tok\]
    3cab177bae65205d81e7978f63556c63

# <a name='section5'></a>REFERENCES

  1. H\. Dobbertin, A\. Bosselaers, B\. Preneel, "RIPEMD\-160, a strengthened
     version of RIPEMD"
     [http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf](http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf)







|


|


|



|
|







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

  - <a name='8'></a>__::ripemd::RIPEHMAC128Final__ *token*

    These commands are identical to the RIPEMD128 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % ripemd::ripemd128 -hex "Tcl does RIPEMD-128"
    3cab177bae65205d81e7978f63556c63

    % ripemd::hmac128 -hex -key Sekret "Tcl does RIPEMD-128"
    b359dc5971a05beea0be7b106b30e389

    % set tok [ripemd::RIPEMD128Init]
    ::ripemd::1
    % ripemd::RIPEMD128Update $tok "Tcl "
    % ripemd::RIPEMD128Update $tok "does "
    % ripemd::RIPEMD128Update $tok "RIPEMD-128"
    % ripemd::Hex [ripemd::RIPEMD128Final $tok]
    3cab177bae65205d81e7978f63556c63

# <a name='section5'></a>REFERENCES

  1. H\. Dobbertin, A\. Bosselaers, B\. Preneel, "RIPEMD\-160, a strengthened
     version of RIPEMD"
     [http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf](http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf)
Changes to embedded/md/tcllib/files/modules/ripemd/ripemd160.md.
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

  - <a name='8'></a>__::ripemd::RIPEHMAC160Final__ *token*

    These commands are identical to the RIPEMD160 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % ripemd::ripemd160 \-hex "Tcl does RIPEMD\-160"
    0829dea75a1a7074c702896723fe37763481a0a7

    % ripemd::hmac160 \-hex \-key Sekret "Tcl does RIPEMD\-160"
    bf0c927231733686731dddb470b64a9c23f7f53b

    % set tok \[ripemd::RIPEMD160Init\]
    ::ripemd::1
    % ripemd::RIPEMD160Update $tok "Tcl "
    % ripemd::RIPEMD160Update $tok "does "
    % ripemd::RIPEMD160Update $tok "RIPEMD\-160"
    % ripemd::Hex \[ripemd::RIPEMD160Final $tok\]
    0829dea75a1a7074c702896723fe37763481a0a7

# <a name='section5'></a>REFERENCES

  1. H\. Dobbertin, A\. Bosselaers, B\. Preneel, "RIPEMD\-160, a strengthened
     version of RIPEMD"
     [http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf](http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf)







|


|


|



|
|







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

  - <a name='8'></a>__::ripemd::RIPEHMAC160Final__ *token*

    These commands are identical to the RIPEMD160 equivalent commands\.

# <a name='section4'></a>EXAMPLES

    % ripemd::ripemd160 -hex "Tcl does RIPEMD-160"
    0829dea75a1a7074c702896723fe37763481a0a7

    % ripemd::hmac160 -hex -key Sekret "Tcl does RIPEMD-160"
    bf0c927231733686731dddb470b64a9c23f7f53b

    % set tok [ripemd::RIPEMD160Init]
    ::ripemd::1
    % ripemd::RIPEMD160Update $tok "Tcl "
    % ripemd::RIPEMD160Update $tok "does "
    % ripemd::RIPEMD160Update $tok "RIPEMD-160"
    % ripemd::Hex [ripemd::RIPEMD160Final $tok]
    0829dea75a1a7074c702896723fe37763481a0a7

# <a name='section5'></a>REFERENCES

  1. H\. Dobbertin, A\. Bosselaers, B\. Preneel, "RIPEMD\-160, a strengthened
     version of RIPEMD"
     [http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf](http://www\.esat\.kuleuven\.ac\.be/~cosicart/pdf/AB\-9601/AB\-9601\.pdf)
Changes to embedded/md/tcllib/files/modules/sasl/gtoken.md.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section3'></a>AUTHORS

Pat Thoyts

# <a name='section4'></a>Bugs, Ideas, Feedback








|

|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section3'></a>AUTHORS

Pat Thoyts

# <a name='section4'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/sasl/sasl.md.
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

See the examples subdirectory for more complete samples using SASL with network
protocols\. The following should give an idea how the SASL commands are to be
used\. In reality this should be event driven\. Each time the __step__ command
is called, the last server response should be provided as the command argument
so that the SASL mechanism can take appropriate action\.

    proc ClientCallback \{context command args\} \{
        switch \-exact \-\- $command \{
            login    \{ return "" \}
            username \{ return $::tcl\_platform\(user\) \}
            password \{ return "SecRet" \}
            realm    \{ return "" \}
            hostname \{ return \[info host\] \}
            default  \{ return \-code error unxpected \}
        \}
    \}



    proc Demo \{\{mech PLAIN\}\} \{
        set ctx \[SASL::new \-mechanism $mech \-callback ClientCallback\]
        set challenge ""
        while \{1\} \{
            set more\_steps \[SASL::step $ctx challenge\]
            puts "Send '\[SASL::response $ctx\]'"
            puts "Read server response into challenge var"
            if \{\!$more\_steps\} \{break\}
        \}

        SASL::cleanup $ctx
    \}


# <a name='section7'></a>REFERENCES

  1. Myers, J\. "Simple Authentication and Security Layer \(SASL\)", RFC 2222,
     October 1997\.
     \([http://www\.ietf\.org/rfc/rfc2222\.txt](http://www\.ietf\.org/rfc/rfc2222\.txt)\)








|
|
|
|
|
|
|
|
<
<
|
>
>
|
|

|
|
|

|
<
>

<
>







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

See the examples subdirectory for more complete samples using SASL with network
protocols\. The following should give an idea how the SASL commands are to be
used\. In reality this should be event driven\. Each time the __step__ command
is called, the last server response should be provided as the command argument
so that the SASL mechanism can take appropriate action\.

    proc ClientCallback {context command args} {
        switch -exact -- $command {
            login    { return "" }
            username { return $::tcl_platform(user) }
            password { return "SecRet" }
            realm    { return "" }
            hostname { return [info host] }
            default  { return -code error unxpected }


        }
    }

    proc Demo {{mech PLAIN}} {
        set ctx [SASL::new -mechanism $mech -callback ClientCallback]
        set challenge ""
        while {1} {
            set more_steps [SASL::step $ctx challenge]
            puts "Send '[SASL::response $ctx]'"
            puts "Read server response into challenge var"
            if {!$more_steps} {break}

        }
        SASL::cleanup $ctx

    }

# <a name='section7'></a>REFERENCES

  1. Myers, J\. "Simple Authentication and Security Layer \(SASL\)", RFC 2222,
     October 1997\.
     \([http://www\.ietf\.org/rfc/rfc2222\.txt](http://www\.ietf\.org/rfc/rfc2222\.txt)\)

Changes to embedded/md/tcllib/files/modules/sha1/sha1.md.
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

    % sha1::sha1 "Tcl does SHA1"
    285a6a91c45a9066bf39fcf24425796ef0b2a8bf

    % sha1::hmac Sekret "Tcl does SHA1"
    ae6251fa51b95b18cba2be95eb031d07475ff03c

    % set tok \[sha1::SHA1Init\]
    ::sha1::1
    % sha1::SHA1Update $tok "Tcl "
    % sha1::SHA1Update $tok "does "
    % sha1::SHA1Update $tok "SHA1"
    % sha1::Hex \[sha1::SHA1Final $tok\]
    285a6a91c45a9066bf39fcf24425796ef0b2a8bf

# <a name='section5'></a>REFERENCES

  1. "Secure Hash Standard", National Institute of Standards and Technology,
     U\.S\. Department Of Commerce, April 1995\.
     \([http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm](http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm)\)







|




|







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

    % sha1::sha1 "Tcl does SHA1"
    285a6a91c45a9066bf39fcf24425796ef0b2a8bf

    % sha1::hmac Sekret "Tcl does SHA1"
    ae6251fa51b95b18cba2be95eb031d07475ff03c

    % set tok [sha1::SHA1Init]
    ::sha1::1
    % sha1::SHA1Update $tok "Tcl "
    % sha1::SHA1Update $tok "does "
    % sha1::SHA1Update $tok "SHA1"
    % sha1::Hex [sha1::SHA1Final $tok]
    285a6a91c45a9066bf39fcf24425796ef0b2a8bf

# <a name='section5'></a>REFERENCES

  1. "Secure Hash Standard", National Institute of Standards and Technology,
     U\.S\. Department Of Commerce, April 1995\.
     \([http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm](http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm)\)
Changes to embedded/md/tcllib/files/modules/sha1/sha256.md.
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

    % sha2::sha256 "Tcl does SHA256"
    0b91043ee484abd83c3e4b08d6034d71b937026379f0f59bda6e625e6e214789

    % sha2::hmac Sekret "Tcl does SHA256"
    4f9352c64d655e8a36abe73e6163a9d7a54039877c1c92ec90b07d48d4e854e0

    % set tok \[sha2::SHA256Init\]
    ::sha2::1
    % sha2::SHA256Update $tok "Tcl "
    % sha2::SHA256Update $tok "does "
    % sha2::SHA256Update $tok "SHA256"
    % sha2::Hex \[sha2::SHA256Final $tok\]
    0b91043ee484abd83c3e4b08d6034d71b937026379f0f59bda6e625e6e214789

# <a name='section5'></a>REFERENCES

  1. "Secure Hash Standard", National Institute of Standards and Technology,
     U\.S\. Department Of Commerce, April 1995\.
     \([http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm](http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm)\)







|




|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

    % sha2::sha256 "Tcl does SHA256"
    0b91043ee484abd83c3e4b08d6034d71b937026379f0f59bda6e625e6e214789

    % sha2::hmac Sekret "Tcl does SHA256"
    4f9352c64d655e8a36abe73e6163a9d7a54039877c1c92ec90b07d48d4e854e0

    % set tok [sha2::SHA256Init]
    ::sha2::1
    % sha2::SHA256Update $tok "Tcl "
    % sha2::SHA256Update $tok "does "
    % sha2::SHA256Update $tok "SHA256"
    % sha2::Hex [sha2::SHA256Final $tok]
    0b91043ee484abd83c3e4b08d6034d71b937026379f0f59bda6e625e6e214789

# <a name='section5'></a>REFERENCES

  1. "Secure Hash Standard", National Institute of Standards and Technology,
     U\.S\. Department Of Commerce, April 1995\.
     \([http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm](http://www\.itl\.nist\.gov/fipspubs/fip180\-1\.htm)\)
Changes to embedded/md/tcllib/files/modules/simulation/annealing.md.
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    stuck in a local optimum and theoretically it is capable of finding the
    global optimum within the search space\.

The method resembles the cooling of material, hence the name\.

The package *simulation::annealing* offers the command *findMinimum*:

    puts \[::simulation::annealing::findMinimum  \-trials 300  \-parameters \{x \-5\.0 5\.0 y \-5\.0 5\.0\}  \-function \{$x\*$x\+$y\*$y\+sin\(10\.0\*$x\)\+4\.0\*cos\(20\.0\*$y\)\}\]

prints the estimated minimum value of the function f\(x,y\) =
*x\*\*2\+y\*\*2\+sin\(10\*x\)\+4\*cos\(20\*y\)* and the values of x and y where the minimum
was attained:

    result \-4\.9112922923 x \-0\.181647676593 y 0\.155743646974

# <a name='section2'></a>PROCEDURES

The package defines the following auxiliary procedures:

  - <a name='1'></a>__::simulation::annealing::getOption__ *keyword*








|





|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    stuck in a local optimum and theoretically it is capable of finding the
    global optimum within the search space\.

The method resembles the cooling of material, hence the name\.

The package *simulation::annealing* offers the command *findMinimum*:

    puts [::simulation::annealing::findMinimum  -trials 300  -parameters {x -5.0 5.0 y -5.0 5.0}  -function {$x*$x+$y*$y+sin(10.0*$x)+4.0*cos(20.0*$y)}]

prints the estimated minimum value of the function f\(x,y\) =
*x\*\*2\+y\*\*2\+sin\(10\*x\)\+4\*cos\(20\*y\)* and the values of x and y where the minimum
was attained:

    result -4.9112922923 x -0.181647676593 y 0.155743646974

# <a name='section2'></a>PROCEDURES

The package defines the following auxiliary procedures:

  - <a name='1'></a>__::simulation::annealing::getOption__ *keyword*

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

  - This does mean that the automatic determination of a scale factor is out of
    the question \- the high function values that force the point inside the
    region would distort the estimation\.

Here is an example of finding an optimum inside a circle:

    puts \[::simulation::annealing::findMinimum  \-trials 3000  \-reduce 0\.98  \-parameters \{x \-5\.0 5\.0 y \-5\.0 5\.0\}  \-code \{
            if \{ hypot\($x\-5\.0,$y\-5\.0\) < 4\.0 \} \{
                set result \[expr \{$x\*$x\+$y\*$y\+sin\(10\.0\*$x\)\+4\.0\*cos\(20\.0\*$y\)\}\]
            \} else \{
                set result 1\.0e100

            \}
        \}\]

The method is theoretically capable of determining the global optimum, but often
you need to use a large number of trials and a slow reduction of temperature to
get reliable and repeatable estimates\.

You can use the *\-final* option to use a deterministic optimization method,
once you are sure you are near the required optimum\.

The *findCombinatorialMinimum* procedure is suited for situations where the
parameters have the values 0 or 1 \(and there can be many of them\)\. Here is an
example:

  - We have a function that attains an absolute minimum if the first ten numbers
    are 1 and the rest is 0:

    proc cost \{params\} \{
        set cost 0
        foreach p \[lrange $params 0 9\] \{
            if \{ $p == 0 \} \{
                incr cost
            \}
        \}


        foreach p \[lrange $params 10 end\] \{
            if \{ $p == 1 \} \{
                incr cost
            \}
        \}


        return $cost
    \}


  - We want to find the solution that gives this minimum for various lengths of
    the solution vector *params*:

    foreach n \{100 1000 10000\} \{
        break
        puts "Problem size: $n"
        puts \[::simulation::annealing::findCombinatorialMinimum  \-trials 300  \-verbose 0  \-number\-params $n  \-code \{set result \[cost $params\]\}\]
    \}


  - As the vector grows, the computation time increases, but the procedure will
    stop if some kind of equilibrium is reached\. To achieve a useful solution
    you may want to try different values of the trials parameter for instance\.
    Also ensure that the function to be minimized depends on all or most
    parameters \- see the source code for a counter example and run that\.








|
|
|
|
|
>
|
<















|

|
|

<
<
>
>
|
|

<
<
>
>

<
>




|


|
<
>







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

  - This does mean that the automatic determination of a scale factor is out of
    the question \- the high function values that force the point inside the
    region would distort the estimation\.

Here is an example of finding an optimum inside a circle:

    puts [::simulation::annealing::findMinimum  -trials 3000  -reduce 0.98  -parameters {x -5.0 5.0 y -5.0 5.0}  -code {
            if { hypot($x-5.0,$y-5.0) < 4.0 } {
                set result [expr {$x*$x+$y*$y+sin(10.0*$x)+4.0*cos(20.0*$y)}]
            } else {
                set result 1.0e100
            }
        }]


The method is theoretically capable of determining the global optimum, but often
you need to use a large number of trials and a slow reduction of temperature to
get reliable and repeatable estimates\.

You can use the *\-final* option to use a deterministic optimization method,
once you are sure you are near the required optimum\.

The *findCombinatorialMinimum* procedure is suited for situations where the
parameters have the values 0 or 1 \(and there can be many of them\)\. Here is an
example:

  - We have a function that attains an absolute minimum if the first ten numbers
    are 1 and the rest is 0:

    proc cost {params} {
        set cost 0
        foreach p [lrange $params 0 9] {
            if { $p == 0 } {
                incr cost


            }
        }
        foreach p [lrange $params 10 end] {
            if { $p == 1 } {
                incr cost


            }
        }
        return $cost

    }

  - We want to find the solution that gives this minimum for various lengths of
    the solution vector *params*:

    foreach n {100 1000 10000} {
        break
        puts "Problem size: $n"
        puts [::simulation::annealing::findCombinatorialMinimum  -trials 300  -verbose 0  -number-params $n  -code {set result [cost $params]}]

    }

  - As the vector grows, the computation time increases, but the procedure will
    stop if some kind of equilibrium is reached\. To achieve a useful solution
    you may want to try different values of the trials parameter for instance\.
    Also ensure that the function to be minimized depends on all or most
    parameters \- see the source code for a counter example and run that\.

Changes to embedded/md/tcllib/files/modules/simulation/montecarlo.md.
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
You can think of a model of a network of computers, an ecosystem of some kind or
in fact anything that can be quantitatively described and has some stochastic
element in it\.

The package *simulation::montecarlo* offers a basic framework for such a
modelling technique:

    \#

    \# MC experiments:
    \# Determine the mean and median of a set of points and compare them
    \#

    ::simulation::montecarlo::singleExperiment \-init \{
        package require math::statistics

        set prng \[::simulation::random::prng\_Normal 0\.0 1\.0\]
    \} \-loop \{
        set numbers \{\}
        for \{ set i 0 \} \{ $i < \[getOption samples\] \} \{ incr i \} \{
            lappend numbers \[$prng\]
        \}

        set mean   \[::math::statistics::mean $numbers\]
        set median \[::math::statistics::median $numbers\] ;\# ? Exists?
        setTrialResult \[list $mean $median\]
    \} \-final \{
        set result \[getTrialResults\]
        set means   \{\}
        set medians \{\}
        foreach r $result \{
            foreach \{m M\} $r break
            lappend means   $m
            lappend medians $M
        \}

        puts \[getOption reportfile\] "Correlation: \[::math::statistics::corr $means $medians\]"

    \} \-trials 100 \-samples 10 \-verbose 1 \-columns \{Mean Median\}

This example attemps to find out how well the median value and the mean value of
a random set of numbers correlate\. Sometimes a median value is a more robust
characteristic than a mean value \- especially if you have a statistical
distribution with "fat" tails\.

# <a name='section2'></a>PROCEDURES







<
>
|
|
<
>
|


|
|
|
|
|
<
>
|
|
|
|
|
|
|
|
|


<
>
|

|







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
You can think of a model of a network of computers, an ecosystem of some kind or
in fact anything that can be quantitatively described and has some stochastic
element in it\.

The package *simulation::montecarlo* offers a basic framework for such a
modelling technique:


    #
    # MC experiments:
    # Determine the mean and median of a set of points and compare them

    #
    ::simulation::montecarlo::singleExperiment -init {
        package require math::statistics

        set prng [::simulation::random::prng_Normal 0.0 1.0]
    } -loop {
        set numbers {}
        for { set i 0 } { $i < [getOption samples] } { incr i } {
            lappend numbers [$prng]

        }
        set mean   [::math::statistics::mean $numbers]
        set median [::math::statistics::median $numbers] ;# ? Exists?
        setTrialResult [list $mean $median]
    } -final {
        set result [getTrialResults]
        set means   {}
        set medians {}
        foreach r $result {
            foreach {m M} $r break
            lappend means   $m
            lappend medians $M

        }
        puts [getOption reportfile] "Correlation: [::math::statistics::corr $means $medians]"

    } -trials 100 -samples 10 -verbose 1 -columns {Mean Median}

This example attemps to find out how well the median value and the mean value of
a random set of numbers correlate\. Sometimes a median value is a more robust
characteristic than a mean value \- especially if you have a statistical
distribution with "fat" tails\.

# <a name='section2'></a>PROCEDURES
Changes to embedded/md/tcllib/files/modules/simulation/simulation_random.md.
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  - numbers that are distributed normally, uniformly, according to a Pareto or
    Gumbel distribution and so on

  - coordinates of points uniformly spread inside a sphere or a rectangle

For example:

    set p \[::simulation::random::prng\_Normal \-1\.0 10\.0\]

produces a new command \(whose name is stored in the variable "p"\) that generates
normally distributed numbers with a mean of \-1\.0 and a standard deviation of
10\.0\.

# <a name='section2'></a>PROCEDURES








|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  - numbers that are distributed normally, uniformly, according to a Pareto or
    Gumbel distribution and so on

  - coordinates of points uniformly spread inside a sphere or a rectangle

For example:

    set p [::simulation::random::prng_Normal -1.0 10.0]

produces a new command \(whose name is stored in the variable "p"\) that generates
normally distributed numbers with a mean of \-1\.0 and a standard deviation of
10\.0\.

# <a name='section2'></a>PROCEDURES

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

  - <a name='8'></a>__::simulation::random::prng\_Gumbel__ *min* *f*

    Create a command \(PRNG\) that generates numbers distributed according to
    Gumbel with a given minimum value and a given scale factor\. The probability
    density function is:

    P\(v\) = exp\( \-exp\(f\*\(v\-min\)\)\)

      * float *min*

        Minimum number that will be generated

      * float *f*








|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

  - <a name='8'></a>__::simulation::random::prng\_Gumbel__ *min* *f*

    Create a command \(PRNG\) that generates numbers distributed according to
    Gumbel with a given minimum value and a given scale factor\. The probability
    density function is:

    P(v) = exp( -exp(f*(v-min)))

      * float *min*

        Minimum number that will be generated

      * float *f*

Changes to embedded/md/tcllib/files/modules/smtpd/smtpd.md.
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
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section4'></a>COMMANDS

  - <a name='1'></a>__::smtpd::start__ ?*myaddr*? ?*port*?

    Start the service listening on *port* or the default port 25\. If
    *myaddr* is given as a domain\-style name or numerical dotted\-quad IP
    address then the server socket will be bound to that network interface\. By
    default the server is bound to all network interfaces\. For example:

    set sock \[::smtpd::start \[info hostname\] 0\]

    will bind to the hosts internet interface on the first available port\.

    At present the package only supports a single instance of a SMTP server\.
    This could be changed if required at the cost of making the package a little
    more complicated to read\. If there is a good reason for running multiple
    SMTP services then it will only be necessary to fix the __options__







|

|










|







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
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section4'></a>COMMANDS

  - <a name='1'></a>__::smtpd::start__ ?*myaddr*? ?*port*?

    Start the service listening on *port* or the default port 25\. If
    *myaddr* is given as a domain\-style name or numerical dotted\-quad IP
    address then the server socket will be bound to that network interface\. By
    default the server is bound to all network interfaces\. For example:

    set sock [::smtpd::start [info hostname] 0]

    will bind to the hosts internet interface on the first available port\.

    At present the package only supports a single instance of a SMTP server\.
    This could be changed if required at the cost of making the package a little
    more complicated to read\. If there is a good reason for running multiple
    SMTP services then it will only be necessary to fix the __options__
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
  - __validate\_host__ callback

    This procedure is called with the clients ip address as soon as a connection
    request has been accepted and before any protocol commands are processed\. If
    you wish to deny access to a specific host then an error should be returned
    by this callback\. For example:

    proc validate\_host \{ipnum\} \{
       if \{\[string match "192\.168\.1\.\*" $ipnum\]\} \{
          error "go away\!"
       \}
    \}



    If access is denied the client will receive a standard message that includes
    the text of your error, such as:

    550 Access denied: I hate you\.

    As per the SMTP protocol, the connection is not closed but we wait for the
    client to send a QUIT command\. Any other commands cause a __503 Bad
    Sequence__ error\.

  - __validate\_sender__ callback

    The validate\_sender callback is called with the senders mail address during
    processing of a MAIL command to allow you to accept or reject mail based
    upon the declared sender\. To reject mail you should throw an error\. For
    example, to reject mail from user "denied":

    proc validate\_sender \{address\} \{
       eval array set addr \[mime::parseaddress $address\]
       if \{\[string match "denied" $addr\(local\)\]\} \{
            error "mailbox $addr\(local\) denied"
       \}

       return
    \}


    The content of any error message will not be passed back to the client\.

  - __validate\_recipient__ callback

    The validate\_recipient callback is similar to the validate\_sender callback
    and permits you to verify a local mailbox and accept mail for a local user
    address during RCPT command handling\. To reject mail, throw an error as
    above\. The error message is ignored\.

  - __deliverMIME__ callback

    The deliverMIME callback is called once a mail message has been successfully
    passed to the server\. A mime token is constructed from the sender,
    recipients and data and the users procedure it called with this single
    argument\. When the call returns, the mime token is cleaned up so if the user
    wishes to preserve the data she must make a copy\.

    proc deliverMIME \{token\} \{
        set sender \[lindex \[mime::getheader $token From\] 0\]
        set recipients \[lindex \[mime::getheader $token To\] 0\]
        set mail "From $sender \[clock format \[clock seconds\]\]"
        append mail "\\n" \[mime::buildmessage $token\]
        puts $mail
    \}


  - __deliver__ callback

    The deliver callback is called once a mail message has been successfully
    passed to the server and there is no \-deliverMIME option set\. The procedure
    is called with the sender, a list of recipients and the text of the mail as
    a list of lines\. For example:

    proc deliver \{sender recipients data\} \{
       set mail "From $sender  \[clock format \[clock seconds\]\]"
       append mail "\\n" \[join $data "\\n"\]
       puts "$mail"
    \}


    Note that the DATA command will return an error if no sender or recipient
    has yet been defined\.

# <a name='section6'></a>VARIABLES

  - __::smtpd::stopped__







|
|
|
<
<
>
>




|












|
|
|
|
<
>

<
>


















|
|
|
|
|

<
>








|
|
|

<
>







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
  - __validate\_host__ callback

    This procedure is called with the clients ip address as soon as a connection
    request has been accepted and before any protocol commands are processed\. If
    you wish to deny access to a specific host then an error should be returned
    by this callback\. For example:

    proc validate_host {ipnum} {
       if {[string match "192.168.1.*" $ipnum]} {
          error "go away!"


       }
    }

    If access is denied the client will receive a standard message that includes
    the text of your error, such as:

    550 Access denied: I hate you.

    As per the SMTP protocol, the connection is not closed but we wait for the
    client to send a QUIT command\. Any other commands cause a __503 Bad
    Sequence__ error\.

  - __validate\_sender__ callback

    The validate\_sender callback is called with the senders mail address during
    processing of a MAIL command to allow you to accept or reject mail based
    upon the declared sender\. To reject mail you should throw an error\. For
    example, to reject mail from user "denied":

    proc validate_sender {address} {
       eval array set addr [mime::parseaddress $address]
       if {[string match "denied" $addr(local)]} {
            error "mailbox $addr(local) denied"

       }
       return

    }

    The content of any error message will not be passed back to the client\.

  - __validate\_recipient__ callback

    The validate\_recipient callback is similar to the validate\_sender callback
    and permits you to verify a local mailbox and accept mail for a local user
    address during RCPT command handling\. To reject mail, throw an error as
    above\. The error message is ignored\.

  - __deliverMIME__ callback

    The deliverMIME callback is called once a mail message has been successfully
    passed to the server\. A mime token is constructed from the sender,
    recipients and data and the users procedure it called with this single
    argument\. When the call returns, the mime token is cleaned up so if the user
    wishes to preserve the data she must make a copy\.

    proc deliverMIME {token} {
        set sender [lindex [mime::getheader $token From] 0]
        set recipients [lindex [mime::getheader $token To] 0]
        set mail "From $sender [clock format [clock seconds]]"
        append mail "\n" [mime::buildmessage $token]
        puts $mail

    }

  - __deliver__ callback

    The deliver callback is called once a mail message has been successfully
    passed to the server and there is no \-deliverMIME option set\. The procedure
    is called with the sender, a list of recipients and the text of the mail as
    a list of lines\. For example:

    proc deliver {sender recipients data} {
       set mail "From $sender  [clock format [clock seconds]]"
       append mail "\n" [join $data "\n"]
       puts "$mail"

    }

    Note that the DATA command will return an error if no sender or recipient
    has yet been defined\.

# <a name='section6'></a>VARIABLES

  - __::smtpd::stopped__
Changes to embedded/md/tcllib/files/modules/snit/snit.md.
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
        The variable __type__ is automatically defined in the *body* to
        the type's fully\-qualified name\. In addition, type variables are
        automatically visible in the *body* of every type method\.

        If the *name* consists of two or more tokens, Snit handles it
        specially:

            typemethod \{a b\} \{arg\} \{ puts "Got $arg" \}

        This statement implicitly defines a type method called __a__ which
        has a subcommand __b__\. __b__ is called like this:

            $type a b "Hello, world\!"

        __a__ may have any number of subcommands\. This makes it possible to
        define a hierarchical command structure; see
        __[method](\.\./\.\./\.\./\.\./index\.md\#method)__, below, for more
        examples\.

        Type methods can call commands from the namespace in which the type is
        defined without importing them, e\.g\., if the type name is
        __::parentns::typename__, then the type's type methods can call
        __::parentns::someproc__ just as __someproc__\. *Snit 1\.x
        Incompatibility:* This does not work in Snit 1\.x, as it depends on
        __namespace path__, a new command in Tcl 8\.5\.

        *Snit 1\.x Incompatibility:* In Snit 1\.x, the following following two
        calls to this type method are equivalent:

            $type a b "Hello, world\!"
            $type \{a b\} "Hello, world\!"

        In Snit 2\.2, the second form is invalid\.

      * <a name='4'></a>__typeconstructor__ *body*

        The type constructor's *body* is executed once when the type is first
        defined; it is typically used to initialize array\-valued type variables







|




|
















|
|







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
        The variable __type__ is automatically defined in the *body* to
        the type's fully\-qualified name\. In addition, type variables are
        automatically visible in the *body* of every type method\.

        If the *name* consists of two or more tokens, Snit handles it
        specially:

            typemethod {a b} {arg} { puts "Got $arg" }

        This statement implicitly defines a type method called __a__ which
        has a subcommand __b__\. __b__ is called like this:

            $type a b "Hello, world!"

        __a__ may have any number of subcommands\. This makes it possible to
        define a hierarchical command structure; see
        __[method](\.\./\.\./\.\./\.\./index\.md\#method)__, below, for more
        examples\.

        Type methods can call commands from the namespace in which the type is
        defined without importing them, e\.g\., if the type name is
        __::parentns::typename__, then the type's type methods can call
        __::parentns::someproc__ just as __someproc__\. *Snit 1\.x
        Incompatibility:* This does not work in Snit 1\.x, as it depends on
        __namespace path__, a new command in Tcl 8\.5\.

        *Snit 1\.x Incompatibility:* In Snit 1\.x, the following following two
        calls to this type method are equivalent:

            $type a b "Hello, world!"
            $type {a b} "Hello, world!"

        In Snit 2\.2, the second form is invalid\.

      * <a name='4'></a>__typeconstructor__ *body*

        The type constructor's *body* is executed once when the type is first
        defined; it is typically used to initialize array\-valued type variables
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
        Type and instance variables are automatically visible in all instance
        methods\. If the type has locally defined options, the __options__
        array is also visible\.

        If the *name* consists of two or more tokens, Snit handles it
        specially:

            method \{a b\} \{\} \{ \.\.\. \}

        This statement implicitly defines a method called __a__ which has a
        subcommand __b__\. __b__ is called like this:

            $self a b "Hello, world\!"

        __a__ may have any number of subcommands\. This makes it possible to
        define a hierarchical command structure:

            % snit::type dog \{
                method \{tail wag\}   \{\} \{return "Wag, wag"\}
                method \{tail droop\} \{\} \{return "Droop, droop"\}
            \}

            ::dog
            % dog spot
            ::spot
            % spot tail wag
            Wag, wag
            % spot tail droop
            Droop, droop







|




|




|
|
|
<
>







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
        Type and instance variables are automatically visible in all instance
        methods\. If the type has locally defined options, the __options__
        array is also visible\.

        If the *name* consists of two or more tokens, Snit handles it
        specially:

            method {a b} {} { ... }

        This statement implicitly defines a method called __a__ which has a
        subcommand __b__\. __b__ is called like this:

            $self a b "Hello, world!"

        __a__ may have any number of subcommands\. This makes it possible to
        define a hierarchical command structure:

            % snit::type dog {
                method {tail wag}   {} {return "Wag, wag"}
                method {tail droop} {} {return "Droop, droop"}

            }
            ::dog
            % dog spot
            ::spot
            % spot tail wag
            Wag, wag
            % spot tail droop
            Droop, droop
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
        __::parentns::someproc__ just as __someproc__\. *Snit 1\.x
        Incompatibility:* This does not work in Snit 1\.x, as it depends on
        __namespace path__, a new command in Tcl 8\.5\.

        *Snit 1\.x Incompatibility:* In Snit 1\.x, the following following two
        calls to this method are equivalent:

            $self a b "Hello, world\!"
            $self \{a b\} "Hello, world\!"

        In Snit 2\.2, the second form is invalid\.

      * <a name='7'></a>__option__ *namespec* ?*defaultValue*?

      * <a name='8'></a>__option__ *namespec* ?*options\.\.\.*?

        Defines an option for instances of this type, and optionally gives it an
        initial value\. The initial value defaults to the empty string if no
        *defaultValue* is specified\.

        An option defined in this way is said to be *locally defined*\.

        The *namespec* is a list defining the option's name, resource name,
        and class name, e\.g\.:

            option \{\-font font Font\} \{Courier 12\}

        The option name must begin with a hyphen, and must not contain any upper
        case letters\. The resource name and class name are optional; if not
        specified, the resource name defaults to the option name, minus the
        hyphen, and the class name defaults to the resource name with the first
        letter capitalized\. Thus, the following statement is equivalent to the
        previous example:

            option \-font \{Courier 12\}

        See [The Tk Option Database](#subsection9) for more information
        about resource and class names\.

        Options are normally set and retrieved using the standard instance
        methods __configure__ and __cget__; within instance code \(method
        bodies, etc\.\), option values are available through the __options__
        array:

            set myfont $options\(\-font\)

        If the type defines any option handlers \(e\.g\.,
        __\-configuremethod__\), then it should probably use __configure__
        and __cget__ to access its options to avoid subtle errors\.

        The __option__ statement may include the following options:








|
|
















|








|









|







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
        __::parentns::someproc__ just as __someproc__\. *Snit 1\.x
        Incompatibility:* This does not work in Snit 1\.x, as it depends on
        __namespace path__, a new command in Tcl 8\.5\.

        *Snit 1\.x Incompatibility:* In Snit 1\.x, the following following two
        calls to this method are equivalent:

            $self a b "Hello, world!"
            $self {a b} "Hello, world!"

        In Snit 2\.2, the second form is invalid\.

      * <a name='7'></a>__option__ *namespec* ?*defaultValue*?

      * <a name='8'></a>__option__ *namespec* ?*options\.\.\.*?

        Defines an option for instances of this type, and optionally gives it an
        initial value\. The initial value defaults to the empty string if no
        *defaultValue* is specified\.

        An option defined in this way is said to be *locally defined*\.

        The *namespec* is a list defining the option's name, resource name,
        and class name, e\.g\.:

            option {-font font Font} {Courier 12}

        The option name must begin with a hyphen, and must not contain any upper
        case letters\. The resource name and class name are optional; if not
        specified, the resource name defaults to the option name, minus the
        hyphen, and the class name defaults to the resource name with the first
        letter capitalized\. Thus, the following statement is equivalent to the
        previous example:

            option -font {Courier 12}

        See [The Tk Option Database](#subsection9) for more information
        about resource and class names\.

        Options are normally set and retrieved using the standard instance
        methods __configure__ and __cget__; within instance code \(method
        bodies, etc\.\), option values are available through the __options__
        array:

            set myfont $options(-font)

        If the type defines any option handlers \(e\.g\.,
        __\-configuremethod__\), then it should probably use __configure__
        and __cget__ to access its options to avoid subtle errors\.

        The __option__ statement may include the following options:

409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
            Every locally\-defined option may define its validation type, which
            may be either the name of a validation type or a specification for a
            validation subtype

            For example, an option may declare that its value must be an integer
            by specifying __snit::integer__ as its validation type:

                option \-number \-type snit::integer

            It may also declare that its value is an integer between 1 and 10 by
            specifying a validation subtype:

                option \-number \-type \{snit::integer \-min 1 \-max 10\}

            If a validation type or subtype is defined for an option, then it
            will be used to validate the option's value whenever it is changed
            by the object's __configure__ or __configurelist__ methods\.
            In addition, all such options will have their values validated
            automatically immediately after the constructor executes\.








|




|







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
            Every locally\-defined option may define its validation type, which
            may be either the name of a validation type or a specification for a
            validation subtype

            For example, an option may declare that its value must be an integer
            by specifying __snit::integer__ as its validation type:

                option -number -type snit::integer

            It may also declare that its value is an integer between 1 and 10 by
            specifying a validation subtype:

                option -number -type {snit::integer -min 1 -max 10}

            If a validation type or subtype is defined for an option, then it
            will be used to validate the option's value whenever it is changed
            by the object's __configure__ or __configurelist__ methods\.
            In addition, all such options will have their values validated
            automatically immediately after the constructor executes\.

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
            method\. Whatever the method's *body* returns will be the return
            value of the call to __cget__\.

            The named method must take one argument, the option name\. For
            example, this code is equivalent to \(though slower than\) Snit's
            default handling of __cget__:

                option \-font \-cgetmethod GetOption
                method GetOption \{option\} \{
                    return $options\($option\)
                \}


            Note that it's possible for any number of options to share a
            __\-cgetmethod__\.

          + __\-configuremethod__ *methodName*

            Every locally\-defined option may define a __\-configuremethod__;
            it is called when the option's value is set using the
            __configure__ or __configurelist__ methods\. It is the named
            method's responsibility to save the option's value; in other words,
            the value will not be saved to the __options\(\)__ array unless
            the method saves it there\.

            The named method must take two arguments, the option name and its
            new value\. For example, this code is equivalent to \(though slower
            than\) Snit's default handling of __configure__:

                option \-font \-configuremethod SetOption
                method SetOption \{option value\} \{
                    set options\($option\) $value
                \}


            Note that it's possible for any number of options to share a single
            __\-configuremethod__\.

          + __\-validatemethod__ *methodName*

            Every locally\-defined option may define a __\-validatemethod__;
            it is called when the option's value is set using the
            __configure__ or __configurelist__ methods, just before the
            __\-configuremethod__ \(if any\)\. It is the named method's
            responsibility to validate the option's new value, and to throw an
            error if the value is invalid\.

            The named method must take two arguments, the option name and its
            new value\. For example, this code verifies that __\-flag__'s
            value is a valid Boolean value:

                option \-font \-validatemethod CheckBoolean
                method CheckBoolean \{option value\} \{
                    if \{\!\[string is boolean \-strict $value\]\} \{
                        error "option $option must have a boolean value\."
                    \}
                \}



            Note that it's possible for any number of options to share a single
            __\-validatemethod__\.

      * <a name='9'></a>__constructor__ *arglist* *body*

        The constructor definition specifies a *body* of code to be executed
        when a new instance is created\. The *arglist* is a normal Tcl argument
        list and may contain default arguments and the __args__ argument\.

        As with methods, the arguments __type__, __self__,
        __selfns__, and __win__ are defined implicitly, and all type and
        instance variables are automatically visible in its *body*\.

        If the *definition* doesn't explicitly define the constructor, Snit
        defines one implicitly\. If the type declares at least one option
        \(whether locally or by delegation\), the default constructor will be
        defined as follows:

            constructor \{args\} \{
                $self configurelist $args
            \}


        For standard Tk widget behavior, the argument list should be the single
        name __args__, as shown\.

        If the *definition* defines neither a constructor nor any options, the
        default constructor is defined as follows:

            constructor \{\} \{\}

        As with methods, the constructor can call commands from the namespace in
        which the type is defined without importing them, e\.g\., if the type name
        is __::parentns::typename__, then the constructor can call
        __::parentns::someproc__ just as __someproc__\. *Snit 1\.x
        Incompatibility:* This does not work in Snit 1\.x, as it depends on
        __namespace path__, a new command in Tcl 8\.5\.







|
|
|
<
>

















|
|
|
<
>

















|
|
|
|
<
<
>
>



















|

<
>







|







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
            method\. Whatever the method's *body* returns will be the return
            value of the call to __cget__\.

            The named method must take one argument, the option name\. For
            example, this code is equivalent to \(though slower than\) Snit's
            default handling of __cget__:

                option -font -cgetmethod GetOption
                method GetOption {option} {
                    return $options($option)

                }

            Note that it's possible for any number of options to share a
            __\-cgetmethod__\.

          + __\-configuremethod__ *methodName*

            Every locally\-defined option may define a __\-configuremethod__;
            it is called when the option's value is set using the
            __configure__ or __configurelist__ methods\. It is the named
            method's responsibility to save the option's value; in other words,
            the value will not be saved to the __options\(\)__ array unless
            the method saves it there\.

            The named method must take two arguments, the option name and its
            new value\. For example, this code is equivalent to \(though slower
            than\) Snit's default handling of __configure__:

                option -font -configuremethod SetOption
                method SetOption {option value} {
                    set options($option) $value

                }

            Note that it's possible for any number of options to share a single
            __\-configuremethod__\.

          + __\-validatemethod__ *methodName*

            Every locally\-defined option may define a __\-validatemethod__;
            it is called when the option's value is set using the
            __configure__ or __configurelist__ methods, just before the
            __\-configuremethod__ \(if any\)\. It is the named method's
            responsibility to validate the option's new value, and to throw an
            error if the value is invalid\.

            The named method must take two arguments, the option name and its
            new value\. For example, this code verifies that __\-flag__'s
            value is a valid Boolean value:

                option -font -validatemethod CheckBoolean
                method CheckBoolean {option value} {
                    if {![string is boolean -strict $value]} {
                        error "option $option must have a boolean value."


                    }
                }

            Note that it's possible for any number of options to share a single
            __\-validatemethod__\.

      * <a name='9'></a>__constructor__ *arglist* *body*

        The constructor definition specifies a *body* of code to be executed
        when a new instance is created\. The *arglist* is a normal Tcl argument
        list and may contain default arguments and the __args__ argument\.

        As with methods, the arguments __type__, __self__,
        __selfns__, and __win__ are defined implicitly, and all type and
        instance variables are automatically visible in its *body*\.

        If the *definition* doesn't explicitly define the constructor, Snit
        defines one implicitly\. If the type declares at least one option
        \(whether locally or by delegation\), the default constructor will be
        defined as follows:

            constructor {args} {
                $self configurelist $args

            }

        For standard Tk widget behavior, the argument list should be the single
        name __args__, as shown\.

        If the *definition* defines neither a constructor nor any options, the
        default constructor is defined as follows:

            constructor {} {}

        As with methods, the constructor can call commands from the namespace in
        which the type is defined without importing them, e\.g\., if the type name
        is __::parentns::typename__, then the constructor can call
        __::parentns::someproc__ just as __someproc__\. *Snit 1\.x
        Incompatibility:* This does not work in Snit 1\.x, as it depends on
        __namespace path__, a new command in Tcl 8\.5\.
572
573
574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
        arguments will be passed to the named component's command instead\. That
        is, the following statement

            delegate method wag to tail

        is roughly equivalent to this explicitly defined method:

            method wag \{args\} \{
                uplevel $tail wag $args
            \}


        As with methods, the *name* may have multiple tokens; in this case,
        the last token of the name is assumed to be the name of the component's
        method\.

        The optional __as__ clause allows you to specify the delegated
        method name and possibly add some arguments:







|

<
>







572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
        arguments will be passed to the named component's command instead\. That
        is, the following statement

            delegate method wag to tail

        is roughly equivalent to this explicitly defined method:

            method wag {args} {
                uplevel $tail wag $args

            }

        As with methods, the *name* may have multiple tokens; in this case,
        the last token of the name is assumed to be the name of the component's
        method\.

        The optional __as__ clause allows you to specify the delegated
        method name and possibly add some arguments:
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
        delegated\. The __using__ clause is defined as given above\. In this
        form, the statement must contain the __to__ clause, the
        __using__ clause, or both\.

        In fact, the "\*" can be a list of two or more tokens whose last element
        is "\*", as in the following example:

            delegate method \{tail \*\} to tail

        This implicitly defines the method __tail__ whose subcommands will
        be delegated to the __tail__ component\.

      * <a name='15'></a>__delegate__ __option__ *namespec* __to__ *comp*

      * <a name='16'></a>__delegate__ __option__ *namespec* __to__ *comp* __as__ *target*

      * <a name='17'></a>__delegate__ __option__ __\*__ __to__ *comp*

      * <a name='18'></a>__delegate__ __option__ __\*__ __to__ *comp* __except__ *exceptions*

        Defines a delegated option; the *namespec* is defined as for the
        __option__ statement\. When the __configure__,
        __configurelist__, or __cget__ instance method is used to set or
        retrieve the option's value, the equivalent __configure__ or
        __cget__ command will be applied to the component as though the
        option was defined with the following __\-configuremethod__ and
        __\-cgetmethod__:

            method ConfigureMethod \{option value\} \{
                $comp configure $option $value
            \}


            method CgetMethod \{option\} \{
                return \[$comp cget $option\]
            \}


        Note that delegated options never appear in the __options__ array\.

        If the __as__ clause is specified, then the *target* option name
        is used in place of *name*\.

        The form __delegate option \*__ delegates all unknown options to the







|




















|

<
|
>
|
|
<
>







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
        delegated\. The __using__ clause is defined as given above\. In this
        form, the statement must contain the __to__ clause, the
        __using__ clause, or both\.

        In fact, the "\*" can be a list of two or more tokens whose last element
        is "\*", as in the following example:

            delegate method {tail *} to tail

        This implicitly defines the method __tail__ whose subcommands will
        be delegated to the __tail__ component\.

      * <a name='15'></a>__delegate__ __option__ *namespec* __to__ *comp*

      * <a name='16'></a>__delegate__ __option__ *namespec* __to__ *comp* __as__ *target*

      * <a name='17'></a>__delegate__ __option__ __\*__ __to__ *comp*

      * <a name='18'></a>__delegate__ __option__ __\*__ __to__ *comp* __except__ *exceptions*

        Defines a delegated option; the *namespec* is defined as for the
        __option__ statement\. When the __configure__,
        __configurelist__, or __cget__ instance method is used to set or
        retrieve the option's value, the equivalent __configure__ or
        __cget__ command will be applied to the component as though the
        option was defined with the following __\-configuremethod__ and
        __\-cgetmethod__:

            method ConfigureMethod {option value} {
                $comp configure $option $value

            }

            method CgetMethod {option} {
                return [$comp cget $option]

            }

        Note that delegated options never appear in the __options__ array\.

        If the __as__ clause is specified, then the *target* option name
        is used in place of *name*\.

        The form __delegate option \*__ delegates all unknown options to the
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

        If the __\-public__ option is specified, then the option is made
        public by defining a *method* whose subcommands are delegated to the
        component e\.g\., specifying __\-public mycomp__ is equivalent to the
        following:

            component mycomp
            delegate method \{mymethod \*\} to mycomp

        If the __\-inherit__ option is specified, then *flag* must be a
        Boolean value; if *flag* is true then all unknown methods and options
        will be delegated to this component\. The name __\-inherit__ implies
        that instances of this new type inherit, in a sense, the methods and
        options of the component\. That is, __\-inherit yes__ is equivalent
        to:

            component mycomp
            delegate option \* to mycomp
            delegate method \* to mycomp

      * <a name='20'></a>__delegate__ __typemethod__ *name* __to__ *comp* ?__as__ *target*?

        Delegates type method *name* to type component *comp*\. That is, when
        type method *name* is called on this type, the type method and its
        arguments will be passed to the named type component's command instead\.
        That is, the following statement

            delegate typemethod lostdogs to pound

        is roughly equivalent to this explicitly defined method:

            typemethod lostdogs \{args\} \{
                uplevel $pound lostdogs $args
            \}


        As with type methods, the *name* may have multiple tokens; in this
        case, the last token of the name is assumed to be the name of the
        component's method\.

        The optional __as__ clause allows you to specify the delegated
        method name and possibly add some arguments:







|









|
|












|

<
>







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

        If the __\-public__ option is specified, then the option is made
        public by defining a *method* whose subcommands are delegated to the
        component e\.g\., specifying __\-public mycomp__ is equivalent to the
        following:

            component mycomp
            delegate method {mymethod *} to mycomp

        If the __\-inherit__ option is specified, then *flag* must be a
        Boolean value; if *flag* is true then all unknown methods and options
        will be delegated to this component\. The name __\-inherit__ implies
        that instances of this new type inherit, in a sense, the methods and
        options of the component\. That is, __\-inherit yes__ is equivalent
        to:

            component mycomp
            delegate option * to mycomp
            delegate method * to mycomp

      * <a name='20'></a>__delegate__ __typemethod__ *name* __to__ *comp* ?__as__ *target*?

        Delegates type method *name* to type component *comp*\. That is, when
        type method *name* is called on this type, the type method and its
        arguments will be passed to the named type component's command instead\.
        That is, the following statement

            delegate typemethod lostdogs to pound

        is roughly equivalent to this explicitly defined method:

            typemethod lostdogs {args} {
                uplevel $pound lostdogs $args

            }

        As with type methods, the *name* may have multiple tokens; in this
        case, the last token of the name is assumed to be the name of the
        component's method\.

        The optional __as__ clause allows you to specify the delegated
        method name and possibly add some arguments:
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
        create foo__, where __foo__ is the name of a new instance of the
        type\. If you use __delegate typemethod \*__, then the __create__
        type method must always be used explicitly\.

        The "\*" can be a list of two or more tokens whose last element is "\*",
        as in the following example:

            delegate typemethod \{tail \*\} to tail

        This implicitly defines the type method __tail__ whose subcommands
        will be delegated to the __tail__ type component\.

      * <a name='23'></a>__typecomponent__ *comp* ?__\-public__ *typemethod*? ?__\-inherit__ *flag*?

        Explicitly declares a type component called *comp*, and automatically
        defines the component's type variable\. A type component is an arbitrary
        command to which type methods and instance methods can be delegated; the
        command's name is stored in a type variable\.

        If the __\-public__ option is specified, then the type component is
        made public by defining a *typemethod* whose subcommands are delegated
        to the type component, e\.g\., specifying __\-public mytypemethod__ is
        equivalent to the following:

            typecomponent mycomp
            delegate typemethod \{mytypemethod \*\} to mycomp

        If the __\-inherit__ option is specified, then *flag* must be a
        Boolean value; if *flag* is true then all unknown type methods will be
        delegated to this type component\. \(See the note on "delegate typemethod
        \*", above\.\) The name __\-inherit__ implies that this type inherits,
        in a sense, the behavior of the type component\. That is, __\-inherit
        yes__ is equivalent to:

            typecomponent mycomp
            delegate typemethod \* to mycomp

      * <a name='24'></a>__pragma__ ?*options\.\.\.*?

        The __pragma__ statement provides control over how Snit generates a
        type\. It takes the following options; in each case, *flag* must be a
        Boolean value recognized by Tcl, e\.g\., __0__, __1__,
        __yes__, __no__, and so on\.







|

















|









|







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
        create foo__, where __foo__ is the name of a new instance of the
        type\. If you use __delegate typemethod \*__, then the __create__
        type method must always be used explicitly\.

        The "\*" can be a list of two or more tokens whose last element is "\*",
        as in the following example:

            delegate typemethod {tail *} to tail

        This implicitly defines the type method __tail__ whose subcommands
        will be delegated to the __tail__ type component\.

      * <a name='23'></a>__typecomponent__ *comp* ?__\-public__ *typemethod*? ?__\-inherit__ *flag*?

        Explicitly declares a type component called *comp*, and automatically
        defines the component's type variable\. A type component is an arbitrary
        command to which type methods and instance methods can be delegated; the
        command's name is stored in a type variable\.

        If the __\-public__ option is specified, then the type component is
        made public by defining a *typemethod* whose subcommands are delegated
        to the type component, e\.g\., specifying __\-public mytypemethod__ is
        equivalent to the following:

            typecomponent mycomp
            delegate typemethod {mytypemethod *} to mycomp

        If the __\-inherit__ option is specified, then *flag* must be a
        Boolean value; if *flag* is true then all unknown type methods will be
        delegated to this type component\. \(See the note on "delegate typemethod
        \*", above\.\) The name __\-inherit__ implies that this type inherits,
        in a sense, the behavior of the type component\. That is, __\-inherit
        yes__ is equivalent to:

            typecomponent mycomp
            delegate typemethod * to mycomp

      * <a name='24'></a>__pragma__ ?*options\.\.\.*?

        The __pragma__ statement provides control over how Snit generates a
        type\. It takes the following options; in each case, *flag* must be a
        Boolean value recognized by Tcl, e\.g\., __0__, __1__,
        __yes__, __no__, and so on\.
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
      * <a name='27'></a>__onconfigure__ *name* *arglist* *body*

        __Deprecated\.__ Define __option__'s __\-configuremethod__
        option instead\.

        As of version 0\.95, the following definitions,

            option \-myoption
            onconfigure \-myoption \{value\} \{
                \# Code to save the option's value
            \}


        are implemented as follows:

            option \-myoption \-configuremethod \_configure\-myoption
            method \_configure\-myoption \{\_option value\} \{
                \# Code to save the option's value
            \}


      * <a name='28'></a>__oncget__ *name* *body*

        __Deprecated\.__ Define __option__'s __\-cgetmethod__ option
        instead\.

        As of version 0\.95, the following definitions,

            option \-myoption
            oncget \-myoption \{
                \# Code to return the option's value
            \}


        are implemented as follows:

            option \-myoption \-cgetmethod \_cget\-myoption
            method \_cget\-myoption \{\_option\} \{
                \# Code to return the option's value
            \}


  - <a name='29'></a>__snit::widget__ *name* *definition*

    This command defines a Snit megawidget type with the specified *name*\. The
    *definition* is defined as for __snit::type__\. A __snit::widget__
    differs from a __snit::type__ in these ways:








|
|
|
<
>



|
|
|
<
>








|
|
|
<
>



|
|
|
<
>







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
      * <a name='27'></a>__onconfigure__ *name* *arglist* *body*

        __Deprecated\.__ Define __option__'s __\-configuremethod__
        option instead\.

        As of version 0\.95, the following definitions,

            option -myoption
            onconfigure -myoption {value} {
                # Code to save the option's value

            }

        are implemented as follows:

            option -myoption -configuremethod _configure-myoption
            method _configure-myoption {_option value} {
                # Code to save the option's value

            }

      * <a name='28'></a>__oncget__ *name* *body*

        __Deprecated\.__ Define __option__'s __\-cgetmethod__ option
        instead\.

        As of version 0\.95, the following definitions,

            option -myoption
            oncget -myoption {
                # Code to return the option's value

            }

        are implemented as follows:

            option -myoption -cgetmethod _cget-myoption
            method _cget-myoption {_option} {
                # Code to return the option's value

            }

  - <a name='29'></a>__snit::widget__ *name* *definition*

    This command defines a Snit megawidget type with the specified *name*\. The
    *definition* is defined as for __snit::type__\. A __snit::widget__
    differs from a __snit::type__ in these ways:

1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

    Furthermore, if the __\-hastypemethods__ pragma is false, then Snit type
    commands can be called with no arguments at all; in this case, the type
    command creates an instance with an automatically generated name\. In other
    words, provided that the __\-hastypemethods__ pragma is false and the
    type has instances, the following commands are equivalent:

        snit::type dog \{ \.\.\. \}

        set mydog \[dog create %AUTO%\]
        set mydog \[dog %AUTO%\]
        set mydog \[dog\]

    This doesn't work for Snit widgets, for obvious reasons\.

    *Snit 1\.x Incompatibility:* In Snit 1\.x, the above behavior is available
    whether __\-hastypemethods__ is true \(the default\) or false\.

## <a name='subsection3'></a>Standard Type Methods







|

|
|
|







1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127

    Furthermore, if the __\-hastypemethods__ pragma is false, then Snit type
    commands can be called with no arguments at all; in this case, the type
    command creates an instance with an automatically generated name\. In other
    words, provided that the __\-hastypemethods__ pragma is false and the
    type has instances, the following commands are equivalent:

        snit::type dog { ... }

        set mydog [dog create %AUTO%]
        set mydog [dog %AUTO%]
        set mydog [dog]

    This doesn't work for Snit widgets, for obvious reasons\.

    *Snit 1\.x Incompatibility:* In Snit 1\.x, the above behavior is available
    whether __\-hastypemethods__ is true \(the default\) or false\.

## <a name='subsection3'></a>Standard Type Methods
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
    The __mymethod__ command is used for formatting callback commands to be
    passed to other objects\. It returns a command that when called will invoke
    method *name* with the specified arguments, plus of course any arguments
    added by the caller\. In other words, both of the following commands will
    cause the object's __dosomething__ method to be called when the
    __$button__ is pressed:

        $button configure \-command \[list $self dosomething myargument\]

        $button configure \-command \[mymethod dosomething myargument\]

    The chief distinction between the two is that the latter form will not break
    if the object's command is renamed\.

  - <a name='61'></a>__mytypemethod__ *name* ?*args\.\.\.*?

    The __mytypemethod__ command is used for formatting callback commands to
    be passed to other objects\. It returns a command that when called will
    invoke type method *name* with the specified arguments, plus of course any
    arguments added by the caller\. In other words, both of the following
    commands will cause the object's __dosomething__ type method to be
    called when __$button__ is pressed:

        $button configure \-command \[list $type dosomething myargument\]

        $button configure \-command \[mytypemethod dosomething myargument\]

    Type commands cannot be renamed, so in practice there's little difference
    between the two forms\. __mytypemethod__ is provided for parallelism with
    __mymethod__\.

  - <a name='62'></a>__myproc__ *name* ?*args\.\.\.*?

    The __myproc__ command is used for formatting callback commands to be
    passed to other objects\. It returns a command that when called will invoke
    the type proc *name* with the specified arguments, plus of course any
    arguments added by the caller\. In other words, both of the following
    commands will cause the object's __dosomething__ proc to be called when
    __$button__ is pressed:

        $button configure \-command \[list $\{type\}::dosomething myargument\]

        $button configure \-command \[myproc dosomething myargument\]

  - <a name='63'></a>__myvar__ *name*

    Given an instance variable name, returns the fully qualified name\. Use this
    if you're passing the variable to some other object, e\.g\., as a
    __\-textvariable__ to a Tk label widget\.








|

|













|

|














|

|







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
    The __mymethod__ command is used for formatting callback commands to be
    passed to other objects\. It returns a command that when called will invoke
    method *name* with the specified arguments, plus of course any arguments
    added by the caller\. In other words, both of the following commands will
    cause the object's __dosomething__ method to be called when the
    __$button__ is pressed:

        $button configure -command [list $self dosomething myargument]

        $button configure -command [mymethod dosomething myargument]

    The chief distinction between the two is that the latter form will not break
    if the object's command is renamed\.

  - <a name='61'></a>__mytypemethod__ *name* ?*args\.\.\.*?

    The __mytypemethod__ command is used for formatting callback commands to
    be passed to other objects\. It returns a command that when called will
    invoke type method *name* with the specified arguments, plus of course any
    arguments added by the caller\. In other words, both of the following
    commands will cause the object's __dosomething__ type method to be
    called when __$button__ is pressed:

        $button configure -command [list $type dosomething myargument]

        $button configure -command [mytypemethod dosomething myargument]

    Type commands cannot be renamed, so in practice there's little difference
    between the two forms\. __mytypemethod__ is provided for parallelism with
    __mymethod__\.

  - <a name='62'></a>__myproc__ *name* ?*args\.\.\.*?

    The __myproc__ command is used for formatting callback commands to be
    passed to other objects\. It returns a command that when called will invoke
    the type proc *name* with the specified arguments, plus of course any
    arguments added by the caller\. In other words, both of the following
    commands will cause the object's __dosomething__ proc to be called when
    __$button__ is pressed:

        $button configure -command [list ${type}::dosomething myargument]

        $button configure -command [myproc dosomething myargument]

  - <a name='63'></a>__myvar__ *name*

    Given an instance variable name, returns the fully qualified name\. Use this
    if you're passing the variable to some other object, e\.g\., as a
    __\-textvariable__ to a Tk label widget\.

1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

    Creates a new object of type *objType* called *objName* and installs it
    as component *compName*, as described in [Components and
    Delegation](#subsection7)\. Any additional *args\.\.\.* are passed along
    with the name to the *objType* command\. If this is a __snit::type__,
    then the following two commands are equivalent:

        install myComp using myObjType $self\.myComp args\.\.\.

        set myComp \[myObjType $self\.myComp args\.\.\.\]

    Note that whichever method is used, *compName* must still be declared in
    the type definition using __component__, or must be referenced in at
    least one __delegate__ statement\.

    If this is a __snit::widget__ or __snit::widgetadaptor__, and if
    options have been delegated to component *compName*, then those options







|

|







1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455

    Creates a new object of type *objType* called *objName* and installs it
    as component *compName*, as described in [Components and
    Delegation](#subsection7)\. Any additional *args\.\.\.* are passed along
    with the name to the *objType* command\. If this is a __snit::type__,
    then the following two commands are equivalent:

        install myComp using myObjType $self.myComp args...

        set myComp [myObjType $self.myComp args...]

    Note that whichever method is used, *compName* must still be declared in
    the type definition using __component__, or must be referenced in at
    least one __delegate__ statement\.

    If this is a __snit::widget__ or __snit::widgetadaptor__, and if
    options have been delegated to component *compName*, then those options
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
When an object includes other objects, as when a toolbar contains buttons or a
GUI object contains an object that references a database, the included object is
called a component\. The standard way to handle component objects owned by a Snit
object is to declare them using __component__, which creates a component
instance variable\. In the following example, a __dog__ object has a
__tail__ object:

    snit::type dog \{
        component mytail

        constructor \{args\} \{
            set mytail \[tail %AUTO% \-partof $self\]
            $self configurelist $args
        \}


        method wag \{\} \{
            $mytail wag
        \}
    \}



    snit::type tail \{
        option \-length 5
        option \-partof
        method wag \{\} \{ return "Wag, wag, wag\."\}
    \}


Because the __tail__ object's name is stored in an instance variable, it's
easily accessible in any method\.

The __install__ command provides an alternate way to create and install the
component:

    snit::type dog \{
        component mytail

        constructor \{args\} \{
            install mytail using tail %AUTO% \-partof $self
            $self configurelist $args
        \}


        method wag \{\} \{
            $mytail wag
        \}
    \}



For __snit::type__s, the two methods are equivalent; for
__snit::widget__s and __snit::widgetadaptor__s, the __install__
command properly initializes the widget's options by querying [The Tk Option
Database](#subsection9)\.

In the above examples, the __dog__ object's __wag__ method simply calls
the __tail__ component's __wag__ method\. In OO jargon, this is called
delegation\. Snit provides an easier way to do this:

    snit::type dog \{
        delegate method wag to mytail

        constructor \{args\} \{
            install mytail using tail %AUTO% \-partof $self
            $self configurelist $args
        \}
    \}



The __delegate__ statement in the type definition implicitly defines the
instance variable __mytail__ to hold the component's name \(though it's good
form to use __component__ to declare it explicitly\); it also defines the
__dog__ object's __wag__ method, delegating it to the __mytail__
component\.

If desired, all otherwise unknown methods can be delegated to a specific
component:

        snit::type dog \{
    	delegate method \* to mytail

    	constructor \{args\} \{
    	    set mytail \[tail %AUTO% \-partof $self\]
    	    $self configurelist $args
    	\}


    	method bark \{ return "Bark, bark, bark\!" \}
        \}


In this case, a __dog__ object will handle its own __bark__ method; but
__wag__ will be passed along to __mytail__\. Any other method, being
recognized by neither __dog__ nor __tail__, will simply raise an error\.

Option delegation is similar to method delegation, except for the interactions
with the Tk option database; this is described in [The Tk Option







|


|
|

<
|
>
|

<
<
|
>
>
|
|
|
|
<
>







|


|
|

<
|
>
|

<
<
>
>










|


|
|

<
<
>
>










|
|

|
|

<
|
>
|
<
>







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
When an object includes other objects, as when a toolbar contains buttons or a
GUI object contains an object that references a database, the included object is
called a component\. The standard way to handle component objects owned by a Snit
object is to declare them using __component__, which creates a component
instance variable\. In the following example, a __dog__ object has a
__tail__ object:

    snit::type dog {
        component mytail

        constructor {args} {
            set mytail [tail %AUTO% -partof $self]
            $self configurelist $args

        }

        method wag {} {
            $mytail wag


        }
    }

    snit::type tail {
        option -length 5
        option -partof
        method wag {} { return "Wag, wag, wag."}

    }

Because the __tail__ object's name is stored in an instance variable, it's
easily accessible in any method\.

The __install__ command provides an alternate way to create and install the
component:

    snit::type dog {
        component mytail

        constructor {args} {
            install mytail using tail %AUTO% -partof $self
            $self configurelist $args

        }

        method wag {} {
            $mytail wag


        }
    }

For __snit::type__s, the two methods are equivalent; for
__snit::widget__s and __snit::widgetadaptor__s, the __install__
command properly initializes the widget's options by querying [The Tk Option
Database](#subsection9)\.

In the above examples, the __dog__ object's __wag__ method simply calls
the __tail__ component's __wag__ method\. In OO jargon, this is called
delegation\. Snit provides an easier way to do this:

    snit::type dog {
        delegate method wag to mytail

        constructor {args} {
            install mytail using tail %AUTO% -partof $self
            $self configurelist $args


        }
    }

The __delegate__ statement in the type definition implicitly defines the
instance variable __mytail__ to hold the component's name \(though it's good
form to use __component__ to declare it explicitly\); it also defines the
__dog__ object's __wag__ method, delegating it to the __mytail__
component\.

If desired, all otherwise unknown methods can be delegated to a specific
component:

        snit::type dog {
    	delegate method * to mytail

    	constructor {args} {
    	    set mytail [tail %AUTO% -partof $self]
    	    $self configurelist $args

    	}

    	method bark { return "Bark, bark, bark!" }

        }

In this case, a __dog__ object will handle its own __bark__ method; but
__wag__ will be passed along to __mytail__\. Any other method, being
recognized by neither __dog__ nor __tail__, will simply raise an error\.

Option delegation is similar to method delegation, except for the interactions
with the Tk option database; this is described in [The Tk Option
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
widgets, the widget class name is the just the widget type name with an initial
capital letter, e\.g\., the widget class for __button__ widgets is "Button"\.

Similarly, the widget class of a __snit::widget__ defaults to the
unqualified type name with the first letter capitalized\. For example, the widget
class of

    snit::widget ::mylibrary::scrolledText \{ \.\.\. \}

is "ScrolledText"\. The widget class can also be set explicitly using the
__widgetclass__ statement within the __snit::widget__ definition\.

Any widget can be used as the __hulltype__ provided that it supports the
__\-class__ option for changing its widget class name\. See the discussion of
the __hulltype__ command, above\. The user may pass __\-class__ to the







|







1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
widgets, the widget class name is the just the widget type name with an initial
capital letter, e\.g\., the widget class for __button__ widgets is "Button"\.

Similarly, the widget class of a __snit::widget__ defaults to the
unqualified type name with the first letter capitalized\. For example, the widget
class of

    snit::widget ::mylibrary::scrolledText { ... }

is "ScrolledText"\. The widget class can also be set explicitly using the
__widgetclass__ statement within the __snit::widget__ definition\.

Any widget can be used as the __hulltype__ provided that it supports the
__\-class__ option for changing its widget class name\. See the discussion of
the __hulltype__ command, above\. The user may pass __\-class__ to the
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727

1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755

1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770

1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790

1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813

1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
The resource and class names are used to initialize option default values by
querying the Tk option database\. The resource name is usually just the option
name minus the hyphen, but may contain uppercase letters at word boundaries; the
class name is usually just the resource name with an initial capital, but not
always\. For example, here are the option, resource, and class names for several
__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget options:

    \-background         background         Background
    \-borderwidth        borderWidth        BorderWidth
    \-insertborderwidth  insertBorderWidth  BorderWidth
    \-padx               padX               Pad

As is easily seen, sometimes the resource and class names can be inferred from
the option name, but not always\.

Snit options also have a resource name and a class name\. By default, these names
follow the rule given above: the resource name is the option name without the
hyphen, and the class name is the resource name with an initial capital\. This is
true for both locally\-defined options and explicitly delegated options:

        snit::widget mywidget \{
            option \-background
            delegate option \-borderwidth to hull
            delegate option \* to text
    	\# \.\.\.
        \}


In this case, the widget class name is "Mywidget"\. The widget has the following
options: __\-background__, which is locally defined, and
__\-borderwidth__, which is explicitly delegated; all other widgets are
delegated to a component called "text", which is probably a Tk
__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget\. If so, __mywidget__
has all the same options as a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__
widget\. The option, resource, and class names are as follows:

    \-background  background  Background
    \-borderwidth borderwidth Borderwidth
    \-padx        padX        Pad

Note that the locally defined option, __\-background__, happens to have the
same three names as the standard Tk __\-background__ option; and
__\-pad__, which is delegated implicitly to the __text__ component, has
the same three names for __mywidget__ as it does for the
__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget\. __\-borderwidth__, on
the other hand, has different resource and class names than usual, because the
internal word "width" isn't capitalized\. For consistency, it should be; this is
done as follows:

        snit::widget mywidget \{
    	option \-background
    	delegate option \{\-borderwidth borderWidth\} to hull
    	delegate option \* to text
    	\# \.\.\.
        \}


The class name will default to "BorderWidth", as expected\.

Suppose, however, that __mywidget__ also delegated __\-padx__ and
__\-pady__ to the hull\. In this case, both the resource name and the class
name must be specified explicitly:

        snit::widget mywidget \{
    	option \-background
    	delegate option \{\-borderwidth borderWidth\} to hull
    	delegate option \{\-padx padX Pad\} to hull
    	delegate option \{\-pady padY Pad\} to hull
    	delegate option \* to text
    	\# \.\.\.
        \}


__Querying the option database:__ If you set your widgetclass and option
names as described above, Snit will query the option database when each instance
is created, and will generally do the right thing when it comes to querying the
option database\. The remainder of this section goes into the gory details\.

__Initializing locally defined options:__ When an instance of a snit::widget
is created, its locally defined options are initialized as follows: each
option's resource and class names are used to query the Tk option database\. If
the result is non\-empty, it is used as the option's default; otherwise, the
default hardcoded in the type definition is used\. In either case, the default
can be overridden by the caller\. For example,

        option add \*Mywidget\.texture pebbled

        snit::widget mywidget \{
    	option \-texture smooth
    	\# \.\.\.
        \}


        mywidget \.mywidget \-texture greasy

Here, __\-texture__ would normally default to "smooth", but because of the
entry added to the option database it defaults to "pebbled"\. However, the caller
has explicitly overridden the default, and so the new widget will be "greasy"\.

__Initializing options delegated to the hull:__ A __snit::widget__'s
hull is a widget, and given that its class has been set it is expected to query
the option database for itself\. The only exception concerns options that are
delegated to it with a different name\. Consider the following code:

        option add \*Mywidget\.borderWidth 5
        option add \*Mywidget\.relief sunken
        option add \*Mywidget\.hullbackground red
        option add \*Mywidget\.background green

        snit::widget mywidget \{
    	delegate option \-borderwidth to hull
    	delegate option \-hullbackground to hull as \-background
    	delegate option \* to hull
    	\# \.\.\.
        \}


        mywidget \.mywidget

        set A \[\.mywidget cget \-relief\]
        set B \[\.mywidget cget \-hullbackground\]
        set C \[\.mywidget cget \-background\]
        set D \[\.mywidget cget \-borderwidth\]

The question is, what are the values of variables A, B, C and D?

The value of A is "sunken"\. The hull is a Tk frame that has been given the
widget class "Mywidget"; it will automatically query the option database and
pick up this value\. Since the __\-relief__ option is implicitly delegated to
the hull, Snit takes no action\.







|
|
|
|









|
|
|
|
|
<
>









|
|
|










|
|
|
|
|
<
>







|
|
|
|
|
|
|
<
>













|

|
|
|
<
|
>
|










|
|
|
|

|
|
|
|
|
<
|
>
|

|
|
|
|







1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754

1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769

1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788

1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811

1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
The resource and class names are used to initialize option default values by
querying the Tk option database\. The resource name is usually just the option
name minus the hyphen, but may contain uppercase letters at word boundaries; the
class name is usually just the resource name with an initial capital, but not
always\. For example, here are the option, resource, and class names for several
__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget options:

    -background         background         Background
    -borderwidth        borderWidth        BorderWidth
    -insertborderwidth  insertBorderWidth  BorderWidth
    -padx               padX               Pad

As is easily seen, sometimes the resource and class names can be inferred from
the option name, but not always\.

Snit options also have a resource name and a class name\. By default, these names
follow the rule given above: the resource name is the option name without the
hyphen, and the class name is the resource name with an initial capital\. This is
true for both locally\-defined options and explicitly delegated options:

        snit::widget mywidget {
            option -background
            delegate option -borderwidth to hull
            delegate option * to text
    	# ...

        }

In this case, the widget class name is "Mywidget"\. The widget has the following
options: __\-background__, which is locally defined, and
__\-borderwidth__, which is explicitly delegated; all other widgets are
delegated to a component called "text", which is probably a Tk
__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget\. If so, __mywidget__
has all the same options as a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__
widget\. The option, resource, and class names are as follows:

    -background  background  Background
    -borderwidth borderwidth Borderwidth
    -padx        padX        Pad

Note that the locally defined option, __\-background__, happens to have the
same three names as the standard Tk __\-background__ option; and
__\-pad__, which is delegated implicitly to the __text__ component, has
the same three names for __mywidget__ as it does for the
__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget\. __\-borderwidth__, on
the other hand, has different resource and class names than usual, because the
internal word "width" isn't capitalized\. For consistency, it should be; this is
done as follows:

        snit::widget mywidget {
    	option -background
    	delegate option {-borderwidth borderWidth} to hull
    	delegate option * to text
    	# ...

        }

The class name will default to "BorderWidth", as expected\.

Suppose, however, that __mywidget__ also delegated __\-padx__ and
__\-pady__ to the hull\. In this case, both the resource name and the class
name must be specified explicitly:

        snit::widget mywidget {
    	option -background
    	delegate option {-borderwidth borderWidth} to hull
    	delegate option {-padx padX Pad} to hull
    	delegate option {-pady padY Pad} to hull
    	delegate option * to text
    	# ...

        }

__Querying the option database:__ If you set your widgetclass and option
names as described above, Snit will query the option database when each instance
is created, and will generally do the right thing when it comes to querying the
option database\. The remainder of this section goes into the gory details\.

__Initializing locally defined options:__ When an instance of a snit::widget
is created, its locally defined options are initialized as follows: each
option's resource and class names are used to query the Tk option database\. If
the result is non\-empty, it is used as the option's default; otherwise, the
default hardcoded in the type definition is used\. In either case, the default
can be overridden by the caller\. For example,

        option add *Mywidget.texture pebbled

        snit::widget mywidget {
    	option -texture smooth
    	# ...

        }

        mywidget .mywidget -texture greasy

Here, __\-texture__ would normally default to "smooth", but because of the
entry added to the option database it defaults to "pebbled"\. However, the caller
has explicitly overridden the default, and so the new widget will be "greasy"\.

__Initializing options delegated to the hull:__ A __snit::widget__'s
hull is a widget, and given that its class has been set it is expected to query
the option database for itself\. The only exception concerns options that are
delegated to it with a different name\. Consider the following code:

        option add *Mywidget.borderWidth 5
        option add *Mywidget.relief sunken
        option add *Mywidget.hullbackground red
        option add *Mywidget.background green

        snit::widget mywidget {
    	delegate option -borderwidth to hull
    	delegate option -hullbackground to hull as -background
    	delegate option * to hull
    	# ...

        }

        mywidget .mywidget

        set A [.mywidget cget -relief]
        set B [.mywidget cget -hullbackground]
        set C [.mywidget cget -background]
        set D [.mywidget cget -borderwidth]

The question is, what are the values of variables A, B, C and D?

The value of A is "sunken"\. The hull is a Tk frame that has been given the
widget class "Mywidget"; it will automatically query the option database and
pick up this value\. Since the __\-relief__ option is implicitly delegated to
the hull, Snit takes no action\.
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857


1858
1859
1860
1861

1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891


1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902


1903
1904
1905
1906
1907
1908
1909
further\.

For __snit::widgetadaptor__s, the case is somewhat altered\. Widget adaptors
retain the widget class of their hull, and the hull is not created automatically
by Snit\. Instead, the __snit::widgetadaptor__ must call __installhull__
in its constructor\. The normal way to do this is as follows:

        snit::widgetadaptor mywidget \{
    	\# \.\.\.
    	constructor \{args\} \{
    	    \# \.\.\.
    	    installhull using text \-foreground white


    	    \#
    	\}
    	\#\.\.\.
        \}


In this case, the __installhull__ command will create the hull using a
command like this:

    set hull \[text $win \-foreground white\]

The hull is a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget, so its
widget class is "Text"\. Just as with __snit::widget__ hulls, Snit assumes
that it will pick up all of its normal option values automatically; options
delegated from a different name are initialized from the option database in the
same way\.

__Initializing options delegated to other components:__ Non\-hull components
are matched against the option database in two ways\. First, a component widget
remains a widget still, and therefore is initialized from the option database in
the usual way\. Second, the option database is queried for all options delegated
to the component, and the component is initialized accordingly\-\-provided that
the __install__ command is used to create it\.

Before option database support was added to Snit, the usual way to create a
component was to simply create it in the constructor and assign its command name
to the component variable:

        snit::widget mywidget \{
    	delegate option \-background to myComp

    	constructor \{args\} \{
    	    set myComp \[text $win\.text \-foreground black\]
    	\}
        \}



The drawback of this method is that Snit has no opportunity to initialize the
component properly\. Hence, the following approach is now used:

        snit::widget mywidget \{
    	delegate option \-background to myComp

    	constructor \{args\} \{
    	    install myComp using text $win\.text \-foreground black
    	\}
        \}



The __install__ command does the following:

  - Builds a list of the options explicitly included in the __install__
    command \-\- in this case, __\-foreground__\.

  - Queries the option database for all options delegated explicitly to the







|
|
|
|
|
>
>
|
<
<
<
>




|


















|
|

|
|
<
<
>
>




|
|

|
|
<
<
>
>







1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860



1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889


1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900


1901
1902
1903
1904
1905
1906
1907
1908
1909
further\.

For __snit::widgetadaptor__s, the case is somewhat altered\. Widget adaptors
retain the widget class of their hull, and the hull is not created automatically
by Snit\. Instead, the __snit::widgetadaptor__ must call __installhull__
in its constructor\. The normal way to do this is as follows:

        snit::widgetadaptor mywidget {
    	# ...
    	constructor {args} {
    	    # ...
    	    installhull using text -foreground white
    	    #
    	}
    	#...



        }

In this case, the __installhull__ command will create the hull using a
command like this:

    set hull [text $win -foreground white]

The hull is a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget, so its
widget class is "Text"\. Just as with __snit::widget__ hulls, Snit assumes
that it will pick up all of its normal option values automatically; options
delegated from a different name are initialized from the option database in the
same way\.

__Initializing options delegated to other components:__ Non\-hull components
are matched against the option database in two ways\. First, a component widget
remains a widget still, and therefore is initialized from the option database in
the usual way\. Second, the option database is queried for all options delegated
to the component, and the component is initialized accordingly\-\-provided that
the __install__ command is used to create it\.

Before option database support was added to Snit, the usual way to create a
component was to simply create it in the constructor and assign its command name
to the component variable:

        snit::widget mywidget {
    	delegate option -background to myComp

    	constructor {args} {
    	    set myComp [text $win.text -foreground black]


    	}
        }

The drawback of this method is that Snit has no opportunity to initialize the
component properly\. Hence, the following approach is now used:

        snit::widget mywidget {
    	delegate option -background to myComp

    	constructor {args} {
    	    install myComp using text $win.text -foreground black


    	}
        }

The __install__ command does the following:

  - Builds a list of the options explicitly included in the __install__
    command \-\- in this case, __\-foreground__\.

  - Queries the option database for all options delegated explicitly to the
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944

1945
1946
1947
1948


1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
1967
1968
1969

1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985

1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031

2032
2033
2034

2035
2036
2037
2038
2039
2040
2041

## <a name='subsection10'></a>Macros and Meta\-programming

The __snit::macro__ command enables a certain amount of meta\-programming
with Snit classes\. For example, suppose you like to define properties: instance
variables that have set/get methods\. Your code might look like this:

    snit::type dog \{
        variable mood happy

        method getmood \{\} \{
            return $mood
        \}


        method setmood \{newmood\} \{
            set mood $newmood
        \}
    \}



That's nine lines of text per property\. Or, you could define the following
__snit::macro__:

    snit::macro property \{name initValue\} \{
        variable $name $initValue

        method get$name \{\} "return $name"

        method set$name \{value\} "set $name \\$value"
    \}


Note that a __snit::macro__ is just a normal Tcl proc defined in the slave
interpreter used to compile type and widget definitions; as a result, it has
access to all the commands used to define types and widgets\.

Given this new macro, you can define a property in one line of code:

    snit::type dog \{
        property mood happy
    \}


Within a macro, the commands __variable__ and
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ refer to the Snit type\-definition
commands, not the standard Tcl commands\. To get the standard Tcl commands, use
__\_variable__ and __\_proc__\.

Because a single slave interpreter is used for compiling all Snit types and
widgets in the application, there's the possibility of macro name collisions\. If
you're writing a reuseable package using Snit, and you use some
__snit::macro__s, define them in your package namespace:

    snit::macro mypkg::property \{name initValue\} \{ \.\.\. \}

    snit::type dog \{
        mypkg::property mood happy
    \}


This leaves the global namespace open for application authors\.

## <a name='subsection11'></a>Validation Types

A validation type is an object that can be used to validate Tcl values of a
particular kind\. For example, __snit::integer__ is used to validate that a
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    snit::integer validate 5     ;\# Does nothing
    snit::integer validate 5\.0   ;\# Throws an error \(not an integer\!\)

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error\.

Snit defines a family of validation types, all of which are implemented as
__snit::type__'s\. They can be used as is; in addition, their instances serve
as parameterized subtypes\. For example, a probability is a number between 0\.0
and 1\.0 inclusive:

    snit::double probability \-min 0\.0 \-max 1\.0

The example above creates an instance of __snit::double__\-\-a validation
subtype\-\-called __probability__, which can be used to validate probability
values:

    probability validate 0\.5   ;\# Does nothing
    probability validate 7\.9   ;\# Throws an error

Validation subtypes can be defined explicitly, as in the above example; when a
locally\-defined option's __\-type__ is specified, they may also be created on
the fly:

    snit::enum ::dog::breed \-values \{mutt retriever sheepdog\}

    snit::type dog \{
        \# Define subtypes on the fly\.\.\.
        option \-breed \-type \{
            snit::enum \-values \{mutt retriever sheepdog\}
        \}


        \# Or use predefined subtypes\.\.\.
        option \-breed \-type ::dog::breed
    \}


Any object that has a __validate__ method with the semantics described above
can be used as a validation type; see [Defining Validation
Types](#subsection12) for information on how to define new ones\.

Snit defines the following validation types:








|


|

<
|
>
|

<
<
>
>




|


|

|
<
>







|

<
>











|

|

<
>














|
|









|





|
|





|

|
|
|
|
<
|
>
|
|
<
>







1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942

1943
1944
1945
1946


1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958

1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029

2030
2031
2032
2033

2034
2035
2036
2037
2038
2039
2040
2041

## <a name='subsection10'></a>Macros and Meta\-programming

The __snit::macro__ command enables a certain amount of meta\-programming
with Snit classes\. For example, suppose you like to define properties: instance
variables that have set/get methods\. Your code might look like this:

    snit::type dog {
        variable mood happy

        method getmood {} {
            return $mood

        }

        method setmood {newmood} {
            set mood $newmood


        }
    }

That's nine lines of text per property\. Or, you could define the following
__snit::macro__:

    snit::macro property {name initValue} {
        variable $name $initValue

        method get$name {} "return $name"

        method set$name {value} "set $name \$value"

    }

Note that a __snit::macro__ is just a normal Tcl proc defined in the slave
interpreter used to compile type and widget definitions; as a result, it has
access to all the commands used to define types and widgets\.

Given this new macro, you can define a property in one line of code:

    snit::type dog {
        property mood happy

    }

Within a macro, the commands __variable__ and
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ refer to the Snit type\-definition
commands, not the standard Tcl commands\. To get the standard Tcl commands, use
__\_variable__ and __\_proc__\.

Because a single slave interpreter is used for compiling all Snit types and
widgets in the application, there's the possibility of macro name collisions\. If
you're writing a reuseable package using Snit, and you use some
__snit::macro__s, define them in your package namespace:

    snit::macro mypkg::property {name initValue} { ... }

    snit::type dog {
        mypkg::property mood happy

    }

This leaves the global namespace open for application authors\.

## <a name='subsection11'></a>Validation Types

A validation type is an object that can be used to validate Tcl values of a
particular kind\. For example, __snit::integer__ is used to validate that a
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    snit::integer validate 5     ;# Does nothing
    snit::integer validate 5.0   ;# Throws an error (not an integer!)

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error\.

Snit defines a family of validation types, all of which are implemented as
__snit::type__'s\. They can be used as is; in addition, their instances serve
as parameterized subtypes\. For example, a probability is a number between 0\.0
and 1\.0 inclusive:

    snit::double probability -min 0.0 -max 1.0

The example above creates an instance of __snit::double__\-\-a validation
subtype\-\-called __probability__, which can be used to validate probability
values:

    probability validate 0.5   ;# Does nothing
    probability validate 7.9   ;# Throws an error

Validation subtypes can be defined explicitly, as in the above example; when a
locally\-defined option's __\-type__ is specified, they may also be created on
the fly:

    snit::enum ::dog::breed -values {mutt retriever sheepdog}

    snit::type dog {
        # Define subtypes on the fly...
        option -breed -type {
            snit::enum -values {mutt retriever sheepdog}

        }

        # Or use predefined subtypes...
        option -breed -type ::dog::breed

    }

Any object that has a __validate__ method with the semantics described above
can be used as a validation type; see [Defining Validation
Types](#subsection12) for information on how to define new ones\.

Snit defines the following validation types:

2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147

2148
2149
2150
2151
2152
2153
2154
2155

2156
2157
2158
2159
2160
2161
2162

      * __\-type__ *type*

        Specifies the type of the list elements; *type* must be the name of a
        validation type or subtype\. In the following example, the value of
        __\-numbers__ must be a list of integers\.

    option \-numbers \-type \{snit::listtype \-type snit::integer\}

        Note that this option doesn't support defining new validation subtypes
        on the fly; that is, the following code will not work \(yet, anyway\):

    option \-numbers \-type \{
        snit::listtype \-type \{snit::integer \-min 5\}
    \}


        Instead, define the subtype explicitly:

    snit::integer gt4 \-min 5

    snit::type mytype \{
        option \-numbers \-type \{snit::listtype \-type gt4\}
    \}


  - <a name='86'></a>__snit::pixels__ __validate__ ?*value*?

  - <a name='87'></a>__snit::pixels__ *name* ?*option* *value*\.\.\.?

    *Tk programs only\.* Validates screen distances, in any of the forms
    accepted by __winfo pixels__\. Subtypes may be created with the following







|




|
|
<
>



|

|
|
<
>







2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146

2147
2148
2149
2150
2151
2152
2153
2154

2155
2156
2157
2158
2159
2160
2161
2162

      * __\-type__ *type*

        Specifies the type of the list elements; *type* must be the name of a
        validation type or subtype\. In the following example, the value of
        __\-numbers__ must be a list of integers\.

    option -numbers -type {snit::listtype -type snit::integer}

        Note that this option doesn't support defining new validation subtypes
        on the fly; that is, the following code will not work \(yet, anyway\):

    option -numbers -type {
        snit::listtype -type {snit::integer -min 5}

    }

        Instead, define the subtype explicitly:

    snit::integer gt4 -min 5

    snit::type mytype {
        option -numbers -type {snit::listtype -type gt4}

    }

  - <a name='86'></a>__snit::pixels__ __validate__ ?*value*?

  - <a name='87'></a>__snit::pixels__ *name* ?*option* *value*\.\.\.?

    *Tk programs only\.* Validates screen distances, in any of the forms
    accepted by __winfo pixels__\. Subtypes may be created with the following
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240

2241
2242

2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270

2271
2272
2273

2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286

2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305

2306
2307
2308
2309


2310
2311
2312
2313
2314
2315
2316
command\. A validation type is simply an object that has a __validate__
method; the __validate__ method must take one argument, a value, return the
value if it is valid, and throw an error with __\-errorcode__ INVALID if the
value is invalid\. This can be done with a simple
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__\. For example, the
__snit::boolean__ validate type could have been implemented like this:

    proc ::snit::boolean \{"validate" value\} \{
        if \{\!\[string is boolean \-strict $value\]\} \{
            return \-code error \-errorcode INVALID  "invalid boolean \\"$value\\", should be one of: 1, 0, \.\.\."
        \}


        return $value
    \}


A validation type defined in this way cannot be subtyped, of course; but for
many applications this will be sufficient\.

Finally, one can define a full\-fledged, subtype\-able validation type as a
__snit::type__\. Here's a skeleton to get you started:

    snit::type myinteger \{
        \# First, define any options you'd like to use to define
        \# subtypes\.  Give them defaults such that they won't take
        \# effect if they aren't used, and marked them "read\-only"\.
        \# After all, you shouldn't be changing their values after
        \# a subtype is defined\.
        \#

        \# For example:

        option \-min \-default "" \-readonly 1
        option \-max \-default "" \-readonly 1

        \# Next, define a "validate" type method which should do the
        \# validation in the basic case\.  This will allow the
        \# type command to be used as a validation type\.

        typemethod validate \{value\} \{
            if \{\!\[string is integer \-strict $value\]\} \{
                return \-code error \-errorcode INVALID  "invalid value \\"$value\\", expected integer"
            \}


            return $value
        \}


        \# Next, the constructor should validate the subtype options,
        \# if any\.  Since they are all readonly, we don't need to worry
        \# about validating the options on change\.

        constructor \{args\} \{
            \# FIRST, get the options
            $self configurelist $args

            \# NEXT, validate them\.

            \# I'll leave this to your imagination\.
        \}


        \# Next, define a "validate" instance method; its job is to
        \# validate values for subtypes\.

        method validate \{value\} \{
            \# First, call the type method to do the basic validation\.
            $type validate $value

            \# Now we know it's a valid integer\.

            if \{\("" \!= $options\(\-min\) && $value < $options\(\-min\)\)  &#124;&#124;
                \("" \!= $options\(\-max\) && $value > $options\(\-max\)\)\} \{
                \# It's out of range; format a detailed message about
                \# the error, and throw it\.

                set msg "\.\.\.\."

                return \-code error \-errorcode INVALID $msg
            \}


            \# Otherwise, if it's valid just return it\.
            return $valid
        \}
    \}



And now you have a type that can be subtyped\.

The file "validate\.tcl" in the Snit distribution defines all of Snit's
validation types; you can find the complete implementation for
__snit::integer__ and the other types there, to use as examples for your own
types\.







|
|
|
<
|
>

<
>







|
|
|
|
|
|
<
>
|

|
|

|
|
|

|
|
|
<
|
>

<
|
>
|
|
|

|
|


|

|
<
|
>
|
|

|
|


|

|
|
|
|

|

|
<
|
>
|

<
<
>
>







2229
2230
2231
2232
2233
2234
2235
2236
2237
2238

2239
2240
2241

2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255

2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268

2269
2270
2271

2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284

2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307


2308
2309
2310
2311
2312
2313
2314
2315
2316
command\. A validation type is simply an object that has a __validate__
method; the __validate__ method must take one argument, a value, return the
value if it is valid, and throw an error with __\-errorcode__ INVALID if the
value is invalid\. This can be done with a simple
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__\. For example, the
__snit::boolean__ validate type could have been implemented like this:

    proc ::snit::boolean {"validate" value} {
        if {![string is boolean -strict $value]} {
            return -code error -errorcode INVALID  "invalid boolean \"$value\", should be one of: 1, 0, ..."

        }

        return $value

    }

A validation type defined in this way cannot be subtyped, of course; but for
many applications this will be sufficient\.

Finally, one can define a full\-fledged, subtype\-able validation type as a
__snit::type__\. Here's a skeleton to get you started:

    snit::type myinteger {
        # First, define any options you'd like to use to define
        # subtypes.  Give them defaults such that they won't take
        # effect if they aren't used, and marked them "read-only".
        # After all, you shouldn't be changing their values after
        # a subtype is defined.

        #
        # For example:

        option -min -default "" -readonly 1
        option -max -default "" -readonly 1

        # Next, define a "validate" type method which should do the
        # validation in the basic case.  This will allow the
        # type command to be used as a validation type.

        typemethod validate {value} {
            if {![string is integer -strict $value]} {
                return -code error -errorcode INVALID  "invalid value \"$value\", expected integer"

            }

            return $value

        }

        # Next, the constructor should validate the subtype options,
        # if any.  Since they are all readonly, we don't need to worry
        # about validating the options on change.

        constructor {args} {
            # FIRST, get the options
            $self configurelist $args

            # NEXT, validate them.

            # I'll leave this to your imagination.

        }

        # Next, define a "validate" instance method; its job is to
        # validate values for subtypes.

        method validate {value} {
            # First, call the type method to do the basic validation.
            $type validate $value

            # Now we know it's a valid integer.

            if {("" != $options(-min) && $value < $options(-min))  ||
                ("" != $options(-max) && $value > $options(-max))} {
                # It's out of range; format a detailed message about
                # the error, and throw it.

                set msg "...."

                return -code error -errorcode INVALID $msg

            }

            # Otherwise, if it's valid just return it.
            return $valid


        }
    }

And now you have a type that can be subtyped\.

The file "validate\.tcl" in the Snit distribution defines all of Snit's
validation types; you can find the complete implementation for
__snit::integer__ and the other types there, to use as examples for your own
types\.
Changes to embedded/md/tcllib/files/modules/snit/snitfaq.md.
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
unaffected by the minor incompatibilities between the two versions\) you can use
Snit 1\.3 for Tcl 8\.4 and Snit 2\.2 for Tcl 8\.5\.

## <a name='subsection9'></a>How do I select the version of Snit I want to use?

To always use Snit 1\.3 \(or a later version of Snit 1\.x\), invoke Snit as follows:

    package require snit 1\.3

To always use Snit 2\.2 \(or a later version of Snit 2\.x\), say this instead:

    package require snit 2\.2

Note that if you request Snit 2\.2 explicitly, your application will halt with
Tcl 8\.4, since Snit 2\.2 is unavailable for Tcl 8\.4\.

If you wish your application to always use the latest available version of Snit,
don't specify a version number:








|



|







560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
unaffected by the minor incompatibilities between the two versions\) you can use
Snit 1\.3 for Tcl 8\.4 and Snit 2\.2 for Tcl 8\.5\.

## <a name='subsection9'></a>How do I select the version of Snit I want to use?

To always use Snit 1\.3 \(or a later version of Snit 1\.x\), invoke Snit as follows:

    package require snit 1.3

To always use Snit 2\.2 \(or a later version of Snit 2\.x\), say this instead:

    package require snit 2.2

Note that if you request Snit 2\.2 explicitly, your application will halt with
Tcl 8\.4, since Snit 2\.2 is unavailable for Tcl 8\.4\.

If you wish your application to always use the latest available version of Snit,
don't specify a version number:

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

There are four specific incompatibilities between Snit 1\.3 and Snit 2\.2\.

  - Snit 1\.3 supports implicit naming of objects\. Suppose you define a new
    __snit::type__ called __dog__\. You can create instances of
    __dog__ in three ways:

    dog spot               ;\# Explicit naming
    set obj1 \[dog %AUTO%\]  ;\# Automatic naming
    set obj2 \[dog\]         ;\# Implicit naming

    In Snit 2\.2, type commands are defined using the __namespace ensemble__
    mechanism; and __namespace ensemble__ doesn't allow an ensemble command
    to be called without a subcommand\. In short, using __namespace
    ensemble__ there's no way to support implicit naming\.

    All is not lost, however\. If the type has no type methods, then the type
    command is a simple command rather than an ensemble, and __namespace
    ensemble__ is not used\. In this case, implicit naming is still possible\.

    In short, you can have implicit naming if you're willing to do without type
    methods \(including the standard type methods, like __$type info__\)\. To
    do so, use the __\-hastypemethods__ pragma:

    pragma \-hastypemethods 0

  - Hierarchical methods and type methods are implemented differently in Snit
    2\.2\.

    A hierarchical method is an instance method which has subcommands; these
    subcommands are themselves methods\. The Tk text widget's __tag__ command
    and its subcommands are examples of hierarchical methods\. You can implement
    such subcommands in Snit simply by including multiple words in the method
    names:

    method \{tag configure\} \{tag args\} \{ \.\.\. \}

    method \{tag cget\} \{tag option\} \{\.\.\.\}

    Here we've implicitly defined a __tag__ method which has two
    subcommands, __configure__ and __cget__\.

    In Snit 1\.3, hierarchical methods could be called in two ways:

    $obj tag cget \-myoption      ;\# The good way
    $obj \{tag cget\} \-myoption    ;\# The weird way

    In the second call, we see that a hierarchical method or type method is
    simply one whose name contains multiple words\.

    In Snit 2\.2 this is no longer the case, and the "weird" way of calling
    hierarchical methods and type methods no longer works\.








|
|
|














|










|

|






|
|







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

There are four specific incompatibilities between Snit 1\.3 and Snit 2\.2\.

  - Snit 1\.3 supports implicit naming of objects\. Suppose you define a new
    __snit::type__ called __dog__\. You can create instances of
    __dog__ in three ways:

    dog spot               ;# Explicit naming
    set obj1 [dog %AUTO%]  ;# Automatic naming
    set obj2 [dog]         ;# Implicit naming

    In Snit 2\.2, type commands are defined using the __namespace ensemble__
    mechanism; and __namespace ensemble__ doesn't allow an ensemble command
    to be called without a subcommand\. In short, using __namespace
    ensemble__ there's no way to support implicit naming\.

    All is not lost, however\. If the type has no type methods, then the type
    command is a simple command rather than an ensemble, and __namespace
    ensemble__ is not used\. In this case, implicit naming is still possible\.

    In short, you can have implicit naming if you're willing to do without type
    methods \(including the standard type methods, like __$type info__\)\. To
    do so, use the __\-hastypemethods__ pragma:

    pragma -hastypemethods 0

  - Hierarchical methods and type methods are implemented differently in Snit
    2\.2\.

    A hierarchical method is an instance method which has subcommands; these
    subcommands are themselves methods\. The Tk text widget's __tag__ command
    and its subcommands are examples of hierarchical methods\. You can implement
    such subcommands in Snit simply by including multiple words in the method
    names:

    method {tag configure} {tag args} { ... }

    method {tag cget} {tag option} {...}

    Here we've implicitly defined a __tag__ method which has two
    subcommands, __configure__ and __cget__\.

    In Snit 1\.3, hierarchical methods could be called in two ways:

    $obj tag cget -myoption      ;# The good way
    $obj {tag cget} -myoption    ;# The weird way

    In the second call, we see that a hierarchical method or type method is
    simply one whose name contains multiple words\.

    In Snit 2\.2 this is no longer the case, and the "weird" way of calling
    hierarchical methods and type methods no longer works\.

698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    the type can call other commands defined by the package without any extra
    work\.

    This feature depends on the new Tcl 8\.5 __namespace path__ command,
    which is why it hasn't been implemented for V1\.x\. V1\.x code can achieve
    something similar by placing

    namespace import \[namespace parent\]::\*

    in a type constructor\. This is less useful, however, as it picks up only
    those commands which have already been exported by the parent namespace at
    the time the type is defined\.

# <a name='section4'></a>OBJECTS








|







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    the type can call other commands defined by the package without any extra
    work\.

    This feature depends on the new Tcl 8\.5 __namespace path__ command,
    which is why it hasn't been implemented for V1\.x\. V1\.x code can achieve
    something similar by placing

    namespace import [namespace parent]::*

    in a type constructor\. This is less useful, however, as it picks up only
    those commands which have already been exported by the parent namespace at
    the time the type is defined\.

# <a name='section4'></a>OBJECTS

741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757

Further, an *instance* is also a Tcl command\-\-a command that gives access to
the operations which are defined for that abstract data type\. Conventionally,
the operations are defined as subcommands of the instance command\. For example,
to insert text into a Tk text widget, you use the text widget's __insert__
subcommand:

    \# Create a text widget and insert some text in it\.
    text \.mytext \-width 80 \-height 24
    \.mytext insert end "Howdy\!"

In this example, __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ is the
*[type](\.\./\.\./\.\./\.\./index\.md\#type)* command and __\.mytext__ is the
*instance* command\.

In Snit, object subcommands are generally called [INSTANCE
METHODS](#section5)\.







|
|
|







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757

Further, an *instance* is also a Tcl command\-\-a command that gives access to
the operations which are defined for that abstract data type\. Conventionally,
the operations are defined as subcommands of the instance command\. For example,
to insert text into a Tk text widget, you use the text widget's __insert__
subcommand:

    # Create a text widget and insert some text in it.
    text .mytext -width 80 -height 24
    .mytext insert end "Howdy!"

In this example, __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ is the
*[type](\.\./\.\./\.\./\.\./index\.md\#type)* command and __\.mytext__ is the
*instance* command\.

In Snit, object subcommands are generally called [INSTANCE
METHODS](#section5)\.
769
770
771
772
773
774
775
776
777
778

779
780
781
782
783
784
785
## <a name='subsection15'></a>What is a snit::type?

A __snit::type__ is a non\-GUI abstract data type, e\.g\., a stack or a queue\.
__snit::type__s are defined using the __snit::type__ command\. For
example, if you were designing a kennel management system for a dog breeder,
you'd need a dog type\.

    % snit::type dog \{
        \# \.\.\.
    \}

    ::dog
    %

This definition defines a new command \(__::dog__, in this case\) that can be
used to define dog objects\.

An instance of a __snit::type__ can have [INSTANCE METHODS](#section5),







|
|
<
>







769
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
785
## <a name='subsection15'></a>What is a snit::type?

A __snit::type__ is a non\-GUI abstract data type, e\.g\., a stack or a queue\.
__snit::type__s are defined using the __snit::type__ command\. For
example, if you were designing a kennel management system for a dog breeder,
you'd need a dog type\.

    % snit::type dog {
        # ...

    }
    ::dog
    %

This definition defines a new command \(__::dog__, in this case\) that can be
used to define dog objects\.

An instance of a __snit::type__ can have [INSTANCE METHODS](#section5),
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

## <a name='subsection18'></a>How do I create an instance of a snit::type?

You create an instance of a __snit::type__ by passing the new instance's
name to the type's create method\. In the following example, we create a
__dog__ object called __spot__\.

    % snit::type dog \{
        \# \.\.\.\.
    \}

    ::dog
    % dog create spot
    ::spot
    %

In general, the __create__ method name can be omitted so long as the
instance name doesn't conflict with any defined [TYPE METHODS](#section9)\.
\(See [TYPE COMPONENTS](#section15) for the special case in which this
doesn't work\.\) So the following example is identical to the previous example:

    % snit::type dog \{
        \# \.\.\.\.
    \}

    ::dog
    % dog spot
    ::spot
    %

This document generally uses the shorter form\.

If the __dog__ type defines [OPTIONS](#section7), these can usually be
given defaults at creation time:

    % snit::type dog \{
        option \-breed mongrel
        option \-color brown

        method bark \{\} \{ return "$self barks\." \}
    \}

    ::dog
    % dog create spot \-breed dalmation \-color spotted
    ::spot
    % spot cget \-breed
    dalmation
    % spot cget \-color
    spotted
    %

Once created, the instance name now names a new Tcl command that is used to
manipulate the object\. For example, the following code makes the dog bark:

    % spot bark
    ::spot barks\.
    %

## <a name='subsection19'></a>How do I refer to an object indirectly?

Some programmers prefer to save the object name in a variable, and reference it
that way\. For example,

    % snit::type dog \{ \.\.\. \}
    ::dog
    % set d \[dog spot \-breed dalmation \-color spotted\]
    ::spot
    % $d cget \-breed
    dalmation
    % $d bark
    ::spot barks\.
    %

If you prefer this style, you might prefer to have Snit generate the instance's
name automatically\.

## <a name='subsection20'></a>How can I generate the object name automatically?

If you'd like Snit to generate an object name for you, use the __%AUTO%__
keyword as the requested name:

    % snit::type dog \{ \.\.\. \}
    ::dog
    % set d \[dog %AUTO%\]
    ::dog2
    % $d bark
    ::dog2 barks\.
    %

The __%AUTO%__ keyword can be embedded in a longer string:

    % set d \[dog obj\_%AUTO%\]
    ::obj\_dog4
    % $d bark
    ::obj\_dog4 barks\.
    %

## <a name='subsection21'></a>Can types be renamed?

Tcl's __rename__ command renames other commands\. It's a common technique in
Tcl to modify an existing command by renaming it and defining a new command with
the original name; the new command usually calls the renamed command\.







|
|
<
>










|
|
<
>










|
|
|

|
<
>

|

|

|







|







|

|

|


|










|

|


|




|
|

|







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

## <a name='subsection18'></a>How do I create an instance of a snit::type?

You create an instance of a __snit::type__ by passing the new instance's
name to the type's create method\. In the following example, we create a
__dog__ object called __spot__\.

    % snit::type dog {
        # ....

    }
    ::dog
    % dog create spot
    ::spot
    %

In general, the __create__ method name can be omitted so long as the
instance name doesn't conflict with any defined [TYPE METHODS](#section9)\.
\(See [TYPE COMPONENTS](#section15) for the special case in which this
doesn't work\.\) So the following example is identical to the previous example:

    % snit::type dog {
        # ....

    }
    ::dog
    % dog spot
    ::spot
    %

This document generally uses the shorter form\.

If the __dog__ type defines [OPTIONS](#section7), these can usually be
given defaults at creation time:

    % snit::type dog {
        option -breed mongrel
        option -color brown

        method bark {} { return "$self barks." }

    }
    ::dog
    % dog create spot -breed dalmation -color spotted
    ::spot
    % spot cget -breed
    dalmation
    % spot cget -color
    spotted
    %

Once created, the instance name now names a new Tcl command that is used to
manipulate the object\. For example, the following code makes the dog bark:

    % spot bark
    ::spot barks.
    %

## <a name='subsection19'></a>How do I refer to an object indirectly?

Some programmers prefer to save the object name in a variable, and reference it
that way\. For example,

    % snit::type dog { ... }
    ::dog
    % set d [dog spot -breed dalmation -color spotted]
    ::spot
    % $d cget -breed
    dalmation
    % $d bark
    ::spot barks.
    %

If you prefer this style, you might prefer to have Snit generate the instance's
name automatically\.

## <a name='subsection20'></a>How can I generate the object name automatically?

If you'd like Snit to generate an object name for you, use the __%AUTO%__
keyword as the requested name:

    % snit::type dog { ... }
    ::dog
    % set d [dog %AUTO%]
    ::dog2
    % $d bark
    ::dog2 barks.
    %

The __%AUTO%__ keyword can be embedded in a longer string:

    % set d [dog obj_%AUTO%]
    ::obj_dog4
    % $d bark
    ::obj_dog4 barks.
    %

## <a name='subsection21'></a>Can types be renamed?

Tcl's __rename__ command renames other commands\. It's a common technique in
Tcl to modify an existing command by renaming it and defining a new command with
the original name; the new command usually calls the renamed command\.
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
    instance methods using __$self__\.

  - If the object is renamed, however, then __$self__'s value will change\.
    Therefore, don't use __$self__ for anything that will break if
    __$self__ changes\. For example, don't pass a callback command to another
    object like this:

    \.btn configure \-command \[list $self ButtonPress\]

    You'll get an error if __\.btn__ calls your command after your object is
    renamed\.

  - Instead, your object should define its callback command like this:

    \.btn configure \-command \[mymethod ButtonPress\]

    The __mymethod__ command returns code that will call the desired method
    safely; the caller of the callback can add additional arguments to the end
    of the command as usual\.

  - Every object has a private namespace; the name of this namespace is
    available in method bodies, etc\., as the value of the implicit argument







|






|







915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
    instance methods using __$self__\.

  - If the object is renamed, however, then __$self__'s value will change\.
    Therefore, don't use __$self__ for anything that will break if
    __$self__ changes\. For example, don't pass a callback command to another
    object like this:

    .btn configure -command [list $self ButtonPress]

    You'll get an error if __\.btn__ calls your command after your object is
    renamed\.

  - Instead, your object should define its callback command like this:

    .btn configure -command [mymethod ButtonPress]

    The __mymethod__ command returns code that will call the desired method
    safely; the caller of the callback can add additional arguments to the end
    of the command as usual\.

  - Every object has a private namespace; the name of this namespace is
    available in method bodies, etc\., as the value of the implicit argument
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
Snit megawidgets \(i\.e\., instances of __snit::widget__ and
__snit::widgetadaptor__\) can be destroyed like any other widget: by using
the Tk __destroy__ command on the widget or on one of its ancestors in the
window hierarchy\.

Every instance of a __snit::type__ has a __destroy__ method:

    % snit::type dog \{ \.\.\. \}
    ::dog
    % dog spot
    ::spot
    % spot bark
    ::spot barks\.
    % spot destroy
    % spot barks
    invalid command name "spot"
    %

Finally, every Snit type has a type method called __destroy__; calling it
destroys the type and all of its instances:

    % snit::type dog \{ \.\.\. \}
    ::dog
    % dog spot
    ::spot
    % spot bark
    ::spot barks\.
    % dog destroy
    % spot bark
    invalid command name "spot"
    % dog fido
    invalid command name "dog"
    %








|




|








|




|







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
Snit megawidgets \(i\.e\., instances of __snit::widget__ and
__snit::widgetadaptor__\) can be destroyed like any other widget: by using
the Tk __destroy__ command on the widget or on one of its ancestors in the
window hierarchy\.

Every instance of a __snit::type__ has a __destroy__ method:

    % snit::type dog { ... }
    ::dog
    % dog spot
    ::spot
    % spot bark
    ::spot barks.
    % spot destroy
    % spot barks
    invalid command name "spot"
    %

Finally, every Snit type has a type method called __destroy__; calling it
destroys the type and all of its instances:

    % snit::type dog { ... }
    ::dog
    % dog spot
    ::spot
    % spot bark
    ::spot barks.
    % dog destroy
    % spot bark
    invalid command name "spot"
    % dog fido
    invalid command name "dog"
    %

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

## <a name='subsection25'></a>How do I define an instance method?

Instance methods are defined in the type definition using the
__[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement\. Consider the
following code that might be used to add dogs to a computer simulation:

    % snit::type dog \{
        method bark \{\} \{
            return "$self barks\."
        \}


        method chase \{thing\} \{
            return "$self chases $thing\."
        \}
    \}


    ::dog
    %

A dog can bark, and it can chase things\.

The __[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement looks just like
a normal Tcl __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, except that it
appears in a __snit::type__ definition\. Notice that every instance method
gets an implicit argument called __self__; this argument contains the
object's name\. \(There's more on implicit method arguments below\.\)

## <a name='subsection26'></a>How does a client call an instance method?

The method name becomes a subcommand of the object\. For example, let's put a
simulated dog through its paces:

    % dog spot
    ::spot
    % spot bark
    ::spot barks\.
    % spot chase cat
    ::spot chases cat\.
    %

## <a name='subsection27'></a>How does an instance method call another instance method?

If method A needs to call method B on the same object, it does so just as a
client does: it calls method B as a subcommand of the object itself, using the
object name stored in the implicit argument __self__\.

Suppose, for example, that our dogs never chase anything without barking at
them:

    % snit::type dog \{
        method bark \{\} \{
            return "$self barks\."
        \}


        method chase \{thing\} \{
            return "$self chases $thing\.  \[$self bark\]"
        \}
    \}


    ::dog
    % dog spot
    ::spot
    % spot bark
    ::spot barks\.
    % spot chase cat
    ::spot chases cat\.  ::spot barks\.
    %

## <a name='subsection28'></a>Are there any limitations on instance method names?

Not really, so long as you avoid the standard instance method names:
__configure__, __configurelist__, __cget__, __destroy__, and
__info__\. Also, method names consisting of multiple words define







|
|
|
<
|
>
|
|
<
<
>
>



















|

|











|
|
|
<
|
>
|
|
<
<
>
>




|

|







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

## <a name='subsection25'></a>How do I define an instance method?

Instance methods are defined in the type definition using the
__[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement\. Consider the
following code that might be used to add dogs to a computer simulation:

    % snit::type dog {
        method bark {} {
            return "$self barks."

        }

        method chase {thing} {
            return "$self chases $thing."


        }
    }
    ::dog
    %

A dog can bark, and it can chase things\.

The __[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement looks just like
a normal Tcl __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, except that it
appears in a __snit::type__ definition\. Notice that every instance method
gets an implicit argument called __self__; this argument contains the
object's name\. \(There's more on implicit method arguments below\.\)

## <a name='subsection26'></a>How does a client call an instance method?

The method name becomes a subcommand of the object\. For example, let's put a
simulated dog through its paces:

    % dog spot
    ::spot
    % spot bark
    ::spot barks.
    % spot chase cat
    ::spot chases cat.
    %

## <a name='subsection27'></a>How does an instance method call another instance method?

If method A needs to call method B on the same object, it does so just as a
client does: it calls method B as a subcommand of the object itself, using the
object name stored in the implicit argument __self__\.

Suppose, for example, that our dogs never chase anything without barking at
them:

    % snit::type dog {
        method bark {} {
            return "$self barks."

        }

        method chase {thing} {
            return "$self chases $thing.  [$self bark]"


        }
    }
    ::dog
    % dog spot
    ::spot
    % spot bark
    ::spot barks.
    % spot chase cat
    ::spot chases cat.  ::spot barks.
    %

## <a name='subsection28'></a>Are there any limitations on instance method names?

Not really, so long as you avoid the standard instance method names:
__configure__, __configurelist__, __cget__, __destroy__, and
__info__\. Also, method names consisting of multiple words define
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

## <a name='subsection30'></a>How do I define a hierarchical method?

Define methods whose names consist of multiple words\. These words define the
hierarchy implicitly\. For example, the following code defines a __tag__
method with subcommands __cget__ and __configure__:

    snit::widget mytext \{
        method \{tag configure\} \{tag args\} \{ \.\.\. \}

        method \{tag cget\} \{tag option\} \{\.\.\.\}
    \}


Note that there is no explicit definition for the __tag__ method; it is
implicit in the definition of __tag configure__ and __tag cget__\. If you
tried to define __tag__ explicitly in this example, you'd get an error\.

## <a name='subsection31'></a>How do I call hierarchical methods?

As subcommands of subcommands\.

    % mytext \.text
    \.text
    % \.text tag configure redtext \-foreground red \-background black
    % \.text tag cget redtext \-foreground
    red
    %

## <a name='subsection32'></a>How do I make an instance method private?

It's often useful to define private methods, that is, instance methods intended
to be called only by other methods of the same object\.

Snit doesn't implement any access control on instance methods, so all methods
are *de facto* public\. Conventionally, though, the names of public methods
begin with a lower\-case letter, and the names of private methods begin with an
upper\-case letter\.

For example, suppose our simulated dogs only bark in response to other stimuli;
they never bark just for fun\. So the __bark__ method becomes __Bark__ to
indicate that it is private:

    % snit::type dog \{
        \# Private by convention: begins with uppercase letter\.
        method Bark \{\} \{
            return "$self barks\."
        \}


        method chase \{thing\} \{
            return "$self chases $thing\. \[$self Bark\]"
        \}
    \}


    ::dog
    % dog fido
    ::fido
    % fido chase cat
    ::fido chases cat\. ::fido barks\.
    %

## <a name='subsection33'></a>Are there any limitations on instance method arguments?

Method argument lists are defined just like normal Tcl
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ argument lists; in particular,
they can include arguments with default values and the __args__ argument\.







|
|

|
<
>









|
|
|
|

















|
|
|
|
<
|
>
|
|
<
<
>
>




|







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

## <a name='subsection30'></a>How do I define a hierarchical method?

Define methods whose names consist of multiple words\. These words define the
hierarchy implicitly\. For example, the following code defines a __tag__
method with subcommands __cget__ and __configure__:

    snit::widget mytext {
        method {tag configure} {tag args} { ... }

        method {tag cget} {tag option} {...}

    }

Note that there is no explicit definition for the __tag__ method; it is
implicit in the definition of __tag configure__ and __tag cget__\. If you
tried to define __tag__ explicitly in this example, you'd get an error\.

## <a name='subsection31'></a>How do I call hierarchical methods?

As subcommands of subcommands\.

    % mytext .text
    .text
    % .text tag configure redtext -foreground red -background black
    % .text tag cget redtext -foreground
    red
    %

## <a name='subsection32'></a>How do I make an instance method private?

It's often useful to define private methods, that is, instance methods intended
to be called only by other methods of the same object\.

Snit doesn't implement any access control on instance methods, so all methods
are *de facto* public\. Conventionally, though, the names of public methods
begin with a lower\-case letter, and the names of private methods begin with an
upper\-case letter\.

For example, suppose our simulated dogs only bark in response to other stimuli;
they never bark just for fun\. So the __bark__ method becomes __Bark__ to
indicate that it is private:

    % snit::type dog {
        # Private by convention: begins with uppercase letter.
        method Bark {} {
            return "$self barks."

        }

        method chase {thing} {
            return "$self chases $thing. [$self Bark]"


        }
    }
    ::dog
    % dog fido
    ::fido
    % fido chase cat
    ::fido chases cat. ::fido barks.
    %

## <a name='subsection33'></a>Are there any limitations on instance method arguments?

Method argument lists are defined just like normal Tcl
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ argument lists; in particular,
they can include arguments with default values and the __args__ argument\.
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
__selfns__, __win__, and __self__\.

## <a name='subsection35'></a>What is $type?

The implicit argument __type__ contains the fully qualified name of the
object's type:

    % snit::type thing \{
        method mytype \{\} \{
            return $type
        \}
    \}


    ::thing
    % thing something
    ::something
    % something mytype
    ::thing
    %

## <a name='subsection36'></a>What is $self?

The implicit argument __self__ contains the object's fully qualified name\.

If the object's command is renamed, then __$self__ will change to match in
subsequent calls\. Thus, your code should not assume that __$self__ is
constant unless you know for sure that the object will never be renamed\.

    % snit::type thing \{
        method myself \{\} \{
            return $self
        \}
    \}


    ::thing
    % thing mutt
    ::mutt
    % mutt myself
    ::mutt
    % rename mutt jeff
    % jeff myself
    ::jeff
    %

## <a name='subsection37'></a>What is $selfns?

Each Snit object has a private namespace in which to store its [INSTANCE
VARIABLES](#section6) and [OPTIONS](#section7)\. The implicit argument
__selfns__ contains the name of this namespace; its value never changes, and
is constant for the life of the object, even if the object's name changes:

    % snit::type thing \{
        method myNameSpace \{\} \{
            return $selfns
        \}
    \}


    ::thing
    % thing jeff
    ::jeff
    % jeff myNameSpace
    ::thing::Snit\_inst3
    % rename jeff mutt
    % mutt myNameSpace
    ::thing::Snit\_inst3
    %

The above example reveals how Snit names an instance's private namespace;
however, you should not write code that depends on the specific naming
convention, as it might change in future releases\.

## <a name='subsection38'></a>What is $win?







|
|

<
<
>
>















|
|

<
<
>
>

















|
|

<
<
>
>




|


|







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
__selfns__, __win__, and __self__\.

## <a name='subsection35'></a>What is $type?

The implicit argument __type__ contains the fully qualified name of the
object's type:

    % snit::type thing {
        method mytype {} {
            return $type


        }
    }
    ::thing
    % thing something
    ::something
    % something mytype
    ::thing
    %

## <a name='subsection36'></a>What is $self?

The implicit argument __self__ contains the object's fully qualified name\.

If the object's command is renamed, then __$self__ will change to match in
subsequent calls\. Thus, your code should not assume that __$self__ is
constant unless you know for sure that the object will never be renamed\.

    % snit::type thing {
        method myself {} {
            return $self


        }
    }
    ::thing
    % thing mutt
    ::mutt
    % mutt myself
    ::mutt
    % rename mutt jeff
    % jeff myself
    ::jeff
    %

## <a name='subsection37'></a>What is $selfns?

Each Snit object has a private namespace in which to store its [INSTANCE
VARIABLES](#section6) and [OPTIONS](#section7)\. The implicit argument
__selfns__ contains the name of this namespace; its value never changes, and
is constant for the life of the object, even if the object's name changes:

    % snit::type thing {
        method myNameSpace {} {
            return $selfns


        }
    }
    ::thing
    % thing jeff
    ::jeff
    % jeff myNameSpace
    ::thing::Snit_inst3
    % rename jeff mutt
    % mutt myNameSpace
    ::thing::Snit_inst3
    %

The above example reveals how Snit names an instance's private namespace;
however, you should not write code that depends on the specific naming
convention, as it might change in future releases\.

## <a name='subsection38'></a>What is $win?
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
It depends on the context\.

Suppose in my application I have a __dog__ object named __fido__, and I
want __fido__ to bark when a Tk button called __\.bark__ is pressed\. In
this case, I create the callback command in the usual way, using
__[list](\.\./\.\./\.\./\.\./index\.md\#list)__:

    button \.bark \-text "Bark\!" \-command \[list fido bark\]

In typical Tcl style, we use a callback to hook two independent components
together\. But suppose that the __dog__ object has a graphical interface and
owns the button itself? In this case, the __dog__ must pass one of its own
instance methods to the button it owns\. The obvious thing to do is this:

    % snit::widget dog \{
        constructor \{args\} \{
            \#\.\.\.
            button $win\.barkbtn \-text "Bark\!" \-command \[list $self bark\]
            \#\.\.\.
        \}
    \}


    ::dog
    %

\(Note that in this example, our __dog__ becomes a __snit::widget__,
because it has GUI behavior\. See [WIDGETS](#section17) for more\.\) Thus, if
we create a __dog__ called __\.spot__, it will create a Tk button called
__\.spot\.barkbtn__; when pressed, the button will call __$self bark__\.

Now, this will work\-\-provided that __\.spot__ is never renamed to something
else\. But surely renaming widgets is abnormal? And so it is\-\-unless
__\.spot__ is the hull component of a __snit::widgetadaptor__\. If it is,
then it will be renamed, and __\.spot__ will become the name of the
__snit::widgetadaptor__ object\. When the button is pressed, the command
__$self bark__ will be handled by the __snit::widgetadaptor__, which
might or might not do the right thing\.

There's a safer way to do it, and it looks like this:

    % snit::widget dog \{
        constructor \{args\} \{
            \#\.\.\.
            button $win\.barkbtn \-text "Bark\!" \-command \[mymethod bark\]
            \#\.\.\.
        \}
    \}


    ::dog
    %

The command __mymethod__ takes any number of arguments, and can be used like
__[list](\.\./\.\./\.\./\.\./index\.md\#list)__ to build up a callback command;
the only difference is that __mymethod__ returns a form of the command that
won't change even if the instance's name changes\.







|






|
|
|
|
|
<
<
>
>


















|
|
|
|
|
<
<
>
>







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
It depends on the context\.

Suppose in my application I have a __dog__ object named __fido__, and I
want __fido__ to bark when a Tk button called __\.bark__ is pressed\. In
this case, I create the callback command in the usual way, using
__[list](\.\./\.\./\.\./\.\./index\.md\#list)__:

    button .bark -text "Bark!" -command [list fido bark]

In typical Tcl style, we use a callback to hook two independent components
together\. But suppose that the __dog__ object has a graphical interface and
owns the button itself? In this case, the __dog__ must pass one of its own
instance methods to the button it owns\. The obvious thing to do is this:

    % snit::widget dog {
        constructor {args} {
            #...
            button $win.barkbtn -text "Bark!" -command [list $self bark]
            #...


        }
    }
    ::dog
    %

\(Note that in this example, our __dog__ becomes a __snit::widget__,
because it has GUI behavior\. See [WIDGETS](#section17) for more\.\) Thus, if
we create a __dog__ called __\.spot__, it will create a Tk button called
__\.spot\.barkbtn__; when pressed, the button will call __$self bark__\.

Now, this will work\-\-provided that __\.spot__ is never renamed to something
else\. But surely renaming widgets is abnormal? And so it is\-\-unless
__\.spot__ is the hull component of a __snit::widgetadaptor__\. If it is,
then it will be renamed, and __\.spot__ will become the name of the
__snit::widgetadaptor__ object\. When the button is pressed, the command
__$self bark__ will be handled by the __snit::widgetadaptor__, which
might or might not do the right thing\.

There's a safer way to do it, and it looks like this:

    % snit::widget dog {
        constructor {args} {
            #...
            button $win.barkbtn -text "Bark!" -command [mymethod bark]
            #...


        }
    }
    ::dog
    %

The command __mymethod__ takes any number of arguments, and can be used like
__[list](\.\./\.\./\.\./\.\./index\.md\#list)__ to build up a callback command;
the only difference is that __mymethod__ returns a form of the command that
won't change even if the instance's name changes\.
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

## <a name='subsection42'></a>How is a scalar instance variable defined?

Scalar instance variables are defined in the type definition using the
__variable__ statement\. You can simply name it, or you can initialize it
with a value:

    snit::type mytype \{
        \# Define variable "greeting" and initialize it with "Howdy\!"
        variable greeting "Howdy\!"
    \}


## <a name='subsection43'></a>How is an array instance variable defined?

Array instance variables are also defined in the type definition using the
__variable__ command\. You can initialize them at the same time by specifying
the __\-array__ option:

    snit::type mytype \{
        \# Define array variable "greetings"
        variable greetings \-array \{
            formal "Good Evening"
            casual "Howdy\!"
        \}
    \}



## <a name='subsection44'></a>What happens if I don't initialize an instance variable?

Variables do not really exist until they are given values\. If you do not
initialize a variable when you define it, then you must be sure to assign a
value to it \(in the constructor, say, or in some method\) before you reference
it\.







|
|
|
<
>







|
|
|

|
<
<
>
>







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

## <a name='subsection42'></a>How is a scalar instance variable defined?

Scalar instance variables are defined in the type definition using the
__variable__ statement\. You can simply name it, or you can initialize it
with a value:

    snit::type mytype {
        # Define variable "greeting" and initialize it with "Howdy!"
        variable greeting "Howdy!"

    }

## <a name='subsection43'></a>How is an array instance variable defined?

Array instance variables are also defined in the type definition using the
__variable__ command\. You can initialize them at the same time by specifying
the __\-array__ option:

    snit::type mytype {
        # Define array variable "greetings"
        variable greetings -array {
            formal "Good Evening"
            casual "Howdy!"


        }
    }

## <a name='subsection44'></a>What happens if I don't initialize an instance variable?

Variables do not really exist until they are given values\. If you do not
initialize a variable when you define it, then you must be sure to assign a
value to it \(in the constructor, say, or in some method\) before you reference
it\.
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
anyway\. This method breaks down if your instance variables include multiple
arrays; in Tcl 8\.5, however, the __[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__
command might come to your rescue\.

The second method is to declare your instance variables explicitly in your
instance code, while *not* including them in the type definition:

    snit::type dog \{
        constructor \{\} \{
            variable mood

            set mood happy
        \}


        method setmood \{newMood\} \{
            variable mood

            set mood $newMood
        \}


        method getmood \{\} \{
            variable mood

            return $mood
        \}
    \}



This allows you to ensure that only the required variables are included in each
method, at the cost of longer code and run\-time errors when you forget to
declare a variable you need\.

## <a name='subsection47'></a>How do I pass an instance variable's name to another object?

In Tk, it's common to pass a widget a variable name; for example, Tk label
widgets have a __\-textvariable__ option which names the variable which will
contain the widget's text\. This allows the program to update the label's value
just by assigning a new value to the variable\.

If you naively pass the instance variable name to the label widget, you'll be
confused by the result; Tk will assume that the name names a global variable\.
Instead, you need to provide a fully\-qualified variable name\. From within an
instance method or a constructor, you can fully qualify the variable's name
using the __myvar__ command:

    snit::widget mywidget \{
        variable labeltext ""

        constructor \{args\} \{
            \# \.\.\.

            label $win\.label \-textvariable \[myvar labeltext\]

            \# \.\.\.
        \}
    \}



## <a name='subsection48'></a>How do I make an instance variable public?

Practically speaking, you don't\. Instead, you'll implement public variables as
[OPTIONS](#section7)\. Alternatively, you can write [INSTANCE
METHODS](#section5) to set and get the variable's value\.








|
|



<
|
>
|



<
|
>
|



<
<
>
>


















|


|
|

|

|
<
<
>
>







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
anyway\. This method breaks down if your instance variables include multiple
arrays; in Tcl 8\.5, however, the __[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__
command might come to your rescue\.

The second method is to declare your instance variables explicitly in your
instance code, while *not* including them in the type definition:

    snit::type dog {
        constructor {} {
            variable mood

            set mood happy

        }

        method setmood {newMood} {
            variable mood

            set mood $newMood

        }

        method getmood {} {
            variable mood

            return $mood


        }
    }

This allows you to ensure that only the required variables are included in each
method, at the cost of longer code and run\-time errors when you forget to
declare a variable you need\.

## <a name='subsection47'></a>How do I pass an instance variable's name to another object?

In Tk, it's common to pass a widget a variable name; for example, Tk label
widgets have a __\-textvariable__ option which names the variable which will
contain the widget's text\. This allows the program to update the label's value
just by assigning a new value to the variable\.

If you naively pass the instance variable name to the label widget, you'll be
confused by the result; Tk will assume that the name names a global variable\.
Instead, you need to provide a fully\-qualified variable name\. From within an
instance method or a constructor, you can fully qualify the variable's name
using the __myvar__ command:

    snit::widget mywidget {
        variable labeltext ""

        constructor {args} {
            # ...

            label $win.label -textvariable [myvar labeltext]

            # ...


        }
    }

## <a name='subsection48'></a>How do I make an instance variable public?

Practically speaking, you don't\. Instead, you'll implement public variables as
[OPTIONS](#section7)\. Alternatively, you can write [INSTANCE
METHODS](#section5) to set and get the variable's value\.

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
1652
1653
1654


1655
1656
1657
1658
1659
1660
1661

## <a name='subsection50'></a>How do I define an option?

Options are defined in the type definition using the __option__ statement\.
Consider the following type, to be used in an application that manages a list of
dogs for a pet store:

    snit::type dog \{
        option \-breed \-default mongrel
        option \-color \-default brown
        option \-akc   \-default 0
        option \-shots \-default 0
    \}


According to this, a dog has four notable properties: a breed, a color, a flag
that says whether it's pedigreed with the American Kennel Club, and another flag
that says whether it has had its shots\. The default dog, evidently, is a brown
mutt\.

There are a number of options you can specify when defining an option; if
__\-default__ is the only one, you can omit the word __\-default__ as
follows:

    snit::type dog \{
        option \-breed mongrel
        option \-color brown
        option \-akc   0
        option \-shots 0
    \}


If no __\-default__ value is specified, the option's default value will be
the empty string \(but see [THE TK OPTION DATABASE](#section19)\)\.

The Snit man page refers to options like these as "locally defined" options\.

## <a name='subsection51'></a>How can a client set options at object creation?

The normal convention is that the client may pass any number of options and
their values after the object's name at object creation\. For example, the
__::dog__ command defined in the previous answer can now be used to create
individual dogs\. Any or all of the options may be set at creation time\.

    % dog spot \-breed beagle \-color "mottled" \-akc 1 \-shots 1
    ::spot
    % dog fido \-shots 1
    ::fido
    %

So __::spot__ is a pedigreed beagle; __::fido__ is a typical mutt, but
his owners evidently take care of him, because he's had his shots\.

*Note:* If the type defines a constructor, it can specify a different
object\-creation syntax\. See [CONSTRUCTORS](#section12) for more
information\.

## <a name='subsection52'></a>How can a client retrieve an option's value?

Retrieve option values using the __cget__ method:

    % spot cget \-color
    mottled
    % fido cget \-breed
    mongrel
    %

## <a name='subsection53'></a>How can a client set options after object creation?

Any number of options may be set at one time using the __configure__
instance method\. Suppose that closer inspection shows that ::fido is not a brown
mongrel, but rather a rare Arctic Boar Hound of a lovely dun color:

    % fido configure \-color dun \-breed "Arctic Boar Hound"
    % fido cget \-color
    dun
    % fido cget \-breed
    Arctic Boar Hound

Alternatively, the __configurelist__ method takes a list of options and
values; occasionally this is more convenient:

    % set features \[list \-color dun \-breed "Arctic Boar Hound"\]
    \-color dun \-breed \{Arctic Boar Hound\}
    % fido configurelist $features
    % fido cget \-color
    dun
    % fido cget \-breed
    Arctic Boar Hound
    %

In Tcl 8\.5, the __\*__ keyword can be used with __configure__ in this
case:

    % set features \[list \-color dun \-breed "Arctic Boar Hound"\]
    \-color dun \-breed \{Arctic Boar Hound\}
    % fido configure \{\*\}$features
    % fido cget \-color
    dun
    % fido cget \-breed
    Arctic Boar Hound
    %

The results are the same\.

## <a name='subsection54'></a>How should an instance method access an option value?

There are two ways an instance method can set and retrieve an option's value\.
One is to use the __configure__ and __cget__ methods, as shown below\.

    % snit::type dog \{
        option \-weight 10

        method gainWeight \{\} \{
            set wt \[$self cget \-weight\]
            incr wt
            $self configure \-weight $wt
        \}
    \}


    ::dog
    % dog fido
    ::fido
    % fido cget \-weight
    10
    % fido gainWeight
    % fido cget \-weight
    11
    %

Alternatively, Snit provides a built\-in array instance variable called
__options__\. The indices are the option names; the values are the option
values\. The method __gainWeight__ can thus be rewritten as follows:

    method gainWeight \{\} \{
        incr options\(\-weight\)
    \}


As you can see, using the __options__ variable involves considerably less
typing and is the usual way to do it\. But if you use __\-configuremethod__ or
__\-cgetmethod__ \(described in the following answers\), you might wish to use
the __configure__ and __cget__ methods anyway, just so that any special
processing you've implemented is sure to get done\. Also, if the option is
delegated to a component then __configure__ and __cget__ are the only
way to access it without accessing the component directly\. See
[DELEGATION](#section16) for more information\.

## <a name='subsection55'></a>How can I make an option read\-only?

Define the option with __\-readonly yes__\.

Suppose you've got an option that determines how instances of your type are
constructed; it must be set at creation time, after which it's constant\. For
example, a dog never changes its breed; it might or might not have had its
shots, and if not can have them at a later time\. __\-breed__ should be
read\-only, but __\-shots__ should not be\.

    % snit::type dog \{
        option \-breed \-default mongrel \-readonly yes
        option \-shots \-default no
    \}

    ::dog
    % dog fido \-breed retriever
    ::fido
    % fido configure \-shots yes
    % fido configure \-breed terrier
    option \-breed can only be set at instance creation
    %

## <a name='subsection56'></a>How can I catch accesses to an option's value?

Define a __\-cgetmethod__ for the option\.

## <a name='subsection57'></a>What is a \-cgetmethod?

A __\-cgetmethod__ is a method that's called whenever the related option's
value is queried via the __cget__ instance method\. The handler can compute
the option's value, retrieve it from a database, or do anything else you'd like
it to do\.

Here's what the default behavior would look like if written using a
__\-cgetmethod__:

    snit::type dog \{
        option \-color \-default brown \-cgetmethod GetOption

        method GetOption \{option\} \{
            return $options\($option\)
        \}
    \}



Any instance method can be used, provided that it takes one argument, the name
of the option whose value is to be retrieved\.

## <a name='subsection58'></a>How can I catch changes to an option's value?

Define a __\-configuremethod__ for the option\.

## <a name='subsection59'></a>What is a \-configuremethod?

A __\-configuremethod__ is a method that's called whenever the related option
is given a new value via the __configure__ or __configurelist__ instance
methods\. The method can pass the value on to some other object, store it in a
database, or do anything else you'd like it to do\.

Here's what the default configuration behavior would look like if written using
a __\-configuremethod__:

    snit::type dog \{
        option \-color \-default brown \-configuremethod SetOption

        method SetOption \{option value\} \{
            set options\($option\) $value
        \}
    \}



Any instance method can be used, provided that it takes two arguments, the name
of the option and the new value\.

Note that if your method doesn't store the value in the __options__ array,
the __options__ array won't get updated\.








|
|
|
|
|
<
>










|
|
|
|
|
<
>













|

|














|

|









|
|

|





|
|

|

|






|
|
|
|

|










|
|

|
|

|
<
<
>
>



|


|







|
|
<
>




















|
|
|
<
>

|

|
|
|
















|
|

|
|
<
<
>
>


















|
|

|
|
<
<
>
>







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
1652


1653
1654
1655
1656
1657
1658
1659
1660
1661

## <a name='subsection50'></a>How do I define an option?

Options are defined in the type definition using the __option__ statement\.
Consider the following type, to be used in an application that manages a list of
dogs for a pet store:

    snit::type dog {
        option -breed -default mongrel
        option -color -default brown
        option -akc   -default 0
        option -shots -default 0

    }

According to this, a dog has four notable properties: a breed, a color, a flag
that says whether it's pedigreed with the American Kennel Club, and another flag
that says whether it has had its shots\. The default dog, evidently, is a brown
mutt\.

There are a number of options you can specify when defining an option; if
__\-default__ is the only one, you can omit the word __\-default__ as
follows:

    snit::type dog {
        option -breed mongrel
        option -color brown
        option -akc   0
        option -shots 0

    }

If no __\-default__ value is specified, the option's default value will be
the empty string \(but see [THE TK OPTION DATABASE](#section19)\)\.

The Snit man page refers to options like these as "locally defined" options\.

## <a name='subsection51'></a>How can a client set options at object creation?

The normal convention is that the client may pass any number of options and
their values after the object's name at object creation\. For example, the
__::dog__ command defined in the previous answer can now be used to create
individual dogs\. Any or all of the options may be set at creation time\.

    % dog spot -breed beagle -color "mottled" -akc 1 -shots 1
    ::spot
    % dog fido -shots 1
    ::fido
    %

So __::spot__ is a pedigreed beagle; __::fido__ is a typical mutt, but
his owners evidently take care of him, because he's had his shots\.

*Note:* If the type defines a constructor, it can specify a different
object\-creation syntax\. See [CONSTRUCTORS](#section12) for more
information\.

## <a name='subsection52'></a>How can a client retrieve an option's value?

Retrieve option values using the __cget__ method:

    % spot cget -color
    mottled
    % fido cget -breed
    mongrel
    %

## <a name='subsection53'></a>How can a client set options after object creation?

Any number of options may be set at one time using the __configure__
instance method\. Suppose that closer inspection shows that ::fido is not a brown
mongrel, but rather a rare Arctic Boar Hound of a lovely dun color:

    % fido configure -color dun -breed "Arctic Boar Hound"
    % fido cget -color
    dun
    % fido cget -breed
    Arctic Boar Hound

Alternatively, the __configurelist__ method takes a list of options and
values; occasionally this is more convenient:

    % set features [list -color dun -breed "Arctic Boar Hound"]
    -color dun -breed {Arctic Boar Hound}
    % fido configurelist $features
    % fido cget -color
    dun
    % fido cget -breed
    Arctic Boar Hound
    %

In Tcl 8\.5, the __\*__ keyword can be used with __configure__ in this
case:

    % set features [list -color dun -breed "Arctic Boar Hound"]
    -color dun -breed {Arctic Boar Hound}
    % fido configure {*}$features
    % fido cget -color
    dun
    % fido cget -breed
    Arctic Boar Hound
    %

The results are the same\.

## <a name='subsection54'></a>How should an instance method access an option value?

There are two ways an instance method can set and retrieve an option's value\.
One is to use the __configure__ and __cget__ methods, as shown below\.

    % snit::type dog {
        option -weight 10

        method gainWeight {} {
            set wt [$self cget -weight]
            incr wt
            $self configure -weight $wt


        }
    }
    ::dog
    % dog fido
    ::fido
    % fido cget -weight
    10
    % fido gainWeight
    % fido cget -weight
    11
    %

Alternatively, Snit provides a built\-in array instance variable called
__options__\. The indices are the option names; the values are the option
values\. The method __gainWeight__ can thus be rewritten as follows:

    method gainWeight {} {
        incr options(-weight)

    }

As you can see, using the __options__ variable involves considerably less
typing and is the usual way to do it\. But if you use __\-configuremethod__ or
__\-cgetmethod__ \(described in the following answers\), you might wish to use
the __configure__ and __cget__ methods anyway, just so that any special
processing you've implemented is sure to get done\. Also, if the option is
delegated to a component then __configure__ and __cget__ are the only
way to access it without accessing the component directly\. See
[DELEGATION](#section16) for more information\.

## <a name='subsection55'></a>How can I make an option read\-only?

Define the option with __\-readonly yes__\.

Suppose you've got an option that determines how instances of your type are
constructed; it must be set at creation time, after which it's constant\. For
example, a dog never changes its breed; it might or might not have had its
shots, and if not can have them at a later time\. __\-breed__ should be
read\-only, but __\-shots__ should not be\.

    % snit::type dog {
        option -breed -default mongrel -readonly yes
        option -shots -default no

    }
    ::dog
    % dog fido -breed retriever
    ::fido
    % fido configure -shots yes
    % fido configure -breed terrier
    option -breed can only be set at instance creation
    %

## <a name='subsection56'></a>How can I catch accesses to an option's value?

Define a __\-cgetmethod__ for the option\.

## <a name='subsection57'></a>What is a \-cgetmethod?

A __\-cgetmethod__ is a method that's called whenever the related option's
value is queried via the __cget__ instance method\. The handler can compute
the option's value, retrieve it from a database, or do anything else you'd like
it to do\.

Here's what the default behavior would look like if written using a
__\-cgetmethod__:

    snit::type dog {
        option -color -default brown -cgetmethod GetOption

        method GetOption {option} {
            return $options($option)


        }
    }

Any instance method can be used, provided that it takes one argument, the name
of the option whose value is to be retrieved\.

## <a name='subsection58'></a>How can I catch changes to an option's value?

Define a __\-configuremethod__ for the option\.

## <a name='subsection59'></a>What is a \-configuremethod?

A __\-configuremethod__ is a method that's called whenever the related option
is given a new value via the __configure__ or __configurelist__ instance
methods\. The method can pass the value on to some other object, store it in a
database, or do anything else you'd like it to do\.

Here's what the default configuration behavior would look like if written using
a __\-configuremethod__:

    snit::type dog {
        option -color -default brown -configuremethod SetOption

        method SetOption {option value} {
            set options($option) $value


        }
    }

Any instance method can be used, provided that it takes two arguments, the name
of the option and the new value\.

Note that if your method doesn't store the value in the __options__ array,
the __options__ array won't get updated\.

1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686



1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
valid, and throw an error if it isn't\. The __\-validatemethod__, if any, is
called before the value is stored in the __options__ array; in particular,
it's called before the __\-configuremethod__, if any\.

For example, suppose an option always takes a Boolean value\. You can ensure that
the value is in fact a valid Boolean like this:

    % snit::type dog \{
        option \-shots \-default no \-validatemethod BooleanOption

        method BooleanOption \{option value\} \{
            if \{\!\[string is boolean \-strict $value\]\} \{
                error "expected a boolean value, got \\"$value\\""
            \}
        \}
    \}



    ::dog
    % dog fido
    % fido configure \-shots yes
    % fido configure \-shots NotABooleanValue
    expected a boolean value, got "NotABooleanValue"
    %

Note that the same __\-validatemethod__ can be used to validate any number of
boolean options\.

Any method can be a __\-validatemethod__ provided that it takes two







|
|

|
|
|
<
<
<
>
>
>


|
|







1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683



1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
valid, and throw an error if it isn't\. The __\-validatemethod__, if any, is
called before the value is stored in the __options__ array; in particular,
it's called before the __\-configuremethod__, if any\.

For example, suppose an option always takes a Boolean value\. You can ensure that
the value is in fact a valid Boolean like this:

    % snit::type dog {
        option -shots -default no -validatemethod BooleanOption

        method BooleanOption {option value} {
            if {![string is boolean -strict $value]} {
                error "expected a boolean value, got \"$value\""



            }
        }
    }
    ::dog
    % dog fido
    % fido configure -shots yes
    % fido configure -shots NotABooleanValue
    expected a boolean value, got "NotABooleanValue"
    %

Note that the same __\-validatemethod__ can be used to validate any number of
boolean options\.

Any method can be a __\-validatemethod__ provided that it takes two
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718

1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734


1735
1736
1737
1738
1739
1740
1741

## <a name='subsection63'></a>How is a scalar type variable defined?

Scalar type variables are defined in the type definition using the
__typevariable__ statement\. You can simply name it, or you can initialize it
with a value:

    snit::type mytype \{
        \# Define variable "greeting" and initialize it with "Howdy\!"
        typevariable greeting "Howdy\!"
    \}


Every object of type __mytype__ now has access to a single variable called
__greeting__\.

## <a name='subsection64'></a>How is an array\-valued type variable defined?

Array\-valued type variables are also defined using the __typevariable__
command; to initialize them, include the __\-array__ option:

    snit::type mytype \{
        \# Define typearray variable "greetings"
        typevariable greetings \-array \{
            formal "Good Evening"
            casual "Howdy\!"
        \}
    \}



## <a name='subsection65'></a>What happens if I don't initialize a type variable?

Variables do not really exist until they are given values\. If you do not
initialize a variable when you define it, then you must be sure to assign a
value to it \(in the type constructor, say\) before you reference it\.








|
|
|
<
>









|
|
|

|
<
<
>
>







1708
1709
1710
1711
1712
1713
1714
1715
1716
1717

1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732


1733
1734
1735
1736
1737
1738
1739
1740
1741

## <a name='subsection63'></a>How is a scalar type variable defined?

Scalar type variables are defined in the type definition using the
__typevariable__ statement\. You can simply name it, or you can initialize it
with a value:

    snit::type mytype {
        # Define variable "greeting" and initialize it with "Howdy!"
        typevariable greeting "Howdy!"

    }

Every object of type __mytype__ now has access to a single variable called
__greeting__\.

## <a name='subsection64'></a>How is an array\-valued type variable defined?

Array\-valued type variables are also defined using the __typevariable__
command; to initialize them, include the __\-array__ option:

    snit::type mytype {
        # Define typearray variable "greetings"
        typevariable greetings -array {
            formal "Good Evening"
            casual "Howdy!"


        }
    }

## <a name='subsection65'></a>What happens if I don't initialize a type variable?

Variables do not really exist until they are given values\. If you do not
initialize a variable when you define it, then you must be sure to assign a
value to it \(in the type constructor, say\) before you reference it\.

1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781


1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794

1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818


1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845

1846

1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857

If you naively pass a type variable name to the label widget, you'll be confused
by the result; Tk will assume that the name names a global variable\. Instead,
you need to provide a fully\-qualified variable name\. From within an instance
method or a constructor, you can fully qualify the type variable's name using
the __mytypevar__ command:

    snit::widget mywidget \{
        typevariable labeltext ""

        constructor \{args\} \{
            \# \.\.\.

            label $win\.label \-textvariable \[mytypevar labeltext\]

            \# \.\.\.
        \}
    \}



## <a name='subsection69'></a>How do I make a type variable public?

There are two ways to do this\. The preferred way is to write a pair of [TYPE
METHODS](#section9) to set and query the type variable's value\.

Type variables are stored in the type's namespace, which has the same name as
the type itself\. Thus, you can also publicize the type variable's name in your
documentation so that clients can access it directly\. For example,

    snit::type mytype \{
        typevariable myvariable
    \}


    set ::mytype::myvariable "New Value"

# <a name='section9'></a>TYPE METHODS

## <a name='subsection70'></a>What is a type method?

A type method is a procedure associated with the type itself rather than with
any specific instance of the type, and called as a subcommand of the type
command\.

## <a name='subsection71'></a>How do I define a type method?

Type methods are defined in the type definition using the __typemethod__
statement:

    snit::type dog \{
        \# List of pedigreed dogs
        typevariable pedigreed

        typemethod pedigreedDogs \{\} \{
            return $pedigreed
        \}
    \}



Suppose the __dog__ type maintains a list of the names of the dogs that have
pedigrees\. The __pedigreedDogs__ type method returns this list\.

The __typemethod__ statement looks just like a normal Tcl
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, except that it appears in a
__snit::type__ definition\. Notice that every type method gets an implicit
argument called __type__, which contains the fully\-qualified type name\.

## <a name='subsection72'></a>How does a client call a type method?

The type method name becomes a subcommand of the type's command\. For example,
assuming that the constructor adds each pedigreed dog to the list of
__pedigreedDogs__,

    snit::type dog \{
        option \-pedigreed 0

        \# List of pedigreed dogs
        typevariable pedigreed

        typemethod pedigreedDogs \{\} \{
            return $pedigreed
        \}

        \# \.\.\.
    \}



    dog spot \-pedigreed 1
    dog fido

    foreach dog \[dog pedigreedDogs\] \{ \.\.\. \}

## <a name='subsection73'></a>Are there any limitations on type method names?

Not really, so long as you avoid the standard type method names: __create__,
__destroy__, and __info__\.

## <a name='subsection74'></a>How do I make a type method private?







|


|
|

|

|
<
<
>
>










|

<
>
















|
|


|

<
<
>
>















|
|

|


|

<
|
|
<
>
|
>
|


|







1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779


1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793

1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816


1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841

1842
1843

1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857

If you naively pass a type variable name to the label widget, you'll be confused
by the result; Tk will assume that the name names a global variable\. Instead,
you need to provide a fully\-qualified variable name\. From within an instance
method or a constructor, you can fully qualify the type variable's name using
the __mytypevar__ command:

    snit::widget mywidget {
        typevariable labeltext ""

        constructor {args} {
            # ...

            label $win.label -textvariable [mytypevar labeltext]

            # ...


        }
    }

## <a name='subsection69'></a>How do I make a type variable public?

There are two ways to do this\. The preferred way is to write a pair of [TYPE
METHODS](#section9) to set and query the type variable's value\.

Type variables are stored in the type's namespace, which has the same name as
the type itself\. Thus, you can also publicize the type variable's name in your
documentation so that clients can access it directly\. For example,

    snit::type mytype {
        typevariable myvariable

    }

    set ::mytype::myvariable "New Value"

# <a name='section9'></a>TYPE METHODS

## <a name='subsection70'></a>What is a type method?

A type method is a procedure associated with the type itself rather than with
any specific instance of the type, and called as a subcommand of the type
command\.

## <a name='subsection71'></a>How do I define a type method?

Type methods are defined in the type definition using the __typemethod__
statement:

    snit::type dog {
        # List of pedigreed dogs
        typevariable pedigreed

        typemethod pedigreedDogs {} {
            return $pedigreed


        }
    }

Suppose the __dog__ type maintains a list of the names of the dogs that have
pedigrees\. The __pedigreedDogs__ type method returns this list\.

The __typemethod__ statement looks just like a normal Tcl
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, except that it appears in a
__snit::type__ definition\. Notice that every type method gets an implicit
argument called __type__, which contains the fully\-qualified type name\.

## <a name='subsection72'></a>How does a client call a type method?

The type method name becomes a subcommand of the type's command\. For example,
assuming that the constructor adds each pedigreed dog to the list of
__pedigreedDogs__,

    snit::type dog {
        option -pedigreed 0

        # List of pedigreed dogs
        typevariable pedigreed

        typemethod pedigreedDogs {} {
            return $pedigreed

        }


        # ...
    }

    dog spot -pedigreed 1
    dog fido

    foreach dog [dog pedigreedDogs] { ... }

## <a name='subsection73'></a>Are there any limitations on type method names?

Not really, so long as you avoid the standard type method names: __create__,
__destroy__, and __info__\.

## <a name='subsection74'></a>How do I make a type method private?
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892


1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
defined for [INSTANCE METHODS](#section5)\.

## <a name='subsection76'></a>How does an instance or type method call a type method?

If an instance or type method needs to call a type method, it should use
__$type__ to do so:

    snit::type dog \{

        typemethod pedigreedDogs \{\} \{ \.\.\. \}

        typemethod printPedigrees \{\} \{
            foreach obj \[$type pedigreedDogs\] \{ \.\.\. \}
        \}
    \}



## <a name='subsection77'></a>How do I pass a type method as a callback?

It's common in Tcl to pass a snippet of code to another object, for it to call
later\. Because types cannot be renamed, you can just use the type name, or, if
the callback is registered from within a type method, __type__\. For example,
suppose we want to print a list of pedigreed dogs when a Tk button is pushed:

    button \.btn \-text "Pedigrees" \-command \[list dog printPedigrees\]
    pack \.btn

Alternatively, from a method or type method you can use the __mytypemethod__
command, just as you would use __mymethod__ to define a callback command for
[INSTANCE METHODS](#section5)\.

## <a name='subsection78'></a>Can type methods be hierarchical?








|

|

|
|
<
<
>
>








|
|







1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890


1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
defined for [INSTANCE METHODS](#section5)\.

## <a name='subsection76'></a>How does an instance or type method call a type method?

If an instance or type method needs to call a type method, it should use
__$type__ to do so:

    snit::type dog {

        typemethod pedigreedDogs {} { ... }

        typemethod printPedigrees {} {
            foreach obj [$type pedigreedDogs] { ... }


        }
    }

## <a name='subsection77'></a>How do I pass a type method as a callback?

It's common in Tcl to pass a snippet of code to another object, for it to call
later\. Because types cannot be renamed, you can just use the type name, or, if
the callback is registered from within a type method, __type__\. For example,
suppose we want to print a list of pedigreed dogs when a Tk button is pushed:

    button .btn -text "Pedigrees" -command [list dog printPedigrees]
    pack .btn

Alternatively, from a method or type method you can use the __mytypemethod__
command, just as you would use __mymethod__ to define a callback command for
[INSTANCE METHODS](#section5)\.

## <a name='subsection78'></a>Can type methods be hierarchical?

1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933

1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964


1965
1966
1967
1968
1969
1970
1971
isn't related to any particular instance\.

## <a name='subsection80'></a>How do I define a proc?

Procs are defined by including a __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__
statement in the type definition:

    snit::type mytype \{
        \# Pops and returns the first item from the list stored in the
        \# listvar, updating the listvar
       proc pop \{listvar\} \{ \.\.\. \}

       \# \.\.\.
    \}


## <a name='subsection81'></a>Are there any limitations on proc names?

Any name can be used, so long as it does not begin with __Snit\___; names
beginning with __Snit\___ are reserved for Snit's own use\. However, the wise
programmer will avoid __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ names
\(__[set](\.\./\.\./\.\./\.\./index\.md\#set)__,
__[list](\.\./\.\./\.\./\.\./index\.md\#list)__, __if__, etc\.\) that would
shadow standard Tcl command names\.

__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ names, being private, should begin
with a capital letter according to convention; however, as there are typically
no public __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__s in the type's namespace
it doesn't matter much either way\.

## <a name='subsection82'></a>How does a method call a proc?

Just like it calls any Tcl command\. For example,

    snit::type mytype \{
        \# Pops and returns the first item from the list stored in the
        \# listvar, updating the listvar
        proc pop \{listvar\} \{ \.\.\. \}

        variable requestQueue \{\}

        \# Get one request from the queue and process it\.
        method processRequest \{\} \{
            set req \[pop requestQueue\]
        \}
    \}



## <a name='subsection83'></a>How can I pass a proc to another object as a callback?

The __myproc__ command returns a callback command for the
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, just as __mymethod__ does for
a method\.








|
|
|
|

|
<
>



















|
|
|
|

|

|
|
|
<
<
>
>







1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932

1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962


1963
1964
1965
1966
1967
1968
1969
1970
1971
isn't related to any particular instance\.

## <a name='subsection80'></a>How do I define a proc?

Procs are defined by including a __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__
statement in the type definition:

    snit::type mytype {
        # Pops and returns the first item from the list stored in the
        # listvar, updating the listvar
       proc pop {listvar} { ... }

       # ...

    }

## <a name='subsection81'></a>Are there any limitations on proc names?

Any name can be used, so long as it does not begin with __Snit\___; names
beginning with __Snit\___ are reserved for Snit's own use\. However, the wise
programmer will avoid __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ names
\(__[set](\.\./\.\./\.\./\.\./index\.md\#set)__,
__[list](\.\./\.\./\.\./\.\./index\.md\#list)__, __if__, etc\.\) that would
shadow standard Tcl command names\.

__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ names, being private, should begin
with a capital letter according to convention; however, as there are typically
no public __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__s in the type's namespace
it doesn't matter much either way\.

## <a name='subsection82'></a>How does a method call a proc?

Just like it calls any Tcl command\. For example,

    snit::type mytype {
        # Pops and returns the first item from the list stored in the
        # listvar, updating the listvar
        proc pop {listvar} { ... }

        variable requestQueue {}

        # Get one request from the queue and process it.
        method processRequest {} {
            set req [pop requestQueue]


        }
    }

## <a name='subsection83'></a>How can I pass a proc to another object as a callback?

The __myproc__ command returns a callback command for the
__[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__, just as __mymethod__ does for
a method\.

1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995


1996
1997
1998
1999
2000
2001
2002
## <a name='subsection85'></a>How do I define a type constructor?

A type constructor is defined by using the __typeconstructor__ statement in
the type definition\. For example, suppose the type uses an array\-valued type
variable as a look\-up table, and the values in the array have to be computed at
start\-up\.

    % snit::type mytype \{
        typevariable lookupTable

        typeconstructor \{
            array set lookupTable \{key value\.\.\.\}
        \}
    \}



# <a name='section12'></a>CONSTRUCTORS

## <a name='subsection86'></a>What is a constructor?

In object\-oriented programming, an object's constructor is responsible for
initializing the object completely at creation time\. The constructor receives







|


|
|
<
<
>
>







1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993


1994
1995
1996
1997
1998
1999
2000
2001
2002
## <a name='subsection85'></a>How do I define a type constructor?

A type constructor is defined by using the __typeconstructor__ statement in
the type definition\. For example, suppose the type uses an array\-valued type
variable as a look\-up table, and the values in the array have to be computed at
start\-up\.

    % snit::type mytype {
        typevariable lookupTable

        typeconstructor {
            array set lookupTable {key value...}


        }
    }

# <a name='section12'></a>CONSTRUCTORS

## <a name='subsection86'></a>What is a constructor?

In object\-oriented programming, an object's constructor is responsible for
initializing the object completely at creation time\. The constructor receives
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030


2031
2032
2033
2034


2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053


2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078

2079
2080

2081
2082
2083
2084
2085
2086
2087
2088
2089

A constructor is defined by using the __constructor__ statement in the type
definition\. Suppose that it's desired to keep a list of all pedigreed dogs\. The
list can be maintained in a type variable and retrieved by a type method\.
Whenever a dog is created, it can add itself to the list\-\-provided that it's
registered with the American Kennel Club\.

    % snit::type dog \{
        option \-akc 0

        typevariable akcList \{\}

        constructor \{args\} \{
            $self configurelist $args

            if \{$options\(\-akc\)\} \{
                lappend akcList $self
            \}
        \}



        typemethod akclist \{\} \{
            return $akcList
        \}
    \}


    ::dog
    % dog spot \-akc 1
    ::spot
    % dog fido
    ::fido
    % dog akclist
    ::spot
    %

## <a name='subsection88'></a>What does the default constructor do?

If you don't provide a constructor explicitly, you get the default constructor,
which is identical to the explicitly\-defined constructor shown here:

    snit::type dog \{
        constructor \{args\} \{
            $self configurelist $args
        \}
    \}



When the constructor is called, __args__ will be set to the list of
arguments that follow the object's name\. The constructor is allowed to interpret
this list any way it chooses; the normal convention is to assume that it's a
list of option names and values, as shown in the example above\. If you simply
want to save the option values, you should use the __configurelist__ method,
as shown\.

## <a name='subsection89'></a>Can I choose a different set of arguments for the constructor?

Yes, you can\. For example, suppose we wanted to be sure that the breed was
explicitly stated for every dog at creation time, and couldn't be changed
thereafter\. One way to do that is as follows:

    % snit::type dog \{
        variable breed

        option \-color brown
        option \-akc 0

        constructor \{theBreed args\} \{
            set breed $theBreed
            $self configurelist $args
        \}


        method breed \{\} \{ return $breed \}
    \}

    ::dog
    % dog spot dalmatian \-color spotted \-akc 1
    ::spot
    % spot breed
    dalmatian

The drawback is that this syntax is non\-standard, and may limit the
compatibility of your new type with other people's code\. For example, Snit
assumes that it can create [COMPONENTS](#section14) using the standard







|
|

|

|


|

<
<
|
>
>
|

<
<
>
>

|












|
|

<
<
>
>














|


|
|

|


<
|
>
|
<
>

|







2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027


2028
2029
2030
2031
2032


2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051


2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076

2077
2078
2079

2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

A constructor is defined by using the __constructor__ statement in the type
definition\. Suppose that it's desired to keep a list of all pedigreed dogs\. The
list can be maintained in a type variable and retrieved by a type method\.
Whenever a dog is created, it can add itself to the list\-\-provided that it's
registered with the American Kennel Club\.

    % snit::type dog {
        option -akc 0

        typevariable akcList {}

        constructor {args} {
            $self configurelist $args

            if {$options(-akc)} {
                lappend akcList $self


            }
        }

        typemethod akclist {} {
            return $akcList


        }
    }
    ::dog
    % dog spot -akc 1
    ::spot
    % dog fido
    ::fido
    % dog akclist
    ::spot
    %

## <a name='subsection88'></a>What does the default constructor do?

If you don't provide a constructor explicitly, you get the default constructor,
which is identical to the explicitly\-defined constructor shown here:

    snit::type dog {
        constructor {args} {
            $self configurelist $args


        }
    }

When the constructor is called, __args__ will be set to the list of
arguments that follow the object's name\. The constructor is allowed to interpret
this list any way it chooses; the normal convention is to assume that it's a
list of option names and values, as shown in the example above\. If you simply
want to save the option values, you should use the __configurelist__ method,
as shown\.

## <a name='subsection89'></a>Can I choose a different set of arguments for the constructor?

Yes, you can\. For example, suppose we wanted to be sure that the breed was
explicitly stated for every dog at creation time, and couldn't be changed
thereafter\. One way to do that is as follows:

    % snit::type dog {
        variable breed

        option -color brown
        option -akc 0

        constructor {theBreed args} {
            set breed $theBreed
            $self configurelist $args

        }

        method breed {} { return $breed }

    }
    ::dog
    % dog spot dalmatian -color spotted -akc 1
    ::spot
    % spot breed
    dalmatian

The drawback is that this syntax is non\-standard, and may limit the
compatibility of your new type with other people's code\. For example, Snit
assumes that it can create [COMPONENTS](#section14) using the standard
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135


2136
2137
2138
2139
2140
2141
2142
2143


2144
2145
2146
2147


2148
2149
2150
2151
2152
2153
2154

Destructors are defined by using the __destructor__ statement in the type
definition\.

Suppose we're maintaining a list of pedigreed dogs; then we'll want to remove
dogs from it when they are destroyed\.

    snit::type dog \{
        option \-akc 0

        typevariable akcList \{\}

        constructor \{args\} \{
            $self configurelist $args

            if \{$options\(\-akc\)\} \{
                lappend akcList $self
            \}
        \}



        destructor \{
            set ndx \[lsearch $akcList $self\]

            if \{$ndx \!= \-1\} \{
                set akcList \[lreplace $akcList $ndx $ndx\]
            \}
        \}



        typemethod akclist \{\} \{
            return $akcList
        \}
    \}



## <a name='subsection94'></a>Are there any limitations on destructor arguments?

Yes; a destructor has no explicit arguments\.

## <a name='subsection95'></a>What implicit arguments are passed to the destructor?








|
|

|

|


|

<
<
|
>
>
|
|

|
|
<
<
|
>
>
|

<
<
>
>







2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132


2133
2134
2135
2136
2137
2138
2139
2140


2141
2142
2143
2144
2145


2146
2147
2148
2149
2150
2151
2152
2153
2154

Destructors are defined by using the __destructor__ statement in the type
definition\.

Suppose we're maintaining a list of pedigreed dogs; then we'll want to remove
dogs from it when they are destroyed\.

    snit::type dog {
        option -akc 0

        typevariable akcList {}

        constructor {args} {
            $self configurelist $args

            if {$options(-akc)} {
                lappend akcList $self


            }
        }

        destructor {
            set ndx [lsearch $akcList $self]

            if {$ndx != -1} {
                set akcList [lreplace $akcList $ndx $ndx]


            }
        }

        typemethod akclist {} {
            return $akcList


        }
    }

## <a name='subsection94'></a>Are there any limitations on destructor arguments?

Yes; a destructor has no explicit arguments\.

## <a name='subsection95'></a>What implicit arguments are passed to the destructor?

2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195

2196
2197
2198
2199


2200
2201
2202
2203
2204
2205
2206

For example, a __dog__ might create a __tail__ component; the component
will need to be destroyed\. But suppose there's an error while processing the
creation options\-\-the destructor will be called, and there will be no
__tail__ to destroy\. The simplest solution is generally to catch and ignore
any errors while destroying components\.

    snit::type dog \{
        component tail

        constructor \{args\} \{
            $self configurelist $args

            set tail \[tail %AUTO%\]
        \}


        destructor \{
            catch \{$tail destroy\}
        \}
    \}



# <a name='section14'></a>COMPONENTS

## <a name='subsection98'></a>What is a component?

Often an object will create and manage a number of other objects\. A Snit
megawidget, for example, will often create a number of Tk widgets\. These objects







|


|


|
<
|
>
|
|
<
<
>
>







2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193

2194
2195
2196
2197


2198
2199
2200
2201
2202
2203
2204
2205
2206

For example, a __dog__ might create a __tail__ component; the component
will need to be destroyed\. But suppose there's an error while processing the
creation options\-\-the destructor will be called, and there will be no
__tail__ to destroy\. The simplest solution is generally to catch and ignore
any errors while destroying components\.

    snit::type dog {
        component tail

        constructor {args} {
            $self configurelist $args

            set tail [tail %AUTO%]

        }

        destructor {
            catch {$tail destroy}


        }
    }

# <a name='section14'></a>COMPONENTS

## <a name='subsection98'></a>What is a component?

Often an object will create and manage a number of other objects\. A Snit
megawidget, for example, will often create a number of Tk widgets\. These objects
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234

2235
2236
2237
2238


2239
2240
2241
2242
2243
2244
2245
__component__ statement\. The __component__ statement declares an
*instance variable* which is used to store the component's command name when
the component is created\.

For example, suppose your __dog__ object creates a __tail__ object \(the
better to wag with, no doubt\):

    snit::type dog \{
        component mytail

        constructor \{args\} \{
            \# Create and save the component's command
            set mytail \[tail %AUTO% \-partof $self\]
            $self configurelist $args
        \}


        method wag \{\} \{
            $mytail wag
        \}
    \}



As shown here, it doesn't matter what the __tail__ object's real name is;
the __dog__ object refers to it by its component name\.

The above example shows one way to delegate the __wag__ method to the
__mytail__ component; see [DELEGATION](#section16) for an easier way\.








|


|
|
|

<
|
>
|

<
<
>
>







2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232

2233
2234
2235
2236


2237
2238
2239
2240
2241
2242
2243
2244
2245
__component__ statement\. The __component__ statement declares an
*instance variable* which is used to store the component's command name when
the component is created\.

For example, suppose your __dog__ object creates a __tail__ object \(the
better to wag with, no doubt\):

    snit::type dog {
        component mytail

        constructor {args} {
            # Create and save the component's command
            set mytail [tail %AUTO% -partof $self]
            $self configurelist $args

        }

        method wag {} {
            $mytail wag


        }
    }

As shown here, it doesn't matter what the __tail__ object's real name is;
the __dog__ object refers to it by its component name\.

The above example shows one way to delegate the __wag__ method to the
__mytail__ component; see [DELEGATION](#section16) for an easier way\.

2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285

2286
2287
2288

2289
2290
2291
2292
2293
2294
2295
2296


2297
2298
2299
2300
2301
2302
2303
2304
2305

2306
2307
2308
2309

2310
2311
2312
2313


2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334


2335
2336
2337
2338
2339
2340
2341
controlled by the __snit::type__ or __snit::widget__\.

As stated above, a component is an object to which our object can delegate
methods or options\. Under this definition, our object will usually create its
component objects, but not necessarily\. Consider the following: a dog object has
a tail component; but tail knows that it's part of the dog:

    snit::type dog \{
        component mytail

        constructor \{args\} \{
            set mytail \[tail %AUTO% \-partof $self\]
            $self configurelist $args
        \}


        destructor \{
            catch \{$mytail destroy\}
        \}


        delegate method wagtail to mytail as wag

        method bark \{\} \{
            return "$self barked\."
        \}
    \}



     snit::type tail \{
         component mydog
         option \-partof \-readonly yes

         constructor \{args\} \{
             $self configurelist $args
             set mydog $options\(\-partof\)
         \}


         method wag \{\} \{
             return "Wag, wag\."
         \}


         method pull \{\} \{
             $mydog bark
         \}
     \}



Thus, if you ask a dog to wag its tail, it tells its tail to wag; and if you
pull the dog's tail, the tail tells the dog to bark\. In this scenario, the tail
is a component of the dog, and the dog is a component of the tail, but the dog
owns the tail and not the other way around\.

## <a name='subsection103'></a>What does the install command do?

The __install__ command creates an owned component using a specified
command, and assigns the result to the component's instance variable\. For
example:

    snit::type dog \{
        component mytail

        constructor \{args\} \{
            \# set mytail \[tail %AUTO% \-partof $self\]
            install mytail using tail %AUTO% \-partof $self
            $self configurelist $args
        \}
    \}



In a __snit::type__'s code, the __install__ command shown above is
equivalent to the __set mytail__ command that's commented out\. In a
__snit::widget__'s or __snit::widgetadaptor__'s, code, however, the
__install__ command also queries [THE TK OPTION DATABASE](#section19)
and initializes the new component's options accordingly\. For consistency, it's a
good idea to get in the habit of using __install__ for all owned components\.







|


|
|

<
|
>
|
|
<
>



|
|
<
<
|
>
>
|

|

|

|
<
|
>
|
|
<
|
>
|

<
<
>
>












|


|
|
|

<
<
>
>







2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283

2284
2285
2286
2287

2288
2289
2290
2291
2292
2293


2294
2295
2296
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307

2308
2309
2310
2311


2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332


2333
2334
2335
2336
2337
2338
2339
2340
2341
controlled by the __snit::type__ or __snit::widget__\.

As stated above, a component is an object to which our object can delegate
methods or options\. Under this definition, our object will usually create its
component objects, but not necessarily\. Consider the following: a dog object has
a tail component; but tail knows that it's part of the dog:

    snit::type dog {
        component mytail

        constructor {args} {
            set mytail [tail %AUTO% -partof $self]
            $self configurelist $args

        }

        destructor {
            catch {$mytail destroy}

        }

        delegate method wagtail to mytail as wag

        method bark {} {
            return "$self barked."


        }
    }

     snit::type tail {
         component mydog
         option -partof -readonly yes

         constructor {args} {
             $self configurelist $args
             set mydog $options(-partof)

         }

         method wag {} {
             return "Wag, wag."

         }

         method pull {} {
             $mydog bark


         }
     }

Thus, if you ask a dog to wag its tail, it tells its tail to wag; and if you
pull the dog's tail, the tail tells the dog to bark\. In this scenario, the tail
is a component of the dog, and the dog is a component of the tail, but the dog
owns the tail and not the other way around\.

## <a name='subsection103'></a>What does the install command do?

The __install__ command creates an owned component using a specified
command, and assigns the result to the component's instance variable\. For
example:

    snit::type dog {
        component mytail

        constructor {args} {
            # set mytail [tail %AUTO% -partof $self]
            install mytail using tail %AUTO% -partof $self
            $self configurelist $args


        }
    }

In a __snit::type__'s code, the __install__ command shown above is
equivalent to the __set mytail__ command that's commented out\. In a
__snit::widget__'s or __snit::widgetadaptor__'s, code, however, the
__install__ command also queries [THE TK OPTION DATABASE](#section19)
and initializes the new component's options accordingly\. For consistency, it's a
good idea to get in the habit of using __install__ for all owned components\.
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371


2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
command names, i\.e\., names which include the full namespace of the command\. Note
that Snit always creates objects with fully qualified names\.

Next, the object names of components and owned by your object must be unique\.
This is no problem for widget components, since widget names are always unique;
but consider the following code:

    snit::type tail \{ \.\.\. \}

    snit::type dog \{
        delegate method wag to mytail

        constructor \{\} \{
            install mytail using tail mytail
        \}
    \}



This code uses the component name, __mytail__, as the component object name\.
This is not good, and here's why: Snit instance code executes in the Snit type's
namespace\. In this case, the __mytail__ component is created in the
__::dog::__ namespace, and will thus have the name __::dog::mytail__\.

Now, suppose you create two dogs\. Both dogs will attempt to create a tail called
__::dog::mytail__\. The first will succeed, and the second will fail, since
Snit won't let you create an object if its name is already a command\. Here are
two ways to avoid this situation:

First, if the component type is a __snit::type__ you can specify
__%AUTO%__ as its name, and be guaranteed to get a unique name\. This is the
safest thing to do:

    install mytail using tail %AUTO%

If the component type isn't a __snit::type__ you can create the component in
the object's instance namespace:

    install mytail using tail $\{selfns\}::mytail

Make sure you pick a unique name within the instance namespace\.

## <a name='subsection106'></a>Must I destroy the components I own?

That depends\. When a parent widget is destroyed, all child widgets are destroyed
automatically\. Thus, if your object is a __snit::widget__ or







|

|


|

<
<
>
>




















|







2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369


2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
command names, i\.e\., names which include the full namespace of the command\. Note
that Snit always creates objects with fully qualified names\.

Next, the object names of components and owned by your object must be unique\.
This is no problem for widget components, since widget names are always unique;
but consider the following code:

    snit::type tail { ... }

    snit::type dog {
        delegate method wag to mytail

        constructor {} {
            install mytail using tail mytail


        }
    }

This code uses the component name, __mytail__, as the component object name\.
This is not good, and here's why: Snit instance code executes in the Snit type's
namespace\. In this case, the __mytail__ component is created in the
__::dog::__ namespace, and will thus have the name __::dog::mytail__\.

Now, suppose you create two dogs\. Both dogs will attempt to create a tail called
__::dog::mytail__\. The first will succeed, and the second will fail, since
Snit won't let you create an object if its name is already a command\. Here are
two ways to avoid this situation:

First, if the component type is a __snit::type__ you can specify
__%AUTO%__ as its name, and be guaranteed to get a unique name\. This is the
safest thing to do:

    install mytail using tail %AUTO%

If the component type isn't a __snit::type__ you can create the component in
the object's instance namespace:

    install mytail using tail ${selfns}::mytail

Make sure you pick a unique name within the instance namespace\.

## <a name='subsection106'></a>Must I destroy the components I own?

That depends\. When a parent widget is destroyed, all child widgets are destroyed
automatically\. Thus, if your object is a __snit::widget__ or
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436


2437
2438
2439
2440
2441
2442
2443
2444
2445
__\-public__ option\. The value of this option is the name of a method which
will be delegated to your component's object command\.

For example, supposed you've written a combobox megawidget which owns a listbox
widget, and you want to make the listbox's entire interface public\. You can do
it like this:

    snit::widget combobox \{
         component listbox \-public listbox

         constructor \{args\} \{
             install listbox using listbox $win\.listbox \.\.\.\.
         \}
    \}



    combobox \.mycombo
    \.mycombo listbox configure \-width 30

Your comobox widget, __\.mycombo__, now has a __listbox__ method which
has all of the same subcommands as the listbox widget itself\. Thus, the above
code sets the listbox component's width to 30\.

Usually you'll let the method name be the same as the component name; however,
you can name it anything you like\.







|
|

|
|
<
<
|
>
>
|
|







2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433


2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
__\-public__ option\. The value of this option is the name of a method which
will be delegated to your component's object command\.

For example, supposed you've written a combobox megawidget which owns a listbox
widget, and you want to make the listbox's entire interface public\. You can do
it like this:

    snit::widget combobox {
         component listbox -public listbox

         constructor {args} {
             install listbox using listbox $win.listbox ....


         }
    }

    combobox .mycombo
    .mycombo listbox configure -width 30

Your comobox widget, __\.mycombo__, now has a __listbox__ method which
has all of the same subcommands as the listbox widget itself\. Thus, the above
code sets the listbox component's width to 30\.

Usually you'll let the method name be the same as the component name; however,
you can name it anything you like\.
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477

2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496


2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521

2522
2523
2524
2525

2526
2527
2528
2529

2530
2531
2532
2533
2534
2535

2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562


2563
2564
2565
2566

2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598


2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611

2612
2613
2614
2615

2616
2617

2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637

2638
2639
2640
2641
2642
2643
2644
same options \(__\-inherit__ and __\-public__\) as the __component__
statement does, and defines a type variable to hold the type component's object
command\.

Suppose in your model you've got many dogs, but only one veterinarian\. You might
make the veterinarian a type component\.

    snit::type veterinarian \{ \.\.\. \}

    snit::type dog \{
        typecomponent vet

        \# \.\.\.
    \}


## <a name='subsection111'></a>How do I install a type component?

Just use the __[set](\.\./\.\./\.\./\.\./index\.md\#set)__ command to assign the
component's object command to the type component\. Because types \(even
__snit::widget__ types\) are not widgets, and do not have options anyway, the
extra features of the __install__ command are not needed\.

You'll usually install type components in the type constructor, as shown here:

    snit::type veterinarian \{ \.\.\. \}

    snit::type dog \{
        typecomponent vet

        typeconstructor \{
            set vet \[veterinarian %AUTO%\]
        \}
    \}



## <a name='subsection112'></a>Are there any limitations on type component names?

Yes, the same as on [INSTANCE VARIABLES](#section6), [TYPE
VARIABLES](#section8), and normal [COMPONENTS](#section14)\.

# <a name='section16'></a>DELEGATION

## <a name='subsection113'></a>What is delegation?

Delegation, simply put, is when you pass a task you've been given to one of your
assistants\. \(You do have assistants, don't you?\) Snit objects can do the same
thing\. The following example shows one way in which the __dog__ object can
delegate its __wag__ method and its __\-taillength__ option to its
__tail__ component\.

    snit::type dog \{
        variable mytail

        option \-taillength \-configuremethod SetTailOption \-cgetmethod GetTailOption

        method SetTailOption \{option value\} \{
             $mytail configure $option $value
        \}


        method GetTailOption \{option\} \{
             $mytail cget $option
        \}


        method wag \{\} \{
            $mytail wag
        \}


        constructor \{args\} \{
            install mytail using tail %AUTO% \-partof $self
            $self configurelist $args
        \}

    \}


This is the hard way to do it, by it demonstrates what delegation is all about\.
See the following answers for the easy way to do it\.

Note that the constructor calls the __configurelist__ method
__[after](\.\./\.\./\.\./\.\./index\.md\#after)__ it creates its __tail__;
otherwise, if __\-taillength__ appeared in the list of __args__ we'd get
an error\.

## <a name='subsection114'></a>How can I delegate a method to a component object?

Delegation occurs frequently enough that Snit makes it easy\. Any method can be
delegated to any component or type component by placing a single
__delegate__ statement in the type definition\. \(See
[COMPONENTS](#section14) and [TYPE COMPONENTS](#section15) for more
information about component names\.\)

For example, here's a much better way to delegate the __dog__ object's
__wag__ method:

    % snit::type dog \{
        delegate method wag to mytail

        constructor \{\} \{
            install mytail using tail %AUTO%
        \}
    \}


    ::dog
    % snit::type tail \{
        method wag \{\} \{ return "Wag, wag, wag\."\}
    \}

    ::tail
    % dog spot
    ::spot
    % spot wag
    Wag, wag, wag\.

This code has the same effect as the code shown under the previous question:
when a __dog__'s __wag__ method is called, the call and its arguments
are passed along automatically to the __tail__ object\.

Note that when a component is mentioned in a __delegate__ statement, the
component's instance variable is defined implicitly\. However, it's still good
practice to declare it explicitly using the __component__ statement\.

Note also that you can define a method name using the
__[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement, or you can define
it using __delegate__; you can't do both\.

## <a name='subsection115'></a>Can I delegate to a method with a different name?

Suppose you wanted to delegate the __dog__'s __wagtail__ method to the
__tail__'s __wag__ method\. After all you wag the tail, not the dog\. It's
easily done:

    snit::type dog \{
        delegate method wagtail to mytail as wag

        constructor \{args\} \{
            install mytail using tail %AUTO% \-partof $self
            $self configurelist $args
        \}
    \}



## <a name='subsection116'></a>Can I delegate to a method with additional arguments?

Suppose the __tail__'s __wag__ method takes as an argument the number of
times the tail should be wagged\. You want to delegate the __dog__'s
__wagtail__ method to the __tail__'s __wag__ method, specifying that
the tail should be wagged exactly three times\. This is easily done, too:

    snit::type dog \{
        delegate method wagtail to mytail as \{wag 3\}
        \# \.\.\.
    \}


    snit::type tail \{
        method wag \{count\} \{
            return \[string repeat "Wag " $count\]
        \}

        \# \.\.\.
    \}


## <a name='subsection117'></a>Can I delegate a method to something other than an object?

Normal method delegation assumes that you're delegating a method \(a subcommand
of an object command\) to a method of another object \(a subcommand of a different
object command\)\. But not all Tcl objects follow Tk conventions, and not
everything you'd to which you'd like to delegate a method is necessary an
object\. Consequently, Snit makes it easy to delegate a method to pretty much
anything you like using the __delegate__ statement's __using__ clause\.

Suppose your dog simulation stores dogs in a database, each dog as a single
record\. The database API you're using provides a number of commands to manage
records; each takes the record ID \(a string you choose\) as its first argument\.
For example, __saverec__ saves a record\. If you let the record ID be the
name of the dog object, you can delegate the dog's __save__ method to the
__saverec__ command as follows:

    snit::type dog \{
        delegate method save using \{saverec %s\}
    \}


The __%s__ is replaced with the instance name when the __save__ method
is called; any additional arguments are the appended to the resulting command\.

The __using__ clause understands a number of other %\-conversions; in
addition to the instance name, you can substitute in the method name
\(__%m__\), the type name \(__%t__\), the instance namespace \(__%n__\),







|

|


|
<
>










|

|


|
|
<
<
>
>
















|


|

|

<
|
>
|

<
|
>
|

<
|
>
|
|

<
|
|
>




















|


|

<
<
>
>

|
|
<
>




|



















|


|
|

<
<
>
>








|
|
|
<
|
>
|
|
|
<
>
|
<
>

















|
|
<
>







2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476

2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494


2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519

2520
2521
2522
2523

2524
2525
2526
2527

2528
2529
2530
2531
2532

2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560


2561
2562
2563
2564
2565

2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596


2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609

2610
2611
2612
2613
2614

2615
2616

2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636

2637
2638
2639
2640
2641
2642
2643
2644
same options \(__\-inherit__ and __\-public__\) as the __component__
statement does, and defines a type variable to hold the type component's object
command\.

Suppose in your model you've got many dogs, but only one veterinarian\. You might
make the veterinarian a type component\.

    snit::type veterinarian { ... }

    snit::type dog {
        typecomponent vet

        # ...

    }

## <a name='subsection111'></a>How do I install a type component?

Just use the __[set](\.\./\.\./\.\./\.\./index\.md\#set)__ command to assign the
component's object command to the type component\. Because types \(even
__snit::widget__ types\) are not widgets, and do not have options anyway, the
extra features of the __install__ command are not needed\.

You'll usually install type components in the type constructor, as shown here:

    snit::type veterinarian { ... }

    snit::type dog {
        typecomponent vet

        typeconstructor {
            set vet [veterinarian %AUTO%]


        }
    }

## <a name='subsection112'></a>Are there any limitations on type component names?

Yes, the same as on [INSTANCE VARIABLES](#section6), [TYPE
VARIABLES](#section8), and normal [COMPONENTS](#section14)\.

# <a name='section16'></a>DELEGATION

## <a name='subsection113'></a>What is delegation?

Delegation, simply put, is when you pass a task you've been given to one of your
assistants\. \(You do have assistants, don't you?\) Snit objects can do the same
thing\. The following example shows one way in which the __dog__ object can
delegate its __wag__ method and its __\-taillength__ option to its
__tail__ component\.

    snit::type dog {
        variable mytail

        option -taillength -configuremethod SetTailOption -cgetmethod GetTailOption

        method SetTailOption {option value} {
             $mytail configure $option $value

        }

        method GetTailOption {option} {
             $mytail cget $option

        }

        method wag {} {
            $mytail wag

        }

        constructor {args} {
            install mytail using tail %AUTO% -partof $self
            $self configurelist $args

        }

    }

This is the hard way to do it, by it demonstrates what delegation is all about\.
See the following answers for the easy way to do it\.

Note that the constructor calls the __configurelist__ method
__[after](\.\./\.\./\.\./\.\./index\.md\#after)__ it creates its __tail__;
otherwise, if __\-taillength__ appeared in the list of __args__ we'd get
an error\.

## <a name='subsection114'></a>How can I delegate a method to a component object?

Delegation occurs frequently enough that Snit makes it easy\. Any method can be
delegated to any component or type component by placing a single
__delegate__ statement in the type definition\. \(See
[COMPONENTS](#section14) and [TYPE COMPONENTS](#section15) for more
information about component names\.\)

For example, here's a much better way to delegate the __dog__ object's
__wag__ method:

    % snit::type dog {
        delegate method wag to mytail

        constructor {} {
            install mytail using tail %AUTO%


        }
    }
    ::dog
    % snit::type tail {
        method wag {} { return "Wag, wag, wag."}

    }
    ::tail
    % dog spot
    ::spot
    % spot wag
    Wag, wag, wag.

This code has the same effect as the code shown under the previous question:
when a __dog__'s __wag__ method is called, the call and its arguments
are passed along automatically to the __tail__ object\.

Note that when a component is mentioned in a __delegate__ statement, the
component's instance variable is defined implicitly\. However, it's still good
practice to declare it explicitly using the __component__ statement\.

Note also that you can define a method name using the
__[method](\.\./\.\./\.\./\.\./index\.md\#method)__ statement, or you can define
it using __delegate__; you can't do both\.

## <a name='subsection115'></a>Can I delegate to a method with a different name?

Suppose you wanted to delegate the __dog__'s __wagtail__ method to the
__tail__'s __wag__ method\. After all you wag the tail, not the dog\. It's
easily done:

    snit::type dog {
        delegate method wagtail to mytail as wag

        constructor {args} {
            install mytail using tail %AUTO% -partof $self
            $self configurelist $args


        }
    }

## <a name='subsection116'></a>Can I delegate to a method with additional arguments?

Suppose the __tail__'s __wag__ method takes as an argument the number of
times the tail should be wagged\. You want to delegate the __dog__'s
__wagtail__ method to the __tail__'s __wag__ method, specifying that
the tail should be wagged exactly three times\. This is easily done, too:

    snit::type dog {
        delegate method wagtail to mytail as {wag 3}
        # ...

    }

    snit::type tail {
        method wag {count} {
            return [string repeat "Wag " $count]

        }
        # ...

    }

## <a name='subsection117'></a>Can I delegate a method to something other than an object?

Normal method delegation assumes that you're delegating a method \(a subcommand
of an object command\) to a method of another object \(a subcommand of a different
object command\)\. But not all Tcl objects follow Tk conventions, and not
everything you'd to which you'd like to delegate a method is necessary an
object\. Consequently, Snit makes it easy to delegate a method to pretty much
anything you like using the __delegate__ statement's __using__ clause\.

Suppose your dog simulation stores dogs in a database, each dog as a single
record\. The database API you're using provides a number of commands to manage
records; each takes the record ID \(a string you choose\) as its first argument\.
For example, __saverec__ saves a record\. If you let the record ID be the
name of the dog object, you can delegate the dog's __save__ method to the
__saverec__ command as follows:

    snit::type dog {
        delegate method save using {saverec %s}

    }

The __%s__ is replaced with the instance name when the __save__ method
is called; any additional arguments are the appended to the resulting command\.

The __using__ clause understands a number of other %\-conversions; in
addition to the instance name, you can substitute in the method name
\(__%m__\), the type name \(__%t__\), the instance namespace \(__%n__\),
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680


2681
2682
2683
2684
2685

2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715


2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739

2740
2741
2742
2743


2744
2745
2746
2747
2748
2749
2750

The first question in this section \(see [DELEGATION](#section16)\) shows one
way to delegate an option to a component; but this pattern occurs often enough
that Snit makes it easy\. For example, every __tail__ object has a
__\-length__ option; we want to allow the creator of a __dog__ object to
set the tail's length\. We can do this:

    % snit::type dog \{
        delegate option \-length to mytail

        constructor \{args\} \{
            install mytail using tail %AUTO% \-partof $self
            $self configurelist $args
        \}
    \}


    ::dog
    % snit::type tail \{
        option \-partof
        option \-length 5
    \}

    ::tail
    % dog spot \-length 7
    ::spot
    % spot cget \-length
    7

This produces nearly the same result as the __\-configuremethod__ and
__\-cgetmethod__ shown under the first question in this section: whenever a
__dog__ object's __\-length__ option is set or retrieved, the underlying
__tail__ object's option is set or retrieved in turn\.

Note that you can define an option name using the __option__ statement, or
you can define it using __delegate__; you can't do both\.

## <a name='subsection121'></a>Can I delegate to an option with a different name?

In the previous answer we delegated the __dog__'s __\-length__ option
down to its __tail__\. This is, of course, wrong\. The dog has a length, and
the tail has a length, and they are different\. What we'd really like to do is
give the __dog__ a __\-taillength__ option, but delegate it to the
__tail__'s __\-length__ option:

    snit::type dog \{
        delegate option \-taillength to mytail as \-length

        constructor \{args\} \{
            set mytail \[tail %AUTO% \-partof $self\]
            $self configurelist $args
        \}
    \}



## <a name='subsection122'></a>How can I delegate any unrecognized method or option to a component object?

It may happen that a Snit object gets most of its behavior from one of its
components\. This often happens with __snit::widgetadaptors__, for example,
where we wish to slightly the modify the behavior of an existing widget\. To
carry on with our __dog__ example, however, suppose that we have a
__snit::type__ called __animal__ that implements a variety of animal
behaviors\-\-moving, eating, sleeping, and so forth\. We want our __dog__
objects to inherit these same behaviors, while adding dog\-like behaviors of its
own\. Here's how we can give a __dog__ methods and options of its own while
delegating all other methods and options to its __animal__ component:

    snit::type dog \{
        delegate option \* to animal
        delegate method \* to animal

        option \-akc 0

        constructor \{args\} \{
            install animal using animal %AUTO% \-name $self
            $self configurelist $args
        \}


        method wag \{\} \{
            return "$self wags its tail"
        \}
    \}



That's it\. A __dog__ is now an __animal__ that has a __\-akc__ option
and can __wag__ its tail\.

Note that we don't need to specify the full list of method names or option names
that __animal__ will receive\. It gets anything __dog__ doesn't
recognize\-\-and if it doesn't recognize it either, it will simply throw an error,







|
|

|
|

<
<
>
>

|
|
|
<
>

|

|


















|
|

|
|

<
<
>
>













|
|
|

|

|
|

<
|
>
|

<
<
>
>







2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678


2679
2680
2681
2682
2683
2684

2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713


2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737

2738
2739
2740
2741


2742
2743
2744
2745
2746
2747
2748
2749
2750

The first question in this section \(see [DELEGATION](#section16)\) shows one
way to delegate an option to a component; but this pattern occurs often enough
that Snit makes it easy\. For example, every __tail__ object has a
__\-length__ option; we want to allow the creator of a __dog__ object to
set the tail's length\. We can do this:

    % snit::type dog {
        delegate option -length to mytail

        constructor {args} {
            install mytail using tail %AUTO% -partof $self
            $self configurelist $args


        }
    }
    ::dog
    % snit::type tail {
        option -partof
        option -length 5

    }
    ::tail
    % dog spot -length 7
    ::spot
    % spot cget -length
    7

This produces nearly the same result as the __\-configuremethod__ and
__\-cgetmethod__ shown under the first question in this section: whenever a
__dog__ object's __\-length__ option is set or retrieved, the underlying
__tail__ object's option is set or retrieved in turn\.

Note that you can define an option name using the __option__ statement, or
you can define it using __delegate__; you can't do both\.

## <a name='subsection121'></a>Can I delegate to an option with a different name?

In the previous answer we delegated the __dog__'s __\-length__ option
down to its __tail__\. This is, of course, wrong\. The dog has a length, and
the tail has a length, and they are different\. What we'd really like to do is
give the __dog__ a __\-taillength__ option, but delegate it to the
__tail__'s __\-length__ option:

    snit::type dog {
        delegate option -taillength to mytail as -length

        constructor {args} {
            set mytail [tail %AUTO% -partof $self]
            $self configurelist $args


        }
    }

## <a name='subsection122'></a>How can I delegate any unrecognized method or option to a component object?

It may happen that a Snit object gets most of its behavior from one of its
components\. This often happens with __snit::widgetadaptors__, for example,
where we wish to slightly the modify the behavior of an existing widget\. To
carry on with our __dog__ example, however, suppose that we have a
__snit::type__ called __animal__ that implements a variety of animal
behaviors\-\-moving, eating, sleeping, and so forth\. We want our __dog__
objects to inherit these same behaviors, while adding dog\-like behaviors of its
own\. Here's how we can give a __dog__ methods and options of its own while
delegating all other methods and options to its __animal__ component:

    snit::type dog {
        delegate option * to animal
        delegate method * to animal

        option -akc 0

        constructor {args} {
            install animal using animal %AUTO% -name $self
            $self configurelist $args

        }

        method wag {} {
            return "$self wags its tail"


        }
    }

That's it\. A __dog__ is now an __animal__ that has a __\-akc__ option
and can __wag__ its tail\.

Note that we don't need to specify the full list of method names or option names
that __animal__ will receive\. It gets anything __dog__ doesn't
recognize\-\-and if it doesn't recognize it either, it will simply throw an error,
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779


2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794

2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807


2808
2809
2810
2811
2812
2813
2814
2815
2816

2817
2818
2819
2820
2821
2822
2823
what if the __animal__ type has some methods or options that we'd like to
suppress?

One solution is to explicitly delegate all the options and methods, and forgo
the convenience of __delegate method \*__ and __delegate option \*__\. But
if we wish to suppress only a few options or methods, there's an easier way:

    snit::type dog \{
        delegate option \* to animal except \-numlegs
        delegate method \* to animal except \{fly climb\}

        \# \.\.\.

        constructor \{args\} \{
            install animal using animal %AUTO% \-name $self \-numlegs 4
            $self configurelist $args
        \}

        \# \.\.\.
    \}



Dogs have four legs, so we specify that explicitly when we create the
__animal__ component, and explicitly exclude __\-numlegs__ from the set
of delegated options\. Similarly, dogs can neither __fly__ nor __climb__,
so we exclude those __animal__ methods as shown\.

## <a name='subsection124'></a>Can a hierarchical method be delegated?

Yes; just specify multiple words in the delegated method's name:

    snit::type tail \{
        method wag \{\} \{return "Wag, wag"\}
        method droop \{\} \{return "Droop, droop"\}
    \}


    snit::type dog \{
        delegate method \{tail wag\} to mytail
        delegate method \{tail droop\} to mytail

        \# \.\.\.

        constructor \{args\} \{
            install mytail using tail %AUTO%
            $self configurelist $args
        \}

        \# \.\.\.
    \}



Unrecognized hierarchical methods can also be delegated; the following code
delegates all subcommands of the "tail" method to the "mytail" component:

    snit::type dog \{
        delegate method \{tail \*\} to mytail

        \# \.\.\.
    \}


# <a name='section17'></a>WIDGETS

## <a name='subsection125'></a>What is a snit::widget?

A __snit::widget__ is the Snit version of what Tcl programmers usually call
a *megawidget*: a widget\-like object usually consisting of one or more Tk







|
|
|

|

|
|

<
|
|
<
>
>










|
|
|
<
|
>
|
|
|

|

|


<
|
|
<
>
>




|
|

|
<
>







2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775

2776
2777

2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792

2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803

2804
2805

2806
2807
2808
2809
2810
2811
2812
2813
2814
2815

2816
2817
2818
2819
2820
2821
2822
2823
what if the __animal__ type has some methods or options that we'd like to
suppress?

One solution is to explicitly delegate all the options and methods, and forgo
the convenience of __delegate method \*__ and __delegate option \*__\. But
if we wish to suppress only a few options or methods, there's an easier way:

    snit::type dog {
        delegate option * to animal except -numlegs
        delegate method * to animal except {fly climb}

        # ...

        constructor {args} {
            install animal using animal %AUTO% -name $self -numlegs 4
            $self configurelist $args

        }


        # ...
    }

Dogs have four legs, so we specify that explicitly when we create the
__animal__ component, and explicitly exclude __\-numlegs__ from the set
of delegated options\. Similarly, dogs can neither __fly__ nor __climb__,
so we exclude those __animal__ methods as shown\.

## <a name='subsection124'></a>Can a hierarchical method be delegated?

Yes; just specify multiple words in the delegated method's name:

    snit::type tail {
        method wag {} {return "Wag, wag"}
        method droop {} {return "Droop, droop"}

    }

    snit::type dog {
        delegate method {tail wag} to mytail
        delegate method {tail droop} to mytail

        # ...

        constructor {args} {
            install mytail using tail %AUTO%
            $self configurelist $args

        }


        # ...
    }

Unrecognized hierarchical methods can also be delegated; the following code
delegates all subcommands of the "tail" method to the "mytail" component:

    snit::type dog {
        delegate method {tail *} to mytail

        # ...

    }

# <a name='section17'></a>WIDGETS

## <a name='subsection125'></a>What is a snit::widget?

A __snit::widget__ is the Snit version of what Tcl programmers usually call
a *megawidget*: a widget\-like object usually consisting of one or more Tk
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884

2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904

2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932


2933
2934
2935
2936
2937
2938
2939

A __snit::widget__'s hull component will usually be a Tk
__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ widget; however, it may be any
Tk widget that defines the __\-class__ option\. You can explicitly choose the
hull type you prefer by including the __hulltype__ command in the widget
definition:

    snit::widget mytoplevel \{
        hulltype toplevel

        \# \.\.\.
    \}


If no __hulltype__ command appears, the hull will be a
__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__\.

By default, Snit recognizes the following hull types: the Tk widgets
__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__, __labelframe__,
__toplevel__, and the Tile widgets __ttk::frame__,
__ttk::labelframe__, and __ttk::toplevel__\. To enable the use of some
other kind of widget as the hull type, you can __lappend__ the widget
command to the variable __snit::hulltypes__ \(always provided the widget
defines the __\-class__ option\. For example, suppose Tk gets a new widget
type called a __prettyframe__:

    lappend snit::hulltypes prettyframe

    snit::widget mywidget \{
        hulltype prettyframe

        \# \.\.\.
    \}


## <a name='subsection130'></a>How should I name widgets which are components of a snit::widget?

Every widget, whether a genuine Tk widget or a Snit megawidget, has to have a
valid Tk window name\. When a __snit::widget__ is first created, its instance
name, __self__, is a Tk window name; however, if the __snit::widget__ is
used as the hull component by a __snit::widgetadaptor__ its instance name
will be changed to something else\. For this reason, every __snit::widget__
method, constructor, destructor, and so forth is passed another implicit
argument, __win__, which is the window name of the megawidget\. Any children
should be named using __win__ as the root\.

Thus, suppose you're writing a toolbar widget, a frame consisting of a number of
buttons placed side\-by\-side\. It might look something like this:

    snit::widget toolbar \{
        delegate option \* to hull

        constructor \{args\} \{
            button $win\.open \-text Open \-command \[mymethod open\]
            button $win\.save \-text Save \-command \[mymethod save\]

            \# \.\.\.\.

            $self configurelist $args

        \}
    \}



See also the question on renaming objects, toward the top of this file\.

# <a name='section18'></a>WIDGET ADAPTORS

## <a name='subsection131'></a>What is a snit::widgetadaptor?








|


|
<
>















|


|
<
>















|
|

|
|
|

|



<
<
>
>







2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883

2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903

2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930


2931
2932
2933
2934
2935
2936
2937
2938
2939

A __snit::widget__'s hull component will usually be a Tk
__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__ widget; however, it may be any
Tk widget that defines the __\-class__ option\. You can explicitly choose the
hull type you prefer by including the __hulltype__ command in the widget
definition:

    snit::widget mytoplevel {
        hulltype toplevel

        # ...

    }

If no __hulltype__ command appears, the hull will be a
__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__\.

By default, Snit recognizes the following hull types: the Tk widgets
__[frame](\.\./\.\./\.\./\.\./index\.md\#frame)__, __labelframe__,
__toplevel__, and the Tile widgets __ttk::frame__,
__ttk::labelframe__, and __ttk::toplevel__\. To enable the use of some
other kind of widget as the hull type, you can __lappend__ the widget
command to the variable __snit::hulltypes__ \(always provided the widget
defines the __\-class__ option\. For example, suppose Tk gets a new widget
type called a __prettyframe__:

    lappend snit::hulltypes prettyframe

    snit::widget mywidget {
        hulltype prettyframe

        # ...

    }

## <a name='subsection130'></a>How should I name widgets which are components of a snit::widget?

Every widget, whether a genuine Tk widget or a Snit megawidget, has to have a
valid Tk window name\. When a __snit::widget__ is first created, its instance
name, __self__, is a Tk window name; however, if the __snit::widget__ is
used as the hull component by a __snit::widgetadaptor__ its instance name
will be changed to something else\. For this reason, every __snit::widget__
method, constructor, destructor, and so forth is passed another implicit
argument, __win__, which is the window name of the megawidget\. Any children
should be named using __win__ as the root\.

Thus, suppose you're writing a toolbar widget, a frame consisting of a number of
buttons placed side\-by\-side\. It might look something like this:

    snit::widget toolbar {
        delegate option * to hull

        constructor {args} {
            button $win.open -text Open -command [mymethod open]
            button $win.save -text Save -command [mymethod save]

            # ....

            $self configurelist $args



        }
    }

See also the question on renaming objects, toward the top of this file\.

# <a name='section18'></a>WIDGET ADAPTORS

## <a name='subsection131'></a>What is a snit::widgetadaptor?

2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971

2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986

2987
2988
2989
2990
2991
2992
2993
For example, the following code creates a read\-only text widget by the simple
device of turning its __insert__ and __delete__ methods into no\-ops\.
Then, we define new methods, __ins__ and __del__, which get delegated to
the hull component as __insert__ and __delete__\. Thus, we've adapted the
text widget and given it new behavior while still leaving it fundamentally a
text widget\.

    ::snit::widgetadaptor rotext \{

        constructor \{args\} \{
            \# Create the text widget; turn off its insert cursor
            installhull using text \-insertwidth 0

            \# Apply any options passed at creation time\.
            $self configurelist $args
        \}


        \# Disable the text widget's insert and delete methods, to
        \# make this readonly\.
        method insert \{args\} \{\}
        method delete \{args\} \{\}

        \# Enable ins and del as synonyms, so the program can insert and
        \# delete\.
        delegate method ins to hull as insert
        delegate method del to hull as delete

        \# Pass all other methods and options to the real text widget, so
        \# that the remaining behavior is as expected\.
        delegate method \* to hull
        delegate option \* to hull
    \}


The most important part is in the constructor\. Whereas __snit::widget__
creates the hull for you, __snit::widgetadaptor__ cannot \-\- it doesn't know
what kind of widget you want\. So the first thing the constructor does is create
the hull component \(a Tk text widget in this case\), and then installs it using
the __installhull__ command\.








|

|
|
|

|

<
|
>
|
|
|
|

|
|



|
|
|
|
<
>







2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969

2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985

2986
2987
2988
2989
2990
2991
2992
2993
For example, the following code creates a read\-only text widget by the simple
device of turning its __insert__ and __delete__ methods into no\-ops\.
Then, we define new methods, __ins__ and __del__, which get delegated to
the hull component as __insert__ and __delete__\. Thus, we've adapted the
text widget and given it new behavior while still leaving it fundamentally a
text widget\.

    ::snit::widgetadaptor rotext {

        constructor {args} {
            # Create the text widget; turn off its insert cursor
            installhull using text -insertwidth 0

            # Apply any options passed at creation time.
            $self configurelist $args

        }

        # Disable the text widget's insert and delete methods, to
        # make this readonly.
        method insert {args} {}
        method delete {args} {}

        # Enable ins and del as synonyms, so the program can insert and
        # delete.
        delegate method ins to hull as insert
        delegate method del to hull as delete

        # Pass all other methods and options to the real text widget, so
        # that the remaining behavior is as expected.
        delegate method * to hull
        delegate option * to hull

    }

The most important part is in the constructor\. Whereas __snit::widget__
creates the hull for you, __snit::widgetadaptor__ cannot \-\- it doesn't know
what kind of widget you want\. So the first thing the constructor does is create
the hull component \(a Tk text widget in this case\), and then installs it using
the __installhull__ command\.

3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022


3023
3024
3025
3026
3027
3028
3029
__PagesManager__ itself, using its __add__ method\. It's convenient to
adapt these frames to do what we'd like them to do\.

In a case like this, the Tk widget will already exist when the
__snit::widgetadaptor__ is created\. Snit provides an alternate form of the
__installhull__ command for this purpose:

    snit::widgetadaptor pageadaptor \{
        constructor \{args\} \{
            \# The widget already exists; just install it\.
            installhull $win

            \# \.\.\.
        \}
    \}



## <a name='subsection134'></a>Can I adapt another megawidget?

Maybe\. If the other megawidget is a __snit::widget__ or
__snit::widgetadaptor__, then yes\. If it isn't then, again, maybe\. You'll
have to try it and see\. You're most likely to have trouble with widget
destruction\-\-you have to make sure that your megawidget code receives the







|
|
|


|
<
<
>
>







3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020


3021
3022
3023
3024
3025
3026
3027
3028
3029
__PagesManager__ itself, using its __add__ method\. It's convenient to
adapt these frames to do what we'd like them to do\.

In a case like this, the Tk widget will already exist when the
__snit::widgetadaptor__ is created\. Snit provides an alternate form of the
__installhull__ command for this purpose:

    snit::widgetadaptor pageadaptor {
        constructor {args} {
            # The widget already exists; just install it.
            installhull $win

            # ...


        }
    }

## <a name='subsection134'></a>Can I adapt another megawidget?

Maybe\. If the other megawidget is a __snit::widget__ or
__snit::widgetadaptor__, then yes\. If it isn't then, again, maybe\. You'll
have to try it and see\. You're most likely to have trouble with widget
destruction\-\-you have to make sure that your megawidget code receives the
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107

3108
3109
3110
3111
3112
3113
3114
widget command name with an initial capital\. For example, the widget class of
the Tk __button__ widget is __Button__\.

Similarly, the widget class of a __snit::widget__ defaults to the
unqualified type name with the first letter capitalized\. For example, the widget
class of

    snit::widget ::mylibrary::scrolledText \{ \.\.\. \}

is __ScrolledText__\.

The widget class can also be set explicitly using the __widgetclass__
statement within the __snit::widget__ definition:

    snit::widget ::mylibrary::scrolledText \{
        widgetclass Text

        \# \.\.\.
    \}


The above definition says that a __scrolledText__ megawidget has the same
widget class as an ordinary __[text](\.\./\.\./\.\./\.\./index\.md\#text)__
widget\. This might or might not be a good idea, depending on how the rest of the
megawidget is defined, and how its options are delegated\.

## <a name='subsection138'></a>What is my snit::widgetadaptor's widget class?







|






|


|
<
>







3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106

3107
3108
3109
3110
3111
3112
3113
3114
widget command name with an initial capital\. For example, the widget class of
the Tk __button__ widget is __Button__\.

Similarly, the widget class of a __snit::widget__ defaults to the
unqualified type name with the first letter capitalized\. For example, the widget
class of

    snit::widget ::mylibrary::scrolledText { ... }

is __ScrolledText__\.

The widget class can also be set explicitly using the __widgetclass__
statement within the __snit::widget__ definition:

    snit::widget ::mylibrary::scrolledText {
        widgetclass Text

        # ...

    }

The above definition says that a __scrolledText__ megawidget has the same
widget class as an ordinary __[text](\.\./\.\./\.\./\.\./index\.md\#text)__
widget\. This might or might not be a good idea, depending on how the rest of the
megawidget is defined, and how its options are delegated\.

## <a name='subsection138'></a>What is my snit::widgetadaptor's widget class?
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165


3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193


3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212

3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233

3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263

3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
The resource and class names are used to initialize option default values by
querying the option database\. The resource name is usually just the option name
minus the hyphen, but may contain uppercase letters at word boundaries; the
class name is usually just the resource name with an initial capital, but not
always\. For example, here are the option, resource, and class names for several
Tk __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget options:

    \-background         background         Background
    \-borderwidth        borderWidth        BorderWidth
    \-insertborderwidth  insertBorderWidth  BorderWidth
    \-padx               padX               Pad

As is easily seen, sometimes the resource and class names can be inferred from
the option name, but not always\.

## <a name='subsection140'></a>What are the resource and class names for my megawidget's options?

For options implicitly delegated to a component using __delegate option \*__,
the resource and class names will be exactly those defined by the component\. The
__configure__ method returns these names, along with the option's default
and current values:

    % snit::widget mytext \{
        delegate option \* to text

        constructor \{args\} \{
            install text using text \.text
            \# \.\.\.
        \}

        \# \.\.\.
    \}


    ::mytext
    % mytext \.text
    \.text
    % \.text configure \-padx
    \-padx padX Pad 1 1
    %

For all other options \(whether locally defined or explicitly delegated\), the
resource and class names can be defined explicitly, or they can be allowed to
have default values\.

By default, the resource name is just the option name minus the hyphen; the the
class name is just the option name with an initial capital letter\. For example,
suppose we explicitly delegate "\-padx":

    % snit::widget mytext \{
        option \-myvalue 5

        delegate option \-padx to text
        delegate option \* to text

        constructor \{args\} \{
            install text using text \.text
            \# \.\.\.
        \}

        \# \.\.\.
    \}


    ::mytext
    % mytext \.text
    \.text
    % \.text configure \-myvalue
    \-myvalue myvalue Myvalue 5 5
    % \.text configure \-padx
    \-padx padx Padx 1 1
    %

Here the resource and class names are chosen using the default rules\. Often
these rules are sufficient, but in the case of "\-padx" we'd most likely prefer
that the option's resource and class names are the same as for the built\-in Tk
widgets\. This is easily done:

    % snit::widget mytext \{
        delegate option \{\-padx padX Pad\} to text

        \# \.\.\.
    \}

    ::mytext
    % mytext \.text
    \.text
    % \.text configure \-padx
    \-padx padX Pad 1 1
    %

## <a name='subsection141'></a>How does Snit initialize my megawidget's locally\-defined options?

The option database is queried for each of the megawidget's locally\-defined
options, using the option's resource and class name\. If the result isn't "",
then it replaces the default value given in widget definition\. In either case,
the default can be overridden by the caller\. For example,

    option add \*Mywidget\.texture pebbled

    snit::widget mywidget \{
        option \-texture smooth
        \# \.\.\.
    \}


    mywidget \.mywidget \-texture greasy

Here, __\-texture__ would normally default to "smooth", but because of the
entry added to the option database it defaults to "pebbled"\. However, the caller
has explicitly overridden the default, and so the new widget will be "greasy"\.

## <a name='subsection142'></a>How does Snit initialize delegated options?

That depends on whether the options are delegated to the hull, or to some other
component\.

## <a name='subsection143'></a>How does Snit initialize options delegated to the hull?

A __snit::widget__'s hull is a widget, and given that its class has been set
it is expected to query the option database for itself\. The only exception
concerns options that are delegated to it with a different name\. Consider the
following code:

    option add \*Mywidget\.borderWidth 5
    option add \*Mywidget\.relief sunken
    option add \*Mywidget\.hullbackground red
    option add \*Mywidget\.background green

    snit::widget mywidget \{
        delegate option \-borderwidth to hull
        delegate option \-hullbackground to hull as \-background
        delegate option \* to hull
        \# \.\.\.
    \}


    mywidget \.mywidget

    set A \[\.mywidget cget \-relief\]
    set B \[\.mywidget cget \-hullbackground\]
    set C \[\.mywidget cget \-background\]
    set D \[\.mywidget cget \-borderwidth\]

The question is, what are the values of variables A, B, C and D?

The value of A is "sunken"\. The hull is a Tk frame which has been given the
widget class __Mywidget__; it will automatically query the option database
and pick up this value\. Since the __\-relief__ option is implicitly delegated
to the hull, Snit takes no action\.







|
|
|
|











|
|

|
|
|
<
|
|
<
>
>

|
|
|
|










|
|

|
|

|
|
|
<
|
|
<
>
>

|
|
|
|
|
|







|
|

|
<
>

|
|
|
|









|

|
|
|
<
|
>
|

















|
|
|
|

|
|
|
|
|
<
|
>
|

|
|
|
|







3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161

3162
3163

3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189

3190
3191

3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211

3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231

3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261

3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
The resource and class names are used to initialize option default values by
querying the option database\. The resource name is usually just the option name
minus the hyphen, but may contain uppercase letters at word boundaries; the
class name is usually just the resource name with an initial capital, but not
always\. For example, here are the option, resource, and class names for several
Tk __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget options:

    -background         background         Background
    -borderwidth        borderWidth        BorderWidth
    -insertborderwidth  insertBorderWidth  BorderWidth
    -padx               padX               Pad

As is easily seen, sometimes the resource and class names can be inferred from
the option name, but not always\.

## <a name='subsection140'></a>What are the resource and class names for my megawidget's options?

For options implicitly delegated to a component using __delegate option \*__,
the resource and class names will be exactly those defined by the component\. The
__configure__ method returns these names, along with the option's default
and current values:

    % snit::widget mytext {
        delegate option * to text

        constructor {args} {
            install text using text .text
            # ...

        }


        # ...
    }
    ::mytext
    % mytext .text
    .text
    % .text configure -padx
    -padx padX Pad 1 1
    %

For all other options \(whether locally defined or explicitly delegated\), the
resource and class names can be defined explicitly, or they can be allowed to
have default values\.

By default, the resource name is just the option name minus the hyphen; the the
class name is just the option name with an initial capital letter\. For example,
suppose we explicitly delegate "\-padx":

    % snit::widget mytext {
        option -myvalue 5

        delegate option -padx to text
        delegate option * to text

        constructor {args} {
            install text using text .text
            # ...

        }


        # ...
    }
    ::mytext
    % mytext .text
    .text
    % .text configure -myvalue
    -myvalue myvalue Myvalue 5 5
    % .text configure -padx
    -padx padx Padx 1 1
    %

Here the resource and class names are chosen using the default rules\. Often
these rules are sufficient, but in the case of "\-padx" we'd most likely prefer
that the option's resource and class names are the same as for the built\-in Tk
widgets\. This is easily done:

    % snit::widget mytext {
        delegate option {-padx padX Pad} to text

        # ...

    }
    ::mytext
    % mytext .text
    .text
    % .text configure -padx
    -padx padX Pad 1 1
    %

## <a name='subsection141'></a>How does Snit initialize my megawidget's locally\-defined options?

The option database is queried for each of the megawidget's locally\-defined
options, using the option's resource and class name\. If the result isn't "",
then it replaces the default value given in widget definition\. In either case,
the default can be overridden by the caller\. For example,

    option add *Mywidget.texture pebbled

    snit::widget mywidget {
        option -texture smooth
        # ...

    }

    mywidget .mywidget -texture greasy

Here, __\-texture__ would normally default to "smooth", but because of the
entry added to the option database it defaults to "pebbled"\. However, the caller
has explicitly overridden the default, and so the new widget will be "greasy"\.

## <a name='subsection142'></a>How does Snit initialize delegated options?

That depends on whether the options are delegated to the hull, or to some other
component\.

## <a name='subsection143'></a>How does Snit initialize options delegated to the hull?

A __snit::widget__'s hull is a widget, and given that its class has been set
it is expected to query the option database for itself\. The only exception
concerns options that are delegated to it with a different name\. Consider the
following code:

    option add *Mywidget.borderWidth 5
    option add *Mywidget.relief sunken
    option add *Mywidget.hullbackground red
    option add *Mywidget.background green

    snit::widget mywidget {
        delegate option -borderwidth to hull
        delegate option -hullbackground to hull as -background
        delegate option * to hull
        # ...

    }

    mywidget .mywidget

    set A [.mywidget cget -relief]
    set B [.mywidget cget -hullbackground]
    set C [.mywidget cget -background]
    set D [.mywidget cget -borderwidth]

The question is, what are the values of variables A, B, C and D?

The value of A is "sunken"\. The hull is a Tk frame which has been given the
widget class __Mywidget__; it will automatically query the option database
and pick up this value\. Since the __\-relief__ option is implicitly delegated
to the hull, Snit takes no action\.
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313

3314
3315

3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
in accordance with the standard Tk naming for this option\. As with
__\-relief__, the hull picks up its own __\-borderwidth__ option before
Snit does anything\. Because the option is delegated under its own name, Snit
assumes that the correct thing has happened, and doesn't worry about it any
further\. To avoid confusion, the __\-borderwidth__ option should have been
delegated like this:

    delegate option \{\-borderwidth borderWidth BorderWidth\} to hull

For __snit::widgetadaptor__s, the case is somewhat altered\. Widget adaptors
retain the widget class of their hull, and the hull is not created automatically
by Snit\. Instead, the __snit::widgetadaptor__ must call __installhull__
in its constructor\. The normal way to do this is as follows:

    snit::widgetadaptor mywidget \{
        \# \.\.\.
        constructor \{args\} \{
            \# \.\.\.
            installhull using text \-foreground white
            \# \.\.\.
        \}

        \# \.\.\.
    \}


In this case, the __installhull__ command will create the hull using a
command like this:

    set hull \[text $win \-foreground white\]

The hull is a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget, so its
widget class is __Text__\. Just as with __snit::widget__ hulls, Snit
assumes that it will pick up all of its normal option values automatically,
without help from Snit\. Options delegated from a different name are initialized
from the option database in the same way as described above\.

In earlier versions of Snit, __snit::widgetadaptor__s were expected to call
__installhull__ like this:

    installhull \[text $win \-foreground white\]

This form still works\-\-but Snit will not query the option database as described
above\.

## <a name='subsection144'></a>How does Snit initialize options delegated to other components?

For hull components, Snit assumes that Tk will do most of the work







|






|
|
|
|
|
|
<
>
|
<
>




|










|







3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312

3313
3314

3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
in accordance with the standard Tk naming for this option\. As with
__\-relief__, the hull picks up its own __\-borderwidth__ option before
Snit does anything\. Because the option is delegated under its own name, Snit
assumes that the correct thing has happened, and doesn't worry about it any
further\. To avoid confusion, the __\-borderwidth__ option should have been
delegated like this:

    delegate option {-borderwidth borderWidth BorderWidth} to hull

For __snit::widgetadaptor__s, the case is somewhat altered\. Widget adaptors
retain the widget class of their hull, and the hull is not created automatically
by Snit\. Instead, the __snit::widgetadaptor__ must call __installhull__
in its constructor\. The normal way to do this is as follows:

    snit::widgetadaptor mywidget {
        # ...
        constructor {args} {
            # ...
            installhull using text -foreground white
            # ...

        }
        # ...

    }

In this case, the __installhull__ command will create the hull using a
command like this:

    set hull [text $win -foreground white]

The hull is a __[text](\.\./\.\./\.\./\.\./index\.md\#text)__ widget, so its
widget class is __Text__\. Just as with __snit::widget__ hulls, Snit
assumes that it will pick up all of its normal option values automatically,
without help from Snit\. Options delegated from a different name are initialized
from the option database in the same way as described above\.

In earlier versions of Snit, __snit::widgetadaptor__s were expected to call
__installhull__ like this:

    installhull [text $win -foreground white]

This form still works\-\-but Snit will not query the option database as described
above\.

## <a name='subsection144'></a>How does Snit initialize options delegated to other components?

For hull components, Snit assumes that Tk will do most of the work
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362


3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373


3374
3375
3376
3377
3378
3379
3380
component, and the component is initialized accordingly\-\-provided that the
__install__ command is used to create it\.

Before option database support was added to Snit, the usual way to create a
component was to simply create it in the constructor and assign its command name
to the component variable:

    snit::widget mywidget \{
        delegate option \-background to myComp

        constructor \{args\} \{
            set myComp \[text $win\.text \-foreground black\]
        \}
    \}



The drawback of this method is that Snit has no opportunity to initialize the
component properly\. Hence, the following approach is now used:

    snit::widget mywidget \{
        delegate option \-background to myComp

        constructor \{args\} \{
            install myComp using text $win\.text \-foreground black
        \}
    \}



The __install__ command does the following:

  - Builds a list of the options explicitly included in the __install__
    command\-\-in this case, __\-foreground__\.

  - Queries the option database for all options delegated explicitly to the







|
|

|
|
<
<
>
>




|
|

|
|
<
<
>
>







3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360


3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371


3372
3373
3374
3375
3376
3377
3378
3379
3380
component, and the component is initialized accordingly\-\-provided that the
__install__ command is used to create it\.

Before option database support was added to Snit, the usual way to create a
component was to simply create it in the constructor and assign its command name
to the component variable:

    snit::widget mywidget {
        delegate option -background to myComp

        constructor {args} {
            set myComp [text $win.text -foreground black]


        }
    }

The drawback of this method is that Snit has no opportunity to initialize the
component properly\. Hence, the following approach is now used:

    snit::widget mywidget {
        delegate option -background to myComp

        constructor {args} {
            install myComp using text $win.text -foreground black


        }
    }

The __install__ command does the following:

  - Builds a list of the options explicitly included in the __install__
    command\-\-in this case, __\-foreground__\.

  - Queries the option database for all options delegated explicitly to the
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442


3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468


3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492


3493
3494
3495
3496
3497
3498
3499
your ensemble command\. Then, create an instance of the type with the desired
name\.

For example, the following code uses [DELEGATION](#section16) to create a
work\-alike for the standard __[string](\.\./\.\./\.\./\.\./index\.md\#string)__
command:

    snit::type ::mynamespace::mystringtype \{
        delegate method \* to stringhandler

        constructor \{\} \{
            set stringhandler string
        \}
    \}



    ::mynamespace::mystringtype mystring

We create the type in a namespace, so that the type command is hidden; then we
create a single instance with the desired name\-\- __mystring__, in this case\.

This method has two drawbacks\. First, it leaves the type command floating about\.
More seriously, your shiny new ensemble command will have __info__ and
__destroy__ subcommands that you probably have no use for\. But read on\.

## <a name='subsection149'></a>How can I create an ensemble command using a snit::type?

Define a type whose [TYPE METHODS](#section9) are the subcommands of your
ensemble command\.

For example, the following code uses [DELEGATION](#section16) to create a
work\-alike for the standard __[string](\.\./\.\./\.\./\.\./index\.md\#string)__
command:

    snit::type mystring \{
        delegate typemethod \* to stringhandler

        typeconstructor \{
            set stringhandler string
        \}
    \}



Now the type command itself is your ensemble command\.

This method has only one drawback, and though it's major, it's also
surmountable\. Your new ensemble command will have __create__, __info__
and __destroy__ subcommands you don't want\. And worse yet, since the
__create__ method can be implicit, users of your command will accidentally
be creating instances of your __mystring__ type if they should mispell one
of the subcommands\. The command will succeed\-\-the first time\-\-but won't do
what's wanted\. This is very bad\.

The work around is to set some [PRAGMAS](#section21), as shown here:

    snit::type mystring \{
        pragma \-hastypeinfo    no
        pragma \-hastypedestroy no
        pragma \-hasinstances   no

        delegate typemethod \* to stringhandler

        typeconstructor \{
            set stringhandler string
        \}
    \}



Here we've used the __pragma__ statement to tell Snit that we don't want the
__info__ typemethod or the __destroy__ typemethod, and that our type has
no instances; this eliminates the __create__ typemethod and all related
code\. As a result, our ensemble command will be well\-behaved, with no unexpected
subcommands\.








|
|

|

<
<
>
>



















|
|

|

<
<
>
>













|
|
|
|

|

|

<
<
>
>







3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440


3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466


3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490


3491
3492
3493
3494
3495
3496
3497
3498
3499
your ensemble command\. Then, create an instance of the type with the desired
name\.

For example, the following code uses [DELEGATION](#section16) to create a
work\-alike for the standard __[string](\.\./\.\./\.\./\.\./index\.md\#string)__
command:

    snit::type ::mynamespace::mystringtype {
        delegate method * to stringhandler

        constructor {} {
            set stringhandler string


        }
    }

    ::mynamespace::mystringtype mystring

We create the type in a namespace, so that the type command is hidden; then we
create a single instance with the desired name\-\- __mystring__, in this case\.

This method has two drawbacks\. First, it leaves the type command floating about\.
More seriously, your shiny new ensemble command will have __info__ and
__destroy__ subcommands that you probably have no use for\. But read on\.

## <a name='subsection149'></a>How can I create an ensemble command using a snit::type?

Define a type whose [TYPE METHODS](#section9) are the subcommands of your
ensemble command\.

For example, the following code uses [DELEGATION](#section16) to create a
work\-alike for the standard __[string](\.\./\.\./\.\./\.\./index\.md\#string)__
command:

    snit::type mystring {
        delegate typemethod * to stringhandler

        typeconstructor {
            set stringhandler string


        }
    }

Now the type command itself is your ensemble command\.

This method has only one drawback, and though it's major, it's also
surmountable\. Your new ensemble command will have __create__, __info__
and __destroy__ subcommands you don't want\. And worse yet, since the
__create__ method can be implicit, users of your command will accidentally
be creating instances of your __mystring__ type if they should mispell one
of the subcommands\. The command will succeed\-\-the first time\-\-but won't do
what's wanted\. This is very bad\.

The work around is to set some [PRAGMAS](#section21), as shown here:

    snit::type mystring {
        pragma -hastypeinfo    no
        pragma -hastypedestroy no
        pragma -hasinstances   no

        delegate typemethod * to stringhandler

        typeconstructor {
            set stringhandler string


        }
    }

Here we've used the __pragma__ statement to tell Snit that we don't want the
__info__ typemethod or the __destroy__ typemethod, and that our type has
no instances; this eliminates the __create__ typemethod and all related
code\. As a result, our ensemble command will be well\-behaved, with no unexpected
subcommands\.

3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519

3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530

3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541

3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564

3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592

3593
3594
3595
3596
3597
3598
3599
Use the __pragma__ statement\. Each pragma is an option with a value; each
time you use the __pragma__ statement you can set one or more of them\.

## <a name='subsection152'></a>How can I get rid of the "info" type method?

Set the __\-hastypeinfo__ pragma to __no__:

    snit::type dog \{
        pragma \-hastypeinfo no
        \# \.\.\.
    \}


Snit will refrain from defining the __info__ type method\.

## <a name='subsection153'></a>How can I get rid of the "destroy" type method?

Set the __\-hastypedestroy__ pragma to __no__:

    snit::type dog \{
        pragma \-hastypedestroy no
        \# \.\.\.
    \}


Snit will refrain from defining the __destroy__ type method\.

## <a name='subsection154'></a>How can I get rid of the "create" type method?

Set the __\-hasinstances__ pragma to __no__:

    snit::type dog \{
        pragma \-hasinstances no
        \# \.\.\.
    \}


Snit will refrain from defining the __create__ type method; if you call the
type command with an unknown method name, you'll get an error instead of a new
instance of the type\.

This is useful if you wish to use a __snit::type__ to define an ensemble
command rather than a type with instances\.

Pragmas __\-hastypemethods__ and __\-hasinstances__ cannot both be false
\(or there'd be nothing left\)\.

## <a name='subsection155'></a>How can I get rid of type methods altogether?

Normal Tk widget type commands don't have subcommands; all they do is create
widgets\-\-in Snit terms, the type command calls the __create__ type method
directly\. To get the same behavior from Snit, set the __\-hastypemethods__
pragma to __no__:

    snit::type dog \{
        pragma \-hastypemethods no
        \#\.\.\.
    \}


    \# Creates ::spot
    dog spot

    \# Tries to create an instance called ::create
    dog create spot

Pragmas __\-hastypemethods__ and __\-hasinstances__ cannot both be false
\(or there'd be nothing left\)\.

## <a name='subsection156'></a>Why can't I create an object that replaces an old object with the same name?

Up until Snit 0\.95, you could use any name for an instance of a
__snit::type__, even if the name was already in use by some other object or
command\. You could do the following, for example:

    snit::type dog \{ \.\.\. \}

    dog proc

You now have a new dog named "proc", which is probably not something that you
really wanted to do\. As a result, Snit now throws an error if your chosen
instance name names an existing command\. To restore the old behavior, set the
__\-canreplace__ pragma to __yes__:

    snit::type dog \{
        pragma \-canreplace yes
        \# \.\.\.
    \}


## <a name='subsection157'></a>How can I make my simple type run faster?

In Snit 1\.x, you can set the __\-simpledispatch__ pragma to __yes__\.

Snit 1\.x method dispatch is both flexible and fast, but the flexibility comes
with a price\. If your type doesn't require the flexibility, the







|
|
|
<
>







|
|
|
<
>







|
|
|
<
>


















|
|
|
<
|
>
|


|











|








|
|
|
<
>







3509
3510
3511
3512
3513
3514
3515
3516
3517
3518

3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529

3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540

3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562

3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591

3592
3593
3594
3595
3596
3597
3598
3599
Use the __pragma__ statement\. Each pragma is an option with a value; each
time you use the __pragma__ statement you can set one or more of them\.

## <a name='subsection152'></a>How can I get rid of the "info" type method?

Set the __\-hastypeinfo__ pragma to __no__:

    snit::type dog {
        pragma -hastypeinfo no
        # ...

    }

Snit will refrain from defining the __info__ type method\.

## <a name='subsection153'></a>How can I get rid of the "destroy" type method?

Set the __\-hastypedestroy__ pragma to __no__:

    snit::type dog {
        pragma -hastypedestroy no
        # ...

    }

Snit will refrain from defining the __destroy__ type method\.

## <a name='subsection154'></a>How can I get rid of the "create" type method?

Set the __\-hasinstances__ pragma to __no__:

    snit::type dog {
        pragma -hasinstances no
        # ...

    }

Snit will refrain from defining the __create__ type method; if you call the
type command with an unknown method name, you'll get an error instead of a new
instance of the type\.

This is useful if you wish to use a __snit::type__ to define an ensemble
command rather than a type with instances\.

Pragmas __\-hastypemethods__ and __\-hasinstances__ cannot both be false
\(or there'd be nothing left\)\.

## <a name='subsection155'></a>How can I get rid of type methods altogether?

Normal Tk widget type commands don't have subcommands; all they do is create
widgets\-\-in Snit terms, the type command calls the __create__ type method
directly\. To get the same behavior from Snit, set the __\-hastypemethods__
pragma to __no__:

    snit::type dog {
        pragma -hastypemethods no
        #...

    }

    # Creates ::spot
    dog spot

    # Tries to create an instance called ::create
    dog create spot

Pragmas __\-hastypemethods__ and __\-hasinstances__ cannot both be false
\(or there'd be nothing left\)\.

## <a name='subsection156'></a>Why can't I create an object that replaces an old object with the same name?

Up until Snit 0\.95, you could use any name for an instance of a
__snit::type__, even if the name was already in use by some other object or
command\. You could do the following, for example:

    snit::type dog { ... }

    dog proc

You now have a new dog named "proc", which is probably not something that you
really wanted to do\. As a result, Snit now throws an error if your chosen
instance name names an existing command\. To restore the old behavior, set the
__\-canreplace__ pragma to __yes__:

    snit::type dog {
        pragma -canreplace yes
        # ...

    }

## <a name='subsection157'></a>How can I make my simple type run faster?

In Snit 1\.x, you can set the __\-simpledispatch__ pragma to __yes__\.

Snit 1\.x method dispatch is both flexible and fast, but the flexibility comes
with a price\. If your type doesn't require the flexibility, the
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642

3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656


3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672


3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685

3686
3687
3688

3689
3690
3691
3692
3693
3694
3695
3696
3697

3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723

3724
3725
3726
3727
3728
3729
3730
one set of methods in the first case, and another set in the second case\. But
how can your type definition know whether the fast C extension is available or
not?

It's easily done\. Outside of any type definition, define a macro that returns 1
if the extension is available, and 0 otherwise:

    if \{$gotFastExtension\} \{
        snit::macro fastcode \{\} \{return 1\}
    \} else \{
        snit::macro fastcode \{\} \{return 0\}
    \}


Then, use your macro in your type definition:

    snit::type dog \{

        if \{\[fastcode\]\} \{
            \# Fast methods
            method bark \{\} \{\.\.\.\}
            method wagtail \{\} \{\.\.\.\}
        \} else \{
            \# Slow methods
            method bark \{\} \{\.\.\.\}
            method wagtail \{\} \{\.\.\.\}
        \}
    \}



## <a name='subsection161'></a>How do I define new type definition syntax?

Use a macro\. For example, your __snit::widget__'s __\-background__ option
should be propagated to a number of component widgets\. You could implement that
like this:

    snit::widget mywidget \{
        option \-background \-default white \-configuremethod PropagateBackground

        method PropagateBackground \{option value\} \{
            $comp1 configure $option $value
            $comp2 configure $option $value
            $comp3 configure $option $value
        \}
    \}



For one option, this is fine; if you've got a number of options, it becomes
tedious and error prone\. So package it as a macro:

    snit::macro propagate \{option "to" components\} \{
        option $option \-configuremethod Propagate$option

        set body "\\n"

        foreach comp $components \{
            append body "\\$$comp configure $option \\$value\\n"
        \}


        method Propagate$option \{option value\} $body
    \}


Then you can use it like this:

    snit::widget mywidget \{
        option \-background default \-white
        option \-foreground default \-black

        propagate \-background to \{comp1 comp2 comp3\}
        propagate \-foreground to \{comp1 comp2 comp3\}
    \}


## <a name='subsection162'></a>Are there are restrictions on macro names?

Yes, there are\. You can't redefine any standard Tcl commands or Snit type
definition statements\. You can use any other command name, including the name of
a previously defined macro\.

If you're using Snit macros in your application, go ahead and name them in the
global namespace, as shown above\. But if you're using them to define types or
widgets for use by others, you should define your macros in the same namespace
as your types or widgets\. That way, they won't conflict with other people's
macros\.

If my fancy __snit::widget__ is called __::mylib::mywidget__, for
example, then I should define my __propagate__ macro as
__::mylib::propagate__:

    snit::macro mylib::propagate \{option "to" components\} \{ \.\.\. \}

    snit::widget ::mylib::mywidget \{
        option \-background default \-white
        option \-foreground default \-black

        mylib::propagate \-background to \{comp1 comp2 comp3\}
        mylib::propagate \-foreground to \{comp1 comp2 comp3\}
    \}


# <a name='section23'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *snit* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
<
|
>


|

|
|
|
|
|
|
|
|
<
<
>
>







|
|

|



<
<
>
>




|
|

|

|
|
<
|
>
|
<
|
>


|
|
|

|
|
<
>

















|

|
|
|

|
|
<
>







3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640

3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654


3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670


3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683

3684
3685
3686

3687
3688
3689
3690
3691
3692
3693
3694
3695
3696

3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722

3723
3724
3725
3726
3727
3728
3729
3730
one set of methods in the first case, and another set in the second case\. But
how can your type definition know whether the fast C extension is available or
not?

It's easily done\. Outside of any type definition, define a macro that returns 1
if the extension is available, and 0 otherwise:

    if {$gotFastExtension} {
        snit::macro fastcode {} {return 1}
    } else {
        snit::macro fastcode {} {return 0}

    }

Then, use your macro in your type definition:

    snit::type dog {

        if {[fastcode]} {
            # Fast methods
            method bark {} {...}
            method wagtail {} {...}
        } else {
            # Slow methods
            method bark {} {...}
            method wagtail {} {...}


        }
    }

## <a name='subsection161'></a>How do I define new type definition syntax?

Use a macro\. For example, your __snit::widget__'s __\-background__ option
should be propagated to a number of component widgets\. You could implement that
like this:

    snit::widget mywidget {
        option -background -default white -configuremethod PropagateBackground

        method PropagateBackground {option value} {
            $comp1 configure $option $value
            $comp2 configure $option $value
            $comp3 configure $option $value


        }
    }

For one option, this is fine; if you've got a number of options, it becomes
tedious and error prone\. So package it as a macro:

    snit::macro propagate {option "to" components} {
        option $option -configuremethod Propagate$option

        set body "\n"

        foreach comp $components {
            append body "\$$comp configure $option \$value\n"

        }

        method Propagate$option {option value} $body

    }

Then you can use it like this:

    snit::widget mywidget {
        option -background default -white
        option -foreground default -black

        propagate -background to {comp1 comp2 comp3}
        propagate -foreground to {comp1 comp2 comp3}

    }

## <a name='subsection162'></a>Are there are restrictions on macro names?

Yes, there are\. You can't redefine any standard Tcl commands or Snit type
definition statements\. You can use any other command name, including the name of
a previously defined macro\.

If you're using Snit macros in your application, go ahead and name them in the
global namespace, as shown above\. But if you're using them to define types or
widgets for use by others, you should define your macros in the same namespace
as your types or widgets\. That way, they won't conflict with other people's
macros\.

If my fancy __snit::widget__ is called __::mylib::mywidget__, for
example, then I should define my __propagate__ macro as
__::mylib::propagate__:

    snit::macro mylib::propagate {option "to" components} { ... }

    snit::widget ::mylib::mywidget {
        option -background default -white
        option -foreground default -black

        mylib::propagate -background to {comp1 comp2 comp3}
        mylib::propagate -foreground to {comp1 comp2 comp3}

    }

# <a name='section23'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *snit* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/stooop/stooop.md.
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

      * __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *name* \{__this__ ?*arg arg \.\.\.*?\} *body*

        This is a member procedure of the class, as its first argument is named
        __this__\. It allows a simple access of member data for the object
        referenced by __this__ inside the procedure\. For example:

            set \($this,data\) 0

      * __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *name* \{?*arg arg \.\.\.*?\} *body*

        This is a static \(as in C\+\+\) member procedure of the class, as its first
        argument is not named __this__\. Static \(global\) class data can be
        accessed as in:

            set \(data\) 0

      * __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *class* \{__this copy__\} *body*

        This is the optional copy procedure for the class\. It must have the same
        name as the class and exactly 2 arguments named __this__ and
        __copy__\. It is invoked following a __new__ invocation on an
        existing object of the class\.







|







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

      * __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *name* \{__this__ ?*arg arg \.\.\.*?\} *body*

        This is a member procedure of the class, as its first argument is named
        __this__\. It allows a simple access of member data for the object
        referenced by __this__ inside the procedure\. For example:

            set ($this,data) 0

      * __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *name* \{?*arg arg \.\.\.*?\} *body*

        This is a static \(as in C\+\+\) member procedure of the class, as its first
        argument is not named __this__\. Static \(global\) class data can be
        accessed as in:

            set (data) 0

      * __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ *class* \{__this copy__\} *body*

        This is the optional copy procedure for the class\. It must have the same
        name as the class and exactly 2 arguments named __this__ and
        __copy__\. It is invoked following a __new__ invocation on an
        existing object of the class\.
Changes to embedded/md/tcllib/files/modules/stooop/switched.md.
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

The __switched__ class serves as base class for user classes with switch /
option configuration procedures\. It provides facilities for managing options
through a simple interface\.

For example:

    set vehicle \[new car \-length 4\.5 \-width 2 \-power 100 \-fuel diesel\]
    puts "my car was running on \[switched::cget $vehicle \-fuel\]"
    switched::configure $vehicle \-power 40 \-fuel electricity
    puts "but is now running on clean \[switched::cget $vehicle \-fuel\]"

Of course, as you might have guessed, the __car__ class is derived from the
__switched__ class\. Let us see how it works:

    class car \{
        proc car \{this args\} switched \{$args\} \{
            \# car specific initialization code here
            switched::complete $this
        \}

        \.\.\.
    \}


The switched class constructor takes the optional configuration option / value
pairs as parameters\. The switched class layer then completely manages the
switched options: it checks their validity, stores their values and provides a
clean interface to the user layer configuration setting procedures\.

The switched class members available to the programmer are:







|
|
|
|




|
|
|

<
>
|
<
>







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

The __switched__ class serves as base class for user classes with switch /
option configuration procedures\. It provides facilities for managing options
through a simple interface\.

For example:

    set vehicle [new car -length 4.5 -width 2 -power 100 -fuel diesel]
    puts "my car was running on [switched::cget $vehicle -fuel]"
    switched::configure $vehicle -power 40 -fuel electricity
    puts "but is now running on clean [switched::cget $vehicle -fuel]"

Of course, as you might have guessed, the __car__ class is derived from the
__switched__ class\. Let us see how it works:

    class car {
        proc car {this args} switched {$args} {
            # car specific initialization code here
            switched::complete $this

        }
        ...

    }

The switched class constructor takes the optional configuration option / value
pairs as parameters\. The switched class layer then completely manages the
switched options: it checks their validity, stores their values and provides a
clean interface to the user layer configuration setting procedures\.

The switched class members available to the programmer are:
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98

99
100

101
102
103
104
105
106
107
    This procedure must return the configuration description for *all* options
    that the switched object will accept\. It is a pure virtual member procedure
    and therefore its implementation is *mandatory* in the derived class
    layer\. The procedure must return a list of lists\. Each list pertains to a
    single option and is composed of the switch name, the default value for the
    option and an optional initial value\. For example:

    class car \{
        \.\.\.
        proc options \{this\} \{
            return \[list \[list \-fuel petrol petrol\] \[list \-length \{\} \{\}\] \[list \-power \{\} \{\}\] \[list \-width \{\} \{\}\] \]
        \}

        proc set\-fuel \{this value\} \{
            \.\.\.
        \}

        \.\.\.
    \}


    In this case, 4 options are specified: __fuel__, __length__,
    __power__ and __width__\. The default and initial values for the
    __fuel__ option are identical and set to __petrol__\. For the other
    options, values are all empty\.

    For each option, there must be a corresponding __set\-__option____







|
|
|
|
<
>
|
|
<
>
|
<
>







84
85
86
87
88
89
90
91
92
93
94

95
96
97

98
99

100
101
102
103
104
105
106
107
    This procedure must return the configuration description for *all* options
    that the switched object will accept\. It is a pure virtual member procedure
    and therefore its implementation is *mandatory* in the derived class
    layer\. The procedure must return a list of lists\. Each list pertains to a
    single option and is composed of the switch name, the default value for the
    option and an optional initial value\. For example:

    class car {
        ...
        proc options {this} {
            return [list [list -fuel petrol petrol] [list -length {} {}] [list -power {} {}] [list -width {} {}] ]

        }
        proc set-fuel {this value} {
            ...

        }
        ...

    }

    In this case, 4 options are specified: __fuel__, __length__,
    __power__ and __width__\. The default and initial values for the
    __fuel__ option are identical and set to __petrol__\. For the other
    options, values are all empty\.

    For each option, there must be a corresponding __set\-__option____
116
117
118
119
120
121
122
123
124
125
126
127

128
129

130
131
132
133
134
135
136

    In this procedure, if the initial value differs from the default value or is
    omitted, then initial configuration is forced and the corresponding
    __set\-__option____ procedure is invoked by the switched
    __complete__ procedure located at the end of the derived class
    constructor\. For example:

    class car \{
        \.\.\.
        proc options \{this\} \{
            return \[list \[list \-fuel petrol\] \[list \-length \{\} \{\}\] \[list \-power 100 50\] \[list \-width \{\} \{\}\] \]
        \}

        \.\.\.
    \}


    In this case, configuration is forced on the __fuel__ and __power__
    options, that is the corresponding __set\-__option____ procedures
    will be invoked when the switched object is constructed \(see
    __set\-__option____ procedures documentation below\)\.

    For the __fuel__ option, since there is no initial value, the







|
|
|
|
<
>
|
<
>







116
117
118
119
120
121
122
123
124
125
126

127
128

129
130
131
132
133
134
135
136

    In this procedure, if the initial value differs from the default value or is
    omitted, then initial configuration is forced and the corresponding
    __set\-__option____ procedure is invoked by the switched
    __complete__ procedure located at the end of the derived class
    constructor\. For example:

    class car {
        ...
        proc options {this} {
            return [list [list -fuel petrol] [list -length {} {}] [list -power 100 50] [list -width {} {}] ]

        }
        ...

    }

    In this case, configuration is forced on the __fuel__ and __power__
    options, that is the corresponding __set\-__option____ procedures
    will be invoked when the switched object is constructed \(see
    __set\-__option____ procedures documentation below\)\.

    For the __fuel__ option, since there is no initial value, the
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

  - <a name='3'></a>__<switched>__ __set\-__option____ *this* *value*

    These procedures may be viewed as dynamic virtual functions\. There must be
    one implementation per supported option, as returned by the __options__
    procedure\. For example:

    class car \{
        \.\.\.
        proc options \{this\} \{
            return \[list \.\.\.
                \[list \-width \{\} \{\}\] \]
        \}

        \.\.\.
        proc set\-width \{this value\} \{
            \.\.\.
        \}

        \.\.\.
    \}


    Since the __\-width__ option was listed in the __options__ procedure,
    a __set\-width__ procedure implementation is provided, which of course
    would proceed to set the width of the car \(and would modify the looks of a
    graphical representation, for example\)\.

    As you add a supported __option__ in the list returned by the
    __options__ procedure, the corresponding __set\-__option____
    procedure may be called as soon as the switched object is complete, which
    occurs when the switched level __complete__ procedure is invoked\. For
    example:

    class car \{
        proc car \{this args\} switched \{args\} \{
            \.\.\.
            switched::complete $this
       \}

        \.\.\.
        proc options \{this\} \{
            return \[list \[list \-fuel petrol\] \[list \-length 4\.5\] \[list \-power 350\] \[list \-width 1\.8\] \]
        \}

        proc set\-fuel \{this value\} \{
            \.\.\.
        \}

        proc set\-length \{this value\} \{
            \.\.\.
        \}

        proc set\-power \{this value\} \{
            \.\.\.
        \}

        proc set\-width \{this value\} \{
            \.\.\.
        \}
    \}



    new car

    In this case, a new car is created with no options, which causes the car
    constructor to be called, which in turns calls the switched level
    __complete__ procedure after the car object layer is completely
    initialized\. At this point, since there are no initial values in any option







|
|
|
|
|
<
>
|
|
|
<
>
|
<
>












|
|
|

<
>
|
|
|
<
>
|
|
<
>
|
|
<
>
|
|
<
>
|
|
<
<
>
>







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

  - <a name='3'></a>__<switched>__ __set\-__option____ *this* *value*

    These procedures may be viewed as dynamic virtual functions\. There must be
    one implementation per supported option, as returned by the __options__
    procedure\. For example:

    class car {
        ...
        proc options {this} {
            return [list ...
                [list -width {} {}] ]

        }
        ...
        proc set-width {this value} {
            ...

        }
        ...

    }

    Since the __\-width__ option was listed in the __options__ procedure,
    a __set\-width__ procedure implementation is provided, which of course
    would proceed to set the width of the car \(and would modify the looks of a
    graphical representation, for example\)\.

    As you add a supported __option__ in the list returned by the
    __options__ procedure, the corresponding __set\-__option____
    procedure may be called as soon as the switched object is complete, which
    occurs when the switched level __complete__ procedure is invoked\. For
    example:

    class car {
        proc car {this args} switched {args} {
            ...
            switched::complete $this

       }
        ...
        proc options {this} {
            return [list [list -fuel petrol] [list -length 4.5] [list -power 350] [list -width 1.8] ]

        }
        proc set-fuel {this value} {
            ...

        }
        proc set-length {this value} {
            ...

        }
        proc set-power {this value} {
            ...

        }
        proc set-width {this value} {
            ...


        }
    }

    new car

    In this case, a new car is created with no options, which causes the car
    constructor to be called, which in turns calls the switched level
    __complete__ procedure after the car object layer is completely
    initialized\. At this point, since there are no initial values in any option
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

    The __\-option__ data member is an options current value\. There is one
    for each option listed in the options procedure\. It is a read\-only value
    which the switched layer checks against when an option is changed\. It is
    rarely used at the layer derived from switched, except in the few cases,
    such as in the following example:

    \.\.\.
    proc car::options \{this\} \{
        return \{
            \.\.\.
            \{\-manufacturer \{\} \{\}\}
            \.\.\.
        \}
    \}


    proc car::set\-manufacturer \{this value\} \{\}


    proc car::printData \{this\} \{
        puts "manufacturer: $switched::\($this,\-manufacturer\)"
        \.\.\.
    \}


    In this case, the manufacturer's name is stored at the switched layer level
    \(this is why the set\-manufacturer procedure has nothing to do\) and later
    retrieved in the printData procedure\.

  - __complete__

    The __complete__ data member \(not to be confused with the
    __complete__ procedure\) is a boolean\. Its initial value is __false__
    and it is set to __true__ at the very end of the switched
    __complete__ procedure\. It becomes useful when some options should be
    set at construction time only and not dynamically, as the following example
    shows:

    proc car::set\-width \{this value\} \{
        if \{$switched::\($this,complete\)\} \{
            error \{option \-width cannot be set dynamically\}
        \}

        \.\.\.
    \}


# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *stooop* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|
<
<
|
>
|
>

|
|
|
<
>














|
|
|
<
>
|
<
>







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

    The __\-option__ data member is an options current value\. There is one
    for each option listed in the options procedure\. It is a read\-only value
    which the switched layer checks against when an option is changed\. It is
    rarely used at the layer derived from switched, except in the few cases,
    such as in the following example:

    ...
    proc car::options {this} {
        return {
            ...
            {-manufacturer {} {}}
            ...


        }
    }

    proc car::set-manufacturer {this value} {}

    proc car::printData {this} {
        puts "manufacturer: $switched::($this,-manufacturer)"
        ...

    }

    In this case, the manufacturer's name is stored at the switched layer level
    \(this is why the set\-manufacturer procedure has nothing to do\) and later
    retrieved in the printData procedure\.

  - __complete__

    The __complete__ data member \(not to be confused with the
    __complete__ procedure\) is a boolean\. Its initial value is __false__
    and it is set to __true__ at the very end of the switched
    __complete__ procedure\. It becomes useful when some options should be
    set at construction time only and not dynamically, as the following example
    shows:

    proc car::set-width {this value} {
        if {$switched::($this,complete)} {
            error {option -width cannot be set dynamically}

        }
        ...

    }

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *stooop* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/stringprep/stringprep.md.
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    if *string1* is lexicographically less than *string2*, or 1 if
    *string1* is lexicographically greater than *string2*\.

# <a name='section3'></a>EXAMPLES

Nameprep profile definition \(see RFC\-3491\):

    ::stringprep::register nameprep  \-mapping \{B\.1 B\.2\}  \-normalization KC  \-prohibited \{A\.1 C\.1\.2 C\.2\.2 C\.3 C\.4 C\.5 C\.6 C\.7 C\.8 C\.9\}  \-prohibitedBidi 1

Nodeprep and resourceprep profile definitions \(see RFC\-3920\):

    ::stringprep::register nodeprep  \-mapping \{B\.1 B\.2\}  \-normalization KC  \-prohibited \{A\.1 C\.1\.1 C\.1\.2 C\.2\.1 C\.2\.2 C\.3 C\.4 C\.5 C\.6 C\.7 C\.8 C\.9\}  \-prohibitedList \{0x22 0x26 0x27 0x2f 0x3a 0x3c 0x3e 0x40\}  \-prohibitedBidi 1

    ::stringprep::register resourceprep  \-mapping \{B\.1\}  \-normalization KC  \-prohibited \{A\.1 C\.1\.2 C\.2\.1 C\.2\.2 C\.3 C\.4 C\.5 C\.6 C\.7 C\.8 C\.9\}  \-prohibitedBidi 1

# <a name='section4'></a>REFERENCES

  1. "Preparation of Internationalized Strings \('stringprep'\)",
     \([http://www\.ietf\.org/rfc/rfc3454\.txt](http://www\.ietf\.org/rfc/rfc3454\.txt)\)

  1. "Nameprep: A Stringprep Profile for Internationalized Domain Names \(IDN\)",







|



|

|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    if *string1* is lexicographically less than *string2*, or 1 if
    *string1* is lexicographically greater than *string2*\.

# <a name='section3'></a>EXAMPLES

Nameprep profile definition \(see RFC\-3491\):

    ::stringprep::register nameprep  -mapping {B.1 B.2}  -normalization KC  -prohibited {A.1 C.1.2 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9}  -prohibitedBidi 1

Nodeprep and resourceprep profile definitions \(see RFC\-3920\):

    ::stringprep::register nodeprep  -mapping {B.1 B.2}  -normalization KC  -prohibited {A.1 C.1.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9}  -prohibitedList {0x22 0x26 0x27 0x2f 0x3a 0x3c 0x3e 0x40}  -prohibitedBidi 1

    ::stringprep::register resourceprep  -mapping {B.1}  -normalization KC  -prohibited {A.1 C.1.2 C.2.1 C.2.2 C.3 C.4 C.5 C.6 C.7 C.8 C.9}  -prohibitedBidi 1

# <a name='section4'></a>REFERENCES

  1. "Preparation of Internationalized Strings \('stringprep'\)",
     \([http://www\.ietf\.org/rfc/rfc3454\.txt](http://www\.ietf\.org/rfc/rfc3454\.txt)\)

  1. "Nameprep: A Stringprep Profile for Internationalized Domain Names \(IDN\)",
Changes to embedded/md/tcllib/files/modules/stringprep/unicode.md.
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

    A shortcut to ::unicode::tostring \[unicode::normalize \\$form
    \[::unicode::fromstring \\$string\]\]\. Normalizes Tcl string and returns
    normalized string\.

# <a name='section3'></a>EXAMPLES

    % ::unicode::fromstring "\\u0410\\u0411\\u0412\\u0413"
    1040 1041 1042 1043
    % ::unicode::tostring \{49 50 51 52 53\}
    12345
    %

    % ::unicode::normalize D \{7692 775\}
    68 803 775
    % ::unicode::normalizeS KD "\\u1d2c"
    A
    %

# <a name='section4'></a>REFERENCES

  1. "Unicode Standard Annex \#15: Unicode Normalization Forms",
     \([http://unicode\.org/reports/tr15/](http://unicode\.org/reports/tr15/)\)







|

|



|

|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

    A shortcut to ::unicode::tostring \[unicode::normalize \\$form
    \[::unicode::fromstring \\$string\]\]\. Normalizes Tcl string and returns
    normalized string\.

# <a name='section3'></a>EXAMPLES

    % ::unicode::fromstring "\u0410\u0411\u0412\u0413"
    1040 1041 1042 1043
    % ::unicode::tostring {49 50 51 52 53}
    12345
    %

    % ::unicode::normalize D {7692 775}
    68 803 775
    % ::unicode::normalizeS KD "\u1d2c"
    A
    %

# <a name='section4'></a>REFERENCES

  1. "Unicode Standard Annex \#15: Unicode Normalization Forms",
     \([http://unicode\.org/reports/tr15/](http://unicode\.org/reports/tr15/)\)
Changes to embedded/md/tcllib/files/modules/struct/disjointset.md.
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
    covering the whole set\.

  - An alternative name for the *partitions* would be *equvalence classes*,
    and all elements in the same class are considered as equal\.

Here is a pictorial representation of the concepts listed above:

    \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+ The outer lines are the boundaries of the set S\.
    &#124;           /     &#124; The inner regions delineated by the skewed lines
    &#124;  \*       /   \*  &#124; are the partitions P\. The \*'s denote the elements
    &#124;      \*  / \\     &#124; E in the set, each in a single partition, their
    &#124;\*       /   \\    &#124; equivalence class\.
    &#124;       /  \*  \\   &#124;
    &#124;      / \*   /    &#124;
    &#124; \*   /\\  \* /     &#124;
    &#124;    /  \\  /      &#124;
    &#124;   /    \\/  \*    &#124;
    &#124;  / \*    \\       &#124;
    &#124; /     \*  \\      &#124;
    \+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+

For more information see
[http://en\.wikipedia\.org/wiki/Disjoint\_set\_data\_structure](http://en\.wikipedia\.org/wiki/Disjoint\_set\_data\_structure)\.

# <a name='section2'></a>API

The package exports a single command, __::struct::disjointset__\. All







|
|
|
|
|
|
|
|
|
|
|
|
|







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
    covering the whole set\.

  - An alternative name for the *partitions* would be *equvalence classes*,
    and all elements in the same class are considered as equal\.

Here is a pictorial representation of the concepts listed above:

    +-----------------+ The outer lines are the boundaries of the set S.
    |           /     | The inner regions delineated by the skewed lines
    |  *       /   *  | are the partitions P. The *'s denote the elements
    |      *  / \     | E in the set, each in a single partition, their
    |*       /   \    | equivalence class.
    |       /  *  \   |
    |      / *   /    |
    | *   /\  * /     |
    |    /  \  /      |
    |   /    \/  *    |
    |  / *    \       |
    | /     *  \      |
    +-----------------+

For more information see
[http://en\.wikipedia\.org/wiki/Disjoint\_set\_data\_structure](http://en\.wikipedia\.org/wiki/Disjoint\_set\_data\_structure)\.

# <a name='section2'></a>API

The package exports a single command, __::struct::disjointset__\. All
Changes to embedded/md/tcllib/files/modules/struct/graph.md.
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
    This is the *assignment* operator for graph objects\. It copies the graph
    contained in the graph object *sourcegraph* over the graph data in
    *graphName*\. The old contents of *graphName* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *graphName* __deserialize__ \[*sourcegraph* __serialize__\]

    The operation assumes that the *sourcegraph* provides the method
    __serialize__ and that this method returns a valid graph serialization\.

  - <a name='4'></a>*graphName* __\-\->__ *destgraph*

    This is the *reverse assignment* operator for graph objects\. It copies the
    graph contained in the graph object *graphName* over the graph data in the
    object *destgraph*\. The old contents of *destgraph* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *destgraph* __deserialize__ \[*graphName* __serialize__\]

    The operation assumes that the *destgraph* provides the method
    __deserialize__ and that this method takes a graph serialization\.

  - <a name='5'></a>*graphName* __append__ *key* *value*

    Appends a *value* to one of the keyed values associated with the graph\.







|













|







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
    This is the *assignment* operator for graph objects\. It copies the graph
    contained in the graph object *sourcegraph* over the graph data in
    *graphName*\. The old contents of *graphName* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *graphName* __deserialize__ [*sourcegraph* __serialize__]

    The operation assumes that the *sourcegraph* provides the method
    __serialize__ and that this method returns a valid graph serialization\.

  - <a name='4'></a>*graphName* __\-\->__ *destgraph*

    This is the *reverse assignment* operator for graph objects\. It copies the
    graph contained in the graph object *graphName* over the graph data in the
    object *destgraph*\. The old contents of *destgraph* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *destgraph* __deserialize__ [*graphName* __serialize__]

    The operation assumes that the *destgraph* provides the method
    __deserialize__ and that this method takes a graph serialization\.

  - <a name='5'></a>*graphName* __append__ *key* *value*

    Appends a *value* to one of the keyed values associated with the graph\.
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

    For all attribute dictionaries they keys are the names of the attributes,
    and the values are the values for each name\.

    *Note:* The order of the nodes in the serialization has no relevance, nor
    has the order of the arcs per node\.

        \# A possible serialization for the graph structure
        \#

        \#        d \-\-\-\-\-> %2
        \#       /         ^ \\\\
        \#      /         /   \\\\
        \#     /         b     \\\\
        \#    /         /       \\\\
        \#  %1 <\- a \- %0         e
        \#    ^         \\\\      /
        \#     \\\\        c     /
        \#      \\\\        \\\\  /
        \#       \\\\        v v
        \#        f \-\-\-\-\-\- %3
        \# is
        \#

        \# %3 \{\} \{\{f 6 \{\}\}\} %0 \{\} \{\{a 6 \{\}\} \{b 9 \{\}\} \{c 0 \{\}\}\} %1 \{\} \{\{d 9 \{\}\}\} %2 \{\} \{\{e 0 \{\}\}\} \{\}
        \#

        \# This assumes that the graph has neither attribute data nor weighted arcs\.

  - <a name='64'></a>*graphName* __set__ *key* ?*value*?

    Set or get one of the keyed values associated with a graph\. A graph may have
    any number of keyed values associated with it\. If *value* is not
    specified, this command returns the current value assigned to the key; if
    *value* is specified, this command assigns that value to the key\.







|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
<
>
|
<
>
|







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

    For all attribute dictionaries they keys are the names of the attributes,
    and the values are the values for each name\.

    *Note:* The order of the nodes in the serialization has no relevance, nor
    has the order of the arcs per node\.

        # A possible serialization for the graph structure

        #
        #        d -----> %2
        #       /         ^ \\
        #      /         /   \\
        #     /         b     \\
        #    /         /       \\
        #  %1 <- a - %0         e
        #    ^         \\      /
        #     \\        c     /
        #      \\        \\  /
        #       \\        v v
        #        f ------ %3
        # is

        #
        # %3 {} {{f 6 {}}} %0 {} {{a 6 {}} {b 9 {}} {c 0 {}}} %1 {} {{d 9 {}}} %2 {} {{e 0 {}}} {}

        #
        # This assumes that the graph has neither attribute data nor weighted arcs.

  - <a name='64'></a>*graphName* __set__ *key* ?*value*?

    Set or get one of the keyed values associated with a graph\. A graph may have
    any number of keyed values associated with it\. If *value* is not
    specified, this command returns the current value assigned to the key; if
    *value* is specified, this command assigns that value to the key\.
Changes to embedded/md/tcllib/files/modules/struct/matrix.md.
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
    This is the assignment operator for matrix objects\. It copies the matrix
    contained in the matrix object *sourcematrix* over the matrix data in
    *matrixName*\. The old contents of *matrixName* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *matrixName* __deserialize__ \[*sourcematrix* __serialize__\]

  - <a name='4'></a>*matrixName* __\-\->__ *destmatrix*

    This is the reverse assignment operator for matrix objects\. It copies the
    matrix contained in the matrix object *matrixName* over the matrix data in
    the object *destmatrix*\. The old contents of *destmatrix* are deleted by
    this operation\.

    This operation is in effect equivalent to

        *destmatrix* __deserialize__ \[*matrixName* __serialize__\]

  - <a name='5'></a>*matrixName* __add column__ ?*values*?

    Extends the matrix by one column and then acts like __set column__ \(see
    below\) on this new column if there were *values* supplied\. Without
    *values* the new cells will be set to the empty string\. The new column is
    appended immediately behind the last existing column\.







|










|







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
    This is the assignment operator for matrix objects\. It copies the matrix
    contained in the matrix object *sourcematrix* over the matrix data in
    *matrixName*\. The old contents of *matrixName* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *matrixName* __deserialize__ [*sourcematrix* __serialize__]

  - <a name='4'></a>*matrixName* __\-\->__ *destmatrix*

    This is the reverse assignment operator for matrix objects\. It copies the
    matrix contained in the matrix object *matrixName* over the matrix data in
    the object *destmatrix*\. The old contents of *destmatrix* are deleted by
    this operation\.

    This operation is in effect equivalent to

        *destmatrix* __deserialize__ [*matrixName* __serialize__]

  - <a name='5'></a>*matrixName* __add column__ ?*values*?

    Extends the matrix by one column and then acts like __set column__ \(see
    below\) on this new column if there were *values* supplied\. Without
    *values* the new cells will be set to the empty string\. The new column is
    appended immediately behind the last existing column\.
390
391
392
393
394
395
396
397
398

399
400
401
402

403
404

405
406
407
408
409
410
411
412
    The last element of the list contains the values of the matrix cells we have
    serialized, in the form of a value like it is returned by the __get
    rect__\. However empty cells to the right and bottom of the matrix can be
    left out of that value as the size information in the serialization allows
    the receiver the creation of a matrix with the proper size despite the
    missing values\.

        \# A possible serialization for the matrix structure
        \#

        \# &#124; a b d g &#124;
        \# &#124; c e     &#124;
        \# &#124; f       &#124;
        \#

        \# is
        \#

        \# 3 4 \{\{a b d g\} \{c e\} \{f\}\}

  - <a name='36'></a>*matrixName* __set cell__ *column row value*

    Sets the value in the cell identified by row and column index to the data in
    the third argument\.

  - <a name='37'></a>*matrixName* __set column__ *column values*







|
<
>
|
|
|
<
>
|
<
>
|







390
391
392
393
394
395
396
397

398
399
400
401

402
403

404
405
406
407
408
409
410
411
412
    The last element of the list contains the values of the matrix cells we have
    serialized, in the form of a value like it is returned by the __get
    rect__\. However empty cells to the right and bottom of the matrix can be
    left out of that value as the size information in the serialization allows
    the receiver the creation of a matrix with the proper size despite the
    missing values\.

        # A possible serialization for the matrix structure

        #
        # | a b d g |
        # | c e     |
        # | f       |

        #
        # is

        #
        # 3 4 {{a b d g} {c e} {f}}

  - <a name='36'></a>*matrixName* __set cell__ *column row value*

    Sets the value in the cell identified by row and column index to the data in
    the third argument\.

  - <a name='37'></a>*matrixName* __set column__ *column values*
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
# <a name='section2'></a>EXAMPLES

The examples below assume a 5x5 matrix M with the first row containing the
values 1 to 5, with 1 in the top\-left cell\. Each other row contains the contents
of the row above it, rotated by one cell to the right\.

    % M get rect 0 0 4 4
    \{\{1 2 3 4 5\} \{5 1 2 3 4\} \{4 5 1 2 3\} \{3 4 5 1 2\} \{2 3 4 5 1\}\}

    % M set rect 1 1 \{\{0 0 0\} \{0 0 0\} \{0 0 0\}\}
    % M get rect 0 0 4 4
    \{\{1 2 3 4 5\} \{5 0 0 0 4\} \{4 0 0 0 3\} \{3 0 0 0 2\} \{2 3 4 5 1\}\}

Assuming that the style definitions in the example section of the manpage for
the package __[report](\.\./report/report\.md)__ are loaded into the
interpreter now an example which formats a matrix into a tabular report\. The
code filling the matrix with data is not shown\. contains useful data\.

    % ::struct::matrix m
    % \# \.\.\. fill m with data, assume 5 columns
    % ::report::report r 5 style captionedtable 1
    % m format 2string r
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    &#124;000&#124;VERSIONS:          &#124;2:8\.4a3&#124;1:8\.4a3&#124;1:8\.4a3%&#124;
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    &#124;001&#124;CATCH return ok    &#124;7      &#124;13     &#124;53\.85   &#124;
    &#124;002&#124;CATCH return error &#124;68     &#124;91     &#124;74\.73   &#124;
    &#124;003&#124;CATCH no catch used&#124;7      &#124;14     &#124;50\.00   &#124;
    &#124;004&#124;IF if true numeric &#124;12     &#124;33     &#124;36\.36   &#124;
    &#124;005&#124;IF elseif          &#124;15     &#124;47     &#124;31\.91   &#124;
    &#124;   &#124;true numeric       &#124;       &#124;       &#124;        &#124;
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    %
    % \# alternate way of doing the above
    % r printmatrix m

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: matrix* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report







|

|

|







|


|
|
|
|
|
|
|
|
|
|

|







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
# <a name='section2'></a>EXAMPLES

The examples below assume a 5x5 matrix M with the first row containing the
values 1 to 5, with 1 in the top\-left cell\. Each other row contains the contents
of the row above it, rotated by one cell to the right\.

    % M get rect 0 0 4 4
    {{1 2 3 4 5} {5 1 2 3 4} {4 5 1 2 3} {3 4 5 1 2} {2 3 4 5 1}}

    % M set rect 1 1 {{0 0 0} {0 0 0} {0 0 0}}
    % M get rect 0 0 4 4
    {{1 2 3 4 5} {5 0 0 0 4} {4 0 0 0 3} {3 0 0 0 2} {2 3 4 5 1}}

Assuming that the style definitions in the example section of the manpage for
the package __[report](\.\./report/report\.md)__ are loaded into the
interpreter now an example which formats a matrix into a tabular report\. The
code filling the matrix with data is not shown\. contains useful data\.

    % ::struct::matrix m
    % # ... fill m with data, assume 5 columns
    % ::report::report r 5 style captionedtable 1
    % m format 2string r
    +---+-------------------+-------+-------+--------+
    |000|VERSIONS:          |2:8.4a3|1:8.4a3|1:8.4a3%|
    +---+-------------------+-------+-------+--------+
    |001|CATCH return ok    |7      |13     |53.85   |
    |002|CATCH return error |68     |91     |74.73   |
    |003|CATCH no catch used|7      |14     |50.00   |
    |004|IF if true numeric |12     |33     |36.36   |
    |005|IF elseif          |15     |47     |31.91   |
    |   |true numeric       |       |       |        |
    +---+-------------------+-------+-------+--------+
    %
    % # alternate way of doing the above
    % r printmatrix m

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: matrix* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
Changes to embedded/md/tcllib/files/modules/struct/matrix1.md.
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
# <a name='section2'></a>EXAMPLES

The examples below assume a 5x5 matrix M with the first row containing the
values 1 to 5, with 1 in the top\-left cell\. Each other row contains the contents
of the row above it, rotated by one cell to the right\.

    % M getrect 0 0 4 4
    \{\{1 2 3 4 5\} \{5 1 2 3 4\} \{4 5 1 2 3\} \{3 4 5 1 2\} \{2 3 4 5 1\}\}

    % M setrect 1 1 \{\{0 0 0\} \{0 0 0\} \{0 0 0\}\}
    % M getrect 0 0 4 4
    \{\{1 2 3 4 5\} \{5 0 0 0 4\} \{4 0 0 0 3\} \{3 0 0 0 2\} \{2 3 4 5 1\}\}

Assuming that the style definitions in the example section of the manpage for
the package __[report](\.\./report/report\.md)__ are loaded into the
interpreter now an example which formats a matrix into a tabular report\. The
code filling the matrix with data is not shown\. contains useful data\.

    % ::struct::matrix m
    % \# \.\.\. fill m with data, assume 5 columns
    % ::report::report r 5 style captionedtable 1
    % m format 2string r
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    &#124;000&#124;VERSIONS:          &#124;2:8\.4a3&#124;1:8\.4a3&#124;1:8\.4a3%&#124;
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    &#124;001&#124;CATCH return ok    &#124;7      &#124;13     &#124;53\.85   &#124;
    &#124;002&#124;CATCH return error &#124;68     &#124;91     &#124;74\.73   &#124;
    &#124;003&#124;CATCH no catch used&#124;7      &#124;14     &#124;50\.00   &#124;
    &#124;004&#124;IF if true numeric &#124;12     &#124;33     &#124;36\.36   &#124;
    &#124;005&#124;IF elseif          &#124;15     &#124;47     &#124;31\.91   &#124;
    &#124;   &#124;true numeric       &#124;       &#124;       &#124;        &#124;
    \+\-\-\-\+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\+\-\-\-\-\-\-\-\-\+
    %
    % \# alternate way of doing the above
    % r printmatrix m

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: matrix* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report







|

|

|







|


|
|
|
|
|
|
|
|
|
|

|







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
# <a name='section2'></a>EXAMPLES

The examples below assume a 5x5 matrix M with the first row containing the
values 1 to 5, with 1 in the top\-left cell\. Each other row contains the contents
of the row above it, rotated by one cell to the right\.

    % M getrect 0 0 4 4
    {{1 2 3 4 5} {5 1 2 3 4} {4 5 1 2 3} {3 4 5 1 2} {2 3 4 5 1}}

    % M setrect 1 1 {{0 0 0} {0 0 0} {0 0 0}}
    % M getrect 0 0 4 4
    {{1 2 3 4 5} {5 0 0 0 4} {4 0 0 0 3} {3 0 0 0 2} {2 3 4 5 1}}

Assuming that the style definitions in the example section of the manpage for
the package __[report](\.\./report/report\.md)__ are loaded into the
interpreter now an example which formats a matrix into a tabular report\. The
code filling the matrix with data is not shown\. contains useful data\.

    % ::struct::matrix m
    % # ... fill m with data, assume 5 columns
    % ::report::report r 5 style captionedtable 1
    % m format 2string r
    +---+-------------------+-------+-------+--------+
    |000|VERSIONS:          |2:8.4a3|1:8.4a3|1:8.4a3%|
    +---+-------------------+-------+-------+--------+
    |001|CATCH return ok    |7      |13     |53.85   |
    |002|CATCH return error |68     |91     |74.73   |
    |003|CATCH no catch used|7      |14     |50.00   |
    |004|IF if true numeric |12     |33     |36.36   |
    |005|IF elseif          |15     |47     |31.91   |
    |   |true numeric       |       |       |        |
    +---+-------------------+-------+-------+--------+
    %
    % # alternate way of doing the above
    % r printmatrix m

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: matrix* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
Changes to embedded/md/tcllib/files/modules/struct/pool.md.
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
In this example, brand names are used to label the various items\. However, a
brand name could be regarded as a property of an item\. Because the pool command
is not designed to manage properties of items, they need to be managed
separately\. In the latter case the items should be labeled with more neutral
names such as: car1, car2, car3 , etc \.\.\. and a separate database or array
should hold the brand names associated with the car labels\.

    1\. Load the package into an interpreter
    % package require pool
    0\.1

    2\. Create a pool object called \`CarPool' with a maximum size of 55 items \(cars\):
    % pool CarPool 55
    CarPool

    4\. Add items to the pool:
    % CarPool add Toyota Trabant Chrysler1 Chrysler2 Volkswagen

    5\. Somebody crashed the Toyota\. Remove it from the pool as follows:
    % CarPool remove Toyota

    6\. Acquired a new car for the pool\. Add it as follows:
    % CarPool add Nissan

    7\. Check whether the pool was adjusted correctly:
    % CarPool info allitems
    Trabant Chrysler1 Chrysler2 Volkswagen Nissan

Suspend the interactive session temporarily, and show the programmatic use of
the request subcommand:

    \# Mrs\. Swift needs a car\. She doesn't have a preference for a
    \# particular car\. We'll issue a request on her behalf as follows:
    if \{ \[CarPool request car \-allocID "Mrs\. Swift"\] \}  \{
        \# request was honoured, process the variable \`car'
        puts "$car has been allocated to \[CarPool info allocID $car\]\."
    \} else \{
        \# request was denied
         puts "No car available\."
    \}


Note how the __if__ command uses the value returned by the __request__
subcommand\.

    \# Suppose Mr\. Wiggly has a preference for the Trabant:
    if \{ \[CarPool request car \-allocID "Mr\. Wiggly" \-prefer Trabant\] \}  \{
        \# request was honoured, process the variable \`car'
        puts "$car has been allocated to \[CarPool info allocID $car\]\."
    \} else \{
        \# request was denied
         puts "The Trabant was not available\."
    \}


Resume the interactive session:

    8\. When the car is returned then you can render it available by:
    % CarPool release Trabant

    9\. When done, you delete the pool\.
    % CarPool destroy
    Couldn't destroy \`CarPool' because some items are still allocated\.

    Oops, forgot that Mrs\. Swift still occupies a car\.

    10\. We force the destruction of the pool as follows:
    % CarPool destroy \-force

*Example 2*

This example describes the case from which the author's need for pool management
originated\. It is an example of a server application that receives requests from
client applications\. The client requests are dispatched onto a back\-end
application before being returned to the client application\. In many cases there
are a few equivalent instances of back\-end applications to which a client
request may be passed along\. The file descriptors that identify the channels to
these back\-end instances make up a pool of connections\. A particular connection
may be allocated to just one client request at a time\.

    \# Create the pool of connections \(pipes\)
    set maxpipes 10
    pool Pipes $maxpipes
    for \{set i 0\} \{$i < $maxpipes\} \{incr i\} \{
        set fd \[open "&#124;backendApplication" w\+\]
        Pipes add $fd
    \}


    \# A client request comes in\. The request is identified as \`clientX'\.
    \# Dispatch it onto an instance of a back\-end application
    if \{ \[Pipes request fd \-allocID clientX\] \} \{
        \# a connection was allocated
        \# communicate to the back\-end application via the variable \`fd'
        puts $fd "someInstruction"
        \# \.\.\.\.\.\. etc\.
    \} else \{
        \# all connections are currently occupied
        \# store the client request in a queue for later processing,
        \# or return a 'Server busy' message to the client\.
    \}


# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: pool* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.







|

|

|



|


|


|


|






|
|
|
|
|
|
|
|
<
|
>



|
|
|
|
|
|
|
<
>



|


|

|

|

|
|












|


|
|

<
|
>
|
|
|
|
|

|
|
|
|
|
<
>







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
In this example, brand names are used to label the various items\. However, a
brand name could be regarded as a property of an item\. Because the pool command
is not designed to manage properties of items, they need to be managed
separately\. In the latter case the items should be labeled with more neutral
names such as: car1, car2, car3 , etc \.\.\. and a separate database or array
should hold the brand names associated with the car labels\.

    1. Load the package into an interpreter
    % package require pool
    0.1

    2. Create a pool object called `CarPool' with a maximum size of 55 items (cars):
    % pool CarPool 55
    CarPool

    4. Add items to the pool:
    % CarPool add Toyota Trabant Chrysler1 Chrysler2 Volkswagen

    5. Somebody crashed the Toyota. Remove it from the pool as follows:
    % CarPool remove Toyota

    6. Acquired a new car for the pool. Add it as follows:
    % CarPool add Nissan

    7. Check whether the pool was adjusted correctly:
    % CarPool info allitems
    Trabant Chrysler1 Chrysler2 Volkswagen Nissan

Suspend the interactive session temporarily, and show the programmatic use of
the request subcommand:

    # Mrs. Swift needs a car. She doesn't have a preference for a
    # particular car. We'll issue a request on her behalf as follows:
    if { [CarPool request car -allocID "Mrs. Swift"] }  {
        # request was honoured, process the variable `car'
        puts "$car has been allocated to [CarPool info allocID $car]."
    } else {
        # request was denied
         puts "No car available."

    }

Note how the __if__ command uses the value returned by the __request__
subcommand\.

    # Suppose Mr. Wiggly has a preference for the Trabant:
    if { [CarPool request car -allocID "Mr. Wiggly" -prefer Trabant] }  {
        # request was honoured, process the variable `car'
        puts "$car has been allocated to [CarPool info allocID $car]."
    } else {
        # request was denied
         puts "The Trabant was not available."

    }

Resume the interactive session:

    8. When the car is returned then you can render it available by:
    % CarPool release Trabant

    9. When done, you delete the pool.
    % CarPool destroy
    Couldn't destroy `CarPool' because some items are still allocated.

    Oops, forgot that Mrs. Swift still occupies a car.

    10. We force the destruction of the pool as follows:
    % CarPool destroy -force

*Example 2*

This example describes the case from which the author's need for pool management
originated\. It is an example of a server application that receives requests from
client applications\. The client requests are dispatched onto a back\-end
application before being returned to the client application\. In many cases there
are a few equivalent instances of back\-end applications to which a client
request may be passed along\. The file descriptors that identify the channels to
these back\-end instances make up a pool of connections\. A particular connection
may be allocated to just one client request at a time\.

    # Create the pool of connections (pipes)
    set maxpipes 10
    pool Pipes $maxpipes
    for {set i 0} {$i < $maxpipes} {incr i} {
        set fd [open "|backendApplication" w+]
        Pipes add $fd

    }

    # A client request comes in. The request is identified as `clientX'.
    # Dispatch it onto an instance of a back-end application
    if { [Pipes request fd -allocID clientX] } {
        # a connection was allocated
        # communicate to the back-end application via the variable `fd'
        puts $fd "someInstruction"
        # ...... etc.
    } else {
        # all connections are currently occupied
        # store the client request in a queue for later processing,
        # or return a 'Server busy' message to the client.

    }

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: pool* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/struct/record.md.
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

Record members can either be variables, or other records, However, the same
record can not be nested witin itself \(circular\)\. To define a nested record, you
need to specify the __record__ keyword, along the with name of the record,
and the name of the instance of that nested record\. For example, it would look
like this:

    \# this is the nested record
    record define mynestedrecord \{
        nest1
        nest2
    \}


    \# This is the main record
    record define myrecord \{
        mem1
        mem2
        \{record mynestedrecord mem3\}
    \}


You can also assign default or initial values to the members of a record, by
enclosing the member entry in braces:

    record define myrecord \{
        mem1
        \{mem2 5\}
    \}


All instances created from this record definition, will initially have 5 as the
value for *mem2*\. If no default is given, then the value will be the empty
string\.

*Getting Values*








|
|


<
|
>
|
|


|
<
>




|

|
<
>







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

Record members can either be variables, or other records, However, the same
record can not be nested witin itself \(circular\)\. To define a nested record, you
need to specify the __record__ keyword, along the with name of the record,
and the name of the instance of that nested record\. For example, it would look
like this:

    # this is the nested record
    record define mynestedrecord {
        nest1
        nest2

    }

    # This is the main record
    record define myrecord {
        mem1
        mem2
        {record mynestedrecord mem3}

    }

You can also assign default or initial values to the members of a record, by
enclosing the member entry in braces:

    record define myrecord {
        mem1
        {mem2 5}

    }

All instances created from this record definition, will initially have 5 as the
value for *mem2*\. If no default is given, then the value will be the empty
string\.

*Getting Values*

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
interface more Tcl like, which made sense\. However, the original alias access
still exists\. It might prove to be helpful to some\.

Basically, for every member of every instance, an alias is created\. This alias
is used to get and set values for that member\. An example will illustrate the
point, using the above defined records:

    \# Create an instance first
    % myrecord inst1
    ::inst1
    % \# To get a member of an instance, just use the
    % \# alias \(it behaves like a Tcl command\):
    % inst1\.mem1
    %
    % \# To set a member via the alias, just include
    % \# a value \(optionally the equal sign \- syntactic sugar\)
    % inst1\.mem1 = 5
    5
    % inst1\.mem1
    5
    % \# For nested records, just continue with the
    % \# dot notation \(note no equal sign\)
    % inst1\.mem3\.nest1 10
    10
    % inst1\.mem3\.nest1
    10
    % \# just the instance by itself gives all
    % \# member/values pairs for that instance
    % inst1
    \-mem1 5 \-mem2 \{\} \-mem3 \{\-nest1 10 \-nest2 \{\}\}
    % \# and to get all members within the nested record
    % inst1\.mem3
    \-nest1 10 \-nest2 \{\}
    %

# <a name='section3'></a>RECORD COMMAND

The following subcommands and corresponding arguments are available to any
record command:








|


|
|
|

|
|
|

|

|
|
|

|

|
|

|
|
|
|







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
interface more Tcl like, which made sense\. However, the original alias access
still exists\. It might prove to be helpful to some\.

Basically, for every member of every instance, an alias is created\. This alias
is used to get and set values for that member\. An example will illustrate the
point, using the above defined records:

    # Create an instance first
    % myrecord inst1
    ::inst1
    % # To get a member of an instance, just use the
    % # alias (it behaves like a Tcl command):
    % inst1.mem1
    %
    % # To set a member via the alias, just include
    % # a value (optionally the equal sign - syntactic sugar)
    % inst1.mem1 = 5
    5
    % inst1.mem1
    5
    % # For nested records, just continue with the
    % # dot notation (note no equal sign)
    % inst1.mem3.nest1 10
    10
    % inst1.mem3.nest1
    10
    % # just the instance by itself gives all
    % # member/values pairs for that instance
    % inst1
    -mem1 5 -mem2 {} -mem3 {-nest1 10 -nest2 {}}
    % # and to get all members within the nested record
    % inst1.mem3
    -nest1 10 -nest2 {}
    %

# <a name='section3'></a>RECORD COMMAND

The following subcommands and corresponding arguments are available to any
record command:

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
*Example 1*

Probably the most obvious example would be to hold contact information, such as
addresses, phone numbers, comments, etc\. Since a person can have multiple phone
numbers, multiple email addresses, etc, we will use nested records to define
these\. So, the first thing we do is define the nested records:

    \#\#
    \#\#  This is an interactive example, to see what is
    \#\#  returned by each command as well\.
    \#\#

    % namespace import ::struct::record::\*

    % \# define a nested record\. Notice that country has default 'USA'\.
    % record define locations \{
        street
        street2
        city
        state
        zipcode
        \{country USA\}
        phone
    \}

    ::locations
    % \# Define the main record\. Notice that it uses the location record twice\.
    % record define contacts \{
        first
        middle
        last
        \{record locations home\}
        \{record locations work\}
    \}

    ::contacts
    % \# Create an instance for the contacts record\.
    % contacts cont1
    ::cont1
    % \# Display some introspection values
    % record show records
    ::contacts ::locations
    % \#
    % record show values cont1
    \-first \{\} \-middle \{\} \-last \{\} \-home \{\-street \{\} \-street2 \{\} \-city \{\} \-state \{\} \-zipcode \{\} \-country USA \-phone \{\}\} \-work \{\-street \{\} \-street2 \{\} \-city \{\} \-state \{\} \-zipcode \{\} \-country USA \-phone \{\}\}
    % \#
    % record show instances contacts
    ::cont1
    % \#
    % cont1 config
    \-first \{\} \-middle \{\} \-last \{\} \-home \{\-street \{\} \-street2 \{\} \-city \{\} \-state \{\} \-zipcode \{\} \-country USA \-phone \{\}\} \-work \{\-street \{\} \-street2 \{\} \-city \{\} \-state \{\} \-zipcode \{\} \-country USA \-phone \{\}\}
    % \#
    % cont1 cget
    \-first \{\} \-middle \{\} \-last \{\} \-home \{\-street \{\} \-street2 \{\} \-city \{\} \-state \{\} \-zipcode \{\} \-country USA \-phone \{\}\} \-work \{\-street \{\} \-street2 \{\} \-city \{\} \-state \{\} \-zipcode \{\} \-country USA \-phone \{\}\}
    % \# copy one record to another record
    % record define contacts2 \[record show members contacts\]
    ::contacts2
    % record show members contacts2
    first middle last \{record locations home\} \{record locations work\}
    % record show members contacts
    first middle last \{record locations home\} \{record locations work\}
    %

*Example 1*

This next example just illustrates a simple linked list

    % \# define a very simple record for linked list
    % record define llist \{
        value
        next
    \}

    ::llist
    % llist lstart
    ::lstart
    % lstart config \-value 1 \-next \[llist \#auto\]
    % \[lstart cget \-next\] config \-value 2 \-next \[llist \#auto\]
    % \[\[lstart cget \-next\] cget \-next\] config \-value 3 \-next "end"
    % set next lstart
    lstart
    % while 1 \{
    lappend values \[$next cget \-value\]
    set next \[$next cget \-next\]
    if \{\[string match "end" $next\]\} \{break\}
    \}

    % puts "$values"
    1 2 3
    % \# cleanup linked list
    % \# We could just use delete record llist also
    % foreach I \[record show instances llist\] \{
    record delete instance $I
    \}

    % record show instances llist
    %

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: record* of the







|
|
|
|

|

|
|





|

<
>

|
|



|
|
<
>

|


|


|

|
|


|

|
|

|
|
|


|

|






|
|


<
>



|
|
|


|
|
|
|
<
>


|
|
|

<
>







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
*Example 1*

Probably the most obvious example would be to hold contact information, such as
addresses, phone numbers, comments, etc\. Since a person can have multiple phone
numbers, multiple email addresses, etc, we will use nested records to define
these\. So, the first thing we do is define the nested records:

    ##
    ##  This is an interactive example, to see what is
    ##  returned by each command as well.
    ##

    % namespace import ::struct::record::*

    % # define a nested record. Notice that country has default 'USA'.
    % record define locations {
        street
        street2
        city
        state
        zipcode
        {country USA}
        phone

    }
    ::locations
    % # Define the main record. Notice that it uses the location record twice.
    % record define contacts {
        first
        middle
        last
        {record locations home}
        {record locations work}

    }
    ::contacts
    % # Create an instance for the contacts record.
    % contacts cont1
    ::cont1
    % # Display some introspection values
    % record show records
    ::contacts ::locations
    % #
    % record show values cont1
    -first {} -middle {} -last {} -home {-street {} -street2 {} -city {} -state {} -zipcode {} -country USA -phone {}} -work {-street {} -street2 {} -city {} -state {} -zipcode {} -country USA -phone {}}
    % #
    % record show instances contacts
    ::cont1
    % #
    % cont1 config
    -first {} -middle {} -last {} -home {-street {} -street2 {} -city {} -state {} -zipcode {} -country USA -phone {}} -work {-street {} -street2 {} -city {} -state {} -zipcode {} -country USA -phone {}}
    % #
    % cont1 cget
    -first {} -middle {} -last {} -home {-street {} -street2 {} -city {} -state {} -zipcode {} -country USA -phone {}} -work {-street {} -street2 {} -city {} -state {} -zipcode {} -country USA -phone {}}
    % # copy one record to another record
    % record define contacts2 [record show members contacts]
    ::contacts2
    % record show members contacts2
    first middle last {record locations home} {record locations work}
    % record show members contacts
    first middle last {record locations home} {record locations work}
    %

*Example 1*

This next example just illustrates a simple linked list

    % # define a very simple record for linked list
    % record define llist {
        value
        next

    }
    ::llist
    % llist lstart
    ::lstart
    % lstart config -value 1 -next [llist #auto]
    % [lstart cget -next] config -value 2 -next [llist #auto]
    % [[lstart cget -next] cget -next] config -value 3 -next "end"
    % set next lstart
    lstart
    % while 1 {
    lappend values [$next cget -value]
    set next [$next cget -next]
    if {[string match "end" $next]} {break}

    }
    % puts "$values"
    1 2 3
    % # cleanup linked list
    % # We could just use delete record llist also
    % foreach I [record show instances llist] {
    record delete instance $I

    }
    % record show instances llist
    %

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: record* of the
Changes to embedded/md/tcllib/files/modules/struct/struct_list.md.
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        of indices into *sequence1* describes the range of items which has
        been replaced\. The first index refers to the first item in the range,
        and the second index refers to the last item in the range\. The pair of
        indices into *sequence2* describes the range of items replacing the
        original range\. Again the first index refers to the first item in the
        range, and the second index refers to the last item in the range\.

        sequence 1 = \{a b r a c a d a b r a\}
        lcs 1      =   \{1 2   4 5     8 9 10\}
        lcs 2      =   \{0 1   3 4     5 6 7\}
        sequence 2 =   \{b r i c a     b r a c\}

        Inversion  = \{\{deleted  \{0  0\} \{\-1 0\}\}
                      \{changed  \{3  3\}  \{2 2\}\}
                      \{deleted  \{6  7\}  \{4 5\}\}
                      \{added   \{10 11\}  \{8 8\}\}\}

    *Notes:*

      * An index of __\-1__ in a *deleted* chunk refers to just before the
        first element of the second sequence\.

      * Also an index equal to the length of the first sequence in an *added*







|
|
|
|

|
|
|
|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        of indices into *sequence1* describes the range of items which has
        been replaced\. The first index refers to the first item in the range,
        and the second index refers to the last item in the range\. The pair of
        indices into *sequence2* describes the range of items replacing the
        original range\. Again the first index refers to the first item in the
        range, and the second index refers to the last item in the range\.

        sequence 1 = {a b r a c a d a b r a}
        lcs 1      =   {1 2   4 5     8 9 10}
        lcs 2      =   {0 1   3 4     5 6 7}
        sequence 2 =   {b r i c a     b r a c}

        Inversion  = {{deleted  {0  0} {-1 0}}
                      {changed  {3  3}  {2 2}}
                      {deleted  {6  7}  {4 5}}
                      {added   {10 11}  {8 8}}}

    *Notes:*

      * An index of __\-1__ in a *deleted* chunk refers to just before the
        first element of the second sequence\.

      * Also an index equal to the length of the first sequence in an *added*
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
    that command, except that it may contain chunks of type __unchanged__
    too\.

    These new chunks describe the parts which are unchanged between the two
    sequences\. This means that the result of this command describes both the
    changed and unchanged parts of the two sequences in one structure\.

        sequence 1 = \{a b r a c a d a b r a\}
        lcs 1      =   \{1 2   4 5     8 9 10\}
        lcs 2      =   \{0 1   3 4     5 6 7\}
        sequence 2 =   \{b r i c a     b r a c\}

        Inversion/Merge  = \{\{deleted   \{0  0\} \{\-1 0\}\}
                            \{unchanged \{1  2\}  \{0 1\}\}
                            \{changed   \{3  3\}  \{2 2\}\}
                            \{unchanged \{4  5\}  \{3 4\}\}
                            \{deleted   \{6  7\}  \{4 5\}\}
                            \{unchanged \{8 10\}  \{5 7\}\}
                            \{added    \{10 11\}  \{8 8\}\}\}

  - <a name='6'></a>__::struct::list__ __lcsInvertMerge2__ *lcs1* *lcs2* *len1* *len2*

    Similar to __lcsInvertMerge__\. Instead of directly taking the result of
    a call to __longestCommonSubsequence__ this subcommand expects the
    indices for the two sequences in two separate lists\.








|
|
|
|

|
|
|
|
|
|
|







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
    that command, except that it may contain chunks of type __unchanged__
    too\.

    These new chunks describe the parts which are unchanged between the two
    sequences\. This means that the result of this command describes both the
    changed and unchanged parts of the two sequences in one structure\.

        sequence 1 = {a b r a c a d a b r a}
        lcs 1      =   {1 2   4 5     8 9 10}
        lcs 2      =   {0 1   3 4     5 6 7}
        sequence 2 =   {b r i c a     b r a c}

        Inversion/Merge  = {{deleted   {0  0} {-1 0}}
                            {unchanged {1  2}  {0 1}}
                            {changed   {3  3}  {2 2}}
                            {unchanged {4  5}  {3 4}}
                            {deleted   {6  7}  {4 5}}
                            {unchanged {8 10}  {5 7}}
                            {added    {10 11}  {8 8}}}

  - <a name='6'></a>__::struct::list__ __lcsInvertMerge2__ *lcs1* *lcs2* *len1* *len2*

    Similar to __lcsInvertMerge__\. Instead of directly taking the result of
    a call to __longestCommonSubsequence__ this subcommand expects the
    indices for the two sequences in two separate lists\.

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
    If there are more variables specified than there are elements in the
    *sequence* the empty string will be assigned to the superfluous variables\.

    If there are more elements in the *sequence* than variable names specified
    the subcommand returns a list containing the unassigned elements\. Else an
    empty list is returned\.

        tclsh> ::struct::list assign \{a b c d e\} foo bar
        c d e
        tclsh> set foo
        a
        tclsh> set bar
        b

  - <a name='10'></a>__::struct::list__ __flatten__ ?__\-full__? ?__\-\-__? *sequence*

    The subcommand takes a single *sequence* and returns a new sequence where
    one level of nesting was removed from the input sequence\. In other words,
    the sublists in the input sequence are replaced by their elements\.

    The subcommand will remove any nesting it finds if the option __\-full__
    is specified\.

        tclsh> ::struct::list flatten \{1 2 3 \{4 5\} \{6 7\} \{\{8 9\}\} 10\}
        1 2 3 4 5 6 7 \{8 9\} 10
        tclsh> ::struct::list flatten \-full \{1 2 3 \{4 5\} \{6 7\} \{\{8 9\}\} 10\}
        1 2 3 4 5 6 7 8 9 10

  - <a name='11'></a>__::struct::list__ __map__ *sequence* *cmdprefix*

    The subcommand takes a *sequence* to operate on and a command prefix
    \(*cmdprefix*\) specifying an operation, applies the command prefix to each
    element of the sequence and returns a sequence consisting of the results of
    that application\.

    The command prefix will be evaluated with a single word appended to it\. The
    evaluation takes place in the context of the caller of the subcommand\.

        tclsh> \# squaring all elements in a list

        tclsh> proc sqr \{x\} \{expr \{$x\*$x\}\}
        tclsh> ::struct::list map \{1 2 3 4 5\} sqr
        1 4 9 16 25

        tclsh> \# Retrieving the second column from a matrix
        tclsh> \# given as list of lists\.

        tclsh> proc projection \{n list\} \{::lindex $list $n\}
        tclsh> ::struct::list map \{\{a b c\} \{1 2 3\} \{d f g\}\} \{projection 1\}
        b 2 f

  - <a name='12'></a>__::struct::list__ __mapfor__ *var* *sequence* *script*

    The subcommand takes a *sequence* to operate on and a tcl *script*,
    applies the script to each element of the sequence and returns a sequence
    consisting of the results of that application\.

    The script will be evaluated as is, and has access to the current list
    element through the specified iteration variable *var*\. The evaluation
    takes place in the context of the caller of the subcommand\.

            tclsh> \# squaring all elements in a list

            tclsh> ::struct::list mapfor x \{1 2 3 4 5\} \{
        	expr \{$x \* $x\}
            \}

            1 4 9 16 25

            tclsh> \# Retrieving the second column from a matrix
            tclsh> \# given as list of lists\.

            tclsh> ::struct::list mapfor x \{\{a b c\} \{1 2 3\} \{d f g\}\} \{
        	lindex $x 1
            \}

            b 2 f

  - <a name='13'></a>__::struct::list__ __filter__ *sequence* *cmdprefix*

    The subcommand takes a *sequence* to operate on and a command prefix
    \(*cmdprefix*\) specifying an operation, applies the command prefix to each
    element of the sequence and returns a sequence consisting of all elements of
    the *sequence* for which the command prefix returned __true__\. In
    other words, this command filters out all elements of the input *sequence*
    which fail the test the *cmdprefix* represents, and returns the remaining
    elements\.

    The command prefix will be evaluated with a single word appended to it\. The
    evaluation takes place in the context of the caller of the subcommand\.

        tclsh> \# removing all odd numbers from the input

        tclsh> proc even \{x\} \{expr \{\($x % 2\) == 0\}\}
        tclsh> ::struct::list filter \{1 2 3 4 5\} even
        2 4

    *Note:* The __filter__ is a specialized application of __fold__
    where the result is extended with the current item or not, depending o nthe
    result of the test\.

  - <a name='14'></a>__::struct::list__ __filterfor__ *var* *sequence* *expr*

    The subcommand takes a *sequence* to operate on and a tcl expression
    \(*expr*\) specifying a condition, applies the conditionto each element of
    the sequence and returns a sequence consisting of all elements of the
    *sequence* for which the expression returned __true__\. In other words,
    this command filters out all elements of the input *sequence* which fail
    the test the condition *expr* represents, and returns the remaining
    elements\.

    The expression will be evaluated as is, and has access to the current list
    element through the specified iteration variable *var*\. The evaluation
    takes place in the context of the caller of the subcommand\.

        tclsh> \# removing all odd numbers from the input

        tclsh> ::struct::list filterfor x \{1 2 3 4 5\} \{\($x % 2\) == 0\}
        2 4

  - <a name='15'></a>__::struct::list__ __split__ *sequence* *cmdprefix* ?*passVar* *failVar*?

    This is a variant of method __filter__, see above\. Instead of returning
    just the elements passing the test we get lists of both passing and failing
    elements\.







|















|
|
|












|

|
|


|
|

|
|












|

|
|
<
>


|
|

|

<
>















|

|
|




















|

|







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
    If there are more variables specified than there are elements in the
    *sequence* the empty string will be assigned to the superfluous variables\.

    If there are more elements in the *sequence* than variable names specified
    the subcommand returns a list containing the unassigned elements\. Else an
    empty list is returned\.

        tclsh> ::struct::list assign {a b c d e} foo bar
        c d e
        tclsh> set foo
        a
        tclsh> set bar
        b

  - <a name='10'></a>__::struct::list__ __flatten__ ?__\-full__? ?__\-\-__? *sequence*

    The subcommand takes a single *sequence* and returns a new sequence where
    one level of nesting was removed from the input sequence\. In other words,
    the sublists in the input sequence are replaced by their elements\.

    The subcommand will remove any nesting it finds if the option __\-full__
    is specified\.

        tclsh> ::struct::list flatten {1 2 3 {4 5} {6 7} {{8 9}} 10}
        1 2 3 4 5 6 7 {8 9} 10
        tclsh> ::struct::list flatten -full {1 2 3 {4 5} {6 7} {{8 9}} 10}
        1 2 3 4 5 6 7 8 9 10

  - <a name='11'></a>__::struct::list__ __map__ *sequence* *cmdprefix*

    The subcommand takes a *sequence* to operate on and a command prefix
    \(*cmdprefix*\) specifying an operation, applies the command prefix to each
    element of the sequence and returns a sequence consisting of the results of
    that application\.

    The command prefix will be evaluated with a single word appended to it\. The
    evaluation takes place in the context of the caller of the subcommand\.

        tclsh> # squaring all elements in a list

        tclsh> proc sqr {x} {expr {$x*$x}}
        tclsh> ::struct::list map {1 2 3 4 5} sqr
        1 4 9 16 25

        tclsh> # Retrieving the second column from a matrix
        tclsh> # given as list of lists.

        tclsh> proc projection {n list} {::lindex $list $n}
        tclsh> ::struct::list map {{a b c} {1 2 3} {d f g}} {projection 1}
        b 2 f

  - <a name='12'></a>__::struct::list__ __mapfor__ *var* *sequence* *script*

    The subcommand takes a *sequence* to operate on and a tcl *script*,
    applies the script to each element of the sequence and returns a sequence
    consisting of the results of that application\.

    The script will be evaluated as is, and has access to the current list
    element through the specified iteration variable *var*\. The evaluation
    takes place in the context of the caller of the subcommand\.

            tclsh> # squaring all elements in a list

            tclsh> ::struct::list mapfor x {1 2 3 4 5} {
        	expr {$x * $x}

            }
            1 4 9 16 25

            tclsh> # Retrieving the second column from a matrix
            tclsh> # given as list of lists.

            tclsh> ::struct::list mapfor x {{a b c} {1 2 3} {d f g}} {
        	lindex $x 1

            }
            b 2 f

  - <a name='13'></a>__::struct::list__ __filter__ *sequence* *cmdprefix*

    The subcommand takes a *sequence* to operate on and a command prefix
    \(*cmdprefix*\) specifying an operation, applies the command prefix to each
    element of the sequence and returns a sequence consisting of all elements of
    the *sequence* for which the command prefix returned __true__\. In
    other words, this command filters out all elements of the input *sequence*
    which fail the test the *cmdprefix* represents, and returns the remaining
    elements\.

    The command prefix will be evaluated with a single word appended to it\. The
    evaluation takes place in the context of the caller of the subcommand\.

        tclsh> # removing all odd numbers from the input

        tclsh> proc even {x} {expr {($x % 2) == 0}}
        tclsh> ::struct::list filter {1 2 3 4 5} even
        2 4

    *Note:* The __filter__ is a specialized application of __fold__
    where the result is extended with the current item or not, depending o nthe
    result of the test\.

  - <a name='14'></a>__::struct::list__ __filterfor__ *var* *sequence* *expr*

    The subcommand takes a *sequence* to operate on and a tcl expression
    \(*expr*\) specifying a condition, applies the conditionto each element of
    the sequence and returns a sequence consisting of all elements of the
    *sequence* for which the expression returned __true__\. In other words,
    this command filters out all elements of the input *sequence* which fail
    the test the condition *expr* represents, and returns the remaining
    elements\.

    The expression will be evaluated as is, and has access to the current list
    element through the specified iteration variable *var*\. The evaluation
    takes place in the context of the caller of the subcommand\.

        tclsh> # removing all odd numbers from the input

        tclsh> ::struct::list filterfor x {1 2 3 4 5} {($x % 2) == 0}
        2 4

  - <a name='15'></a>__::struct::list__ __split__ *sequence* *cmdprefix* ?*passVar* *failVar*?

    This is a variant of method __filter__, see above\. Instead of returning
    just the elements passing the test we get lists of both passing and failing
    elements\.
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

      * __end__

        Application of the command to the result of the last call and the last
        element of the list\. The result of this call is returned as the result
        of the subcommand\.

        tclsh> \# summing the elements in a list\.
        tclsh> proc \+ \{a b\} \{expr \{$a \+ $b\}\}
        tclsh> ::struct::list fold \{1 2 3 4 5\} 0 \+
        15

  - <a name='17'></a>__::struct::list__ __shift__ *listvar*

    The subcommand takes the list contained in the variable named by *listvar*
    and shifts it down one element\. After the call *listvar* will contain a
    list containing the second to last elements of the input list\. The first







|
|
|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

      * __end__

        Application of the command to the result of the last call and the last
        element of the list\. The result of this call is returned as the result
        of the subcommand\.

        tclsh> # summing the elements in a list.
        tclsh> proc + {a b} {expr {$a + $b}}
        tclsh> ::struct::list fold {1 2 3 4 5} 0 +
        15

  - <a name='17'></a>__::struct::list__ __shift__ *listvar*

    The subcommand takes the list contained in the variable named by *listvar*
    and shifts it down one element\. After the call *listvar* will contain a
    list containing the second to last elements of the input list\. The first
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
    \.\.\.__ is identical to __list arg \.\.\.__, though the *arg* is required
    with __repeat__\.

    *Examples:*

        tclsh> ::struct::list repeat 3 a
        a a a
        tclsh> ::struct::list repeat 3 \[::struct::list repeat 3 0\]
        \{0 0 0\} \{0 0 0\} \{0 0 0\}
        tclsh> ::struct::list repeat 3 a b c
        a b c a b c a b c
        tclsh> ::struct::list repeat 3 \[::struct::list repeat 2 a\] b c
        \{a a\} b c \{a a\} b c \{a a\} b c

  - <a name='21'></a>__::struct::list__ __repeatn__ *value* *size*\.\.\.

    The subcommand creates a \(nested\) list containing the *value* in all
    positions\. The exact size and degree of nesting is determined by the
    *size* arguments, all of which have to be integer numbers greater than or
    equal to zero\.







|
|


|
|







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
    \.\.\.__ is identical to __list arg \.\.\.__, though the *arg* is required
    with __repeat__\.

    *Examples:*

        tclsh> ::struct::list repeat 3 a
        a a a
        tclsh> ::struct::list repeat 3 [::struct::list repeat 3 0]
        {0 0 0} {0 0 0} {0 0 0}
        tclsh> ::struct::list repeat 3 a b c
        a b c a b c a b c
        tclsh> ::struct::list repeat 3 [::struct::list repeat 2 a] b c
        {a a} b c {a a} b c {a a} b c

  - <a name='21'></a>__::struct::list__ __repeatn__ *value* *size*\.\.\.

    The subcommand creates a \(nested\) list containing the *value* in all
    positions\. The exact size and degree of nesting is determined by the
    *size* arguments, all of which have to be integer numbers greater than or
    equal to zero\.
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
    of the length specified by the last *size* argument given to it\. The
    elements of that list are defined as the result of __Repeat__ for the
    same arguments, but with the last *size* value removed\.

    An empty list will be returned if no *size* arguments are present\.

        tclsh> ::struct::list repeatn  0 3 4
        \{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}
        tclsh> ::struct::list repeatn  0 \{3 4\}
        \{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}
        tclsh> ::struct::list repeatn  0 \{3 4 5\}
        \{\{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}\} \{\{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}\} \{\{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}\} \{\{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}\} \{\{0 0 0\} \{0 0 0\} \{0 0 0\} \{0 0 0\}\}

  - <a name='22'></a>__::struct::list__ __dbJoin__ ?__\-inner__&#124;__\-left__&#124;__\-right__&#124;__\-full__? ?__\-keys__ *varname*? \{*keycol* *table*\}\.\.\.

    The method performs a table join according to relational algebra\. The
    execution of any of the possible outer join operation is triggered by the
    presence of either option __\-left__, __\-right__, or __\-full__\.
    If none of these options is present a regular inner join will be performed\.







|
|
|
|
|







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
    of the length specified by the last *size* argument given to it\. The
    elements of that list are defined as the result of __Repeat__ for the
    same arguments, but with the last *size* value removed\.

    An empty list will be returned if no *size* arguments are present\.

        tclsh> ::struct::list repeatn  0 3 4
        {0 0 0} {0 0 0} {0 0 0} {0 0 0}
        tclsh> ::struct::list repeatn  0 {3 4}
        {0 0 0} {0 0 0} {0 0 0} {0 0 0}
        tclsh> ::struct::list repeatn  0 {3 4 5}
        {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}}

  - <a name='22'></a>__::struct::list__ __dbJoin__ ?__\-inner__&#124;__\-left__&#124;__\-right__&#124;__\-full__? ?__\-keys__ *varname*? \{*keycol* *table*\}\.\.\.

    The method performs a table join according to relational algebra\. The
    execution of any of the possible outer join operation is triggered by the
    presence of either option __\-left__, __\-right__, or __\-full__\.
    If none of these options is present a regular inner join will be performed\.
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
  1. The full outer join combines both left and right outer join\. In other
     words, the additional rows are as defined for left outer join, and right
     outer join, combined\.

We extend all the joins from two to __n__ tables \(__n__ > 2\) by
executing

    \(\.\.\.\(\(table1 join table2\) join table3\) \.\.\.\) join tableN

Examples for all the joins:

    Inner Join

    \{0 foo\}              \{0 bagel\}    \{0 foo   0 bagel\}
    \{1 snarf\} inner join \{1 snatz\}  = \{1 snarf 1 snatz\}
    \{2 blue\}             \{3 driver\}

    Left Outer Join

    \{0 foo\}                   \{0 bagel\}    \{0 foo   0 bagel\}
    \{1 snarf\} left outer join \{1 snatz\}  = \{1 snarf 1 snatz\}
    \{2 blue\}                  \{3 driver\}   \{2 blue  \{\} \{\}\}

    Right Outer Join

    \{0 foo\}                    \{0 bagel\}    \{0 foo   0 bagel\}
    \{1 snarf\} right outer join \{1 snatz\}  = \{1 snarf 1 snatz\}
    \{2 blue\}                   \{3 driver\}   \{\{\} \{\}   3 driver\}

    Full Outer Join

    \{0 foo\}                   \{0 bagel\}    \{0 foo   0 bagel\}
    \{1 snarf\} full outer join \{1 snatz\}  = \{1 snarf 1 snatz\}
    \{2 blue\}                  \{3 driver\}   \{2 blue  \{\} \{\}\}
                                           \{\{\} \{\}   3 driver\}

# <a name='section5'></a>REFERENCES

  1. J\. W\. Hunt and M\. D\. McIlroy, "An algorithm for differential file
     comparison," Comp\. Sci\. Tech\. Rep\. \#41, Bell Telephone Laboratories \(1976\)\.
     Available on the Web at the second author's personal site:
     [http://www\.cs\.dartmouth\.edu/~doug/](http://www\.cs\.dartmouth\.edu/~doug/)







|





|
|
|



|
|
|



|
|
|



|
|
|
|







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
  1. The full outer join combines both left and right outer join\. In other
     words, the additional rows are as defined for left outer join, and right
     outer join, combined\.

We extend all the joins from two to __n__ tables \(__n__ > 2\) by
executing

    (...((table1 join table2) join table3) ...) join tableN

Examples for all the joins:

    Inner Join

    {0 foo}              {0 bagel}    {0 foo   0 bagel}
    {1 snarf} inner join {1 snatz}  = {1 snarf 1 snatz}
    {2 blue}             {3 driver}

    Left Outer Join

    {0 foo}                   {0 bagel}    {0 foo   0 bagel}
    {1 snarf} left outer join {1 snatz}  = {1 snarf 1 snatz}
    {2 blue}                  {3 driver}   {2 blue  {} {}}

    Right Outer Join

    {0 foo}                    {0 bagel}    {0 foo   0 bagel}
    {1 snarf} right outer join {1 snatz}  = {1 snarf 1 snatz}
    {2 blue}                   {3 driver}   {{} {}   3 driver}

    Full Outer Join

    {0 foo}                   {0 bagel}    {0 foo   0 bagel}
    {1 snarf} full outer join {1 snatz}  = {1 snarf 1 snatz}
    {2 blue}                  {3 driver}   {2 blue  {} {}}
                                           {{} {}   3 driver}

# <a name='section5'></a>REFERENCES

  1. J\. W\. Hunt and M\. D\. McIlroy, "An algorithm for differential file
     comparison," Comp\. Sci\. Tech\. Rep\. \#41, Bell Telephone Laboratories \(1976\)\.
     Available on the Web at the second author's personal site:
     [http://www\.cs\.dartmouth\.edu/~doug/](http://www\.cs\.dartmouth\.edu/~doug/)
Changes to embedded/md/tcllib/files/modules/struct/struct_tree.md.
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
    This is the assignment operator for tree objects\. It copies the tree
    contained in the tree object *sourcetree* over the tree data in
    *treeName*\. The old contents of *treeName* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *treeName* __deserialize__ \[*sourcetree* __serialize__\]

  - <a name='5'></a>*treeName* __\-\->__ *desttree*

    This is the reverse assignment operator for tree objects\. It copies the tree
    contained in the tree object *treeName* over the tree data in the object
    *desttree*\. The old contents of *desttree* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *desttree* __deserialize__ \[*treeName* __serialize__\]

  - <a name='6'></a>*treeName* __ancestors__ *node*

    This method extends the method __parent__ and returns a list containing
    all ancestor nodes to the specified *node*\. The immediate ancestor, in
    other words, parent node, is the first element in that list, its parent the
    second element, and so on until the root node is reached, making it the last







|










|







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
    This is the assignment operator for tree objects\. It copies the tree
    contained in the tree object *sourcetree* over the tree data in
    *treeName*\. The old contents of *treeName* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *treeName* __deserialize__ [*sourcetree* __serialize__]

  - <a name='5'></a>*treeName* __\-\->__ *desttree*

    This is the reverse assignment operator for tree objects\. It copies the tree
    contained in the tree object *treeName* over the tree data in the object
    *desttree*\. The old contents of *desttree* are deleted by this
    operation\.

    This operation is in effect equivalent to

        *desttree* __deserialize__ [*treeName* __serialize__]

  - <a name='6'></a>*treeName* __ancestors__ *node*

    This method extends the method __parent__ and returns a list containing
    all ancestor nodes to the specified *node*\. The immediate ancestor, in
    other words, parent node, is the first element in that list, its parent the
    second element, and so on until the root node is reached, making it the last
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
            mytree insert root end 1
            mytree insert root end 2
            mytree insert 0    end 3
            mytree insert 0    end 4
            mytree insert 4    end 5 ; mytree set 5 volume 50
            mytree insert 4    end 6

            proc vol \{t n\} \{
        	$t keyexists $n volume
            \}

            proc vgt40 \{t n\} \{
        	if \{\!\[$t keyexists $n volume\]\} \{return 0\}
        	expr \{\[$t get $n volume\] > 40\}
            \}


            tclsh> lsort \[mytree children \-all root filter vol\]
            0 5

            tclsh> lsort \[mytree children \-all root filter vgt40\]
            5

            tclsh> lsort \[mytree children root filter vol\]
            0

            tclsh> puts \(\[lsort \[mytree children root filter vgt40\]\]\)
            \(\)

  - <a name='13'></a>*treeName* __cut__ *node*

    Removes the node specified by *node* from the tree, but not its children\.
    The children of *node* are made children of the parent of the *node*, at
    the index at which *node* was located\.








|

<
>
|
|
|
<
|
>
|


|


|


|
|







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
            mytree insert root end 1
            mytree insert root end 2
            mytree insert 0    end 3
            mytree insert 0    end 4
            mytree insert 4    end 5 ; mytree set 5 volume 50
            mytree insert 4    end 6

            proc vol {t n} {
        	$t keyexists $n volume

            }
            proc vgt40 {t n} {
        	if {![$t keyexists $n volume]} {return 0}
        	expr {[$t get $n volume] > 40}

            }

            tclsh> lsort [mytree children -all root filter vol]
            0 5

            tclsh> lsort [mytree children -all root filter vgt40]
            5

            tclsh> lsort [mytree children root filter vol]
            0

            tclsh> puts ([lsort [mytree children root filter vgt40]])
            ()

  - <a name='13'></a>*treeName* __cut__ *node*

    Removes the node specified by *node* from the tree, but not its children\.
    The children of *node* are made children of the parent of the *node*, at
    the index at which *node* was located\.

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
    rely on for the structure of the tree is that the root node is signaled by
    the empty string for the parent reference, that all other nodes refer to
    their parent through the index in the list, and that children occur in the
    same order as in their parent\.

        A possible serialization for the tree structure

                    \+\- d
              \+\- a \-\+
        root \-\+\- b  \+\- e
              \+\- c
        is

        \{root \{\} \{\} a 0 \{\} d 3 \{\} e 3 \{\} b 0 \{\} c 0 \{\}\}

        The above assumes that none of the nodes have attributes\.

  - <a name='38'></a>*treeName* __set__ *node* *key* ?*value*?

    Set or get one of the keyed values associated with a node\. A node may have
    any number of keyed values associated with it\. If *value* is not
    specified, this command returns the current value assigned to the key; if
    *value* is specified, this command assigns that value to the key, and







|
|
|
|


|

|







479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
    rely on for the structure of the tree is that the root node is signaled by
    the empty string for the parent reference, that all other nodes refer to
    their parent through the index in the list, and that children occur in the
    same order as in their parent\.

        A possible serialization for the tree structure

                    +- d
              +- a -+
        root -+- b  +- e
              +- c
        is

        {root {} {} a 0 {} d 3 {} e 3 {} b 0 {} c 0 {}}

        The above assumes that none of the nodes have attributes.

  - <a name='38'></a>*treeName* __set__ *node* *key* ?*value*?

    Set or get one of the keyed values associated with a node\. A node may have
    any number of keyed values associated with it\. If *value* is not
    specified, this command returns the current value assigned to the key; if
    *value* is specified, this command assigns that value to the key, and
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
    visited\), or upon leaving will have undefined results\. They may succeed,
    error out, silently compute the wrong result, or anything in between\.

    At last a small table showing the relationship between the various options
    and the possible actions\.

        order       type    actions         notes
        \-\-\-\-\-       \-\-\-\-    \-\-\-\-\-           \-\-\-\-\-
        pre         dfs     enter           parent before children
        post        dfs     leave           parent after children
        in          dfs     visit           parent between first and second child\.
        both        dfs     enter, leave    parent before and after children
        \-\-\-\-\-       \-\-\-\-    \-\-\-\-\-           \-\-\-\-\-
        pre         bfs     enter           parent before children
        post        bfs     leave           parent after children
        in          bfs             \-\- illegal \-\-
        both        bfs     enter, leave    parent before and after children
        \-\-\-\-\-       \-\-\-\-    \-\-\-\-\-           \-\-\-\-\-

    Note the command __::struct::tree::prune__\. This command can be used in
    the walk script to force the command to ignore the children of the node we
    are currently at\. It will throw an error if the order of traversal is either
    __post__ or __in__ as these modes visit the children before their
    parent, making pruning non\-sensical\.








|


|

|


|

|







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
    visited\), or upon leaving will have undefined results\. They may succeed,
    error out, silently compute the wrong result, or anything in between\.

    At last a small table showing the relationship between the various options
    and the possible actions\.

        order       type    actions         notes
        -----       ----    -----           -----
        pre         dfs     enter           parent before children
        post        dfs     leave           parent after children
        in          dfs     visit           parent between first and second child.
        both        dfs     enter, leave    parent before and after children
        -----       ----    -----           -----
        pre         bfs     enter           parent before children
        post        bfs     leave           parent after children
        in          bfs             -- illegal --
        both        bfs     enter, leave    parent before and after children
        -----       ----    -----           -----

    Note the command __::struct::tree::prune__\. This command can be used in
    the walk script to force the command to ignore the children of the node we
    are currently at\. It will throw an error if the order of traversal is either
    __post__ or __in__ as these modes visit the children before their
    parent, making pruning non\-sensical\.

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
     Another extension is the ability to look not only at the immediate children
     of the node, but the whole tree below it\.

# <a name='section3'></a>EXAMPLES

The following example demonstrates the creation of new nodes:

    mytree insert root end 0   ; \# Create node 0, as child of the root
    mytree insert root end 1 2 ; \# Ditto nodes 1 & 2
    mytree insert 0    end 3   ; \# Now create node 3 as child of node 0
    mytree insert 0    end     ; \# Create another child of 0, with a
    \#                              generated name\. The name is returned
    \#                              as the result of the command\.

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: tree* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
     Another extension is the ability to look not only at the immediate children
     of the node, but the whole tree below it\.

# <a name='section3'></a>EXAMPLES

The following example demonstrates the creation of new nodes:

    mytree insert root end 0   ; # Create node 0, as child of the root
    mytree insert root end 1 2 ; # Ditto nodes 1 & 2
    mytree insert 0    end 3   ; # Now create node 3 as child of node 0
    mytree insert 0    end     ; # Create another child of 0, with a
    #                              generated name. The name is returned
    #                              as the result of the command.

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *struct :: tree* of the
[Tcllib Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report
any ideas for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/tar/tar.md.
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
    Returns a nested dict containing information on the named ?file? in
    *tarball*, or all files if none is specified\. The top level are pairs of
    filename and info\. The info is a dict with the keys "__mode__
    __uid__ __gid__ __size__ __mtime__ __type__
    __linkname__ __uname__ __gname__ __devmajor__
    __devminor__"

        % ::tar::stat tarball\.tar
        foo\.jpg \{mode 0644 uid 1000 gid 0 size 7580 mtime 811903867 type file linkname \{\} uname user gname wheel devmajor 0 devminor 0\}

    If the option __\-chan__ is present *tarball* is interpreted as an open
    channel\. It is assumed that the channel was opened for reading, and
    configured for binary input\. The command will *not* close the channel\.

  - <a name='3'></a>__::tar::untar__ *tarball* *args*








|
|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
    Returns a nested dict containing information on the named ?file? in
    *tarball*, or all files if none is specified\. The top level are pairs of
    filename and info\. The info is a dict with the keys "__mode__
    __uid__ __gid__ __size__ __mtime__ __type__
    __linkname__ __uname__ __gname__ __devmajor__
    __devminor__"

        % ::tar::stat tarball.tar
        foo.jpg {mode 0644 uid 1000 gid 0 size 7580 mtime 811903867 type file linkname {} uname user gname wheel devmajor 0 devminor 0}

    If the option __\-chan__ is present *tarball* is interpreted as an open
    channel\. It is assumed that the channel was opened for reading, and
    configured for binary input\. The command will *not* close the channel\.

  - <a name='3'></a>__::tar::untar__ *tarball* *args*

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

      * __\-chan__

        If this option is present *tarball* is interpreted as an open channel\.
        It is assumed that the channel was opened for reading, and configured
        for binary input\. The command will *not* close the channel\.

        % foreach \{file size\} \[::tar::untar tarball\.tar \-glob \*\.jpg\] \{
        puts "Extracted $file \($size bytes\)"
        \}


  - <a name='4'></a>__::tar::get__ *tarball* *fileName* ?__\-chan__?

    Returns the contents of *fileName* from the *tarball*\.

        % set readme \[::tar::get tarball\.tar doc/README\] \{
        % puts $readme
        \}


    If the option __\-chan__ is present *tarball* is interpreted as an open
    channel\. It is assumed that the channel was opened for reading, and
    configured for binary input\. The command will *not* close the channel\.

    An error is thrown when *fileName* is not found in the tar archive\.








|
|
<
>





|

<
>







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

      * __\-chan__

        If this option is present *tarball* is interpreted as an open channel\.
        It is assumed that the channel was opened for reading, and configured
        for binary input\. The command will *not* close the channel\.

        % foreach {file size} [::tar::untar tarball.tar -glob *.jpg] {
        puts "Extracted $file ($size bytes)"

        }

  - <a name='4'></a>__::tar::get__ *tarball* *fileName* ?__\-chan__?

    Returns the contents of *fileName* from the *tarball*\.

        % set readme [::tar::get tarball.tar doc/README] {
        % puts $readme

        }

    If the option __\-chan__ is present *tarball* is interpreted as an open
    channel\. It is assumed that the channel was opened for reading, and
    configured for binary input\. The command will *not* close the channel\.

    An error is thrown when *fileName* is not found in the tar archive\.

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

      * __\-chan__

        If this option is present *tarball* is interpreted as an open channel\.
        It is assumed that the channel was opened for writing, and configured
        for binary output\. The command will *not* close the channel\.

        % ::tar::create new\.tar \[glob \-nocomplain file\*\]
        % ::tar::contents new\.tar
        file1 file2 file3

  - <a name='6'></a>__::tar::add__ *tarball* *files* *args*

    Appends *files* to the end of the existing *tarball*\. *files* must be
    specified as a single argument which is a proper list of filenames\.








|
|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

      * __\-chan__

        If this option is present *tarball* is interpreted as an open channel\.
        It is assumed that the channel was opened for writing, and configured
        for binary output\. The command will *not* close the channel\.

        % ::tar::create new.tar [glob -nocomplain file*]
        % ::tar::contents new.tar
        file1 file2 file3

  - <a name='6'></a>__::tar::add__ *tarball* *files* *args*

    Appends *files* to the end of the existing *tarball*\. *files* must be
    specified as a single argument which is a proper list of filenames\.

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

  - <a name='7'></a>__::tar::remove__ *tarball* *files*

    Removes *files* from the *tarball*\. No error will result if the file
    does not exist in the tarball\. Directory write permission and free disk
    space equivalent to at least the size of the tarball will be needed\.

        % ::tar::remove new\.tar \{file2 file3\}
        % ::tar::contents new\.tar
        file3

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *tar* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas







|
|







179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

  - <a name='7'></a>__::tar::remove__ *tarball* *files*

    Removes *files* from the *tarball*\. No error will result if the file
    does not exist in the tarball\. Directory write permission and free disk
    space equivalent to at least the size of the tarball will be needed\.

        % ::tar::remove new.tar {file2 file3}
        % ::tar::contents new.tar
        file3

# <a name='section2'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *tar* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
Changes to embedded/md/tcllib/files/modules/tepam/tepam_argument_dialogbox.md.
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
    been acknowledged \(via the *OK* button\) and validated by a data checker\.
    If the entered data have been rejected \(via the *Cancel* button\) the
    __argument\_dialogbox__ returns __cancel__\.

    A small example illustrates how the __argument\_dialogbox__ can be
    employed:

        set DialogResult \[__tepam::argument\_dialogbox__ \\
           __\-title__ "Itinerary selection" \\
           __\-file__ \{*\-label "Itinerary report" \-variable report\_file*\} \\
           __\-frame__ \{*\-label "Itinerary start"*\} \\
              __\-comment__ \{*\-text "Specify your itinerary start location"*\} \\
              __\-entry__ \{*\-label "City" \-variable start\_city \-type string*\} \\
              __\-entry__ \{*\-label "Street" \-variable start\_street \-type string \-optional 1*\} \\
              __\-entry__ \{*\-label "Street number" \-variable start\_street\_nbr \-type integer \-optional 1*\} \\
           __\-frame__ \{*\-label "Itinerary destination"*\} \\
              __\-comment__ \{*\-text "Specify your itinerary destination"*\} \\
              __\-entry__ \{*\-label "City" \-variable dest\_city \-type string*\} \\
              __\-entry__ \{*\-label "Street" \-variable dest\_street \-type string \-optional 1*\} \\
              __\-entry__ \{*\-label "Street number" \-variable dest\_street\_nbr \-type integer \-optional 1*\} \\
           __\-frame__ \{\} \\
           __\-checkbutton__ \{*\-label "Don't use highways" \-variable no\_highway*\}

    \] This example opens a dialog box that has the title *Itinerary
    selection*\. A first entry widget in this box allows selecting a report
    file\. It follows two frames to define respectively an itinerary start and
    end location\. Each of these locations that are described with a comment has
    three entry widgets to specify respectively the city, street and the street
    number\. Bellow the second frame there is a check button that allows
    specifying if eventual highways should be ignored\.

  - <a name='2'></a>__tepam::argument\_dialogbox__ \{*item\_name item\_attributes ?item\_name item\_attributes? ?\.\.\.?*\}

    Sometimes it is simpler to provide all the data entry item definitions in
    form of a single list to __argument\_dialogbox__, and not as individual
    arguments\. The second format that is supported by __argument\_dialogbox__
    corresponds exactly to the first one, except that all item definitions are
    packed into a single list that is provided to __argument\_dialogbox__\.
    The previous example can therefore also be written in the following way:

        set DialogResult \[__tepam::argument\_dialogbox \{__
           __\-title__ "Itinerary selection"
           __\-file__ \{*\-label "Itinerary report" \-variable report\_file*\}
           \.\.\.
           __\-checkbutton__ \{*\-label "Don't use highways" \-variable no\_highway*\}

    __\}__\]

The commands __argument\_dialogbox__ as well as
__[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ are exported from the
namespace __tepam__\. To use these commands without the __tepam::__
namespace prefix, it is sufficient to import them into the main namespace:

    __namespace import tepam::\*__

    set DialogResult \[__argument\_dialogbox__ \\
       \-title "Itinerary selection"
       \.\.\.

The following subsections explain the different argument item types that are
accepted by the __argument\_dialogbox__, classified into three groups\. The
first data entry item definition format will be used in the remaining document,
knowing that this format can always be transformed into the second format by
putting all arguments into a single list that is then provided to
__argument\_dialogbox__\.

## <a name='subsection1'></a>Context Definition Items

The first item group allows specifying some context aspects of an argument
dialog box\. These items are taking a simple character string as item attribute:

    tepam::argument\_dialogbox \\
       __\-<argument\_name>__ *string* \\
       \.\.\.

The following items are classified into this group:

  - \-title *string*

    The dialog box window title which is by default *Dialog* can be changed
    with the *\-title* item:

    tepam::argument\_dialogbox \\
       __\-title__ "System configuration" \\
       \.\.\.

  - \-window *string*

    The argument dialog box uses by default *\.dialog* as dialog top level
    window\. This path can be changed with the *\-window* item:

    tepam::argument\_dialogbox \\
       __\-window__ \.dialog \\
       \.\.\.

  - \-parent *string*

    By defining a parent window, the argument dialog box will be displayed
    beside this one\. Without explicit parent window definition, the top\-level
    window will be considered as parent window\.

    tepam::argument\_dialogbox \\
       __\-parent__ \.my\_appl \\
       \.\.\.

  - \-context *string*

    If a context is defined the dialog box state, e\.g\. the entered data as well
    as the window size and position, is restored the next time the argument
    dialog box is called\. The assignment of a context allows saving the dialog
    box state in its context to distinguish between different usages of the
    argument dialog box\.

    tepam::argument\_dialogbox \\
       __\-context__ destination\_definitions \\
       \.\.\.

## <a name='subsection2'></a>Formatting and Display Options

Especially for big, complex forms it becomes important that the different data
entry widgets are graphically well organized and commented to provide an
immediate and clear overview to the user\. A couple of items allow structuring
and commenting the dialog boxes\.

The items of this classification group require as item attributes a definition
list, which contains itself attribute name and value pairs:

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-<argument\_name>__ \{ *
          ?\-<attribute\_name> <attribute\_value>?
          ?\-<attribute\_name> <attribute\_value>?
          ?\.\.\.?*
       \}

       \.\.\.

The following items are classified into this group:

  - \-frame *list*

    The *\-frame* item allows packing all following entry widgets into a
    labeled frame, until a next frame item is defined or until the last entry
    widget has been defined\. It recognizes the following attributes inside the
    item attribute list:

      * \-label *string*

        An optional frame label can be specified with the *\-label* statement\.

    Example:

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-frame__ \{*\-label "Destination address"*\}
       \.\.\.

    To close an open frame without opening a new one, an empty list has to be
    provided to the *\-frame* statement\.

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-frame__ \{\}
       \.\.\.

  - \-sep \[const \{\{\}\}\]

    Entry widgets can be separated with the *\-sep* statement which doesn't
    require additional definitions\. The related definition list has to exist,
    but its content is ignored\.

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-sep__ \{\}
       \.\.\.

  - \-comment *string*

    Comments and descriptions can be added with the *\-text* attribute of the
    *\-comment* item\. Please note that each entry widget itself can also
    contain a *\-text* attribute for comments and descriptions\. But the
    *\-comment* item allows for example adding a description between two
    frames\.

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-comment__ \{*\-text "Specify bellow the destination address"*\}
       \.\.\.

  - \-yscroll __0__&#124;__1__&#124;__auto__

    This attribute allows controlling an eventual vertical scrollbar\. Setting it
    to __0__ will permanently disable the scrollbar, setting it to __1__
    will enable it\. By default it is set to __auto__\. The scrollbar is
    enabled in this mode only if the vertical data entry form size exceeds 66%
    of the screen height\.

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-yscroll__ __auto__
       \.\.\.

## <a name='subsection3'></a>Global Custom Data Validation

This item group allows specifying global custom checks to validate the entered
data\.

  - \-validatecommand *script*

    Custom data checks can be performed via validation commands that are defined
    with the *\-validatecommand* item\. Example:

    tepam::argument\_dialogbox \\
       \-entry \{\-label "Your comment" \-variable YourCom\} \\
       __\-validatecommand__ \{IllegalWordDetector $YourCom\}

    The validation command is executed in the context of the calling procedure,
    once all the basic data checks have been performed and data variables are
    assigned\. All data is accessed via the data variables\. Note that there is
    also an entry widget specific attribute *\-validatecommand* that allows
    declaring custom checks for specific data entries\.








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


















|
|
|
|
|








|

|
|
|













|
|
|








|
|
|






|
|
|







|
|
|









|
|
|











|
|
|
|
|
|
<
>
|
















|
|
|
|




|
|
|
|







|
|
|
|









|
|
|
|









|
|
|
|











|
|
|







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
    been acknowledged \(via the *OK* button\) and validated by a data checker\.
    If the entered data have been rejected \(via the *Cancel* button\) the
    __argument\_dialogbox__ returns __cancel__\.

    A small example illustrates how the __argument\_dialogbox__ can be
    employed:

        set DialogResult [__tepam::argument_dialogbox__ \
           __-title__ "Itinerary selection" \
           __-file__ {*-label "Itinerary report" -variable report_file*} \
           __-frame__ {*-label "Itinerary start"*} \
              __-comment__ {*-text "Specify your itinerary start location"*} \
              __-entry__ {*-label "City" -variable start_city -type string*} \
              __-entry__ {*-label "Street" -variable start_street -type string -optional 1*} \
              __-entry__ {*-label "Street number" -variable start_street_nbr -type integer -optional 1*} \
           __-frame__ {*-label "Itinerary destination"*} \
              __-comment__ {*-text "Specify your itinerary destination"*} \
              __-entry__ {*-label "City" -variable dest_city -type string*} \
              __-entry__ {*-label "Street" -variable dest_street -type string -optional 1*} \
              __-entry__ {*-label "Street number" -variable dest_street_nbr -type integer -optional 1*} \
           __-frame__ {} \
           __-checkbutton__ {*-label "Don't use highways" -variable no_highway*}

    \] This example opens a dialog box that has the title *Itinerary
    selection*\. A first entry widget in this box allows selecting a report
    file\. It follows two frames to define respectively an itinerary start and
    end location\. Each of these locations that are described with a comment has
    three entry widgets to specify respectively the city, street and the street
    number\. Bellow the second frame there is a check button that allows
    specifying if eventual highways should be ignored\.

  - <a name='2'></a>__tepam::argument\_dialogbox__ \{*item\_name item\_attributes ?item\_name item\_attributes? ?\.\.\.?*\}

    Sometimes it is simpler to provide all the data entry item definitions in
    form of a single list to __argument\_dialogbox__, and not as individual
    arguments\. The second format that is supported by __argument\_dialogbox__
    corresponds exactly to the first one, except that all item definitions are
    packed into a single list that is provided to __argument\_dialogbox__\.
    The previous example can therefore also be written in the following way:

        set DialogResult [__tepam::argument_dialogbox {__
           __-title__ "Itinerary selection"
           __-file__ {*-label "Itinerary report" -variable report_file*}
           ...
           __-checkbutton__ {*-label "Don't use highways" -variable no_highway*}

    __\}__\]

The commands __argument\_dialogbox__ as well as
__[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ are exported from the
namespace __tepam__\. To use these commands without the __tepam::__
namespace prefix, it is sufficient to import them into the main namespace:

    __namespace import tepam::*__

    set DialogResult [__argument_dialogbox__ \
       -title "Itinerary selection"
       ...

The following subsections explain the different argument item types that are
accepted by the __argument\_dialogbox__, classified into three groups\. The
first data entry item definition format will be used in the remaining document,
knowing that this format can always be transformed into the second format by
putting all arguments into a single list that is then provided to
__argument\_dialogbox__\.

## <a name='subsection1'></a>Context Definition Items

The first item group allows specifying some context aspects of an argument
dialog box\. These items are taking a simple character string as item attribute:

    tepam::argument_dialogbox \
       __-<argument_name>__ *string* \
       ...

The following items are classified into this group:

  - \-title *string*

    The dialog box window title which is by default *Dialog* can be changed
    with the *\-title* item:

    tepam::argument_dialogbox \
       __-title__ "System configuration" \
       ...

  - \-window *string*

    The argument dialog box uses by default *\.dialog* as dialog top level
    window\. This path can be changed with the *\-window* item:

    tepam::argument_dialogbox \
       __-window__ .dialog \
       ...

  - \-parent *string*

    By defining a parent window, the argument dialog box will be displayed
    beside this one\. Without explicit parent window definition, the top\-level
    window will be considered as parent window\.

    tepam::argument_dialogbox \
       __-parent__ .my_appl \
       ...

  - \-context *string*

    If a context is defined the dialog box state, e\.g\. the entered data as well
    as the window size and position, is restored the next time the argument
    dialog box is called\. The assignment of a context allows saving the dialog
    box state in its context to distinguish between different usages of the
    argument dialog box\.

    tepam::argument_dialogbox \
       __-context__ destination_definitions \
       ...

## <a name='subsection2'></a>Formatting and Display Options

Especially for big, complex forms it becomes important that the different data
entry widgets are graphically well organized and commented to provide an
immediate and clear overview to the user\. A couple of items allow structuring
and commenting the dialog boxes\.

The items of this classification group require as item attributes a definition
list, which contains itself attribute name and value pairs:

    tepam::argument_dialogbox \
       ...
       __-<argument_name>__ { *
          ?-<attribute_name> <attribute_value>?
          ?-<attribute_name> <attribute_value>?
          ?...?*

       }
       ...

The following items are classified into this group:

  - \-frame *list*

    The *\-frame* item allows packing all following entry widgets into a
    labeled frame, until a next frame item is defined or until the last entry
    widget has been defined\. It recognizes the following attributes inside the
    item attribute list:

      * \-label *string*

        An optional frame label can be specified with the *\-label* statement\.

    Example:

    tepam::argument_dialogbox \
       ...
       __-frame__ {*-label "Destination address"*}
       ...

    To close an open frame without opening a new one, an empty list has to be
    provided to the *\-frame* statement\.

    tepam::argument_dialogbox \
       ...
       __-frame__ {}
       ...

  - \-sep \[const \{\{\}\}\]

    Entry widgets can be separated with the *\-sep* statement which doesn't
    require additional definitions\. The related definition list has to exist,
    but its content is ignored\.

    tepam::argument_dialogbox \
       ...
       __-sep__ {}
       ...

  - \-comment *string*

    Comments and descriptions can be added with the *\-text* attribute of the
    *\-comment* item\. Please note that each entry widget itself can also
    contain a *\-text* attribute for comments and descriptions\. But the
    *\-comment* item allows for example adding a description between two
    frames\.

    tepam::argument_dialogbox \
       ...
       __-comment__ {*-text "Specify bellow the destination address"*}
       ...

  - \-yscroll __0__&#124;__1__&#124;__auto__

    This attribute allows controlling an eventual vertical scrollbar\. Setting it
    to __0__ will permanently disable the scrollbar, setting it to __1__
    will enable it\. By default it is set to __auto__\. The scrollbar is
    enabled in this mode only if the vertical data entry form size exceeds 66%
    of the screen height\.

    tepam::argument_dialogbox \
       ...
       __-yscroll__ __auto__
       ...

## <a name='subsection3'></a>Global Custom Data Validation

This item group allows specifying global custom checks to validate the entered
data\.

  - \-validatecommand *script*

    Custom data checks can be performed via validation commands that are defined
    with the *\-validatecommand* item\. Example:

    tepam::argument_dialogbox \
       -entry {-label "Your comment" -variable YourCom} \
       __-validatecommand__ {IllegalWordDetector $YourCom}

    The validation command is executed in the context of the calling procedure,
    once all the basic data checks have been performed and data variables are
    assigned\. All data is accessed via the data variables\. Note that there is
    also an entry widget specific attribute *\-validatecommand* that allows
    declaring custom checks for specific data entries\.

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

## <a name='subsection4'></a>Data Entry Widget Items

Data entry widgets are created with the widget items\. These items require as
item attributes a definition list, which contains itself attribute name and
value pairs:

    tepam::argument\_dialogbox \\
       \.\.\.
       __\-<argument\_name>__ \{ *
          ?\-<attribute\_name> <attribute\_value>?
          ?\-<attribute\_name> <attribute\_value>?
          ?\.\.\.?*
       \}

       \.\.\.

The attribute list can contain various attributes to describe and comment an
entry widget and to constrain its entered value\. All entry widgets are accepting
a common set of attributes that are described in the section [Entry Widget Item
Attributes](#subsection5)\.

TEPAM defines a rich set of entry widgets\. If necessary, this set can be
extended with additional application specific entry widgets \(see [APPLICATION
SPECIFIC ENTRY WIDGETS](#section3)\):

  - \-entry *list*

    The *\-entry* item generates the simplest but most universal data entry
    widget\. It allows entering any kind of data in form of single line strings\.

    tepam::argument\_dialogbox \\
       __\-entry__ \{\-label Name \-variable Entry\}

  - \-text *list*

    The *\-text* item generates a multi line text entry widget\. The widget
    height can be selected with the *\-height* attribute\.

    tepam::argument\_dialogbox \\
       __\-text__ \{\-label Name \-variable Text \-height 5\}

  - \-checkbox *list*

    A group of check boxes is created with the *\-checkbox* item\. The number of
    check boxes and their option values are specified with a list assigned to
    the *\-choices* attribute or via a variable declared with the
    *\-choicevariable* attribute:

    tepam::argument\_dialogbox \\
       __\-checkbox__ \{\-label "Font sytle" \-variable FontStyle \\
                   \-choices \{bold italic underline\} \-default italic\}

    If the labels of the check boxes should differ from the option values, their
    labels can be defined with the *\-choicelabels* attribute:

    tepam::argument\_dialogbox \\
       __\-checkbox__ \{\-label "Font sytle" \-variable FontStyle \\
                  \-choices \{bold italic underline\} \\
                  \-choicelabels \{Bold Italic Underline\} \\
                  \-default italic\}

    In contrast to a radio box group, a check box group allows selecting
    simultaneously several choice options\. The selection is stored for this
    reason inside the defined variable in form of a list, even if only one
    choice option has been selected\.

  - \-radiobox *list*

    A group of radio boxes is created with the *\-radiobox* item\. The number of
    radio boxes and their option values are specified with a list assigned to
    the *\-choices* attribute or via a variable declared with the
    *\-choicevariable* attribute\.

    In contrast to a check box group, a radio box group allows selecting
    simultaneously only one choice option\. The selected option value is stored
    directly, and not in form of a list, inside the defined variable\.

    tepam::argument\_dialogbox \\
       __\-radiobox__ \{\-label "Text adjustment" \-variable Adjustment \\
                  \-choices \{left center right\} \-default left\}

    If the labels of the radio boxes should differ from the option values, their
    labels can be defined with the *\-choicelabels* attribute:

    tepam::argument\_dialogbox \\
       __\-radiobox__ \{\-label "Text adjustment" \-variable Adjustment \\
                  \-choices \{left center right\} \\
                  \-choicelabels \{Left Center Right\} \-default left\}

  - \-checkbutton *list*

    The *\-checkbutton* entry widget allows activating or deactivating a single
    choice option\. The result written into the variable will either be __0__
    if the check button was not activated or __1__ if it was activated\. An
    eventually provided default value has also to be either __0__ or
    __1__\.

    tepam::argument\_dialogbox \\
       __\-checkbutton__ \{\-label Capitalize \-variable Capitalize \-default 1\}

Several types of list and combo boxes are available to handle selection lists\.

  - \-combobox *list*

    The combobox is a combination of a normal entry widget together with a
    drop\-down list box\. The combobox allows selecting from this drop\-down list
    box a single element\. The list of the available elements can be provided
    either as a list to the *\-choices* attribute, or via a variable that is
    specified with the *\-choicevariable* attribute\.

    tepam::argument\_dialogbox \\
       __\-combobox__ \{\-label "Text size" \-variable Size \-choices \{8 9 10 12 15 18\} \-default 12\}

    And here is an example of using a variable to define the selection list:

    set TextSizes \{8 9 10 12 15 18\}
    tepam::argument\_dialogbox \\
       __\-combobox__ \{\-label "Text size" \-variable Size \-choicevariable TextSizes \-default 12\}

  - \-listbox *list*

    In contrast to the combo box, the list box is always displayed by the
    *listbox* entry widget\. Only one element is selectable unless the
    *\-multiple\_selection* attribute is set\. The list box height can be
    selected with the *\-height* attribute\. If the height is not explicitly
    defined, the list box height is automatically adapted to the argument dialog
    box size\. The first example uses a variable to define the available choices:

    set set AvailableSizes
    for \{set k 0\} \{$k<16\} \{incr k\} \{lappend AvailableSizes \[expr 1<<$k\]\}

    tepam::argument\_dialogbox \\
       __\-listbox__ \{\-label "Distance" \-variable Distance \\
                 \-choicevariable AvailableSizes \-default 6 \-height 5\}

    Here is a multi\-element selection example\. Please note that also the default
    selection can contain multiple elements:

    tepam::argument\_dialogbox \\
       __\-listbox__ \{\-label "Text styles" \-variable Styles \\
                 \-choices \{bold italic underline overstrike\} \\
                 \-choicelabels \{Bold Italic Underline Overstrike\} \\
                 \-default \{bold underline\} \-multiple\_selection 1 \\
                 \-height 3\}

  - \-disjointlistbox *list*

    A disjoint list box has to be used instead of a normal list box if the
    selection order is important\. The disjoint list box entry widget has in fact
    two list boxes, one to select elements and one to display the selected
    elements in the chosen order\.

    Disjoint listboxes allow always selecting multiple elements\. With the
    exception of the *\-multiple\_selection* attribute, disjointed list boxes
    are accepting the same attributes as the normal listbox, e\.g\. *\-height,
    \-choices, \-choicevariable, \-default*\.

    tepam::argument\_dialogbox \\
       __\-disjointlistbox__ \{\-label "Preferred scripting languages" \-variable Languages \\
                 \-comment "Please select your preferred languages in the order" \\
                 \-choices \{JavaScript Lisp Lua Octave PHP Perl Python Ruby Scheme Tcl\} \\
                 \-default \{Tcl Perl Python\}\}

The file and directory selectors are building a next group of data entry
widgets\. A paragraph of section [Entry Widget Item
Attributes](#subsection5) explains the widget specific attributes that allow
specifying the targeted file types, active directory etc\.

  - \-file *list*

    The item *\-file* creates a group composed by an entry widget together with
    a button that allows opening a file browser\. The data type *file* is
    automatically selected for this entry if no data type has been explicitly
    defined with the *\-type* attribute\.

    tepam::argument\_dialogbox \\
       __\-file__ \{\-label "Image file" \-variable ImageF \\
              \-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\}\} \\
              \-initialfile "picture\.gif"\}

  - \-existingfile *list*

    The item *\-existingfile* creates a group composed by an entry widget
    together with a button that allows opening a browser to select an existing
    file\. The data type *existingfile* is automatically selected for this
    entry if no data type has been explicitly defined with the *\-type*
    attribute\.

    tepam::argument\_dialogbox \\
       __\-existingfile__ \{\-label "Image file" \-variable ImageF \\
                      \-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\}\} \\
                      \-initialfile "picture\.gif"\}

  - \-directory *list*

    The item *\-directory* creates a group composed by an entry widget together
    with a button that allows opening a directory browser\. The data type
    *directory* is automatically selected for this entry if no data type has
    been explicitly defined with the *\-type* attribute\.

    tepam::argument\_dialogbox \\
       __\-directory__ \{\-label "Report directory" \-variable ReportDir\}

  - \-existingdirectory *list*

    The item *\-existingdirectory* creates a group composed by an entry widget
    together with a button that allows opening a browser to select an existing
    directory\. The data type *existingdirectory* is automatically selected for
    this entry if no data type has been explicitly defined with the *\-type*
    attribute\.

    tepam::argument\_dialogbox \\
       __\-existingdirectory__ \{\-label "Report directory" \-variable ReportDir\}

Finally, there is a last group of some other special data entry widgets\.

  - \-color *list*

    The color selector is composed by an entry widget together with a button
    that allows opening a color browser\. The data type *color* is
    automatically selected for this entry widget type if no data type has been
    explicitly defined with the *\-type* attribute\.

    tepam::argument\_dialogbox \\
       __\-color__ \{\-label "Background color" \-variable Color \-default red\}

  - \-font *list*

    The font selector is composed by an entry widget together with a button that
    allows opening a font browser\. The data type *font* is automatically
    selected for this entry widget type if no data type has been explicitly
    defined with the *\-type* attribute\. The entry widget displays an example







|
|
|
|
|
|
<
>
|















|
|






|
|








|
|
|




|
|
|
|
|

















|
|
|




|
|
|
|









|
|











|
|



|
|
|











|

|
|
|




|
|
|
|
|
|













|
|
|
|
|













|
|
|
|









|
|
|
|








|
|









|
|










|
|







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

## <a name='subsection4'></a>Data Entry Widget Items

Data entry widgets are created with the widget items\. These items require as
item attributes a definition list, which contains itself attribute name and
value pairs:

    tepam::argument_dialogbox \
       ...
       __-<argument_name>__ { *
          ?-<attribute_name> <attribute_value>?
          ?-<attribute_name> <attribute_value>?
          ?...?*

       }
       ...

The attribute list can contain various attributes to describe and comment an
entry widget and to constrain its entered value\. All entry widgets are accepting
a common set of attributes that are described in the section [Entry Widget Item
Attributes](#subsection5)\.

TEPAM defines a rich set of entry widgets\. If necessary, this set can be
extended with additional application specific entry widgets \(see [APPLICATION
SPECIFIC ENTRY WIDGETS](#section3)\):

  - \-entry *list*

    The *\-entry* item generates the simplest but most universal data entry
    widget\. It allows entering any kind of data in form of single line strings\.

    tepam::argument_dialogbox \
       __-entry__ {-label Name -variable Entry}

  - \-text *list*

    The *\-text* item generates a multi line text entry widget\. The widget
    height can be selected with the *\-height* attribute\.

    tepam::argument_dialogbox \
       __-text__ {-label Name -variable Text -height 5}

  - \-checkbox *list*

    A group of check boxes is created with the *\-checkbox* item\. The number of
    check boxes and their option values are specified with a list assigned to
    the *\-choices* attribute or via a variable declared with the
    *\-choicevariable* attribute:

    tepam::argument_dialogbox \
       __-checkbox__ {-label "Font sytle" -variable FontStyle \
                   -choices {bold italic underline} -default italic}

    If the labels of the check boxes should differ from the option values, their
    labels can be defined with the *\-choicelabels* attribute:

    tepam::argument_dialogbox \
       __-checkbox__ {-label "Font sytle" -variable FontStyle \
                  -choices {bold italic underline} \
                  -choicelabels {Bold Italic Underline} \
                  -default italic}

    In contrast to a radio box group, a check box group allows selecting
    simultaneously several choice options\. The selection is stored for this
    reason inside the defined variable in form of a list, even if only one
    choice option has been selected\.

  - \-radiobox *list*

    A group of radio boxes is created with the *\-radiobox* item\. The number of
    radio boxes and their option values are specified with a list assigned to
    the *\-choices* attribute or via a variable declared with the
    *\-choicevariable* attribute\.

    In contrast to a check box group, a radio box group allows selecting
    simultaneously only one choice option\. The selected option value is stored
    directly, and not in form of a list, inside the defined variable\.

    tepam::argument_dialogbox \
       __-radiobox__ {-label "Text adjustment" -variable Adjustment \
                  -choices {left center right} -default left}

    If the labels of the radio boxes should differ from the option values, their
    labels can be defined with the *\-choicelabels* attribute:

    tepam::argument_dialogbox \
       __-radiobox__ {-label "Text adjustment" -variable Adjustment \
                  -choices {left center right} \
                  -choicelabels {Left Center Right} -default left}

  - \-checkbutton *list*

    The *\-checkbutton* entry widget allows activating or deactivating a single
    choice option\. The result written into the variable will either be __0__
    if the check button was not activated or __1__ if it was activated\. An
    eventually provided default value has also to be either __0__ or
    __1__\.

    tepam::argument_dialogbox \
       __-checkbutton__ {-label Capitalize -variable Capitalize -default 1}

Several types of list and combo boxes are available to handle selection lists\.

  - \-combobox *list*

    The combobox is a combination of a normal entry widget together with a
    drop\-down list box\. The combobox allows selecting from this drop\-down list
    box a single element\. The list of the available elements can be provided
    either as a list to the *\-choices* attribute, or via a variable that is
    specified with the *\-choicevariable* attribute\.

    tepam::argument_dialogbox \
       __-combobox__ {-label "Text size" -variable Size -choices {8 9 10 12 15 18} -default 12}

    And here is an example of using a variable to define the selection list:

    set TextSizes {8 9 10 12 15 18}
    tepam::argument_dialogbox \
       __-combobox__ {-label "Text size" -variable Size -choicevariable TextSizes -default 12}

  - \-listbox *list*

    In contrast to the combo box, the list box is always displayed by the
    *listbox* entry widget\. Only one element is selectable unless the
    *\-multiple\_selection* attribute is set\. The list box height can be
    selected with the *\-height* attribute\. If the height is not explicitly
    defined, the list box height is automatically adapted to the argument dialog
    box size\. The first example uses a variable to define the available choices:

    set set AvailableSizes
    for {set k 0} {$k<16} {incr k} {lappend AvailableSizes [expr 1<<$k]}

    tepam::argument_dialogbox \
       __-listbox__ {-label "Distance" -variable Distance \
                 -choicevariable AvailableSizes -default 6 -height 5}

    Here is a multi\-element selection example\. Please note that also the default
    selection can contain multiple elements:

    tepam::argument_dialogbox \
       __-listbox__ {-label "Text styles" -variable Styles \
                 -choices {bold italic underline overstrike} \
                 -choicelabels {Bold Italic Underline Overstrike} \
                 -default {bold underline} -multiple_selection 1 \
                 -height 3}

  - \-disjointlistbox *list*

    A disjoint list box has to be used instead of a normal list box if the
    selection order is important\. The disjoint list box entry widget has in fact
    two list boxes, one to select elements and one to display the selected
    elements in the chosen order\.

    Disjoint listboxes allow always selecting multiple elements\. With the
    exception of the *\-multiple\_selection* attribute, disjointed list boxes
    are accepting the same attributes as the normal listbox, e\.g\. *\-height,
    \-choices, \-choicevariable, \-default*\.

    tepam::argument_dialogbox \
       __-disjointlistbox__ {-label "Preferred scripting languages" -variable Languages \
                 -comment "Please select your preferred languages in the order" \
                 -choices {JavaScript Lisp Lua Octave PHP Perl Python Ruby Scheme Tcl} \
                 -default {Tcl Perl Python}}

The file and directory selectors are building a next group of data entry
widgets\. A paragraph of section [Entry Widget Item
Attributes](#subsection5) explains the widget specific attributes that allow
specifying the targeted file types, active directory etc\.

  - \-file *list*

    The item *\-file* creates a group composed by an entry widget together with
    a button that allows opening a file browser\. The data type *file* is
    automatically selected for this entry if no data type has been explicitly
    defined with the *\-type* attribute\.

    tepam::argument_dialogbox \
       __-file__ {-label "Image file" -variable ImageF \
              -filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}}} \
              -initialfile "picture.gif"}

  - \-existingfile *list*

    The item *\-existingfile* creates a group composed by an entry widget
    together with a button that allows opening a browser to select an existing
    file\. The data type *existingfile* is automatically selected for this
    entry if no data type has been explicitly defined with the *\-type*
    attribute\.

    tepam::argument_dialogbox \
       __-existingfile__ {-label "Image file" -variable ImageF \
                      -filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}}} \
                      -initialfile "picture.gif"}

  - \-directory *list*

    The item *\-directory* creates a group composed by an entry widget together
    with a button that allows opening a directory browser\. The data type
    *directory* is automatically selected for this entry if no data type has
    been explicitly defined with the *\-type* attribute\.

    tepam::argument_dialogbox \
       __-directory__ {-label "Report directory" -variable ReportDir}

  - \-existingdirectory *list*

    The item *\-existingdirectory* creates a group composed by an entry widget
    together with a button that allows opening a browser to select an existing
    directory\. The data type *existingdirectory* is automatically selected for
    this entry if no data type has been explicitly defined with the *\-type*
    attribute\.

    tepam::argument_dialogbox \
       __-existingdirectory__ {-label "Report directory" -variable ReportDir}

Finally, there is a last group of some other special data entry widgets\.

  - \-color *list*

    The color selector is composed by an entry widget together with a button
    that allows opening a color browser\. The data type *color* is
    automatically selected for this entry widget type if no data type has been
    explicitly defined with the *\-type* attribute\.

    tepam::argument_dialogbox \
       __-color__ {-label "Background color" -variable Color -default red}

  - \-font *list*

    The font selector is composed by an entry widget together with a button that
    allows opening a font browser\. The data type *font* is automatically
    selected for this entry widget type if no data type has been explicitly
    defined with the *\-type* attribute\. The entry widget displays an example
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
    If no default font is provided via the *\-default* attribute, the default
    font of the label widget to display the selected font will be used as
    default selected font\. If the font family of this label widget is not part
    of the available families the first available family is used as default\. If
    the font size of this label widget is not part of the available sizes the
    next close available size is selected as default size\.

    tepam::argument\_dialogbox \\
       __\-font__ \{\-label "Font" \-variable Font \\
              \-font\_sizes \{8 10 12 16\} \\
              \-default \{Arial 20 italic\}\}

## <a name='subsection5'></a>Entry Widget Item Attributes

All the entry widget items are accepting the following attributes:

  - \-text *string*

    Eventual descriptions and comments specified with the *\-text* attribute
    are displayed above the entry widget\.

    tepam::argument\_dialogbox \\
       \-entry \{__\-text "Please enter your name bellow"__ \-variable Name\}

  - \-label *string*

    The label attribute creates left to the entry widget a label using the
    provided string as label text:

    tepam::argument\_dialogbox \\
       \-entry \{__\-label Name__ \-variable Name\}

  - \-variable *string*

    All entry widgets require a specified variable\. After accepting the entered
    information with the OK button, the entry widget data is stored inside the
    defined variables\.

    tepam::argument\_dialogbox \\
       \-existingdirectory \{\-label "Report directory" __\-variable ReportDir__\}

  - \-default *string*

    Eventual default data for the entry widgets can be provided via the
    *\-default* attribute\. The default value is overridden if an argument
    dialog box with a defined context is called another time\. The value
    acknowledged in a previous call will be used in this case as default value\.

    tepam::argument\_dialogbox \\
       \-checkbox \{\-label "Font sytle" \-variable FontStyle \\
                   \-choices \{bold italic underline\} __\-default italic__\}

  - \-optional __0__&#124;__1__

    Data can be specified as optional or mandatory with the *\-optional*
    attribute that requires either __0__ \(mandatory\) or __1__ \(optional\)
    as attribute data\.

    In case an entry is optional and no data has been entered, e\.g\. the entry
    contains an empty character string, the entry will be considered as
    undefined and the assigned variable will not be defined\.

    tepam::argument\_dialogbox \\
       \-entry \{\-label "City" \-variable start\_city \-type string\} \\
       \-entry \{\-label "Street" \-variable start\_street \-type string __\-optional 0__\} \\
       \-entry \{\-label "Street number" \-variable start\_street\_nbr \-type integer __\-optional 1__\} \\

  - \-type *string*

    If the data type is defined with the *\-type* attribute the argument dialog
    box will automatically perform a data type check after acknowledging the
    entered values and before the dialog box is closed\. If a type incompatible
    value is found an error message box appears and the user can correct the
    value\.

    The argument dialog box accepts all types that have been specified by the
    TEPAM package and that are also used by
    __[tepam::procedure](tepam\_procedure\.md)__ \(see the
    *tepam::procedure reference manual*\)\.

    Some entry widgets like the file and directory widgets, as well as the color
    and font widgets are specifying automatically the default data type if no
    type has been specified explicitly with the *\-type* attribute\.

    tepam::argument\_dialogbox \\
       __\-entry__ \{\-label "Street number" \-variable start\_street\_nbr __\-type integer__\} \\

  - \-range *string*

    Values can be constrained with the *\-range* attribute\. The valid range is
    defined with a list containing the minimum valid value and a maximum valid
    value\.

    The *\-range* attribute has to be used only for numerical arguments, like
    integers and doubles\.

    tepam::argument\_dialogbox \\
       \-entry \{\-label Month \-variable Month \-type integer __\-range \{1 12\}__\}

  - \-validatecommand *string*

    Custom argument value validations can be performed via specific validation
    commands that are defined with the *\-validatecommand* attribute\. The
    provided validation command can be a complete script in which the pattern
    *%P* is placeholder for the argument value that has to be validated\.

    tepam::argument\_dialogbox \\
       \-entry \{\-label "Your comment" \-variable YourCom \\
               __\-validatecommand__ "IllegalWordDetector %P"\}

    While the purpose of this custom argument validation attribute is the
    validation of a specific argument, there is also a global data validation
    attribute *\-validatecommand* that allows performing validation that
    involves multiple arguments\.

  - \-validatecommand\_error\_text *string*

    This attribute allows overriding the default error message for a custom
    argument validation \(defined by *\-validatecommand*\)\.

Some other attributes are supported by the list and combo boxes as well as by
the radio and check buttons\.

  - \-choices *string*

    Choice lists can directly be defined with the *\-choices* attribute\. This
    way to define choice lists is especially adapted for smaller, fixed
    selection lists\.

    tepam::argument\_dialogbox \\
       \-listbox \{\-label "Text styles" \-variable Styles \\
                 __\-choices \{bold italic underline\}__ \-default underline

  - \-choicelabels *string* *\(only check and radio buttons\)*

    If the labels of the check and radio boxes should differ from the option
    values, they can be defined with the *\-choicelabels* attribute:

    tepam::argument\_dialogbox \\
       \-checkbox \{\-label "Font sytle" \-variable FontStyle \\
                  \-choices \{bold italic underline\} \\
                  __\-choicelabels \{Bold Italic Underline\}__

  - \-choicevariable *string*

    Another way to define the choice lists is using the *\-choicevariable*
    attribute\. This way to define choice lists is especially adapted for huge
    and eventually variable selection lists\.

    set TextSizes \{8 9 10 12 15 18\}
    tepam::argument\_dialogbox \\
       \-combobox \{\-label "Text size" \-variable Size __\-choicevariable TextSizes__\}

  - \-multiple\_selection __0__&#124;__1__

    The list box item \(__\-listbox__\) allows by default selecting only one
    list element\. By setting the *\-multiple\_selection* attribute to __1__,
    multiple elements can be selected\.

    tepam::argument\_dialogbox \\
       \-listbox \{\-label "Text styles" \-variable Styles \\
                 \-choices \{bold italic underline\} \-default underline \\
                 __\-multiple\_selection 1__ \-height 3\}

Some additional attributes are supported by the file and directory selection
widgets\.

  - \-filetypes *string*

    The file type attribute is used by the __\-file__ and
    __\-existingfile__ items to define the file endings that are searched by
    the file browser\.

    tepam::argument\_dialogbox \\
       \-file \{\-label "Image file" \-variable ImageF \\
              __\-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\}\}__\}

  - \-initialfile *string*

    The initial file used by the file browsers of the __\-file__ and
    __\-existingfile__ widgets are by default the file defined with the
    *\-default* attribute, unless a file is specified with the *\-initialfile*
    attribute\.

    tepam::argument\_dialogbox \\
       \-file \{\-variable ImageF __\-initialfile "picture\.gif"__\}

  - \-activedir *string*

    The *\-activedir* attribute will override the default active search
    directory used by the file browsers of all file and directory entry widgets\.
    The default active search directory is defined by the directory of a
    specified initial file \(*\-initialfile*\) if defined, and otherwise by the
    directory of the default file/directory, specified with the *\-default*
    attribute\.

    tepam::argument\_dialogbox \\
       \-file "\-variable ImageF __\-activedir $pwd__"

Finally, there is a last attribute supported by some widgets:

  - \-height *string*

    All widgets containing a selection list \(__\-listbox__,
    __\-disjointlistbox__, __\-font__\) as well as the multi line
    __\-text__ widget are accepting the *\-height* attribute that defines
    the number of displayed rows of the selection lists\.

    tepam::argument\_dialogbox \\
       \-listbox \{\-label "Text size" \-variable Size \\
                 \-choices \{8 9 10 12 15 18\} \-default 12 __\-height 3__\}

    If the no height has been explicitly specified the height of the widget will
    be dynamically adapted to the argument dialog box size\.

# <a name='section3'></a>APPLICATION SPECIFIC ENTRY WIDGETS

An application specific entry widget can be made available to the argument
dialog box by adding a dedicated procedure to the __tepam__ namespace\. This
procedure has three arguments; the first one is the widget path, the second one
a subcommand and the third argument has various purposes:

    *proc* tepam::ad\_form\(<WidgetName>\) \{W Command \{Par ""\}\} \{
       *upvar Option Option; \# if required*
       *variable argument\_dialogbox; \# if required*
       switch $Command \{
          "create" <CreateCommandSequence>
          "set\_choice" <SetChoiceCommandSequence>
          "set" <SetCommandv>
          "get" <GetCommandSequence>
       \}
    \}



__Argument\_dialogbox__ takes care about the *\-label* and *\-text*
attributes for all entry widgets\. For any data entry widget it creates a frame
into which the data entry widget components can be placed\. The path to this
frame is provided via the *W* argument\.

The entry widget procedure has to support 3 mandatory and an optional command







|
|
|
|










|
|






|
|







|
|








|
|
|











|
|
|
|


















|
|










|
|








|
|
|




















|
|
|






|
|
|
|







|
|
|







|
|
|
|










|
|
|








|
|










|
|










|
|
|











|
|
|
|

|


<
<
>
>







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
    If no default font is provided via the *\-default* attribute, the default
    font of the label widget to display the selected font will be used as
    default selected font\. If the font family of this label widget is not part
    of the available families the first available family is used as default\. If
    the font size of this label widget is not part of the available sizes the
    next close available size is selected as default size\.

    tepam::argument_dialogbox \
       __-font__ {-label "Font" -variable Font \
              -font_sizes {8 10 12 16} \
              -default {Arial 20 italic}}

## <a name='subsection5'></a>Entry Widget Item Attributes

All the entry widget items are accepting the following attributes:

  - \-text *string*

    Eventual descriptions and comments specified with the *\-text* attribute
    are displayed above the entry widget\.

    tepam::argument_dialogbox \
       -entry {__-text "Please enter your name bellow"__ -variable Name}

  - \-label *string*

    The label attribute creates left to the entry widget a label using the
    provided string as label text:

    tepam::argument_dialogbox \
       -entry {__-label Name__ -variable Name}

  - \-variable *string*

    All entry widgets require a specified variable\. After accepting the entered
    information with the OK button, the entry widget data is stored inside the
    defined variables\.

    tepam::argument_dialogbox \
       -existingdirectory {-label "Report directory" __-variable ReportDir__}

  - \-default *string*

    Eventual default data for the entry widgets can be provided via the
    *\-default* attribute\. The default value is overridden if an argument
    dialog box with a defined context is called another time\. The value
    acknowledged in a previous call will be used in this case as default value\.

    tepam::argument_dialogbox \
       -checkbox {-label "Font sytle" -variable FontStyle \
                   -choices {bold italic underline} __-default italic__}

  - \-optional __0__&#124;__1__

    Data can be specified as optional or mandatory with the *\-optional*
    attribute that requires either __0__ \(mandatory\) or __1__ \(optional\)
    as attribute data\.

    In case an entry is optional and no data has been entered, e\.g\. the entry
    contains an empty character string, the entry will be considered as
    undefined and the assigned variable will not be defined\.

    tepam::argument_dialogbox \
       -entry {-label "City" -variable start_city -type string} \
       -entry {-label "Street" -variable start_street -type string __-optional 0__} \
       -entry {-label "Street number" -variable start_street_nbr -type integer __-optional 1__} \

  - \-type *string*

    If the data type is defined with the *\-type* attribute the argument dialog
    box will automatically perform a data type check after acknowledging the
    entered values and before the dialog box is closed\. If a type incompatible
    value is found an error message box appears and the user can correct the
    value\.

    The argument dialog box accepts all types that have been specified by the
    TEPAM package and that are also used by
    __[tepam::procedure](tepam\_procedure\.md)__ \(see the
    *tepam::procedure reference manual*\)\.

    Some entry widgets like the file and directory widgets, as well as the color
    and font widgets are specifying automatically the default data type if no
    type has been specified explicitly with the *\-type* attribute\.

    tepam::argument_dialogbox \
       __-entry__ {-label "Street number" -variable start_street_nbr __-type integer__} \

  - \-range *string*

    Values can be constrained with the *\-range* attribute\. The valid range is
    defined with a list containing the minimum valid value and a maximum valid
    value\.

    The *\-range* attribute has to be used only for numerical arguments, like
    integers and doubles\.

    tepam::argument_dialogbox \
       -entry {-label Month -variable Month -type integer __-range {1 12}__}

  - \-validatecommand *string*

    Custom argument value validations can be performed via specific validation
    commands that are defined with the *\-validatecommand* attribute\. The
    provided validation command can be a complete script in which the pattern
    *%P* is placeholder for the argument value that has to be validated\.

    tepam::argument_dialogbox \
       -entry {-label "Your comment" -variable YourCom \
               __-validatecommand__ "IllegalWordDetector %P"}

    While the purpose of this custom argument validation attribute is the
    validation of a specific argument, there is also a global data validation
    attribute *\-validatecommand* that allows performing validation that
    involves multiple arguments\.

  - \-validatecommand\_error\_text *string*

    This attribute allows overriding the default error message for a custom
    argument validation \(defined by *\-validatecommand*\)\.

Some other attributes are supported by the list and combo boxes as well as by
the radio and check buttons\.

  - \-choices *string*

    Choice lists can directly be defined with the *\-choices* attribute\. This
    way to define choice lists is especially adapted for smaller, fixed
    selection lists\.

    tepam::argument_dialogbox \
       -listbox {-label "Text styles" -variable Styles \
                 __-choices {bold italic underline}__ -default underline

  - \-choicelabels *string* *\(only check and radio buttons\)*

    If the labels of the check and radio boxes should differ from the option
    values, they can be defined with the *\-choicelabels* attribute:

    tepam::argument_dialogbox \
       -checkbox {-label "Font sytle" -variable FontStyle \
                  -choices {bold italic underline} \
                  __-choicelabels {Bold Italic Underline}__

  - \-choicevariable *string*

    Another way to define the choice lists is using the *\-choicevariable*
    attribute\. This way to define choice lists is especially adapted for huge
    and eventually variable selection lists\.

    set TextSizes {8 9 10 12 15 18}
    tepam::argument_dialogbox \
       -combobox {-label "Text size" -variable Size __-choicevariable TextSizes__}

  - \-multiple\_selection __0__&#124;__1__

    The list box item \(__\-listbox__\) allows by default selecting only one
    list element\. By setting the *\-multiple\_selection* attribute to __1__,
    multiple elements can be selected\.

    tepam::argument_dialogbox \
       -listbox {-label "Text styles" -variable Styles \
                 -choices {bold italic underline} -default underline \
                 __-multiple_selection 1__ -height 3}

Some additional attributes are supported by the file and directory selection
widgets\.

  - \-filetypes *string*

    The file type attribute is used by the __\-file__ and
    __\-existingfile__ items to define the file endings that are searched by
    the file browser\.

    tepam::argument_dialogbox \
       -file {-label "Image file" -variable ImageF \
              __-filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}}}__}

  - \-initialfile *string*

    The initial file used by the file browsers of the __\-file__ and
    __\-existingfile__ widgets are by default the file defined with the
    *\-default* attribute, unless a file is specified with the *\-initialfile*
    attribute\.

    tepam::argument_dialogbox \
       -file {-variable ImageF __-initialfile "picture.gif"__}

  - \-activedir *string*

    The *\-activedir* attribute will override the default active search
    directory used by the file browsers of all file and directory entry widgets\.
    The default active search directory is defined by the directory of a
    specified initial file \(*\-initialfile*\) if defined, and otherwise by the
    directory of the default file/directory, specified with the *\-default*
    attribute\.

    tepam::argument_dialogbox \
       -file "-variable ImageF __-activedir $pwd__"

Finally, there is a last attribute supported by some widgets:

  - \-height *string*

    All widgets containing a selection list \(__\-listbox__,
    __\-disjointlistbox__, __\-font__\) as well as the multi line
    __\-text__ widget are accepting the *\-height* attribute that defines
    the number of displayed rows of the selection lists\.

    tepam::argument_dialogbox \
       -listbox {-label "Text size" -variable Size \
                 -choices {8 9 10 12 15 18} -default 12 __-height 3__}

    If the no height has been explicitly specified the height of the widget will
    be dynamically adapted to the argument dialog box size\.

# <a name='section3'></a>APPLICATION SPECIFIC ENTRY WIDGETS

An application specific entry widget can be made available to the argument
dialog box by adding a dedicated procedure to the __tepam__ namespace\. This
procedure has three arguments; the first one is the widget path, the second one
a subcommand and the third argument has various purposes:

    *proc* tepam::ad_form(<WidgetName>) {W Command {Par ""}} {
       *upvar Option Option; # if required*
       *variable argument_dialogbox; # if required*
       switch $Command {
          "create" <CreateCommandSequence>
          "set_choice" <SetChoiceCommandSequence>
          "set" <SetCommandv>
          "get" <GetCommandSequence>


       }
    }

__Argument\_dialogbox__ takes care about the *\-label* and *\-text*
attributes for all entry widgets\. For any data entry widget it creates a frame
into which the data entry widget components can be placed\. The path to this
frame is provided via the *W* argument\.

The entry widget procedure has to support 3 mandatory and an optional command
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
__argument\_dialogbox__ has to be used for this purpose together with array
indexes starting with *"$W,"*, e\.g\. *argument\_dialogbox\($W,values\)*\.

Examples of entry widget procedures are directly provided by the TEPAM package
source file that specifies the standard entry widget procedures\. The simplest
procedure is the one for the basic *entry* widget:

    proc tepam::ad\_form\(entry\) \{W Command \{Par ""\}\} \{
       switch $Command \{
          "create" \{pack \[entry \\$W\.entry\] \-fill x \\
                            \-expand yes \-pady 4 \-side left\}
          "set" \{\\$W\.entry insert 0 $Par\}
          "get" \{return \[\\$W\.entry get\]\}
       \}
    \}



It is also possible to relay on an existing entry widget procedure to derive a
new, more specific one\. The *radiobox* widget is used for example, to create a
new entry widget that allows selecting either *left*, *center* or *right*\.
The original *radiobox* widget is called with the *set\_choice* command
immediately after the *create* command, to define the fixed list of selection
options\.

    proc tepam::ad\_form\(rcl\) \{W Command \{Par ""\}\} \{
       set Res \[ad\_form\(radiobox\) $W $Command $Par\]
       if \{$Command=="create"\} \{
          ad\_form\(radiobox\) $W set\_choice \{left center right\}
       \}

       return $Res
    \}


Please consult the TEPAM package source file to find additional and more complex
examples of entry widget procedures\.

# <a name='section4'></a>VARIABLES

The __argument\_dialogbox__ is using two variables inside the namespace







|
|
|
|
|
|
<
<
>
>








|
|
|
|
<
>

<
>







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
__argument\_dialogbox__ has to be used for this purpose together with array
indexes starting with *"$W,"*, e\.g\. *argument\_dialogbox\($W,values\)*\.

Examples of entry widget procedures are directly provided by the TEPAM package
source file that specifies the standard entry widget procedures\. The simplest
procedure is the one for the basic *entry* widget:

    proc tepam::ad_form(entry) {W Command {Par ""}} {
       switch $Command {
          "create" {pack [entry \$W.entry] -fill x \
                            -expand yes -pady 4 -side left}
          "set" {\$W.entry insert 0 $Par}
          "get" {return [\$W.entry get]}


       }
    }

It is also possible to relay on an existing entry widget procedure to derive a
new, more specific one\. The *radiobox* widget is used for example, to create a
new entry widget that allows selecting either *left*, *center* or *right*\.
The original *radiobox* widget is called with the *set\_choice* command
immediately after the *create* command, to define the fixed list of selection
options\.

    proc tepam::ad_form(rcl) {W Command {Par ""}} {
       set Res [ad_form(radiobox) $W $Command $Par]
       if {$Command=="create"} {
          ad_form(radiobox) $W set_choice {left center right}

       }
       return $Res

    }

Please consult the TEPAM package source file to find additional and more complex
examples of entry widget procedures\.

# <a name='section4'></a>VARIABLES

The __argument\_dialogbox__ is using two variables inside the namespace
Changes to embedded/md/tcllib/files/modules/tepam/tepam_doc_gen.md.
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
Support for a new document format can be added by defining in the
__tepam::doc\_gen__ namespace a set of procedures that generate the different
document components\.

The following documentation listing contains tokens that refer to the different
document generation procedures:

    *     <01>*
    *<03> <20s>*   NAME*<20e>*
    *     <30s>*       message\_box \- Displays text in a message box*<30e>*
    *     <20s>*   SYNOPSYS*<20e>*
    *     <40s>*       message\_box \[\-mtype <mtype>\] <text>*<40e>*
    *     <20s>*   DESCRIPTION*<20e>*
    *     <21s>     message\_box<21e>*
    *     <54s>       message\_box \[\-mtype <mtype>\] <text><54e>*
    *     <50s>*       This procedure allows displaying a text in an message box\. The following
    *          *       message types are supported:*<50e>*
    *<51> <53s>*       \* Info*<53e>*
    *     <53s>*       \* Warning*<53e>*
    *     <53s>*       \* Error*<53e>*                                           *<52>*
    *     <50s>*       If the text parameter is use multiple times the different texts are
    *          *       concatenated to create the message text\.*<50e>*
    *     <20s>*   ARGUMENTS*<20e>*
    *<60> <62s>*       \[\-mtype <mtype>\]*<62e>*
    *<63> <65s>*          Message type*<65e>*
    *     <66s>*          Default: "Warning"*<66e>*
    *     <66s>*          Multiple: yes*<66e>*
    *     <66s>*          Choices: Info, Warning, Error*<66e>*                  *<64>*
    *     <62s>*       <text>*<62e>*
    *<63> <65s>*          One or multiple text lines to display*<65e>*
    *     <66s>*          Type: string*<66e>*
    *     <66s>*          Multiple: yes*<66e>*                                  *<64><61>*
    *     <20s>*   EXAMPLE*<20e>*
    *<70> <72s>*       message\_box "Please save first the document"*<72e>*
    *     <73s>*       \-> 1*<73e>*                                              *<71><04>*
    *     <02>*

There are 2 types of document generation procedures:

  - Content generation procedures \(e\.g\. <40s>\.\.\.<40e>\)

    These procedures generate some document content based on the text that is
    provided as procedure argument\. The listing above shows two tokens for these







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
Support for a new document format can be added by defining in the
__tepam::doc\_gen__ namespace a set of procedures that generate the different
document components\.

The following documentation listing contains tokens that refer to the different
document generation procedures:

    *     <01>*
    *<03> <20s>*   NAME*<20e>*
    *     <30s>*       message_box - Displays text in a message box*<30e>*
    *     <20s>*   SYNOPSYS*<20e>*
    *     <40s>*       message_box [-mtype <mtype>] <text>*<40e>*
    *     <20s>*   DESCRIPTION*<20e>*
    *     <21s>     message_box<21e>*
    *     <54s>       message_box [-mtype <mtype>] <text><54e>*
    *     <50s>*       This procedure allows displaying a text in an message box. The following
    *          *       message types are supported:*<50e>*
    *<51> <53s>*       * Info*<53e>*
    *     <53s>*       * Warning*<53e>*
    *     <53s>*       * Error*<53e>*                                           *<52>*
    *     <50s>*       If the text parameter is use multiple times the different texts are
    *          *       concatenated to create the message text.*<50e>*
    *     <20s>*   ARGUMENTS*<20e>*
    *<60> <62s>*       [-mtype <mtype>]*<62e>*
    *<63> <65s>*          Message type*<65e>*
    *     <66s>*          Default: "Warning"*<66e>*
    *     <66s>*          Multiple: yes*<66e>*
    *     <66s>*          Choices: Info, Warning, Error*<66e>*                  *<64>*
    *     <62s>*       <text>*<62e>*
    *<63> <65s>*          One or multiple text lines to display*<65e>*
    *     <66s>*          Type: string*<66e>*
    *     <66s>*          Multiple: yes*<66e>*                                  *<64><61>*
    *     <20s>*   EXAMPLE*<20e>*
    *<70> <72s>*       message_box "Please save first the document"*<72e>*
    *     <73s>*       -> 1*<73e>*                                              *<71><04>*
    *     <02>*

There are 2 types of document generation procedures:

  - Content generation procedures \(e\.g\. <40s>\.\.\.<40e>\)

    These procedures generate some document content based on the text that is
    provided as procedure argument\. The listing above shows two tokens for these
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

      * *IsOptional*

        If true \(=__1__\) the argument is optional which should be indicated
        by the generated string \(for example by putting the argument into
        brackets \{\[\]\} or into question marks '?'\):

    gen\(TXT,ArgumentString\) mtype 1 0 string \->

        *"\[mtype\]"*

      * *IsNamed*

        If true \(=__1__\) an argument is a named argument \(option\)\. The
        generated string should in this case contain the argument/option name,
        followed by the argument itself:

    gen\(TXT,ArgumentString\) mtype 0 1 string \->

        *"\-mtype <mtype>"* Named arguments can also be optional:

    gen\(TXT,ArgumentString\) mtype 1 1 string \->

        *"\[\-mtype <mtype>\]"*

      * *Type*

        Indicates the type of the argument\. If the type is set to __none__
        the argument is a flag, which needs to be indicated by the generated
        string\. Example:

    gen\(TXT,ArgumentString\) close 1 1 none \->

        *"\[\-close\]"*

# <a name='section5'></a>EXAMPLES

## <a name='subsection5'></a>tepam::doc\_gen::generate

The __TEPAM Doc Gen__ package can be explored by generating the
documentation of the command __tepam::doc\_gen::generate__\. The following
example generates the document in text format \(default format\):

    __tepam::doc\_gen::generate__ tepam::doc\_gen::generate

The next example generates the documentation in HTML format:

    __tepam::doc\_gen::generate__ \-format HTML tepam::doc\_gen::generate

The flag ?header\_footer? adds also the file header and footer:

    __tepam::doc\_gen::generate__ \-format HTML \-header\_footer tepam::doc\_gen::generate

The documentation can directly be stored in a file\. The file header and footer
are automatically generated in this way:

    __tepam::doc\_gen::generate__ \-format HTML \-dest\_file doc\_gen\.html tepam::doc\_gen::generate

The generated HTML file refers a CSS stylesheet file \(default:
tepam\_doc\_stylesheet\.css\)\. To display the HTML file correctly this CSS
stylesheet file needs to be copied into the directory of the generated HTML
file\.

The Tcl DOC Tools format can be used as intermediate format to generate other
formats, for example HTML:

    *\# Generate the documentation in Tcl Doc Tool format*
    set dt \[__tepam::doc\_gen::generate__ \-format DT \-header\_footer tepam::doc\_gen::generate\]
    **
    *\# Create a new doc tools object \(HTML format\)*
    package require doctools
    ::doctools::new myDoc \-format html
    **
    *\# Open the HTML file, and write the HTML formatted documentation*
    set fHtml \[open doc\_gen\.dt\.html w\]
    puts $fHtml \[myDoc format $dt\]
    close $fHtml

## <a name='subsection6'></a>tepam::doc\_gen::patch

While __generate__ provides a limited number of possibilities to vary the
document structure, __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ offers more
flexibility\. Multiple documentations for different procedures and meta
information can for example be added\.

The following listing shows how the
__[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ command works\. It defines first
a HTML master document string that contains 2 procedure documentation
placeholders \(*\{\*<ProcedureName>\*\}*\)\. There placeholders are replaced by
__[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ with the generated documentation
of the referred procedures\. Since nonstandard placeholders are used,
__[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ is called with an explicit
placeholder pattern definition \(argument *search\_pattern*\)\.

    *\# Define the HTML master document*
    set HtmlMasterDoc \{\\
    <html>
      <head>
        <title>tepam::doc\_gen</title>
        <link rel="stylesheet" href="tepam\_doc\_stylesheet\.css">
        <meta content="documentation" name="keywords"></meta>
      </head>
      <body>
        <h1>tepam::doc\_gen</h1>
          <h2>Generate</h2>
    __\{\*tepam::doc\_gen::generate\*\}__
          <h2>Patch</h2>
    __\{\*tepam::doc\_gen::patch\*\}__
      </body>
    <html>\\
    \}

    **
    *\# Patch the master document: This will replace the placeholders by the
    \# procedure documentation divisions:*
    __tepam::doc\_gen::patch__ \-format HTML \-search\_pattern \{\\\{\\\*\(\.\*?\)\\\*\\\}\} \\
                          \-src\_string $HtmlMasterDoc \-dest\_file tepam\_doc\_gen\.html

# <a name='seealso'></a>SEE ALSO

[tepam\(n\)](tepam\_introduction\.md),
[tepam::procedure\(n\)](tepam\_procedure\.md)

# <a name='keywords'></a>KEYWORDS







|









|



|









|











|



|



|




|









|
|
|
|

|
|
|
|
|


















|
|


|
|



|

|

|

|
<
>
|
|
|
|
|







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

      * *IsOptional*

        If true \(=__1__\) the argument is optional which should be indicated
        by the generated string \(for example by putting the argument into
        brackets \{\[\]\} or into question marks '?'\):

    gen(TXT,ArgumentString) mtype 1 0 string ->

        *"\[mtype\]"*

      * *IsNamed*

        If true \(=__1__\) an argument is a named argument \(option\)\. The
        generated string should in this case contain the argument/option name,
        followed by the argument itself:

    gen(TXT,ArgumentString) mtype 0 1 string ->

        *"\-mtype <mtype>"* Named arguments can also be optional:

    gen(TXT,ArgumentString) mtype 1 1 string ->

        *"\[\-mtype <mtype>\]"*

      * *Type*

        Indicates the type of the argument\. If the type is set to __none__
        the argument is a flag, which needs to be indicated by the generated
        string\. Example:

    gen(TXT,ArgumentString) close 1 1 none ->

        *"\[\-close\]"*

# <a name='section5'></a>EXAMPLES

## <a name='subsection5'></a>tepam::doc\_gen::generate

The __TEPAM Doc Gen__ package can be explored by generating the
documentation of the command __tepam::doc\_gen::generate__\. The following
example generates the document in text format \(default format\):

    __tepam::doc_gen::generate__ tepam::doc_gen::generate

The next example generates the documentation in HTML format:

    __tepam::doc_gen::generate__ -format HTML tepam::doc_gen::generate

The flag ?header\_footer? adds also the file header and footer:

    __tepam::doc_gen::generate__ -format HTML -header_footer tepam::doc_gen::generate

The documentation can directly be stored in a file\. The file header and footer
are automatically generated in this way:

    __tepam::doc_gen::generate__ -format HTML -dest_file doc_gen.html tepam::doc_gen::generate

The generated HTML file refers a CSS stylesheet file \(default:
tepam\_doc\_stylesheet\.css\)\. To display the HTML file correctly this CSS
stylesheet file needs to be copied into the directory of the generated HTML
file\.

The Tcl DOC Tools format can be used as intermediate format to generate other
formats, for example HTML:

    *# Generate the documentation in Tcl Doc Tool format*
    set dt [__tepam::doc_gen::generate__ -format DT -header_footer tepam::doc_gen::generate]
    **
    *# Create a new doc tools object (HTML format)*
    package require doctools
    ::doctools::new myDoc -format html
    **
    *# Open the HTML file, and write the HTML formatted documentation*
    set fHtml [open doc_gen.dt.html w]
    puts $fHtml [myDoc format $dt]
    close $fHtml

## <a name='subsection6'></a>tepam::doc\_gen::patch

While __generate__ provides a limited number of possibilities to vary the
document structure, __[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ offers more
flexibility\. Multiple documentations for different procedures and meta
information can for example be added\.

The following listing shows how the
__[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ command works\. It defines first
a HTML master document string that contains 2 procedure documentation
placeholders \(*\{\*<ProcedureName>\*\}*\)\. There placeholders are replaced by
__[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ with the generated documentation
of the referred procedures\. Since nonstandard placeholders are used,
__[patch](\.\./\.\./\.\./\.\./index\.md\#patch)__ is called with an explicit
placeholder pattern definition \(argument *search\_pattern*\)\.

    *# Define the HTML master document*
    set HtmlMasterDoc {\
    <html>
      <head>
        <title>tepam::doc_gen</title>
        <link rel="stylesheet" href="tepam_doc_stylesheet.css">
        <meta content="documentation" name="keywords"></meta>
      </head>
      <body>
        <h1>tepam::doc_gen</h1>
          <h2>Generate</h2>
    __{*tepam::doc_gen::generate*}__
          <h2>Patch</h2>
    __{*tepam::doc_gen::patch*}__
      </body>
    <html>\

    }
    **
    *# Patch the master document: This will replace the placeholders by the
    # procedure documentation divisions:*
    __tepam::doc_gen::patch__ -format HTML -search_pattern {\{\*(.*?)\*\}} \
                          -src_string $HtmlMasterDoc -dest_file tepam_doc_gen.html

# <a name='seealso'></a>SEE ALSO

[tepam\(n\)](tepam\_introduction\.md),
[tepam::procedure\(n\)](tepam\_procedure\.md)

# <a name='keywords'></a>KEYWORDS
Changes to embedded/md/tcllib/files/modules/tepam/tepam_introduction.md.
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
takes as __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ also 3 arguments: The
procedure name, the procedure header and the procedure body\.

The following example declares the subcommand
__[message](\.\./\.\./\.\./\.\./index\.md\#message)__ of the procedure
__display__\. This command has several named and unnamed arguments:

    __[tepam::procedure](tepam\_procedure\.md)__ \{display message\} \{
       \-return            \-
       \-short\_description "Displays a simple message box"
       \-description       "This procedure allows displaying a configurable message box\."
       \-args \{
          \{\-mtype \-default Warning \-choices \{Info Warning Error\} \-description "Message type"\}
          \{\-font \-type font \-default \{Arial 10 italic\} \-description "Message text font"\}
          \{\-level \-type integer \-optional \-range \{1 10\} \-description "Message level"\}
          \{\-fg \-type color \-default black \-description "Message color"\}
          \{\-bg \-type color \-optional \-description "Background color"\}
          \{\-no\_border \-type none \-description "Use a splash window style \(no border\)"\}
          \{\-log\_file \-type file \-optional \-description "Optional message log file"\}
          \{text \-type string \-multiple \-description "Multiple text lines to display"\}

       \}
    \} \{
    *   puts "display message:"
       foreach var \{mtype font level fg bg no\_border log\_file text\} \{
          if \{\[info exists $var\]\} \{
             puts  "  $var=\[set $var\]"
          \}
       \}


    *\}

A call of procedure that has been declared in this way will first invoke the
TEPAM argument manager, before the procedure body is executed\. The argument
manager parses the provided arguments, validates them, completes them eventually
with some default values, and makes them finally available to the procedure body
as local variables\. In case an argument is missing or has a wrong type, the
argument manager generates an error message that explains the reason for the







|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
<
|
|
|
|
<
<
>
>
|







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
takes as __[proc](\.\./\.\./\.\./\.\./index\.md\#proc)__ also 3 arguments: The
procedure name, the procedure header and the procedure body\.

The following example declares the subcommand
__[message](\.\./\.\./\.\./\.\./index\.md\#message)__ of the procedure
__display__\. This command has several named and unnamed arguments:

    __[tepam::procedure](tepam_procedure.md)__ {display message} {
       -return            -
       -short_description "Displays a simple message box"
       -description       "This procedure allows displaying a configurable message box."
       -args {
          {-mtype -default Warning -choices {Info Warning Error} -description "Message type"}
          {-font -type font -default {Arial 10 italic} -description "Message text font"}
          {-level -type integer -optional -range {1 10} -description "Message level"}
          {-fg -type color -default black -description "Message color"}
          {-bg -type color -optional -description "Background color"}
          {-no_border -type none -description "Use a splash window style (no border)"}
          {-log_file -type file -optional -description "Optional message log file"}
          {text -type string -multiple -description "Multiple text lines to display"}
       }
    } {

    *   puts "display message:"
       foreach var {mtype font level fg bg no_border log_file text} {
          if {[info exists $var]} {
             puts  "  $var=[set $var]"


          }
       }
    *}

A call of procedure that has been declared in this way will first invoke the
TEPAM argument manager, before the procedure body is executed\. The argument
manager parses the provided arguments, validates them, completes them eventually
with some default values, and makes them finally available to the procedure body
as local variables\. In case an argument is missing or has a wrong type, the
argument manager generates an error message that explains the reason for the
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
the named arguments \(Tk style\)\.

# <a name='section4'></a>PROCEDURE HELP

The declared procedure can simply be called with the *\-help* option to get the
information about the usage of the procedure and its arguments:

    __display message__ \-help

* \-> NAME display message \- Displays a simple message box SYNOPSYS display
message \[\-mtype <mtype>\] : Message type, default: "Warning", choices: \{Info
Warning Error\} \[\-font <font>\] : Message text font, type: font, default: Arial 10
italic \[\-level <level>\] : Message level, type: integer, range: 1\.\.10 \[\-fg <fg>\]
: Message color, type: color, default: black \[\-bg <bg>\] : Background color,
type: color \[\-no\_border \] : Use a splash window style \(no border\) \[\-log\_file
<log\_file>\] : Optional message log file, type: file <text> : Multiple text lines
to display, type: string DESCRIPTION This procedure allows displaying a
configurable message box\.*

# <a name='section5'></a>PROCEDURE CALL

The specified procedure can be called in many ways\. The following listing shows
some valid procedure calls:

    __display message__ "The document hasn't yet been saved\!"
    *\-> display message:
         mtype=Warning
         font=Arial 10 italic
         fg=black
         no\_border=0
         text=\{The document hasn't yet been saved\!\}*

    __display message__ \-fg red \-bg black "Please save first the document"
    *\-> display message:
         mtype=Warning
         font=Arial 10 italic
         fg=red
         bg=black
         no\_border=0
         text=\{Please save first the document\}*

    __display message__ \-mtype Error \-no\_border "Why is here no border?"
    *\-> display message:
         mtype=Error
         font=Arial 10 italic
         fg=black
         no\_border=1
         text=\{Why is here no border?\}*

    __display message__ \-font \{Courier 12\} \-level 10 \\
       "Is there enough space?" "Reduce otherwise the font size\!"

*\-> display message: mtype=Warning font=Courier 12 level=10 fg=black
no\_border=0 text=\{Is there enough space?\} \{Reduce otherwise the font size\!\}*
The next lines show how wrong arguments are recognized\. The *text* argument
that is mandatory is missing in the first procedure call:

    __display message__ \-font \{Courier 12\}

* \-> display message: Required argument is missing: text* Only known arguments
are accepted:

    __display message__ \-category warning Hello

* \-> display message: Argument '\-category' not known* Argument types are
automatically checked and an error message is generated in case the argument
value has not the expected type:

    __display message__ \-fg MyColor "Hello"

* \-> display message: Argument 'fg' requires type 'color'\. Provided value:
'MyColor'* Selection choices have to be respected \.\.\.

    __display message__ \-mtype Fatal Hello

* \-> display message: Argument \(mtype\) has to be one of the following elements:
Info, Warning, Error* \.\.\. as well as valid value ranges:

    __display message__ \-level 12 Hello

* \-> display message: Argument \(level\) has to be between 1 and 10*

# <a name='section6'></a>INTERACTIVE PROCEDURE CALLS

The most intuitive way to call the procedure is using an form that allows
specifying all arguments interactively\. This form will automatically be
generated if the declared procedure is called with the *\-interactive* flag\. To
use this feature the Tk library has to be loaded\.

    __display message__ \-interactive

The generated form contains for each argument a data entry widget that is
adapted to the argument type\. Check buttons are used to specify flags, radio
boxes for tiny choice lists, disjoint list boxes for larger choice lists and
files, directories, fonts and colors can be selected with dedicated browsers\.

After acknowledging the specified argument data via an OK button, the entered







|
















|
|



|
|

|
|




|
|

|
|



|
|

|
|






|




|





|




|




|










|







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
the named arguments \(Tk style\)\.

# <a name='section4'></a>PROCEDURE HELP

The declared procedure can simply be called with the *\-help* option to get the
information about the usage of the procedure and its arguments:

    __display message__ -help

* \-> NAME display message \- Displays a simple message box SYNOPSYS display
message \[\-mtype <mtype>\] : Message type, default: "Warning", choices: \{Info
Warning Error\} \[\-font <font>\] : Message text font, type: font, default: Arial 10
italic \[\-level <level>\] : Message level, type: integer, range: 1\.\.10 \[\-fg <fg>\]
: Message color, type: color, default: black \[\-bg <bg>\] : Background color,
type: color \[\-no\_border \] : Use a splash window style \(no border\) \[\-log\_file
<log\_file>\] : Optional message log file, type: file <text> : Multiple text lines
to display, type: string DESCRIPTION This procedure allows displaying a
configurable message box\.*

# <a name='section5'></a>PROCEDURE CALL

The specified procedure can be called in many ways\. The following listing shows
some valid procedure calls:

    __display message__ "The document hasn't yet been saved!"
    *-> display message:
         mtype=Warning
         font=Arial 10 italic
         fg=black
         no_border=0
         text={The document hasn't yet been saved!}*

    __display message__ -fg red -bg black "Please save first the document"
    *-> display message:
         mtype=Warning
         font=Arial 10 italic
         fg=red
         bg=black
         no_border=0
         text={Please save first the document}*

    __display message__ -mtype Error -no_border "Why is here no border?"
    *-> display message:
         mtype=Error
         font=Arial 10 italic
         fg=black
         no_border=1
         text={Why is here no border?}*

    __display message__ -font {Courier 12} -level 10 \
       "Is there enough space?" "Reduce otherwise the font size!"

*\-> display message: mtype=Warning font=Courier 12 level=10 fg=black
no\_border=0 text=\{Is there enough space?\} \{Reduce otherwise the font size\!\}*
The next lines show how wrong arguments are recognized\. The *text* argument
that is mandatory is missing in the first procedure call:

    __display message__ -font {Courier 12}

* \-> display message: Required argument is missing: text* Only known arguments
are accepted:

    __display message__ -category warning Hello

* \-> display message: Argument '\-category' not known* Argument types are
automatically checked and an error message is generated in case the argument
value has not the expected type:

    __display message__ -fg MyColor "Hello"

* \-> display message: Argument 'fg' requires type 'color'\. Provided value:
'MyColor'* Selection choices have to be respected \.\.\.

    __display message__ -mtype Fatal Hello

* \-> display message: Argument \(mtype\) has to be one of the following elements:
Info, Warning, Error* \.\.\. as well as valid value ranges:

    __display message__ -level 12 Hello

* \-> display message: Argument \(level\) has to be between 1 and 10*

# <a name='section6'></a>INTERACTIVE PROCEDURE CALLS

The most intuitive way to call the procedure is using an form that allows
specifying all arguments interactively\. This form will automatically be
generated if the declared procedure is called with the *\-interactive* flag\. To
use this feature the Tk library has to be loaded\.

    __display message__ -interactive

The generated form contains for each argument a data entry widget that is
adapted to the argument type\. Check buttons are used to specify flags, radio
boxes for tiny choice lists, disjoint list boxes for larger choice lists and
files, directories, fonts and colors can be selected with dedicated browsers\.

After acknowledging the specified argument data via an OK button, the entered
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
entry forms\. It creates an input mask that allows specifying a file to copy, a
destination folder as well as a checkbox that allows specifying if an eventual
existing file can be overwritten\. Comfortable browsers can be used to select
files and directories\. And finally, the form offers also the possibility to
accept and decline the selection\. Here is the code snippet that is doing all
this:

    __[tepam::argument\_dialogbox](tepam\_argument\_dialogbox\.md)__ \\
       __\-existingfile__ \{\-label "Source file" \-variable SourceFile\} \\
       __\-existingdirectory__ \{\-label "Destination folder" \-variable DestDir\} \\
       __\-checkbutton__ \{\-label "Overwrite existing file" \-variable Overwrite\}

The __argument\_dialogbox__ returns __ok__ if the entered data are
validated\. It will return __cancel__ if the data entry has been canceled\.
After the validation of the entered data, the __argument\_dialogbox__ defines
all the specified variables with the entered data inside the calling context\.

An __argument\_dialogbox__ requires a pair of arguments for each variable







|
|
|
|







314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
entry forms\. It creates an input mask that allows specifying a file to copy, a
destination folder as well as a checkbox that allows specifying if an eventual
existing file can be overwritten\. Comfortable browsers can be used to select
files and directories\. And finally, the form offers also the possibility to
accept and decline the selection\. Here is the code snippet that is doing all
this:

    __[tepam::argument_dialogbox](tepam_argument_dialogbox.md)__ \
       __-existingfile__ {-label "Source file" -variable SourceFile} \
       __-existingdirectory__ {-label "Destination folder" -variable DestDir} \
       __-checkbutton__ {-label "Overwrite existing file" -variable Overwrite}

The __argument\_dialogbox__ returns __ok__ if the entered data are
validated\. It will return __cancel__ if the data entry has been canceled\.
After the validation of the entered data, the __argument\_dialogbox__ defines
all the specified variables with the entered data inside the calling context\.

An __argument\_dialogbox__ requires a pair of arguments for each variable
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
expected data types, valid data ranges, etc\.

The next example of a more complex argument dialog box provides a good overview
about the different available entry widget types and parameter attributes\. The
example contains also some formatting instructions like *\-frame* and *\-sep*
which allows organizing the different entry widgets in frames and sections:

    set ChoiceList \{"Choice 1" "Choice 2" "Choice 3" "Choice 4" "Choice 5" "Choice 6"\}

    set Result \[__[tepam::argument\_dialogbox](tepam\_argument\_dialogbox\.md)__ \\
       __\-title__ "System configuration" \\
       __\-context__ test\_1 \\
       __\-frame__ \{\-label "Entries"\} \\
          __\-entry__ \{\-label Entry1 \-variable Entry1\} \\
          __\-entry__ \{\-label Entry2 \-variable Entry2 \-default "my default"\} \\
       __\-frame__ \{\-label "Listbox & combobox"\} \\
          __\-listbox__ \{\-label "Listbox, single selection" \-variable Listbox1 \\
                    \-choices \{1 2 3 4 5 6 7 8\} \-default 1 \-height 3\} \\
          __\-listbox__ \{\-label "Listbox, multiple selection" \-variable Listbox2
                    \-choicevariable ChoiceList \-default \{"Choice 2" "Choice 3"\}
                    \-multiple\_selection 1 \-height 3\} \\
          __\-disjointlistbox__ \{\-label "Disjoined listbox" \-variable DisJntListbox
                            \-choicevariable ChoiceList \\
                            \-default \{"Choice 3" "Choice 5"\} \-height 3\} \\
          __\-combobox__ \{\-label "Combobox" \-variable Combobox \\
                     \-choices \{1 2 3 4 5 6 7 8\} \-default 3\} \\
       __\-frame__ \{\-label "Checkbox, radiobox and checkbutton"\} \\
          __\-checkbox__ \{\-label Checkbox \-variable Checkbox
                     \-choices \{bold italic underline\} \-choicelabels \{Bold Italic Underline\} \\
                     \-default italic\} \\
          __\-radiobox__ \{\-label Radiobox \-variable Radiobox
                     \-choices \{bold italic underline\} \-choicelabels \{Bold Italic Underline\} \\
                     \-default underline\} \\
          __\-checkbutton__ \{\-label CheckButton \-variable Checkbutton \-default 1\} \\
       __\-frame__ \{\-label "Files & directories"\} \\
          __\-existingfile__ \{\-label "Input file" \-variable InputFile\} \\
          __\-file__ \{\-label "Output file" \-variable OutputFile\} \\
          __\-sep__ \{\} \\
          __\-existingdirectory__ \{\-label "Input directory" \-variable InputDirectory\} \\
          __\-directory__ \{\-label "Output irectory" \-variable OutputDirectory\} \\
       __\-frame__ \{\-label "Colors and fonts"\} \\
          __\-color__ \{\-label "Background color" \-variable Color \-default red\} \\
          __\-sep__ \{\} \\
          __\-font__ \{\-label "Font" \-variable Font \-default \{Courier 12 italic\}\}

\] The __argument\_dialogbox__ defines all the specified variables with the
entered data and returns __ok__ if the data have been validated via the Ok
button\. If the data entry is cancelled by activating the Cancel button, the
__argument\_dialogbox__ returns __cancel__\.

    if \{$Result=="cancel"\} \{
       puts "Canceled"
    \} else \{ \# $Result=="ok"
       puts "Arguments: "
       foreach Var \{
          Entry1 Entry2
          Listbox1 Listbox2 DisJntListbox
          Combobox Checkbox Radiobox Checkbutton
          InputFile OutputFile InputDirectory OutputDirectory
          Color Font
       \} \{
          puts "  $Var: '\[set $Var\]'"
       \}
    \}



*\-> Arguments: Entry1: 'Hello, this is a trial' Entry2: 'my default' Listbox1:
'1' Listbox2: '\{Choice 2\} \{Choice 3\}' DisJntListbox: '\{Choice 3\} \{Choice 5\}'
Combobox: '3' Checkbox: 'italic' Radiobox: 'underline' Checkbutton: '1'
InputFile: 'c:\\tepam\\in\.txt' OutputFile: 'c:\\tepam\\out\.txt' InputDirectory:
'c:\\tepam\\input' OutputDirectory: 'c:\\tepam\\output' Color: 'red' Font: 'Courier
12 italic'*







|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|






|

|

|





|
|
<
<
>
>







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
expected data types, valid data ranges, etc\.

The next example of a more complex argument dialog box provides a good overview
about the different available entry widget types and parameter attributes\. The
example contains also some formatting instructions like *\-frame* and *\-sep*
which allows organizing the different entry widgets in frames and sections:

    set ChoiceList {"Choice 1" "Choice 2" "Choice 3" "Choice 4" "Choice 5" "Choice 6"}

    set Result [__[tepam::argument_dialogbox](tepam_argument_dialogbox.md)__ \
       __-title__ "System configuration" \
       __-context__ test_1 \
       __-frame__ {-label "Entries"} \
          __-entry__ {-label Entry1 -variable Entry1} \
          __-entry__ {-label Entry2 -variable Entry2 -default "my default"} \
       __-frame__ {-label "Listbox & combobox"} \
          __-listbox__ {-label "Listbox, single selection" -variable Listbox1 \
                    -choices {1 2 3 4 5 6 7 8} -default 1 -height 3} \
          __-listbox__ {-label "Listbox, multiple selection" -variable Listbox2
                    -choicevariable ChoiceList -default {"Choice 2" "Choice 3"}
                    -multiple_selection 1 -height 3} \
          __-disjointlistbox__ {-label "Disjoined listbox" -variable DisJntListbox
                            -choicevariable ChoiceList \
                            -default {"Choice 3" "Choice 5"} -height 3} \
          __-combobox__ {-label "Combobox" -variable Combobox \
                     -choices {1 2 3 4 5 6 7 8} -default 3} \
       __-frame__ {-label "Checkbox, radiobox and checkbutton"} \
          __-checkbox__ {-label Checkbox -variable Checkbox
                     -choices {bold italic underline} -choicelabels {Bold Italic Underline} \
                     -default italic} \
          __-radiobox__ {-label Radiobox -variable Radiobox
                     -choices {bold italic underline} -choicelabels {Bold Italic Underline} \
                     -default underline} \
          __-checkbutton__ {-label CheckButton -variable Checkbutton -default 1} \
       __-frame__ {-label "Files & directories"} \
          __-existingfile__ {-label "Input file" -variable InputFile} \
          __-file__ {-label "Output file" -variable OutputFile} \
          __-sep__ {} \
          __-existingdirectory__ {-label "Input directory" -variable InputDirectory} \
          __-directory__ {-label "Output irectory" -variable OutputDirectory} \
       __-frame__ {-label "Colors and fonts"} \
          __-color__ {-label "Background color" -variable Color -default red} \
          __-sep__ {} \
          __-font__ {-label "Font" -variable Font -default {Courier 12 italic}}

\] The __argument\_dialogbox__ defines all the specified variables with the
entered data and returns __ok__ if the data have been validated via the Ok
button\. If the data entry is cancelled by activating the Cancel button, the
__argument\_dialogbox__ returns __cancel__\.

    if {$Result=="cancel"} {
       puts "Canceled"
    } else { # $Result=="ok"
       puts "Arguments: "
       foreach Var {
          Entry1 Entry2
          Listbox1 Listbox2 DisJntListbox
          Combobox Checkbox Radiobox Checkbutton
          InputFile OutputFile InputDirectory OutputDirectory
          Color Font
       } {
          puts "  $Var: '[set $Var]'"


       }
    }

*\-> Arguments: Entry1: 'Hello, this is a trial' Entry2: 'my default' Listbox1:
'1' Listbox2: '\{Choice 2\} \{Choice 3\}' DisJntListbox: '\{Choice 3\} \{Choice 5\}'
Combobox: '3' Checkbox: 'italic' Radiobox: 'underline' Checkbutton: '1'
InputFile: 'c:\\tepam\\in\.txt' OutputFile: 'c:\\tepam\\out\.txt' InputDirectory:
'c:\\tepam\\input' OutputDirectory: 'c:\\tepam\\output' Color: 'red' Font: 'Courier
12 italic'*
Changes to embedded/md/tcllib/files/modules/tepam/tepam_procedure.md.
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
    commands are incorporated into a single main command and are selectable via
    the first argument\.

    The __string__ command is an example of such a command that implements
    for example subcommands to check a character string length, to compare
    strings, to extract substrings, etc:

        __string length__ *string*
        __string compare__ *string* *string*
        __string range__ *string* *first* *last*
        \.\.\.

    TEPAM provides a framework that allows implementing easily such subcommands
    in form of Tcl procedures\. It allows not only defining a first level of
    subcommands, but also a higher level of subcommands\. The __string__
    command class check could be implemented as independent sub\-sub\-commands of
    the __string__ command:

        __string is alnum__ *string*
        __string is integer__ *string*
        __string is double__ *string*
        \.\.\.

  - *Procedure attribute*

    TEPAM allows attaching to a declared procedure different kind of attributes\.
    Some of these attributes are *just* used for documentation purposes, but
    other attributes specify the way how the procedure has to be called\. Also
    the procedure arguments are defined in form of a procedure attribute\.

  - *Argument*

    TEPAM uses the term *argument* for the parameters of a procedure\.

    The following example calls the subcommand __string compare__ with
    several arguments:

        __string compare__

    *\-nocase \-length 3 "emphasized" "emphasised"* The following paragraphs
    discuss these different argument types\.

  - *Named argument*

    Some parameters, as *\-length 3* of the subcommand __string compare__







|
|
|
|







|
|
|
|















|







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
    commands are incorporated into a single main command and are selectable via
    the first argument\.

    The __string__ command is an example of such a command that implements
    for example subcommands to check a character string length, to compare
    strings, to extract substrings, etc:

        __string length__ *string*
        __string compare__ *string* *string*
        __string range__ *string* *first* *last*
        ...

    TEPAM provides a framework that allows implementing easily such subcommands
    in form of Tcl procedures\. It allows not only defining a first level of
    subcommands, but also a higher level of subcommands\. The __string__
    command class check could be implemented as independent sub\-sub\-commands of
    the __string__ command:

        __string is alnum__ *string*
        __string is integer__ *string*
        __string is double__ *string*
        ...

  - *Procedure attribute*

    TEPAM allows attaching to a declared procedure different kind of attributes\.
    Some of these attributes are *just* used for documentation purposes, but
    other attributes specify the way how the procedure has to be called\. Also
    the procedure arguments are defined in form of a procedure attribute\.

  - *Argument*

    TEPAM uses the term *argument* for the parameters of a procedure\.

    The following example calls the subcommand __string compare__ with
    several arguments:

        __string compare__

    *\-nocase \-length 3 "emphasized" "emphasised"* The following paragraphs
    discuss these different argument types\.

  - *Named argument*

    Some parameters, as *\-length 3* of the subcommand __string compare__
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

  - *Named arguments first, unnamed arguments later*

    The __string compare__ command of the previous example requires that the
    *named arguments* \(options, flags\) are provided first\. The two mandatory
    \(unnamed\) arguments have to be provided as last argument\.

        __string compare__

    *\-nocase \-length 3 Water $Text* This is the usual Tcl style \(exceptions
    exist\) which is referred in the TEPAM documentation as *named arguments
    first, unnamed arguments later style*\.

  - *Unnamed arguments first, named arguments later*

    In contrast to most Tcl commands, Tk uses generally \(exceptions exist also
    here\) a different calling style where the *unnamed arguments* have to be
    provided first, before the *named arguments* have to be provided:

        __pack__

    *\.ent1 \.ent2 \-fill x \-expand yes \-side left* This style is referred in the
    TEPAM documentation as *unnamed arguments first, named arguments later
    style*\.

# <a name='section3'></a>PROCEDURE DECLARATION

TEPAM allows declaring new Tcl procedures with the command
__tepam::procedure__ that has similar to the standard Tcl command
__proc__ also 3 arguments:

  - <a name='1'></a>__tepam::procedure__ *name* *attributes* *body*

The TEPAM procedure declaration syntax is demonstrated by the following example:

    __tepam::procedure__ \{display message\} \{
       \-short\_description
          "Displays a simple message box"
       \-description
          "This procedure allows displaying a configurable\\
           message box\. The default message type that is\\
           created is a warning, but also errors and info can\\
           be generated\.
           The procedure accepts multiple text lines\."
       \-example
          \{display message \-mtype Warning "Save first your job"\}
       \-args \{
          \{\-mtype \-choices \{Info Warning Error\} \\
                  \-default Warning \-description "Message type"\}
          \{text   \-type string \-multiple \\
                  \-description "Multiple text lines to display"\}

       \}
    \} \{
       puts "Message type: $mtype"
       puts "Message: $text"
    \}


The 3 arguments of __procedure__ are:

  - *name*

    The procedure name can be used in very flexible ways\. Procedure names can
    have namespace qualifiers\. By providing a two element name list as procedure
    name, a subcommand of a procedure will be declared\. It is even possible to
    declare sub\-sub\-commands of a procedure by providing name lists with three
    elements\.

    Here are some valid procedure declarations using different procedure names
    \(the attribute and body arguments are empty for simplicity\):

    *\# Simple procedure name:*
    tepam::procedure __display\_message__ \{\} \{\}
    **
    *\# Procedure declared in the main namespace:*
    tepam::procedure __::display\_message__ \{\} \{\}
    **
    *\# Procedure in the namespace* __::ns__*:*
    tepam::procedure __::ns::display\_message__ \{\} \{\}
    **
    *\# Declaration of the subcommand* __message__ *of the procedure* __display__*:*
    tepam::procedure __\{display message\}__ \{\} \{\}

  - *attributes*

    All procedure attributes are provided in form of an option list that
    contains pairs of option names and option values\. The example above has as
    procedure attribute a short and a normal description, but also the procedure
    arguments are defined in form of a procedure attribute\.







|











|















|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
<


<
>














|
|
|
|
|
|
|
|
|
|
|







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

  - *Named arguments first, unnamed arguments later*

    The __string compare__ command of the previous example requires that the
    *named arguments* \(options, flags\) are provided first\. The two mandatory
    \(unnamed\) arguments have to be provided as last argument\.

        __string compare__

    *\-nocase \-length 3 Water $Text* This is the usual Tcl style \(exceptions
    exist\) which is referred in the TEPAM documentation as *named arguments
    first, unnamed arguments later style*\.

  - *Unnamed arguments first, named arguments later*

    In contrast to most Tcl commands, Tk uses generally \(exceptions exist also
    here\) a different calling style where the *unnamed arguments* have to be
    provided first, before the *named arguments* have to be provided:

        __pack__

    *\.ent1 \.ent2 \-fill x \-expand yes \-side left* This style is referred in the
    TEPAM documentation as *unnamed arguments first, named arguments later
    style*\.

# <a name='section3'></a>PROCEDURE DECLARATION

TEPAM allows declaring new Tcl procedures with the command
__tepam::procedure__ that has similar to the standard Tcl command
__proc__ also 3 arguments:

  - <a name='1'></a>__tepam::procedure__ *name* *attributes* *body*

The TEPAM procedure declaration syntax is demonstrated by the following example:

    __tepam::procedure__ {display message} {
       -short_description
          "Displays a simple message box"
       -description
          "This procedure allows displaying a configurable\
           message box. The default message type that is\
           created is a warning, but also errors and info can\
           be generated.
           The procedure accepts multiple text lines."
       -example
          {display message -mtype Warning "Save first your job"}
       -args {
          {-mtype -choices {Info Warning Error} \
                  -default Warning -description "Message type"}
          {text   -type string -multiple \
                  -description "Multiple text lines to display"}
       }
    } {

       puts "Message type: $mtype"
       puts "Message: $text"

    }

The 3 arguments of __procedure__ are:

  - *name*

    The procedure name can be used in very flexible ways\. Procedure names can
    have namespace qualifiers\. By providing a two element name list as procedure
    name, a subcommand of a procedure will be declared\. It is even possible to
    declare sub\-sub\-commands of a procedure by providing name lists with three
    elements\.

    Here are some valid procedure declarations using different procedure names
    \(the attribute and body arguments are empty for simplicity\):

    *# Simple procedure name:*
    tepam::procedure __display_message__ {} {}
    **
    *# Procedure declared in the main namespace:*
    tepam::procedure __::display_message__ {} {}
    **
    *# Procedure in the namespace* __::ns__*:*
    tepam::procedure __::ns::display_message__ {} {}
    **
    *# Declaration of the subcommand* __message__ *of the procedure* __display__*:*
    tepam::procedure __{display message}__ {} {}

  - *attributes*

    All procedure attributes are provided in form of an option list that
    contains pairs of option names and option values\. The example above has as
    procedure attribute a short and a normal description, but also the procedure
    arguments are defined in form of a procedure attribute\.
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

    This is the normal procedure body\. The declared arguments will be available
    to the procedure body in form of variables\.

    The procedure body will only be executed if the provided set of arguments
    could be validated by the TEPAM argument manager\.

    tepam::procedure \{display\_message\} \{
       \-args \{
          \{\-__mtype__ \-default Warning \-choices \{Warning Error\}\}
          \{__text__ \-type string\}

       \}
    \} \{
       puts "Message type: __$mtype__"
       puts "Message: __$text__"
    \}


The commands __[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ as well as
__argument\_dialogbox__ are exported from the namespace __tepam__\. To use
these commands without the __tepam::__ namespace prefix, it is sufficient to
import them into the main namespace:

    __namespace import tepam::\*__

    __[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ \{display\_message\} \{
       \-args \{
          \.\.\.

## <a name='subsection1'></a>Procedure Attributes

The first group of attributes affect the behavior of the declared procedure:

  - \-named\_arguments\_first __0__&#124;__1__








|
|
|
|
>
|
<
|
|
<
>






|

|
|
|







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

    This is the normal procedure body\. The declared arguments will be available
    to the procedure body in form of variables\.

    The procedure body will only be executed if the provided set of arguments
    could be validated by the TEPAM argument manager\.

    tepam::procedure {display_message} {
       -args {
          {-__mtype__ -default Warning -choices {Warning Error}}
          {__text__ -type string}
       }
    } {

       puts "Message type: __$mtype__"
       puts "Message: __$text__"

    }

The commands __[procedure](\.\./\.\./\.\./\.\./index\.md\#procedure)__ as well as
__argument\_dialogbox__ are exported from the namespace __tepam__\. To use
these commands without the __tepam::__ namespace prefix, it is sufficient to
import them into the main namespace:

    __namespace import tepam::*__

    __[procedure](../../../../index.md#procedure)__ {display_message} {
       -args {
          ...

## <a name='subsection1'></a>Procedure Attributes

The first group of attributes affect the behavior of the declared procedure:

  - \-named\_arguments\_first __0__&#124;__1__

363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
  - \-validatecommand *script*

    Custom argument validations can be performed via specific validation
    commands that are defined with the *\-validatecommand* attribute\.

    Validation command declaration example:

    tepam::procedure \{display\_message\} \{
       \-args \{
          \{text \-type string \-description "Message text"\} \}
       __\-validatecommand \{IllegalWordDetector $text\}__
    \} \{
    \}


    The validation command is executed in the context of the declared procedure
    body\. The different argument values are accessed via the argument names\.
    Note there is also an argument attribute *\-validatecommand* that allows
    declaring custom checks for specific arguments\.

    The attribute *\-validatecommand* can be repeated to declare multiple







|
|
|
|
|
<
>







363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
  - \-validatecommand *script*

    Custom argument validations can be performed via specific validation
    commands that are defined with the *\-validatecommand* attribute\.

    Validation command declaration example:

    tepam::procedure {display_message} {
       -args {
          {text -type string -description "Message text"} }
       __-validatecommand {IllegalWordDetector $text}__
    } {

    }

    The validation command is executed in the context of the declared procedure
    body\. The different argument values are accessed via the argument names\.
    Note there is also an argument attribute *\-validatecommand* that allows
    declaring custom checks for specific arguments\.

    The attribute *\-validatecommand* can be repeated to declare multiple
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
    examples, using the *\-example* attribute\.

## <a name='subsection2'></a>Argument Declaration

The following example shows the structure that is used for the argument
definitions in the context of a procedure declaration:

    tepam::procedure \{display\_message\} \{
       \-args __\{
          \{\-mtype \-default Warning \-choices \{Info Warning Error\} \-description "Message type"\}
          \{\-font \-type font \-default \{Arial 10 italic\} \-description "Message text font"\}
          \{\-level \-type integer \-optional \-range \{1 10\} \-description "Message level"\}
          \{\-fg \-type color \-optional \-description "Message color"\}
          \{\-log\_file \-type file \-optional \-description "Optional message log file"\}
          \{text \-type string \-multiple \-description "Multiple text lines to display"\}
       \}__
    \} \{
    \}


Each of the procedure arguments is declared with a list that has as first
element the argument name, followed by eventual attributes\. The argument
definition syntax can be formalized in the following way:

    tepam::procedure <name> \{
       \-args __\{
          \{<argument\_name\_1> <arg\_attr\_name\_1a> <arg\_attr\_value\_1a>  <arg\_attr\_name\_1b> <arg\_attr\_value\_1b> \.\.\.\}
          \{<argument\_name\_2> <arg\_attr\_name\_2a> <arg\_attr\_value\_2a>  <arg\_attr\_name\_2b> <arg\_attr\_value\_2b> \.\.\.\}
          \.\.\.
       \}__
    \} <body>

The argument names and attributes have to be used in the following way:

  - Argument name \(*<argument\_name\_<n>>*\)

    The provided argument name specifies whether the argument is an *unnamed
    argument* or a *named argument*\. In addition to this, an argument name
    can also be blank to indicate an argument comment, or it can start with \# to
    indicate a section comment\.

      * *"<Name>"*

        This is the simplest form of an argument name: An argument whose name is
        not starting with '\-' is an *unnamed argument*\. The parameter provided
        during a procedure call will be assigned to a variable with the name
        *<Name>*\.

    tepam::procedure \{print\_string\} \{
       \-args \{
          \{__[text](\.\./\.\./\.\./\.\./index\.md\#text)__ \-type string \-description "This is an unnamed argument"\}

       \}
    \} \{
       puts __$text__
    \}

    print\_string __"Hello"__


        * \-> Hello*

      * *"\-<Name>"*

        An argument whose name starts with '\-' is a *named argument* \(also
        called *option*\)\. The parameter provided during a procedure call will
        be assigned to a variable with the name *<Name>* \(not *\-<Name>*\)\.

    tepam::procedure \{print\_string\} \{
       \-args \{
          \{__\-text__ \-type string \-description "This is a named argument"\}

       \}
    \} \{
       puts __$text__
    \}


    print\_string __\-text "Hello"__

        * \-> Hello*

      * *"\-\-"*

        This flag allows clearly specifying the end of the named arguments and
        the beginning of the unnamed arguments, in case the *named arguments
        first, unnamed arguments later style \(Tcl\)* has been selected\.

        If the *unnamed arguments first, named arguments later style \(Tk\)*
        style is selected, this flag is ignored if the unnamed arguments have
        already been parsed\. Otherwise it will be assigned to the corresponding
        unnamed argument\.

      * *"\-"* or *""*

        A blank argument name \(either '\-' or *''*\) starts a comment for the
        following arguments\.

    tepam::procedure \{print\_time\} \{
       \-interactive\_display\_format short
       \-args \{
          \{hours \-type integer \-description "Hour"\}
          \{minutes \-type integer \-description "Minute"\}

          __\{\- The following arguments are optional:\}__
          \{seconds \-type integer \-default 0 \-description "Seconds"\}
          \{milliseconds \-type integer \-default 0 \-description "Milliseconds"\}

       \}
    \} \{
       puts "$\{hour\}h$\{minutes\}:\[expr $seconds\+0\.001\*$milliseconds\]"
    \}


        Argument comments are basically used in the graphical argument
        definition forms that are created if a procedure is called
        interactively\.

      * *"\#\*"*

        An argument definition list that starts with '\#' is considered as a
        section comment\. The argument definition list will be trimmed from the
        '\#' characters and the remaining string will be used as section comment\.

        Section comments can be used to structure visually the argument
        definition code\. Section comments are also used to structure the
        generated help texts and the interactive argument definition forms\.

    tepam::procedure \{complex\_multiply\} \{
       \-description "This function perform a complex multiplication"
       \-args \{
          __\{\#\#\#\# First complex number \#\#\#\#\}__
          \{\-r0 \-type double \-description "First number real part"\}
          \{\-i0 \-type double \-description "First number imaginary part"\}

          __\{\#\#\#\# Second complex number \#\#\#\#\}__
          \{\-r1 \-type double \-description "Second number real part"\}
          \{\-i1 \-type double \-description "Second number imaginary part"\}

       \}
    \} \{
       return \[expr $r0\*$r1 \- $i0\*$i1\]
    \}


  - Argument attributes \(*<arg\_attr\_name\_<mn>> <arg\_attr\_value\_<mn>>*\)

    The following argument attributes are supported:

      * \-description *string*








|
|
|
|
|
|
|
|
|
|
<
>





|
|
|
|
|
|
|

















|
|
|
>
|
<
|
<
|
|
>









|
|
|
>
|
<
|
<
|
>
|



















|
|
|
|
|

|
|
|
>
|
<
|
<
>















|
|
|
|
|
|

|
|
|
>
|
<
|
<
>







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
    examples, using the *\-example* attribute\.

## <a name='subsection2'></a>Argument Declaration

The following example shows the structure that is used for the argument
definitions in the context of a procedure declaration:

    tepam::procedure {display_message} {
       -args __{
          {-mtype -default Warning -choices {Info Warning Error} -description "Message type"}
          {-font -type font -default {Arial 10 italic} -description "Message text font"}
          {-level -type integer -optional -range {1 10} -description "Message level"}
          {-fg -type color -optional -description "Message color"}
          {-log_file -type file -optional -description "Optional message log file"}
          {text -type string -multiple -description "Multiple text lines to display"}
       }__
    } {

    }

Each of the procedure arguments is declared with a list that has as first
element the argument name, followed by eventual attributes\. The argument
definition syntax can be formalized in the following way:

    tepam::procedure <name> {
       -args __{
          {<argument_name_1> <arg_attr_name_1a> <arg_attr_value_1a>  <arg_attr_name_1b> <arg_attr_value_1b> ...}
          {<argument_name_2> <arg_attr_name_2a> <arg_attr_value_2a>  <arg_attr_name_2b> <arg_attr_value_2b> ...}
          ...
       }__
    } <body>

The argument names and attributes have to be used in the following way:

  - Argument name \(*<argument\_name\_<n>>*\)

    The provided argument name specifies whether the argument is an *unnamed
    argument* or a *named argument*\. In addition to this, an argument name
    can also be blank to indicate an argument comment, or it can start with \# to
    indicate a section comment\.

      * *"<Name>"*

        This is the simplest form of an argument name: An argument whose name is
        not starting with '\-' is an *unnamed argument*\. The parameter provided
        during a procedure call will be assigned to a variable with the name
        *<Name>*\.

    tepam::procedure {print_string} {
       -args {
          {__[text](../../../../index.md#text)__ -type string -description "This is an unnamed argument"}
       }
    } {

       puts __$text__

    }

    print_string __"Hello"__

        * \-> Hello*

      * *"\-<Name>"*

        An argument whose name starts with '\-' is a *named argument* \(also
        called *option*\)\. The parameter provided during a procedure call will
        be assigned to a variable with the name *<Name>* \(not *\-<Name>*\)\.

    tepam::procedure {print_string} {
       -args {
          {__-text__ -type string -description "This is a named argument"}
       }
    } {

       puts __$text__

    }

    print_string __-text "Hello"__

        * \-> Hello*

      * *"\-\-"*

        This flag allows clearly specifying the end of the named arguments and
        the beginning of the unnamed arguments, in case the *named arguments
        first, unnamed arguments later style \(Tcl\)* has been selected\.

        If the *unnamed arguments first, named arguments later style \(Tk\)*
        style is selected, this flag is ignored if the unnamed arguments have
        already been parsed\. Otherwise it will be assigned to the corresponding
        unnamed argument\.

      * *"\-"* or *""*

        A blank argument name \(either '\-' or *''*\) starts a comment for the
        following arguments\.

    tepam::procedure {print_time} {
       -interactive_display_format short
       -args {
          {hours -type integer -description "Hour"}
          {minutes -type integer -description "Minute"}

          __{- The following arguments are optional:}__
          {seconds -type integer -default 0 -description "Seconds"}
          {milliseconds -type integer -default 0 -description "Milliseconds"}
       }
    } {

       puts "${hour}h${minutes}:[expr $seconds+0.001*$milliseconds]"

    }

        Argument comments are basically used in the graphical argument
        definition forms that are created if a procedure is called
        interactively\.

      * *"\#\*"*

        An argument definition list that starts with '\#' is considered as a
        section comment\. The argument definition list will be trimmed from the
        '\#' characters and the remaining string will be used as section comment\.

        Section comments can be used to structure visually the argument
        definition code\. Section comments are also used to structure the
        generated help texts and the interactive argument definition forms\.

    tepam::procedure {complex_multiply} {
       -description "This function perform a complex multiplication"
       -args {
          __{#### First complex number ####}__
          {-r0 -type double -description "First number real part"}
          {-i0 -type double -description "First number imaginary part"}

          __{#### Second complex number ####}__
          {-r1 -type double -description "Second number real part"}
          {-i1 -type double -description "Second number imaginary part"}
       }
    } {

       return [expr $r0*$r1 - $i0*$i1]

    }

  - Argument attributes \(*<arg\_attr\_name\_<mn>> <arg\_attr\_value\_<mn>>*\)

    The following argument attributes are supported:

      * \-description *string*

651
652
653
654
655
656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
        validation commands that are defined with the *\-validatecommand*
        attribute\. The provided validation command can be a complete script in
        which the pattern *%P* is replaced by the argument value that has to
        be validated\.

        Validation command declaration example:

    tepam::procedure \{display\_message\} \{
       \-args \{
          \{text \-type string \-description "Message text" \\
                __\-validatecommand \{IllegalWordDetector %P\}__\}
    \} \{
    \}


        While the purpose of this custom argument validation attribute is the
        validation of a specific argument, there is also a global attribute
        *\-validatecommand* that allows performing validation that involves
        multiple arguments\.

      * \-validatecommand\_error\_text *string*







|
|
|
|
|
<
>







651
652
653
654
655
656
657
658
659
660
661
662

663
664
665
666
667
668
669
670
        validation commands that are defined with the *\-validatecommand*
        attribute\. The provided validation command can be a complete script in
        which the pattern *%P* is replaced by the argument value that has to
        be validated\.

        Validation command declaration example:

    tepam::procedure {display_message} {
       -args {
          {text -type string -description "Message text" \
                __-validatecommand {IllegalWordDetector %P}__}
    } {

    }

        While the purpose of this custom argument validation attribute is the
        validation of a specific argument, there is also a global attribute
        *\-validatecommand* that allows performing validation that involves
        multiple arguments\.

      * \-validatecommand\_error\_text *string*
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
      * \-auxargs *list*

        In case a procedure is called interactively, additional argument
        attributes can be provided to the interactive argument definition form
        via the *\-auxargs* attribute that is itself a list of attribute
        name/attribute value pairs:

    \-auxargs \{\-<arg\_attr\_name\_1a> <arg\_attr\_value\_1a> \\
              \-<arg\_attr\_name\_1b> <arg\_attr\_value\_1b>
              \.\.\.
    \}


        For example, if a procedure takes as argument a file name it may be
        beneficial to specify the required file type for the interactive
        argument definition form\. This information can be provided via the
        *\-auxargs* attribute to the argument definition form:

    tepam::procedure LoadPicture \{
       \-args \{
          \{FileName \-type existingfile \-description "Picture file" \\
                     __\-auxargs \{\-filetypes \{\{"GIF" \{\*\.gif\}\} \{"JPG" \{\*\.jpg\}\} \}\}__\}

       \}
    \} \{
    \}


      * \-auxargs\_commands *script*

        If the auxiliary argument attributes are not static but have to be
        dynamically adaptable, the *\-auxargs\_commands* allows defining them
        via commands that are executed during a procedure call\. A list of pairs
        of auxiliary attribute names and commands has to be provided to the
        *\-auxargs\_commands* attribute\. The provided commands are executed in
        the context of the calling procedure\.

    \-auxargs\_commands \{\-<arg\_attr\_name\_1a> <arg\_attr\_command\_1a> \\
                       \-<arg\_attr\_name\_1b> <arg\_attr\_command\_1b>
                       \.\.\.
    \}


# <a name='section4'></a>VARIABLES

Several variables defined inside the __::tepam__ namespace impact the mode
of operation of the procedures that have been declared with the TEPAM
__procedure__ command\.

  - __named\_arguments\_first__

    This variable defines the general calling style of the procedures\. It is by
    default set to __1__ which selects the *named arguments first, unnamed
    arguments later* style \(Tcl style\)\.

    By setting this variable to __0__, the *named arguments first, unnamed
    arguments later* style is globally selected \(Tk style\):

    set tepam::named\_arguments\_first 0

    While this variable defines the general calling style, the procedure
    attribute *\-named\_arguments\_first* can adapt this style individually for
    each declared procedure\.

  - __auto\_argument\_name\_completion__

    This variable controls the general automatic argument name matching mode\. By
    default it is set to __1__, meaning that the called procedures are
    trying to match eventually abbreviated argument names with the declared
    argument names\.

    By setting this variable to __0__ the automatic argument name matching
    mode is disabled:

    set tepam::auto\_argument\_name\_completion 0

    While this variable defines the general matching mode, the procedure
    attribute *\-auto\_argument\_name\_completion* can adapt this mode
    individually for each declared procedure\.

  - __interactive\_display\_format__

    A procedure declared via the TEPAM __procedure__ command can always be
    called with the __\-interactive__ switch\. By doing so, a graphical form
    will be generated that allows entering interactively all procedure
    arguments\.

    There are two display modes for these interactive forms\. The *extended*
    mode which is the default mode is more adapted for small procedure argument
    sets\. The __short__ form is more adequate for huge procedure argument
    sets:

    set tepam::interactive\_display\_format "short"

    The choice to use short or extended forms can be globally configured via the
    variable __interactive\_display\_format__\. This global setting can be
    changed individually for a procedure with the procedure attribute
    *\-interactive\_display\_format*\.

  - __help\_line\_length__

    The maximum line length used by the procedure help text generator can be
    specified with this variable\. The default length which is set to 80
    \(characters\) can easily be adapted to the need of an application:

    set tepam::help\_line\_length 120

    Since this variable is applied directly during the help text generation, its
    value can continuously be adapted to the current need\.

  - __command\_log__

    Procedure calls can be logged inside the list variable







|
|
|
<
>






|
|
|
|
>
|
<
<
>










|
|
|
<
>
















|















|

















|












|







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
      * \-auxargs *list*

        In case a procedure is called interactively, additional argument
        attributes can be provided to the interactive argument definition form
        via the *\-auxargs* attribute that is itself a list of attribute
        name/attribute value pairs:

    -auxargs {-<arg_attr_name_1a> <arg_attr_value_1a> \
              -<arg_attr_name_1b> <arg_attr_value_1b>
              ...

    }

        For example, if a procedure takes as argument a file name it may be
        beneficial to specify the required file type for the interactive
        argument definition form\. This information can be provided via the
        *\-auxargs* attribute to the argument definition form:

    tepam::procedure LoadPicture {
       -args {
          {FileName -type existingfile -description "Picture file" \
                     __-auxargs {-filetypes {{"GIF" {*.gif}} {"JPG" {*.jpg}} }}__}
       }
    } {


    }

      * \-auxargs\_commands *script*

        If the auxiliary argument attributes are not static but have to be
        dynamically adaptable, the *\-auxargs\_commands* allows defining them
        via commands that are executed during a procedure call\. A list of pairs
        of auxiliary attribute names and commands has to be provided to the
        *\-auxargs\_commands* attribute\. The provided commands are executed in
        the context of the calling procedure\.

    -auxargs_commands {-<arg_attr_name_1a> <arg_attr_command_1a> \
                       -<arg_attr_name_1b> <arg_attr_command_1b>
                       ...

    }

# <a name='section4'></a>VARIABLES

Several variables defined inside the __::tepam__ namespace impact the mode
of operation of the procedures that have been declared with the TEPAM
__procedure__ command\.

  - __named\_arguments\_first__

    This variable defines the general calling style of the procedures\. It is by
    default set to __1__ which selects the *named arguments first, unnamed
    arguments later* style \(Tcl style\)\.

    By setting this variable to __0__, the *named arguments first, unnamed
    arguments later* style is globally selected \(Tk style\):

    set tepam::named_arguments_first 0

    While this variable defines the general calling style, the procedure
    attribute *\-named\_arguments\_first* can adapt this style individually for
    each declared procedure\.

  - __auto\_argument\_name\_completion__

    This variable controls the general automatic argument name matching mode\. By
    default it is set to __1__, meaning that the called procedures are
    trying to match eventually abbreviated argument names with the declared
    argument names\.

    By setting this variable to __0__ the automatic argument name matching
    mode is disabled:

    set tepam::auto_argument_name_completion 0

    While this variable defines the general matching mode, the procedure
    attribute *\-auto\_argument\_name\_completion* can adapt this mode
    individually for each declared procedure\.

  - __interactive\_display\_format__

    A procedure declared via the TEPAM __procedure__ command can always be
    called with the __\-interactive__ switch\. By doing so, a graphical form
    will be generated that allows entering interactively all procedure
    arguments\.

    There are two display modes for these interactive forms\. The *extended*
    mode which is the default mode is more adapted for small procedure argument
    sets\. The __short__ form is more adequate for huge procedure argument
    sets:

    set tepam::interactive_display_format "short"

    The choice to use short or extended forms can be globally configured via the
    variable __interactive\_display\_format__\. This global setting can be
    changed individually for a procedure with the procedure attribute
    *\-interactive\_display\_format*\.

  - __help\_line\_length__

    The maximum line length used by the procedure help text generator can be
    specified with this variable\. The default length which is set to 80
    \(characters\) can easily be adapted to the need of an application:

    set tepam::help_line_length 120

    Since this variable is applied directly during the help text generation, its
    value can continuously be adapted to the current need\.

  - __command\_log__

    Procedure calls can be logged inside the list variable
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
TEPAM provides a comprehensive set of procedure argument types\. They can easily
be completed with application specific types if necessary\.

## <a name='subsection3'></a>Predefined Argument Types

To remember, a type can be assigned to each specified procedure argument:

    tepam::procedure \{warning\} \{
       \-args \{
          \{\-font __\-type font__ \-default \{Arial 10 italic\}\}
          \{\-severity\_level __\-type integer__ \-optional \-range \{1 10\}\}
          \{\-fg __\-type color__ \-optional \-description "Message color"\}
          \{text __\-type string__ \-multiple \-description "Multiple text lines to display"\}

       \}
    \} \{
       \.\.\.
    \}


There are some *special purpose types* that are building the first category of
predefined argument types:

  - __none__ A *flag*, also called *switch*, is defined as a named
    argument that has the type __none__\. Flags are always optional and the
    default value of the assigned variable is set to __0__\. In contrast to
    the \(normal\) named arguments, no argument value has to be provided to a
    flag\.

    tepam::procedure flag\_test \{
       \-args \{
          __\{\-flag \-type none \-description "This is a flag"\}__

       \}
    \} \{
       puts __$flag__
    \}


    flag\_test
    *\-> 0*

    flag\_test \-flag

    *\-> 1*

    Since no argument value has to be provided to a flag, also no data check is
    performed for this argument type\.

  - __string__ __String__ is a generic argument data type\. Any data







|
|
|
|
|
|
>
|
<
|
<
>










|
|
|
>
|
<
|
<
|
>
|
|

|







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
TEPAM provides a comprehensive set of procedure argument types\. They can easily
be completed with application specific types if necessary\.

## <a name='subsection3'></a>Predefined Argument Types

To remember, a type can be assigned to each specified procedure argument:

    tepam::procedure {warning} {
       -args {
          {-font __-type font__ -default {Arial 10 italic}}
          {-severity_level __-type integer__ -optional -range {1 10}}
          {-fg __-type color__ -optional -description "Message color"}
          {text __-type string__ -multiple -description "Multiple text lines to display"}
       }
    } {

       ...

    }

There are some *special purpose types* that are building the first category of
predefined argument types:

  - __none__ A *flag*, also called *switch*, is defined as a named
    argument that has the type __none__\. Flags are always optional and the
    default value of the assigned variable is set to __0__\. In contrast to
    the \(normal\) named arguments, no argument value has to be provided to a
    flag\.

    tepam::procedure flag_test {
       -args {
          __{-flag -type none -description "This is a flag"}__
       }
    } {

       puts __$flag__

    }

    flag_test
    *-> 0*

    flag_test -flag

    *\-> 1*

    Since no argument value has to be provided to a flag, also no data check is
    performed for this argument type\.

  - __string__ __String__ is a generic argument data type\. Any data
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

Several *numerical types* are defined by TEPAM\. The type validation procedures
are using the __string is <type> \-strict__ commands to check the validity of
the provided arguments, which assures that no empty strings are accepted as
argument value\. The type validation expression for the numerical types and the
argument types to which this expression is applied are:

    string is __<type\_to\_check>__ \-strict

*<argument\_value>*

  - *boolean*

  - *integer*

  - *double*

Empty strings are accepted as argument value for all the alpha numeric argument
types\. The argument types that are falling into this category and validation
expression used for them are:

    string is *<type\_to\_check>*

*<argument\_value>*

  - *alnum*

  - *alpha*








|













|







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

Several *numerical types* are defined by TEPAM\. The type validation procedures
are using the __string is <type> \-strict__ commands to check the validity of
the provided arguments, which assures that no empty strings are accepted as
argument value\. The type validation expression for the numerical types and the
argument types to which this expression is applied are:

    string is __<type_to_check>__ -strict

*<argument\_value>*

  - *boolean*

  - *integer*

  - *double*

Empty strings are accepted as argument value for all the alpha numeric argument
types\. The argument types that are falling into this category and validation
expression used for them are:

    string is *<type_to_check>*

*<argument\_value>*

  - *alnum*

  - *alpha*

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

In addition to the data types checked with the __string is <type>__
commands, TEPAM specifies some other useful data types:

  - *char* Each string that has a length of 1 character meets the
    *character* type\. The type check is made with the following expression:

    expr \[string length *<argument\_value>*\]==1

  - *color* Any character strings that are accepted by Tk as a color are
    considered as valid color argument\. Please note that the Tk package has to
    be loaded to use the type *color*\. TEPAM is using the following command to
    validate the color type:

    expr \!\[catch \{winfo rgb \. *<argument\_value>*\}

    \]

  - *font* Any character strings that are accepted by Tk as a font are
    considered as valid font argument\. Please note that the Tk package has to be
    loaded to use the *font* type\. TEPAM is using the following command to
    validate the color type:

    expr \!\[catch \{font measure <argument\_value> ""\}

    \]

  - *file* Any strings that are not containing one of the following characters
    are considered as valid file names: \* ? " < >\. It is not necessary that the
    file and its containing directory exist\. Zero\-length strings are not
    considered as valid file names\.

    The following expression is used to validate the file names:

    expr \[string length <argument\_value>\]>0 && \!\[regexp \{\[\\"\*?<>:\]\} <argument\_value>

    \]

  - *existingfile* The argument is valid if it matches with an existing file\.
    The following check is performed to validate the arguments of this type:

    file exists <argument\_value>

  - *directory* The directory argument is validated exactly in the same way as
    the file arguments\.

  - *existingdirectory* The argument is valid if it matches with an existing
    directory\. The following check is performed to validate the arguments of
    this type:

    file isdirectory <argument\_value>

## <a name='subsection4'></a>Defining Application Specific Argument Types

To add support for a new application specific argument type it is just necessary
to add into the namespace __tepam__ a validation function
__Validation\(<type>\)__\. This function requires one argument\. It has to
returns __1__ if the provided argument matches with the relevant data type\.
The function has to return otherwise __0__\.

The validation command section of the "tepam\.tcl" package provides sufficient
examples of validation functions, since it implements the ones for the standard
TEPAM types\.

The following additional code snippet shows the validation function for a custom
argument type that requires values that have a character string length of
exactly 2:

    proc tepam::Validate\(two\_char\) \{v\} \{expr \{\[string length $v\]==2\}\}

# <a name='section6'></a>PROCEDURE CALLS

## <a name='subsection5'></a>Help

Each procedure can be called with the *\-help* flag\. The procedure will then
print a generated help text to *stdout* and will then return without
performing any additional actions\.

Taking the first procedure declared in [PROCEDURE CALLS](#section6), the
help request and the printed help text would be:

    __display message \-help__

*\-> NAME display message \- Displays a simple message box SYNOPSIS display
message \[\-mtype <mtype>\] Message type, default: "Warning", choices: \{Info,
Warning, Error\} <text> Multiple text lines to display, type: string DESCRIPTION
This procedure allows displaying a configurable message box\. The default message
type that is created is a warning, but also errors and info can be generated\.
The procedure accepts multiple text lines\. EXAMPLE display message \-mtype
Warning "Save first your job"* The argument manager is checking if the last
provided argument is *\-help* and generates the requested help message if this
is the case\. So, also the following example will print the help message:

__display message \-mtype Info "It is 7:00" \-help__ On the other hand, the
following call will result in an error:

    __display message \-help \-mtype Info "It is 7:00"__

*\-> display message: Argument '\-help' not known*

## <a name='subsection6'></a>Interactive Procedure Call

If Tk has been loaded a procedure can be called with the *\-interactive* flag
to open a graphical form that allows specifying interactively all procedure
arguments\. The following example assures that the Tk library is loaded and shows
the command line to call interactively the procedure declared in [PROCEDURE
CALLS](#section6):

    package require Tk

__display message \-interactive__ Also the *\-interactive* flag has to be
placed at the last argument position as this is also required for the *\-help*
flag\. Arguments defined before the *\-interactive* flag will be ignored\. The
following example is therefore also a valid interactive procedure call:

    __display message__ \-mtype Info "It is 7:00"

__\-interactive__

## <a name='subsection7'></a>Unnamed Arguments

Unnamed arguments are typically provided to the called procedure as simple
parameters\. This procedure calling form requires that the provided arguments are
strictly following the order of the specified arguments\. Several parameters can
be assigned to the last argument if this one has the *\-multiple* attribute\.
So, the following declared procedure \.\.\.

    tepam::procedure \{display\_message\} \{
       \-args \{
          \{mtype \-choices \{Info Warning Error\}\}
          \{text \-type string \-multiple\}

       \}
    \} \{
       puts "$mtype: \[join $text\]"
    \}


\.\.\. can for example be called in the following ways:

    __display\_message Info "It is PM 7:00\."__
    *\-> Info: It is PM 7:00\.*

    __display\_message Info "It is PM 7:00\." "You should go home\."__

*\-> Info: It is PM 7:00\. You should go home\.* The nice thing is that unnamed
arguments can also be called as named arguments, which can be handy, for example
if the exact specified argument order is not known to a user:

    __display\_message \-mtype Info \-text "It is PM 7:00\."__
    *\-> Info: It is PM 7:00\.*

    __display\_message \-text "It is PM 7:00\." \-mtype Info__
    *\-> Info: It is PM 7:00\.*

    __display\_message \-mtype Info \-text "It is PM 7:00\." \-text "You should go home\."__
    *\-> Info: It is PM 7:00\. You should go home\.*

    __display\_message \-text "It is PM 7:00\." \-text "You should go home\." \-mtype Info__

*\-> Info: It is PM 7:00\. You should go home\.*

## <a name='subsection8'></a>Named Arguments

Named arguments have to be provided to a procedure in form of a parameter pairs
composed by the argument names and the argument values\. The order how they are
provided during a procedure call is irrelevant and has not to match with the
argument specification order\.

The following declared procedure \.\.\.

    tepam::procedure \{display\_message\} \{
       \-args \{
          \{\-mtype \-choices \{Info Warning Error\}\}
          \{\-text \-type string \-multiple\}

       \}
    \} \{
       puts "$mtype: \[join $text\]"
    \}


\.\.\. can be called in the following ways:

    __display\_message \-mtype Info \-text "It is PM 7:00\."__
    *\-> Info: It is PM 7:00\.*

    __display\_message \-text "It is PM 7:00\." \-mtype Info__
    *\-> Info: It is PM 7:00\.*

    __display\_message \-mtype Info \-text "It is PM 7:00\." \-text "You should go home\."__
    *\-> Info: It is PM 7:00\. You should go home\.*

    __display\_message \-text "It is PM 7:00\." \-text "You should go home\." \-mtype Info__

*\-> Info: It is PM 7:00\. You should go home\.* Also named arguments that have
not the *\-multiple* attribute can be provided multiple times\. Only the last
provided argument will be retained in such a case:

    __display\_message \-mtype Info \-text "It is PM 7:00\." \-mtype Warning__

*\-> Warning: It is PM 7:00\.*

## <a name='subsection9'></a>Unnamed Arguments First, Named Arguments Later \(Tk Style\)

A procedure that has been defined while the variable
__tepam::named\_arguments\_first__ was set to 1, or with the procedure
attribute *\-named\_arguments\_first* set to 1 has to be called in the Tcl style\.
The following procedure declaration will be used in this section to illustrate
the meaning of this calling style:

    __set tepam::named\_arguments\_first 1__
    tepam::procedure my\_proc \{
       \-args \{
          \{\-n1 \-default ""\}
          \{\-n2 \-default ""\}
          \{u1 \-default ""\}
          \{u2 \-default ""\}

       \}
    \} \{
       puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'"
    \}


The unnamed arguments are placed at the end of procedure call, after the named
arguments:

    my\_proc __\-n1 N1 \-n2 N2 U1 U2__

*\-> n1:'N1', n2:'N2', u1:'U1', u2:'U2'* The argument parser considers the
first argument that doesn't start with the '\-' character as well as all
following arguments as unnamed argument:

    my\_proc __U1 U2__

*\-> n1:'', n2:'', u1:'U1', u2:'U2'* Named arguments can be defined multiple
times\. If the named argument has the *\-multiply* attribute, all argument
values will be collected in a list\. Otherwise, only the last provided attribute
value will be retained:

    my\_proc __\-n1 N1 \-n2 N2 \-n1 M1 U1 U2__

*\-> n1:'M1', n2:'N2', u1:'U1', u2:'U2'* The name of the first unnamed argument
has therefore not to start with the '\-' character\. The unnamed argument is
otherwise considered as name of another named argument\. This is especially
important if the first unnamed argument is given by a variable that can contain
any character strings:

    my\_proc __\-n1 N1 \-n2 N2 "\->" "<\-"__
    *\-> my\_proc: Argument '\->' not known*

    set U1 "\->"
    my\_proc __\-n1 N1 \-n2 N2 $U1 U2__
    my\_proc: Argument '\->' not known

The '\-\-' flag allows separating unambiguously the unnamed arguments from the
named arguments\. All data after the '\-\-' flag will be considered as unnamed
argument:

    my\_proc __\-n1 N1 \-n2 N2 \-\- "\->" "<\-"__
    *\-> n1:'N1', n2:'N2', u1:'\->', u2:'<\-'*

    set U1 "\->"
    my\_proc __\-n1 N1 \-n2 N2 \-\- $U1 U2__

*\-> n1:'N1', n2:'N2', u1:'\->', u2:'<\-'*

## <a name='subsection10'></a>Named Arguments First, Unnamed Arguments Later \(Tcl Style\)

The Tk calling style will be chosen if a procedure is defined while the variable
__tepam::named\_arguments\_first__ is set to 0, or if the procedure attribute
*\-named\_arguments\_first* has been set to 0\. The following procedure will be
used in this section to illustrate this calling style:

    __set tepam::named\_arguments\_first 0__
    tepam::procedure my\_proc \{
       \-args \{
          \{\-n1 \-default ""\}
          \{\-n2 \-default ""\}
          \{u1\}
          \{u2 \-default "" \-multiple\}

       \}
    \} \{
       puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'"
    \}


The unnamed arguments have to be provided first in this case\. The named
arguments are provided afterwards:

    my\_proc __U1 U2 \-n1 N1 \-n2 N2__

*\-> n1:'N1', n1:'N1', u1:'U1', u2:'U2'* The argument parser will assign to
each defined unnamed argument a value before it switches to read the named
arguments\. This default behavior changes a bit if there are unnamed arguments
that are optional or that can take multiple values\.

An argument value will only be assigned to an unnamed argument that is optional







|






|








|










|






|








|

















|












|














|


















|











|
|
|
|
>
|
<
|
<
>



|
|

|





|
|

|
|

|
|

|












|
|
|
|
>
|
<
|
<
|
>


|
|

|
|

|
|

|





|











|
|
|
|
|
|
|
>
|
<

<
>




|





|






|







|
|

|
|
|





|
|

|
|










|
|
|
|
|
|
|
>
|
<

<
>




|







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

In addition to the data types checked with the __string is <type>__
commands, TEPAM specifies some other useful data types:

  - *char* Each string that has a length of 1 character meets the
    *character* type\. The type check is made with the following expression:

    expr [string length *<argument_value>*]==1

  - *color* Any character strings that are accepted by Tk as a color are
    considered as valid color argument\. Please note that the Tk package has to
    be loaded to use the type *color*\. TEPAM is using the following command to
    validate the color type:

    expr ![catch {winfo rgb . *<argument_value>*}

    \]

  - *font* Any character strings that are accepted by Tk as a font are
    considered as valid font argument\. Please note that the Tk package has to be
    loaded to use the *font* type\. TEPAM is using the following command to
    validate the color type:

    expr ![catch {font measure <argument_value> ""}

    \]

  - *file* Any strings that are not containing one of the following characters
    are considered as valid file names: \* ? " < >\. It is not necessary that the
    file and its containing directory exist\. Zero\-length strings are not
    considered as valid file names\.

    The following expression is used to validate the file names:

    expr [string length <argument_value>]>0 && ![regexp {[\"*?<>:]} <argument_value>

    \]

  - *existingfile* The argument is valid if it matches with an existing file\.
    The following check is performed to validate the arguments of this type:

    file exists <argument_value>

  - *directory* The directory argument is validated exactly in the same way as
    the file arguments\.

  - *existingdirectory* The argument is valid if it matches with an existing
    directory\. The following check is performed to validate the arguments of
    this type:

    file isdirectory <argument_value>

## <a name='subsection4'></a>Defining Application Specific Argument Types

To add support for a new application specific argument type it is just necessary
to add into the namespace __tepam__ a validation function
__Validation\(<type>\)__\. This function requires one argument\. It has to
returns __1__ if the provided argument matches with the relevant data type\.
The function has to return otherwise __0__\.

The validation command section of the "tepam\.tcl" package provides sufficient
examples of validation functions, since it implements the ones for the standard
TEPAM types\.

The following additional code snippet shows the validation function for a custom
argument type that requires values that have a character string length of
exactly 2:

    proc tepam::Validate(two_char) {v} {expr {[string length $v]==2}}

# <a name='section6'></a>PROCEDURE CALLS

## <a name='subsection5'></a>Help

Each procedure can be called with the *\-help* flag\. The procedure will then
print a generated help text to *stdout* and will then return without
performing any additional actions\.

Taking the first procedure declared in [PROCEDURE CALLS](#section6), the
help request and the printed help text would be:

    __display message -help__

*\-> NAME display message \- Displays a simple message box SYNOPSIS display
message \[\-mtype <mtype>\] Message type, default: "Warning", choices: \{Info,
Warning, Error\} <text> Multiple text lines to display, type: string DESCRIPTION
This procedure allows displaying a configurable message box\. The default message
type that is created is a warning, but also errors and info can be generated\.
The procedure accepts multiple text lines\. EXAMPLE display message \-mtype
Warning "Save first your job"* The argument manager is checking if the last
provided argument is *\-help* and generates the requested help message if this
is the case\. So, also the following example will print the help message:

__display message \-mtype Info "It is 7:00" \-help__ On the other hand, the
following call will result in an error:

    __display message -help -mtype Info "It is 7:00"__

*\-> display message: Argument '\-help' not known*

## <a name='subsection6'></a>Interactive Procedure Call

If Tk has been loaded a procedure can be called with the *\-interactive* flag
to open a graphical form that allows specifying interactively all procedure
arguments\. The following example assures that the Tk library is loaded and shows
the command line to call interactively the procedure declared in [PROCEDURE
CALLS](#section6):

    package require Tk

__display message \-interactive__ Also the *\-interactive* flag has to be
placed at the last argument position as this is also required for the *\-help*
flag\. Arguments defined before the *\-interactive* flag will be ignored\. The
following example is therefore also a valid interactive procedure call:

    __display message__ -mtype Info "It is 7:00"

__\-interactive__

## <a name='subsection7'></a>Unnamed Arguments

Unnamed arguments are typically provided to the called procedure as simple
parameters\. This procedure calling form requires that the provided arguments are
strictly following the order of the specified arguments\. Several parameters can
be assigned to the last argument if this one has the *\-multiple* attribute\.
So, the following declared procedure \.\.\.

    tepam::procedure {display_message} {
       -args {
          {mtype -choices {Info Warning Error}}
          {text -type string -multiple}
       }
    } {

       puts "$mtype: [join $text]"

    }

\.\.\. can for example be called in the following ways:

    __display_message Info "It is PM 7:00."__
    *-> Info: It is PM 7:00.*

    __display_message Info "It is PM 7:00." "You should go home."__

*\-> Info: It is PM 7:00\. You should go home\.* The nice thing is that unnamed
arguments can also be called as named arguments, which can be handy, for example
if the exact specified argument order is not known to a user:

    __display_message -mtype Info -text "It is PM 7:00."__
    *-> Info: It is PM 7:00.*

    __display_message -text "It is PM 7:00." -mtype Info__
    *-> Info: It is PM 7:00.*

    __display_message -mtype Info -text "It is PM 7:00." -text "You should go home."__
    *-> Info: It is PM 7:00. You should go home.*

    __display_message -text "It is PM 7:00." -text "You should go home." -mtype Info__

*\-> Info: It is PM 7:00\. You should go home\.*

## <a name='subsection8'></a>Named Arguments

Named arguments have to be provided to a procedure in form of a parameter pairs
composed by the argument names and the argument values\. The order how they are
provided during a procedure call is irrelevant and has not to match with the
argument specification order\.

The following declared procedure \.\.\.

    tepam::procedure {display_message} {
       -args {
          {-mtype -choices {Info Warning Error}}
          {-text -type string -multiple}
       }
    } {

       puts "$mtype: [join $text]"

    }

\.\.\. can be called in the following ways:

    __display_message -mtype Info -text "It is PM 7:00."__
    *-> Info: It is PM 7:00.*

    __display_message -text "It is PM 7:00." -mtype Info__
    *-> Info: It is PM 7:00.*

    __display_message -mtype Info -text "It is PM 7:00." -text "You should go home."__
    *-> Info: It is PM 7:00. You should go home.*

    __display_message -text "It is PM 7:00." -text "You should go home." -mtype Info__

*\-> Info: It is PM 7:00\. You should go home\.* Also named arguments that have
not the *\-multiple* attribute can be provided multiple times\. Only the last
provided argument will be retained in such a case:

    __display_message -mtype Info -text "It is PM 7:00." -mtype Warning__

*\-> Warning: It is PM 7:00\.*

## <a name='subsection9'></a>Unnamed Arguments First, Named Arguments Later \(Tk Style\)

A procedure that has been defined while the variable
__tepam::named\_arguments\_first__ was set to 1, or with the procedure
attribute *\-named\_arguments\_first* set to 1 has to be called in the Tcl style\.
The following procedure declaration will be used in this section to illustrate
the meaning of this calling style:

    __set tepam::named_arguments_first 1__
    tepam::procedure my_proc {
       -args {
          {-n1 -default ""}
          {-n2 -default ""}
          {u1 -default ""}
          {u2 -default ""}
       }
    } {

       puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'"

    }

The unnamed arguments are placed at the end of procedure call, after the named
arguments:

    my_proc __-n1 N1 -n2 N2 U1 U2__

*\-> n1:'N1', n2:'N2', u1:'U1', u2:'U2'* The argument parser considers the
first argument that doesn't start with the '\-' character as well as all
following arguments as unnamed argument:

    my_proc __U1 U2__

*\-> n1:'', n2:'', u1:'U1', u2:'U2'* Named arguments can be defined multiple
times\. If the named argument has the *\-multiply* attribute, all argument
values will be collected in a list\. Otherwise, only the last provided attribute
value will be retained:

    my_proc __-n1 N1 -n2 N2 -n1 M1 U1 U2__

*\-> n1:'M1', n2:'N2', u1:'U1', u2:'U2'* The name of the first unnamed argument
has therefore not to start with the '\-' character\. The unnamed argument is
otherwise considered as name of another named argument\. This is especially
important if the first unnamed argument is given by a variable that can contain
any character strings:

    my_proc __-n1 N1 -n2 N2 "->" "<-"__
    *-> my_proc: Argument '->' not known*

    set U1 "->"
    my_proc __-n1 N1 -n2 N2 $U1 U2__
    my_proc: Argument '->' not known

The '\-\-' flag allows separating unambiguously the unnamed arguments from the
named arguments\. All data after the '\-\-' flag will be considered as unnamed
argument:

    my_proc __-n1 N1 -n2 N2 -- "->" "<-"__
    *-> n1:'N1', n2:'N2', u1:'->', u2:'<-'*

    set U1 "->"
    my_proc __-n1 N1 -n2 N2 -- $U1 U2__

*\-> n1:'N1', n2:'N2', u1:'\->', u2:'<\-'*

## <a name='subsection10'></a>Named Arguments First, Unnamed Arguments Later \(Tcl Style\)

The Tk calling style will be chosen if a procedure is defined while the variable
__tepam::named\_arguments\_first__ is set to 0, or if the procedure attribute
*\-named\_arguments\_first* has been set to 0\. The following procedure will be
used in this section to illustrate this calling style:

    __set tepam::named_arguments_first 0__
    tepam::procedure my_proc {
       -args {
          {-n1 -default ""}
          {-n2 -default ""}
          {u1}
          {u2 -default "" -multiple}
       }
    } {

       puts "n1:'$n1', n2:'$n2', u1:'$u1', u2:'$u2'"

    }

The unnamed arguments have to be provided first in this case\. The named
arguments are provided afterwards:

    my_proc __U1 U2 -n1 N1 -n2 N2__

*\-> n1:'N1', n1:'N1', u1:'U1', u2:'U2'* The argument parser will assign to
each defined unnamed argument a value before it switches to read the named
arguments\. This default behavior changes a bit if there are unnamed arguments
that are optional or that can take multiple values\.

An argument value will only be assigned to an unnamed argument that is optional
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
separating unambiguously the named arguments from the unnamed ones with the '\-\-'
flag\.

Let's explore in a bit less theoretically the ways how the previously defined
procedure can be called: The first example calls the procedure without any
parameters, which leads to an error since *u1* is a mandatory argument:

    my\_proc

*\-> my\_proc: Required argument is missing: u1* The procedure call is valid if
one parameter is provided for *u1*:

    my\_proc __U1__

*\-> n1:'', n2:'', u1:'U1', u2:''* If more parameters are provided that are not
starting with the '\-' character, they will be attributed to the unnamed
arguments\. *U2* will receive 3 of these parameters, since it accepts multiple
values:

    my\_proc __U1 U2 U3 U4__

*\-> n1:'', n2:'', u1:'U1', u2:'U2 U3 U4'* As soon as one parameter starts with
'\-' and all unnamed arguments have been assigned, the argument manager tries to
interpret the parameter as name of a named argument\. The procedure call will
fail if a value beginning with '\-' is assigned to an unnamed argument:

    my\_proc __U1 U2 U3 U4 \-U5__

*\-> my\_proc: Argument '\-U5' not known* The attribution of a parameter to a
named argument will fail if there are undefined unnamed \(non optional\)
arguments\. The name specification will in this case simply be considered as a
parameter value that is attributed to the *next* unnamed argument\. This was
certainly not the intention in the following example:

    my\_proc __\-n1 N1__

*\-> n1:'', n2:'', u1:'\-n1', u2:'N1'* The situation is completely different if
values have already been assigned to all mandatory unnamed arguments\. A
parameter beginning with the '\-' character will in this case be considered as a
name identifier for a named argument:

    my\_proc __U1 \-n1 N1__

*\-> n1:'N1', n2:'', u1:'U1', u2:''* No unnamed arguments are allowed behind
the named arguments:

    my\_proc __U1 \-n1 N1 U2__

*\-> my\_proc: Argument 'U2' is not an option* The '\-\-' flag has no special
meaning if not all mandatory arguments have got assigned a value\. This flag will
simply be attributed to one of the unnamed arguments:

    my\_proc __\-\- \-n1 N1__

*\-> n1:'N1', n2:'', u1:'\-\-', u2:''* But the '\-\-' flag is simply ignored if the
argument parser has started to handle the named arguments:

    my\_proc __U1 \-\- \-n1 N1__
    *\-> n1:'N1', n2:'', u1:'U1', u2:''*

    my\_proc __U1 \-n1 N1 \-\- \-n2 N2__

*\-> n1:'N1', n2:'N2', u1:'U1', u2:''*

## <a name='subsection11'></a>Raw Argument List

It may be necessary sometimes that the procedure body is able to access the
entire list of arguments provided during a procedure call\. This can happen via
the __args__ variable that contains always the unprocessed argument list:

    tepam::procedure \{display\_message\} \{
       \-args \{
          \{\-mtype \-choices \{Warning Error\} \-default Warning\}
          \{text \-type string \-multiple\}


       \}
    \} \{
       puts "args: __$args__"
    \}

    display\_message \-mtype Warning "It is 7:00"

*\-> args: \-mtype Warning \{It is 7:00\}*

# <a name='seealso'></a>SEE ALSO

[tepam\(n\)](tepam\_introduction\.md),
[tepam::argument\_dialogbox\(n\)](tepam\_argument\_dialogbox\.md)







|




|






|






|







|






|




|





|




|
|

|









|
|
|
|

>
|
<
|
<
>
|







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
separating unambiguously the named arguments from the unnamed ones with the '\-\-'
flag\.

Let's explore in a bit less theoretically the ways how the previously defined
procedure can be called: The first example calls the procedure without any
parameters, which leads to an error since *u1* is a mandatory argument:

    my_proc

*\-> my\_proc: Required argument is missing: u1* The procedure call is valid if
one parameter is provided for *u1*:

    my_proc __U1__

*\-> n1:'', n2:'', u1:'U1', u2:''* If more parameters are provided that are not
starting with the '\-' character, they will be attributed to the unnamed
arguments\. *U2* will receive 3 of these parameters, since it accepts multiple
values:

    my_proc __U1 U2 U3 U4__

*\-> n1:'', n2:'', u1:'U1', u2:'U2 U3 U4'* As soon as one parameter starts with
'\-' and all unnamed arguments have been assigned, the argument manager tries to
interpret the parameter as name of a named argument\. The procedure call will
fail if a value beginning with '\-' is assigned to an unnamed argument:

    my_proc __U1 U2 U3 U4 -U5__

*\-> my\_proc: Argument '\-U5' not known* The attribution of a parameter to a
named argument will fail if there are undefined unnamed \(non optional\)
arguments\. The name specification will in this case simply be considered as a
parameter value that is attributed to the *next* unnamed argument\. This was
certainly not the intention in the following example:

    my_proc __-n1 N1__

*\-> n1:'', n2:'', u1:'\-n1', u2:'N1'* The situation is completely different if
values have already been assigned to all mandatory unnamed arguments\. A
parameter beginning with the '\-' character will in this case be considered as a
name identifier for a named argument:

    my_proc __U1 -n1 N1__

*\-> n1:'N1', n2:'', u1:'U1', u2:''* No unnamed arguments are allowed behind
the named arguments:

    my_proc __U1 -n1 N1 U2__

*\-> my\_proc: Argument 'U2' is not an option* The '\-\-' flag has no special
meaning if not all mandatory arguments have got assigned a value\. This flag will
simply be attributed to one of the unnamed arguments:

    my_proc __-- -n1 N1__

*\-> n1:'N1', n2:'', u1:'\-\-', u2:''* But the '\-\-' flag is simply ignored if the
argument parser has started to handle the named arguments:

    my_proc __U1 -- -n1 N1__
    *-> n1:'N1', n2:'', u1:'U1', u2:''*

    my_proc __U1 -n1 N1 -- -n2 N2__

*\-> n1:'N1', n2:'N2', u1:'U1', u2:''*

## <a name='subsection11'></a>Raw Argument List

It may be necessary sometimes that the procedure body is able to access the
entire list of arguments provided during a procedure call\. This can happen via
the __args__ variable that contains always the unprocessed argument list:

    tepam::procedure {display_message} {
       -args {
          {-mtype -choices {Warning Error} -default Warning}
          {text -type string -multiple}

       }
    } {

       puts "args: __$args__"

    }
    display_message -mtype Warning "It is 7:00"

*\-> args: \-mtype Warning \{It is 7:00\}*

# <a name='seealso'></a>SEE ALSO

[tepam\(n\)](tepam\_introduction\.md),
[tepam::argument\_dialogbox\(n\)](tepam\_argument\_dialogbox\.md)
Changes to embedded/md/tcllib/files/modules/textutil/expander.md.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
The Tcl __[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ command is often used to
support a kind of template processing\. Given a string with embedded variables or
function calls, __[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ will interpolate
the variable and function values, returning the new string:

    % set greeting "Howdy"
    Howdy
    % proc place \{\} \{return "World"\}
    % subst \{$greeting, \[place\]\!\}
    Howdy, World\!
    %

By defining a suitable set of Tcl commands,
__[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ can be used to implement a
markup language similar to HTML\.

The __[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ command is efficient, but it







|
|
|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
The Tcl __[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ command is often used to
support a kind of template processing\. Given a string with embedded variables or
function calls, __[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ will interpolate
the variable and function values, returning the new string:

    % set greeting "Howdy"
    Howdy
    % proc place {} {return "World"}
    % subst {$greeting, [place]!}
    Howdy, World!
    %

By defining a suitable set of Tcl commands,
__[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ can be used to implement a
markup language similar to HTML\.

The __[subst](\.\./\.\./\.\./\.\./index\.md\#subst)__ command is efficient, but it
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

    The command creates a new expander object with an associated Tcl command
    whose name is *expanderName*\. This command may be used to invoke various
    operations on the graph\. If the *expanderName* is not fully qualified it
    is interpreted as relative to the current namespace\. The command has the
    following general form:

    *expanderName* option ?*arg arg \.\.\.*?

    *Option* and the *arg*s determine the exact behavior of the command\.

The following commands are possible for expander objects:

  - <a name='2'></a>*expanderName* __cappend__ *text*








|







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

    The command creates a new expander object with an associated Tcl command
    whose name is *expanderName*\. This command may be used to invoke various
    operations on the graph\. If the *expanderName* is not fully qualified it
    is interpreted as relative to the current namespace\. The command has the
    following general form:

    *expanderName* option ?*arg arg ...*?

    *Option* and the *arg*s determine the exact behavior of the command\.

The following commands are possible for expander objects:

  - <a name='2'></a>*expanderName* __cappend__ *text*

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
# <a name='section3'></a>TUTORIAL

## <a name='subsection1'></a>Basics

To begin, create an expander object:

    % package require textutil::expander
    1\.2
    % ::textutil::expander myexp
    ::myexp
    %

The created __::myexp__ object can be used to expand text strings containing
embedded Tcl commands\. By default, embedded commands are delimited by square
brackets\. Note that expander doesn't attempt to interpolate variables, since
variables can be referenced by embedded commands:

    % set greeting "Howdy"
    Howdy
    % proc place \{\} \{return "World"\}
    % ::myexp expand \{\[set greeting\], \[place\]\!\}
    Howdy, World\!
    %

## <a name='subsection2'></a>Embedding Macros

An expander macro is simply a Tcl script embedded within a text string\. Expander
evaluates the script in the global context, and replaces it with its result
string\. For example,

        % set greetings \{Howdy Hi "What's up"\}
        Howdy Hi "What's up"
        % ::myexp expand \{There are many ways to say "Hello, World\!":
        \[set result \{\}
        foreach greeting $greetings \{
    	append result "$greeting, World\!\\\\n"
        \}

        set result\]
        And that's just a small sample\!\}
        There are many ways to say "Hello, World\!":
        Howdy, World\!
        Hi, World\!
        What's up, World\!

        And that's just a small sample\!
        %

## <a name='subsection3'></a>Writing Macro Commands

More typically, *macro commands* are used to create a markup language\. A macro
command is just a Tcl command that returns an output string\. For example, expand
can be used to implement a generic document markup language that can be
retargeted to HTML or any other output format:

    % proc bold \{\} \{return "<b>"\}
    % proc /bold \{\} \{return "</b>"\}
    % ::myexp expand \{Some of this text is in \[bold\]boldface\[/bold\]\}
    Some of this text is in <b>boldface</b>
    %

The above definitions of __bold__ and __/bold__ returns HTML, but such
commands can be as complicated as needed; they could, for example, decide what
to return based on the desired output format\.

## <a name='subsection4'></a>Changing the Expansion Brackets

By default, embedded macros are enclosed in square brackets, __\[__ and
__\]__\. If square brackets need to be included in the output, the input can
contain the __lb__ and __rb__ commands\. Alternatively, or if square
brackets are objectionable for some other reason, the macro expansion brackets
can be changed to any pair of non\-empty strings\.

The __setbrackets__ command changes the brackets permanently\. For example,
you can write pseudo\-html by change them to __<__ and __>__:

    % ::myexp setbrackets < >
    % ::myexp expand \{<bold>This is boldface</bold>\}
    <b>This is boldface</b>

Alternatively, you can change the expansion brackets temporarily by passing the
desired brackets to the __expand__ command:

    % ::myexp setbrackets "\\\\\[" "\\\\\]"
    % ::myexp expand \{<bold>This is boldface</bold>\} \{< >\}
    <b>This is boldface</b>
    %

## <a name='subsection5'></a>Customized Macro Expansion

By default, macros are evaluated using the Tcl __uplevel \#0__ command, so
that the embedded code executes in the global context\. The application can
provide a different evaluation command using __evalcmd__; this allows the
application to use a safe interpreter, for example, or even to evaluated
something other than Tcl code\. There is one caveat: to be recognized as valid, a
macro must return 1 when passed to Tcl's "info complete" command\.

For example, the following code "evaluates" each macro by returning the macro
text itself\.

    proc identity \{macro\} \{return $macro\}
    ::myexp evalcmd identity

## <a name='subsection6'></a>Using the Context Stack

Often it's desirable to define a pair of macros which operate in some way on the
plain text between them\. Consider a set of macros for adding footnotes to a web
page: one could have implement something like this:

    Dr\. Pangloss, however, thinks that this is the best of all
    possible worlds\.\[footnote "See Candide, by Voltaire"\]

The __footnote__ macro would, presumably, assign a number to this footnote
and save the text to be formatted later on\. However, this solution is ugly if
the footnote text is long or should contain additional markup\. Consider the
following instead:

    Dr\. Pangloss, however, thinks that this is the best of all
    possible worlds\.\[footnote\]See \[bookTitle "Candide"\], by
    \[authorsName "Voltaire"\], for more information\.\[/footnote\]

Here the footnote text is contained between __footnote__ and
__/footnote__ macros, continues onto a second line, and contains several
macros of its own\. This is both clearer and more flexible; however, with the
features presented so far there's no easy way to do it\. That's the purpose of
the context stack\.

All macro expansion takes place in a particular context\. Here, the
__footnote__ macro pushes a new context onto the context stack\. Then, all
expanded text gets placed in that new context\. __/footnote__ retrieves it by
popping the context\. Here's a skeleton implementation of these two macros:

    proc footnote \{\} \{
        ::myexp cpush footnote
    \}


    proc /footnote \{\} \{
        set footnoteText \[::myexp cpop footnote\]

        \# Save the footnote text, and return an appropriate footnote
        \# number and link\.
    \}


The __cpush__ command pushes a new context onto the stack; the argument is
the context's name\. It can be any string, but would typically be the name of the
macro itself\. Then, __cpop__ verifies that the current context has the
expected name, pops it off of the stack, and returns the accumulated text\.

Expand provides several other tools related to the context stack\. Suppose the
first macro in a context pair takes arguments or computes values which the
second macro in the pair needs\. After calling __cpush__, the first macro can
define one or more context variables; the second macro can retrieve their values
any time before calling __cpop__\. For example, suppose the document must
specify the footnote number explicitly:

    proc footnote \{footnoteNumber\} \{
        ::myexp cpush footnote
        ::myexp csave num $footnoteNumber
        \# Return an appropriate link
    \}


    proc /footnote \{\} \{
        set footnoteNumber \[::myexp cget num\]
        set footnoteText \[::myexp cpop footnote\]

        \# Save the footnote text and its footnoteNumber for future
        \# output\.
    \}


At times, it might be desirable to define macros that are valid only within a
particular context pair; such macros should verify that they are only called
within the correct context using either __cis__ or __cname__\.

# <a name='section4'></a>HISTORY








|











|
|
|








|

|
|
|
|
<
>
|
|
|
|
|
|

|









|
|
|



















|





|
|















|








|
|






|
|
|












|

<
|
>
|
|

|
|
<
>













|


|
<
|
>
|
|
|

|
|
<
>







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
# <a name='section3'></a>TUTORIAL

## <a name='subsection1'></a>Basics

To begin, create an expander object:

    % package require textutil::expander
    1.2
    % ::textutil::expander myexp
    ::myexp
    %

The created __::myexp__ object can be used to expand text strings containing
embedded Tcl commands\. By default, embedded commands are delimited by square
brackets\. Note that expander doesn't attempt to interpolate variables, since
variables can be referenced by embedded commands:

    % set greeting "Howdy"
    Howdy
    % proc place {} {return "World"}
    % ::myexp expand {[set greeting], [place]!}
    Howdy, World!
    %

## <a name='subsection2'></a>Embedding Macros

An expander macro is simply a Tcl script embedded within a text string\. Expander
evaluates the script in the global context, and replaces it with its result
string\. For example,

        % set greetings {Howdy Hi "What's up"}
        Howdy Hi "What's up"
        % ::myexp expand {There are many ways to say "Hello, World!":
        [set result {}
        foreach greeting $greetings {
    	append result "$greeting, World!\\n"

        }
        set result]
        And that's just a small sample!}
        There are many ways to say "Hello, World!":
        Howdy, World!
        Hi, World!
        What's up, World!

        And that's just a small sample!
        %

## <a name='subsection3'></a>Writing Macro Commands

More typically, *macro commands* are used to create a markup language\. A macro
command is just a Tcl command that returns an output string\. For example, expand
can be used to implement a generic document markup language that can be
retargeted to HTML or any other output format:

    % proc bold {} {return "<b>"}
    % proc /bold {} {return "</b>"}
    % ::myexp expand {Some of this text is in [bold]boldface[/bold]}
    Some of this text is in <b>boldface</b>
    %

The above definitions of __bold__ and __/bold__ returns HTML, but such
commands can be as complicated as needed; they could, for example, decide what
to return based on the desired output format\.

## <a name='subsection4'></a>Changing the Expansion Brackets

By default, embedded macros are enclosed in square brackets, __\[__ and
__\]__\. If square brackets need to be included in the output, the input can
contain the __lb__ and __rb__ commands\. Alternatively, or if square
brackets are objectionable for some other reason, the macro expansion brackets
can be changed to any pair of non\-empty strings\.

The __setbrackets__ command changes the brackets permanently\. For example,
you can write pseudo\-html by change them to __<__ and __>__:

    % ::myexp setbrackets < >
    % ::myexp expand {<bold>This is boldface</bold>}
    <b>This is boldface</b>

Alternatively, you can change the expansion brackets temporarily by passing the
desired brackets to the __expand__ command:

    % ::myexp setbrackets "\\[" "\\]"
    % ::myexp expand {<bold>This is boldface</bold>} {< >}
    <b>This is boldface</b>
    %

## <a name='subsection5'></a>Customized Macro Expansion

By default, macros are evaluated using the Tcl __uplevel \#0__ command, so
that the embedded code executes in the global context\. The application can
provide a different evaluation command using __evalcmd__; this allows the
application to use a safe interpreter, for example, or even to evaluated
something other than Tcl code\. There is one caveat: to be recognized as valid, a
macro must return 1 when passed to Tcl's "info complete" command\.

For example, the following code "evaluates" each macro by returning the macro
text itself\.

    proc identity {macro} {return $macro}
    ::myexp evalcmd identity

## <a name='subsection6'></a>Using the Context Stack

Often it's desirable to define a pair of macros which operate in some way on the
plain text between them\. Consider a set of macros for adding footnotes to a web
page: one could have implement something like this:

    Dr. Pangloss, however, thinks that this is the best of all
    possible worlds.[footnote "See Candide, by Voltaire"]

The __footnote__ macro would, presumably, assign a number to this footnote
and save the text to be formatted later on\. However, this solution is ugly if
the footnote text is long or should contain additional markup\. Consider the
following instead:

    Dr. Pangloss, however, thinks that this is the best of all
    possible worlds.[footnote]See [bookTitle "Candide"], by
    [authorsName "Voltaire"], for more information.[/footnote]

Here the footnote text is contained between __footnote__ and
__/footnote__ macros, continues onto a second line, and contains several
macros of its own\. This is both clearer and more flexible; however, with the
features presented so far there's no easy way to do it\. That's the purpose of
the context stack\.

All macro expansion takes place in a particular context\. Here, the
__footnote__ macro pushes a new context onto the context stack\. Then, all
expanded text gets placed in that new context\. __/footnote__ retrieves it by
popping the context\. Here's a skeleton implementation of these two macros:

    proc footnote {} {
        ::myexp cpush footnote

    }

    proc /footnote {} {
        set footnoteText [::myexp cpop footnote]

        # Save the footnote text, and return an appropriate footnote
        # number and link.

    }

The __cpush__ command pushes a new context onto the stack; the argument is
the context's name\. It can be any string, but would typically be the name of the
macro itself\. Then, __cpop__ verifies that the current context has the
expected name, pops it off of the stack, and returns the accumulated text\.

Expand provides several other tools related to the context stack\. Suppose the
first macro in a context pair takes arguments or computes values which the
second macro in the pair needs\. After calling __cpush__, the first macro can
define one or more context variables; the second macro can retrieve their values
any time before calling __cpop__\. For example, suppose the document must
specify the footnote number explicitly:

    proc footnote {footnoteNumber} {
        ::myexp cpush footnote
        ::myexp csave num $footnoteNumber
        # Return an appropriate link

    }

    proc /footnote {} {
        set footnoteNumber [::myexp cget num]
        set footnoteText [::myexp cpop footnote]

        # Save the footnote text and its footnoteNumber for future
        # output.

    }

At times, it might be desirable to define macros that are valid only within a
particular context pair; such macros should verify that they are only called
within the correct context using either __cis__ or __cname__\.

# <a name='section4'></a>HISTORY

Changes to embedded/md/tcllib/files/modules/tie/tie.md.
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
    source](\.\./\.\./\.\./\.\./index\.md\#data\_source)* the object talks to\.

And here a small table comparing the *[data
source](\.\./\.\./\.\./\.\./index\.md\#data\_source)* methods to the regular Tcl
commands for accessing an array\.

    Regular Tcl             Data source
    \-\-\-\-\-\-\-\-\-\-\-             \-\-\-\-\-\-\-\-\-\-\-
    array names a           ds names
    array size  a           ds size
    array get   a           ds get
    array set   a dict      ds set   dict
    array unset a pattern   ds unset ?pattern?
    \-\-\-\-\-\-\-\-\-\-\-             \-\-\-\-\-\-\-\-\-\-\-
    set a\($idx\) $val        ds setv   idx val
    unset a\($idx\)           ds unsetv idx
    $a\($idx\)                ds getv   idx
    \-\-\-\-\-\-\-\-\-\-\-             \-\-\-\-\-\-\-\-\-\-\-

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *tie* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|





|
|
|
|
|







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
    source](\.\./\.\./\.\./\.\./index\.md\#data\_source)* the object talks to\.

And here a small table comparing the *[data
source](\.\./\.\./\.\./\.\./index\.md\#data\_source)* methods to the regular Tcl
commands for accessing an array\.

    Regular Tcl             Data source
    -----------             -----------
    array names a           ds names
    array size  a           ds size
    array get   a           ds get
    array set   a dict      ds set   dict
    array unset a pattern   ds unset ?pattern?
    -----------             -----------
    set a($idx) $val        ds setv   idx val
    unset a($idx)           ds unsetv idx
    $a($idx)                ds getv   idx
    -----------             -----------

# <a name='section4'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *tie* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/tiff/tiff.md.
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
    __PhotometricInterpretation__, __ImageDescription__,
    __Orientation__, __XResolution__, __YResolution__,
    __ResolutionUnit__, __DateTime__, __Artist__, and
    __HostComputer__\. The values are the associated properties of the TIFF
    ?image? in *file*\. Values may be empty if the associated tag is not
    present in the file\.

        puts \[::tiff::imageInfo photo\.tif\]

        ImageWidth 686 ImageLength 1024 BitsPerSample \{8 8 8\} Compression 1
        PhotometricInterpretation 2 ImageDescription \{\} Orientation 1
        XResolution 170\.667 YResolution 170\.667 ResolutionUnit 2 DateTime \{2005:12:28 19:44:45\}
        Artist \{\} HostComputer \{\}

    There is nothing special about these tags, this is simply a convience
    procedure which calls __getEntry__ with common entries\. Throws an error
    if *file* is not a TIFF image\.

  - <a name='6'></a>__::tiff::entries__ *file* ?image?

    Returns a list of all entries in the given *file* and ?image? in
    hexadecimal format\. Throws an error if *file* is not a TIFF image\.

  - <a name='7'></a>__::tiff::getEntry__ *file* *entry* ?image?

    Returns the value of *entry* from image ?image? in the TIFF *file*\.
    *entry* may be a list of multiple entries\. If an entry does not exist, an
    empty string is returned

        set data \[::tiff::getEntry photo\.tif \{0131 0132\}\]
        puts "file was written at \[lindex $data 0\] with software \[lindex $data 1\]"

    Throws an error if *file* is not a TIFF image\.

  - <a name='8'></a>__::tiff::addEntry__ *file* *entry* ?image?

    Adds the specified entries to the image named by ?image? \(default 0\), or
    optionally __all__\. *entry* must be a list where each element is a
    list of tag, type, and value\. If a tag already exists, it is overwritten\.

        ::tiff::addEntry photo\.tif \{\{010e 2 "an example photo"\} \{013b 2 "Aaron F"\}\}

    The data types are defined as follows

      * __1__

        BYTE \(8 bit unsigned integer\)








|

|
|
|
|
















|
|









|







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
    __PhotometricInterpretation__, __ImageDescription__,
    __Orientation__, __XResolution__, __YResolution__,
    __ResolutionUnit__, __DateTime__, __Artist__, and
    __HostComputer__\. The values are the associated properties of the TIFF
    ?image? in *file*\. Values may be empty if the associated tag is not
    present in the file\.

        puts [::tiff::imageInfo photo.tif]

        ImageWidth 686 ImageLength 1024 BitsPerSample {8 8 8} Compression 1
        PhotometricInterpretation 2 ImageDescription {} Orientation 1
        XResolution 170.667 YResolution 170.667 ResolutionUnit 2 DateTime {2005:12:28 19:44:45}
        Artist {} HostComputer {}

    There is nothing special about these tags, this is simply a convience
    procedure which calls __getEntry__ with common entries\. Throws an error
    if *file* is not a TIFF image\.

  - <a name='6'></a>__::tiff::entries__ *file* ?image?

    Returns a list of all entries in the given *file* and ?image? in
    hexadecimal format\. Throws an error if *file* is not a TIFF image\.

  - <a name='7'></a>__::tiff::getEntry__ *file* *entry* ?image?

    Returns the value of *entry* from image ?image? in the TIFF *file*\.
    *entry* may be a list of multiple entries\. If an entry does not exist, an
    empty string is returned

        set data [::tiff::getEntry photo.tif {0131 0132}]
        puts "file was written at [lindex $data 0] with software [lindex $data 1]"

    Throws an error if *file* is not a TIFF image\.

  - <a name='8'></a>__::tiff::addEntry__ *file* *entry* ?image?

    Adds the specified entries to the image named by ?image? \(default 0\), or
    optionally __all__\. *entry* must be a list where each element is a
    list of tag, type, and value\. If a tag already exists, it is overwritten\.

        ::tiff::addEntry photo.tif {{010e 2 "an example photo"} {013b 2 "Aaron F"}}

    The data types are defined as follows

      * __1__

        BYTE \(8 bit unsigned integer\)

Changes to embedded/md/tcllib/files/modules/tool/meta.md.
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
    available to a user of the class and of derived classes\.

    Note: The command is equivalent to the command __typemethod__ provided
    by the OO package __[snit](\.\./snit/snit\.md)__ for the same purpose\.

    Example

        oo::class create ActiveRecord \{
            classmethod find args \{ puts "\[self\] called with arguments: $args" \}
        \}

        oo::class create Table \{
            superclass ActiveRecord
        \}

        puts \[Table find foo bar\]
        \# ======
        \# which will write
        \# ======
        \# ::Table called with arguments: foo bar

  - <a name='3'></a>__classvariable__ ?*arg*\.\.\.?

    This command is available within instance methods\. It takes a series of
    variable names and makes them available in the method's scope\. The
    originating scope for the variables is the class \(instance\) the object
    instance belongs to\. In other words, the referenced variables are shared
    between all instances of their class\.

    Note: The command is roughly equivalent to the command __typevariable__
    provided by the OO package __[snit](\.\./snit/snit\.md)__ for the same
    purpose\. The difference is that it cannot be used in the class definition
    itself\.

    Example:

        % oo::class create Foo \{
            method bar \{z\} \{
                classvariable x y
                return \[incr x $z\],\[incr y\]
            \}
        \}


        ::Foo
        % Foo create a
        ::a
        % Foo create b
        ::b
        % a bar 2
        2,1
        % a bar 3
        5,2
        % b bar 7
        12,3
        % b bar \-1
        11,4
        % a bar 0
        11,5

  - <a name='4'></a>__link__ *method*\.\.\.

  - <a name='5'></a>__link__ \{*alias* *method*\}\.\.\.

    This command is available within instance methods\. It takes a list of method
    names and/or pairs of alias\- and method\-name and makes the named methods
    available to all instance methods without requiring the __my__ command\.

    The alias name under which the method becomes available defaults to the
    method name, except where explicitly specified through an alias/method pair\.

    Examples:

        link foo
        \# The method foo is now directly accessible as foo instead of my foo\.

        link \{bar foo\}
        \# The method foo is now directly accessible as bar\.

        link a b c
        \# The methods a, b, and c all become directly acessible under their
        \# own names\.

    The main use of this command is expected to be in instance constructors, for
    convenience, or to set up some methods for use in a mini DSL\.

  - <a name='6'></a>__ooutil::singleton__ ?*arg*\.\.\.?

    This command is a meta\-class, i\.e\. a variant of the builtin
    __oo::class__ which ensures that it creates only a single instance of
    the classes defined with it\.

    Syntax and results are like for __oo::class__\.

    Example:

        % oo::class create example \{
           self mixin singleton
           method foo \{\} \{self\}
        \}

        ::example
        % \[example new\] foo
        ::oo::Obj22
        % \[example new\] foo
        ::oo::Obj22

# <a name='section3'></a>AUTHORS

Donal Fellows, Andreas Kupries

# <a name='section4'></a>Bugs, Ideas, Feedback







|
|
<
>
|

<
>
|
|
|
|
|
















|
|

|
<
<
>
>











|


















|

|
|


|
|














|

|
<
>

|

|







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
    available to a user of the class and of derived classes\.

    Note: The command is equivalent to the command __typemethod__ provided
    by the OO package __[snit](\.\./snit/snit\.md)__ for the same purpose\.

    Example

        oo::class create ActiveRecord {
            classmethod find args { puts "[self] called with arguments: $args" }

        }
        oo::class create Table {
            superclass ActiveRecord

        }
        puts [Table find foo bar]
        # ======
        # which will write
        # ======
        # ::Table called with arguments: foo bar

  - <a name='3'></a>__classvariable__ ?*arg*\.\.\.?

    This command is available within instance methods\. It takes a series of
    variable names and makes them available in the method's scope\. The
    originating scope for the variables is the class \(instance\) the object
    instance belongs to\. In other words, the referenced variables are shared
    between all instances of their class\.

    Note: The command is roughly equivalent to the command __typevariable__
    provided by the OO package __[snit](\.\./snit/snit\.md)__ for the same
    purpose\. The difference is that it cannot be used in the class definition
    itself\.

    Example:

        % oo::class create Foo {
            method bar {z} {
                classvariable x y
                return [incr x $z],[incr y]


            }
        }
        ::Foo
        % Foo create a
        ::a
        % Foo create b
        ::b
        % a bar 2
        2,1
        % a bar 3
        5,2
        % b bar 7
        12,3
        % b bar -1
        11,4
        % a bar 0
        11,5

  - <a name='4'></a>__link__ *method*\.\.\.

  - <a name='5'></a>__link__ \{*alias* *method*\}\.\.\.

    This command is available within instance methods\. It takes a list of method
    names and/or pairs of alias\- and method\-name and makes the named methods
    available to all instance methods without requiring the __my__ command\.

    The alias name under which the method becomes available defaults to the
    method name, except where explicitly specified through an alias/method pair\.

    Examples:

        link foo
        # The method foo is now directly accessible as foo instead of my foo.

        link {bar foo}
        # The method foo is now directly accessible as bar.

        link a b c
        # The methods a, b, and c all become directly acessible under their
        # own names.

    The main use of this command is expected to be in instance constructors, for
    convenience, or to set up some methods for use in a mini DSL\.

  - <a name='6'></a>__ooutil::singleton__ ?*arg*\.\.\.?

    This command is a meta\-class, i\.e\. a variant of the builtin
    __oo::class__ which ensures that it creates only a single instance of
    the classes defined with it\.

    Syntax and results are like for __oo::class__\.

    Example:

        % oo::class create example {
           self mixin singleton
           method foo {} {self}

        }
        ::example
        % [example new] foo
        ::oo::Obj22
        % [example new] foo
        ::oo::Obj22

# <a name='section3'></a>AUTHORS

Donal Fellows, Andreas Kupries

# <a name='section4'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/tool/tool.md.
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

The TOOL metaclass was build with the __oo::dialect__ package, and thus can
be used as the basis for additional metaclasses\. As a metaclass, TOOL has it's
own "class" class, "object" class, and define namespace\.

    package require tool

    \# tool::class workds just like oo::class
    tool::class create myclass \{
    \}


    \# tool::define works just like oo::define
    tool::define myclass method noop \{\} \{\}

    \# tool::define and tool::class understand additional keywords
    tool::define myclass array\_ensemble mysettings mysettings \{\}

    \# And tool interoperates with oo::define
    oo::define myclass method do\_something \{\} \{ return something \}

    \# TOOL and TclOO objects are interchangeable
    oo::class create myooclass \{
      superclass myclass
    \}


Several manual pages go into more detail about specific keywords and methods\.

  - __tool::array\_ensemble__

  - __[tool::dict\_ensemble](tool\_dict\_ensemble\.md)__








|
|
<
|
>
|
|

|
|

|
|

|
|

<
>







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

The TOOL metaclass was build with the __oo::dialect__ package, and thus can
be used as the basis for additional metaclasses\. As a metaclass, TOOL has it's
own "class" class, "object" class, and define namespace\.

    package require tool

    # tool::class workds just like oo::class
    tool::class create myclass {

    }

    # tool::define works just like oo::define
    tool::define myclass method noop {} {}

    # tool::define and tool::class understand additional keywords
    tool::define myclass array_ensemble mysettings mysettings {}

    # And tool interoperates with oo::define
    oo::define myclass method do_something {} { return something }

    # TOOL and TclOO objects are interchangeable
    oo::class create myooclass {
      superclass myclass

    }

Several manual pages go into more detail about specific keywords and methods\.

  - __tool::array\_ensemble__

  - __[tool::dict\_ensemble](tool\_dict\_ensemble\.md)__

158
159
160
161
162
163
164
165
166
167
168
169
170


171
172
173
174
175
176
177
    __[method](\.\./\.\./\.\./\.\./index\.md\#method)__ command\.

  - <a name='6'></a>tool::define __option__ *name* *dictopts*

    Declares an option\. *dictopts* is a key/value list defining parameters for
    the option\. See __tool::option\_handling__\.

    tool::class create myclass \{
      option color \{
        post\-command: \{puts \[list %self%'s %field% is now %value%\]\}
        default: green
      \}
    \}


    myclass create foo
    foo configure color purple
    > foo's color is now purple

  - <a name='7'></a>tool::define __property__ ?branch? *field* *value*

    Defines a new leaf in the class metadata tree\. With no branch, the leaf will







|
|
|

<
<
>
>







158
159
160
161
162
163
164
165
166
167
168


169
170
171
172
173
174
175
176
177
    __[method](\.\./\.\./\.\./\.\./index\.md\#method)__ command\.

  - <a name='6'></a>tool::define __option__ *name* *dictopts*

    Declares an option\. *dictopts* is a key/value list defining parameters for
    the option\. See __tool::option\_handling__\.

    tool::class create myclass {
      option color {
        post-command: {puts [list %self%'s %field% is now %value%]}
        default: green


      }
    }
    myclass create foo
    foo configure color purple
    > foo's color is now purple

  - <a name='7'></a>tool::define __property__ ?branch? *field* *value*

    Defines a new leaf in the class metadata tree\. With no branch, the leaf will
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
    Executes a block of text within the namespace of the object\. Lines that
    begin with a \# are ignored as comments\. Commands that begin with :: are
    interpreted as calling a global command\. All other Tcl commands that lack a
    "my" prefix are given one, to allow the script to exercise internal methods\.
    This method is intended for configuration scripts, where the object's
    methods are intepreting a domain specific language\.

    tool::class myclass \{
      constructor script \{
        my Eval\_Script $script
      \}

      method node \{nodename info\} \{
        my variable node
        dict set node $nodename $info
      \}

      method get \{args\} \{
        my variable node
        return \[dict get $node $args\]
      \}
    \}


    myclass create movies \{
      \# This block of code is executed by the object
      node \{The Day the Earth Stood Still\} \{
        date: 1952
        characters: \{GORT Klatoo\}
      \}
    \}


    movies get \{The Day the Earth Stood Still\} date:
    > 1952

  - <a name='17'></a>*object* __Option\_Default__ *field*

    Computes the default value for an option\. See __tool::option\_handling__\.

# <a name='section5'></a>AUTHORS







|
|
|
<
>
|


<
>
|

|
<
<
>
>
|
|
|

|
<
<
>
>
|







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
    Executes a block of text within the namespace of the object\. Lines that
    begin with a \# are ignored as comments\. Commands that begin with :: are
    interpreted as calling a global command\. All other Tcl commands that lack a
    "my" prefix are given one, to allow the script to exercise internal methods\.
    This method is intended for configuration scripts, where the object's
    methods are intepreting a domain specific language\.

    tool::class myclass {
      constructor script {
        my Eval_Script $script

      }
      method node {nodename info} {
        my variable node
        dict set node $nodename $info

      }
      method get {args} {
        my variable node
        return [dict get $node $args]


      }
    }
    myclass create movies {
      # This block of code is executed by the object
      node {The Day the Earth Stood Still} {
        date: 1952
        characters: {GORT Klatoo}


      }
    }
    movies get {The Day the Earth Stood Still} date:
    > 1952

  - <a name='17'></a>*object* __Option\_Default__ *field*

    Computes the default value for an option\. See __tool::option\_handling__\.

# <a name='section5'></a>AUTHORS
Changes to embedded/md/tcllib/files/modules/transfer/connect.md.
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# <a name='section3'></a>Secure connections

One way to secure connections made by objects of this package is to require the
package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__ and then configure the
option __\-socketcmd__ to force the use of command __tls::socket__ to
open the socket\.

    \# Load and initialize tls
    package require tls
    tls::init \-cafile /path/to/ca/cert \-keyfile \.\.\.

    \# Create a connector with secure socket setup,
    transfer::connect C \-socketcmd tls::socket \.\.\.
    \.\.\.

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use







|

|

|
|
|







220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# <a name='section3'></a>Secure connections

One way to secure connections made by objects of this package is to require the
package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__ and then configure the
option __\-socketcmd__ to force the use of command __tls::socket__ to
open the socket\.

    # Load and initialize tls
    package require tls
    tls::init -cafile /path/to/ca/cert -keyfile ...

    # Create a connector with secure socket setup,
    transfer::connect C -socketcmd tls::socket ...
    ...

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *transfer* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *transfer* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/transfer/receiver.md.
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# <a name='section3'></a>Secure connections

One way to secure connections made by objects of this package is to require the
package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__ and then configure the
option __\-socketcmd__ to force the use of command __tls::socket__ to
open the socket\.

    \# Load and initialize tls
    package require tls
    tls::init \-cafile /path/to/ca/cert \-keyfile \.\.\.

    \# Create a connector with secure socket setup,
    transfer::receiver R \-socketcmd tls::socket \.\.\.
    \.\.\.

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use







|

|

|
|
|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# <a name='section3'></a>Secure connections

One way to secure connections made by objects of this package is to require the
package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__ and then configure the
option __\-socketcmd__ to force the use of command __tls::socket__ to
open the socket\.

    # Load and initialize tls
    package require tls
    tls::init -cafile /path/to/ca/cert -keyfile ...

    # Create a connector with secure socket setup,
    transfer::receiver R -socketcmd tls::socket ...
    ...

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *transfer* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|







295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *transfer* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/transfer/tqueue.md.
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
them\. Because otherwise everything in the system which depends on getting a
notification about the status of a request will hang in the air\. I am slowly
convincing myself that it is more sensible to trigger the relevant completion
callbacks with an error message about the queue abort, and 0 bytes transfered\.

All transfer requests are of the form

    \{type data options\.\.\.\}

where *type* is in \{__chan__, __string__\}, and *data* specifies the
information to transfer\. For __chan__ the data is the handle of the channel
containing the actual information to transfer, whereas for __string__
*data* contains directly the information to transfer\. The *options* are a
list of them and their values, and are the same as are accepted by the low\-level
copy operations of the package __[transfer::copy](copyops\.md)__\. Note







|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
them\. Because otherwise everything in the system which depends on getting a
notification about the status of a request will hang in the air\. I am slowly
convincing myself that it is more sensible to trigger the relevant completion
callbacks with an error message about the queue abort, and 0 bytes transfered\.

All transfer requests are of the form

    {type data options...}

where *type* is in \{__chan__, __string__\}, and *data* specifies the
information to transfer\. For __chan__ the data is the handle of the channel
containing the actual information to transfer, whereas for __string__
*data* contains directly the information to transfer\. The *options* are a
list of them and their values, and are the same as are accepted by the low\-level
copy operations of the package __[transfer::copy](copyops\.md)__\. Note
Changes to embedded/md/tcllib/files/modules/transfer/transmitter.md.
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# <a name='section3'></a>Secure connections

One way to secure connections made by objects of this package is to require the
package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__ and then configure the
option __\-socketcmd__ to force the use of command __tls::socket__ to
open the socket\.

    \# Load and initialize tls
    package require tls
    tls::init \-cafile /path/to/ca/cert \-keyfile \.\.\.

    \# Create a connector with secure socket setup,
    transfer::transmitter T \-socketcmd tls::socket \.\.\.
    \.\.\.

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use







|

|

|
|
|







279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# <a name='section3'></a>Secure connections

One way to secure connections made by objects of this package is to require the
package __[tls](\.\./\.\./\.\./\.\./index\.md\#tls)__ and then configure the
option __\-socketcmd__ to force the use of command __tls::socket__ to
open the socket\.

    # Load and initialize tls
    package require tls
    tls::init -cafile /path/to/ca/cert -keyfile ...

    # Create a connector with secure socket setup,
    transfer::transmitter T -socketcmd tls::socket ...
    ...

# <a name='section4'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.

Policy decisions like the set of protocols to support and what ciphers to use
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *transfer* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section5'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *transfer* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/treeql/treeql.md.
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
         to\.

      1. The arguments used \(i\.e\. operator name and arguments\) are removed from
         the list of method arguments, and then the whole process is repeated
         from step \[1\], until the list of arguments is empty or an error
         occurred\.

            \# q is the query object\.

            q query root children get data

            \# The above query
            \# \- Resets the node set to the root node \- root
            \# \- Adds the children of root to the set \- children
            \# \- Replaces the node set with the       \- get data
            \#   values for the attribute 'data',
            \#   for all nodes in the set which
            \#   have such an attribute\.
            \# \- And returns this information\.

            \# Below we can see the same query, but rewritten
            \# to show the structure as it is seen by the query
            \# interpreter\.

            q query \\\\
        	    root \\\\
        	    children \\\\
        	    get data

    The operators of the TreeQL language available for this are explained in the
    section about [The Tree Query Language](#section3)\. This section also
    explains the term *node set* used above\.

  - <a name='3'></a>*qo* __result__







|



|
|
|
|
|
|
|
|

|
|
|

|
|
|







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
         to\.

      1. The arguments used \(i\.e\. operator name and arguments\) are removed from
         the list of method arguments, and then the whole process is repeated
         from step \[1\], until the list of arguments is empty or an error
         occurred\.

            # q is the query object.

            q query root children get data

            # The above query
            # - Resets the node set to the root node - root
            # - Adds the children of root to the set - children
            # - Replaces the node set with the       - get data
            #   values for the attribute 'data',
            #   for all nodes in the set which
            #   have such an attribute.
            # - And returns this information.

            # Below we can see the same query, but rewritten
            # to show the structure as it is seen by the query
            # interpreter.

            q query \\
        	    root \\
        	    children \\
        	    get data

    The operators of the TreeQL language available for this are explained in the
    section about [The Tree Query Language](#section3)\. This section also
    explains the term *node set* used above\.

  - <a name='3'></a>*qo* __result__
Changes to embedded/md/tcllib/files/modules/try/tcllib_throw.md.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  - <a name='1'></a>__::throw__ *error\_code* *error\_message*

    throw is merely a reordering of the arguments of the error command\. It
    throws an error with the indicated error code and error message\.

# <a name='section2'></a>EXAMPLES

    __throw__ \{MYERROR CODE\} "My error message"

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *try* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  - <a name='1'></a>__::throw__ *error\_code* *error\_message*

    throw is merely a reordering of the arguments of the error command\. It
    throws an error with the indicated error code and error message\.

# <a name='section2'></a>EXAMPLES

    __throw__ {MYERROR CODE} "My error message"

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *try* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/try/tcllib_try.md.
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
        original exception's status dictionary will be added to the new
        exception's status dictionary under the __\-during__ key\.

# <a name='section2'></a>EXAMPLES

Ensure that a file is closed no matter what:

    set f \[open /some/file/name a\]
    __try__ \{
        puts \\$f "some message"
        \# \.\.\.
    \} __finally__ \{
        close \\$f
    \}


Handle different reasons for a file to not be openable for reading:

    __try__ \{
        set f \[open /some/file/name\]
    \} __trap__ \{POSIX EISDIR\} \{\} \{
        puts "failed to open /some/file/name: it's a directory"
    \} __trap__ \{POSIX ENOENT\} \{\} \{
        puts "failed to open /some/file/name: it doesn't exist"
    \}


# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *try* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|
|
|
|
|
|
<
>



|
|
|

|

<
>







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
        original exception's status dictionary will be added to the new
        exception's status dictionary under the __\-during__ key\.

# <a name='section2'></a>EXAMPLES

Ensure that a file is closed no matter what:

    set f [open /some/file/name a]
    __try__ {
        puts \$f "some message"
        # ...
    } __finally__ {
        close \$f

    }

Handle different reasons for a file to not be openable for reading:

    __try__ {
        set f [open /some/file/name]
    } __trap__ {POSIX EISDIR} {} {
        puts "failed to open /some/file/name: it's a directory"
    } __trap__ {POSIX ENOENT} {} {
        puts "failed to open /some/file/name: it doesn't exist"

    }

# <a name='section3'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *try* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/udpcluster/udpcluster.md.
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
are open, and what protocols are expected on those ports\. Developers are free to
add any additional key/value pairs beyond those\.

Using udpcluster\.

For every service you wish to publish invoke:

    cluster::publish echo@\[cluster::macid\] \{port 10000 protocol echo\}

To query what services are available on the local network:

    set results \[cluster::search PATTERN\]
    \# And inside that result\.\.\.
    echo@LOCALMACID \{
       port 10000
       protocol echo
    \}


To unpublish a service:

    cluster::unpublish echo@\[cluster::macid\]

Results will Historical Notes:

This tool was originally known as nns::cluster, but as development progressed,
it was clear that it wasn't interacting with any of the other facilities in NNS\.

# <a name='section2'></a>Bugs, Ideas, Feedback







|



|
|
|


<
>



|







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
are open, and what protocols are expected on those ports\. Developers are free to
add any additional key/value pairs beyond those\.

Using udpcluster\.

For every service you wish to publish invoke:

    cluster::publish echo@[cluster::macid] {port 10000 protocol echo}

To query what services are available on the local network:

    set results [cluster::search PATTERN]
    # And inside that result...
    echo@LOCALMACID {
       port 10000
       protocol echo

    }

To unpublish a service:

    cluster::unpublish echo@[cluster::macid]

Results will Historical Notes:

This tool was originally known as nns::cluster, but as development progressed,
it was clear that it wasn't interacting with any of the other facilities in NNS\.

# <a name='section2'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/units/units.md.
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

    Converts the *value* string into a floating point number, scaled to the
    specified *targetUnits*\. The *value* string may contain a number and
    units\. If units are specified, then they must be compatible with the
    *targetUnits*\. If units are not specified for the *value*, then it will
    be scaled to the target units\. For example,

        % ::units::convert "2\.3 miles" km
        3\.7014912
        % ::units::convert 300m/s miles/hour
        671\.080887616
        % ::units::convert "1\.0 m kg/s^2" newton
        1\.0
        % ::units::convert 1\.0 millimeter
        1000\.0

  - <a name='2'></a>__::units::reduce__ *unitString*

    Returns a unit string consisting of a scale factor followed by a space
    separated list of sorted and reduced primitive units\. The reduced unit
    string may include a forward\-slash \(separated from the surrounding primitive
    subunits by spaces\) indicating that the remaining subunits are in the
    denominator\. Generates an error if the *unitString* is invalid\.

        % ::units::reduce pascal
        1000\.0 gram / meter second second

  - <a name='3'></a>__::units::new__ *name* *baseUnits*

    Creates a new unit conversion with the specified name\. The new unit *name*
    must be only alphabetic \(upper or lower case\) letters\. The *baseUnits*
    string can consist of any valid units conversion string, including constant
    factors, numerator and denominator parts, units with prefixes, and
    exponents\. The baseUnits may contain any number of subunits, but it must
    reduce to primitive units\. BaseUnits could also be the string *\-primitive*
    to represent a new kind of quantity which cannot be derived from other
    units\. But you probably would not do that unless you have discovered some
    kind of new universal property\.

        % ::units::new furlong "220 yards"
        % ::units::new fortnight "14 days"
        % ::units::convert 100m/s furlongs/fortnight
        601288\.475303

# <a name='section3'></a>UNIT STRING FORMAT

Value and unit string format is quite flexible\. It is possible to define
virtually any combination of units, prefixes, and powers\. Valid unit strings
must conform to these rules\.








|
|

|
|
|
|
|










|
















|







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

    Converts the *value* string into a floating point number, scaled to the
    specified *targetUnits*\. The *value* string may contain a number and
    units\. If units are specified, then they must be compatible with the
    *targetUnits*\. If units are not specified for the *value*, then it will
    be scaled to the target units\. For example,

        % ::units::convert "2.3 miles" km
        3.7014912
        % ::units::convert 300m/s miles/hour
        671.080887616
        % ::units::convert "1.0 m kg/s^2" newton
        1.0
        % ::units::convert 1.0 millimeter
        1000.0

  - <a name='2'></a>__::units::reduce__ *unitString*

    Returns a unit string consisting of a scale factor followed by a space
    separated list of sorted and reduced primitive units\. The reduced unit
    string may include a forward\-slash \(separated from the surrounding primitive
    subunits by spaces\) indicating that the remaining subunits are in the
    denominator\. Generates an error if the *unitString* is invalid\.

        % ::units::reduce pascal
        1000.0 gram / meter second second

  - <a name='3'></a>__::units::new__ *name* *baseUnits*

    Creates a new unit conversion with the specified name\. The new unit *name*
    must be only alphabetic \(upper or lower case\) letters\. The *baseUnits*
    string can consist of any valid units conversion string, including constant
    factors, numerator and denominator parts, units with prefixes, and
    exponents\. The baseUnits may contain any number of subunits, but it must
    reduce to primitive units\. BaseUnits could also be the string *\-primitive*
    to represent a new kind of quantity which cannot be derived from other
    units\. But you probably would not do that unless you have discovered some
    kind of new universal property\.

        % ::units::new furlong "220 yards"
        % ::units::new fortnight "14 days"
        % ::units::convert 100m/s furlongs/fortnight
        601288.475303

# <a name='section3'></a>UNIT STRING FORMAT

Value and unit string format is quite flexible\. It is possible to define
virtually any combination of units, prefixes, and powers\. Valid unit strings
must conform to these rules\.

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
    string denoted by a circumflex \("^"\), followed by a integer, after the unit
    name \(or plural suffix, if there is one\)\. Negative exponents are not
    allowed\. \(Remember that the hyphen is a unit separator\.\)

## <a name='subsection1'></a>Example Valid Unit Strings

    Unit String              Reduced Unit String
    \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    meter                    1\.0 meter
    kilometer                1000\.0 meter
    km                       1000\.0 meter
    km/s                     1000\.0 meter / second
    /microsecond             1000000\.0 / second
    /us                      1000000\.0 / second
    kg\-m/s^2                 1000\.0 gram meter / second second
    30second                 30\.0 second
    30 second                30\.0 second
    30 seconds               30\.0 second
    200\*meter/20\.5\*second    9\.75609756098 meter / second

# <a name='section4'></a>SI UNITS

The standard SI units are predefined according to *NIST Special Publication
330*\. Standard units for both SI Base Units \(Table 1\) and SI Derived Units with
Special Names \(Tables 3a and 3b\) are included here for reference\. Each standard
unit name and abbreviation are included in this package\.

## <a name='subsection2'></a>SI Base Units

    Quantity                Unit Name    Abbr\.
    \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    Length                  meter        m
    Mass                    kilogram     kg
    Time                    second       s
    Current                 ampere       A
    Temperature             kelvin       K
    Amount                  mole         mol
    Luminous Intensity      candela      cd

## <a name='subsection3'></a>SI Derived Units with Special Names

    Quantity                Unit Name    Abbr\.   Units     Base Units
    \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    plane angle             radian      rad     m/m       m/m
    solid angle             steradian   sr      m^2/m^2   m^2/m^2
    frequency               hertz       Hz                /s
    force                   newton      N                 m\-kg/s^2
    pressure                pascal      Pa      N/m^2     kg/m\-s^2
    energy, work            joule       J       N\-m       m^2\-kg/s^2
    power, radiant flux     watt        W       J/s       m^2\-kg/s^3
    electric charge         coulomb     C                 s\-A
    electric potential      volt        V       W/A       m^2\-kg/s^3\-A
    capacitance             farad       F       C/V       s^4\-A^2/m^2\-kg
    electric resistance     ohm                 V/A       m^2\-kg/s^3\-A^2
    electric conductance    siemens     S       A/V       s^3\-A^2/m^2\-kg
    magnetic flux           weber       Wb      V\-s       m^2\-kg/s^2\-A
    magnetic flux density   tesla       T       Wb/m^2    kg/s^2\-A
    inductance              henry       H       Wb/A      m^2\-kg/s^2\-A^2
    luminous flux           lumen       lm                cd\-sr
    illuminance             lux         lx      lm/m^2    cd\-sr/m^2
    activity \(of a
    radionuclide\)           becquerel   Bq                /s
    absorbed dose           gray        Gy      J/kg      m^2/s^2
    dose equivalent         sievert     Sv      J/kg      m^2/s^2

Note that the SI unit kilograms is actually implemented as grams because 1e\-6
kilogram = 1 milligram, not 1 microkilogram\. The abbreviation for Electric
Resistance \(ohms\), which is the omega character, is not supported\.








|
|
|
|
|
|
|
|
|
|
|
|










|
|










|
|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
    string denoted by a circumflex \("^"\), followed by a integer, after the unit
    name \(or plural suffix, if there is one\)\. Negative exponents are not
    allowed\. \(Remember that the hyphen is a unit separator\.\)

## <a name='subsection1'></a>Example Valid Unit Strings

    Unit String              Reduced Unit String
    ------------------------------------------------------------
    meter                    1.0 meter
    kilometer                1000.0 meter
    km                       1000.0 meter
    km/s                     1000.0 meter / second
    /microsecond             1000000.0 / second
    /us                      1000000.0 / second
    kg-m/s^2                 1000.0 gram meter / second second
    30second                 30.0 second
    30 second                30.0 second
    30 seconds               30.0 second
    200*meter/20.5*second    9.75609756098 meter / second

# <a name='section4'></a>SI UNITS

The standard SI units are predefined according to *NIST Special Publication
330*\. Standard units for both SI Base Units \(Table 1\) and SI Derived Units with
Special Names \(Tables 3a and 3b\) are included here for reference\. Each standard
unit name and abbreviation are included in this package\.

## <a name='subsection2'></a>SI Base Units

    Quantity                Unit Name    Abbr.
    ---------------------------------------------
    Length                  meter        m
    Mass                    kilogram     kg
    Time                    second       s
    Current                 ampere       A
    Temperature             kelvin       K
    Amount                  mole         mol
    Luminous Intensity      candela      cd

## <a name='subsection3'></a>SI Derived Units with Special Names

    Quantity                Unit Name    Abbr.   Units     Base Units
    --------------------------------------------------------------------
    plane angle             radian      rad     m/m       m/m
    solid angle             steradian   sr      m^2/m^2   m^2/m^2
    frequency               hertz       Hz                /s
    force                   newton      N                 m-kg/s^2
    pressure                pascal      Pa      N/m^2     kg/m-s^2
    energy, work            joule       J       N-m       m^2-kg/s^2
    power, radiant flux     watt        W       J/s       m^2-kg/s^3
    electric charge         coulomb     C                 s-A
    electric potential      volt        V       W/A       m^2-kg/s^3-A
    capacitance             farad       F       C/V       s^4-A^2/m^2-kg
    electric resistance     ohm                 V/A       m^2-kg/s^3-A^2
    electric conductance    siemens     S       A/V       s^3-A^2/m^2-kg
    magnetic flux           weber       Wb      V-s       m^2-kg/s^2-A
    magnetic flux density   tesla       T       Wb/m^2    kg/s^2-A
    inductance              henry       H       Wb/A      m^2-kg/s^2-A^2
    luminous flux           lumen       lm                cd-sr
    illuminance             lux         lx      lm/m^2    cd-sr/m^2
    activity (of a
    radionuclide)           becquerel   Bq                /s
    absorbed dose           gray        Gy      J/kg      m^2/s^2
    dose equivalent         sievert     Sv      J/kg      m^2/s^2

Note that the SI unit kilograms is actually implemented as grams because 1e\-6
kilogram = 1 milligram, not 1 microkilogram\. The abbreviation for Electric
Resistance \(ohms\), which is the omega character, is not supported\.

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
SI Units can have a multiple or sub\-multiple prefix\. The prefix or its
abbreviation should appear before the unit, without spaces\. Compound prefixes
are not allowed, and a prefix should never be used alone\. These prefixes are
defined in Table 5 of *Special Publication 330*\.

## <a name='subsection4'></a>SI Prefixes

    Prefix Name     Abbr\.   Factor
    \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    yotta           Y       1e24
    zetta           Z       1e21
    exa             E       1e18
    peta            P       1e15
    tera            T       1e12
    giga            G       1e9
    mega            M       1e6
    kilo            k       1e3
    hecto           h       1e2
    deka            da      1e1
    deca                    1e1

    deci            d       1e\-1
    centi           c       1e\-2
    milli           m       1e\-3
    micro           u       1e\-6
    nano            n       1e\-9
    pico            p       1e\-12
    femto           f       1e\-15
    atto            a       1e\-18
    zepto           z       1e\-21
    yocto           y       1e\-24

Note that we define the same prefix with both the USA \("deka"\) and non\-USA
\("deca"\) spellings\. Also note that we take the liberty of allowing "micro" to be
typed as a "u" instead of the Greek character mu\.

Many non\-SI units are commonly used in applications\. Appendix B\.8 of *NIST
Special Publication 811* lists many non\-SI conversion factors\. It is not
possible to include all possible unit definitions in this package\. In some
cases, many different conversion factors exist for a given unit, depending on
the context\. \(The appendix lists over 40 conversions for British thermal units\!\)
Application specific conversions can always be added using the __new__
command, but some well known and often used conversions are included in this
package\.

## <a name='subsection5'></a>Non\-SI Units

    Unit Name            Abbr\.    Base Units
    \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
    angstrom                      1\.0E\-10 m
    astronomicalUnit     AU       1\.495979E11 m
    atmosphere                    1\.01325E5 Pa
    bar                           1\.0E5 Pa
    calorie                       4\.1868 J
    curie                         3\.7E10 Bq
    day                           8\.64E4 s
    degree                        1\.745329E\-2 rad
    erg                           1\.0E\-7 J
    faraday                       9\.648531 C
    fermi                         1\.0E\-15 m
    foot                 ft       3\.048E\-1 m
    gauss                         1\.0E\-4 T
    gilbert                       7\.957747E\-1 A
    grain                gr       6\.479891E\-5 kg
    hectare              ha       1\.0E4 m^2
    hour                 h        3\.6E3 s
    inch                 in       2\.54E\-2 m
    lightYear                     9\.46073E15 m
    liter                L        1\.0E\-3 m^3
    maxwell              Mx       1\.0E\-8 Wb
    mho                           1\.0 S
    micron                        1\.0E\-6 m
    mil                           2\.54E\-5 m
    mile                 mi       1\.609344E3 m
    minute               min      6\.0E1 s
    parsec               pc       3\.085E16 m
    pica                          4\.233333E\-3 m
    pound                lb       4\.535924E\-1 kg
    revolution                    6\.283185 rad
    revolutionPerMinute  rpm      1\.047198E\-1 rad/s
    yard                 yd       9\.144E\-1 m
    year                          3\.1536E7 s

## <a name='subsection6'></a>Quantities and Derived Units with Special Names

This units conversion package is limited specifically to unit reduction,
comparison, and scaling\. This package does not consider any of the quantity
names for either base or derived units\. A similar implementation or an extension
in a typed or object\-oriented language might introduce user defined types for







|
|












|
|
|
|
|
|
|
|
|
|
















|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
SI Units can have a multiple or sub\-multiple prefix\. The prefix or its
abbreviation should appear before the unit, without spaces\. Compound prefixes
are not allowed, and a prefix should never be used alone\. These prefixes are
defined in Table 5 of *Special Publication 330*\.

## <a name='subsection4'></a>SI Prefixes

    Prefix Name     Abbr.   Factor
    ---------------------------------------
    yotta           Y       1e24
    zetta           Z       1e21
    exa             E       1e18
    peta            P       1e15
    tera            T       1e12
    giga            G       1e9
    mega            M       1e6
    kilo            k       1e3
    hecto           h       1e2
    deka            da      1e1
    deca                    1e1

    deci            d       1e-1
    centi           c       1e-2
    milli           m       1e-3
    micro           u       1e-6
    nano            n       1e-9
    pico            p       1e-12
    femto           f       1e-15
    atto            a       1e-18
    zepto           z       1e-21
    yocto           y       1e-24

Note that we define the same prefix with both the USA \("deka"\) and non\-USA
\("deca"\) spellings\. Also note that we take the liberty of allowing "micro" to be
typed as a "u" instead of the Greek character mu\.

Many non\-SI units are commonly used in applications\. Appendix B\.8 of *NIST
Special Publication 811* lists many non\-SI conversion factors\. It is not
possible to include all possible unit definitions in this package\. In some
cases, many different conversion factors exist for a given unit, depending on
the context\. \(The appendix lists over 40 conversions for British thermal units\!\)
Application specific conversions can always be added using the __new__
command, but some well known and often used conversions are included in this
package\.

## <a name='subsection5'></a>Non\-SI Units

    Unit Name            Abbr.    Base Units
    --------------------------------------------------
    angstrom                      1.0E-10 m
    astronomicalUnit     AU       1.495979E11 m
    atmosphere                    1.01325E5 Pa
    bar                           1.0E5 Pa
    calorie                       4.1868 J
    curie                         3.7E10 Bq
    day                           8.64E4 s
    degree                        1.745329E-2 rad
    erg                           1.0E-7 J
    faraday                       9.648531 C
    fermi                         1.0E-15 m
    foot                 ft       3.048E-1 m
    gauss                         1.0E-4 T
    gilbert                       7.957747E-1 A
    grain                gr       6.479891E-5 kg
    hectare              ha       1.0E4 m^2
    hour                 h        3.6E3 s
    inch                 in       2.54E-2 m
    lightYear                     9.46073E15 m
    liter                L        1.0E-3 m^3
    maxwell              Mx       1.0E-8 Wb
    mho                           1.0 S
    micron                        1.0E-6 m
    mil                           2.54E-5 m
    mile                 mi       1.609344E3 m
    minute               min      6.0E1 s
    parsec               pc       3.085E16 m
    pica                          4.233333E-3 m
    pound                lb       4.535924E-1 kg
    revolution                    6.283185 rad
    revolutionPerMinute  rpm      1.047198E-1 rad/s
    yard                 yd       9.144E-1 m
    year                          3.1536E7 s

## <a name='subsection6'></a>Quantities and Derived Units with Special Names

This units conversion package is limited specifically to unit reduction,
comparison, and scaling\. This package does not consider any of the quantity
names for either base or derived units\. A similar implementation or an extension
in a typed or object\-oriented language might introduce user defined types for
Changes to embedded/md/tcllib/files/modules/uri/uri.md.
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

The Tcl command __file normalize__ will convert the backslashes to forward
slashes\. To generate a valid __path__ for the scheme
*[file](\.\./\.\./\.\./\.\./index\.md\#file)*, the normalized filename must be
prepended with "__/__", and then any characters that do not match the
__regexp__ bracket expression

    \[a\-zA\-Z0\-9$\_\.\+\!\*'\(,\)?:@&=\-\]

must be percent\-encoded\.

The result in this example is "__/C:/Other%20Files/startup\.txt__" which is a
valid value for __path__\.

    % uri::join path /C:/Other%20Files/startup\.txt scheme file

    file:///C:/Other%20Files/startup\.txt

    % uri::split file:///C:/Other%20Files/startup\.txt

    path /C:/Other%20Files/startup\.txt scheme file

On UNIX® systems filenames begin with "__/__" which is also used as the
directory separator\. The only action needed to convert a filename to a valid
__path__ is percent\-encoding\.

# <a name='section7'></a>CREDITS








|






|

|

|

|







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

The Tcl command __file normalize__ will convert the backslashes to forward
slashes\. To generate a valid __path__ for the scheme
*[file](\.\./\.\./\.\./\.\./index\.md\#file)*, the normalized filename must be
prepended with "__/__", and then any characters that do not match the
__regexp__ bracket expression

    [a-zA-Z0-9$_.+!*'(,)?:@&=-]

must be percent\-encoded\.

The result in this example is "__/C:/Other%20Files/startup\.txt__" which is a
valid value for __path__\.

    % uri::join path /C:/Other%20Files/startup.txt scheme file

    file:///C:/Other%20Files/startup.txt

    % uri::split file:///C:/Other%20Files/startup.txt

    path /C:/Other%20Files/startup.txt scheme file

On UNIX® systems filenames begin with "__/__" which is also used as the
directory separator\. The only action needed to convert a filename to a valid
__path__ is percent\-encoding\.

# <a name='section7'></a>CREDITS

Changes to embedded/md/tcllib/files/modules/uuid/uuid.md.
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  - <a name='2'></a>__::uuid::uuid equal__ *id1* *id2*

    Compares two uuids and returns true if both arguments are the same uuid\.

# <a name='section3'></a>EXAMPLES

    % uuid::uuid generate
    b12dc22c\-5c36\-41d2\-57da\-e29d0ef5839c

# <a name='section4'></a>REFERENCES

  1. Paul J\. Leach, "UUIDs and GUIDs", February 1998\.
     \([http://www\.opengroup\.org/dce/info/draft\-leach\-uuids\-guids\-01\.txt](http://www\.opengroup\.org/dce/info/draft\-leach\-uuids\-guids\-01\.txt)\)

# <a name='section5'></a>Bugs, Ideas, Feedback







|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  - <a name='2'></a>__::uuid::uuid equal__ *id1* *id2*

    Compares two uuids and returns true if both arguments are the same uuid\.

# <a name='section3'></a>EXAMPLES

    % uuid::uuid generate
    b12dc22c-5c36-41d2-57da-e29d0ef5839c

# <a name='section4'></a>REFERENCES

  1. Paul J\. Leach, "UUIDs and GUIDs", February 1998\.
     \([http://www\.opengroup\.org/dce/info/draft\-leach\-uuids\-guids\-01\.txt](http://www\.opengroup\.org/dce/info/draft\-leach\-uuids\-guids\-01\.txt)\)

# <a name='section5'></a>Bugs, Ideas, Feedback
Changes to embedded/md/tcllib/files/modules/valtype/cc_amex.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::amex validate \.\.\.\. ;\# Does nothing
    valtype::creditcard::amex validate \.\.\.\. ;\# Throws an error \(bad American Expresss creditcard number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::amex validate .... ;# Does nothing
    valtype::creditcard::amex validate .... ;# Throws an error (bad American Expresss creditcard number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/cc_discover.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::discover validate \.\.\.\. ;\# Does nothing
    valtype::creditcard::discover validate \.\.\.\. ;\# Throws an error \(bad Discover creditcard number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::discover validate .... ;# Does nothing
    valtype::creditcard::discover validate .... ;# Throws an error (bad Discover creditcard number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/cc_mastercard.md.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::mastercard validate \.\.\.\. ;\# Does nothing
    valtype::creditcard::mastercard validate \.\.\.\. ;\# Throws an error \(bad Mastercard creditcard number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::mastercard validate .... ;# Does nothing
    valtype::creditcard::mastercard validate .... ;# Throws an error (bad Mastercard creditcard number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/cc_visa.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::visa validate \.\.\.\. ;\# Does nothing
    valtype::creditcard::visa validate \.\.\.\. ;\# Throws an error \(bad VISA creditcard number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::creditcard::visa validate .... ;# Does nothing
    valtype::creditcard::visa validate .... ;# Throws an error (bad VISA creditcard number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/ean13.md.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::gs1::ean13 validate \.\.\.\. ;\# Does nothing
    valtype::gs1::ean13 validate \.\.\.\. ;\# Throws an error \(bad EAN13\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::gs1::ean13 validate .... ;# Does nothing
    valtype::gs1::ean13 validate .... ;# Throws an error (bad EAN13).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/iban.md.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::iban validate \.\.\.\. ;\# Does nothing
    valtype::iban validate \.\.\.\. ;\# Throws an error \(bad International Bank Account Number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::iban validate .... ;# Does nothing
    valtype::iban validate .... ;# Throws an error (bad International Bank Account Number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/imei.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::imei validate \.\.\.\. ;\# Does nothing
    valtype::imei validate \.\.\.\. ;\# Throws an error \(bad International Mobile Equipment Identity \(IMEI\) number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::imei validate .... ;# Does nothing
    valtype::imei validate .... ;# Throws an error (bad International Mobile Equipment Identity (IMEI) number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/isbn.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::isbn validate \.\.\.\. ;\# Does nothing
    valtype::isbn validate \.\.\.\. ;\# Throws an error \(bad ISBN\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::isbn validate .... ;# Does nothing
    valtype::isbn validate .... ;# Throws an error (bad ISBN).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/luhn.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::luhn validate \.\.\.\. ;\# Does nothing
    valtype::luhn validate \.\.\.\. ;\# Throws an error \(bad luhn checkdigit\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::luhn validate .... ;# Does nothing
    valtype::luhn validate .... ;# Throws an error (bad luhn checkdigit).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/luhn5.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::luhn5 validate \.\.\.\. ;\# Does nothing
    valtype::luhn5 validate \.\.\.\. ;\# Throws an error \(bad luhn5 checkdigit\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::luhn5 validate .... ;# Does nothing
    valtype::luhn5 validate .... ;# Throws an error (bad luhn5 checkdigit).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/usnpi.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::usnpi validate \.\.\.\. ;\# Does nothing
    valtype::usnpi validate \.\.\.\. ;\# Throws an error \(bad US National Provider Identifier \(US\-NPI\) number\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::usnpi validate .... ;# Does nothing
    valtype::usnpi validate .... ;# Throws an error (bad US National Provider Identifier (US-NPI) number).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/valtype/verhoeff.md.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::verhoeff validate \.\.\.\. ;\# Does nothing
    valtype::verhoeff validate \.\.\.\. ;\# Throws an error \(bad verhoeff checkdigit\)\.

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API








|
|







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Tcl value is an integer\.

Every validation type has a __validate__ method which is used to do the
validation\. This method must take a single argument, the value to be validated;
further, it must do nothing if the value is valid, but throw an error if the
value is invalid:

    valtype::verhoeff validate .... ;# Does nothing
    valtype::verhoeff validate .... ;# Throws an error (bad verhoeff checkdigit).

The __validate__ method will always return the validated value on success,
and throw the __\-errorcode__ INVALID on error, possibly with additional
elements which provide more details about the problem\.

# <a name='section2'></a>API

Changes to embedded/md/tcllib/files/modules/websocket/websocket.md.
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
textual message which should be echoed back by the echo service\. A real example
would probably use the __connect__ callback to know when connection to the
remote server has been establish and would only send data at that time\.

    package require websocket
    ::websocket::loglevel debug

    proc handler \{ sock type msg \} \{
        switch \-glob \-nocase \-\- $type \{
    	co\* \{
    	    puts "Connected on $sock"
    	\}

    	te\* \{
    	    puts "RECEIVED: $msg"
    	\}

    	cl\* \-
    	dis\* \{
    	\}
        \}


    \}


    proc test \{ sock \} \{
        puts "\[::websocket::conninfo $sock type\] from \[::websocket::conninfo $sock sockname\] to \[::websocket::conninfo $sock peername\]"

        ::websocket::send $sock text "Testing, testing\.\.\."
    \}


    set sock \[::websocket::open ws://echo\.websocket\.org/ handler\]
    after 400 test $sock
    vwait forever

# <a name='section5'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.







|
|
|

<
>
|

<
>
|
|
<
<
|
>
|
|
>
|
|

|
<
|
>
|







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
textual message which should be echoed back by the echo service\. A real example
would probably use the __connect__ callback to know when connection to the
remote server has been establish and would only send data at that time\.

    package require websocket
    ::websocket::loglevel debug

    proc handler { sock type msg } {
        switch -glob -nocase -- $type {
    	co* {
    	    puts "Connected on $sock"

    	}
    	te* {
    	    puts "RECEIVED: $msg"

    	}
    	cl* -
    	dis* {


    	}
        }

    }

    proc test { sock } {
        puts "[::websocket::conninfo $sock type] from [::websocket::conninfo $sock sockname] to [::websocket::conninfo $sock peername]"

        ::websocket::send $sock text "Testing, testing..."

    }

    set sock [::websocket::open ws://echo.websocket.org/ handler]
    after 400 test $sock
    vwait forever

# <a name='section5'></a>TLS Security Considerations

This package uses the __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ package to
handle the security for __https__ urls and other socket connections\.
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init \-tls1 1 ;\# forcibly activate support for the TLS1 protocol

    \.\.\. your own application code \.\.\.

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *websocket* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.







|

|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
To handle this change the applications using
__[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ must be patched, and not this
package, nor __[TLS](\.\./\.\./\.\./\.\./index\.md\#tls)__ itself\. Such a patch
may be as simple as generally activating __tls1__ support, as shown in the
example below\.

    package require tls
    tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

    ... your own application code ...

# <a name='section6'></a>Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and
other problems\. Please report such in the category *websocket* of the [Tcllib
Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas
for enhancements you may have for either package and/or documentation\.
Changes to embedded/md/tcllib/files/modules/yaml/huddle.md.
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
When converting huddle\-notation to other serialization formats like JSON or YAML
this type information is used to select the proper notation\. And when going from
JSON/YAML/\.\.\. to huddle their notation can be used to select the proper huddle
type\.

In that manner huddle can serve as a common intermediary format\.

    huddle\-format: >
      \{HUDDLE \{huddle\-node\}\}
    huddle\-node: >
      \{tag content\}
    each content of tag means:
      s: \(content is a\) string
      L: list, each sub node is a huddle\-node
      D: dict, each sub node is a huddle\-node
    confirmed:
      \- JSON
      \- YAML\(generally, but cannot discribe YAML\-tags\)
    limitation:
      \- cannot discribe aliases from a node to other node\.

The __huddle__ package returns data as a Tcl
__[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__\. Either the
__[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__ package or Tcl 8\.5 is required for
use\.

# <a name='section2'></a>COMMANDS







|
|
|
|

|
|
|

|
|

|







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
When converting huddle\-notation to other serialization formats like JSON or YAML
this type information is used to select the proper notation\. And when going from
JSON/YAML/\.\.\. to huddle their notation can be used to select the proper huddle
type\.

In that manner huddle can serve as a common intermediary format\.

    huddle-format: >
      {HUDDLE {huddle-node}}
    huddle-node: >
      {tag content}
    each content of tag means:
      s: (content is a) string
      L: list, each sub node is a huddle-node
      D: dict, each sub node is a huddle-node
    confirmed:
      - JSON
      - YAML(generally, but cannot discribe YAML-tags)
    limitation:
      - cannot discribe aliases from a node to other node.

The __huddle__ package returns data as a Tcl
__[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__\. Either the
__[dict](\.\./\.\./\.\./\.\./index\.md\#dict)__ package or Tcl 8\.5 is required for
use\.

# <a name='section2'></a>COMMANDS
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
    Almost the same as __dict remove__\. Remove a sub\-object from the huddle
    object\. *key* can be used to huddle\-list's index\.

  - <a name='13'></a>__huddle combine__ *object1* *object2* ?*object3 \.\.\.*?

    Merging huddle objects given\.

    % set aa \[huddle create a b c d\]
    HUDDLE \{D \{a \{s b\} c \{s d\}\}\}
    % set bb \[huddle create a k l m\]
    HUDDLE \{D \{a \{s k\} l \{s m\}\}\}
    % huddle combine $aa $bb
    HUDDLE \{D \{a \{s k\} c \{s d\} l \{s m\}\}\}

  - <a name='14'></a>__huddle equal__ *object1* *object2*

    Comparing two huddle objects recursively\. When to equal, returns 1,
    otherwise 0\.

    % set aa \[huddle create a b c d\]
    HUDDLE \{D \{a \{s b\} c \{s d\}\}\}
    % set bb \[huddle create c d a b\]
    HUDDLE \{D \{c \{s d\} a \{s b\}\}\}
    % huddle equal $aa $bb
    1

  - <a name='15'></a>__huddle append__ *objectVar* *key* *value* ?*key value \.\.\.*?

  - <a name='16'></a>__huddle append__ *objectVar* *value* ?*value \.\.\.*?

    Appending child elements\. When for dicts, giving key/value\. When for lists,
    giving values\.

    % set aa \[huddle create a b c d\]
    HUDDLE \{D \{a \{s b\} c \{s d\}\}\}
    % huddle append aa a k l m
    HUDDLE \{D \{a \{s k\} c \{s d\} l \{s m\}\}\}
    % set bb \[huddle list i j k l\]
    HUDDLE \{L \{\{s i\} \{s j\} \{s k\} \{s l\}\}\}
    % huddle append bb g h i
    HUDDLE \{L \{\{s i\} \{s j\} \{s k\} \{s l\} \{s g\} \{s h\} \{s i\}\}\}

  - <a name='17'></a>__huddle keys__ *object*

    The same as __dict keys__\.

  - <a name='18'></a>__huddle llength__ *object*








|
|
|
|

|






|
|
|
|










|
|

|
|
|

|







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
    Almost the same as __dict remove__\. Remove a sub\-object from the huddle
    object\. *key* can be used to huddle\-list's index\.

  - <a name='13'></a>__huddle combine__ *object1* *object2* ?*object3 \.\.\.*?

    Merging huddle objects given\.

    % set aa [huddle create a b c d]
    HUDDLE {D {a {s b} c {s d}}}
    % set bb [huddle create a k l m]
    HUDDLE {D {a {s k} l {s m}}}
    % huddle combine $aa $bb
    HUDDLE {D {a {s k} c {s d} l {s m}}}

  - <a name='14'></a>__huddle equal__ *object1* *object2*

    Comparing two huddle objects recursively\. When to equal, returns 1,
    otherwise 0\.

    % set aa [huddle create a b c d]
    HUDDLE {D {a {s b} c {s d}}}
    % set bb [huddle create c d a b]
    HUDDLE {D {c {s d} a {s b}}}
    % huddle equal $aa $bb
    1

  - <a name='15'></a>__huddle append__ *objectVar* *key* *value* ?*key value \.\.\.*?

  - <a name='16'></a>__huddle append__ *objectVar* *value* ?*value \.\.\.*?

    Appending child elements\. When for dicts, giving key/value\. When for lists,
    giving values\.

    % set aa [huddle create a b c d]
    HUDDLE {D {a {s b} c {s d}}}
    % huddle append aa a k l m
    HUDDLE {D {a {s k} c {s d} l {s m}}}
    % set bb [huddle list i j k l]
    HUDDLE {L {{s i} {s j} {s k} {s l}}}
    % huddle append bb g h i
    HUDDLE {L {{s i} {s j} {s k} {s l} {s g} {s h} {s i}}}

  - <a name='17'></a>__huddle keys__ *object*

    The same as __dict keys__\.

  - <a name='18'></a>__huddle llength__ *object*

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

        the node is a boolean\.

      * ____null____

        the node is a null\.

    % huddle type \{HUDDLE \{s str\}\}
    string
    % huddle type \{HUDDLE \{L \{\{s a\} \{s b\} \{s c\}\}\}\}
    list
    % huddle type \{HUDDLE \{D \{aa \{s b\} cc \{s d\}\}\}\} cc
    string

  - <a name='20'></a>__huddle strip__ *object*

    Stripped all tags\. Converted to normal Tcl's list/dict\.

  - <a name='21'></a>__huddle jsondump__ *object* ?*offset*? ?*newline*? ?*begin\_offset*?

    dump a json\-stream from the huddle\-object\.

      * ____offset__ ""__

        begin offset as spaces " "\.

    \# normal output has some indents\. some strings are escaped\.
    % huddle jsondump \{HUDDLE \{L \{\{L \{\{s i\} \{s baa\} \{s \\\\k\} \{L \{\{s 1\.0\} \{s true\} \{s /g\} \{s h\}\}\} \{L \{\{s g\}\}\}\}\} \{s t\}\}\}\}
    \[
      \[


        "i",
        "baa",
        "\\\\k",
        \[

          1\.0,
          true,
          "\\/g",
          "h"
        \],
        \["g"\]
      \],
      "t"
    \]

    \# stripped output
    % huddle jsondump \{HUDDLE \{D \{dd \{D \{bb \{D \{a \{s baa\} c \{s \{d
    a\}\}\}\} cc \{D \{g \{s h\}\}\}\}\} ee \{D \{i \{s j\} k \{s 1\} j \{s \{ m\\a\}\}\}\}\}\}\} "" ""
    \{"dd": \{"bb": \{"a": "baa","c": "d\\na"\},"cc": \{"g": "h"\}\},"ee": \{"i": "j","k": 1,"j": " m\\\\a"\}\}

  - <a name='22'></a>__huddle compile__ *spec* *data*

    construct a huddle object from plain old tcl values\. *spec* is defined as
    follows:

      * __string__







|

|

|














|
|
<
<
>
>


|
<
>
|

|

|
|
|

<
>
|
|
|
|







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

        the node is a boolean\.

      * ____null____

        the node is a null\.

    % huddle type {HUDDLE {s str}}
    string
    % huddle type {HUDDLE {L {{s a} {s b} {s c}}}}
    list
    % huddle type {HUDDLE {D {aa {s b} cc {s d}}}} cc
    string

  - <a name='20'></a>__huddle strip__ *object*

    Stripped all tags\. Converted to normal Tcl's list/dict\.

  - <a name='21'></a>__huddle jsondump__ *object* ?*offset*? ?*newline*? ?*begin\_offset*?

    dump a json\-stream from the huddle\-object\.

      * ____offset__ ""__

        begin offset as spaces " "\.

    # normal output has some indents. some strings are escaped.
    % huddle jsondump {HUDDLE {L {{L {{s i} {s baa} {s \\k} {L {{s 1.0} {s true} {s /g} {s h}}} {L {{s g}}}}} {s t}}}}


    [
      [
        "i",
        "baa",
        "\\k",

        [
          1.0,
          true,
          "\/g",
          "h"
        ],
        ["g"]
      ],
      "t"

    ]
    # stripped output
    % huddle jsondump {HUDDLE {D {dd {D {bb {D {a {s baa} c {s {d
    a}}}} cc {D {g {s h}}}}} ee {D {i {s j} k {s 1} j {s { m\a}}}}}}} "" ""
    {"dd": {"bb": {"a": "baa","c": "d\na"},"cc": {"g": "h"}},"ee": {"i": "j","k": 1,"j": " m\\a"}}

  - <a name='22'></a>__huddle compile__ *spec* *data*

    construct a huddle object from plain old tcl values\. *spec* is defined as
    follows:

      * __string__
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

        data is a tcl dict where the value of key xx is a tcl list

      * dict \* list

        data is a tcl dict of lists *data* is plain old tcl values

    % huddle compile \{dict \* list\} \{a \{1 2 3\} b \{4 5\}\}
    HUDDLE \{D \{a \{L \{\{s 1\} \{s 2\} \{s 3\}\}\} b \{L \{\{s 4\} \{s 5\}\}\}\}\}
    % huddle compile \{dict \* \{list \{dict d list\}\}\} \{a \{\{c 1\} \{d \{2 2 2\} e 3\}\} b \{\{f 4 g 5\}\}\}
    HUDDLE \{D \{a \{L \{\{D \{c \{s 1\}\}\} \{D \{d \{L \{\{s 2\} \{s 2\} \{s 2\}\}\} e \{s 3\}\}\}\}\} b \{L \{\{D \{f \{s 4\} g \{s 5\}\}\}\}\}\}\}

  - <a name='23'></a>__huddle isHuddle__ *object*

    if *object* is a huddle, returns 1\. the other, returns 0\.

  - <a name='24'></a>__huddle checkHuddle__ *object*

    if *object* is not a huddle, rises an error\.

  - <a name='25'></a>__huddle to\_node__ *object* ?*tag*?

    for type\-callbacks\.

    if *object* is a huddle, returns root\-node\. the other, returns __\[list s
    $object\]__\.

    % huddle to\_node str
    s str
    % huddle to\_node str \!\!str
    \!\!str str
    % huddle to\_node \{HUDDLE \{s str\}\}
    s str
    % huddle to\_node \{HUDDLE \{l \{a b c\}\}\}
    l \{a b c\}

  - <a name='26'></a>__huddle wrap__ *tag* *src*

    for type\-callbacks\.

    Create a huddle object from *src* with specified *tag*\.

    % huddle wrap "" str
    HUDDLE str
    % huddle wrap s str
    HUDDLE \{s str\}

  - <a name='27'></a>__huddle call__ *tag* *command* *args*

    for type\-callbacks\.

    devolving *command* to default *tag*\-callback








|
|
|
|
















|

|
|
|

|
|










|







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

        data is a tcl dict where the value of key xx is a tcl list

      * dict \* list

        data is a tcl dict of lists *data* is plain old tcl values

    % huddle compile {dict * list} {a {1 2 3} b {4 5}}
    HUDDLE {D {a {L {{s 1} {s 2} {s 3}}} b {L {{s 4} {s 5}}}}}
    % huddle compile {dict * {list {dict d list}}} {a {{c 1} {d {2 2 2} e 3}} b {{f 4 g 5}}}
    HUDDLE {D {a {L {{D {c {s 1}}} {D {d {L {{s 2} {s 2} {s 2}}} e {s 3}}}}} b {L {{D {f {s 4} g {s 5}}}}}}}

  - <a name='23'></a>__huddle isHuddle__ *object*

    if *object* is a huddle, returns 1\. the other, returns 0\.

  - <a name='24'></a>__huddle checkHuddle__ *object*

    if *object* is not a huddle, rises an error\.

  - <a name='25'></a>__huddle to\_node__ *object* ?*tag*?

    for type\-callbacks\.

    if *object* is a huddle, returns root\-node\. the other, returns __\[list s
    $object\]__\.

    % huddle to_node str
    s str
    % huddle to_node str !!str
    !!str str
    % huddle to_node {HUDDLE {s str}}
    s str
    % huddle to_node {HUDDLE {l {a b c}}}
    l {a b c}

  - <a name='26'></a>__huddle wrap__ *tag* *src*

    for type\-callbacks\.

    Create a huddle object from *src* with specified *tag*\.

    % huddle wrap "" str
    HUDDLE str
    % huddle wrap s str
    HUDDLE {s str}

  - <a name='27'></a>__huddle call__ *tag* *command* *args*

    for type\-callbacks\.

    devolving *command* to default *tag*\-callback

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
  - <a name='34'></a>__[remove](\.\./\.\./\.\./\.\./index\.md\#remove)__ *src* *key* *value*

    removes a sub\-node from the tagged\-content, and returns self\.

__strip__ must be defined at all types\. __get\_sub__ must be defined at
container types\. __set/remove__ shuould be defined, if you call them\.

    \# callback sample for my\-dict
    proc my\_dict\_setting \{command args\} \{
        switch \-\- $command \{
            setting \{ ; \# type definition
                return \{
                    type dict
                    method \{create keys\}
                    tag \{d child D parent\}
                    constructor create
                    str s
                \}

                \# type:   the type\-name
                \# method: add methods to huddle's subcommand\.
                \#          "get\_sub/strip/set/remove/equal/append" called by huddle module\.
                \#          "strip" must be defined at all types\.
                \#          "get\_sub" must be defined at container types\.
                \#          "set/remove/equal/append" shuould be defined, if you call them\.
                \# tag:    tag definition\("child/parent" word is maybe obsoleted\)
            \}

            get\_sub \{ ; \# get a sub\-node specified by "key" from the tagged\-content
                foreach \{src key\} $args break
                return \[dict get $src $key\]
            \}

            strip \{ ; \# strip from the tagged\-content
                foreach \{src nop\} $args break
                foreach \{key val\} $src \{
                    lappend result $key \[huddle strip $val\]
                \}

                return $result
            \}

            set \{ ; \# set a sub\-node from the tagged\-content
                foreach \{src key value\} $args break
                dict set src $key $value
                return $src
            \}

            remove \{ ; \# remove a sub\-node from the tagged\-content
                foreach \{src key value\} $args break
                return \[dict remove $src $key\]
            \}

            equal \{ ; \# check equal for each node
                foreach \{src1 src2\} $args break
                if \{\[llength $src1\] \!= \[llength $src2\]\} \{return 0\}
                foreach \{key1 val1\} $src1 \{
                    if \{\!\[dict exists $src2 $key1\]\} \{return 0\}
                    if \{\!\[huddle \_equal\_subs $val1 \[dict get $src2 $key1\]\]\} \{return 0\}
                \}

                return 1
            \}

            append \{ ; \# append nodes
                foreach \{str src list\} $args break
                if \{\[llength $list\] % 2\} \{error \{wrong \# args: should be "huddle append objvar ?key value \.\.\.?"\}\}
                set resultL $src
                foreach \{key value\} $list \{
                    if \{$str ne ""\} \{
                        lappend resultL $key \[huddle to\_node $value $str\]
                    \} else \{
                        lappend resultL $key $value
                    \}
                \}


                return \[eval dict create $resultL\]
            \}

            create \{ ; \# $args: all arguments after "huddle create"
                if \{\[llength $args\] % 2\} \{error \{wrong \# args: should be "huddle create ?key value \.\.\.?"\}\}
                set resultL \{\}
                foreach \{key value\} $args \{
                    lappend resultL $key \[huddle to\_node $value\]
                \}

                return \[huddle wrap D $resultL\]
            \}

            keys \{
                foreach \{src nop\} $args break
                return \[dict keys \[lindex \[lindex $src 1\] 1\]\]
            \}

            default \{
                error "$command is not callback for dict"
            \}
        \}
    \}




    \# inheritance sample from default dict\-callback
    proc ::yaml::\_huddle\_mapping \{command args\} \{
        switch \-\- $command \{
            setting \{ ; \# type definition
                return \{
                    type dict
                    method \{mapping\}
                    tag \{\!\!map parent\}
                    constructor mapping
                    str \!\!str
                \}
            \}


            mapping \{ ; \# $args: all arguments after "huddle mapping"
                if \{\[llength $args\] % 2\} \{error \{wrong \# args: should be "huddle mapping ?key value \.\.\.?"\}\}
                set resultL \{\}
                foreach \{key value\} $args \{
                    lappend resultL $key \[huddle to\_node $value \!\!str\]
                \}

                return \[huddle wrap \!\!map $resultL\]
            \}

            default \{ ; \# devolving to default dict\-callback
                return \[huddle call D $command $args\]
            \}
        \}
    \}




# <a name='section4'></a>How to add type

You can add huddle\-node types e\.g\. ::struct::tree\. To do so, first, define a
callback\-procedure for additional tagged\-type\. The proc get argments as
*command* and ?*args*?\. It has some switch\-sections\.

And, addType subcommand will called\.

    huddle addType my\_dict\_setting

# <a name='section5'></a>WORKING SAMPLE

    \# create as a dict
    % set bb \[huddle create a b c d\]
    HUDDLE \{D \{a \{s b\} c \{s d\}\}\}

    \# create as a list
    % set cc \[huddle list e f g h\]
    HUDDLE \{L \{\{s e\} \{s f\} \{s g\} \{s h\}\}\}
    % set bbcc \[huddle create bb $bb cc $cc\]
    HUDDLE \{D \{bb \{D \{a \{s b\} c \{s d\}\}\} cc \{L \{\{s e\} \{s f\} \{s g\} \{s h\}\}\}\}\}
    % set folding \[huddle list $bbcc p \[huddle list q r\] s\]
    HUDDLE \{L \{\{D \{bb \{D \{a \{s b\} c \{s d\}\}\} cc \{L \{\{s e\} \{s f\} \{s g\} \{s h\}\}\}\}\} \{s p\} \{L \{\{s q\} \{s r\}\}\} \{s s\}\}\}

    \# normal Tcl's notation
    % huddle strip $folding
    \{bb \{a b c d\} cc \{e f g h\}\} p \{q r\} s

    \# get a sub node
    % huddle get $folding 0 bb
    HUDDLE \{D \{a \{s b\} c \{s d\}\}\}
    % huddle gets $folding 0 bb
    a b c d

    \# overwrite a node
    % huddle set folding 0 bb c kkk
    HUDDLE \{L \{\{D \{bb \{D \{a \{s b\} c \{s kkk\}\}\} cc \{L \{\{s e\} \{s f\} \{s g\} \{s h\}\}\}\}\} \{s p\} \{L \{\{s q\} \{s r\}\}\} \{s s\}\}\}

    \# remove a node
    % huddle remove $folding 2 1
    HUDDLE \{L \{\{D \{bb \{D \{a \{s b\} c \{s kkk\}\}\} cc \{L \{\{s e\} \{s f\} \{s g\} \{s h\}\}\}\}\} \{s p\} \{L \{\{s q\}\}\} \{s s\}\}\}
    % huddle strip $folding
    \{bb \{a b c kkk\} cc \{e f g h\}\} p \{q r\} s

    \# dump as a JSON stream
    % huddle jsondump $folding
    \[
      \{


        "bb": \{
          "a": "b",
          "c": "kkk"
        \},
        "cc": \[
          "e",
          "f",
          "g",
          "h"
        \]

      \},
      "p",
      \[

        "q",
        "r"
      \],
      "s"
    \]


# <a name='section6'></a>LIMITATIONS

now printing\.

# <a name='section7'></a>Bugs, Ideas, Feedback








|
|
|
|
|

|
|


<
>
|
|
|
|
|
|
|
<
>
|
|
|
<
>
|
|
|
|
<
>

<
>
|
|


<
>
|
|
|
<
>
|
|
|
|
|
|
<
>

<
>
|
|
|

|
|
|
|

<
<
>
>
|
<
>
|
|
|
|
|
<
>
|
<
>
|
|
|
<
>
|

<
<
<
|
>
>
>
|
|
|
|
|

|
|

|
<
<
>
>
|
|
|
|
|
<
>
|
<
>
|
|
<
<
<
>
>
>









|



|
|
|

|
|
|
|
|
|
|

|

|

|

|



|

|

|

|

|

|

<
<
>
>
|


|
|




<
>
|

<
>


|

<
>







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
  - <a name='34'></a>__[remove](\.\./\.\./\.\./\.\./index\.md\#remove)__ *src* *key* *value*

    removes a sub\-node from the tagged\-content, and returns self\.

__strip__ must be defined at all types\. __get\_sub__ must be defined at
container types\. __set/remove__ shuould be defined, if you call them\.

    # callback sample for my-dict
    proc my_dict_setting {command args} {
        switch -- $command {
            setting { ; # type definition
                return {
                    type dict
                    method {create keys}
                    tag {d child D parent}
                    constructor create
                    str s

                }
                # type:   the type-name
                # method: add methods to huddle's subcommand.
                #          "get_sub/strip/set/remove/equal/append" called by huddle module.
                #          "strip" must be defined at all types.
                #          "get_sub" must be defined at container types.
                #          "set/remove/equal/append" shuould be defined, if you call them.
                # tag:    tag definition("child/parent" word is maybe obsoleted)

            }
            get_sub { ; # get a sub-node specified by "key" from the tagged-content
                foreach {src key} $args break
                return [dict get $src $key]

            }
            strip { ; # strip from the tagged-content
                foreach {src nop} $args break
                foreach {key val} $src {
                    lappend result $key [huddle strip $val]

                }
                return $result

            }
            set { ; # set a sub-node from the tagged-content
                foreach {src key value} $args break
                dict set src $key $value
                return $src

            }
            remove { ; # remove a sub-node from the tagged-content
                foreach {src key value} $args break
                return [dict remove $src $key]

            }
            equal { ; # check equal for each node
                foreach {src1 src2} $args break
                if {[llength $src1] != [llength $src2]} {return 0}
                foreach {key1 val1} $src1 {
                    if {![dict exists $src2 $key1]} {return 0}
                    if {![huddle _equal_subs $val1 [dict get $src2 $key1]]} {return 0}

                }
                return 1

            }
            append { ; # append nodes
                foreach {str src list} $args break
                if {[llength $list] % 2} {error {wrong # args: should be "huddle append objvar ?key value ...?"}}
                set resultL $src
                foreach {key value} $list {
                    if {$str ne ""} {
                        lappend resultL $key [huddle to_node $value $str]
                    } else {
                        lappend resultL $key $value


                    }
                }
                return [eval dict create $resultL]

            }
            create { ; # $args: all arguments after "huddle create"
                if {[llength $args] % 2} {error {wrong # args: should be "huddle create ?key value ...?"}}
                set resultL {}
                foreach {key value} $args {
                    lappend resultL $key [huddle to_node $value]

                }
                return [huddle wrap D $resultL]

            }
            keys {
                foreach {src nop} $args break
                return [dict keys [lindex [lindex $src 1] 1]]

            }
            default {
                error "$command is not callback for dict"



            }
        }
    }

    # inheritance sample from default dict-callback
    proc ::yaml::_huddle_mapping {command args} {
        switch -- $command {
            setting { ; # type definition
                return {
                    type dict
                    method {mapping}
                    tag {!!map parent}
                    constructor mapping
                    str !!str


                }
            }
            mapping { ; # $args: all arguments after "huddle mapping"
                if {[llength $args] % 2} {error {wrong # args: should be "huddle mapping ?key value ...?"}}
                set resultL {}
                foreach {key value} $args {
                    lappend resultL $key [huddle to_node $value !!str]

                }
                return [huddle wrap !!map $resultL]

            }
            default { ; # devolving to default dict-callback
                return [huddle call D $command $args]



            }
        }
    }

# <a name='section4'></a>How to add type

You can add huddle\-node types e\.g\. ::struct::tree\. To do so, first, define a
callback\-procedure for additional tagged\-type\. The proc get argments as
*command* and ?*args*?\. It has some switch\-sections\.

And, addType subcommand will called\.

    huddle addType my_dict_setting

# <a name='section5'></a>WORKING SAMPLE

    # create as a dict
    % set bb [huddle create a b c d]
    HUDDLE {D {a {s b} c {s d}}}

    # create as a list
    % set cc [huddle list e f g h]
    HUDDLE {L {{s e} {s f} {s g} {s h}}}
    % set bbcc [huddle create bb $bb cc $cc]
    HUDDLE {D {bb {D {a {s b} c {s d}}} cc {L {{s e} {s f} {s g} {s h}}}}}
    % set folding [huddle list $bbcc p [huddle list q r] s]
    HUDDLE {L {{D {bb {D {a {s b} c {s d}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q} {s r}}} {s s}}}

    # normal Tcl's notation
    % huddle strip $folding
    {bb {a b c d} cc {e f g h}} p {q r} s

    # get a sub node
    % huddle get $folding 0 bb
    HUDDLE {D {a {s b} c {s d}}}
    % huddle gets $folding 0 bb
    a b c d

    # overwrite a node
    % huddle set folding 0 bb c kkk
    HUDDLE {L {{D {bb {D {a {s b} c {s kkk}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q} {s r}}} {s s}}}

    # remove a node
    % huddle remove $folding 2 1
    HUDDLE {L {{D {bb {D {a {s b} c {s kkk}}} cc {L {{s e} {s f} {s g} {s h}}}}} {s p} {L {{s q}}} {s s}}}
    % huddle strip $folding
    {bb {a b c kkk} cc {e f g h}} p {q r} s

    # dump as a JSON stream
    % huddle jsondump $folding


    [
      {
        "bb": {
          "a": "b",
          "c": "kkk"
        },
        "cc": [
          "e",
          "f",
          "g",
          "h"

        ]
      },
      "p",

      [
        "q",
        "r"
      ],
      "s"

    ]

# <a name='section6'></a>LIMITATIONS

now printing\.

# <a name='section7'></a>Bugs, Ideas, Feedback

Changes to embedded/md/tcllib/files/modules/yaml/yaml.md.
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
        *txt* is just a YAML\-stream\.

      * ____\-types__ *list*__

        The *list* is a type list for the yaml\-scalar types\.\(e\.g\. \!\!str
        \!\!timestamp \!\!integer \!\!true \.\.\.\)

            \-types \{timestamp integer null true false\}

        In this case, if a string matched "timestamp", converted to the TCL
        internal timestamp\.\(e\.g\. "2001\-12\-15T02:59:43\.1Z" => 1008385183\)

      * ____\-m:true__ *param*__

        The *param* is two elements of list for the value of true, and
        considered strings\.

            \-m:true \{1 \{true on \+ yes y\}\}

        In this case, the string "yes" found in YAML Stream, automatically
        converted 1\.

      * ____\-m:false__ *param*__

        The *param* is two elements of list for the value of false, and
        considered strings\.

            \-m:false \{0 \{false off \- no n\}\}

      * ____\-m:null__ *param*__

        The *param* is two elements of list for the value of null, and
        considered strings\.

            \-m:null \{"" \{null nil "" ~\}\}

      * ____\-validate____

        Experiment,old: Output stream contains YAML's\-tag, each node\.

            % puts \[::yaml::load \-validate \{\[aaa, bbb\]\}\]
            =>
            \!\!seq \{\{\!\!str aaa\} \{\!\!str bbb\}\}

  - <a name='3'></a>__::yaml::setOption__ ?*options*?

    Change implicit options for the library\. Now, the params are the same as
    __::yaml::yaml2dict__\. Arguments of__::yaml::yaml2dict__ is more
    priority than this setting\.








|









|









|






|





|

|







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
        *txt* is just a YAML\-stream\.

      * ____\-types__ *list*__

        The *list* is a type list for the yaml\-scalar types\.\(e\.g\. \!\!str
        \!\!timestamp \!\!integer \!\!true \.\.\.\)

            -types {timestamp integer null true false}

        In this case, if a string matched "timestamp", converted to the TCL
        internal timestamp\.\(e\.g\. "2001\-12\-15T02:59:43\.1Z" => 1008385183\)

      * ____\-m:true__ *param*__

        The *param* is two elements of list for the value of true, and
        considered strings\.

            -m:true {1 {true on + yes y}}

        In this case, the string "yes" found in YAML Stream, automatically
        converted 1\.

      * ____\-m:false__ *param*__

        The *param* is two elements of list for the value of false, and
        considered strings\.

            -m:false {0 {false off - no n}}

      * ____\-m:null__ *param*__

        The *param* is two elements of list for the value of null, and
        considered strings\.

            -m:null {"" {null nil "" ~}}

      * ____\-validate____

        Experiment,old: Output stream contains YAML's\-tag, each node\.

            % puts [::yaml::load -validate {[aaa, bbb]}]
            =>
            !!seq {{!!str aaa} {!!str bbb}}

  - <a name='3'></a>__::yaml::setOption__ ?*options*?

    Change implicit options for the library\. Now, the params are the same as
    __::yaml::yaml2dict__\. Arguments of__::yaml::yaml2dict__ is more
    priority than this setting\.

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
        word wrap for YAML stream\. currently default is 40\.

# <a name='section3'></a>EXAMPLES

An example of a yaml stream converted to Tcl\. A yaml stream is returned as a
single item with multiple elements\.

    \{

    \-\-\- \!<tag:clarkevans\.com,2002:invoice>
    invoice: 34843
    date   : 2001\-01\-23
    bill\-to: &id001
        given  : Chris
        family : Dumars
        address:
            lines: &#124;
                458 Walkman Dr\.
                Suite \#292
            city    : Royal Oak
            state   : MI
            postal  : 48046
    ship\-to: \*id001
    product:
        \- sku         : BL394D
          quantity    : 4
          description : Basketball
          price       : 450\.00
        \- sku         : BL4438H
          quantity    : 1
          description : Super Hoop
          price       : 2392\.00
    tax  : 251\.42
    total: 4443\.52
    comments:
        Late afternoon is best\.
        Backup contact is Nancy
        Billsmer @ 338\-4338\.
    \}

    =>
    invoice 34843 date 2001\-01\-23 bill\-to \{given Chris family Dumars address \{lines \{458 Walkman Dr\.
    Suite \#292
    \} city \{Royal Oak\} state MI postal 48046\}\} ship\-to \{given Chris family Dumars address \{lines \{458 Walkman Dr\.
    Suite \#292
    \} city \{Royal Oak\} state MI postal 48046\}\} product \{\{sku BL394D quantity 4 description Basketball price 450\.00\} \{sku BL4438H quantity 1 description \{Super Hoop\} price 2392\.00\}\} tax 251\.42 total 4443\.52 comments \{Late afternoon is best\. Backup contact is Nancy Billsmer @ 338\-4338\.\}

An example of a yaml object converted to Tcl\. A yaml object is returned as a
multi\-element list \(a dict\)\.

    \{

    \-\-\-
    \- \[name        , hr, avg  \]
    \- \[Mark McGwire, 65, 0\.278\]
    \- \[Sammy Sosa  , 63, 0\.288\]
    \-

      Mark McGwire: \{hr: 65, avg: 0\.278\}
      Sammy Sosa: \{ hr: 63, avg: 0\.288\}
    \}

    =>
    \{name hr avg\} \{\{Mark McGwire\} 65 0\.278\} \{\{Sammy Sosa\} 63 0\.288\} \{\{Mark McGwire\} \{hr 65 avg 0\.278\} \{Sammy Sosa\} \{hr 63 avg 0\.288\}\}

# <a name='section4'></a>LIMITATIONS

tag parser not implemented\. currentry, tags are merely ignored\.

Only Anchor => Aliases ordering\. back alias\-referring is not supported\.








<
>
|

|
|



|
|
|



|

|


|
|


|
|
|

|

|
<
>

|
|
|
|
|




<
>
|
|
|
|
<
>
|
|
<
>

|







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
        word wrap for YAML stream\. currently default is 40\.

# <a name='section3'></a>EXAMPLES

An example of a yaml stream converted to Tcl\. A yaml stream is returned as a
single item with multiple elements\.


    {
    --- !<tag:clarkevans.com,2002:invoice>
    invoice: 34843
    date   : 2001-01-23
    bill-to: &id001
        given  : Chris
        family : Dumars
        address:
            lines: |
                458 Walkman Dr.
                Suite #292
            city    : Royal Oak
            state   : MI
            postal  : 48046
    ship-to: *id001
    product:
        - sku         : BL394D
          quantity    : 4
          description : Basketball
          price       : 450.00
        - sku         : BL4438H
          quantity    : 1
          description : Super Hoop
          price       : 2392.00
    tax  : 251.42
    total: 4443.52
    comments:
        Late afternoon is best.
        Backup contact is Nancy
        Billsmer @ 338-4338.

    }
    =>
    invoice 34843 date 2001-01-23 bill-to {given Chris family Dumars address {lines {458 Walkman Dr.
    Suite #292
    } city {Royal Oak} state MI postal 48046}} ship-to {given Chris family Dumars address {lines {458 Walkman Dr.
    Suite #292
    } city {Royal Oak} state MI postal 48046}} product {{sku BL394D quantity 4 description Basketball price 450.00} {sku BL4438H quantity 1 description {Super Hoop} price 2392.00}} tax 251.42 total 4443.52 comments {Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.}

An example of a yaml object converted to Tcl\. A yaml object is returned as a
multi\-element list \(a dict\)\.


    {
    ---
    - [name        , hr, avg  ]
    - [Mark McGwire, 65, 0.278]
    - [Sammy Sosa  , 63, 0.288]

    -
      Mark McGwire: {hr: 65, avg: 0.278}
      Sammy Sosa: { hr: 63, avg: 0.288}

    }
    =>
    {name hr avg} {{Mark McGwire} 65 0.278} {{Sammy Sosa} 63 0.288} {{Mark McGwire} {hr 65 avg 0.278} {Sammy Sosa} {hr 63 avg 0.288}}

# <a name='section4'></a>LIMITATIONS

tag parser not implemented\. currentry, tags are merely ignored\.

Only Anchor => Aliases ordering\. back alias\-referring is not supported\.

Changes to embedded/md/tcllib/files/modules/zip/mkzip.md.
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
    particularly on Windows the __info\-zip__ and the Windows built\-in zip
    view have rather poor support for this part of the ZIP file specification\.
    The __7\-Zip__ program does correctly display utf8 filenames however and
    the __vfs::zip__ package will use these of course\.

    If you use

        __::mkzip::mkzip__ mystuff\.tm \-zipkit \-directory mystuff\.vfs

    it will pack your "mystuff\.vfs/" virtual filesystem tree into a zip archive
    with a suitable header such that on unix you may mark it executable and it
    should run with tclkit\. Or you can run it with __tclsh__ or __wish__
    8\.6 if you like\.

    To change the executable header, specify the __\-runtime__ "preface"
    where preface is a file containing code you want prefixed\. For instance, on
    Windows you can create a self\-extracting zip archive using

        mkzip mystuff\.exe \-directory mystuff\.vfs \-runtime unzipsfx\.exe

    The "unzipsfx\.exe" is the Info\-Zip self\-extracting stub\.

    Accepted options:

      * __\-runtime__ path








|










|







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
    particularly on Windows the __info\-zip__ and the Windows built\-in zip
    view have rather poor support for this part of the ZIP file specification\.
    The __7\-Zip__ program does correctly display utf8 filenames however and
    the __vfs::zip__ package will use these of course\.

    If you use

        __::mkzip::mkzip__ mystuff.tm -zipkit -directory mystuff.vfs

    it will pack your "mystuff\.vfs/" virtual filesystem tree into a zip archive
    with a suitable header such that on unix you may mark it executable and it
    should run with tclkit\. Or you can run it with __tclsh__ or __wish__
    8\.6 if you like\.

    To change the executable header, specify the __\-runtime__ "preface"
    where preface is a file containing code you want prefixed\. For instance, on
    Windows you can create a self\-extracting zip archive using

        mkzip mystuff.exe -directory mystuff.vfs -runtime unzipsfx.exe

    The "unzipsfx\.exe" is the Info\-Zip self\-extracting stub\.

    Accepted options:

      * __\-runtime__ path

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

      * __\-exclude__ list

        This option specifies a list of glob patterns\. All paths matching at
        least one of the patterns are not placed into the generated archive\.
        This option defaults to

            CVS/\* \*/CVS/\* \*~ "\.\#\*" "\*/\.\#\*"

      * __\-\-__

        This option signals the end of the options, forcing processing of all
        further words as arguments, even if they begin with a dash character\.

    Accepted arguments:







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

      * __\-exclude__ list

        This option specifies a list of glob patterns\. All paths matching at
        least one of the patterns are not placed into the generated archive\.
        This option defaults to

            CVS/* */CVS/* *~ ".#*" "*/.#*"

      * __\-\-__

        This option signals the end of the options, forcing processing of all
        further words as arguments, even if they begin with a dash character\.

    Accepted arguments:
Changes to idoc/man/files/modules/doctools/doctools.n.
1
2
3
4
5
6
7
8
9
10
11
12
'\"
'\" Generated from file 'doctools\&.man' by tcllib/doctools with format 'nroff'
'\" Copyright (c) 2003-2019 Andreas Kupries <andreas_kupries@users\&.sourceforge\&.net>
'\"
.TH "doctools" n 1\&.5\&.1 tcllib "Documentation tools"
.\" The -*- nroff -*- definitions below are for supplemental macros used
.\" in Tcl/Tk manual entries.
.\"
.\" .AP type name in/out ?indent?
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,




|







1
2
3
4
5
6
7
8
9
10
11
12
'\"
'\" Generated from file 'doctools\&.man' by tcllib/doctools with format 'nroff'
'\" Copyright (c) 2003-2019 Andreas Kupries <andreas_kupries@users\&.sourceforge\&.net>
'\"
.TH "doctools" n 1\&.5\&.2 tcllib "Documentation tools"
.\" The -*- nroff -*- definitions below are for supplemental macros used
.\" in Tcl/Tk manual entries.
.\"
.\" .AP type name in/out ?indent?
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
..
.BS
.SH NAME
doctools \- doctools - Processing documents
.SH SYNOPSIS
package require \fBTcl  8\&.2\fR
.sp
package require \fBdoctools  ?1\&.5\&.1?\fR
.sp
\fB::doctools::new\fR \fIobjectName\fR ?\fIoption value\fR\&.\&.\&.?
.sp
\fB::doctools::help\fR
.sp
\fB::doctools::search\fR \fIpath\fR
.sp







|







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
..
.BS
.SH NAME
doctools \- doctools - Processing documents
.SH SYNOPSIS
package require \fBTcl  8\&.2\fR
.sp
package require \fBdoctools  ?1\&.5\&.2?\fR
.sp
\fB::doctools::new\fR \fIobjectName\fR ?\fIoption value\fR\&.\&.\&.?
.sp
\fB::doctools::help\fR
.sp
\fB::doctools::search\fR \fIpath\fR
.sp
Changes to idoc/www/tcllib/files/modules/doctools/doctools.html.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
&#124; <a href="../../../toc.html">Table Of Contents</a>
&#124; <a href="../../../../index.html">Keyword Index</a>
&#124; <a href="../../../../toc0.html">Categories</a>
&#124; <a href="../../../../toc1.html">Modules</a>
&#124; <a href="../../../../toc2.html">Applications</a>
 ] <hr>
<div class="doctools">
<h1 class="doctools_title">doctools(n) 1.5.1 tcllib &quot;Documentation tools&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>doctools - doctools - Processing documents</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
<ul class="doctools_toc">
<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>







|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
&#124; <a href="../../../toc.html">Table Of Contents</a>
&#124; <a href="../../../../index.html">Keyword Index</a>
&#124; <a href="../../../../toc0.html">Categories</a>
&#124; <a href="../../../../toc1.html">Modules</a>
&#124; <a href="../../../../toc2.html">Applications</a>
 ] <hr>
<div class="doctools">
<h1 class="doctools_title">doctools(n) 1.5.2 tcllib &quot;Documentation tools&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>doctools - doctools - Processing documents</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
<ul class="doctools_toc">
<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<li class="doctools_section"><a href="#copyright">Copyright</a></li>
</ul>
</div>
<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="doctools_synopsis">
<ul class="doctools_requirements">
<li>package require <b class="pkgname">Tcl 8.2</b></li>
<li>package require <b class="pkgname">doctools <span class="opt">?1.5.1?</span></b></li>
</ul>
<ul class="doctools_syntax">
<li><a href="#1"><b class="cmd">::doctools::new</b> <i class="arg">objectName</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#2"><b class="cmd">::doctools::help</b></a></li>
<li><a href="#3"><b class="cmd">::doctools::search</b> <i class="arg">path</i></a></li>
<li><a href="#4"><b class="cmd">objectName</b> <b class="method">method</b> <span class="opt">?<i class="arg">arg arg ...</i>?</span></a></li>
<li><a href="#5"><i class="arg">objectName</i> <b class="method">configure</b></a></li>







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<li class="doctools_section"><a href="#copyright">Copyright</a></li>
</ul>
</div>
<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="doctools_synopsis">
<ul class="doctools_requirements">
<li>package require <b class="pkgname">Tcl 8.2</b></li>
<li>package require <b class="pkgname">doctools <span class="opt">?1.5.2?</span></b></li>
</ul>
<ul class="doctools_syntax">
<li><a href="#1"><b class="cmd">::doctools::new</b> <i class="arg">objectName</i> <span class="opt">?<i class="arg">option value</i>...?</span></a></li>
<li><a href="#2"><b class="cmd">::doctools::help</b></a></li>
<li><a href="#3"><b class="cmd">::doctools::search</b> <i class="arg">path</i></a></li>
<li><a href="#4"><b class="cmd">objectName</b> <b class="method">method</b> <span class="opt">?<i class="arg">arg arg ...</i>?</span></a></li>
<li><a href="#5"><i class="arg">objectName</i> <b class="method">configure</b></a></li>
Changes to modules/doctools/doctools.man.
1
2
3
4
5
6
7
8
9
[comment {-*- tcl -*- doctools manpage}]
[vset PACKAGE_VERSION 1.5.1]
[manpage_begin doctools n [vset PACKAGE_VERSION]]
[see_also doctools_intro]
[see_also doctools_lang_cmdref]
[see_also doctools_lang_intro]
[see_also doctools_lang_syntax]
[see_also doctools_plugin_apiref]
[keywords conversion]

|







1
2
3
4
5
6
7
8
9
[comment {-*- tcl -*- doctools manpage}]
[vset PACKAGE_VERSION 1.5.2]
[manpage_begin doctools n [vset PACKAGE_VERSION]]
[see_also doctools_intro]
[see_also doctools_lang_cmdref]
[see_also doctools_lang_intro]
[see_also doctools_lang_syntax]
[see_also doctools_plugin_apiref]
[keywords conversion]
Changes to modules/doctools/doctools.tcl.
1354
1355
1356
1357
1358
1359
1360
1361
    # => FOO/mpformats

    #catch {search [file join $here                lib doctools mpformats]}
    #catch {search [file join [file dirname $here] lib doctools mpformats]}
    catch {search [file join $here                             mpformats]}
}

package provide doctools 1.5.1







|
1354
1355
1356
1357
1358
1359
1360
1361
    # => FOO/mpformats

    #catch {search [file join $here                lib doctools mpformats]}
    #catch {search [file join [file dirname $here] lib doctools mpformats]}
    catch {search [file join $here                             mpformats]}
}

package provide doctools 1.5.2
Changes to modules/doctools/mpformats/_markdown.tcl.
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Modified bulleting

DIB [list [Dash] [Star] [Plus]]
DEB [list "1[Dot]" "1[CPar]"]

proc Unmark {x} {
    lappend map "\1\n" "  \n"
    # Marked special characters are commands. Covnert into regular
    # form. Unmarked special characters need quoting.
    lappend map \1\\ \\
    lappend map \1`  `
    lappend map \1*  *
    lappend map \1_  _
    lappend map \1#  "#"
    lappend map \1+  +







|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Modified bulleting

DIB [list [Dash] [Star] [Plus]]
DEB [list "1[Dot]" "1[CPar]"]

proc Unmark {x} {
    lappend map "\1\n" "  \n"
    # Marked special characters are commands. Convert into regular
    # form. Unmarked special characters need quoting.
    lappend map \1\\ \\
    lappend map \1`  `
    lappend map \1*  *
    lappend map \1_  _
    lappend map \1#  "#"
    lappend map \1+  +
Changes to modules/doctools/mpformats/fmt.markdown.
1
2
3
4
5
6
7
8
9












10
11
12
13
14
15
16
# -*- tcl -*-
# Convert a doctools document into markdown formatted text
#
# Copyright (c) 2019 Andreas Kupries <[email protected]>

# Note: While markdown is a text format its intended target is HTML,
# making its formatting nearer to that with the ability to set anchors
# and refer to them, linkage in general.













# # ## ### ##### ######## #############
## Load shared code and modify it to our needs.

dt_source _common.tcl
dt_source _text.tcl
dt_source fmt.text
dt_source _markdown.tcl









>
>
>
>
>
>
>
>
>
>
>
>







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
# -*- tcl -*-
# Convert a doctools document into markdown formatted text
#
# Copyright (c) 2019 Andreas Kupries <[email protected]>

# Note: While markdown is a text format its intended target is HTML,
# making its formatting nearer to that with the ability to set anchors
# and refer to them, linkage in general.

# Notes, Attention
# - A number of characters are special to markdown. Such characters in
#   user input are \-quoted to make them non-special to the markdown
#   processor handling our generated document.
#
# - Exceptions are the special characters in verbatim code-blocks
#   (indent 4), and in `...` sequences (verbatim inline). In such
#   blocks they are not special and must not be quoted.
#
#   The generator currently only used verbatim blocks, for doctools
#   examples. It does not use verbatim inlines.

# # ## ### ##### ######## #############
## Load shared code and modify it to our needs.

dt_source _common.tcl
dt_source _text.tcl
dt_source fmt.text
dt_source _markdown.tcl
334
335
336
337
338
339
340
































341
342
343
344
345
346
347
    CloseParagraph
    if {[llength $sa]} { Special {SEE ALSO} seealso   [join [XrefList [lsort $sa] sa] ", "] }
    if {[llength $kw]} { Special KEYWORDS   keywords  [join [XrefList [lsort $kw] kw] ", "] }
    if {$ca ne ""}     { Special CATEGORY   category  $ca                     }
    if {$ct != {}}     { Special COPYRIGHT  copyright $ct [Verbatim]          }
    return
}

































proc c_get_copyright {} {
    return [join [c_get_copyright_r] [LB]]
}

##
# # ## ### ##### ########







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    CloseParagraph
    if {[llength $sa]} { Special {SEE ALSO} seealso   [join [XrefList [lsort $sa] sa] ", "] }
    if {[llength $kw]} { Special KEYWORDS   keywords  [join [XrefList [lsort $kw] kw] ", "] }
    if {$ca ne ""}     { Special CATEGORY   category  $ca                     }
    if {$ct != {}}     { Special COPYRIGHT  copyright $ct [Verbatim]          }
    return
}

c_pass 2 fmt_example_end {} {
    #puts_stderr "AAA/fmt_example_end"
    TextTrimLeadingSpace

    # In examples (verbatim markup) markdown's special characters are
    # no such by default, thus must not be quoted. Mark them as
    # protected from quoting.
    set t [Mark [Text?]]
    TextClear
    Text $t
    
    set penv [GetCurrent]
    if {$penv != {}} {
	# In a list we save the current list context, activate the
	# proper paragraph context and create its example
	# variant. After closing the paragraph using the example we
	# restore and reactivate the list context.
	ContextPush
	ContextSet $penv
	#if {[CloseParagraph [Example]]} PAdvance
	CloseParagraph [Example]
	ContextPop
    } else {
	# In a regular paragraph we simple close the example
	#if {[CloseParagraph [Example]]} PAdvance
	CloseParagraph [Example]
    }

    #puts_stderr "AAA/fmt_example_end/Done"
    return
}

proc c_get_copyright {} {
    return [join [c_get_copyright_r] [LB]]
}

##
# # ## ### ##### ########
Changes to modules/doctools/pkgIndex.tcl.
1
2
3
4
5
6
if {![package vsatisfies [package provide Tcl] 8.2]} {return}
package ifneeded doctools            1.5.1 [list source [file join $dir doctools.tcl]]
package ifneeded doctools::toc       1.2   [list source [file join $dir doctoc.tcl]]
package ifneeded doctools::idx       1.1   [list source [file join $dir docidx.tcl]]
package ifneeded doctools::cvs       1     [list source [file join $dir cvs.tcl]]
package ifneeded doctools::changelog 1.1   [list source [file join $dir changelog.tcl]]

|




1
2
3
4
5
6
if {![package vsatisfies [package provide Tcl] 8.2]} {return}
package ifneeded doctools            1.5.2 [list source [file join $dir doctools.tcl]]
package ifneeded doctools::toc       1.2   [list source [file join $dir doctoc.tcl]]
package ifneeded doctools::idx       1.1   [list source [file join $dir docidx.tcl]]
package ifneeded doctools::cvs       1     [list source [file join $dir cvs.tcl]]
package ifneeded doctools::changelog 1.1   [list source [file join $dir changelog.tcl]]
Added modules/doctools/tests/fmt/desc/25.
Added modules/doctools/tests/fmt/html/25.
















































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<!DOCTYPE html><html><head>
<title>TEST - </title>
<style type="text/css"><!--
    HTML {
	background: 	#FFFFFF;
	color: 		black;
    }
    BODY {
	background: 	#FFFFFF;
	color:	 	black;
    }
    DIV.doctools {
	margin-left:	10%;
	margin-right:	10%;
    }
    DIV.doctools H1,DIV.doctools H2 {
	margin-left:	-5%;
    }
    H1, H2, H3, H4 {
	margin-top: 	1em;
	font-family:	sans-serif;
	font-size:	large;
	color:		#005A9C;
	background: 	transparent;
	text-align:		left;
    }
    H1.doctools_title {
	text-align: center;
    }
    UL,OL {
	margin-right: 0em;
	margin-top: 3pt;
	margin-bottom: 3pt;
    }
    UL LI {
	list-style: disc;
    }
    OL LI {
	list-style: decimal;
    }
    DT {
	padding-top: 	1ex;
    }
    UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
	font:		normal 12pt/14pt sans-serif;
	list-style:	none;
    }
    LI.doctools_section, LI.doctools_subsection {
	list-style: 	none;
	margin-left: 	0em;
	text-indent:	0em;
	padding: 	0em;
    }
    PRE {
	display: 	block;
	font-family:	monospace;
	white-space:	pre;
	margin:		0%;
	padding-top:	0.5ex;
	padding-bottom:	0.5ex;
	padding-left:	1ex;
	padding-right:	1ex;
	width:		100%;
    }
    PRE.doctools_example {
	color: 		black;
	background: 	#f5dcb3;
	border:		1px solid black;
    }
    UL.doctools_requirements LI, UL.doctools_syntax LI {
	list-style: 	none;
	margin-left: 	0em;
	text-indent:	0em;
	padding:	0em;
    }
    DIV.doctools_synopsis {
	color: 		black;
	background: 	#80ffff;
	border:		1px solid black;
	font-family:	serif;
	margin-top: 	1em;
	margin-bottom: 	1em;
    }
    UL.doctools_syntax {
	margin-top: 	1em;
	border-top:	1px solid black;
    }
    UL.doctools_requirements {
	margin-bottom: 	1em;
	border-bottom:	1px solid black;
    }
--></style>
</head>
<!-- Generated from file '.FILE.' by tcllib/doctools with format 'html'
   -->
<!-- Copyright &amp;copy; .COPYRIGHT.
   -->
<!-- TEST.z
   -->
<body><div class="doctools">
<h1 class="doctools_title">TEST(z) 3.14.15.926 .MODULE. &quot;&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>TEST -</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
<ul class="doctools_toc">
<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
<li class="doctools_section"><a href="#section1">Description</a></li>
<li class="doctools_section"><a href="#copyright">Copyright</a></li>
</ul>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<pre class="doctools_example">
Special markdown __non-special__
</pre>
</div>
<div id="copyright" class="doctools_section"><h2><a name="copyright">Copyright</a></h2>
<p>Copyright &copy; .COPYRIGHT.</p>
</div>
</div></body></html>
Added modules/doctools/tests/fmt/latex/25.


































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
% Generated from file '.FILE.' by tcllib/doctools with format 'latex'
% Copyright (c) .COPYRIGHT.
% TEST.z
\documentclass{article}
\begin{document}
\author{aku}
\title{.MODULE. / TEST --  : }
\maketitle
\section{Description}\label{section1}
\begin{verbatim}
Special markdown __non-special__
\end{verbatim}
\section{Copyright}\label{copyright}
\begin{flushleft}
Copyright (c) .COPYRIGHT.\linebreak
\end{flushleft}
\end{document}
Added modules/doctools/tests/fmt/list/25.


>
1
manpage {seealso {} keywords {} file .FILE. section z category {} module .MODULE. version 3.14.15.926 title TEST shortdesc {} desc {} fid .FILE}
Added modules/doctools/tests/fmt/man/25.














>
>
>
>
>
>
>
1
2
3
4
5
6
7
[comment { -- Example 1 }]
[manpage_begin TEST z 3.14.15.926]
[description]
[example {
Special markdown __non-special__
}]
[manpage_end]
Changes to modules/doctools/tests/fmt/markdown/04.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# <a name='description'></a>DESCRIPTION

BEGINNE HIER

    Example Block  More Lines

    Inlined Example \\
    Next Line

FERTIG

# <a name='copyright'></a>COPYRIGHT

Copyright &copy; \.COPYRIGHT\.







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# <a name='description'></a>DESCRIPTION

BEGINNE HIER

    Example Block  More Lines

    Inlined Example \
    Next Line

FERTIG

# <a name='copyright'></a>COPYRIGHT

Copyright &copy; \.COPYRIGHT\.
Added modules/doctools/tests/fmt/markdown/25.


















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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

[//000000001]: # (TEST \- )
[//000000002]: # (Generated from file '\.FILE\.' by tcllib/doctools with format 'markdown')
[//000000003]: # (Copyright &copy; \.COPYRIGHT\.)
[//000000004]: # (TEST\(z\) 3\.14\.15\.926 \.MODULE\. "")

# NAME

TEST \-

# <a name='toc'></a>Table Of Contents

  - [Table Of Contents](#toc)

  - [Description](#section1)

  - [Copyright](#copyright)

# <a name='description'></a>DESCRIPTION

    Special markdown __non-special__

# <a name='copyright'></a>COPYRIGHT

Copyright &copy; \.COPYRIGHT\.
Added modules/doctools/tests/fmt/nroff/25.






























































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
'\"
'\" Generated from file '\&.FILE\&.' by tcllib/doctools with format 'nroff'
'\" Copyright (c) \&.COPYRIGHT\&.
'\"
.TH "TEST" z 3\&.14\&.15\&.926 \&.MODULE\&. ""
.\" The -*- nroff -*- definitions below are for supplemental macros used
.\" in Tcl/Tk manual entries.
.\"
.\" .AP type name in/out ?indent?
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
.\"	needed;  use .AS below instead)
.\"
.\" .AS ?type? ?name?
.\"	Give maximum sizes of arguments for setting tab stops.  Type and
.\"	name are examples of largest possible arguments that will be passed
.\"	to .AP later.  If args are omitted, default tab stops are used.
.\"
.\" .BS
.\"	Start box enclosure.  From here until next .BE, everything will be
.\"	enclosed in one large box.
.\"
.\" .BE
.\"	End of box enclosure.
.\"
.\" .CS
.\"	Begin code excerpt.
.\"
.\" .CE
.\"	End code excerpt.
.\"
.\" .VS ?version? ?br?
.\"	Begin vertical sidebar, for use in marking newly-changed parts
.\"	of man pages.  The first argument is ignored and used for recording
.\"	the version when the .VS was added, so that the sidebars can be
.\"	found and removed when they reach a certain age.  If another argument
.\"	is present, then a line break is forced before starting the sidebar.
.\"
.\" .VE
.\"	End of vertical sidebar.
.\"
.\" .DS
.\"	Begin an indented unfilled display.
.\"
.\" .DE
.\"	End of indented unfilled display.
.\"
.\" .SO ?manpage?
.\"	Start of list of standard options for a Tk widget. The manpage
.\"	argument defines where to look up the standard options; if
.\"	omitted, defaults to "options". The options follow on successive
.\"	lines, in three columns separated by tabs.
.\"
.\" .SE
.\"	End of list of standard options for a Tk widget.
.\"
.\" .OP cmdName dbName dbClass
.\"	Start of description of a specific option.  cmdName gives the
.\"	option's name as specified in the class command, dbName gives
.\"	the option's name in the option database, and dbClass gives
.\"	the option's class in the option database.
.\"
.\" .UL arg1 arg2
.\"	Print arg1 underlined, then print arg2 normally.
.\"
.\" .QW arg1 ?arg2?
.\"	Print arg1 in quotes, then arg2 normally (for trailing punctuation).
.\"
.\" .PQ arg1 ?arg2?
.\"	Print an open parenthesis, arg1 in quotes, then arg2 normally
.\"	(for trailing punctuation) and then a closing parenthesis.
.\"
.\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1 \\fI\\$2\\fP (\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
.\"	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
.\"	# BS - start boxed text
.\"	# ^y = starting y location
.\"	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.\"	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.\"	# VS - start vertical sidebar
.\"	# ^Y = starting y location
.\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
.\"	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
.\"	# Special macro to handle page bottom:  finish off current
.\"	# box/sidebar if in box/sidebar mode, then invoked standard
.\"	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
.\"	# DS - begin display
.de DS
.RS
.nf
.sp
..
.\"	# DE - end display
.de DE
.fi
.RE
.sp
..
.\"	# SO - start of list of standard options
.de SO
'ie '\\$1'' .ds So \\fBoptions\\fR
'el .ds So \\fB\\$1\\fR
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
.\"	# SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\*(So manual entry for details on the standard options.
..
.\"	# OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
.\"	# CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
.\"	# CE - end code excerpt
.de CE
.fi
.RE
..
.\"	# UL - underline word
.de UL
\\$1\l'|0\(ul'\\$2
..
.\"	# QW - apply quotation marks to word
.de QW
.ie '\\*(lq'"' ``\\$1''\\$2
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\$2
..
.\"	# PQ - apply parens and quotation marks to word
.de PQ
.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
.\"" fix emacs highlighting
.el (\\*(lq\\$1\\*(rq\\$2)\\$3
..
.\"	# QR - quoted range
.de QR
.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
..
.\"	# MT - "empty" string
.de MT
.QW ""
..
.BS
.SH NAME
TEST \-
.SH DESCRIPTION
.CS


Special markdown __non-special__

.CE
.SH COPYRIGHT
.nf
Copyright (c) \&.COPYRIGHT\&.

.fi
Added modules/doctools/tests/fmt/null/25.
Added modules/doctools/tests/fmt/text/25.






































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

TEST - 
Generated from file '.FILE.' by tcllib/doctools with format 'text'
TEST(z) 3.14.15.926 .MODULE. ""

NAME
====

TEST -

DESCRIPTION
===========

| Special markdown __non-special__

COPYRIGHT
=========

Copyright (c) .COPYRIGHT.
Added modules/doctools/tests/fmt/tmml/25.
















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- Generated from file '.FILE.' by tcllib/doctools with format 'tmml' -->
<manpage id='.FILE' cat='cmd' title='TEST' version='3.14.15.926' package='.MODULE.'>
<head>
<info key='copyright' value='Copyright (c) .COPYRIGHT.'/>
</head>
<namesection>
<name>TEST</name>
<desc></desc>

</namesection>


<section id='section1'>
<title>DESCRIPTION</title>

<example>
Special markdown __non-special__

</example>
</section>



</manpage>
Added modules/doctools/tests/fmt/wiki/25.




































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'''TEST 3.14.15.926''' '''.MODULE.'''




**DESCRIPTION**


======

Special markdown __non-special__

======


**COPYRIGHT**

 Copyright (c) .COPYRIGHT.