-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstrutil.tcl
115 lines (95 loc) · 2.6 KB
/
strutil.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# -*- tcl -*- Copyright (c) 2012-2024 Andreas Kupries
# # ## ### ##### ######## ############# #####################
## String utility commands.
# # ## ### ##### ######## ############# #####################
## Export (internals - recipe definitions, other utilities)
namespace eval ::kettle::strutil {
namespace export {[a-z]*}
namespace ensemble create
}
# # ## ### ##### ######## ############# #####################
## API
proc ::kettle::strutil::padr {list} {
set maxl 0
foreach str $list {
set l [string length $str]
if {$l <= $maxl} continue
set maxl $l
}
set res {}
foreach str $list { lappend res [format "%-*s" $maxl $str] }
return $res
}
proc ::kettle::strutil::padl {list} {
set maxl 0
foreach str $list {
set l [string length $str]
if {$l <= $maxl} continue
set maxl $l
}
set res {}
foreach str $list { lappend res [format "%*s" $maxl $str] }
return $res
}
proc ::kettle::strutil::reflow {text {prefix { }}} {
return [indent [undent [string trim $text \n]] $prefix]
}
proc ::kettle::strutil::indent {text prefix} {
set text [string trimright $text]
set res {}
foreach line [split $text \n] {
if {[string trim $line] eq {}} {
lappend res {}
} else {
lappend res $prefix[string trimright $line]
}
}
return [join $res \n]
}
proc ::kettle::strutil::undent {text} {
if {$text eq {}} { return {} }
set lines [split $text \n]
set ne {}
foreach l $lines {
if {[string length [string trim $l]] == 0} continue
lappend ne $l
}
set lcp [LCP $ne]
if {$lcp eq {}} { return $text }
regexp "^(\[\t \]*)" $lcp -> lcp
if {$lcp eq {}} { return $text }
set len [string length $lcp]
set res {}
foreach l $lines {
if {[string trim $l] eq {}} {
lappend res {}
} else {
lappend res [string range $l $len end]
}
}
return [join $res \n]
}
proc ::kettle::strutil::LCP {list} {
if {[llength $list] <= 1} {
return [lindex $list 0]
}
set list [lsort $list]
set min [lindex $list 0]
set max [lindex $list end]
# Min and max are the two strings which are most different. If
# they have a common prefix, it will also be the common prefix for
# all of them.
# Fast bailouts for common cases.
set n [string length $min]
if {$n == 0} { return "" }
if {$min eq $max} { return $min }
set prefix ""
set i 0
while {[string index $min $i] eq [string index $max $i]} {
append prefix [string index $min $i]
if {[incr i] > $n} {break}
}
return $prefix
}
# # ## ### ##### ######## ############# #####################
return