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: |
43904ac14b981263ed849b9aa5f96c80 |
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
Changes to embedded/md/tcllib/files/apps/dtplite.md.
︙ | ︙ | |||
320 321 322 323 324 325 326 | - \[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/ | | | | | | | | | | | | | | | 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 | 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 | | | 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 | * *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: | | | | | | | | 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 | 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:  Our grammar, assumed to the stored in the file "calculator\.peg" is | | | | | | | | | | | | | | | | | | | | | | < < > > | | | | < < < < | > > > > | | 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:  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  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 | 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 | | | | 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 | 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 | | | | 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 | 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 | | | 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 | 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 | | | 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 | 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 | | | | | | | | | | | | | | | 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 | \(*Windows*\)\. ## <a name='subsection3'></a>Installing on Unix For *Unix*\-like environments Tcllib comes with the standard set of files to make | | | | | | | | | | | | 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 | # <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 | | | | | | | | 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 | 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: | | | | 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 | 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 | | | | | | | 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 | * __\-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\. | | | 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 | 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: | | | | | | | | | | 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 | 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 | | | | 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 | * %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, | | | 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 | 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" | | | | | | | | | | | | | 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 | ignores whitespace in the string\. # <a name='section2'></a>EXAMPLES % base64::encode "Hello, world" SGVsbG8sIHdvcmxk | | | | | | | | | 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 | 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 | | | | | | | < > | | 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 | - \-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*\. | | | | | 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 | 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 | | < > | | | | < > | 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 | 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\. | | | | | < > | 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 | 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 | | | | | | 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 | 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 | | | | | | | | | | | | | | | | < > | | | | | | < | | > | | | | | | < > | 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 | 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__ : | | | 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 | 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\. | | | | | | 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 | - <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: | | | | 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 | 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: | | | < < > > | 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 | 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: | | | < < > > | 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 | __break__ and __return \-code break__ *result* is supported, acting similarly to __return \{\}__ and __return \-code return__ *result*\. Examples: 1. augmenting a command | | | | | | | | | | | | | | | | | | | < < > > | | | | | 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 | 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: | | | < < > > | < > | | | | < > | < > | | | | | | 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 | 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: | | | | | | | | | | | | | | | < > | 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 | 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 | | | 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 | 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 | | | | 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 | __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: | | | | | | | | | | 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 | 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: | | | | 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 | 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 | | | | 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 | \-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 | | | | 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 | 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 | | | | | | | 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 | 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 | | | | | | 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 | 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 | | | | | | | 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 | - \-format *string* Return the checksum using an alternative format template\. # <a name='section4'></a>EXAMPLES | | | | | 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 | *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\. | | | | | | | 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 | 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: | | | | 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 | 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\. | | | 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 | 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 | | | | | | | | | | | 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 | 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 | | | | | 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 | 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 | | | | | | | | | 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 | - <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\. | | | | | | | | | | | < > | | < < > > | 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 | 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 | | | | | | | | | | 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 | 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" | | | | | | | | | | | | | | | | | | | 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*|*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*|*integerMask*|*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 | 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\. | | | | | | | | | | | | | | | | | | | | | 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 | 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\)\. | | | | | | | | | | | | | | | | | | 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 | line is one of '%' '<' STARSLASH EXPRESSION '>' '%' '<' PLUSMINUS EXPRESSION '>' CODE where | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 '>', '&', '|', 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 | 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 | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | < > | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | | | 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 | *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 | | | 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 | __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 | | | | | | | | | | | | | | | | | | | | | | | < > | | | 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 | 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 | | | | | | | | | 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 | 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\. | < < > > < < > > | < > | < < > > | < > | 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 | 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\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | 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 | 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\. | | | | | | | 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 | 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: | | | | | | | | | 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 | - __division\_end__ This command closes the last opened and not yet closed division\. Using this we can recast the last example like this | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | 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 | [//000000001]: # (doctools \- Documentation tools) [//000000002]: # (Generated from file 'doctools\.man' by tcllib/doctools with format 'markdown') [//000000003]: # (Copyright © 2003\-2019 Andreas Kupries <andreas\_kupries@users\.sourceforge\.net>) | | | 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 © 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> | <a href="../../../toc.md">Table Of Contents</a> | <a href="../../../../index.md">Keyword Index</a> | <a href="../../../../toc0.md">Categories</a> | <a href="../../../../toc1.md">Modules</a> | <a href="../../../../toc2.md">Applications</a> ] <hr> |
︙ | ︙ | |||
46 47 48 49 50 51 52 | - [Category](#category) - [Copyright](#copyright) # <a name='synopsis'></a>SYNOPSIS package require Tcl 8\.2 | | | 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 | 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\. | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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__\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | | | | | | | | | | | 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 | 1. The construct LIST\_BEGIN<X> stands for the markup command __list\_begin__ with __X__ as its type argument\. The syntax: manpage = defs | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | 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 | # <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 | | | | | | | < > | | | | | | | | < > | < | > < > | | | | | | | | | | | | | | | < < > > | 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 | # <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 | | | | | | | < > | | | | | | | | < > | < | > < > | | | | | | | | | | | | | | | < < > > | 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 | 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 ~~~~~~~~~~~ | | | | | | | | | | | | | | | | < > | | | | < > | | | | | 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 | # <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 | | | | | | | | | | | | | | | | | < | > < | > | < > < > | | | | | > | < | | | | | > | < | | > | < > | < < < > > | 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 | # <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 | | | | | | | | | | | | | | | | | < | > < | > | < > < > | | | | | > | < | | | | | > | < | | > | < > | < < < > > | 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 | 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 ~~~~~~~~~~~ | | | | | | | | | | | | | | | | < > | | | | < > | | | | | 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 | - \[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/ | | | | | | | | | | | | | | | 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 | 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: | | | | 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 | 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: | | | | | 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__|__\-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 | 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 | | | | | | | | | < > < | > | | < > | 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 | 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\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | < > < | > | | < > | 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 | 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 | | | 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 | 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: | | | < > | < > | | < > | | < > | 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 | 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: | | | | | < < > > | | | < > | | | < > | | | | | < > | | | | | | | | | | | | | | | | | | 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 | - <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: | | | | | | 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 | - <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 "|" as a delimiter: | | | | 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 "|" 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 | 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 | | | | | | | < > | 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 | # <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\. | | | | | | | | | | | | 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 | 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 | | | | 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 | 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 :\) | | | | | | | | | | 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 | 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 | | | | 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 | 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 | | | | | | | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | | | | < > | 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 | 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\. | | | | 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 | 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 | | | | 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 | 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 | | | | | | 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 | # <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\. | | | | < < > > | | | 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?|all? ?server\_string ?string?? ?server\_name ?string?? |
︙ | ︙ | |||
372 373 374 375 376 377 378 | 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: | | | | | | | | | | < < > > | | | | | | < < > > | | | | | < < > > | | | | | | < > | | | | | < > < > | < < > > | 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 | %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\. | | | | | | | | | | | < > | | 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 | 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\. | | | | | 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 | *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\. | | | 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 | 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__\)\. | | | 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 | 'recent' flagged msgs\), *FLAGS* In conjunction with OK: *PERMFLAGS*, *UIDNEXT*, *UIDVAL*, *UNSEEN* Div\. states: *CURRENT*, *FOUND*, *PERM*\. ::imap4::select $chan INBOX | | | 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 | *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 | | | 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 | * \-FLAGS Remove the flags in *flaglist* to the existing flags for the message\. For example: | | | 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 | *chan* \- imap channel # <a name='section3'></a>EXAMPLES set user myusername set pass xtremescrt | | | | | | | < > | | | | | | < < | > > | | | | | | | 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 | 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 | | | | 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 | 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: | | < > | 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 | 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\. | | | | | | | < > | 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 | - <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\. | | < | > | | | 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 | 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\. | < < > > | | | < > | | < < > > | < > | | | | | < < > > | | 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 | # <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 | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | < > | 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 | 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 | | | | 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 | 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\. | | | 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 | *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 | | | | | 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 | 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: | | | 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 | - <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: | | | 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 | # <a name='section4'></a>EXAMPLES A small example, extracted from the test application coming with this code\. package require ldap | | | | | | | | < | > | | | | | | | < | > | | | | | | | | | | | | | | | | | | | | < > | < | > | | | | | < < > > < > | 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 | 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 | < > | | < > | | | < > | | | < | > | | < > | | < > | < > | | < > | < > | < > | 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 | 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 | < > | < | > | | | < | | > | < | > | | | | | < > < > | | < | > | | | | | < > < > | 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 | This method writes the entry given in the argument *entry* to the LDIF file\. ## <a name='subsection14'></a>Ldif Example package require ldapx | | | | | | | < > | | | | | | < | > | < < > > | 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 | 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 | | | 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 | 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 | | | 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 | 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: | | | 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 | 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 | | | | | | | 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 | 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\. | | < > | | < | > | | 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 | - <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: | | | < | > | | | | < | > | | < | > | | | | | | | | 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 | # <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\. | | | | | | | | | < < > > | < < | > > | | | 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 | * __\-appenderArgs__ appenderArgs Additional arguments to apply to the appender\. The argument of the option is a list of options and their arguments\. For example | | | | | | | | | | 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 | # <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 | | | 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 | 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\. | | | | | | | | | | | | | | | | | | | | | | | | | 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 | * 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: | | | | | | | | | | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | < > | | | | | | | | | | | | | | | | | | | | < > | < > | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | < > < | > | | 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 | - <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 | | | | | | | 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 | 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 | | | 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 | 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: | | | < < > > | < > | | | < < < > > > | < > | | | < < > > | | | | | | | | | < | > | | | | | | | < > | | | | | | | | | 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 | - <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 | | | | 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 | 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\)* | | | | 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 | - 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: | | | 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 | - 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: | | | 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 | 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 | | | | | | | | | | < > | | | | | | | | 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 | 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 | | | | | | < | > | | | | | | | | 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 | 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: | | | | | | | | | | 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 | - <a name='10'></a>__::math::fuzzy::troundn__ *value* *ndigits* Rounds the floating\-point number off to the specified number of decimals \(Pro memorie\)\. Usage: | | | | | | | | | | | | 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 | - <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: | | | | < > | 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 | # <a name='section4'></a>EXAMPLES *Example of using one\-dimensional tables:* Suppose you have several tabulated functions of one variable: x y1 y2 | | | | | | | | | | | | | | < > | | | | | | | | < | > | | | | | | | | | | | 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 | - <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 | | | 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 | 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: | | | 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 | 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 | | | | < > | | < > | 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 | # <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 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | 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 | 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: | | | < < > > | < > | | < < > > | < > | | < > | | | | | | | | | | | 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 | 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 | | | | 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 | 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: | | | | | | 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 | 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 | | | | | | 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 | 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\. | | | | | < > | | | | < > | | < > | | | | 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 | # <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\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | # <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: | | | | 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 | 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: | | < > | < > | | 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 | 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: | | | 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 | *Description of the procedures* - <a name='48'></a>__::math::statistics::tstat__ *dof* ?alpha? Returns the value of the t\-distribution t\* satisfying | | | | | | | 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 | provided\. This procedure simply calls ::mvlinreg::wls with the weights set to 1\.0, and returns the same information\. *Example of the use:* | | | | | | | | | | | | | | | | | | | | | | | | < > | 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 | \- Total number of "observations" in the histogram - <a name='93'></a>__::math::statistics::incompleteGamma__ *x* *p* ?tol? Evaluate the incomplete Gamma integral | | | | | 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 | - subdivide # <a name='section8'></a>EXAMPLES The code below is a small example of how you can examine a set of data: | | | | < > < > | < > | | < | > | | | | | | | < < < | > > | > | < > | | | | | | | | | | < > | < | | > | < > | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | __sinh__\. __sqrt__, __tan__, and __tanh__\. Command substitution, backslash substitution, and argument expansion are not accepted\. # <a name='section4'></a>Examples | | | | | | | 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 | - <a name='8'></a>__::md4::HMACFinal__ *token* These commands are identical to the MD4 equivalent commands\. # <a name='section4'></a>EXAMPLES | | | | | | 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 | - <a name='8'></a>__::md5::HMACFinal__ *token* These commands are identical to the MD5 equivalent commands\. # <a name='section4'></a>EXAMPLES | | | | | | 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 | % md5crypt::md5crypt password 01234567 $1$01234567$b5lh2mHyD2PdJjFfALlEz1 % md5crypt::aprcrypt password 01234567 $apr1$01234567$IXBaQywhAhc0d75ZbaSDp/ | | | | 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 | 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: | | | | | 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 | __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 | | | | | | < | > | | | 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 | 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 | | | | 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 | 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: | | | | 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 | # <a name='section2'></a>EXAMPLES Uploading a file HTML: <html> | | | | | | | | | | 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 | - <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 __$__\. | | | | 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 | 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\. | | | | | < | | > < > | 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 | *msgid2*\) are queried\. # <a name='section3'></a>EXAMPLE A bigger example for posting a single article\. package require nntp | | | | | | | | | | 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 | 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\. | | | | | | | | | | < > < > | | 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 | 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 | | | | 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 | * 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 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | # <a name='description'></a>DESCRIPTION The __oo::meta__ package provides a data registry service for TclOO classes\. # <a name='section2'></a>Usage | | < > | < > | < | > | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | 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 | - <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\. | | < > | 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 | 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 | | | < > | < > | | | | | | | | < < > > | | | | | | | | < > | | | 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 | - <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 | | | | | | 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 | 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, | | | 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 | \(underscore for environment variables, backslash for registry entries, and / for directories\)\. Examples: ::pluginmgr::paths ::obj docidx | | | | | | | | | | | | | | 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 | 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 | | | | 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|1? ?__\-retr\-mode__ retr|list|slow? ?__\-socketcmd__ cmdprefix? ?__\-stls__ 0|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 | __\-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 | | | | | | | | | | 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 | 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 | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | < < > > | | | | < < < < > > > > | 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  # <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 | the plugin in a state where another usage cycle can be run without problems\. # <a name='section4'></a>Usage To use a converter do | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | < > | < < | > > | | | | | | | | | | < > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | __[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 ======================= ======================= ==================== | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | < < > > | | | | < < < < > > > > | 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  # <a name='section6'></a>PE serialization format |
︙ | ︙ | |||
393 394 395 396 397 398 399 | 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 | | | | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | It has no direct formal specification beyond what was said above\. ## <a name='subsection1'></a>Example Assuming the following PEG for simple mathematical expressions | | | | | | | | | | | | | | | < > | | | | | | | | | < > < | > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | < > | < < | > > | | | | | | | | | | < > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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)*\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | < > | < < | > > | | | | | | | | | | < > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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)*\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | < > | < < | > > | | | | | | | | | | < > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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)*\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | < < > > | | | | < < < < > > > > | 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  # <a name='section3'></a>PE serialization format |
︙ | ︙ | |||
390 391 392 393 394 395 396 | 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 | | | | 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 | # <a name='section3'></a>The elements of the language ## <a name='subsection1'></a>Basic structure The general outline of a textual PEG is | | | 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 | 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: | | | | | | 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 | 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\): | | | | | | | | | | | | | | | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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*\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | - <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\. | | | | | | | | | | | | | 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 | It has no direct formal specification beyond what was said above\. ## <a name='subsection1'></a>Example Assuming the following PEG for simple mathematical expressions | | | | | | | | | | | | | | | < > | | | | | | | | | < > < | > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | < > | < < | > > | | | | | | | | | | < > | < > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | It has no direct formal specification beyond what was said above\. ## <a name='subsection1'></a>Example Assuming the following PEG for simple mathematical expressions | | | | | | | | | | | | | < > | < | > | < > | < | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | < | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | < | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | < < < | | | | | | | | | | | | > > > > > < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | < | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | < | > | | | | | | | | | | | | | | | < > | < > | | | | | | | | | | | | | | | < < > > | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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)*\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | 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 | | | | 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 | 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 | | | | 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 | 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:  Our grammar, assumed to the stored in the file "calculator\.peg" is | | | | | | | | | | | | | | | | | | | | | | | | | | < < > > | | | | < < < < | > > > > | | 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:  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  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 | runtime internals are accessible to all instructions folded into the sequence\. - <a name='66'></a>*objectName* __si:void\_state\_push__ This method combines | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | - <a name='106'></a>*objectName* __si:next\_wordchar__ - <a name='107'></a>*objectName* __si:next\_xdigit__ These methods all combine | | | | 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 | 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 | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | < > | < > | 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 | 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 | | | | 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 | - <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 | | | | | | | | < > | | 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 | Hello World, how are you ? Fine, and you ? for example can be represented by | | | | | | 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 | at the functional level\. And example of a RCS patch is d1 2 d4 1 a4 2 | | | | | 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 | 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)\. | | | | | 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 | # <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\. | | | | | < > | | | < > | | | | | | | | | | | | | 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 | Two quick examples: Example 1, Yahoo Boss: set appid APPID set search tcl | | | | | | | | | | | | < > | | | 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 | See __callback__ above for more information\. # <a name='section4'></a>Examples Yahoo Geo: | | | | < > | | | | < > | | | < | > | | | | | | < | > | | | < > | 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 | 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 | | | | 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 | - <a name='8'></a>__::ripemd::RIPEHMAC128Final__ *token* These commands are identical to the RIPEMD128 equivalent commands\. # <a name='section4'></a>EXAMPLES | | | | | | | 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 | - <a name='8'></a>__::ripemd::RIPEHMAC160Final__ *token* These commands are identical to the RIPEMD160 equivalent commands\. # <a name='section4'></a>EXAMPLES | | | | | | | 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 | 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 | | | | 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 | 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\. | | | | | | | | | < < | > > | | | | | | < > < > | 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 | % sha1::sha1 "Tcl does SHA1" 285a6a91c45a9066bf39fcf24425796ef0b2a8bf % sha1::hmac Sekret "Tcl does SHA1" ae6251fa51b95b18cba2be95eb031d07475ff03c | | | | 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 | % sha2::sha256 "Tcl does SHA256" 0b91043ee484abd83c3e4b08d6034d71b937026379f0f59bda6e625e6e214789 % sha2::hmac Sekret "Tcl does SHA256" 4f9352c64d655e8a36abe73e6163a9d7a54039877c1c92ec90b07d48d4e854e0 | | | | 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 | 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*: | | | | 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 | - 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: | | | | | | > | < | | | < < > > | | < < > > < > | | < > | 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 | 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: | < > | | < > | | | | | | < > | | | | | | | | | < > | | | 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 | - 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: | | | 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 | - <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: | | | 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 | 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 | | | | | 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 | - __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: | | | | < < > > | | | | | < > < > | | | | | < > | | | < > | 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 | 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: | | | | | | 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 | 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: | | | | | | < > | 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 | __::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: | | | | | | | 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 | 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: | | | | 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 | 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__: | | | | < > | | | < > | | | | < < > > | < > | | 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 | 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: | | < > | 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 | 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: | | | < | > | | < > | 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 | 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 | | | | | < > | 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 | 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: | | | | | 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 | * <a name='27'></a>__onconfigure__ *name* *arglist* *body* __Deprecated\.__ Define __option__'s __\-configuremethod__ option instead\. As of version 0\.95, the following definitions, | | | | < > | | | < > | | | < > | | | < > | 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 | 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: | | | | | | 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 | 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: | | | | | | | | 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 | 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: | | | | 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 | 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: | | | | < | > | < < | > > | | | | < > | | | < | > | < < > > | | | < < > > | | | | < | > | < > | 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 | 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 | | | 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 | 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: | | | | | | | | | | < > | | | | | | | | < > | | | | | | | < > | | | | < | > | | | | | | | | | | < | > | | | | | | 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 | 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: | | | | | | > > | < < < > | | | | | < < > > | | | | < < > > | 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 | ## <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: | | | < | > | < < > > | | | < > | < > | | < > | | | | | | | | | | < | > | | < > | 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 | * __\-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\. | | | | < > | | | < > | 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 | 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: | | | | < | > < > | | | | | | < > | | | | | | | | | < | > < | > | | | | | | | < | > | | | | | | | | | | | < | > | < < > > | 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 | 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: | | | | 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 | 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: | | | | | | | | | | 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 | 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 | | | 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 | 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: | | | | | 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 | ## <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\. | | | < > | 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 | ## <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__\. | | | < > | | < > | | | | < > | | | | | | | | | | | | | | | 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 | 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: | | | | 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 | 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: | | | | | | 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 | ## <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: | | | | < | > | | < < > > | | | | | < | > | | < < > > | | | 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 | ## <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__: | | | | < > | | | | | | | | < | > | | < < > > | | 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 | __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: | | | < < > > | | < < > > | | < < > > | | | 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 | 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)__: | | | | | | | < < > > | | | | | < < > > | 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 | ## <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: | | | | < > | | | | < < > > | 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 | 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: | | | < | > | < | > | < < > > | | | | | < < > > | 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 | ## <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: | | | | | | < > | | | | | < > | | | | | | | | | | | | | | | | | | | | | < < > > | | | | < > | | | < > | | | | | | | | < < > > | | | | < < > > | 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 | 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: | | | | | | < < < > > > | | | 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 | ## <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: | | | | < > | | | | < < > > | 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 | 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: | | | | | | < < > > | < > | | | < < > > | | | | < | | < > | > | | | 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 | 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: | | | | | < < > > | | | 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 | 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: | | | | | | < > | | | | | | | | < < > > | 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 | ## <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\. | | | | < < > > | 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 | 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\. | | | | | | < < | > > | < < > > | | | < < > > | | | | < | > | < > | | 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 | 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\. | | | | | | < < | > > | | | | < < | > > | < < > > | 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 | 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\. | | | | < | > | | < < > > | 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 | __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\): | | | | | < | > | < < > > | 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 | 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: | | | | < | > | | < > | | < < | > > | | | | < | > | | < | > | < < > > | | | | < < > > | 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 | 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: | | | | < < > > | | 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 | __\-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: | | | | | < < | > > | | | 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 | 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\. | | | | < > | | | | < < > > | | | < | > | < | > | < | > | | < | | > | | < < > > | | < > | | | | < < > > | | | < | > | | | < > | < > | | < > | 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 | 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: | | | | | < < > > | | | < > | | | | | | < < > > | | | | | | < | > | < < > > | 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 | 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: | | | | | | | < | | < > > | | | < | > | | | | | < | | < > > | | | < > | 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 | 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: | | | < > | | < > | | | | | | < < > > | 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 | 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\. | | | | | | < | > | | | | | | | | | | < > | 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 | __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: | | | | | < < > > | 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 | 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 | | | | < > | 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 | 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: | | | | | | | | | | < | | < > > | | | | | | | | | | | < | | < > > | | | | | | | | | < > | | | | | | | | < | > | | | | | | | | | | < | > | | | | | | 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 | 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: | | | | | | | | < > | < > | | | 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 | 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: | | | | | < < > > | | | | < < > > | 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 | 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: | | | | < < > > | | | < < > > | | | | | | < < > > | 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 | 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__: | | | | < > | | | < > | | | < > | | | < | > | | | | | | < > | 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 | 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: | | | | | < | > | | | | | | | | | < < > > | | | < < > > | | | | | < | > | < | > | | | | | < > | | | | | | < > | 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 | * __[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: | | | | 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 | 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: | | | | | | | | < > | < > | 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 | 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: | | | | | < > | | < > | < > | 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 | 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: | | | | | < > | < > | 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 | - <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: | | | | | | < > | | | < > | < > | | | < > | | | < > | | < > | | < > | | < > | | < < > > | 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 | 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: | | | | | | | < < | > | > | | | < > | | | < > | < > | 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 | 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\): | | | | | 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 | A shortcut to ::unicode::tostring \[unicode::normalize \\$form \[::unicode::fromstring \\$string\]\]\. Normalizes Tcl string and returns normalized string\. # <a name='section3'></a>EXAMPLES | | | | | | 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 | 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: | | | | | | | | | | | | | | | 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 | 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 | | | | 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 | 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\. | | < > | | | | | | | | | | | | < > | < > | | 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 | 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 | | | | 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 | 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\. | | < > | | | < > | < > | | 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 | # <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 | | | | | | | | | | | | | | | | | 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 | # <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 | | | | | | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | | | < | > | | | | | | | < > | | | | | | | | | < | > | | | | | | | | | | < > | 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 | 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: | | | < | > | | | < > | | < > | 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 | 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: | | | | | | | | | | | | | | | | | | | | 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 | *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: | | | | | | | | | < > | | | | < > | | | | | | | | | | | | | | | < > | | | | | | | < > | | | < > | 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 | 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\. | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | | < > | | | < > | | | | | | 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 | * __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\. | | | | | 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 | \.\.\.__ is identical to __list arg \.\.\.__, though the *arg* is required with __repeat__\. *Examples:* tclsh> ::struct::list repeat 3 a a a a | | | | | | 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 | 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 | | | | | | | 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__|__\-left__|__\-right__|__\-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 | 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 | | | | | | | | | | | | | | | | 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 | 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 | | | | 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 | 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 | | < > | | | < | > | | | | | | 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 | 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 | | | | | | | | 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 | 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 | | | | | | | 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 | 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: | | | | | | | | 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 | 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__" | | | | 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 | * __\-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\. | | | < > | < > | 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 | * __\-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\. | | | | 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 | - <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\. | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | 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__|__1__|__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 | ## <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: | | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < > > | 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__|__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__|__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 | __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: | | | | | | | < < > > | | | | < > < > | 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 | 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: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | * *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 '?'\): | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | 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 | 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: | | | | | | | | | | | | | | > | < | | | | < < > > | | 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 | 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: | | | | | | | | | | | | | | | | | | | | | | | 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 | 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: | | | | | | 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 | 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: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < > > | 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 | 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: | | | | | | | | | | | 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 | - *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\. | | | | | | | | | | | | | | | | | | > | < < > | | | | | | | | | | | | 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 | 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\. | | | | | > | < | | < > | | | | | 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__|__1__ |
︙ | ︙ | |||
363 364 365 366 367 368 369 | - \-validatecommand *script* Custom argument validations can be performed via specific validation commands that are defined with the *\-validatecommand* attribute\. Validation command declaration example: | | | | | | < > | 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 | 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: | | | | | | | | | | | < > | | | | | | | | | | > | < | < | | > | | | > | < | < | > | | | | | | | | | > | < | < > | | | | | | | | | > | < | < > | 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 | 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: | | | | | | < > | 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 | * \-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: | | | | < > | | | | > | < < > | | | < > | | | | | 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 | 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: | | | | | | | > | < | < > | | | > | < | < | > | | | | 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 | 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: | | | | 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 | 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: | | | | | | | | | | | | | | | > | < | < > | | | | | | | | | | | | | | > | < | < | > | | | | | | | | | | | | | | | > | < < > | | | | | | | | | | | | | | | | | | | > | < < > | | 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 | 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: | | | | | | | | | | | | | | | | > | < | < > | | 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 | 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 | | | | | 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 | 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: | | | 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 | # <a name='section3'></a>TUTORIAL ## <a name='subsection1'></a>Basics To begin, create an expander object: % package require textutil::expander | | | | | | | | | | < > | | | | | | | | | | | | | | | | | | | | < | > | | | | < > | | < | > | | | | | < > | 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 | 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 | | | | | | | | 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 | __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\. | | | | | | | | | | 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 | 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 | | | < > | < > | | | | | | | | < < > > | | | | | | | | < > | | | 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 | 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 | | | < | > | | | | | | | | < > | 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 | __[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__\. | | | | < < > > | 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 | 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\. | | | | < > | < > | | < < > > | | | | < < > > | | 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 | # <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\. | | | | | | | 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 | 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 | | | | 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 | # <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\. | | | | | | | 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 | 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 | | | | 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 | 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 | | | 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 | # <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\. | | | | | | | 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 | 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 | | | | 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 | 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\. | | | | | | | | | | | | | | | | | 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 | - <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 | | | 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 | 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: | | | | | | | < > | | | | < > | 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 | 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: | | | | | < > | | 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 | 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, | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 | 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 | | | | | | | 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 | - <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 | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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: | | | | 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 | 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 | | | | < > | < > | | < < | > | | > | | | < | > | | 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 | 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 | | | | 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 | 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\. | | | | | | | | | | | | 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 | 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\. | | | | | | | | | | | | | | | | | 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 | the node is a boolean\. * ____null____ the node is a null\. | | | | | | < < > > | < > | | | | | < > | | | | | 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 | 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 | | | | | | | | | | | | | 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 | - <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\. | | | | | | | | < > | | | | | | | < > | | | < > | | | | < > < > | | < > | | | < > | | | | | | < > < > | | | | | | | < < > > | < > | | | | | < > | < > | | | < > | < < < | > > > | | | | | | | | < < > > | | | | | < > | < > | | < < < > > > | | | | | | | | | | | | | | | | | | | | | < < > > | | | < > | < > | < > | 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 | *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 \.\.\.\) | | | | | | | | 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 | 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\. | < > | | | | | | | | | | | | | | | < > | | | | | < > | | | | < > | | < > | | 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 | 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 | | | | 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 | * __\-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 | | | 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 | '\" '\" Generated from file 'doctools\&.man' by tcllib/doctools with format 'nroff' '\" Copyright (c) 2003-2019 Andreas Kupries <andreas_kupries@users\&.sourceforge\&.net> '\" | | | 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 | .. .BS .SH NAME doctools \- doctools - Processing documents .SH SYNOPSIS package require \fBTcl 8\&.2\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 | | <a href="../../../toc.html">Table Of Contents</a> | <a href="../../../../index.html">Keyword Index</a> | <a href="../../../../toc0.html">Categories</a> | <a href="../../../../toc1.html">Modules</a> | <a href="../../../../toc2.html">Applications</a> ] <hr> <div class="doctools"> | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | | <a href="../../../toc.html">Table Of Contents</a> | <a href="../../../../index.html">Keyword Index</a> | <a href="../../../../toc0.html">Categories</a> | <a href="../../../../toc1.html">Modules</a> | <a href="../../../../toc2.html">Applications</a> ] <hr> <div class="doctools"> <h1 class="doctools_title">doctools(n) 1.5.2 tcllib "Documentation tools"</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 | <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> | | | 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 | [comment {-*- tcl -*- doctools manpage}] | | | 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 | # => 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]} } | | | 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 | # Modified bulleting DIB [list [Dash] [Star] [Plus]] DEB [list "1[Dot]" "1[CPar]"] proc Unmark {x} { lappend map "\1\n" " \n" | | | 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 | if {![package vsatisfies [package provide Tcl] 8.2]} {return} | | | 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 &copy; .COPYRIGHT. --> <!-- TEST.z --> <body><div class="doctools"> <h1 class="doctools_title">TEST(z) 3.14.15.926 .MODULE. ""</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 © .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 | # <a name='description'></a>DESCRIPTION BEGINNE HIER Example Block More Lines | | | 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 © \.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 © \.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 © \.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. |