Browse Source

punk::ansi 0.1.4: ansistring RANGE argdoc states the pinned contract

Documentation-only bump. The RANGE punk::args -help (and the doctools
comment) now document the behaviours pinned by the 2026-08-05 ansistring
coverage survey (ansi/ansistring.test), replacing the underspecified
"including the ANSI codes in effect" wording:

- SGR codes re-applied at each plain-text run in merged (canonicalized)
  form - style-equivalent but NOT byte-identical to the original.
- SGR-only carriage: other sequence types (cursor movement, OSC, charset
  shifts) are not re-emitted.
- Codes after the last requested grapheme are not included; trailing SGR
  state is retrievable with ansistring INDEXCODE end+1.
- Index semantics: end-relative expressions, one-sided clamping,
  empty-string returns for both-beyond-same-end and inverted ranges (tcl
  string range consistency).

The @cmd -summary reworded from "ANSI codes preserved" (overclaimed) to
"SGR styling re-applied". Open design questions stay deliberately
undocumented as contract - trailing codes on literal end (the shared TODO
with opunk::Str RANGE and its whole-span $this shortcut divergence),
non-SGR retention, charset/gx0 handling - recorded in code comments and
G-151 Notes.

ansi subtree 71/71 green (tclsh90); usage render verified carrying the new
content. Minted modules/punk/ansi-0.1.4.tm via make.tcl modules;
bootsupport/vfscommon promotion left to the next promotion cycle.

Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 1 week ago
parent
commit
e25537bb50
  1. 20
      src/modules/punk/ansi-999999.0a1.0.tm
  2. 3
      src/modules/punk/ansi-buildversion.txt

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

@ -11581,12 +11581,22 @@ tcl::namespace::eval punk::ansi::ansistring {
@id -id ::punk::ansi::ansistring::RANGE
@cmd -name punk::ansi::ansistring::RANGE\
-summary\
"Substring between grapheme positions, with ANSI codes preserved."\
"Substring between grapheme positions, with SGR styling re-applied."\
-help\
"Return the substring of string between grapheme positions startindex
and endindex inclusive (positions as for ansistring INDEX), including
the ANSI codes in effect for those graphemes.
end-relative index expressions are supported."
and endindex inclusive (positions as for ansistring INDEX), with the
ANSI SGR codes in effect for those graphemes re-applied at each
plain-text run - so the range renders as the original did.
The result is style-equivalent but not byte-identical: code stacks
are re-emitted in merged (canonicalized) form, only SGR codes are
carried (other sequence types - cursor movement, OSC, charset
shifts - are not re-emitted), and codes after the last requested
grapheme are not included (the SGR state after the whole string is
retrievable with ansistring INDEXCODE end+1).
end-relative index expressions are supported. An index beyond the
string clamps to the nearest end; if both indices fall beyond the
same end, or startindex resolves past endindex, an empty string is
returned (as for tcl string range)."
@values -min 3 -max 3
string -type string
startindex -type indexexpression
@ -11596,7 +11606,7 @@ tcl::namespace::eval punk::ansi::ansistring {
proc RANGE {string startindex endindex} {
#*** !doctools
#[call [fun RANGE] [arg string] [arg startindex] [arg endindex]]
#[para]Returns the substring of string between the character positions startindex and endindex, inclusive, where the character positions are determined by INDEX. The returned substring will include any ANSI codes that are in effect for those characters.
#[para]Returns the substring of string between the character positions startindex and endindex, inclusive, where the character positions are determined by INDEX. The ANSI SGR codes in effect for those characters are re-applied at each plain-text run in merged (canonicalized) form - style-equivalent but not byte-identical to the original; non-SGR codes and codes after the last requested character are not re-emitted (see INDEXCODE end+1 for trailing SGR state).
#TODO - special case processing for end+n and equivalents to return trailing ANSI codes as well.
#(similar to INDEXCODE)

3
src/modules/punk/ansi-buildversion.txt

@ -1,5 +1,6 @@
0.1.3
0.1.4
#First line must be a semantic version number
#all other lines are ignored.
#0.1.4 - documentation-only: ansistring RANGE argdoc + doctools comment now state the pinned contract (tests ansi/ansistring.test, 2026-08-05 coverage survey): merged/canonicalized SGR re-emission (style-equivalent, not byte-identical), SGR-only carriage (non-SGR sequence types not re-emitted), trailing-code exclusion with INDEXCODE end+1 as the retrieval mechanism, and clamping/empty-range semantics. Summary reworded (was 'codes preserved' - overclaimed). Open design questions (trailing codes on literal end, non-SGR retention, charset/gx0 handling) stay as code TODO/review comments and G-151 Notes - deliberately not promised in the doc.
#0.1.3 - documentation-only: grepstr -return summarydict choicelabel corrected - the summary dict's 'linemap' key is always present (the old text claimed it appeared only with -n; actual always-present behaviour pinned in tests ansi/grepstr.test). Reconciliation deferred from the grepstr characterization wave to the punk::ns hygiene pass.
#0.1.2 - documentation-only: PUNKARGS argdoc blocks added for punk::ansi::codetype (is_sgr_reset, has_sgr_leadingreset, is_cursor_move_in_line, has_all_effective, get_effective_types, is_gx/is_gx_open/is_gx_close, sgr_merge), punk::ansi::sequence_type (is_Fe7/is_Fe/is_Fe8, is_Fp, is_Fs, is_nF, is_3Fp, is_code7/is_code8/is_code, classify), punk::ansi::ta (detect_in_list, detectcode, detectcode_in_list, detect_g0, detect_open, detect_st_open, detect_csi, detect_sgr, split_at_codes, split_codes, split_codes_single, get_codes_single) and punk::ansi::ansistring (VIEW, COUNT, length, trimleft/trimright/trim, INDEX, INDEXCHAR, RANGE, INSERT, INDEXABSOLUTE, INDEXCOLUMNS, COLUMNINDEX); ::punk::ansi::sequence_type added to punk::args::register NAMESPACES so its argdocs are discoverable

Loading…
Cancel
Save