tkregreplace 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README.txt +20 -0
  2. data/tkregreplace.rb +274 -0
  3. metadata +40 -0
data/README.txt ADDED
@@ -0,0 +1,20 @@
1
+ This program is currently in alpha status. It works pretty well at present
2
+ as a visualization tool, however crucial features are still missing from the program
3
+ like the ability to save the text file back to disk. Also there may be somewhat unexpected
4
+ behavior from the UI, not so much becuase of bugs, but more as a reflection of how the
5
+ program attacks the problem. Before the final release of this program I would like to
6
+ implement the following
7
+
8
+ saving files back to the disk
9
+
10
+ a proper about dialog
11
+
12
+ having all the search buttons obey symantics that the user would expect, like say perhaps searching starting from the current cursor
13
+ position rather than from the top and other minor refinements
14
+
15
+ cutting copying and pasting
16
+
17
+ an undo facility, preferably a multi level undo
18
+
19
+
20
+ I think If I can implement these features, this program could actually be useful to somebody.
data/tkregreplace.rb ADDED
@@ -0,0 +1,274 @@
1
+ require 'tk'
2
+
3
+ class TkRegReplace
4
+
5
+ def initialize
6
+ @root = TkRoot.new
7
+
8
+ @text = TkText.new(@root) do
9
+ font '-Adobe-Courier-Medium-R-Normal--*-120-*-*-*-*-*-*'
10
+ end
11
+
12
+ @text.wrap = 'none'
13
+
14
+ menu_spec =
15
+ [
16
+ [
17
+ ['File', 0],
18
+ ['Open', proc {open_file}, 0, 'Ctrl+O'],
19
+ '---',
20
+ ['Quit', proc{exit}, 0, 'Ctrl+Q']
21
+ ],
22
+ [
23
+ ['Edit', 0],
24
+ ['Cut', proc{puts('Cut clicked')}, 2, 'Ctrl+X'],
25
+ ['Copy', proc{puts('Copy clicked')}, 0, 'Ctrl+C'],
26
+ ['Paste', proc{puts('Paste clicked')}, 0, 'Ctrl+V']
27
+ ],
28
+ [
29
+ ['Help', 0, {:menu_name=>'help'}],
30
+ ['About This', proc{puts('xregexsearch&replace ruby script')}, 6]
31
+ ]
32
+ ]
33
+
34
+ @mbar = Tk.root.add_menubar(menu_spec)
35
+ @root.bind('Control-o', proc {open_file})
36
+ @root.bind('Control-q', proc {exit})
37
+
38
+ @frame1 = TkFrame.new(@root)
39
+ @frame2 = TkFrame.new(@root)
40
+ @frame3 = TkFrame.new(@root)
41
+
42
+ @entry1 = TkEntry.new(@frame2)
43
+ @entry1.bind('Return', proc {match})
44
+ @entry2 = TkEntry.new(@frame2)
45
+
46
+ @dmn = TkVariable.new(0)
47
+ @checkbox1 = TkCheckButton.new(@frame3,
48
+ 'text' => "Dot matches newline mode",
49
+ 'variable' => @dmn
50
+ )
51
+
52
+ @ic = TkVariable.new(1)
53
+ @checkbox2 = TkCheckButton.new(@frame3,
54
+ 'text' => "Ignore Case",
55
+ 'variable' => @ic
56
+ )
57
+
58
+ @tags = TkTextTag.new(@text, 'background' => 'red')
59
+ @tag = TkTextTag.new(@text, 'background' => 'blue')
60
+
61
+ @button1 = TkButton.new(@frame1,
62
+ 'text' => 'Match',
63
+ 'command' => proc {@text.focus; match}
64
+ )
65
+
66
+ @button2 = TkButton.new(@frame1,
67
+ 'text' => 'Match again',
68
+ 'command' => proc {@text.focus; match_again}
69
+ )
70
+
71
+ @button3 = TkButton.new(@frame1,
72
+ 'text' => "Match again reverse",
73
+ 'command' => proc {@text.focus; match_again_backwards}
74
+ )
75
+
76
+
77
+ @button4 = TkButton.new(@frame1,
78
+ 'text' => "Replace",
79
+ 'command' => proc {replace}
80
+ )
81
+
82
+ @button5 = TkButton.new(@frame1,
83
+ 'text' => "Replace All (from here downward)",
84
+ 'command' => proc {replace_all}
85
+ )
86
+
87
+ @label1 = TkLabel.new(@frame2,
88
+ 'text' => "Search String"
89
+ )
90
+
91
+ @label2 = TkLabel.new(@frame2,
92
+ 'text' => "Replace String"
93
+ )
94
+
95
+
96
+ @scrollBar = TkScrollbar.new(@root,
97
+ 'command' => proc {|*args| @text.yview(*args)}
98
+ )
99
+
100
+ @scrollBar2 = TkScrollbar.new(@root,
101
+ 'orient' => "horizontal",
102
+ 'command' => proc {|*args| @text.xview(*args)}
103
+ )
104
+
105
+ @text.yscrollcommand(proc { |first, last| @scrollBar.set(first, last)})
106
+ @text.xscrollcommand(proc { |first, last| @scrollBar2.set(first, last)})
107
+
108
+ @frame1.pack('side' => 'bottom', 'fill' => 'x')
109
+ @frame2.pack('side' => 'bottom', 'fill' => 'x', 'pady' => 10)
110
+ @frame3.pack('side' => 'bottom', 'fill' => 'x')
111
+ @checkbox1.pack('side' => 'left', 'fill' => 'x')
112
+ @checkbox2.pack('side' => 'left', 'fill' => 'x')
113
+ @label1.pack('side' => 'left', 'fill' => 'x')
114
+ @entry1.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
115
+ @label2.pack('side' => 'left', 'fill' => 'x')
116
+ @entry2.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
117
+ @button1.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
118
+ @button2.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
119
+ @button3.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
120
+ @button4.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
121
+ @button5.pack('side' => 'left', 'fill' => 'x', 'expand' => true)
122
+ @scrollBar.pack('side' => 'right', 'fill' => 'y')
123
+ @scrollBar2.pack('side' => 'bottom', 'fill' => 'x')
124
+ @text.pack('side' => 'right', 'fill' => 'both', 'expand' => true)
125
+
126
+ Tk.mainloop
127
+ end
128
+
129
+ def open_file
130
+ filetypes = [["All Files", "*"], ["Text Files", "*.txt"]]
131
+ filename = Tk.getOpenFile('filetypes' => filetypes, 'parent' => @root)
132
+ if filename != ""
133
+ @text.value=(File.read(filename))
134
+ end
135
+ end
136
+
137
+ def match
138
+ y = 1; x = 0
139
+ map = Array.new
140
+ string = @text.value
141
+ for i in 0..string.length
142
+ if (string[i] == "\n"[0])
143
+ map[i] = "#{y}.#{x}"
144
+ y = y+1
145
+ x = 0
146
+ else
147
+ map[i] = "#{y}.#{x}"
148
+ x = x+1
149
+ end
150
+ end
151
+
152
+ @tags.destroy
153
+ @tag.destroy
154
+ @tags = TkTextTag.new(@text, 'background' => 'red')
155
+ @tag = TkTextTag.new(@text, 'background' => 'blue')
156
+
157
+ if @entry1.value != ""
158
+ if @dmn == 1 and @ic == 1
159
+ @reg = Regexp.new("(?im:#{@entry1.value})")
160
+ elsif @ic == 1
161
+ @reg = Regexp.new("(?i:#{@entry1.value})")
162
+ elsif @dmn == 1
163
+ @reg = Regexp.new("(?m:#{@entry1.value})")
164
+ else
165
+ @reg = Regexp.new("#{@entry1.value}")
166
+ end
167
+ if (@reg =~ string)
168
+ c = 0
169
+ @tag_index = 0
170
+ @tags.add("#{map[$`.size]}", "#{map[($`.size + $&.size)]}")
171
+ @tag.add(@tags.ranges[0][0],@tags.ranges[0][1])
172
+ @tags.remove(@tag.ranges[0][0], @tag.ranges[0][1])
173
+ @text.set_insert("#{map[$`.size]}")
174
+ @text.see("#{map[$`.size]}")
175
+ c = c + $&.size + $`.size
176
+ while (@reg =~ $')
177
+ if $& == ""
178
+ $' =~ /\n/
179
+ c = c + 1
180
+ else
181
+ @tags.add("#{map[c + $`.size]}", "#{map[c + $`.size + $&.size]}")
182
+ c = c + $&.size + $`.size
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ def match_again
190
+ if @tags.ranges.length > 0
191
+ @tag_index = @tag_index + 1
192
+ @tag_index = 0 if @tag_index > @tags.ranges.length
193
+ @tags.add(@tag.ranges[0][0], @tag.ranges[0][1])
194
+ @tag.remove(@tag.ranges[0][0], @tag.ranges[0][1])
195
+ @tag.add(@tags.ranges[@tag_index][0], @tags.ranges[@tag_index][1])
196
+ @tags.remove(@tag.ranges[0][0], @tag.ranges[0][1])
197
+ @text.set_insert(@tag.ranges[0][0])
198
+ @text.see(@tag.ranges[0][0])
199
+ end
200
+ end
201
+
202
+ def match_again_backwards
203
+ if @tags.ranges.length > 0
204
+ @tag_index = @tag_index - 1
205
+ @tag_index = @tags.ranges.length if @tag_index < 0
206
+ @tags.add(@tag.ranges[0][0], @tag.ranges[0][1])
207
+ @tag.remove(@tag.ranges[0][0], @tag.ranges[0][1])
208
+ @tag.add(@tags.ranges[@tag_index][0], @tags.ranges[@tag_index][1])
209
+ @tags.remove(@tag.ranges[0][0], @tag.ranges[0][1])
210
+ @text.set_insert(@tag.ranges[0][0])
211
+ @text.see(@tag.ranges[0][0])
212
+ end
213
+ end
214
+
215
+ def replace
216
+ if @entry1.value != ""
217
+ if @dmn == 1 and @ic == 1
218
+ @reg = Regexp.new("(?im:#{@entry1.value})")
219
+ elsif @ic == 1
220
+ @reg = Regexp.new("(?i:#{@entry1.value})")
221
+ elsif @dmn == 1
222
+ @reg = Regexp.new("(?m:#{@entry1.value})")
223
+ else
224
+ @reg = Regexp.new("#{@entry1.value}")
225
+ end
226
+ end
227
+
228
+ if (@tag.ranges.length > 0)
229
+ string = @text.get(@tag.ranges[0][0], @tag.ranges[0][1])
230
+ string.sub!(@reg, @entry2.value)
231
+ @text.insert(@tag.ranges[0][0], string)
232
+ @text.delete(@tag.ranges[0][0], @tag.ranges[0][1])
233
+ unless @tag_index > @tags.ranges.length-1
234
+ @tag.add(@tags.ranges[@tag_index][0], @tags.ranges[@tag_index][1])
235
+ @tags.remove(@tag.ranges[0][0], @tag.ranges[0][1])
236
+ @text.set_insert(@tag.ranges[0][0])
237
+ @text.see(@tag.ranges[0][0])
238
+ end
239
+ end
240
+ end
241
+
242
+ def replace_all
243
+ if @entry1.value != ""
244
+ if @dmn == 1 and @ic == 1
245
+ @reg = Regexp.new("(?im:#{@entry1.value})")
246
+ elsif @ic == 1
247
+ @reg = Regexp.new("(?i:#{@entry1.value})")
248
+ elsif @dmn == 1
249
+ @reg = Regexp.new("(?m:#{@entry1.value})")
250
+ else
251
+ @reg = Regexp.new("#{@entry1.value}")
252
+ end
253
+ end
254
+
255
+ while(@tag.ranges.length > 0)
256
+ string = @text.get(@tag.ranges[0][0], @tag.ranges[0][1])
257
+ string.sub!(@reg, @entry2.value)
258
+ @text.insert(@tag.ranges[0][0], string)
259
+ @text.delete(@tag.ranges[0][0], @tag.ranges[0][1])
260
+ unless @tag_index > @tags.ranges.length-1
261
+ @tag.add(@tags.ranges[@tag_index][0], @tags.ranges[@tag_index][1])
262
+ @tags.remove(@tag.ranges[0][0], @tag.ranges[0][1])
263
+ @text.set_insert(@tag.ranges[0][0])
264
+ @text.see(@tag.ranges[0][0])
265
+ end
266
+ end
267
+ end
268
+ end
269
+
270
+ TkRegReplace.new
271
+
272
+ # mark = TkTextMarkInsert.new(@text)
273
+ # puts @text.index(mark)
274
+
metadata ADDED
@@ -0,0 +1,40 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.10
3
+ specification_version: 1
4
+ name: tkregreplace
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2005-11-09
8
+ summary: TK program which visualizes and caries out regular expression matches and or replacements on text files
9
+ require_paths:
10
+ - lib
11
+ email: pfharlock@yahoo.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: "."
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ authors:
28
+ - Gary Watson
29
+ files:
30
+ - tkregreplace.rb
31
+ - README.txt
32
+ test_files: []
33
+ rdoc_options: []
34
+ extra_rdoc_files:
35
+ - README.txt
36
+ executables:
37
+ - tkregreplace.rb
38
+ extensions: []
39
+ requirements: []
40
+ dependencies: []