'''[http://www.chiselapp.com/user/pooryorick/repository/ycl/%|%ycl]''', short for '''Y'''orick's '''C'''omputing too'''L'''kit, is [PYK]'s collection of miscellaneous procedures and programs. ** Installation ** To download ycl: ====== fossil clone http://chiselapp.com/user/pooryorick/repository/ycl ycl.fossil ====== Then, open the fossil and add `/path/to/opened/fossil/packages` to [auto_path%|%$auto_path%|%] There is also a helper script, .../ycl/bin/yclrun, which will automatically adjust $auto_path, and can be used as wrapper: ======none tclsh /path/to/opened/fossil/packages/ycl/bin/yclrun myscript.tcl ====== There is another helper script for an interactive shell: ======none tclsh /path/to/opened/fossil/packages/ycl/bin/yclsh ====== [Zipguy] 2013-11-24: How about if you put all those files into a folder structure? Even one folder, named 'ycl', or 'app-ycl' would work good. Then you could either zip them (or you could have gz'ed them), or SDX them (into a starkit) which would make it a lot easier to download them? There are way too many files for me to chase, individually, even though they look quite interesting. Probably a version would be good too, so you could check it, and see if you've already downloaded the latest version. [pyk]: you can get this by logging into the repository as anonymous, and then choosing to download the zip or tarball for the commit you're interested in. ** Usage ** The documentation appears in the source code immediately prior to each function declaration. It is in a text format which is intended to be reasonably intuitive even without much knowledge of Tcl. Most packages have test suites (look for files ending in .test), which provide examples. ** `ycl/bin/ycl` ** The script `ycl/bin/ycl` can be used to call a command in ycl from a shell. *** synopsis *** : `ycl/bin/ycl` `cmd` ''package'' ''command'' ?''args''? ''command'' is a command available in ''package'' *** Example *** From an [sh] shell: ======none $ tclsh /cygdrive/c/Users/yorick/Documents/ycl/src/packages/ycl/bin/ycl cmd 'math rand' randprint_256 BUV9z#=Zu=dAi@y^ytLk1LrTKRp35tbqN^LgqkH7Z6 ====== ** Contents ** *** chan *** '''`tee`''': Transforms a channel into another channel whose output is asynchronously duplicated to a third channel. '''`tplex`''': A threaded non-blocking channel multiplexer that has various modes. It can act as a buffer for a single channel, which is the right tool for capturing [stderr] from an `[open]` or `[exec]` pipeline. It can act as a multiplexer sending the contents of the channel to multiple recipeient channels. It can act as a sink to just drain a channel. '''`chunked`''': A [reflected channel] that wraps another channel, translating its contents from [Hypertext Transfer Protocol%|%HTTP] chunked format. Written as a reflected channel instead of a [transchan%|%channel transform] so that the wrapped channel can persist after the chunked wrapper is closed. This feature is useful for persistent HTTP connections. '''`wrap`''': A skeleton [reflected channel] that wraps another channel. *** chan clib *** ====== package require {ycl chan clib} ::critcl::api import ycl_chan_clib 0.1 ====== Provides the following [C] functions: '''`filter(Tcl_Interp *interp ,Tcl_Channel inchan ,Tcl_Channel outchan ,(process)(Tcl_Interp *interp ,Tcl_UniChar *uchar ,Tcl_DString *output))`''': Filters data as it passes from `inchan` to `outchan`. `process` recieves one character and modifies `output` , which is then written to `outchan`. *** comm *** '''`[ycl comm http]`''': An http client that makes use of [coroutine%|%coroutines] and [reflected channel%|%reflected channels]. *** context *** Deprecated in favor of `ycl shelf` ====== package require {ycl context} namespace import [yclprefix]::context::context proc fly {ns args} { puts "$ns is flying!" } proc nofly {ns args} { puts "$ns can't fly!" } context bird bird method fly bird fly bird derive eagle eagle fly bird derive emu emu method fly nofly emu fly #remove emu's restriction set emumethods [namespace ensemble configure emu -map] set emumethods [dict remove $emumethods fly] namespace ensemble configure emu -map $emumethods emu fly ====== *** `coro` *** '''`async`''': A distillation of the `[ycl coro relay]` system into three commands: `wait`, `reply`, and `async`. This provides all the functionality of [Javascript] promises but without all the extra syntax. '''`event`''': An event loop for coroutines. Tries to play nice with Tcl's event loop. This system was created to avoid the performance penalty of using Tcl's event loop as a queue for communication between coroutines. '''`[ycl coro relay%|%relay]`''': A small but complete system that allows cooperating coroutines to make and deliver orders amongst themselves. *** [ycl eav%|%eav] *** '''[ycl eav%|%eav]''': An entity-attribute-value system built on [sqlite], featuring a Tcl-ish interface and query capabilities, and traces for maintaining data constraints and reacting in other ways to record updates. *** [Daerth] *** '''[Daerth]''': creates and manages minions of threaded asynchronous pipelined backpressure-mediated compute stations. *** dict *** '''`search`''': Like `[lsearch]`, but searches keys, and returns results in reverse order. '''setm''': Like `[dict set]`, but doesn't deduplicate other keys in the dictionary. '''unsetm''': Like `[dict unset]`, but doesn't deduplicate other keys in the dictionary. *** dir *** ====== package require {ycl dir} namespace import [yclprefix]::dir ====== '''copynode''': Copy a file or directory into an archive location, faithfully duplicating any symbolic links, recursively, in the path of the file. Does not copy the contents of a directory, just the directory node itself, which may be a symbolic link. In order to accomodate arbitrary symbolic links in the path of the file or directory, It is placed in the archive at the same absolute location, with the archive directory as the root. '''duplicates''': find duplicate files '''deduplicate''': remove duplicate files '''iter''': iterate over items in a directory tree. ====== for item in [dir iter /my/dir] { #do stuff } ====== *** entropy *** A "daemon" coroutine that collects entropy when the system is idle. *** exec *** '''invoke''': invoke a child program and asynchronously handle [stdio], [stderr], and exit code. See example at [[`[open]`]. *** iter *** Very similar in spirit to [Generator]. Can be used with [[[for in%|%for ... in%|%]]] ====== package require {ycl iter} ====== A set of iterators '''file''': iterate over a file, by line or arbitrary function '''string''': iterate over the characters in a string *** format *** '''sh::shtotcl''': converts the words of a value in sh syntax to a Tcl [list]. *** iter::for *** ====== package require {ycl iter for} ====== '''[for in%|%for ... in]''': a convenient loop construct for working with iterators *** [knit] *** See [knit]. *** list *** ====== variable fruits {apple banana orange pear kiwi} proc is_fruit item { variable fruits return [expr {$item in $fruits}] } ====== The functions, '''all'', '''any''', '''are''', and '''which''' also support an `in $list` pattern. '''all''': true if all items in a list pass the specified test ====== all {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] all {banana cookie} in $fruits # -> 0 ====== '''any''': true if any items in a list pass the specified test ====== any {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] any {banana cookie} in $fruits # -> 1 ====== '''are''': a list containing true/false answers indicating whether items in a list pass the specified test ====== are {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] are {banana cookie} in $fruits # -> {1 0} ====== '''`dedent`''': Remove common whitespace from list items. '''`filter`''' ''list'' ''mask'': Filter items from ''list'' using ''mask'', which is a list of boolean values. '''`pick`''': Extract elements from a list by combinations of index, range, and step. '''`sl`''': See [scripted list]. '''`which`''': a list of items from a list that pass the specified test ====== which {banana cookie} [list apply [list x {variable fruits; expr {$x in $fruits}} [namespace current]]] which {banana cookie} in $fruits # -> banana ====== *** matrix *** A close-to-drop-in replacement for [tcllib%|%tcllib's] [matrix], but with better performance characteristics since it's more careful about avoiding duplication of data during operation. *** math *** '''`flip`''': Randomly produces a `1` or `0`. The output is intended to have the same high entropy as as [true random numbers] and to be suitable for cryptographic use. This command is analagous to `/dev/random`. '''`rng`''': Cryptogphic random number generator using a seed produced by '''`flip`'''. Analagous to `/dev/urandom`. '''`rand`''': A cryptographically-strong alternative to the built-in `[expr%|%rand()]` function. *** ns *** ====== package require {ycl ns} ====== '''`dupcmds`''': Copy all commands in a namespace to another namespace, refusing to overwrite any existing commands, and ignoring commands named in in `$args`. In contrast to `[oo::copy] `, if a command is both an alias and a procedure, it is treated as an alias. '''`ensemble duplicate`''': Copy a [namespace ensemble], and if necessary, the [namespace] that's backing it, along with any child namespaces, recursively. Also replaces in the ensemble map occurrences of the old ensemble name with the new ensemble name. `dupensemble` can be used as the simplese form of [object orientation%|%object system], where each namespace hierarchy is treated as an object. Tcl's [copy-on-write] semantics make this system much more efficient than one would expect at first blush. `dupensemble` is used by `ycl::shelf` '''`ensemble subcommands`''': List the currently-available subcommands of a [namespace ensemble]. '''`dupvars`''': duplicates all variables in a namespace to another namespace *** proc *** '''`[procstep%|%tcl step]`''': A drop-in replacement for `[proc]` that provides a pre-evaluation hook and an error handling hook for each command in the script. *** upobj *** Together with proc::methods, proc::upmethods, and var::upmethods, compromises an object system much like '''ycl::context'''. Its method calling style provides for `[uplevel] 1` to be the object's namespace, and `[uplevel] 2` to be the caller of the method. This turned out to be a little clunky, and [ycl shelf] is now preferred to this system. ====== #! /bin/env tclsh package require ycl::ns namespace import ycl::ns::object package require ycl::proc namespace import ycl::proc::*method upmethod die {} {} {} { puts "$_ dies." } object chessman import {name die} chessman $ name unknown namespace eval chessman { upmethod move {} {} {} { puts "$_ doesn't know how to move!" } } object pawn pawn parent chessman namespace eval pawn { upmethod move {} {} {} { puts "$_ is plodding forward" } } object knight knight parent chessman namespace eval knight { upmethod move {} {} {} { puts "$_ gallops forward and to the side" } } object amazon namespace eval amazon { upmethod move {args} {} {} { dict with args {} if {$as ni {knight queen}} { puts "$_ can not move as a $as" } else { puts "$_ is moving as a $as" } } } puts "chessman name is: [chessman $ name]" # -> unknown chessman move # -> ::chessman doesn't know how to move! object pawn1 pawn1 parent pawn pawn1 move # -> ::pawn1 is plodding forward puts "pawn1 name is: [pawn1 $ name]" # -> unknown pawn1 $ name {white a} puts "pawn1 name is now: [pawn1 $ name]" # -> white a object knight1 knight1 parent knight knight1 move # -> ::knight1 gallops forward and to the side object knight3 knight3 parent knight2 knight3 parent amazon knight3 move as queen knight3 move as bishop ====== *** package *** '''vcomp''': like `[package vcompare]`, but accepts just about anything as a version string. *** parse *** '''`tcl commands`''': Split a Tcl [script] into its components. This is `[cmdSplit%|%scriptsplit]` '''`tcl iter`''': Uses `ycl coro relay` to deliver the comands in a script read from a [chan%|%channel]. '''`tcl words`''': Split a Tcl [command] into its components. This is `[cmdSplit]`. '''`tcl wordparts`''': Split a logical word from a Tcl command into its literal, escape-sequence, and substitution components. This is `[cmdSplit%|%wordparts]`. '''`tcl stream`''': Incrementally parse a Tcl script from a channel. '''`xml`''': An [xml] parser based on `ycl parser graph`. '''`-relax true`''' enables a forgiving mode when trying to make it through an document. '''`xml util validCharExpr`''' ''`varname`'': Returns an [expr%|%expression] that evaluates to `true` if the character in $varname is a valid [XML] character, and `false` otherwise. '''`xml util encodeInvalidChars`''' ''inchanname'' ''outchanname'': A filter between channels that converts characters that are invalid in [XML] to their XML character representations. Accelerated with [Critcl] when it's available. Uses `ycl chan clib filter`. *** parser *** ====== package require {ycl parser graph} ====== '''`graph`''': A framework for extracting graphs from data. '''`-transient false`''' instructs the parser to leave behind a hierarchy of namespaces representing the graph, and commands like '''`children`''', '''`path`''', and '''`traverse`''' provide an interface to the graph. This system facilitates the creation of parsers that ignore text outside the target syntax of a given parser. *** proc *** ====== package require ycl::dir namespace import [yclprefix]::dir ====== '''`checkargs`''': functional documentation for procedures. Somewhat like [tepam], with additional aspects of [literate programming]. Examples include [http://chiselapp.com/user/pooryorick/repository/ycl/artifact/93cdea1aac40f022%|%ycl::dir::iter], and [http://chiselapp.com/user/pooryorick/repository/ycl/artifact/90bca3673c69e35d%|%ycl::ns::object] '''`[proc alias%|%alias]`''': an analogue of [interp alias] that avoids the potential negative performance impact. In contrast to [interp alias], extra arguments can not be tacked on to the alias. *** [Quick-Tk%|%quicktcl] *** *** [ycl shelf%|%shelf] *** See [ycl shelf] *** string *** ====== package require {ycl string} ====== '''`cmp`''': Like the [Unix] [http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cmp.html%|%cmp] command, compares two strings and returns the index at which they differ, or -1 if they are identical. Uses a bisect strategy for performance, and for memory efficiency does not extract substrings. Short-circuits when a difference is found. '''`shortmatch`''': same as [string match], but return -1 if $string doesn't match, and the index of the last char of the shortest match if it does '''`dedent`''': remove common newline-whitespace '''`delimit`''': split (partition) a string into substrings using any combination of string, match, or regular expressions, returning both the substrings and the delimiters. '''`[ycl string expand%|%expand]`''': Provides a macro syntax to expand substrings within a string by iteratively replacing a listed nested in the substring itself with items from the list. The idea is to generate code while keeping the original source code legible. '''`expand`''': Provides a concise syntax for embedding and expanding templates in text, the primary target being Tcl scripts. Based on `ycl parser graph` '''`template`''': Cut down the verbosity of `[string map]` by using the same name to obtain a value from a local variable and to map that value into the string, providing default delimiters, and by automatically quoting values with `[list]`. Example: ====== set a 5 set b 7 set expr {[set a]} eval [template a b # c { set a @a@ set b @b@ expr {$a + $b + @expr@} ====== *** struct *** '''[`nxs]`''': Nested heterogeneous structures. Example: `nxs get $mystruct l {0 3 1} d {name Bob friends} l 5`. To set a nested vale: `nxs set mystruct l {0 3 1} d {name Bob friends} = l end Jane`. Extend the functions to additional types of nested structures by adding keys to `nxs::get`, `nxs::set`, and `nxs::unset`. To specialize the library, use `ycl ns dupensemble` to create a copy of it. *** switch *** '''`[lswitch]`''': Like `[switch]`, but each ''pattern'' is a [list] of patterns to match against the item in ''string'' at the corresponding position. All `switch` options are supported. *** text *** '''`ftclp`''': Formats a string as a printable Tcl string. Non-printable characters are transformed into their most simple [Dodekalogue%|%backslash-escaped] representation, and backslash is also escaped. *** tk_combobox_oakley *** Assimilated from [Bryan Oakley%|%Bryan Okley's] [combobox]. *** visual *** '''`slides`''': A simple [presentation program%|%presentation system] in [Tk]. ---- '''[anonymous] - 2016-08-26 01:25:05''' What is the license on your ycl toolkit? It's not totally clear and there are some GPL'd items hidden in it. [PYK] 2016-08-30: Contributors license their contributions independently. As for my contributions, I'm currently handling license requests on a case-by-case basis. <> Package