filtri 0.0.1 → 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.
- data/README.md +61 -2
- data/bin/filtri +24 -0
- data/filtri.gemspec +8 -6
- data/lib/filtri/command.rb +108 -0
- data/lib/filtri/version.rb +1 -1
- data/lib/filtri.rb +43 -9
- data/resource/filtri_rules.tmLanguage +75 -0
- data/spec/command_spec.rb +127 -0
- metadata +18 -15
data/README.md
CHANGED
@@ -11,8 +11,6 @@ Filtri is a tiny DSL for text substitution.
|
|
11
11
|
|
12
12
|
Define a set of substitution rules using `rule` and apply to an input string:
|
13
13
|
|
14
|
-
in_str = "foobazbarfoo"
|
15
|
-
expected = "barbugbarbar"
|
16
14
|
|
17
15
|
f = filtri do
|
18
16
|
rule /fo+/ => "bar"
|
@@ -36,8 +34,69 @@ Load with `Filtri::load`:
|
|
36
34
|
Filtri.load("foo.rules").apply("foobarfoobar")
|
37
35
|
=> "**b**!!a!!z**b**!!a!!g**b**!!a!!z**b**!!a!!g"
|
38
36
|
|
37
|
+
## Command line tool
|
38
|
+
|
39
|
+
A command line tool is included in this gem, `filtri`
|
40
|
+
|
41
|
+
### Usage
|
42
|
+
|
43
|
+
Usage: filtri [options] [input]
|
44
|
+
|
45
|
+
Options:
|
46
|
+
-r, --rule STRING Single rule
|
47
|
+
-f, --file RULE_FILE File containing rules
|
48
|
+
-v, --version Version information
|
49
|
+
-h, --help Help
|
50
|
+
|
51
|
+
|
52
|
+
### Examples
|
53
|
+
|
54
|
+
An example applying rules from the files `f1.rule` and `f2.rule` to the input files `input1` and `input2`
|
55
|
+
|
56
|
+
File `f1.rules`:
|
57
|
+
|
58
|
+
rule /(foo+)/ => 'THIS WAS \1'
|
59
|
+
rule /(ba+r)/ => 'THIS WAS \1'
|
60
|
+
|
61
|
+
File `f1.rules`:
|
62
|
+
|
63
|
+
rule /(ba+z)/ => 'THIS WAS \1'
|
64
|
+
rule /bag/ => 'THIS WAS BAG'
|
65
|
+
|
66
|
+
File `input1`:
|
67
|
+
|
68
|
+
foooo
|
69
|
+
baaaaaaaaaaaaaaaaz
|
70
|
+
bag
|
71
|
+
|
72
|
+
File `input2`:
|
73
|
+
|
74
|
+
and baaaaaaaaaaar
|
75
|
+
|
76
|
+
Running `filtri` as
|
77
|
+
|
78
|
+
$ filtri -f f1.rules -f f2.rules input1 input2 > result.txt
|
79
|
+
|
80
|
+
..gives `result.txt`:
|
81
|
+
|
82
|
+
THIS WAS foooo
|
83
|
+
THIS WAS baaaaaaaaaaaaaaaaz
|
84
|
+
THIS WAS BAG
|
85
|
+
and THIS WAS baaaaaaaaaaar
|
86
|
+
|
87
|
+
Single rules can be provided using the option `-r`:
|
88
|
+
|
89
|
+
$ echo "foo" | filtri -r '"foo" => "bar"'
|
90
|
+
bar
|
91
|
+
|
92
|
+
|
93
|
+
## Syntax highlighting
|
94
|
+
|
95
|
+
Definitions for syntax highlighting of `.rule` files in Sublime Text 2 and TextMate is available (`resource/filtri_rules.tmLanguage`)
|
96
|
+
|
39
97
|
## Version information
|
40
98
|
|
99
|
+
* 0.1.0 - Added filtri tool and syntax highlighting
|
41
100
|
* 0.0.1 - Initial version
|
42
101
|
|
43
102
|
## License
|
data/bin/filtri
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require_relative '../lib/filtri/command'
|
5
|
+
|
6
|
+
begin
|
7
|
+
|
8
|
+
debug = true
|
9
|
+
|
10
|
+
opts = FiltriCmd.parse_opts
|
11
|
+
|
12
|
+
unless FiltriCmd.validate_opts(opts)
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
result = FiltriCmd.run(opts, opts[:input])
|
16
|
+
puts result
|
17
|
+
rescue SystemExit => sys_exit
|
18
|
+
exit sys_exit.status
|
19
|
+
rescue Exception => ex
|
20
|
+
|
21
|
+
puts "[Error] #{ex.message}"
|
22
|
+
puts " -----> #{ex.backtrace.join("\n ")}" if debug
|
23
|
+
|
24
|
+
end
|
data/filtri.gemspec
CHANGED
@@ -9,12 +9,14 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.version = Filtri::VERSION
|
10
10
|
spec.authors = ["karl l"]
|
11
11
|
spec.email = ["karl@ninjacontrol.com"]
|
12
|
-
spec.date = '2013-04-
|
13
|
-
spec.summary = "A tiny
|
14
|
-
spec.description = "Filtri is a
|
12
|
+
spec.date = '2013-04-07'
|
13
|
+
spec.summary = "A tiny tool for text substitution"
|
14
|
+
spec.description = "Filtri is a tool that simplifies the work of applying multiple substitution rules to a string."
|
15
15
|
spec.homepage = "https://github.com/karlll/filtri/"
|
16
16
|
spec.license = "MIT"
|
17
|
-
|
17
|
+
|
18
|
+
spec.required_ruby_version = '>= 1.9.3'
|
19
|
+
|
18
20
|
spec.files = `git ls-files`.split($/)
|
19
21
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
@@ -22,9 +24,9 @@ Gem::Specification.new do |spec|
|
|
22
24
|
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
26
|
spec.add_development_dependency "rake"
|
25
|
-
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "rspec", ">= 2.11"
|
26
28
|
spec.add_runtime_dependency "docile"
|
27
|
-
spec.add_runtime_dependency "str2hash"
|
29
|
+
spec.add_runtime_dependency "str2hash", ">= 0.1.0"
|
28
30
|
spec.add_runtime_dependency "to_regexp"
|
29
31
|
|
30
32
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require_relative 'version'
|
3
|
+
require_relative '../filtri'
|
4
|
+
|
5
|
+
class FiltriCmd
|
6
|
+
def self.parse_opts
|
7
|
+
options = {}
|
8
|
+
|
9
|
+
OptionParser.new do |o|
|
10
|
+
o.banner = "Usage: filtri [options] [input]"
|
11
|
+
o.separator ""
|
12
|
+
o.separator "Options:"
|
13
|
+
|
14
|
+
o.on("-r", "--rule STRING", "Single rule") do |rule|
|
15
|
+
if options.include?(:rules)
|
16
|
+
options[:rules] << rule
|
17
|
+
else
|
18
|
+
options[:rules] = [rule]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
o.on("-f", "--file RULE_FILE", "File containing rules") do |rule_files|
|
23
|
+
if options.include?(:rule_files)
|
24
|
+
options[:rule_files] << rule_files
|
25
|
+
else
|
26
|
+
options[:rule_files] = [rule_files]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
o.on( '-v', '--version', 'Version information' ) do
|
31
|
+
puts "version #{Filtri::VERSION}"
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
|
35
|
+
o.on( '-h', '--help', 'Help' ) do
|
36
|
+
puts o
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
end.parse!
|
43
|
+
|
44
|
+
options[:input] = ARGV unless ARGV.length <= 0
|
45
|
+
options
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.validate_opts(opts)
|
50
|
+
|
51
|
+
|
52
|
+
unless opts.include?(:rules) || opts.include?(:rule_files)
|
53
|
+
puts "Error: provide a rule or a rule file."
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
|
57
|
+
[:rule_files, :input].each do |f|
|
58
|
+
if opts.include?(f)
|
59
|
+
opts[f].each do |i|
|
60
|
+
unless File.exist?(i)
|
61
|
+
puts "Error: file #{i} does not exist."
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
true
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
# Apply rules to the provided input
|
73
|
+
#
|
74
|
+
# @param [Hash{Symbol => Array<String>}] rules Where :rules contain single rule strings and :rule_files contain filename(s) of the rule file(s)
|
75
|
+
# @param [Array<String>] input Where :input contain the input file(s)
|
76
|
+
# @return [String] The rules applied to the input
|
77
|
+
# @raise [FiltriInitError, IOError] if an error occurs when initialising the rules from the provided strings or files
|
78
|
+
def self.run(rules, input)
|
79
|
+
rule_strs = rules[:rules] || []
|
80
|
+
rule_files = rules[:rule_files] || []
|
81
|
+
result = []
|
82
|
+
|
83
|
+
|
84
|
+
# Allow for shorthand format of rules
|
85
|
+
|
86
|
+
upd_rule_strs = rule_strs.reduce([]) do |r,v|
|
87
|
+
if v =~ /^(#{Filtri.valid_rules.join("|")})/
|
88
|
+
r << v
|
89
|
+
else
|
90
|
+
r << "rule #{v}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
f = Filtri.new
|
94
|
+
if upd_rule_strs.length > 0
|
95
|
+
f.add_rule_str(upd_rule_strs.join("\n"))
|
96
|
+
end
|
97
|
+
|
98
|
+
rule_files.each do |rf|
|
99
|
+
f.load rf
|
100
|
+
end
|
101
|
+
|
102
|
+
ARGV.replace(input || [])
|
103
|
+
result << f.apply(ARGF.read)
|
104
|
+
|
105
|
+
result.join("")
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
data/lib/filtri/version.rb
CHANGED
data/lib/filtri.rb
CHANGED
@@ -21,6 +21,7 @@ class Filtri
|
|
21
21
|
@rules = []
|
22
22
|
@meta_rules = []
|
23
23
|
@passes = 1
|
24
|
+
@meta_applied = false
|
24
25
|
end
|
25
26
|
|
26
27
|
# Add a filtering rule
|
@@ -92,7 +93,10 @@ class Filtri
|
|
92
93
|
@passes.times do
|
93
94
|
|
94
95
|
unless @meta_rules.empty?
|
95
|
-
|
96
|
+
unless @meta_applied
|
97
|
+
@rules = rewrite(@rules, @meta_rules)
|
98
|
+
@meta_applied = true
|
99
|
+
end
|
96
100
|
end
|
97
101
|
|
98
102
|
@rules.each do |rule|
|
@@ -103,8 +107,6 @@ class Filtri
|
|
103
107
|
in_str
|
104
108
|
end
|
105
109
|
|
106
|
-
# Factory, init with rule-set from a string
|
107
|
-
#
|
108
110
|
# The input string is expected to contain rules and comments, one per line,
|
109
111
|
# separated by a line break.
|
110
112
|
# The expected format of a line is "{operation} <space> {argument} <eol>".
|
@@ -112,11 +114,8 @@ class Filtri
|
|
112
114
|
# is trimmed.
|
113
115
|
#
|
114
116
|
# @param [String] rule_str
|
115
|
-
# @return [Filtri] A new Filtri object with the rules parsed from the provided string(s).
|
116
117
|
# @raise [FiltriInitError] if an error occurs when initialising the rules from the provided strings
|
117
|
-
def
|
118
|
-
|
119
|
-
inst = Filtri.new
|
118
|
+
def add_rule_str(rule_str)
|
120
119
|
|
121
120
|
rule_str.strip.lines do |l|
|
122
121
|
|
@@ -133,7 +132,7 @@ class Filtri
|
|
133
132
|
raise FiltriInitError, "Invalid rule format: '#{op_arg}' (#{err.message})"
|
134
133
|
end
|
135
134
|
# add rule
|
136
|
-
|
135
|
+
self.send(op.to_sym,arg_hash)
|
137
136
|
else
|
138
137
|
raise FiltriInitError, "Unknown rule: #{op}" unless op == "#"
|
139
138
|
end
|
@@ -141,12 +140,42 @@ class Filtri
|
|
141
140
|
end
|
142
141
|
end
|
143
142
|
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
# Factory, init with rule-set from a string
|
148
|
+
#
|
149
|
+
# The input string is expected to contain rules and comments, one per line,
|
150
|
+
# separated by a line break.
|
151
|
+
# The expected format of a line is '{operation} <space> {argument} <eol>'.
|
152
|
+
# Empty lines and lines starting with a '#' are ignored. Whitespace at the beginning of a line
|
153
|
+
# is trimmed.
|
154
|
+
#
|
155
|
+
# @param [String] rule_str
|
156
|
+
# @return [Filtri] A new Filtri object with the rules parsed from the provided string(s).
|
157
|
+
# @raise [FiltriInitError] if an error occurs when initialising the rules from the provided strings
|
158
|
+
def self.from_str(rule_str)
|
159
|
+
|
160
|
+
inst = Filtri.new
|
161
|
+
inst.add_rule_str rule_str
|
144
162
|
inst
|
145
163
|
|
146
164
|
end
|
147
165
|
|
148
166
|
# Load rules from a file
|
149
167
|
# @param [String] file_name
|
168
|
+
# @raise [IOError,SystemCallError] If an error occurs when opening the file
|
169
|
+
# @raise [FiltriInitError] If an error occurs when parsing the rules in the file
|
170
|
+
def load(file_name)
|
171
|
+
|
172
|
+
data = IO.read(file_name)
|
173
|
+
add_rule_str(data)
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
# Factory, Init by loading rules from a file
|
178
|
+
# @param [String] file_name
|
150
179
|
# @return [Filtri] A new Filtri object with the rules contained in the file
|
151
180
|
# @raise [IOError,SystemCallError] If an error occurs when opening the file
|
152
181
|
# @raise [FiltriInitError] If an error occurs when parsing the rules in the file
|
@@ -158,6 +187,10 @@ class Filtri
|
|
158
187
|
end
|
159
188
|
|
160
189
|
|
190
|
+
def self.valid_rules
|
191
|
+
Filtri::RULES
|
192
|
+
end
|
193
|
+
|
161
194
|
end
|
162
195
|
|
163
196
|
class FiltriInitError < StandardError
|
@@ -180,4 +213,5 @@ end
|
|
180
213
|
# @return [Filtri] A new Filtri object containing the provided rules
|
181
214
|
def filtri(&block)
|
182
215
|
Docile.dsl_eval(Filtri.new, &block)
|
183
|
-
end
|
216
|
+
end
|
217
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>fileTypes</key>
|
6
|
+
<array>
|
7
|
+
<string>rules</string>
|
8
|
+
</array>
|
9
|
+
<key>name</key>
|
10
|
+
<string>Filtri rules</string>
|
11
|
+
<key>patterns</key>
|
12
|
+
<array>
|
13
|
+
<dict>
|
14
|
+
<key>comment</key>
|
15
|
+
<string>A comment</string>
|
16
|
+
<key>match</key>
|
17
|
+
<string>^\s*(#.*)$</string>
|
18
|
+
<key>name</key>
|
19
|
+
<string>comment.line.numer-sign.rules</string>
|
20
|
+
</dict>
|
21
|
+
<dict>
|
22
|
+
<key>comment</key>
|
23
|
+
<string>A rule</string>
|
24
|
+
<key>match</key>
|
25
|
+
<string>^\s*rule</string>
|
26
|
+
<key>name</key>
|
27
|
+
<string>support.function.rules</string>
|
28
|
+
</dict>
|
29
|
+
<dict>
|
30
|
+
<key>comment</key>
|
31
|
+
<string>A meta rule</string>
|
32
|
+
<key>match</key>
|
33
|
+
<string>^\s*meta</string>
|
34
|
+
<key>name</key>
|
35
|
+
<string>support.function.rules</string>
|
36
|
+
</dict>
|
37
|
+
<dict>
|
38
|
+
<key>comment</key>
|
39
|
+
<string>A string</string>
|
40
|
+
<key>match</key>
|
41
|
+
<string>"([^"]*)"</string>
|
42
|
+
<key>name</key>
|
43
|
+
<string>string.quoted.double.rules</string>
|
44
|
+
</dict>
|
45
|
+
<dict>
|
46
|
+
<key>comment</key>
|
47
|
+
<string>A string</string>
|
48
|
+
<key>match</key>
|
49
|
+
<string>'([^']*)'</string>
|
50
|
+
<key>name</key>
|
51
|
+
<string>string.quoted.single.rules</string>
|
52
|
+
</dict>
|
53
|
+
<dict>
|
54
|
+
<key>comment</key>
|
55
|
+
<string>A regular expression</string>
|
56
|
+
<key>match</key>
|
57
|
+
<string>/([^']*)/</string>
|
58
|
+
<key>name</key>
|
59
|
+
<string>string.regexp.rules</string>
|
60
|
+
</dict>
|
61
|
+
<dict>
|
62
|
+
<key>comment</key>
|
63
|
+
<string>A mapping</string>
|
64
|
+
<key>match</key>
|
65
|
+
<string>=></string>
|
66
|
+
<key>name</key>
|
67
|
+
<string>keyword.operator.rules</string>
|
68
|
+
</dict>
|
69
|
+
</array>
|
70
|
+
<key>scopeName</key>
|
71
|
+
<string>text.rules</string>
|
72
|
+
<key>uuid</key>
|
73
|
+
<string>7d1b615b-cfb6-41e1-83e1-6ff8508e0133</string>
|
74
|
+
</dict>
|
75
|
+
</plist>
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'filtri/command'
|
3
|
+
|
4
|
+
describe FiltriCmd do
|
5
|
+
|
6
|
+
describe "#parse_opts" do
|
7
|
+
|
8
|
+
it 'parses multiple rules' do
|
9
|
+
|
10
|
+
stub_const("ARGV",["-r", "{:foo => 'bar'}", "--rule", "{:foo2 => 'bar2'}"])
|
11
|
+
out_opts = FiltriCmd.parse_opts
|
12
|
+
out_opts.should eq({:rules=>["{:foo => 'bar'}", "{:foo2 => 'bar2'}"]})
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'parses multiple rule files' do
|
17
|
+
|
18
|
+
stub_const("ARGV",["-f", "file1", "--file", "file2"])
|
19
|
+
out_opts = FiltriCmd.parse_opts
|
20
|
+
out_opts.should eq({:rule_files=>["file1", "file2"]})
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'parses multiple input files' do
|
25
|
+
|
26
|
+
stub_const("ARGV",["-f", "file1", "input1", "input2"])
|
27
|
+
out_opts = FiltriCmd.parse_opts
|
28
|
+
out_opts.should eq({:rule_files=>["file1"], :input=> ["input1", "input2"]})
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#validate_opts" do
|
36
|
+
|
37
|
+
it 'requires a rule or a rule file' do
|
38
|
+
|
39
|
+
stub_const("ARGV",["-f", "file1", "input1", "input2"])
|
40
|
+
out_opts = FiltriCmd.parse_opts
|
41
|
+
File.stub!(:exist?).and_return true
|
42
|
+
FiltriCmd.validate_opts(out_opts).should be_true
|
43
|
+
|
44
|
+
stub_const("ARGV",["--rule", "{:foo => 'bar'}", "input2"])
|
45
|
+
out_opts = FiltriCmd.parse_opts
|
46
|
+
FiltriCmd.validate_opts(out_opts).should be_true
|
47
|
+
|
48
|
+
stub_const("ARGV",["input1", "input2"])
|
49
|
+
out_opts = FiltriCmd.parse_opts
|
50
|
+
$stdout.should_receive(:puts).with(/Error/i)
|
51
|
+
FiltriCmd.validate_opts(out_opts).should be_false
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'checks if files exist' do
|
56
|
+
|
57
|
+
stub_const("ARGV",["-f", "existing_file", "input_file1", "input_file2"])
|
58
|
+
out_opts = FiltriCmd.parse_opts
|
59
|
+
File.stub!(:exist?).with("existing_file").and_return true
|
60
|
+
File.stub!(:exist?).with("input_file1").and_return true
|
61
|
+
File.stub!(:exist?).with("input_file2").and_return true
|
62
|
+
FiltriCmd.validate_opts(out_opts).should be_true
|
63
|
+
|
64
|
+
stub_const("ARGV",["-f", "existing_file", "input_file1", "bad_input_file2"])
|
65
|
+
out_opts = FiltriCmd.parse_opts
|
66
|
+
File.stub!(:exist?).with("existing_file").and_return true
|
67
|
+
File.stub!(:exist?).with("input_file1").and_return true
|
68
|
+
File.stub!(:exist?).with("bad_input_file2").and_return false
|
69
|
+
$stdout.should_receive(:puts).with(/Error/i)
|
70
|
+
FiltriCmd.validate_opts(out_opts).should be_false
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#run" do
|
78
|
+
|
79
|
+
let(:rules) { %q(
|
80
|
+
|
81
|
+
# this is a comment
|
82
|
+
rule /fo+bar/ => "bazbag"
|
83
|
+
rule /go+blin/ => "NILBOG"
|
84
|
+
|
85
|
+
) }
|
86
|
+
|
87
|
+
let(:input1) { %q(
|
88
|
+
|
89
|
+
fooooooooooooooobar
|
90
|
+
cookie
|
91
|
+
goooooblin
|
92
|
+
|
93
|
+
) }
|
94
|
+
|
95
|
+
let(:result1) { %q(
|
96
|
+
|
97
|
+
bazbag
|
98
|
+
cookie
|
99
|
+
NILBOG
|
100
|
+
|
101
|
+
) }
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
it 'reads rules from a file and applies to input file' do
|
106
|
+
opts = {:rule_files=>["rule_file"], :input=> ["input_file"]}
|
107
|
+
|
108
|
+
IO.stub(:read).with("rule_file").and_return rules
|
109
|
+
ARGF.stub!(:read).and_return input1
|
110
|
+
|
111
|
+
result = FiltriCmd.run(opts, opts[:input])
|
112
|
+
result.should eq(result1)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'reads single rules applies to input file' do
|
116
|
+
opts = {:rules=>['rule /fo+bar/ => "bazbag"','rule /go+blin/ => "NILBOG"'], :input=> ["input_file"]}
|
117
|
+
|
118
|
+
ARGF.stub!(:read).and_return input1
|
119
|
+
|
120
|
+
result = FiltriCmd.run(opts, opts[:input])
|
121
|
+
result.should eq(result1)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: filtri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '2.11'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2.11'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: docile
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +82,7 @@ dependencies:
|
|
82
82
|
requirements:
|
83
83
|
- - ! '>='
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
85
|
+
version: 0.1.0
|
86
86
|
type: :runtime
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - ! '>='
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
93
|
+
version: 0.1.0
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: to_regexp
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,11 +107,12 @@ dependencies:
|
|
107
107
|
- - ! '>='
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
-
description: Filtri is a
|
111
|
-
|
110
|
+
description: Filtri is a tool that simplifies the work of applying multiple substitution
|
111
|
+
rules to a string.
|
112
112
|
email:
|
113
113
|
- karl@ninjacontrol.com
|
114
|
-
executables:
|
114
|
+
executables:
|
115
|
+
- filtri
|
115
116
|
extensions: []
|
116
117
|
extra_rdoc_files: []
|
117
118
|
files:
|
@@ -120,9 +121,13 @@ files:
|
|
120
121
|
- LICENSE.txt
|
121
122
|
- README.md
|
122
123
|
- Rakefile
|
124
|
+
- bin/filtri
|
123
125
|
- filtri.gemspec
|
124
126
|
- lib/filtri.rb
|
127
|
+
- lib/filtri/command.rb
|
125
128
|
- lib/filtri/version.rb
|
129
|
+
- resource/filtri_rules.tmLanguage
|
130
|
+
- spec/command_spec.rb
|
126
131
|
- spec/filtri_spec.rb
|
127
132
|
homepage: https://github.com/karlll/filtri/
|
128
133
|
licenses:
|
@@ -136,10 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
141
|
requirements:
|
137
142
|
- - ! '>='
|
138
143
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
140
|
-
segments:
|
141
|
-
- 0
|
142
|
-
hash: 1607576313604211744
|
144
|
+
version: 1.9.3
|
143
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
146
|
none: false
|
145
147
|
requirements:
|
@@ -148,12 +150,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
150
|
version: '0'
|
149
151
|
segments:
|
150
152
|
- 0
|
151
|
-
hash:
|
153
|
+
hash: 107123931516266263
|
152
154
|
requirements: []
|
153
155
|
rubyforge_project:
|
154
156
|
rubygems_version: 1.8.24
|
155
157
|
signing_key:
|
156
158
|
specification_version: 3
|
157
|
-
summary: A tiny
|
159
|
+
summary: A tiny tool for text substitution
|
158
160
|
test_files:
|
161
|
+
- spec/command_spec.rb
|
159
162
|
- spec/filtri_spec.rb
|