19 changed files with 2395 additions and 1651 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,501 @@
|
||||
# -*- tcl -*- |
||||
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'pmix make' or bin/punkmake to update from <pkg>-buildversion.txt |
||||
# module template: shellspy/src/decktemplates/vendor/punk/modules/template_module-0.0.2.tm |
||||
# |
||||
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. |
||||
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# (C) 2024 |
||||
# |
||||
# @@ Meta Begin |
||||
# Application punk::experiment 999999.0a1.0 |
||||
# Meta platform tcl |
||||
# Meta license <unspecified> |
||||
# @@ Meta End |
||||
|
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# doctools header |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
#*** !doctools |
||||
#[manpage_begin shellspy_module_punk::experiment 0 999999.0a1.0] |
||||
#[copyright "2024"] |
||||
#[titledesc {Module API}] [comment {-- Name section and table of contents description --}] |
||||
#[moddesc {-}] [comment {-- Description at end of page heading --}] |
||||
#[require punk::experiment] |
||||
#[keywords module] |
||||
#[description] |
||||
#[para] - |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[section Overview] |
||||
#[para] overview of punk::experiment |
||||
#[subsection Concepts] |
||||
#[para] - |
||||
|
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
## Requirements |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[subsection dependencies] |
||||
#[para] packages used by punk::experiment |
||||
#[list_begin itemized] |
||||
|
||||
package require Tcl 8.6- |
||||
#*** !doctools |
||||
#[item] [package {Tcl 8.6}] |
||||
|
||||
# #package require frobz |
||||
# #*** !doctools |
||||
# #[item] [package {frobz}] |
||||
|
||||
#*** !doctools |
||||
#[list_end] |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
#*** !doctools |
||||
#[section API] |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# oo::class namespace |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
namespace eval punk::experiment::class { |
||||
#*** !doctools |
||||
#[subsection {Namespace punk::experiment::class}] |
||||
#[para] class definitions |
||||
if {[info commands [namespace current]::interface_sample1] eq ""} { |
||||
#*** !doctools |
||||
#[list_begin enumerated] |
||||
|
||||
# oo::class create interface_sample1 { |
||||
# #*** !doctools |
||||
# #[enum] CLASS [class interface_sample1] |
||||
# #[list_begin definitions] |
||||
|
||||
# method test {arg1} { |
||||
# #*** !doctools |
||||
# #[call class::interface_sample1 [method test] [arg arg1]] |
||||
# #[para] test method |
||||
# puts "test: $arg1" |
||||
# } |
||||
|
||||
# #*** !doctools |
||||
# #[list_end] [comment {-- end definitions interface_sample1}] |
||||
# } |
||||
|
||||
#*** !doctools |
||||
#[list_end] [comment {--- end class enumeration ---}] |
||||
} |
||||
} |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# Base namespace |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
namespace eval punk::experiment { |
||||
namespace export {[a-z]*} ;# Convention: export all lowercase |
||||
#variable xyz |
||||
|
||||
#*** !doctools |
||||
#[subsection {Namespace punk::experiment}] |
||||
#[para] Core API functions for punk::experiment |
||||
#[list_begin definitions] |
||||
|
||||
|
||||
|
||||
#proc sample1 {p1 n args} { |
||||
# #*** !doctools |
||||
# #[call [fun sample1] [arg p1] [arg n] [opt {option value...}]] |
||||
# #[para]Description of sample1 |
||||
# #[para] Arguments: |
||||
# # [list_begin arguments] |
||||
# # [arg_def tring p1] A description of string argument p1. |
||||
# # [arg_def integer n] A description of integer argument n. |
||||
# # [list_end] |
||||
# return "ok" |
||||
#} |
||||
|
||||
variable o_opts_table [dict create\ |
||||
] |
||||
variable o_opts_table_defaults [dict create\ |
||||
-test 1\ |
||||
-test2 etc\ |
||||
-test3 333\ |
||||
-test4 444\ |
||||
] |
||||
set topt_keys [dict keys $o_opts_table_defaults] |
||||
set topt_switchkeys [list -test - -test2 - -test3 - -test4] |
||||
|
||||
proc configure args [string map [list %topt_keys% $topt_keys %topt_switchkeys% $topt_switchkeys] { |
||||
variable o_opts_table |
||||
variable o_opts_table_defaults |
||||
if {![llength $args]} { |
||||
return $o_opts_table |
||||
} |
||||
if {[llength $args] == 1} { |
||||
if {[lindex $args 0] in [list %topt_keys%]} { |
||||
#query single option |
||||
set k [lindex $args 0] |
||||
set val [dict get $o_opts_table $k] |
||||
set returndict [dict create option $k value $val ansireset "\x1b\[m"] |
||||
set infodict [dict create] |
||||
switch -- $k { |
||||
-ansibase_header - -ansibase_body - -ansiborder_header - -ansiborder_body - -ansiborder_footer { |
||||
dict set infodict debug [ansistring VIEW $val] |
||||
} |
||||
-framemap_body - -framemap_header - -framelimits_body - -framelimits_header { |
||||
dict set returndict effective [dict get $o_opts_table_effective $k] |
||||
} |
||||
} |
||||
dict set returndict info $infodict |
||||
return $returndict |
||||
#return [dict create option $k value $val ansireset "\x1b\[m" info $infodict] |
||||
} else { |
||||
error "textblock::table configure - unrecognised option '[lindex $args 0]'. Known values [dict keys $o_opts_table_defaults]" |
||||
} |
||||
} |
||||
if {[llength $args] %2 != 0} { |
||||
error "[namespace current]::table configure - unexpected argument count. Require name value pairs" |
||||
} |
||||
foreach {k v} $args { |
||||
switch -- $k { |
||||
%topt_switchkeys% {} |
||||
default { |
||||
error "[namespace current]::table configure - unrecognised option '$k'. Known values [dict keys $o_opts_table_defaults]" |
||||
} |
||||
} |
||||
#if {$k ni [dict keys $o_opts_table_defaults]} { |
||||
# error "[namespace current]::table configure - unrecognised option '$k'. Known values [dict keys $o_opts_table_defaults]" |
||||
#} |
||||
} |
||||
set checked_opts [list] |
||||
foreach {k v} $args { |
||||
switch -- $k { |
||||
-ansibase_header - -ansibase_body - -ansiborder_header - -ansiborder-body - -ansiborder_footer { |
||||
set parts [punk::ansi::ta::split_codes_single $v] ;#caller may have supplied separated codes eg "[a+ Yellow][a+ red]" |
||||
set ansi_codes [list] ; |
||||
foreach {pt code} $parts { |
||||
if {$pt ne ""} { |
||||
#we don't expect plaintext in an ansibase |
||||
error "Unable to interpret $k value as ansi SGR codes. Plaintext detected. Consider using for example: '\[punk::ansi::a+ green]' (or alias '\[a+ green]') to build ansi. debug view: [punk::ansi::ansistring VIEW $v]" |
||||
} |
||||
if {$code ne ""} { |
||||
lappend ansi_codes $code |
||||
} |
||||
} |
||||
set ansival [punk::ansi::codetype::sgr_merge_singles $ansi_codes] |
||||
lappend checked_opts $k $ansival |
||||
} |
||||
-frametype - -frametype_header - -frametype_body { |
||||
#frametype will raise an error if v is not a valid custom dict or one of the known predefined types such as light,heavy,double etc |
||||
lassign [textblock::frametype $v] _cat category _type ftype |
||||
lappend checked_opts $k $v |
||||
} |
||||
-framemap_body - -framemap_header { |
||||
#upvar ::textblock::class::opts_table_defaults tdefaults |
||||
#set default_bmap [dict get $tdefaults -framemap_body] |
||||
#todo - check keys and map |
||||
if {[llength $v] == 1} { |
||||
if {$v eq "default"} { |
||||
upvar ::textblock::class::opts_table_defaults tdefaults |
||||
set default_map [dict get $tdefaults $k] |
||||
lappend checked_opts $k $default_map |
||||
} else { |
||||
error "textblock::table::configure invalid $k value $v. Expected the value 'default' or a dict e.g topleft {hl *}" |
||||
} |
||||
} else { |
||||
foreach {subk subv} $v { |
||||
switch -- $subk { |
||||
topleft - topinner - topright - topsolo - middleleft - middleinner - middleright - middlesolo - bottomleft - bottominner - bottomright - bottomsolo - onlyleft - onlyinner - onlyright - onlysolo {} |
||||
default { |
||||
error "textblock::table::configure invalid $subk. Known values {topleft topinner topright topsolo middleleft middleinner middleright middlesolo bottomleft bottominner bottomright bottomsolo onlyleft onlyinner onlyright onlysolo}" |
||||
} |
||||
} |
||||
dict for {seg subst} $subv { |
||||
switch -- $seg { |
||||
hl - hlt - hlb - vl - vll - vlr - trc - tlc - blc - brc {} |
||||
default { |
||||
error "textblock::table::configure invalid $subk value $seg. Known values {hl hlt hlb vl vll vlr trc tlc blc brc}" |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
lappend checked_opts $k $v |
||||
} |
||||
|
||||
} |
||||
-framelimits_body - -framelimits_header { |
||||
set specific_framelimits [list] |
||||
foreach fl $v { |
||||
switch -- $fl { |
||||
"default" { |
||||
lappend specific_framelimits trc hlt tlc vll blc hlb brc vlr |
||||
} |
||||
hl { |
||||
lappend specific_framelimits hlt hlb |
||||
} |
||||
vl { |
||||
lappend specific_framelimits vll vlr |
||||
} |
||||
hlt - hlb - vll - vlr - trc - tlc - blc - brc { |
||||
lappend specific_framelimits $fl |
||||
} |
||||
default { |
||||
error "textblock::table::configure invalid $k '$fl'. Known values {hl hlb hlt vl vll vlr trc tlc blc brc} (or default for all)" |
||||
} |
||||
} |
||||
} |
||||
lappend checked_opts $k $specific_framelimits |
||||
} |
||||
-ansireset { |
||||
if {$v eq "\uFFEF"} { |
||||
set RST "\x1b\[m" ;#[a] |
||||
lappend checked_opts $k $RST |
||||
} else { |
||||
error "textblock::table::configure -ansireset is read-only. It is present only to prevent unwanted colourised output in configure commands" |
||||
} |
||||
} |
||||
-show_hseps { |
||||
if {![string is boolean $v]} { |
||||
error "textblock::table::configure invalid $k '$v'. Must be a boolean or empty string" |
||||
} |
||||
lappend checked_opts $k $v |
||||
#these don't affect column width calculations |
||||
} |
||||
-show_edge { |
||||
if {![string is boolean $v]} { |
||||
error "textblock::table::configure invalid $k '$v'. Must be a boolean or empty string" |
||||
} |
||||
lappend checked_opts $k $v |
||||
#these don't affect column width calculations - except if table -minwidth/-maxwidth come into play |
||||
set o_calculated_column_widths [list] ;#invalidate cached column widths - a recalc will be forced when needed |
||||
} |
||||
-show_vseps { |
||||
#we allow empty string - so don't use -strict boolean check |
||||
if {![string is boolean $v]} { |
||||
error "textblock::table::configure invalid $k '$v'. Must be a boolean or empty string" |
||||
} |
||||
#affects width calculations |
||||
set o_calculated_column_widths [list] |
||||
lappend checked_opts $k $v |
||||
} |
||||
-minwidth - -maxwidth { |
||||
set o_calculated_column_widths [list] |
||||
lappend checked_opts $k $v |
||||
} |
||||
default { |
||||
lappend checked_opts $k $v |
||||
} |
||||
} |
||||
} |
||||
#all options checked - ok to update o_opts_table and o_opts_table_effective |
||||
|
||||
#set o_opts_table [dict merge $o_opts_table $checked_opts] |
||||
foreach {k v} $args { |
||||
#yes in safe |
||||
switch -- $k { |
||||
-framemap_header - -framemap_body { |
||||
#framemaps don't require setting every key to update. |
||||
#e.g configure -framemaps {topleft <map>} |
||||
#needs to merge with existing unspecified keys such as topright middleleft etc. |
||||
if {$v eq "default"} { |
||||
dict set o_opts_table $k default |
||||
} else { |
||||
if {[dict get $o_opts_table $k] eq "default"} { |
||||
dict set o_opts_table $k $v |
||||
} else { |
||||
dict set o_opts_table $k [dict merge [dict get $o_opts_table $k] $v] |
||||
} |
||||
} |
||||
} |
||||
default { |
||||
dict set o_opts_table $k $v |
||||
} |
||||
} |
||||
} |
||||
#use values from checked_opts for the effective opts |
||||
dict for {k v} $checked_opts { |
||||
switch -- $k { |
||||
-framemap_body - -framemap_header { |
||||
set existing [dict get $o_opts_table_effective $k] |
||||
#set updated $existing |
||||
#dict for {subk subv} $v { |
||||
# dict set updated $subk $subv |
||||
#} |
||||
#dict set o_opts_table_effective $k $updated |
||||
dict set o_opts_table_effective $k [dict merge $existing $v] |
||||
} |
||||
-framelimits_body - -framelimits_header { |
||||
#my Set_effective_framelimits |
||||
dict set o_opts_table_effective $k $v |
||||
} |
||||
default { |
||||
dict set o_opts_table_effective $k $v |
||||
} |
||||
} |
||||
} |
||||
#ansireset exception |
||||
dict set o_opts_table -ansireset [dict get $o_opts_table_effective -ansireset] |
||||
return $o_opts_table |
||||
}] |
||||
|
||||
|
||||
|
||||
proc test1 {args} { |
||||
set result [list] |
||||
dict for {k v} $args { |
||||
switch -- $k { |
||||
-a - -b - -c - -d - -e - -f - -g - -h - -i - -j - -k - -l - -m - -n - -o - -p - -q - -r - -s - -t - -u - -v - -w - -x - -y - -z { |
||||
switch -- $k { |
||||
-a - -b - -c { |
||||
lappend result "dfor-switcharm1-switcharm1-$k" |
||||
} |
||||
default { |
||||
lappend result "dfor-switcharm1-switchdefault-$k" |
||||
} |
||||
} |
||||
} |
||||
default { |
||||
switch -- $k { |
||||
-1 - -2 - -3 - -4 - -5 - -6 - -7 - -8 - -9 { |
||||
lappend result "dfor-switchdefault-switcharm1-$k" |
||||
} |
||||
default { |
||||
lappend result "dfor-switchdefault-switchdefault-$k" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return $result |
||||
} |
||||
|
||||
proc test2 {args} { |
||||
set result [list] |
||||
foreach {k v} $args { |
||||
switch -- $k { |
||||
-a - -b - -c - -d - -e - -f - -g - -h - -i - -j - -k - -l - -m - -n - -o - -p - -q - -r - -s - -t - -u - -v - -w - -x - -y - -z { |
||||
switch -- $k { |
||||
-a - -b - -c { |
||||
lappend result "dfor-switcharm1-switcharm1-$k" |
||||
} |
||||
default { |
||||
lappend result "dfor-switcharm1-switchdefault-$k" |
||||
} |
||||
} |
||||
} |
||||
default { |
||||
switch -- $k { |
||||
-1 - -2 - -3 - -4 - -5 - -6 - -7 - -8 - -9 { |
||||
lappend result "dfor-switchdefault-switcharm1-$k" |
||||
} |
||||
default { |
||||
lappend result "dfor-switchdefault-switchdefault-$k" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return $result |
||||
} |
||||
|
||||
proc test3 {args} { |
||||
set result [list] |
||||
for {set i 0} {$i < [llength $args]} {incr i} { |
||||
set k [lindex $args $i] |
||||
switch -- $k { |
||||
-a - -b - -c - -d - -e - -f - -g - -h - -i - -j - -k - -l - -m - -n - -o - -p - -q - -r - -s - -t - -u - -v - -w - -x - -y - -z { |
||||
switch -- $k { |
||||
-a - -b - -c { |
||||
lappend result "dfor-switcharm1-switcharm1-$k" |
||||
} |
||||
default { |
||||
lappend result "dfor-switcharm1-switchdefault-$k" |
||||
} |
||||
} |
||||
} |
||||
default { |
||||
switch -- $k { |
||||
-1 - -2 - -3 - -4 - -5 - -6 - -7 - -8 - -9 { |
||||
lappend result "dfor-switchdefault-switcharm1-$k" |
||||
} |
||||
default { |
||||
lappend result "dfor-switchdefault-switchdefault-$k" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return $result |
||||
} |
||||
|
||||
oo::class create c1 { |
||||
method test1 args [info body ::punk::experiment::test1] |
||||
method test2 args [info body ::punk::experiment::test2] |
||||
method test3 args [info body ::punk::experiment::test2] |
||||
} |
||||
c1 create obj1 |
||||
|
||||
|
||||
#*** !doctools |
||||
#[list_end] [comment {--- end definitions namespace punk::experiment ---}] |
||||
} |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
# Secondary API namespace |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
namespace eval punk::experiment::lib { |
||||
namespace export {[a-z]*} ;# Convention: export all lowercase |
||||
namespace path [namespace parent] |
||||
#*** !doctools |
||||
#[subsection {Namespace punk::experiment::lib}] |
||||
#[para] Secondary functions that are part of the API |
||||
#[list_begin definitions] |
||||
|
||||
#proc utility1 {p1 args} { |
||||
# #*** !doctools |
||||
# #[call lib::[fun utility1] [arg p1] [opt {?option value...?}]] |
||||
# #[para]Description of utility1 |
||||
# return 1 |
||||
#} |
||||
|
||||
|
||||
|
||||
#*** !doctools |
||||
#[list_end] [comment {--- end definitions namespace punk::experiment::lib ---}] |
||||
} |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
|
||||
|
||||
|
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
#*** !doctools |
||||
#[section Internal] |
||||
namespace eval punk::experiment::system { |
||||
#*** !doctools |
||||
#[subsection {Namespace punk::experiment::system}] |
||||
#[para] Internal functions that are not part of the API |
||||
|
||||
|
||||
|
||||
} |
||||
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ |
||||
## Ready |
||||
package provide punk::experiment [namespace eval punk::experiment { |
||||
variable pkg punk::experiment |
||||
variable version |
||||
set version 999999.0a1.0 |
||||
}] |
||||
return |
||||
|
||||
#*** !doctools |
||||
#[manpage_end] |
||||
|
@ -0,0 +1,3 @@
|
||||
0.1.0 |
||||
#First line must be a semantic version number |
||||
#all other lines are ignored. |
Loading…
Reference in new issue