こんにちは、越水です。
tktext.rbのTkTextに, Tcl/Tkの`text dump'コマンドが実装されていないよう
なので、下のようなコードを書いてみました。将来、dumpが実装されることが
あれば参考にしてください:
require 'tk'
class TkTextDump <TkText
def _dump(type, *index)
str = tk_send('dump', type, *index)
result = []
sel = nil
i = 0
while i < str.size
# retrieve key
idx = str.index(/ /, i)
result.push str[i..(idx-1)]
i = idx + 1
# retrieve value
case result[-1]
when 'text'
if str[i] == ?{
# text formed as {...}
val, i = _retrieve_breathed_text(str, i)
result.push val
else
# text which may contain backslahes
val, i = _retrieve_backslashed_text(str, i)
result.push val
end
else
idx = str.index(/ /, i)
val = str[i..(idx-1)]
case result[-1]
when 'mark'
case val
when 'insert'
result.push TkTextMarkInsert.new(self)
when 'current'
result.push TkTextMarkCurrent.new(self)
else
result.push tk_tcl2rb val
end
when 'tagon'
if val == 'sel'
if sel
result.push sel
else
result.push TkTextTagSel.new(self)
end
else
result.push tk_tcl2rb val
end
when 'tagoff'
result.push tk_tcl2rb sel
when 'window'
result.push tk_tcl2rb val
end
i = idx + 1
end
# retrieve index
idx = str.index(/ /, i)
if idx
result.push str[i..(idx-1)]
i = idx + 1
else
result.push str[i..-1]
break
end
end
kvis = []
until result.empty?
kvis.push [result.shift, result.shift, result.shift]
end
kvis # result is [[key1, value1, index1], [key2, value2, index2], ...]
end
private :_dump
def _retrieve_breathed_text(str, i)
cnt = 0
idx = i
while idx < str.size
case str[idx]
when ?{
cnt += 1
when ?}
cnt -= 1
if cnt == 0
break
end
end
idx += 1
end
return str[i+1..idx-1], idx + 2
end
private :_retrieve_breathed_text
def _retrieve_backslashed_text(str, i)
j = i
idx = nil
loop {
idx = str.index(/ /, j)
if str[idx-1] == ?\\
j += 1
else
break
end
}
val = str[i..(idx-1)]
val.gsub!(/\\( |\{|\})/, '\1')
return val, idx + 1
end
private :_retrieve_backslashed_text
def dump_all(*index)
_dump('-all', *index)
end
def dump_mark(*index)
_dump('-mark', *index)
end
def dump_tag(*index)
_dump('-tag', *index)
end
def dump_text(*index)
_dump('-text', *index)
end
def dump_window(*index)
_dump('-window', *index)
end
end
txt = TkTextDump.new {
insert 'end', '0123456789'
pack
}
btn = TkButton.new {
text 'Get'
command {
txt.dump_all('1.0', 'end').each {
| key, value, index |
if key == 'text'
puts index + ': ' + value
end
}
}
pack
}
Tk.mainloop
# 越水 greentea / fa2.so-net.ne.jp