visionmedia-lightr 0.0.4 → 0.0.5
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/History.rdoc +16 -0
- data/Manifest +9 -3
- data/README.rdoc +3 -26
- data/Rakefile +3 -2
- data/Todo.rdoc +8 -3
- data/benchmarks/_huge.rb +1620 -0
- data/benchmarks/_large.rb +509 -0
- data/benchmarks/helper.rb +12 -0
- data/benchmarks/huge.rb +19 -0
- data/benchmarks/large.rb +20 -0
- data/examples/javascript.rb +18 -13
- data/examples/ruby.rb +12 -2
- data/ext/javascript.rl +62 -0
- data/ext/ruby.rl +83 -0
- data/lib/lightr.rb +0 -2
- data/lib/lightr/grammars.rb +0 -1
- data/lib/lightr/grammars/javascript.rb +2784 -12
- data/lib/lightr/grammars/ruby.rb +6039 -22
- data/lib/lightr/mixins/grammar.rb +9 -48
- data/lib/lightr/version.rb +1 -1
- data/lightr.gemspec +7 -7
- data/spec/grammars/javascript_spec.rb +44 -17
- data/spec/grammars/ruby_spec.rb +128 -24
- data/spec/spec_helper.rb +29 -0
- data/tasks/benchmark.rake +6 -0
- data/tasks/ext.rake +20 -0
- metadata +18 -8
- data/examples/c.rb +0 -47
- data/lib/lightr/grammars/c.rb +0 -16
- data/spec/grammars/c_spec.rb +0 -39
@@ -1,53 +1,29 @@
|
|
1
1
|
|
2
2
|
module Lightr
|
3
|
-
|
4
|
-
##
|
5
|
-
# = Grammar
|
6
|
-
#
|
7
|
-
# Primary Lightr syntax highlighting mixin, providing
|
8
|
-
# the #match method to create your own Lightr DSL.
|
9
|
-
#
|
10
|
-
# === Examples
|
11
|
-
#
|
12
|
-
# module Lightr
|
13
|
-
# class Ruby
|
14
|
-
# include Grammar
|
15
|
-
# id = /[\w\d]*/
|
16
|
-
# int = /\d[\d_]*/
|
17
|
-
# match :comment, /#.*?(\n|\z)/
|
18
|
-
# match :constant, /[A-Z]#{id}/
|
19
|
-
# match :symbol, /:#{id}/
|
20
|
-
# match :number, /-?#{int}(?:\.#{int})?/
|
21
|
-
# match nil, /\n|\s|.+?/
|
22
|
-
# ...
|
23
|
-
#
|
24
|
-
|
25
3
|
module Grammar
|
26
4
|
def self.included base
|
27
5
|
base.extend ClassMethods
|
28
6
|
base.send :include, InstanceMethods
|
29
7
|
end
|
30
|
-
|
8
|
+
|
31
9
|
module ClassMethods
|
32
|
-
def match name, regexp
|
33
|
-
(@matchers ||= []) << [name, regexp]
|
34
|
-
end
|
35
|
-
|
36
10
|
def parse input
|
37
11
|
new(input).parse!
|
38
12
|
end
|
39
13
|
end
|
40
|
-
|
14
|
+
|
41
15
|
module InstanceMethods
|
42
16
|
attr_reader :input, :output
|
43
17
|
alias :to_s :output
|
44
|
-
|
18
|
+
|
45
19
|
def initialize input
|
46
20
|
@input, @output = input, ''
|
47
|
-
@matchers = self.class.instance_variable_get :"@matchers"
|
48
|
-
@regexp = Regexp.union *@matchers.transpose[1]
|
49
21
|
end
|
50
|
-
|
22
|
+
|
23
|
+
def parse!
|
24
|
+
parse @input
|
25
|
+
end
|
26
|
+
|
51
27
|
def escape string
|
52
28
|
string.
|
53
29
|
gsub(/&/, '&').
|
@@ -55,21 +31,6 @@ module Lightr
|
|
55
31
|
gsub(/>/, '>').
|
56
32
|
gsub(/"/, '"')
|
57
33
|
end
|
58
|
-
|
59
|
-
def wrap string
|
60
|
-
@matchers.each do |name, regexp|
|
61
|
-
return escape(string) if name.nil? and string =~ regexp
|
62
|
-
return %(<span class="#{name}">#{escape(string)}</span>) if string =~ regexp
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def parse!
|
67
|
-
@input.dup.gsub @regexp do |match|
|
68
|
-
@output << wrap(match)
|
69
|
-
end
|
70
|
-
self
|
71
|
-
end
|
72
34
|
end
|
73
|
-
|
74
35
|
end
|
75
|
-
end
|
36
|
+
end
|
data/lib/lightr/version.rb
CHANGED
data/lightr.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{lightr}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.5"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["TJ Holowaychuk"]
|
9
|
-
s.date = %q{2009-
|
10
|
-
s.description = %q{
|
9
|
+
s.date = %q{2009-04-06}
|
10
|
+
s.description = %q{High performance syntax highlighting.}
|
11
11
|
s.email = %q{tj@vision-media.ca}
|
12
|
-
s.extra_rdoc_files = ["
|
13
|
-
s.files = ["
|
12
|
+
s.extra_rdoc_files = ["ext/javascript.rl", "ext/ruby.rl", "lib/lightr/grammars/javascript.rb", "lib/lightr/grammars/ruby.rb", "lib/lightr/grammars.rb", "lib/lightr/mixins/grammar.rb", "lib/lightr/mixins.rb", "lib/lightr/version.rb", "lib/lightr.rb", "README.rdoc", "tasks/benchmark.rake", "tasks/docs.rake", "tasks/ext.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
|
13
|
+
s.files = ["benchmarks/_huge.rb", "benchmarks/_large.rb", "benchmarks/helper.rb", "benchmarks/huge.rb", "benchmarks/large.rb", "examples/javascript.rb", "examples/ruby.rb", "ext/javascript.rl", "ext/ruby.rl", "History.rdoc", "lib/lightr/grammars/javascript.rb", "lib/lightr/grammars/ruby.rb", "lib/lightr/grammars.rb", "lib/lightr/mixins/grammar.rb", "lib/lightr/mixins.rb", "lib/lightr/version.rb", "lib/lightr.rb", "lightr.gemspec", "Manifest", "Rakefile", "README.rdoc", "spec/grammars/javascript_spec.rb", "spec/grammars/ruby_spec.rb", "spec/spec_helper.rb", "tasks/benchmark.rake", "tasks/docs.rake", "tasks/ext.rake", "tasks/gemspec.rake", "tasks/spec.rake", "Todo.rdoc"]
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.homepage = %q{http://github.com/visionmedia/lightr}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Lightr", "--main", "README.rdoc"]
|
17
|
-
s.require_paths = ["lib"]
|
17
|
+
s.require_paths = ["lib", "ext"]
|
18
18
|
s.rubyforge_project = %q{lightr}
|
19
19
|
s.rubygems_version = %q{1.3.1}
|
20
|
-
s.summary = %q{
|
20
|
+
s.summary = %q{High performance syntax highlighting.}
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
23
23
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -8,30 +8,57 @@ describe Lightr::JavaScript do
|
|
8
8
|
describe "should highlight" do
|
9
9
|
|
10
10
|
it 'strings' do
|
11
|
-
parse('"test"').should
|
12
|
-
parse("'test'").should
|
11
|
+
parse('"test"').should highlight(:string, '"test"')
|
12
|
+
parse("'test'").should highlight(:string, "'test'")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "strings with escaped quotes" do
|
16
|
+
parse("'\''").should highlight(:string, "'\\''")
|
17
|
+
parse('"\""').should highlight(:string, '"\""')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'this' do
|
21
|
+
parse('this.test').should highlight(:self, 'this')
|
13
22
|
end
|
14
23
|
|
15
24
|
it 'comments' do
|
16
|
-
parse(
|
17
|
-
|
18
|
-
|
25
|
+
parse("//foo bar\n").should highlight(:comment, "//foo bar\n")
|
26
|
+
parse("test /// foo 'bar' \n").should highlight(:comment, "/// foo 'bar' \n")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "regular expressions" do
|
30
|
+
parse('/test/').should highlight(:regexp, '/test/')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "regular expressions with mode flags" do
|
34
|
+
parse('/test/sex').should highlight(:regexp, '/test/sex')
|
35
|
+
parse('/test/sex test').should highlight(:regexp, '/test/sex')
|
36
|
+
end
|
37
|
+
|
38
|
+
it "integers" do
|
39
|
+
parse('100').should highlight(:number, '100')
|
40
|
+
parse('100').should highlight(:int, '100')
|
41
|
+
end
|
42
|
+
|
43
|
+
it "floats" do
|
44
|
+
parse('1.3').should highlight(:number, '1.3')
|
45
|
+
parse('1.3').should highlight(:float, '1.3')
|
19
46
|
end
|
20
47
|
|
21
|
-
|
22
|
-
|
23
|
-
|
48
|
+
it "constructors as constants" do
|
49
|
+
parse('FooBar').should highlight(:constant, 'FooBar')
|
50
|
+
parse('FOOBAR').should highlight(:constant, 'FOOBAR')
|
51
|
+
end
|
52
|
+
|
53
|
+
%w( if else break default case continue do delete true false class enum const final
|
54
|
+
for function instanceof new null return throw try typeof var void with while finally in ).
|
24
55
|
each do |keyword|
|
25
56
|
it "#{keyword.strip} as a keyword" do
|
26
|
-
parse("#{keyword.strip} foo").should
|
57
|
+
parse("\n#{keyword.strip} foo").should highlight(:keyword, keyword.strip)
|
58
|
+
parse("(#{keyword.strip})").should highlight(:keyword, keyword.strip)
|
27
59
|
end
|
28
60
|
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'should not highlight // within strings as comment' do
|
33
|
-
parse('"//test"').should include(%(class="string">"//test"))
|
34
|
-
parse("'//test'").should include(%(class="string">'//test'))
|
61
|
+
|
35
62
|
end
|
36
|
-
|
37
|
-
end
|
63
|
+
|
64
|
+
end
|
data/spec/grammars/ruby_spec.rb
CHANGED
@@ -8,65 +8,169 @@ describe Lightr::Ruby do
|
|
8
8
|
describe "should highlight" do
|
9
9
|
|
10
10
|
it 'symbols' do
|
11
|
-
parse('a :symbol').should
|
12
|
-
parse(':"foo bar" test').should
|
11
|
+
parse('a :symbol is cool').should highlight(:symbol, ':symbol')
|
12
|
+
parse(':"foo bar" test').should highlight(:symbol, ':"foo bar"')
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'strings' do
|
16
|
-
parse('"test"').should
|
17
|
-
parse("'test'").should
|
16
|
+
parse('"test"').should highlight(:string, '"test"')
|
17
|
+
parse("'test'").should highlight(:string, "'test'")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "strings with escaped quotes" do
|
21
|
+
parse("'\''").should highlight(:string, "'\\''")
|
22
|
+
parse('"\""').should highlight(:string, '"\""')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "string %( alternate syntax" do
|
26
|
+
parse('%(something)').should highlight(:string, '%(something)')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "strings with interpolation" do
|
30
|
+
output = parse("begin#\{ (foo ? 'foo' : 'bar' ) \}end")
|
31
|
+
output.should include('class="string">begin<')
|
32
|
+
output.should include('class="string">foo<')
|
33
|
+
output.should include('class="string">bar<')
|
34
|
+
output.should include('class="string">end<')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "array %w( alternative syntax" do
|
38
|
+
parse('%w( foo bar )').should highlight(:string, '%w( foo bar )')
|
39
|
+
parse('%w( foo bar )').should highlight(:array, '%w( foo bar )')
|
18
40
|
end
|
19
41
|
|
20
42
|
it 'self' do
|
21
|
-
parse('self.test').should
|
43
|
+
parse('self.test').should highlight(:self, 'self')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "block params" do
|
47
|
+
parse('|foo, bar|').should highlight(:params, '|foo, bar|')
|
22
48
|
end
|
23
49
|
|
24
50
|
it 'comments' do
|
25
|
-
parse(
|
51
|
+
parse("# foo bar\n").should highlight(:comment, "# foo bar\n")
|
52
|
+
parse("test # foo 'bar' \n").should highlight(:comment, "# foo 'bar' \n")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "shell" do
|
56
|
+
parse("`foo bar`").should highlight(:shell, '`foo bar`')
|
57
|
+
parse("`foo bar`").should highlight(:string, '`foo bar`')
|
58
|
+
end
|
59
|
+
|
60
|
+
it "shell %x{ alternative syntax" do
|
61
|
+
parse("%x{foo}").should highlight(:shell, '%x{foo}')
|
62
|
+
parse("%x{foo}").should highlight(:string, '%x{foo}')
|
26
63
|
end
|
27
64
|
|
28
65
|
it "regular expressions" do
|
29
|
-
parse('/test/').should
|
66
|
+
parse('/test/').should highlight(:regexp, '/test/')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "regular expressions when using %r{ alternative syntax" do
|
70
|
+
parse('%r{/foo/}').should highlight(:regexp, '%r{/foo/}')
|
71
|
+
parse('%r{/foo/}').should highlight(:string, '%r{/foo/}')
|
30
72
|
end
|
31
73
|
|
32
74
|
it "regular expressions with mode flags" do
|
33
|
-
parse('/test/sex').should
|
34
|
-
parse('/test/sex test').should
|
75
|
+
parse('/test/sex').should highlight(:regexp, '/test/sex')
|
76
|
+
parse('/test/sex test').should highlight(:regexp, '/test/sex')
|
77
|
+
parse('%r{test}sex test').should highlight(:regexp, '%r{test}sex')
|
35
78
|
end
|
36
79
|
|
37
80
|
it "instance variables" do
|
38
|
-
parse('@foo_1').should
|
81
|
+
parse('@foo_1').should highlight(:instance, '@foo_1')
|
82
|
+
parse('@foo_1').should highlight(:variable, '@foo_1')
|
39
83
|
end
|
40
84
|
|
41
85
|
it "class variables" do
|
42
|
-
parse('@@__bar').should
|
86
|
+
parse('@@__bar').should highlight(:class, '@@__bar')
|
87
|
+
parse('@@__bar').should highlight(:variable, '@@__bar')
|
88
|
+
end
|
89
|
+
|
90
|
+
it "global variables" do
|
91
|
+
parse('$foo').should highlight(:variable, '$foo')
|
92
|
+
parse('$foo').should highlight(:global, '$foo')
|
93
|
+
parse('$:').should highlight(:variable, '$:')
|
94
|
+
parse('$:').should highlight(:global, '$:')
|
95
|
+
parse('($~)').should highlight(:variable, '$~')
|
96
|
+
parse('($~)').should highlight(:global, '$~')
|
43
97
|
end
|
44
98
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
99
|
+
it "integers" do
|
100
|
+
parse('100_000').should highlight(:number, '100_000')
|
101
|
+
parse('100_000').should highlight(:int, '100_000')
|
102
|
+
end
|
103
|
+
|
104
|
+
it "floats" do
|
105
|
+
parse('1.3').should highlight(:number, '1.3')
|
106
|
+
parse('1.3').should highlight(:float, '1.3')
|
49
107
|
end
|
50
108
|
|
109
|
+
it "ranges" do
|
110
|
+
parse('1..10').should highlight(:number, '1..10')
|
111
|
+
parse('1..10').should highlight(:range, '1..10')
|
112
|
+
parse('1...10').should highlight(:number, '1...10')
|
113
|
+
parse('1...10').should highlight(:range, '1...10')
|
114
|
+
end
|
115
|
+
|
51
116
|
it "constants" do
|
52
|
-
parse('FooBar').should
|
53
|
-
parse('FOOBAR').should
|
117
|
+
parse('FooBar').should highlight(:constant, 'FooBar')
|
118
|
+
parse('FOOBAR').should highlight(:constant, 'FOOBAR')
|
119
|
+
parse('__FILE__').should highlight(:constant, '__FILE__')
|
120
|
+
end
|
121
|
+
|
122
|
+
it "constants with namespace resolution" do
|
123
|
+
parse('Foo::Bar').should highlight(:constant, 'Foo::Bar')
|
124
|
+
parse('Foo::Bar.test()').should highlight(:constant, 'Foo::Bar')
|
125
|
+
end
|
126
|
+
|
127
|
+
it "heredoc syntax" do
|
128
|
+
parse('
|
129
|
+
<<-EOF
|
130
|
+
stuff
|
131
|
+
EOF
|
132
|
+
').should highlight(:string, "<<-EOF\n stuff\n EOF")
|
133
|
+
parse('
|
134
|
+
<<EOF
|
135
|
+
stuff
|
136
|
+
EOF
|
137
|
+
').should highlight(:string, "<<EOF\n stuff\n EOF")
|
138
|
+
parse("
|
139
|
+
<<-'...'
|
140
|
+
stuff
|
141
|
+
...
|
142
|
+
").should highlight(:string, "<<-'...'\n stuff\n ...")
|
143
|
+
end
|
144
|
+
|
145
|
+
it "contents after __END__ as a comment" do
|
146
|
+
ruby = parse(%(
|
147
|
+
:foo
|
148
|
+
__END__
|
149
|
+
:bar
|
150
|
+
should not be literal ruby
|
151
|
+
"test"
|
152
|
+
))
|
153
|
+
ruby.should include('class="string symbol">:foo')
|
154
|
+
ruby.should include('class="keyword">__END__</span><span class="comment"')
|
54
155
|
end
|
55
156
|
|
56
157
|
%w( if else elsif unless retry super then true while until class module def end in alias
|
57
158
|
BEGIN END begin break defined do nil not or and redo rescue return yield ).
|
58
159
|
each do |keyword|
|
59
160
|
it "#{keyword.strip} as a keyword" do
|
60
|
-
parse("#{keyword.strip} foo").should
|
161
|
+
parse("\n#{keyword.strip} foo").should highlight(:keyword, keyword.strip)
|
162
|
+
parse("(#{keyword.strip})").should highlight(:keyword, keyword.strip)
|
61
163
|
end
|
62
164
|
end
|
63
|
-
|
64
|
-
end
|
65
165
|
|
66
|
-
it 'should not highlight # within regexp or strings as comment' do
|
67
|
-
parse('/#test/').should include('class="regexp">/#test/')
|
68
|
-
parse('"#test"').should include(%(class="string">"#test"))
|
69
|
-
parse("'#test'").should include(%(class="string">'#test'))
|
70
166
|
end
|
71
167
|
|
168
|
+
describe "should not highlight" do
|
169
|
+
|
170
|
+
it "keywords when part of other words" do
|
171
|
+
parse('define').should_not highlight(:keyword, 'def')
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
72
176
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,2 +1,31 @@
|
|
1
1
|
|
2
2
|
require 'lightr'
|
3
|
+
|
4
|
+
class HighlightMatcher
|
5
|
+
def initialize klass, contents
|
6
|
+
@klass, @contents = klass, contents
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches? got
|
10
|
+
@input = got
|
11
|
+
@classes = $1.split if got.match /class="(.*?)"/
|
12
|
+
@got = $1 if got.match /">(.*?)<\//
|
13
|
+
@classes.include? @klass.to_s and @got == @contents rescue false
|
14
|
+
end
|
15
|
+
|
16
|
+
def failure_message
|
17
|
+
"expected #{@input} to have class '#{@klass}' and contents of '#{@contents}'"
|
18
|
+
end
|
19
|
+
|
20
|
+
def negative_failure_message
|
21
|
+
"expected #{@input} to not have class '#{@klass}' and contents of '#{@contents}'"
|
22
|
+
end
|
23
|
+
|
24
|
+
def description
|
25
|
+
"highlight #{@klass}s"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def highlight klass, contents
|
30
|
+
HighlightMatcher.new klass, contents
|
31
|
+
end
|
data/tasks/ext.rake
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
FSMS = Dir['ext/*.rl']
|
3
|
+
|
4
|
+
namespace :ext do
|
5
|
+
|
6
|
+
desc 'Build ragel scanners'
|
7
|
+
task :build do
|
8
|
+
FSMS.each do |fsm|
|
9
|
+
`ragel #{fsm} -R -F1 -o lib/lightr/grammars/#{ File.basename(fsm).sub('.rl', '.rb') }`
|
10
|
+
puts "Built #{fsm}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Build scanners and run specs'
|
15
|
+
task :spec do
|
16
|
+
task(:'ext:build').invoke
|
17
|
+
task(:'spec').invoke
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|