sherlock 0.1.1 → 0.1.2
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/lib/collection.rb +8 -8
- data/lib/collection/base.rb +75 -76
- data/lib/collection/files.rb +77 -62
- data/lib/collection/lines.rb +32 -32
- data/lib/collection/matched_line.rb +56 -56
- data/lib/core_ext.rb +42 -42
- data/lib/latex.rb +55 -44
- data/lib/sherlock.rb +23 -32
- data/lib/version.rb +10 -0
- data/spec/collection/base_spec.rb +139 -141
- data/spec/collection/files_spec.rb +59 -46
- data/spec/collection/lines_spec.rb +1 -1
- data/spec/collection/matched_line_spec.rb +1 -1
- data/spec/fixtures/simple/lines.txt +5 -5
- data/spec/fixtures/simple/lorem.txt +18 -18
- data/spec/{detective_spec.rb → sherlock_spec.rb} +14 -14
- data/spec/spec_helper.rb +38 -38
- metadata +8 -9
data/lib/core_ext.rb
CHANGED
@@ -1,42 +1,42 @@
|
|
1
|
-
|
2
|
-
class ::Object
|
3
|
-
#:call-seq:
|
4
|
-
# obj.full?
|
5
|
-
# obj.full? { |f| ... }
|
6
|
-
#
|
7
|
-
# Returns wheter or not the given obj is not blank?.
|
8
|
-
# If a block is given and the obj is full?, the obj is yielded to that block.
|
9
|
-
#
|
10
|
-
# salary = nil
|
11
|
-
# salary.full? # => nil
|
12
|
-
# salary.full? { |s| "#{s} $" } # => nil
|
13
|
-
# salary = 100
|
14
|
-
# salary.full? { |s| "#{s} $" } # => "100 $"
|
15
|
-
#
|
16
|
-
# With ActiveSupport's implementation of Symbol#to_proc it is possible to write:
|
17
|
-
#
|
18
|
-
# current_user.full?(&:name) # => "Dave"
|
19
|
-
def full?
|
20
|
-
f = blank? ? nil : self
|
21
|
-
if block_given? and f
|
22
|
-
yield f
|
23
|
-
else
|
24
|
-
f
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class ::Symbol
|
30
|
-
# Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
|
31
|
-
#
|
32
|
-
# # The same as people.collect { |p| p.name }
|
33
|
-
# people.collect(&:name)
|
34
|
-
#
|
35
|
-
# # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
|
36
|
-
# people.select(&:manager?).collect(&:salary)
|
37
|
-
#
|
38
|
-
# (borrowed from ActiveSupport)
|
39
|
-
def to_proc
|
40
|
-
Proc.new { |*args| args.shift.__send__(self, *args) }
|
41
|
-
end
|
42
|
-
end
|
1
|
+
|
2
|
+
class ::Object
|
3
|
+
#:call-seq:
|
4
|
+
# obj.full?
|
5
|
+
# obj.full? { |f| ... }
|
6
|
+
#
|
7
|
+
# Returns wheter or not the given obj is not blank?.
|
8
|
+
# If a block is given and the obj is full?, the obj is yielded to that block.
|
9
|
+
#
|
10
|
+
# salary = nil
|
11
|
+
# salary.full? # => nil
|
12
|
+
# salary.full? { |s| "#{s} $" } # => nil
|
13
|
+
# salary = 100
|
14
|
+
# salary.full? { |s| "#{s} $" } # => "100 $"
|
15
|
+
#
|
16
|
+
# With ActiveSupport's implementation of Symbol#to_proc it is possible to write:
|
17
|
+
#
|
18
|
+
# current_user.full?(&:name) # => "Dave"
|
19
|
+
def full?
|
20
|
+
f = blank? ? nil : self
|
21
|
+
if block_given? and f
|
22
|
+
yield f
|
23
|
+
else
|
24
|
+
f
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ::Symbol
|
30
|
+
# Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
|
31
|
+
#
|
32
|
+
# # The same as people.collect { |p| p.name }
|
33
|
+
# people.collect(&:name)
|
34
|
+
#
|
35
|
+
# # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
|
36
|
+
# people.select(&:manager?).collect(&:salary)
|
37
|
+
#
|
38
|
+
# (borrowed from ActiveSupport)
|
39
|
+
def to_proc
|
40
|
+
Proc.new { |*args| args.shift.__send__(self, *args) }
|
41
|
+
end unless method_defined?(:to_proc)
|
42
|
+
end
|
data/lib/latex.rb
CHANGED
@@ -1,45 +1,56 @@
|
|
1
|
-
#!/usr/bin/env ruby -wKU
|
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
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
# this is still very experimental
|
4
|
+
#
|
5
|
+
# I want to be able to perform large LaTeX document analysis in an easy readable way
|
6
|
+
# e.g.
|
7
|
+
# Sherlock[:tex].inputs(:except => 'generated')
|
8
|
+
# # => all lines with input directives, except the ones containing 'generated'
|
9
|
+
# Sherlock[:tex].macros(:emph)
|
10
|
+
# # => all lines containing the \emph{} macro
|
11
|
+
#
|
12
|
+
# Maybe even environments could be analysed (e.g. figure and tabular)
|
13
|
+
#
|
14
|
+
module Sherlock
|
15
|
+
module LaTex #:nodoc:
|
16
|
+
class << self
|
17
|
+
def included(base)
|
18
|
+
base.__send__(:include, InstanceMethods)
|
19
|
+
Sherlock::Collection::Files.__send__(:include, Collection::Files::InstanceMethods)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module InstanceMethods
|
24
|
+
def tex_files(opts = {})
|
25
|
+
investigate('**/*.tex', opts)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module Collection
|
30
|
+
module Files
|
31
|
+
module InstanceMethods
|
32
|
+
def collect_macros(pattern)
|
33
|
+
collect(/\\(#{pattern})(\{([^\}]+)\})*/)
|
34
|
+
end
|
35
|
+
alias macros collect_macros
|
36
|
+
|
37
|
+
def inputs(opts = {})
|
38
|
+
macros(:input).filter(opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
def tagged(with_tag)
|
42
|
+
tag_prefix = "%%!!"
|
43
|
+
arr = [with_tag].flatten.map { |tag| "#{tag_prefix} #{tag}" }
|
44
|
+
containing(arr)
|
45
|
+
end
|
46
|
+
|
47
|
+
def not_tagged(with_tag)
|
48
|
+
tag_prefix = "%%!!"
|
49
|
+
arr = [with_tag].flatten.map { |tag| "#{tag_prefix} #{tag}" }
|
50
|
+
not_containing(arr)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
45
56
|
end
|
data/lib/sherlock.rb
CHANGED
@@ -1,33 +1,24 @@
|
|
1
|
-
#!/usr/bin/env ruby -wKU
|
2
|
-
|
3
|
-
# TODO: Output-Methoden für File- und Line-Collections, Tabellen, success & failure inkl. optionaler Colorierung.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
module
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
class << self
|
27
|
-
def included(base)
|
28
|
-
base.__send__(:include, InstanceMethods)
|
29
|
-
end
|
30
|
-
include InstanceMethods
|
31
|
-
alias [] collect_files_matching
|
32
|
-
end
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
# TODO: Output-Methoden für File- und Line-Collections, Tabellen, success & failure inkl. optionaler Colorierung.
|
4
|
+
|
5
|
+
%w(collection core_ext latex version).each do |_module|
|
6
|
+
require File.join(File.dirname(__FILE__), _module)
|
7
|
+
end
|
8
|
+
|
9
|
+
module Sherlock
|
10
|
+
module InstanceMethods
|
11
|
+
def collect_files_matching(*args)
|
12
|
+
Sherlock::Collection::Files.new(*args)
|
13
|
+
end
|
14
|
+
alias investigate collect_files_matching
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def included(base)
|
19
|
+
base.__send__(:include, InstanceMethods)
|
20
|
+
end
|
21
|
+
include InstanceMethods
|
22
|
+
alias [] collect_files_matching
|
23
|
+
end
|
33
24
|
end
|
data/lib/version.rb
ADDED
@@ -1,142 +1,140 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe Sherlock::Collection::Base do
|
4
|
-
def new_collection(arr = nil, opts = {})
|
5
|
-
arr ||= %w(eins zwei drei vier fünf)
|
6
|
-
Sherlock::Collection::Base.new(arr, opts)
|
7
|
-
end
|
8
|
-
|
9
|
-
def filter_arguments
|
10
|
-
[
|
11
|
-
[['ei']],
|
12
|
-
[[/ei/]],
|
13
|
-
[['sieben', 'sechs', 'fünf', 'vier']],
|
14
|
-
[[/ei/, 'fünf'], {:only => /ei$/, :except => 'zwei'}],
|
15
|
-
[{:only => /ei$/, :except => 'zwei'}],
|
16
|
-
]
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#initialize" do
|
20
|
-
it "creates an empty collection without arguments" do
|
21
|
-
empty_collection = Sherlock::Collection::Base.new
|
22
|
-
empty_collection.should be_empty
|
23
|
-
end
|
24
|
-
it "creates a full collection for a given array" do
|
25
|
-
collection = new_collection([:foo, :bar])
|
26
|
-
collection.should_not be_empty
|
27
|
-
end
|
28
|
-
it "creates a full collection for a given collection" do
|
29
|
-
collection = new_collection(new_collection)
|
30
|
-
collection.should_not be_empty
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#first" do
|
35
|
-
it "should give a collection with the first matching element for a string" do
|
36
|
-
collection = new_collection.first('ei')
|
37
|
-
collection.should == new_collection(%w(eins))
|
38
|
-
end
|
39
|
-
it "should give a collection with the first matching element for a regexp" do
|
40
|
-
collection = new_collection.first(/ei/)
|
41
|
-
collection.should == new_collection(%w(eins))
|
42
|
-
end
|
43
|
-
it "should give a collection with the first matching element for an array of strings" do
|
44
|
-
collection = new_collection.first(%w(sieben sechs fünf))
|
45
|
-
collection.should == new_collection(%w(fünf))
|
46
|
-
end
|
47
|
-
it "should give a collection with the first matching element for an array of regexps" do
|
48
|
-
collection = new_collection.first([/sieben/, /sechs/, /fünf/])
|
49
|
-
collection.should == new_collection(%w(fünf))
|
50
|
-
end
|
51
|
-
it "should give a collection with the first matching element for an array of strings and regexps" do
|
52
|
-
collection = new_collection.first([/sieben/, /sechs/, 'fünf'])
|
53
|
-
collection.should == new_collection(%w(fünf))
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe "#filter" do
|
58
|
-
# without real arguments
|
59
|
-
it "should give the same collection without arguments" do
|
60
|
-
collection = new_collection.filter
|
61
|
-
collection.should == new_collection
|
62
|
-
end
|
63
|
-
it "should give the same collection with empty arguments" do
|
64
|
-
collection = new_collection.filter([], {})
|
65
|
-
collection.should == new_collection
|
66
|
-
end
|
67
|
-
|
68
|
-
# without options
|
69
|
-
it "should give a collection with the matching elements for a string" do
|
70
|
-
collection = new_collection.filter('ei')
|
71
|
-
collection.should == new_collection(%w(eins zwei drei))
|
72
|
-
end
|
73
|
-
it "should give a collection with the matching elements for a regexp" do
|
74
|
-
collection = new_collection.filter(/ei/)
|
75
|
-
collection.should == new_collection(%w(eins zwei drei))
|
76
|
-
end
|
77
|
-
it "should give a collection with the matching elements for an array of strings" do
|
78
|
-
collection = new_collection.filter(%w(sieben sechs fünf vier))
|
79
|
-
collection.should == new_collection(%w(vier fünf))
|
80
|
-
end
|
81
|
-
it "should give a collection with the matching elements for an array of regexps" do
|
82
|
-
collection = new_collection.filter([/ei/, /sechs/, /fünf/])
|
83
|
-
collection.should == new_collection(%w(eins zwei drei fünf))
|
84
|
-
end
|
85
|
-
it "should give a collection with the matching elements for an array of strings and regexps" do
|
86
|
-
collection = new_collection.filter([/ei/, 'fünf'])
|
87
|
-
collection.should == new_collection(%w(eins zwei drei fünf))
|
88
|
-
end
|
89
|
-
|
90
|
-
# with options
|
91
|
-
it "should accept options as only argument" do
|
92
|
-
collection = new_collection.filter(:except => 'zwei')
|
93
|
-
collection.should == new_collection(%w(eins drei vier fünf))
|
94
|
-
end
|
95
|
-
it "should accept options as only argument (chained)" do
|
96
|
-
collection = new_collection.filter([/ei/, 'fünf']).filter(:except => 'zwei')
|
97
|
-
collection.should == new_collection(%w(eins drei fünf))
|
98
|
-
end
|
99
|
-
it "should filter results with :except option" do
|
100
|
-
collection = new_collection.filter([/ei/, 'fünf'], :except => 'zwei')
|
101
|
-
collection.should == new_collection(%w(eins drei fünf))
|
102
|
-
end
|
103
|
-
it "should filter results with :only option" do
|
104
|
-
collection = new_collection.filter([/ei/, 'fünf'], :only => /ei$/)
|
105
|
-
collection.should == new_collection(%w(zwei drei))
|
106
|
-
end
|
107
|
-
it "should filter results with :only option first and :except option afterwards" do
|
108
|
-
collection = new_collection.filter([/ei/, 'fünf'], :only => /ei$/, :except => 'zwei')
|
109
|
-
collection.should == new_collection(%w(drei))
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
describe "#[]" do
|
114
|
-
it "should be a shortcut for 'filter'" do
|
115
|
-
filter_arguments.each do |args|
|
116
|
-
new_collection[*args].should == new_collection.filter(*args)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe "#+" do
|
122
|
-
it "should combine two collections" do
|
123
|
-
collection1 = new_collection(nil, :only => 'eins')
|
124
|
-
collection2 = new_collection(nil, :only => 'zwei')
|
125
|
-
result = collection1 + collection2
|
126
|
-
result.should == new_collection(%w(eins zwei))
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
describe "#-" do
|
131
|
-
it "should reduce two collections" do
|
132
|
-
collection1 = new_collection(nil, :only => /ei/)
|
133
|
-
collection2 = new_collection(nil, :only => 'zwei')
|
134
|
-
result = collection1 - collection2
|
135
|
-
result.should == new_collection(%w(eins drei))
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# TODO: tests
|
140
|
-
# TODO: testen, dass filter(), und first() und containing und so alle String, Regexp sowie [String/Regexp] nehmen
|
141
|
-
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Sherlock::Collection::Base do
|
4
|
+
def new_collection(arr = nil, opts = {})
|
5
|
+
arr ||= %w(eins zwei drei vier fünf)
|
6
|
+
Sherlock::Collection::Base.new(arr, opts)
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter_arguments
|
10
|
+
[
|
11
|
+
[['ei']],
|
12
|
+
[[/ei/]],
|
13
|
+
[['sieben', 'sechs', 'fünf', 'vier']],
|
14
|
+
[[/ei/, 'fünf'], {:only => /ei$/, :except => 'zwei'}],
|
15
|
+
[{:only => /ei$/, :except => 'zwei'}],
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#initialize" do
|
20
|
+
it "creates an empty collection without arguments" do
|
21
|
+
empty_collection = Sherlock::Collection::Base.new
|
22
|
+
empty_collection.should be_empty
|
23
|
+
end
|
24
|
+
it "creates a full collection for a given array" do
|
25
|
+
collection = new_collection([:foo, :bar])
|
26
|
+
collection.should_not be_empty
|
27
|
+
end
|
28
|
+
it "creates a full collection for a given collection" do
|
29
|
+
collection = new_collection(new_collection)
|
30
|
+
collection.should_not be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#first" do
|
35
|
+
it "should give a collection with the first matching element for a string" do
|
36
|
+
collection = new_collection.first('ei')
|
37
|
+
collection.should == new_collection(%w(eins))
|
38
|
+
end
|
39
|
+
it "should give a collection with the first matching element for a regexp" do
|
40
|
+
collection = new_collection.first(/ei/)
|
41
|
+
collection.should == new_collection(%w(eins))
|
42
|
+
end
|
43
|
+
it "should give a collection with the first matching element for an array of strings" do
|
44
|
+
collection = new_collection.first(%w(sieben sechs fünf))
|
45
|
+
collection.should == new_collection(%w(fünf))
|
46
|
+
end
|
47
|
+
it "should give a collection with the first matching element for an array of regexps" do
|
48
|
+
collection = new_collection.first([/sieben/, /sechs/, /fünf/])
|
49
|
+
collection.should == new_collection(%w(fünf))
|
50
|
+
end
|
51
|
+
it "should give a collection with the first matching element for an array of strings and regexps" do
|
52
|
+
collection = new_collection.first([/sieben/, /sechs/, 'fünf'])
|
53
|
+
collection.should == new_collection(%w(fünf))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#filter" do
|
58
|
+
# without real arguments
|
59
|
+
it "should give the same collection without arguments" do
|
60
|
+
collection = new_collection.filter
|
61
|
+
collection.should == new_collection
|
62
|
+
end
|
63
|
+
it "should give the same collection with empty arguments" do
|
64
|
+
collection = new_collection.filter([], {})
|
65
|
+
collection.should == new_collection
|
66
|
+
end
|
67
|
+
|
68
|
+
# without options
|
69
|
+
it "should give a collection with the matching elements for a string" do
|
70
|
+
collection = new_collection.filter('ei')
|
71
|
+
collection.should == new_collection(%w(eins zwei drei))
|
72
|
+
end
|
73
|
+
it "should give a collection with the matching elements for a regexp" do
|
74
|
+
collection = new_collection.filter(/ei/)
|
75
|
+
collection.should == new_collection(%w(eins zwei drei))
|
76
|
+
end
|
77
|
+
it "should give a collection with the matching elements for an array of strings" do
|
78
|
+
collection = new_collection.filter(%w(sieben sechs fünf vier))
|
79
|
+
collection.should == new_collection(%w(vier fünf))
|
80
|
+
end
|
81
|
+
it "should give a collection with the matching elements for an array of regexps" do
|
82
|
+
collection = new_collection.filter([/ei/, /sechs/, /fünf/])
|
83
|
+
collection.should == new_collection(%w(eins zwei drei fünf))
|
84
|
+
end
|
85
|
+
it "should give a collection with the matching elements for an array of strings and regexps" do
|
86
|
+
collection = new_collection.filter([/ei/, 'fünf'])
|
87
|
+
collection.should == new_collection(%w(eins zwei drei fünf))
|
88
|
+
end
|
89
|
+
|
90
|
+
# with options
|
91
|
+
it "should accept options as only argument" do
|
92
|
+
collection = new_collection.filter(:except => 'zwei')
|
93
|
+
collection.should == new_collection(%w(eins drei vier fünf))
|
94
|
+
end
|
95
|
+
it "should accept options as only argument (chained)" do
|
96
|
+
collection = new_collection.filter([/ei/, 'fünf']).filter(:except => 'zwei')
|
97
|
+
collection.should == new_collection(%w(eins drei fünf))
|
98
|
+
end
|
99
|
+
it "should filter results with :except option" do
|
100
|
+
collection = new_collection.filter([/ei/, 'fünf'], :except => 'zwei')
|
101
|
+
collection.should == new_collection(%w(eins drei fünf))
|
102
|
+
end
|
103
|
+
it "should filter results with :only option" do
|
104
|
+
collection = new_collection.filter([/ei/, 'fünf'], :only => /ei$/)
|
105
|
+
collection.should == new_collection(%w(zwei drei))
|
106
|
+
end
|
107
|
+
it "should filter results with :only option first and :except option afterwards" do
|
108
|
+
collection = new_collection.filter([/ei/, 'fünf'], :only => /ei$/, :except => 'zwei')
|
109
|
+
collection.should == new_collection(%w(drei))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#[]" do
|
114
|
+
it "should be a shortcut for 'filter'" do
|
115
|
+
filter_arguments.each do |args|
|
116
|
+
new_collection[*args].should == new_collection.filter(*args)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#+" do
|
122
|
+
it "should combine two collections" do
|
123
|
+
collection1 = new_collection(nil, :only => 'eins')
|
124
|
+
collection2 = new_collection(nil, :only => 'zwei')
|
125
|
+
result = collection1 + collection2
|
126
|
+
result.should == new_collection(%w(eins zwei))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "#-" do
|
131
|
+
it "should reduce two collections" do
|
132
|
+
collection1 = new_collection(nil, :only => /ei/)
|
133
|
+
collection2 = new_collection(nil, :only => 'zwei')
|
134
|
+
result = collection1 - collection2
|
135
|
+
result.should == new_collection(%w(eins drei))
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# TODO: tests for #& und #|
|
142
140
|
end
|