Browse Source

punk::ansi::example + ansi code_merge fixes

master
Julian Noble 8 months ago
parent
commit
cc016efdb0
  1. 73
      src/modules/punk/ansi-999999.0a1.0.tm
  2. 47
      src/testansi/bot.ans
  3. 52
      src/vendormodules/overtype-1.6.0.tm

73
src/modules/punk/ansi-999999.0a1.0.tm

@ -101,13 +101,11 @@ namespace eval punk::ansi::class {
} }
set cksum "not-done" set cksum "not-done"
if {$dimensions ne $o_render_dimensions || $o_rendered_what ne [set cksum [$o_ansistringobj checksum]]} { if {$dimensions ne $o_render_dimensions || $o_rendered_what ne [set cksum [$o_ansistringobj checksum]]} {
set b [textblock::block $w $h " "]
#some ansi layout/art relies on wrapping at the width-dimension to display properly #some ansi layout/art relies on wrapping at the width-dimension to display properly
#this includes cursor movements ie right arrow can move cursor to columns in lines below #this includes cursor movements ie right arrow can move cursor to columns in lines below
#overflow is a different concept - perhaps not particularly congruent with the idea of the textblock as a mini terminal emulator. #overflow is a different concept - perhaps not particularly congruent with the idea of the textblock as a mini terminal emulator.
#overflow effectively auto-expands the block(terminal?) width #overflow effectively auto-expands the block(terminal?) width
#overflow and wrap both being true won't make sense unless we implement a max_overflow concept #overflow and wrap both being true won't make sense unless we implement a max_overflow concept
#set o_rendered [overtype::left -overflow 0 -wrap 1 -appendlines 1 $b [$o_ansistringobj GET]]
set o_rendered [overtype::left -overflow 0 -wrap 1 -width $w -appendlines 1 "" [$o_ansistringobj get]] set o_rendered [overtype::left -overflow 0 -wrap 1 -width $w -appendlines 1 "" [$o_ansistringobj get]]
if {$cksum eq "not-done"} { if {$cksum eq "not-done"} {
#if dimensions changed - the checksum won't have been done #if dimensions changed - the checksum won't have been done
@ -135,6 +133,7 @@ namespace eval punk::ansi::class {
return $rendered return $rendered
} }
method render_to_input_line {x {minuschar 0}} { method render_to_input_line {x {minuschar 0}} {
package require textblock
set lfvis [ansistring VIEW -lf 1 \n] set lfvis [ansistring VIEW -lf 1 \n]
set maplf [list \n "[a+ green bold reverse]${lfvis}[a]\n"] ;#a mapping to highlight newlines set maplf [list \n "[a+ green bold reverse]${lfvis}[a]\n"] ;#a mapping to highlight newlines
@ -383,6 +382,64 @@ namespace eval punk::ansi {
} $text completeChars } $text completeChars
return $completeChars return $completeChars
} }
proc example {} {
#todo - review dependency on punk::repo ?
package require textblock
package require punk::repo
package require punk::console
set fnames [list belinda.ans bot.ans flower.ans fish.ans]
set base [punk::repo::find_project]
set ansibase [file join $base src/testansi]
if {![file exists $ansibase]} {
puts stderr "Missing testansi folder at $base/src/testansi"
puts stderr "Ensure ansi test files exist: $fnames"
#error "punk::ansi::example Cannot find example files"
}
set missingbase [a+ yellow][textblock::block 80 23 ?][a]
set pics [list]
foreach f $fnames {
if {![file exists $ansibase/$f]} {
set p [overtype::left $missingbase "[a+ red bold]\nMissing file\n$ansibase/$f[a]"]
lappend pics [dict create filename $f pic $p status missing]
} else {
set img [join [lines_as_list -line trimline -block trimtail [ansicat $ansibase/$f]] \n]
lappend pics [dict create filename $f pic $img status ok]
}
}
set termsize [punk::console:::get_size]
set margin 4
set freewidth [expr {[dict get $termsize columns]-$margin}]
set per_row [expr {$freewidth / 80}]
set rowlist [list]
set row [list]
set i 1
foreach picinfo $pics {
set subtitle ""
if {[dict get $picinfo status] ne "ok"} {
set subtitle [dict get $picinfo status]
}
set title [dict get $picinfo filename]
lappend row [textblock::frame -subtitle $subtitle -title $title [dict get $picinfo pic]]
if {$i % $per_row == 0} {
lappend rowlist $row
set row [list]
} elseif {$i == [llength $pics]} {
lappend rowlist $row
}
incr i
}
set result ""
foreach r $rowlist {
append result [textblock::join {*}$r] \n
}
return $result
}
#control strings #control strings
#https://www.ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf #https://www.ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf
#<excerpt> #<excerpt>
@ -1755,12 +1812,12 @@ namespace eval punk::ansi {
switch -- [lindex $plist $i+1] { switch -- [lindex $plist $i+1] {
5 { 5 {
#256 - 1 more param #256 - 1 more param
dict set codestate fg "5\;[lindex $plist $i+2]" dict set codestate fg "38\;5\;[lindex $plist $i+2]"
incr i 2 incr i 2
} }
2 { 2 {
#rgb #rgb
dict set codestate fg "2\;[lindex $plist $i+2]\;[lindex $plist $i+3]\;[lindex $plist $i+4]" dict set codestate fg "38\;2\;[lindex $plist $i+2]\;[lindex $plist $i+3]\;[lindex $plist $i+4]"
incr i 4 incr i 4
} }
} }
@ -1783,12 +1840,12 @@ namespace eval punk::ansi {
switch -- [lindex $plist $i+1] { switch -- [lindex $plist $i+1] {
5 { 5 {
#256 - 1 more param #256 - 1 more param
dict set codestate bg "5\;[lindex $plist $i+2]" dict set codestate bg "48\;5\;[lindex $plist $i+2]"
incr i 2 incr i 2
} }
2 { 2 {
#rgb #rgb
dict set codestate bg "2\;[lindex $plist $i+2]\;[lindex $plist $i+3]\;[lindex $plist $i+4]" dict set codestate bg "48\;2\;[lindex $plist $i+2]\;[lindex $plist $i+3]\;[lindex $plist $i+4]"
incr i 4 incr i 4
} }
} }
@ -1821,12 +1878,12 @@ namespace eval punk::ansi {
switch -- [lindex $plist $i+1] { switch -- [lindex $plist $i+1] {
5 { 5 {
#256 - 1 more param #256 - 1 more param
dict set codestate underlinecolour "5\;[lindex $plist $i+2]" dict set codestate underlinecolour "58\;5\;[lindex $plist $i+2]"
incr i 2 incr i 2
} }
2 { 2 {
#rgb #rgb
dict set codestate underlinecolour "2\;[lindex $plist $i+2]\;[lindex $plist $i+3]\;[lindex $plist $i+4]" dict set codestate underlinecolour "58\;2\;[lindex $plist $i+2]\;[lindex $plist $i+3]\;[lindex $plist $i+4]"
incr i 4 incr i 4
} }
} }

47
src/testansi/bot.ans

@ -0,0 +1,47 @@
°°°°°°°°°°°°±±±±±±±²²²²²² ÜÜ
ÜÜÜ ²²²±±±±°°°° °°°°°°°°±±±±±±
±±²²²²²² ÜÜÜÜÜßßßßßÜÜ 
 ²²²²±±±°° °°°°±±±±±±±±²²²²²²²
 ÜÜÛÛÛßßÜÜ 
 ÜÜÜÜÜÜܲ²²±±° °°±±±±±±²²²²²²²² 
 ÜÜÛ²²Û°±Û  ÜÜ
ÜÜÜßÜÜÜÜÜÜÜܱܱ±° °°±±±
²²ÜÜÜÜÜÜ ÜÜÛ²±²²° °±Û  
ÜÜÜÜßÛÛÜß °°°°°°° 
°°±° °±±²ÜÜßÛÛÛÛÛÛ
ßÜÜÜÜ Û²±±²±
°° °±Û  ÜÜÛÛ²²²±°° °±
±°°°° °±²ÜÛ²²²±±±°°°°°ßßÜÜ 
Üܲ²±±²± °°°° °°ßÜÜ
ÜÛ²²²±±°° °±±° ùáSù °
° °ÜÛ²²±±°°°°° ßÜÜ
Ü Û²±±±²Û° °°±° °±°°Û²²±±°°
° °±±° ÄÄiCEÄÄ°
 Û²²°±°°° ° °±²±° ß²ÜÜ Û±°°°±²± ° °
°±° °±°°Ûßßßßßß²ÜÜ °±°± ²±±°°° 
°°° °±²±°ÜÜÜÜÛÜ°°°°ßܱ°°° °°Üß
ßßܱ°° ±°°° °±°° °²±°Ü
²²²²²²²²²Ü ß°°°°²°ù °° °±°
° °±°ܲ²²²±±±±±°° ß°±±°±ù ° °±°
° °°° °²²²±±°°°±²±°°³ °±°
° °°° °±±±±°° °°±Û²°³ùùÄ
ÄÅÄÄùù ÛßÜ 
ÛßÜ ÛßÜ ÛÛÜ Û Ü
 Ûßß  ÛßÜ Û Ü
 ÛßÜ ÛßÜÛÛßÜ
ÛÛßÜÛÛßß ³
ÛÛßÜ ÛÛßÜ ÛÛ Û ÛÛ ÛÛßÛ ÛÛßß ÛÛßÜ ÛÛßÛ ÛÛ Û ÛÛ Û ÛÛ Û ÛÛ Û Û
Ûß ³ßßßß ßß ß ßßßß
 ßß ßß ß ßßßß ß
ß ß ßß ß ßßßß ßßßß ßßß 
 ßßßß ßß ùßßß
ßßßßßß ÜÛßÜÜÜÛßßÜÛ
ßÜÛßßßßßß Üßß
ÜßßÜÛßßßßßß ÜÛ
ßßßßßß ùÛÛÛÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛßßßßß ÛÛ
Û ÛÛÛ ÛÛÛßßßßß ßßßßßÛÛÛßßßßß ßß ßßß ßßßßßßß 
ßßßßßßß ßßßßßßß ßßßßßßßù Main BBS: 215/
374-0421 Ä*Ä CAE System: 215/796-9249 
ù

52
src/vendormodules/overtype-1.6.0.tm

@ -1526,7 +1526,8 @@ proc overtype::renderline {args} {
# that non-sgr codes are not that common, so ok to check for resets before verifying it is actually SGR at all. # that non-sgr codes are not that common, so ok to check for resets before verifying it is actually SGR at all.
if {$code ne ""} { if {$code ne ""} {
if {[punk::ansi::codetype::is_sgr_reset $code]} { if {[punk::ansi::codetype::is_sgr_reset $code]} {
set u_codestack [list] #set u_codestack [list]
set u_codestack [list "\x1b\[m"]
} elseif {[punk::ansi::codetype::has_sgr_leadingreset $code]} { } elseif {[punk::ansi::codetype::has_sgr_leadingreset $code]} {
set u_codestack [list $code] set u_codestack [list $code]
} elseif {[punk::ansi::codetype::is_sgr $code]} { } elseif {[punk::ansi::codetype::is_sgr $code]} {
@ -1672,7 +1673,7 @@ proc overtype::renderline {args} {
lappend overlay_grapheme_control_stacks $o_codestack lappend overlay_grapheme_control_stacks $o_codestack
#there will always be an empty code at end due to foreach on 2 vars with odd-sized list ending with pt (overmap coming from perlish split) #there will always be an empty code at end due to foreach on 2 vars with odd-sized list ending with pt (overmap coming from perlish split)
if {[punk::ansi::codetype::is_sgr_reset $code]} { if {[punk::ansi::codetype::is_sgr_reset $code]} {
set o_codestack [list] set o_codestack [list "\x1b\[m"] ;#reset better than empty list - fixes some ansi art issues
lappend overlay_grapheme_control_list [list sgr $code] lappend overlay_grapheme_control_list [list sgr $code]
} elseif {[punk::ansi::codetype::has_sgr_leadingreset $code]} { } elseif {[punk::ansi::codetype::has_sgr_leadingreset $code]} {
set o_codestack [list $code] set o_codestack [list $code]
@ -1686,7 +1687,8 @@ proc overtype::renderline {args} {
} elseif {[regexp {\x1b7|\x1b\[s} $code]} { } elseif {[regexp {\x1b7|\x1b\[s} $code]} {
#experiment #experiment
#cursor_save - for the replays review. #cursor_save - for the replays review.
set temp_cursor_saved [punk::ansi::codetype::sgr_merge_list {*}$o_codestack] #jmn
#set temp_cursor_saved [punk::ansi::codetype::sgr_merge_list {*}$o_codestack]
lappend overlay_grapheme_control_list [list other $code] lappend overlay_grapheme_control_list [list other $code]
} elseif {[regexp {\x1b8|\x1b\[u} $code]} { } elseif {[regexp {\x1b8|\x1b\[u} $code]} {
#experiment #experiment
@ -2132,6 +2134,7 @@ proc overtype::renderline {args} {
set re_cursor_restore {\x1b\[u$} set re_cursor_restore {\x1b\[u$}
set re_cursor_save_dec {\x1b7$} set re_cursor_save_dec {\x1b7$}
set re_cursor_restore_dec {\x1b8$} set re_cursor_restore_dec {\x1b8$}
set re_decstbm {\x1b\[([0-9]*)(?:;){0,1}([0-9]*)r$} ;#DECSTBM set top and bottom margins
set matchinfo [list] set matchinfo [list]
switch -regexp -matchvar matchinfo -- $code\ switch -regexp -matchvar matchinfo -- $code\
@ -2339,6 +2342,22 @@ proc overtype::renderline {args} {
set instruction move set instruction move
break break
}\ }\
$re_decstbm {
#https://www.vt100.net/docs/vt510-rm/DECSTBM.html
#This control function sets the top and bottom margins for the current page. You cannot perform scrolling outside the margins
lassign $matchinfo _match margin_top margin_bottom
#todo - return these for the caller to process..
puts stderr "overtype::renderline DECSTBM set top and bottom margin not implemented"
#Also moves the cursor to col 1 line 1 of the page
set cursor_column 1
set cursor_row 1
incr idx_over
priv::render_unapplied $overlay_grapheme_control_list $gci
set instruction move ;#own instruction? decstbm?
break
}\
$re_vt_sequence { $re_vt_sequence {
lassign $matchinfo _match key mod lassign $matchinfo _match key mod
#Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~ #Note that f1 to f4 show as ESCOP|Q|R|S (VT220?) but f5+ show as ESC\[15~
@ -2442,7 +2461,8 @@ proc overtype::renderline {args} {
sgr { sgr {
#code is the raw code #code is the raw code
if {[punk::ansi::codetype::is_sgr_reset $code]} { if {[punk::ansi::codetype::is_sgr_reset $code]} {
set sgr_stack [list] #jmn
set sgr_stack [list "\x1b\[m"]
} elseif {[punk::ansi::codetype::has_sgr_leadingreset $code]} { } elseif {[punk::ansi::codetype::has_sgr_leadingreset $code]} {
set sgr_stack [list $code] set sgr_stack [list $code]
lappend overlay_grapheme_control_list [list sgr $code] lappend overlay_grapheme_control_list [list sgr $code]
@ -2514,6 +2534,7 @@ proc overtype::renderline {args} {
break break
}\ }\
$re_mode { $re_mode {
lassign $matchinfo _match num type
switch -- $num { switch -- $num {
5 { 5 {
#DECSNM - reverse video #DECSNM - reverse video
@ -2551,8 +2572,21 @@ proc overtype::renderline {args} {
set overflow_idx -1 set overflow_idx -1
} }
} }
25 {
if {$type eq "h"} {
#visible cursor
} else {
#invisible cursor
}
}
} }
}\
default {
#puts stderr "overtype::renderline code [ansistring VIEW -lf 1 -vt 1 -nul 1 $code] not implemented"
} }
} }
default { default {
#don't need to handle sgr or gx0 types #don't need to handle sgr or gx0 types
@ -2613,10 +2647,12 @@ proc overtype::renderline {args} {
set cstack [lindex $understacks $i] set cstack [lindex $understacks $i]
if {$cstack ne $prevstack} { if {$cstack ne $prevstack} {
if {[llength $prevstack] && ![llength $cstack]} { if {[llength $prevstack] && ![llength $cstack]} {
#This reset is important e.g testfile fruit.ans - we get overhang on rhs without it. But why is cstack empty?
append sgrleader \033\[m append sgrleader \033\[m
} } else {
append sgrleader [punk::ansi::codetype::sgr_merge_list {*}$cstack] append sgrleader [punk::ansi::codetype::sgr_merge_list {*}$cstack]
} }
}
set prevstack $cstack set prevstack $cstack
} else { } else {
set prevstack [list] set prevstack [list]
@ -2637,9 +2673,9 @@ proc overtype::renderline {args} {
set cstack [lindex $understacks $i] set cstack [lindex $understacks $i]
set sgrleader "" set sgrleader ""
#whether cstack is same or differs from previous char's stack - we must have an output at the start of the overflow_right #whether cstack is same or differs from previous char's stack - we must have an output at the start of the overflow_right
if {[llength $prevstack] && ![llength $cstack]} { #if {[llength $prevstack] && ![llength $cstack]} {
append sgrleader \033\[m # append sgrleader \033\[m
} #}
append sgrleader [punk::ansi::codetype::sgr_merge_list {*}$cstack] append sgrleader [punk::ansi::codetype::sgr_merge_list {*}$cstack]
append overflow_right $sgrleader append overflow_right $sgrleader
append overflow_right $ch append overflow_right $ch

Loading…
Cancel
Save