textpow1x 1.0.0 → 1.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.
@@ -3,8 +3,6 @@ module Textpow
3
3
  end
4
4
  require 'oniguruma' unless Textpow::RUBY_19
5
5
 
6
- require 'plist'
7
-
8
6
  module Textpow
9
7
  class SyntaxProxy
10
8
  def initialize hash, syntax
@@ -42,10 +40,6 @@ module Textpow
42
40
  end
43
41
 
44
42
  class SyntaxNode
45
- unless Textpow::RUBY_19
46
- OPTIONS = {:options => Oniguruma::OPTION_CAPTURE_GROUP}
47
- end
48
-
49
43
  @@syntaxes = {}
50
44
 
51
45
  attr_accessor :syntax
@@ -67,72 +61,84 @@ module Textpow
67
61
  attr_accessor :repository
68
62
  attr_accessor :patterns
69
63
 
70
- def self.load filename, name_space = :default
71
- table = nil
72
- case filename
73
- when /(\.tmSyntax|\.plist)$/
74
- table = Plist::parse_xml( filename )
75
- else
76
- File.open( filename ) do |f|
77
- table = YAML.load( f )
78
- end
79
- end
80
- if table
81
- SyntaxNode.new( table, nil, name_space )
82
- else
83
- nil
84
- end
64
+ def self.load(file, name_space = :default)
65
+ table = convert_file_to_table(file)
66
+ SyntaxNode.new(table, nil, name_space)
85
67
  end
86
68
 
87
- def initialize hash, syntax = nil, name_space = :default
88
- @name_space = name_space
89
- @@syntaxes[@name_space] ||= {}
90
- @@syntaxes[@name_space][hash["scopeName"]] = self if hash["scopeName"]
69
+ def initialize(table, syntax = nil, name_space = :default)
91
70
  @syntax = syntax || self
92
- hash.each do |key, value|
71
+ @name_space = name_space
72
+
73
+ register_in_syntaxes(table["scopeName"])
74
+ parse_and_store_syntax_info(table)
75
+ end
76
+
77
+ def syntaxes
78
+ @@syntaxes[@name_space]
79
+ end
80
+
81
+ def parse(string, processor = RecordingProcessor.new)
82
+ processor.start_parsing scopeName
83
+ stack = [[self, nil]]
84
+ string.each_line do |line|
85
+ parse_line stack, line, processor
86
+ end
87
+ processor.end_parsing scopeName
88
+
89
+ processor
90
+ end
91
+
92
+ protected
93
+
94
+ def parse_and_store_syntax_info(table)
95
+ table.each do |key, value|
93
96
  case key
94
97
  when "firstLineMatch", "foldingStartMarker", "foldingStopMarker", "match", "begin"
95
98
  begin
96
- if Textpow::RUBY_19
99
+ regex = if Textpow::RUBY_19
97
100
  value.force_encoding("ASCII-8BIT")
98
- instance_variable_set( "@#{key}", Regexp.new( value ) )
101
+ Regexp.new(value)
99
102
  else
100
- instance_variable_set( "@#{key}", Oniguruma::ORegexp.new( value, OPTIONS ) )
103
+ Oniguruma::ORegexp.new(value, :options => Oniguruma::OPTION_CAPTURE_GROUP)
101
104
  end
105
+ instance_variable_set("@#{key}", regex)
102
106
  rescue ArgumentError => e
103
107
  raise ParsingError, "Parsing error in #{value}: #{e.to_s}"
104
108
  end
105
109
  when "content", "fileTypes", "name", "contentName", "end", "scopeName", "keyEquivalent"
106
- instance_variable_set( "@#{key}", value )
110
+ instance_variable_set("@#{key}", value)
107
111
  when "captures", "beginCaptures", "endCaptures"
108
- instance_variable_set( "@#{key}", value.sort )
112
+ instance_variable_set("@#{key}", value.sort)
109
113
  when "repository"
110
114
  parse_repository value
111
115
  when "patterns"
112
116
  create_children value
117
+ when "comment"
113
118
  else
114
119
  STDERR.puts "Ignoring: #{key} => #{value.gsub("\n", "\n>>")}" if $DEBUG
115
120
  end
116
121
  end
117
122
  end
118
123
 
119
-
120
- def syntaxes
121
- @@syntaxes[@name_space]
124
+ # register in global syntax list -> can be found by include
125
+ def register_in_syntaxes(scope)
126
+ @@syntaxes[@name_space] ||= {}
127
+ @@syntaxes[@name_space][scope] = self if scope
122
128
  end
123
129
 
124
- def parse( string, processor = nil )
125
- processor.start_parsing self.scopeName if processor
126
- stack = [[self, nil]]
127
- string.each_line do |line|
128
- parse_line stack, line, processor
130
+ def self.convert_file_to_table(file)
131
+ raise "File not found: #{file}" unless File.exist?(file)
132
+
133
+ case file
134
+ when /(\.tmSyntax|\.plist)$/
135
+ require 'plist'
136
+ Plist::parse_xml(file)
137
+ else
138
+ YAML.load_file(file)
129
139
  end
130
- processor.end_parsing self.scopeName if processor
131
- processor
132
140
  end
133
141
 
134
- protected
135
-
136
142
  def parse_repository repository
137
143
  @repository = {}
138
144
  repository.each do |key, value|
@@ -233,91 +239,80 @@ module Textpow
233
239
  end
234
240
  end
235
241
 
236
- def match_first_son string, position
242
+ def match_first_son(string, position)
243
+ return if not patterns
244
+
237
245
  match = nil
238
- if self.patterns
239
- self.patterns.each do |p|
240
- tmatch = p.match_first string, position
241
- if tmatch
242
- ok = if Textpow::RUBY_19
243
- ! match || match[1].offset(0).first > tmatch[1].offset(0).first
244
- else
245
- ! match || match[1].offset.first > tmatch[1].offset.first
246
- end
247
- match = tmatch if ok
248
- #break if tmatch[1].offset.first == position
246
+ patterns.each do |p|
247
+ tmatch = p.match_first string, position
248
+ if tmatch
249
+ if not match or match_offset(match[1]).first > match_offset(tmatch[1]).first
250
+ match = tmatch
249
251
  end
252
+ #break if tmatch[1].offset.first == position
250
253
  end
251
254
  end
252
255
  match
253
256
  end
254
257
 
255
- def parse_line stack, line, processor
256
- processor.new_line line if processor
258
+ def parse_line(stack, line, processor)
259
+ processor.new_line line
257
260
  top, match = stack.last
258
261
  position = 0
259
262
  #@ln ||= 0
260
263
  #@ln += 1
261
264
  #STDERR.puts @ln
262
- while true
265
+ loop do
263
266
  if top.patterns
264
- pattern, pattern_match = top.match_first_son line, position
265
- else
266
- pattern, pattern_match = nil
267
+ pattern, pattern_match = top.match_first_son(line, position)
267
268
  end
268
269
 
269
- end_match = nil
270
270
  if top.end
271
271
  end_match = top.match_end( line, match, position )
272
272
  end
273
273
 
274
- ok = if Textpow::RUBY_19
275
- end_match && ( ! pattern_match || pattern_match.offset(0).first >= end_match.offset(0).first )
276
- else
277
- end_match && ( ! pattern_match || pattern_match.offset.first >= end_match.offset.first )
278
- end
279
-
280
- if ok
274
+ if end_match and (not pattern_match or match_offset(pattern_match).first >= match_offset(end_match).first)
281
275
  pattern_match = end_match
282
- if Textpow::RUBY_19
283
- start_pos = pattern_match.offset(0).first
284
- end_pos = pattern_match.offset(0).last
285
- else
286
- start_pos = pattern_match.offset.first
287
- end_pos = pattern_match.offset.last
288
- end
289
- processor.close_tag top.contentName, start_pos if top.contentName && processor
290
- parse_captures "captures", top, pattern_match, processor if processor
291
- parse_captures "endCaptures", top, pattern_match, processor if processor
292
- processor.close_tag top.name, end_pos if top.name && processor
276
+ start_pos = match_offset(pattern_match).first
277
+ end_pos = match_offset(pattern_match).last
278
+
279
+ processor.close_tag top.contentName, start_pos if top.contentName
280
+ parse_captures "captures", top, pattern_match, processor
281
+ parse_captures "endCaptures", top, pattern_match, processor
282
+ processor.close_tag top.name, end_pos if top.name
293
283
  stack.pop
294
284
  top, match = stack.last
295
285
  else
296
286
  break unless pattern
297
- if Textpow::RUBY_19
298
- start_pos = pattern_match.offset(0).first
299
- end_pos = pattern_match.offset(0).last
300
- else
301
- start_pos = pattern_match.offset.first
302
- end_pos = pattern_match.offset.last
303
- end
287
+
288
+ start_pos = match_offset(pattern_match).first
289
+ end_pos = match_offset(pattern_match).last
304
290
 
305
291
  if pattern.begin
306
- processor.open_tag pattern.name, start_pos if pattern.name && processor
307
- parse_captures "captures", pattern, pattern_match, processor if processor
308
- parse_captures "beginCaptures", pattern, pattern_match, processor if processor
309
- processor.open_tag pattern.contentName, end_pos if pattern.contentName && processor
292
+ processor.open_tag pattern.name, start_pos if pattern.name
293
+ parse_captures "captures", pattern, pattern_match, processor
294
+ parse_captures "beginCaptures", pattern, pattern_match, processor
295
+ processor.open_tag pattern.contentName, end_pos if pattern.contentName
310
296
  top = pattern
311
297
  match = pattern_match
312
298
  stack << [top, match]
313
299
  elsif pattern.match
314
- processor.open_tag pattern.name, start_pos if pattern.name && processor
315
- parse_captures "captures", pattern, pattern_match, processor if processor
316
- processor.close_tag pattern.name, end_pos if pattern.name && processor
300
+ processor.open_tag pattern.name, start_pos if pattern.name
301
+ parse_captures "captures", pattern, pattern_match, processor
302
+ processor.close_tag pattern.name, end_pos if pattern.name
317
303
  end
318
304
  end
305
+
319
306
  position = end_pos
320
307
  end
321
308
  end
309
+
310
+ def match_offset(match)
311
+ if Textpow::RUBY_19
312
+ match.offset(0)
313
+ else
314
+ match.offset
315
+ end
316
+ end
322
317
  end
323
318
  end
@@ -1,3 +1,3 @@
1
1
  module Textpow
2
- Version = "1.0.0"
2
+ VERSION = Version = "1.1.0"
3
3
  end
data/lib/textpow.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'textpow/syntax'
3
3
  require 'textpow/debug_processor'
4
+ require 'textpow/recording_processor'
4
5
  require 'textpow/score_manager'
5
6
  require 'textpow/version'
6
7
 
@@ -0,0 +1,107 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>BBEditDocumentType</key>
6
+ <string>CodelessLanguageModule</string>
7
+ <key>BBLMColorsSyntax</key>
8
+ <true/>
9
+ <key>BBLMIsCaseSensitive</key>
10
+ <true/>
11
+ <key>BBLMKeywordList</key>
12
+ <array>
13
+ <string>and</string>
14
+ <string>or</string>
15
+ <string>xor</string>
16
+ <string>virtual</string>
17
+ <string>if</string>
18
+ <string>else</string>
19
+ <string>do</string>
20
+ <string>while</string>
21
+ <string>use</string>
22
+ <string>bundle</string>
23
+ <string>native</string>
24
+ <string>static</string>
25
+ <string>public</string>
26
+ <string>private</string>
27
+ <string>class</string>
28
+ <string>interface</string>
29
+ <string>select</string>
30
+ <string>other</string>
31
+ <string>enum</string>
32
+ <string>for</string>
33
+ <string>each</string>
34
+ <string>label</string>
35
+ <string>return</string>
36
+ <string>Byte</string>
37
+ <string>Int</string>
38
+ <string>Parent</string>
39
+ <string>from</string>
40
+ <string>Float</string>
41
+ <string>Char</string>
42
+ <string>Bool</string>
43
+ <string>String</string>
44
+ <string>Nil</string>
45
+ <string>true</string>
46
+ <string>false</string>
47
+ <string>function</string>
48
+ <string>method</string>
49
+ </array>
50
+ <key>BBLMLanguageCode</key>
51
+ <string>LSL</string>
52
+ <key>BBLMLanguageDisplayName</key>
53
+ <string>Objeck</string>
54
+ <key>BBLMScansFunctions</key>
55
+ <true/>
56
+ <key>BBLMSuffixMap</key>
57
+ <array>
58
+ <dict>
59
+ <key>BBLMLanguageSuffix</key>
60
+ <string>.obs</string>
61
+ </dict>
62
+ </array>
63
+ <key>Language Features</key>
64
+ <dict>
65
+ <key>Close Block Comments</key>
66
+ <string>~#</string>
67
+ <key>Close Parameter Lists</key>
68
+ <string>)</string>
69
+ <key>Close Statement Blocks</key>
70
+ <string>}</string>
71
+ <key>Close Strings 1</key>
72
+ <string>&quot;</string>
73
+ <key>Close Strings 2</key>
74
+ <string>&apos;</string>
75
+ <key>End-of-line Ends Strings 1</key>
76
+ <false/>
77
+ <key>End-of-line Ends Strings 2</key>
78
+ <false/>
79
+ <key>Escape Char in Strings 1</key>
80
+ <string>\</string>
81
+ <key>Escape Char in Strings 2</key>
82
+ <string>\</string>
83
+ <key>Identifier and Keyword Characters</key>
84
+ <string>@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz</string>
85
+ <key>Open Block Comments</key>
86
+ <string>#~</string>
87
+ <key>Open Line Comments</key>
88
+ <string>#</string>
89
+ <key>Open Parameter Lists</key>
90
+ <string>(</string>
91
+ <key>Open Statement Blocks</key>
92
+ <string>{</string>
93
+ <key>Open Strings 1</key>
94
+ <string>&quot;</string>
95
+ <key>Open Strings 2</key>
96
+ <string>&apos;</string>
97
+ <key>Prefix for Functions</key>
98
+ <string></string>
99
+ <key>Prefix for Procedures</key>
100
+ <string></string>
101
+ <key>Terminator for Prototypes 1</key>
102
+ <string></string>
103
+ <key>Terminator for Prototypes 2</key>
104
+ <string></string>
105
+ </dict>
106
+ </dict>
107
+ </plist>
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Textpow::ScoreManager do
4
+ it "calculates scores" do
5
+ sp = Textpow::ScoreManager.new
6
+ reference_scope = 'text.html.basic source.php.embedded.html string.quoted.double.php'
7
+
8
+ sp.score('source.php string', reference_scope).should_not == 0
9
+ sp.score('text.html source.php', reference_scope).should_not == 0
10
+ sp.score('string source.php', reference_scope).should == 0
11
+ sp.score('source.php text.html', reference_scope).should == 0
12
+
13
+ sp.score('text.html source.php - string', reference_scope).should == 0
14
+ sp.score('text.html source.php - ruby', reference_scope ).should_not == 0
15
+
16
+ sp.score('string', reference_scope).should > sp.score('source.php', reference_scope)
17
+ sp.score('string.quoted', reference_scope).should > sp.score('source.php', reference_scope)
18
+ sp.score('text source string', reference_scope).should > sp.score( 'source string', reference_scope)
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "syntax files" do
4
+ before do
5
+ STDERR.stub!(:puts)
6
+ end
7
+
8
+ let(:processor){ Textpow::DebugProcessor.new }
9
+
10
+ it "has syntax files" do
11
+ Dir["#{Textpow.syntax_path}/*.syntax"].should_not == []
12
+ end
13
+
14
+ Dir["#{Textpow.syntax_path}/*.syntax"].each do |syntax|
15
+ it "#{syntax} can parse" do
16
+ node = Textpow::SyntaxNode.load(syntax)
17
+ node.parse("xxx\n1 + 1\n### xxx", processor)
18
+ end
19
+ end
20
+
21
+ # syntax broken in 1.9
22
+ xit "parses markdown" do
23
+ node = Textpow::SyntaxNode.load("#{Textpow.syntax_path}/broken/markdown.syntax")
24
+ node.parse("### xxx\nabc\n xxx\n yyy\n - abc\n - ac", processor)
25
+ end
26
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe Textpow::SyntaxNode do
4
+ before do
5
+ Textpow::SyntaxNode.send(:class_variable_set, "@@syntaxes", {})
6
+ end
7
+
8
+ describe "#load" do
9
+ it "can load from xml .plist" do
10
+ Textpow::SyntaxNode.load('spec/fixtures/objeck.plist').should_not == nil
11
+ end
12
+
13
+ it "can load from yaml .syntax" do
14
+ Textpow::SyntaxNode.load('lib/textpow/syntax/ruby.syntax').should_not == nil
15
+ end
16
+
17
+ it "cannot load missing file" do
18
+ lambda{
19
+ Textpow::SyntaxNode.load('xxx.syntax')
20
+ }.should raise_error
21
+ end
22
+
23
+ it "cannot load missing plist file" do
24
+ lambda{
25
+ Textpow::SyntaxNode.load('xxx.plist')
26
+ }.should raise_error
27
+ end
28
+ end
29
+
30
+ describe "#new" do
31
+ it "loads strings from given hash" do
32
+ syntax = Textpow::SyntaxNode.new('content' => 'CONTENT', 'name' => 'NAME')
33
+ syntax.content.should == 'CONTENT'
34
+ syntax.name.should == 'NAME'
35
+ end
36
+
37
+ it "loads regex from given hash" do
38
+ syntax = Textpow::SyntaxNode.new('firstLineMatch' => 'aaa', 'foldingStartMarker' => 'bbb')
39
+ syntax.firstLineMatch.inspect.should == "/aaa/"
40
+ syntax.foldingStartMarker.inspect.should == "/bbb/"
41
+ end
42
+
43
+ it "raises ParsingError on invalid regex" do
44
+ lambda{
45
+ Textpow::SyntaxNode.new('firstLineMatch' => '$?)(:[/\]')
46
+ }.should raise_error(Textpow::ParsingError)
47
+ end
48
+
49
+ it "stores itself as parent" do
50
+ node = Textpow::SyntaxNode.new({})
51
+ node.syntax.should == node
52
+ end
53
+
54
+ it "stores given parent" do
55
+ node = Textpow::SyntaxNode.new({}, 1)
56
+ node.syntax.should == 1
57
+ end
58
+
59
+ it "stores itself in global namespace under scopeName" do
60
+ node = Textpow::SyntaxNode.new("scopeName" => 'xxx')
61
+ node.syntaxes['xxx'].should == node
62
+ Textpow::SyntaxNode.new({}).syntaxes['xxx'].should == node
63
+ end
64
+
65
+ it "stores itself in scoped global namespace under scopeName" do
66
+ node = Textpow::SyntaxNode.new({"scopeName" => 'xxx'}, nil, 'foo')
67
+ node.syntaxes['xxx'].should == node
68
+ Textpow::SyntaxNode.new({},nil,'foo').syntaxes['xxx'].should == node
69
+ Textpow::SyntaxNode.new({}).syntaxes['xxx'].should == nil
70
+ end
71
+ end
72
+
73
+ describe "#parse" do
74
+ let(:node){ Textpow::SyntaxNode.load('lib/textpow/syntax/ruby.syntax') }
75
+
76
+ it "uses a RecordingProcessor by default" do
77
+ node.parse("111").stack.should == [
78
+ [:start_parsing, "source.ruby"],
79
+ [:new_line, "111"],
80
+ [:open_tag, "constant.numeric.ruby", 0],
81
+ [:close_tag, "constant.numeric.ruby", 3],
82
+ [:end_parsing, "source.ruby"]
83
+ ]
84
+ end
85
+
86
+ it "can parse with a processor" do
87
+ processor = Textpow::RecordingProcessor.new
88
+ processor.stack << 'xxx'
89
+ node.parse("111", processor).stack.should == [
90
+ "xxx",
91
+ [:start_parsing, "source.ruby"],
92
+ [:new_line, "111"],
93
+ [:open_tag, "constant.numeric.ruby", 0],
94
+ [:close_tag, "constant.numeric.ruby", 3],
95
+ [:end_parsing, "source.ruby"]
96
+ ]
97
+ end
98
+ end
99
+ end
data/spec/textpow_spec.rb CHANGED
@@ -1,34 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Textpow::ScoreManager do
4
- # TODO legacy test
5
- it "calculates scores" do
6
- sp = Textpow::ScoreManager.new
7
- reference_scope = 'text.html.basic source.php.embedded.html string.quoted.double.php'
8
-
9
- sp.score('source.php string', reference_scope).should_not == 0
10
- sp.score('text.html source.php', reference_scope).should_not == 0
11
- sp.score('string source.php', reference_scope).should == 0
12
- sp.score('source.php text.html', reference_scope).should == 0
13
-
14
- sp.score('text.html source.php - string', reference_scope).should == 0
15
- sp.score('text.html source.php - ruby', reference_scope ).should_not == 0
16
-
17
- sp.score('string', reference_scope).should > sp.score('source.php', reference_scope)
18
- sp.score('string.quoted', reference_scope).should > sp.score('source.php', reference_scope)
19
- sp.score('text source string', reference_scope).should > sp.score( 'source string', reference_scope)
20
- end
21
-
22
- describe "syntax" do
23
- it "has syntax files" do
24
- Dir["#{Textpow.syntax_path}/*.syntax"].should_not == []
25
- end
26
-
27
- Dir["#{Textpow.syntax_path}/*.syntax"].each do |syntax|
28
- it "#{syntax} can parse" do
29
- node = Textpow::SyntaxNode.load(syntax)
30
- node.parse("xxx\n1 + 1\n### xxx")
31
- end
32
- end
3
+ describe Textpow do
4
+ it "has a version" do
5
+ Textpow::Version =~ /^\d\.\d\.\d$/
33
6
  end
34
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: textpow1x
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 0
10
- version: 1.0.0
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dizan Vasquez
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-10-02 00:00:00 +02:00
21
+ date: 2011-10-06 00:00:00 +02:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -49,16 +49,21 @@ extra_rdoc_files: []
49
49
 
50
50
  files:
51
51
  - .gitignore
52
+ - .travis.yml
52
53
  - Gemfile
53
54
  - Gemfile.lock
54
55
  - History.rdoc
56
+ - MIT-LICENSE.txt
55
57
  - Manifest.txt
56
58
  - README.rdoc
57
59
  - Rakefile
58
60
  - bin/plist2syntax
59
61
  - bin/plist2yaml
62
+ - examples/benchmark_js.rb
63
+ - examples/jquery.js
60
64
  - lib/textpow.rb
61
65
  - lib/textpow/debug_processor.rb
66
+ - lib/textpow/recording_processor.rb
62
67
  - lib/textpow/score_manager.rb
63
68
  - lib/textpow/syntax.rb
64
69
  - lib/textpow/syntax/actionscript.syntax
@@ -225,7 +230,11 @@ files:
225
230
  - lib/textpow/syntax/yaml.syntax
226
231
  - lib/textpow/syntax/yui_javascript.syntax
227
232
  - lib/textpow/version.rb
233
+ - spec/fixtures/objeck.plist
228
234
  - spec/spec_helper.rb
235
+ - spec/textpow/score_manager_spec.rb
236
+ - spec/textpow/syntax_files_spec.rb
237
+ - spec/textpow/syntax_spec.rb
229
238
  - spec/textpow_spec.rb
230
239
  has_rdoc: true
231
240
  homepage: http://github.com/grosser/textpow