@ -20,13 +20,436 @@
#package require punk
#package require punk
package require punk::args
package require punk::args
package require punk::char
package require punk::char
package require punk::ansi
package require punk::lib
package require punk::lib
catch {package require patternpunk}
catch {package require patternpunk}
package require overtype
package require overtype
package require term::ansi::code::macros ;#required for frame if old ansi g0 used - review - make package optional?
package require term::ansi::code::macros ;#required for frame if old ansi g0 used - review - make package optional?
package require textutil
package require textutil
namespace eval textblock {
namespace eval class {
if {[info commands [namespace current]::table] eq ""} {
#*** !doctools
#[subsection {Namespace textblock::class}]
#[para] class definitions
#[list_begin itemized] [comment {- textblock::class groupings -}]
# [item]
# [para] [emph {handler_classes}]
# [list_begin enumerated]
oo::class create [namespace current]::table {
#*** !doctools
#[enum] CLASS [class interface_caphandler.registry]
#[list_begin definitions]
# [para] [emph METHODS]
variable o_opts_table
variable o_columndefs
variable o_columndata
variable o_rowdefs
variable o_rowstates
variable o_opts_table_defaults
constructor {args} {
#*** !doctools
#[call class::table [method constructor] [arg args]]
set o_opts_table_defaults [dict create\
-title ""\
-frametype "unicode_box"\
-show_header ""\
]
if {[llength $args] == 1} {
set args [list -title [lindex $args 0]]
}
if {[llength $args] %2 !=0} {
error "[namespace current]::table constructor - unexpected argument count. Require single value being title, or name value pairs"
}
dict for {k v} $args {
if {$k ni [dict keys $o_opts_table_defaults]} {
error "[namespace current]::table unrecognised option '$k'. Known values [dict keys $o_opts_table_defaults]"
}
}
set o_opts_table [dict merge $o_opts_table_defaults $args]
set o_columndefs [dict create]
set o_columndata [dict create]
set o_rowdefs [dict create] ;#user requested row data e.g -minheight -maxheight
set o_rowstates [dict create] ;#actual row data such as -minheight and -maxheight detected from supplied row data
}
method configure args {
if {![llength $args]} {
return $o_opts_table
} else {
if {[llength $args] %2 != 0} {
error "[namespace current]::table configure - unexpected argument count. Require name value pairs"
}
dict for {k v} $args {
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 o_opts_table [dict merge $o_opts_table $args]
}
}
method add_column {args} {
#*** !doctools
#[call class::table [method add_column] [arg args]]
set defaults [dict create\
-header ""\
-footer ""\
-style ""\
-minwidth ""\
-maxwidth ""\
]
if {[llength $args] %2 != 0} {
error "[namespace current]::table::add_column unexpected argument count. Require name value pairs. Known options: [dict keys $defaults]"
}
dict for {k v} $args {
if {$k ni [dict keys $defaults]} {
error "[namespace current]::table::add_column unknown option '$k'. Known options: [dict keys $defaults]"
}
}
set opts [dict merge $defaults $args]
set colcount [dict size $o_columndefs]
set h [dict get $opts -header]
#todo - multiline header
if {[string is integer -strict $h]} {
error "table::add_column -header cannot be an integer"
}
set coldef [dict create -header $h -style [dict get $opts -style] -minwidth [dict get $opts -minwidth] -maxwidth [dict get $opts -maxwidth]]
dict set o_columndefs $colcount $coldef
return $colcount
}
method add_row {valuelist args} {
#*** !doctools
#[call class::table [method add_row] [arg args]]
if {[llength $valuelist] > [dict size $o_columndefs]} {
error "too many row values - only [dict size $o_columndefs] defined"
}
set defaults [dict create\
-minheight 1\
-maxheight ""\
]
if {[llength $args] %2 !=0} {
error "[namespace current]::table::add_row unexpected argument count. Require name value pairs. Known options: [dict keys $defaults]"
}
set opts [dict merge $defaults $args]
set opt_minh [dict get $opts -minheight]
set opt_maxh [dict get $opts -maxheight]
if {![string is integer $opt_minh] || ($opt_maxh ne "" && ![string is integer -strict $opt_maxh])} {
error "[namespace current]::table::add_row error -minheight '$opt_minh' and -maxheight '$opt_maxh' must be integers greater than or equal to 1"
}
if {$opt_minh < 1 || ($opt_maxh ne "" && $opt_maxh < 1)} {
error "[namespace current]::table::add_row error -minheight '$opt_minh' and -maxheight '$opt_maxh' must both be 1 or greater"
}
if {$opt_maxh ne "" && $opt_maxh < $opt_minh} {
error "[namespace current]::table::add_row error -maxheight '$opt_maxh' must greater than -minheight '$opt_minh'"
}
set rowcount [dict size $o_rowdefs]
dict set o_rowdefs $rowcount -minheight $opt_minh
dict set o_rowdefs $rowcount -maxheight $opt_maxh
dict set o_rowstates $rowcount -minheight $opt_minh
set c 0
set max_height_seen 1
foreach v $valuelist {
dict lappend o_columndata $c $v
set valheight [textblock::height $v]
if {$valheight > $max_height_seen} {
set max_height_seen $valheight
}
incr c
}
if {$opt_maxh ne ""} {
dict set o_rowstates $rowcount -maxheight [expr {min($opt_maxh,$max_height_seen)}]
} else {
dict set o_rowstates $rowcount -maxheight $max_height_seen
}
}
method Get_columns_by_name {namematch_list} {
}
#specify range with x..y
method Get_columns_by_indices {index_list} {
foreach spec $index_list {
if {[string is integer -strict $c]} {
set colidx $c
} else {
dict for {colidx coldef} $o_columndefs {
#if {[string match x x]} {}
}
}
}
}
method get_column_by_index {i args} {
set defaults [dict create\
-positiontype "inner"\
]
set valid_positiontypes [list left inner right solo]
dict for {k v} $args {
if {$k ni [dict keys $defaults]} {
error "[namespace::current]::table::get_column_by_index error invalid option '$k'. Known options [dict keys $defaults]"
}
}
set opts [dict merge $defaults $args]
set opt_posn [dict get $opts -positiontype]
if {$opt_posn ni $valid_positiontypes} {
error "[namespace::current]::table::get_column_by_index error invalid value '$opt_posn' for -positiontype. Valid values $valid_positiontypes"
}
set columninfo [my get_column_cells_by_index $i]
set header [dict get $columninfo header]
set cells [dict get $columninfo cells]
set columninfo [my get_column_cells_by_index $i]
set topt_show_header [dict get $o_opts_table -show_header]
if {$topt_show_header eq ""} {
set allheaders ""
set all_cols [dict keys $o_columndefs]
foreach c $all_cols {
append allheaders [dict get $o_columndefs $c -header]
}
if {$allheaders eq ""} {
set do_show_header 0
} else {
set do_show_header 1
}
} else {
set do_show_header $topt_show_header
}
set output ""
set boxlimits ""
set joins ""
set header_boxlimits [list]
set header_joins [list]
switch -- $opt_posn {
left {
set header_boxlimits {hl tlc blc vll}
set header_joins {down-light}
set boxlimits {hlb blc vll}
set boxlimits_headerless {hl blc vll tlc}
set joins {down}
}
inner {
set header_boxlimits {hl tlc blc vll}
set header_joins {left down-light}
set boxlimits {hlb blc vll}
set boxlimits_headerless {hl blc vll tlc}
set joins {down left}
}
right {
set header_boxlimits {hl tlc blc vl trc brc}
set header_joins {left down-light}
set boxlimits {hlb blc vl brc}
set boxlimits_headerless {hl blc vl brc tlc trc}
set joins {down left}
}
solo {
set header_boxlimits {hl tlc blc vl trc brc}
set header_joins {down-light}
set boxlimits {hlb blc vl brc}
set boxlimits_headerless {hl blc vl brc tlc trc}
set joins {down}
}
}
if {$do_show_header} {
append output [textblock::frame -type unicode_box_heavy -boxlimits $header_boxlimits -joins $header_joins $header]\n
}
set r 0
set rmax [expr {[llength $cells]-1}]
foreach c $cells {
#todo - joinleft,joinright,joindown based on opts in args
#append output [textblock::frame -boxlimits {vll blc hlb} $c]\n
if {$r == 0} {
if {$r == $rmax} {
set joins [lremove $joins [lsearch $joins down]]
}
if {$do_show_header} {
append output [textblock::frame -boxlimits $boxlimits -joins $joins $c]\n
} else {
append output [textblock::frame -boxlimits $boxlimits_headerless -joins $joins $c]\n
}
} else {
if {$r == $rmax} {
set joins [lremove $joins [lsearch $joins down]]
}
append output [textblock::frame -boxlimits $boxlimits -joins $joins $c]\n
}
incr r
}
return [string trimright $output \n]
}
method get_column_cells_by_index {i} {
set cidx [lindex [dict keys $o_columndefs] $i]
if {$cidx eq ""} {
set range ""
if {[dict size $o_columndefs] > 0} {
set range "0..[expr {[dict size $o_columndefs] -1}]
}
error "table::get_column_by_index no such index $i valid range is $range"
}
set cdef [dict get $o_columndefs $cidx]
set t [dict get $cdef -header] ;#may be empty string
set items [dict get $o_columndata $cidx]
set defminw [dict get $cdef -minwidth]
set defmaxw [dict get $cdef -maxwidth]
set defstyle [dict get $cdef -style]
set stylecodes ""
if {$defstyle ne ""} {
set stylecodes [punk::ansi::a+ {*}$defstyle]
}
if {"$defminw$defmaxw" ne "" && $defminw eq $defmaxw} {
#an exact width is defined for the column - no need to look at data width
set colwidth $defminw
} else {
#todo - predetermine if any items in column contain newlines and are truncated vertically due to o_rowdefs configuration.
#if so - a truncated line shouldn't be included in our width calculation
set widest [tcl::mathfunc::max {*}[lmap v [concat [list $t] $items] {textblock::width $v}]]
if {$defminw eq ""} {
if {$defmaxw eq ""} {
set colwidth $widest
} else {
set colwidth [expr {min(1,$defmaxw,$widest)}]
}
} else {
if {$defmaxw eq ""} {
set colwidth [expr {max($defminw,$widest)}]
} else {
if {$widest < $defminw} {
set colwidth $defminw
} else {
if {$widest > $defmaxw} {
set colwidth $defmaxw
} else {
set colwidth [expr {max($defminw,$widest)}]
}
}
}
}
}
set cell_line_blank [string repeat " " $colwidth]
set output [dict create]
if {$t ne ""} {
dict set output header [overtype::left $cell_line_blank $t]
} else {
dict set output header $cell_line_blank
}
set r 0
foreach cval $items {
set maxdataheight [dict get $o_rowstates $r -maxheight]
set rowdefminh [dict get $o_rowdefs $r -minheight]
set rowdefmaxh [dict get $o_rowdefs $r -maxheight]
if {"$rowdefminh$rowdefmaxh" ne "" && $rowdefminh eq $rowdefmaxh} {
#an exact height is defined for the row
set rowh $rowdefminh
} else {
if {$rowdefminh eq ""} {
if {$rowdefmaxh eq ""} {
#both defs empty
set rowh $maxdataheight
} else {
set rowh [expr {min(1,$rowdefmaxh,$maxdataheight)}]
}
} else {
if {$rowdefmaxh eq ""} {
set rowh [expr {max($rowdefminh,$maxdataheight)}]
} else {
if {$maxdataheight < $rowdefminh} {
set rowh $rowdefminh
} else {
set rowh [expr {max($rowdefminh,$maxdataheight)}]
}
}
}
}
if {$stylecodes ne ""} {
set cval $stylecodes$cval
}
set cell_lines [lrepeat $rowh $cell_line_blank]
set cell_blank [join $cell_lines \n]
set cval_lines [split $cval \n]
set cval_lines [lrange $cval_lines 0 $rowh-1]
set cval_block [join $cval_lines \n]
#TODO! fix overtype library
set cell [overtype::left -experimental test_mode $cell_blank $cval_block]
dict lappend output cells $cell
incr r
}
return $output
}
method debug {} {
puts stdout "rowdefs: $o_rowdefs"
puts stdout "rowstates: $o_rowstates"
puts stdout "columndefs: $o_columndefs"
}
method print {args} {
if {![llength $args]} {
set cols [dict keys $o_columndata]
} else {
set cols [list]
foreach colspec $args {
set allcols [dict keys $o_columndata]
if {[string first .. $colspec] >=0} {
set parts [punk::ansi::ta::_perlish_split {\.\.} $colspec]
if {[llength $parts] != 3} {
error "[namespace::current]::table error invalid print specification '$colspec'"
}
lassign $parts from _dd to
if {$from eq ""} {
set from 0
}
if {$to eq ""} {
set to end
}
set indices [lrange $allcols $from $to]
lappend cols {*}$indices
} else {
set c [lindex $allcols $colspec]
if {$c ne ""} {
lappend cols $c
}
}
}
}
set blocks [list]
set colposn 0
set numposns [llength $cols]
foreach c $cols {
set flags [list]
if {$colposn == 0 && $colposn == $numposns-1} {
set flags [list -positiontype solo]
} elseif {$colposn == 0} {
set flags [list -positiontype left]
} elseif {$colposn == $numposns-1} {
set flags [list -positiontype right]
} else {
set flags [list -positiontype inner]
}
lappend blocks [my get_column_by_index $c {*}$flags]
incr colposn
}
if {[llength $blocks]} {
return [textblock::join {*}$blocks]
} else {
return "No columns matched"
}
}
#*** !doctools
#[list_end]
}
#*** !doctools
# [list_end] [comment {- end enumeration provider_classes }]
#[list_end] [comment {- end itemized list textblock::class groupings -}]
}
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#
#
#Note: A textblock does not necessarily have lines the same length - either in number of characters or print-width
#Note: A textblock does not necessarily have lines the same length - either in number of characters or print-width
@ -314,6 +737,9 @@ namespace eval textblock {
} else {
} else {
set blocks $args
set blocks $args
}
}
if {![llength $blocks]} {
return
}
set idx 0
set idx 0
set fordata [list]
set fordata [list]
@ -405,13 +831,15 @@ namespace eval textblock {
set contents [lindex $args end]
set contents [lindex $args end]
set arglist [lrange $args 0 end-1]
set arglist [lrange $args 0 end-1]
if {[llength $arglist] % 2 != 0} {
if {[llength $arglist] % 2 != 0} {
error "Usage frame ?-type unicode|altg|ascii|<dict hl (c) vl (c) tlc (c) trc (c) blc (c) brc (c)>? ?-title <ansitext>? ?-subtitle <ansitext>? ?-width <columns>? ?-ansiborder <ansi_sgr>? <contents>"
error "Usage frame ?-type unicode|altg|ascii|<dict hl (c) vl (c) tlc (c) trc (c) blc (c) brc (c)>? ?-title <ansitext>? ?-subtitle <ansitext>? ?-width <columns>? ?-ansiborder <ansi_sgr>? ?-boxlimits hl|hlt|hlb|vl|vll|vlr|tlc|blc|brc? ?-joins left|right|up|down? <contents>"
}
}
#todo args -justify left|centre|right (center)
#todo args -justify left|centre|right (center)
set defaults [dict create\
set defaults [dict create\
-etabs 0\
-etabs 0\
-type unicode_box\
-type unicode_box\
-boxlimits [list hl vl tlc blc trc brc]\
-joins [list]\
-title ""\
-title ""\
-subtitle ""\
-subtitle ""\
-width ""\
-width ""\
@ -423,7 +851,7 @@ namespace eval textblock {
set opts [dict merge $defaults $arglist]
set opts [dict merge $defaults $arglist]
foreach {k v} $opts {
foreach {k v} $opts {
switch -- $k {
switch -- $k {
-etabs - -type - -title - -subtitle - -width - -ansiborder - -ansibase - -align - -ellipsis {}
-etabs - -type - -boxlimits - -joins - - title - -subtitle - -width - -ansiborder - -ansibase - -align - -ellipsis {}
default {
default {
error "frame option '$k' not understood. Valid options are [dict keys $defaults]"
error "frame option '$k' not understood. Valid options are [dict keys $defaults]"
}
}
@ -432,6 +860,8 @@ namespace eval textblock {
# -- --- --- --- --- ---
# -- --- --- --- --- ---
set opt_etabs [dict get $opts -etabs]
set opt_etabs [dict get $opts -etabs]
set opt_type [dict get $opts -type]
set opt_type [dict get $opts -type]
set opt_boxlimits [dict get $opts -boxlimits]
set opt_joins [dict get $opts -joins]
set known_types [list unicode_box unicode_box_heavy unicode_arc unicode_double ascii altg]
set known_types [list unicode_box unicode_box_heavy unicode_arc unicode_double ascii altg]
set default_custom [dict create hl " " vl " " tlc " " trc " " blc " " brc " "]
set default_custom [dict create hl " " vl " " tlc " " trc " " blc " " brc " "]
set custom_keys [list hl hlt hlb vl vll vlr tlc trc blc brc]
set custom_keys [list hl hlt hlb vl vll vlr tlc trc blc brc]
@ -457,6 +887,54 @@ namespace eval textblock {
}
}
set custom_frame [dict merge $default_custom $opt_type]
set custom_frame [dict merge $default_custom $opt_type]
}
}
set is_boxlimits_ok 1
foreach v $opt_boxlimits {
switch -- $v {
hl - hlt - hlb - vl - vll - vlr - tlc - trc - blc - brc {}
default {
#k not in custom_keys
set is_boxlimits_ok 0
break
}
}
}
if {!$is_boxlimits_ok} {
error "frame option -boxlimits '$opt_boxlimits' must contain only values from the set: hl,hlt,hlb,vl,vll,vlr,tlc,trc,blc,brc"
}
set is_joins_ok 1
foreach v $opt_joins {
switch -- $v {
left - left-light - right - right-light - up - up-light - down - down-light {}
default {
set is_joins_ok 0
break
}
}
}
if {!$is_joins_ok} {
error "frame option -joins '$opt_joins' must contain only values from the set: left,right,up,down"
}
#sorted order down left right up
#1 x choose 4
#4 x choose 3
#6 x choose 2
#4 x choose 1
#15 combos
set join_directions [list]
#modifiers - light,heavy (double?) - seem to be some required glyphs missing from unicode
#e.g down-light, up-heavy
set join_modifiers [dict create left "" down "" right "" up ""]
foreach jt $opt_joins {
lassign [split $jt -] direction modifier
if {$modifier ne ""} {
dict set join_modifiers $direction $modifier
}
lappend join_directions $direction
}
set join_directions [lsort -unique $join_directions]
set do_joins [::join $join_directions _]
# -- --- --- --- --- ---
# -- --- --- --- --- ---
set opt_title [dict get $opts -title]
set opt_title [dict get $opts -title]
set opt_subtitle [dict get $opts -subtitle]
set opt_subtitle [dict get $opts -subtitle]
@ -511,6 +989,9 @@ namespace eval textblock {
set underlayline [string repeat " " $contentwidth]
set underlayline [string repeat " " $contentwidth]
set underlay [::join [lrepeat $linecount $underlayline] \n]
set underlay [::join [lrepeat $linecount $underlayline] \n]
set vll_width 1 ;#default for all except custom (printing width)
set vlr_width 1
switch -- $opt_type {
switch -- $opt_type {
"altg" {
"altg" {
#old style ansi escape sequences with alternate graphics page G0
#old style ansi escape sequences with alternate graphics page G0
@ -554,8 +1035,122 @@ namespace eval textblock {
set trc [punk::char::charshort boxd_ldl]
set trc [punk::char::charshort boxd_ldl]
set blc [punk::char::charshort boxd_lur]
set blc [punk::char::charshort boxd_lur]
set brc [punk::char::charshort boxd_lul]
set brc [punk::char::charshort boxd_lul]
#15 combos
#sort order: down left right up
#ltj,rtj,ttj,btj e.g left T junction etc.
#Look at from the perspective of a frame/table outline with a clean border and arms pointing inwards
switch -- $do_joins {
down {
#1
switch -- [dict get $join_modifiers down] {
heavy {
set blc [punk::char::charshort boxd_dhrul] ;#down light and right up heavy (ltj)
}
default {
set blc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
}
}
set brc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
}
left {
#2
set tlc [punk::char::charshort boxd_ldhz] ;#T shape (ttj) - joinleft
set blc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
}
right {
#3
set trc [punk::char::charshort boxd_ldhz] ;#T shape (ttj)
set brc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
}
up {
#4
set tlc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set trc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
}
down_left {
#5
set blc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set tlc [punk::char::charshort boxd_ldhz] ;#T shape (ttj)
set brc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
}
down_right {
#6
set blc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set trc [punk::char::charshort boxd_ldhz] ;#T shape (ttj)
set brc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
}
down_up {
#7
set blc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set brc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
set tlc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set trc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
}
left_right {
#8
#from 2
set tlc [punk::char::charshort boxd_ldhz] ;#T shape (ttj) - joinleft
set blc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
#from3
set trc [punk::char::charshort boxd_ldhz] ;#T shape (ttj)
set brc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
}
left_up {
#9
set tlc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set trc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
set blc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
}
right_up {
#10
set tlc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set trc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set brc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
}
down_left_right {
#11
set blc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set brc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set trc [punk::char::charshort boxd_ldhz] ;#T shape (ttj)
set tlc [punk::char::charshort boxd_ldhz] ;#T shape (ttj)
}
down_left_up {
#12
set tlc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set blc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set trc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
set brc [punk::char::charshort boxd_lvl] ;#light vertical and right (rtj)
}
down_right_up {
#13
set tlc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set blc [punk::char::charshort boxd_lvr] ;#light vertical and right (ltj)
set trc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set brc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
}
left_right_up {
#14
set tlc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set trc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set blc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
set brc [punk::char::charshort boxd_luhz] ;#upside down T shape (btj)
}
down_left_right_up {
#15
set tlc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set blc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set trc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
set brc [punk::char::charshort boxd_lvhz] ;#light vertical and horizontal (fwj)
}
}
set tbar [string repeat $hl $contentwidth]
set tbar [string repeat $hl $contentwidth]
set bbar $tbar
set bbar $tbar
#four way junction (cd::fwj) (punk::ansi::g0 n) (punk::char::charshort lvhz) (+)
}
}
"unicode_box_heavy" {
"unicode_box_heavy" {
#unicode box drawing set
#unicode box drawing set
@ -569,6 +1164,132 @@ namespace eval textblock {
set trc [punk::char::charshort boxd_hdl]
set trc [punk::char::charshort boxd_hdl]
set blc [punk::char::charshort boxd_hur]
set blc [punk::char::charshort boxd_hur]
set brc [punk::char::charshort boxd_hul]
set brc [punk::char::charshort boxd_hul]
switch -- $do_joins {
down {
#1
switch -- [dict get $join_modifiers down] {
light {
set blc [punk::char::charshort boxd_dlruh] ;#down light and right up heavy (ltj)
set brc [punk::char::charshort boxd_dlluh] ;#down light and left up heavy (rtj)
}
default {
set blc [punk::char::charshort boxd_hvr] ;# (ltj)
set brc [punk::char::charshort boxd_hvl] ;# (rtj)
}
}
}
left {
#2
set tlc [punk::char::charshort boxd_ldhz] ;# (ttj)
set blc [punk::char::charshort boxd_luhz] ;# (btj)
}
right {
#3
set trc [punk::char::charshort boxd_hdhz] ;#T shape (ttj)
set brc [punk::char::charshort boxd_huhz] ;# (btj)
}
up {
#4
set tlc [punk::char::charshort boxd_hvr] ;# (ltj)
set trc [punk::char::charshort boxd_hvl] ;# (rtj)
}
down_left {
#5
switch -- d-[dict get $join_modifiers down]_l-[dict get $join_modifiers left] {
d-light_l- {
set blc [punk::char::charshort boxd_dluhzh] ;#down light and up horizontal heavy (fwj)
set brc [punk::char::charshort boxd_dlluh] ;#down light and left up heavy (rtj)
}
d-_l-light {
set blc [punk::char::charshort boxd_llrvh] ;# left light and right Vertical Heavy (fwj)
set brc [punk::char::charshort boxd_vhll] ;#vertical heavy and left light (rtj)
}
d-light_l-light {
set blc [punk::char::charshort boxd_ruhldl] ;#right up heavy and left down light (fwj)
set brc [punk::char::charshort boxd_uhldl] ;#up heavy and left down light (rtj)
}
default {
set blc [punk::char::charshort boxd_hvhz] ;# (fwj)
set brc [punk::char::charshort boxd_hvl] ;# (rtj)
}
}
set tlc [punk::char::charshort boxd_hdhz] ;# (ttj)
}
down_right {
#6
set blc [punk::char::charshort boxd_hvr] ;# (ltj)
set trc [punk::char::charshort boxd_hdhz] ;# (ttj)
set brc [punk::char::charshort boxd_hvhz] ;# (fwj)
}
down_up {
#7
set blc [punk::char::charshort boxd_hvr] ;# (ltj)
set brc [punk::char::charshort boxd_hvl] ;# (rtj)
set tlc [punk::char::charshort boxd_hvr] ;# (ltj)
set trc [punk::char::charshort boxd_hvl] ;# (rtj)
}
left_right {
#8
#from 2
set tlc [punk::char::charshort boxd_hdhz] ;# (ttj)
set blc [punk::char::charshort boxd_huhz] ;# (btj)
#from3
set trc [punk::char::charshort boxd_hdhz] ;# (ttj)
set brc [punk::char::charshort boxd_huhz] ;# (btj)
}
left_up {
#9
set tlc [punk::char::charshort boxd_hvhz] ;# (fwj)
set trc [punk::char::charshort boxd_hvl] ;# (rtj)
set blc [punk::char::charshort boxd_huhz] ;# (btj)
}
right_up {
#10
set tlc [punk::char::charshort boxd_hvr] ;# (ltj)
set trc [punk::char::charshort boxd_hvhz] ;# (fwj)
set brc [punk::char::charshort boxd_huhz] ;# (btj)
}
down_left_right {
#11
set blc [punk::char::charshort boxd_hvhz] ;# (fwj)
set brc [punk::char::charshort boxd_hvhz] ;# (fwj)
set trc [punk::char::charshort boxd_hdhz] ;# (ttj)
set tlc [punk::char::charshort boxd_hdhz] ;# (ttj)
}
down_left_up {
#12
set tlc [punk::char::charshort boxd_hvhz] ;# (fwj)
set blc [punk::char::charshort boxd_hvhz] ;# (fwj)
set trc [punk::char::charshort boxd_hvl] ;# (rtj)
set brc [punk::char::charshort boxd_hvl] ;# (rtj)
}
down_right_up {
#13
set tlc [punk::char::charshort boxd_hvr] ;# (ltj)
set blc [punk::char::charshort boxd_hvr] ;# (ltj)
set trc [punk::char::charshort boxd_hvhz] ;# (fwj)
set brc [punk::char::charshort boxd_hvhz] ;# (fwj)
}
left_right_up {
#14
set tlc [punk::char::charshort boxd_hvhz] ;# (fwj)
set trc [punk::char::charshort boxd_hvhz] ;# (fwj)
set blc [punk::char::charshort boxd_huhz] ;# (btj)
set brc [punk::char::charshort boxd_huhz] ;# (btj)
}
down_left_right_up {
#15
set tlc [punk::char::charshort boxd_hvhz] ;# (fwj)
set blc [punk::char::charshort boxd_hvhz] ;# (fwj)
set trc [punk::char::charshort boxd_hvhz] ;# (fwj)
set brc [punk::char::charshort boxd_hvhz] ;# (fwj)
}
}
set tbar [string repeat $hl $contentwidth]
set tbar [string repeat $hl $contentwidth]
set bbar $tbar
set bbar $tbar
}
}
@ -673,6 +1394,51 @@ namespace eval textblock {
}
}
}
}
}
}
set leftborder 0
set rightborder 0
set topborder 0
set bottomborder 0
# hl - hlt - hlb - vl - vll - vlr - tlc - trc - blc - brc {}
foreach lim $opt_boxlimits {
switch -- $lim {
hl {
set topborder 1
set bottomborder 1
}
hlt {
set topborder 1
}
hlb {
set bottomborder 1
}
vl {
set leftborder 1
set rightborder 1
}
vll {
set leftborder 1
}
vlr {
set rightborder 1
}
tlc {
set topborder 1
set leftborder 1
}
trc {
set topborder 1
set rightborder 1
}
blc {
set bottomborder 1
set leftborder 1
}
brc {
set bottomborder 1
set rightborder 1
}
}
}
#keep lhs/rhs separate? can we do vertical text on sidebars?
#keep lhs/rhs separate? can we do vertical text on sidebars?
set lhs [string repeat $vll\n $linecount]
set lhs [string repeat $vll\n $linecount]
set lhs [string range $lhs 0 end-1]
set lhs [string range $lhs 0 end-1]
@ -689,6 +1455,44 @@ namespace eval textblock {
set rhs $opt_ansiborder$rhs$rst
set rhs $opt_ansiborder$rhs$rst
}
}
#boxlimits used for partial borders in table generation
if {"vll" ni $opt_boxlimits && "vl" ni $opt_boxlimits} {
set blank_vll [string repeat " " $vll_width]
set lhs [string repeat $blank_vll\n $linecount]
set lhs [string range $lhs 0 end-1]
}
if {"vlr" ni $opt_boxlimits && "vl" ni $opt_boxlimits} {
set blank_vlr [string repeat " " $vlr_width]
set rhs [string repeat $blank_vlr\n $linecount]
set rhs [string range $rhs 0 end-1]
}
if {"hl" ni $opt_boxlimits && "hlt" ni $opt_boxlimits} {
set bar_width [punk::ansi::printing_length $tbar]
set tbar [string repeat " " $bar_width]
}
if {"tlc" ni $opt_boxlimits} {
set tlc_width [punk::ansi::printing_length $tlc]
set tlc [string repeat " " $tlc_width]
}
if {"trc" ni $opt_boxlimits} {
set trc_width [punk::ansi::printing_length $trc]
set trc [string repeat " " $trc_width]
}
if {"hl" ni $opt_boxlimits && "hlb" ni $opt_boxlimits} {
set bar_width [punk::ansi::printing_length $bbar]
set bbar [string repeat " " $bar_width]
}
if {"blc" ni $opt_boxlimits} {
set blc_width [punk::ansi::printing_length $blc]
set blc [string repeat " " $blc_width]
}
if {"brc" ni $opt_boxlimits} {
set brc_width [punk::ansi::printing_length $brc]
set brc [string repeat " " $brc_width]
}
if {$opt_title ne ""} {
if {$opt_title ne ""} {
set topbar [overtype::centre -overflow 0 -exposed1 " " -exposed2 " " -ellipsis 1 -bias left $tbar $opt_title] ;#overtype supports gx0 on/off
set topbar [overtype::centre -overflow 0 -exposed1 " " -exposed2 " " -ellipsis 1 -bias left $tbar $opt_title] ;#overtype supports gx0 on/off
} else {
} else {
@ -704,11 +1508,56 @@ namespace eval textblock {
} else {
} else {
set rstbase [a]$opt_ansibase
set rstbase [a]$opt_ansibase
}
}
append fs $tlc$topbar$trc\n
if {$opt_title ne ""} {
#title overrides -boxlimits for topborder
set topborder 1
}
if {$topborder} {
if {$leftborder && $rightborder} {
append fs $tlc$topbar$trc\n
} else {
if {$leftborder} {
append fs $tlc$topbar\n
} elseif {$rightborder} {
append fs $topbar$trc\n
} else {
append fs $topbar\n
}
}
}
set inner [overtype::$opt_align -ellipsis $opt_ellipsis $opt_ansibase$underlay$rstbase $opt_ansibase$contents$rstbase]
set inner [overtype::$opt_align -ellipsis $opt_ellipsis $opt_ansibase$underlay$rstbase $opt_ansibase$contents$rstbase]
set body [textblock::join -- $lhs $opt_ansibase$inner$rstbase $rhs]
if {$leftborder && $rightborder} {
set bodyparts [list $lhs $opt_ansibase$inner$rstbase $rhs]
} else {
if {$leftborder} {
set bodyparts [list $lhs $opt_ansibase$inner$rstbase]
} elseif {$rightborder} {
set bodyparts [list $opt_ansibase$inner$rstbase $rhs]
} else {
set bodyparts [list $opt_ansibase$inner$rstbase]
}
}
set body [textblock::join -- {*}$bodyparts]
#set body [textblock::join -- $lhs $opt_ansibase$inner$rstbase $rhs]
append fs $body
append fs $body
append fs \n $blc$bottombar$brc
if {$opt_subtitle ne ""} {
#subtitle overrides boxlimits for bottomborder
set bottomborder 1
}
if {$bottomborder} {
if {$leftborder && $rightborder} {
append fs \n$blc$bottombar$brc
} else {
if {$leftborder} {
append fs \n$blc$bottombar
} elseif {$rightborder} {
append fs \n$bottombar$brc
} else {
append fs \n$bottombar
}
}
}
return $fs
return $fs