Tcl offers some really excelling string manipulation tools 'straight out of the box' although sometimes something extra might be needed. What if, for instance, the strings contain markup? Any markup is invisible on screen and so any string positioning needs to ignore the effects of that markup on the overall string length.
This can be achieved by using a simple flag to keep track of where characters in a string are containtained within a markup substring or not.
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 | ## insert str1 into str2 at position pos, allow for pango/html markup
# @param[in] str1
# @param[in] str2
# @param[in] pos
# @param[in] opt
# @return modified string
proc string_insert { str1 str2 pos {opt ""} } {
switch $opt {
-markup {
set flag 1
set i 0
set res ""
foreach c [split $str2 ""] {
append res $c
if { $c == "<" } { set flag 0 }
if { $c == ">" } { set flag 1 }
if { $flag } {
if {$i == $pos } { append res $str1 }
incr i
}
}
return $res
}
default {
return [string range $str2 0 $pos-1]$str1[string range $str2 $pos end]
}
}
}
## insert str1 into str2 at specified line and offset, allow for pango/html markup
# @param[in] str1
# @param[in] str2
# @param[in] line
# @param[in] offset
# @param[in] opt
# @return modified string
proc text_insert { str1 str2 line offset {opt ""} } {
# extract specific line
set strings [split $str2 \n]
set ln [lindex $strings $line]
# make insertion
if { $opt == "-markup"} {
set ln [string_insert $str1 $ln $offset $opt]
} else {
set ln [string range $ln 0 $offset-1]$str1[string range $ln $offset end]
}
# repack the text
return [join [lreplace $strings $line $line $ln] \n]
} |
asdasd
Comments