rouge 0.2.0 → 0.2.1
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/Gemfile +1 -0
- data/lib/rouge.rb +3 -0
- data/lib/rouge/cli.rb +18 -2
- data/lib/rouge/formatter.rb +7 -0
- data/lib/rouge/formatters/html.rb +4 -0
- data/lib/rouge/formatters/terminal256.rb +8 -2
- data/lib/rouge/lexer.rb +34 -4
- data/lib/rouge/lexers/c.rb +3 -0
- data/lib/rouge/lexers/common_lisp.rb +1 -0
- data/lib/rouge/lexers/cpp.rb +2 -0
- data/lib/rouge/lexers/css.rb +2 -0
- data/lib/rouge/lexers/diff.rb +2 -0
- data/lib/rouge/lexers/erb.rb +2 -0
- data/lib/rouge/lexers/factor.rb +1 -0
- data/lib/rouge/lexers/haml.rb +9 -4
- data/lib/rouge/lexers/haskell.rb +2 -0
- data/lib/rouge/lexers/html.rb +1 -0
- data/lib/rouge/lexers/java.rb +2 -0
- data/lib/rouge/lexers/javascript.rb +4 -1
- data/lib/rouge/lexers/make.rb +1 -0
- data/lib/rouge/lexers/markdown.rb +2 -0
- data/lib/rouge/lexers/perl.rb +2 -0
- data/lib/rouge/lexers/php.rb +6 -2
- data/lib/rouge/lexers/python.rb +1 -0
- data/lib/rouge/lexers/ruby.rb +2 -1
- data/lib/rouge/lexers/scheme.rb +2 -0
- data/lib/rouge/lexers/shell.rb +2 -0
- data/lib/rouge/lexers/sql.rb +137 -0
- data/lib/rouge/lexers/tcl.rb +1 -0
- data/lib/rouge/lexers/tex.rb +1 -0
- data/lib/rouge/lexers/text.rb +2 -0
- data/lib/rouge/lexers/viml.rb +98 -0
- data/lib/rouge/lexers/viml/keywords.rb +11 -0
- data/lib/rouge/lexers/xml.rb +1 -0
- data/lib/rouge/lexers/yaml.rb +4 -3
- data/lib/rouge/regex_lexer.rb +142 -43
- data/lib/rouge/template_lexer.rb +6 -0
- data/lib/rouge/text_analyzer.rb +9 -0
- data/lib/rouge/util.rb +10 -0
- data/lib/rouge/version.rb +1 -1
- metadata +5 -2
data/Gemfile
CHANGED
data/lib/rouge.rb
CHANGED
@@ -30,8 +30,11 @@ load load_dir.join('rouge/lexers/tex.rb')
|
|
30
30
|
load load_dir.join('rouge/lexers/markdown.rb')
|
31
31
|
load load_dir.join('rouge/lexers/yaml.rb')
|
32
32
|
|
33
|
+
load load_dir.join('rouge/lexers/sql.rb')
|
34
|
+
|
33
35
|
load load_dir.join('rouge/lexers/make.rb')
|
34
36
|
load load_dir.join('rouge/lexers/shell.rb')
|
37
|
+
load load_dir.join('rouge/lexers/viml.rb')
|
35
38
|
|
36
39
|
load load_dir.join('rouge/lexers/javascript.rb')
|
37
40
|
load load_dir.join('rouge/lexers/css.rb')
|
data/lib/rouge/cli.rb
CHANGED
@@ -17,7 +17,7 @@ module Rouge
|
|
17
17
|
exit 0
|
18
18
|
end
|
19
19
|
|
20
|
-
unless %w(highlight style).include?(argv.first)
|
20
|
+
unless %w(highlight style list --help -h help).include?(argv.first)
|
21
21
|
argv.unshift 'highlight'
|
22
22
|
end
|
23
23
|
|
@@ -30,7 +30,7 @@ module Rouge
|
|
30
30
|
:desc => ('Which lexer to use. If not provided, rougify will try to ' +
|
31
31
|
'guess based on --mimetype, the filename, and the file ' +
|
32
32
|
'contents.')
|
33
|
-
option :formatter, :aliases => '-f', :default => '
|
33
|
+
option :formatter, :aliases => '-f', :default => 'terminal256',
|
34
34
|
:desc => ('Which formatter to use.')
|
35
35
|
option :mimetype, :aliases => '-m',
|
36
36
|
:desc => ('a mimetype that Rouge will use to guess the correct lexer. ' +
|
@@ -71,6 +71,22 @@ module Rouge
|
|
71
71
|
puts theme.new(options).render
|
72
72
|
end
|
73
73
|
|
74
|
+
desc 'list', 'list the available lexers, formatters, and styles'
|
75
|
+
def list
|
76
|
+
puts "== Available Lexers =="
|
77
|
+
all_lexers = Lexer.all
|
78
|
+
max_len = all_lexers.map { |l| l.tag.size }.max
|
79
|
+
|
80
|
+
Lexer.all.each do |lexer|
|
81
|
+
desc = "#{lexer.desc}"
|
82
|
+
if lexer.aliases.any?
|
83
|
+
desc << " [aliases: #{lexer.aliases.join(',')}]"
|
84
|
+
end
|
85
|
+
puts "%s: %s" % [lexer.tag, desc]
|
86
|
+
puts
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
74
90
|
private
|
75
91
|
# TODO: does Thor do this for me?
|
76
92
|
def normalize_hash_keys(hash)
|
data/lib/rouge/formatter.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module Rouge
|
2
|
+
# A Formatter takes a token stream and formats it for human viewing.
|
2
3
|
class Formatter
|
3
4
|
REGISTRY = {}
|
4
5
|
|
6
|
+
# Specify or get the unique tag for this formatter. This is used
|
7
|
+
# for specifying a formatter in `rougify`.
|
5
8
|
def self.tag(tag=nil)
|
6
9
|
return @tag unless tag
|
7
10
|
REGISTRY[tag] = self
|
@@ -9,14 +12,18 @@ module Rouge
|
|
9
12
|
@tag = tag
|
10
13
|
end
|
11
14
|
|
15
|
+
# Find a formatter class given a unique tag.
|
12
16
|
def self.find(tag)
|
13
17
|
REGISTRY[tag]
|
14
18
|
end
|
15
19
|
|
20
|
+
# Format a token stream.
|
16
21
|
def render(tokens)
|
17
22
|
enum_for(:stream, tokens).to_a.join
|
18
23
|
end
|
19
24
|
|
25
|
+
# @abstract
|
26
|
+
# yield strings that, when concatenated, form the formatted output
|
20
27
|
def stream(tokens, &b)
|
21
28
|
raise 'abstract'
|
22
29
|
end
|
@@ -3,13 +3,17 @@ require 'cgi'
|
|
3
3
|
|
4
4
|
module Rouge
|
5
5
|
module Formatters
|
6
|
+
# Transforms a token stream into HTML output.
|
6
7
|
class HTML < Formatter
|
7
8
|
tag 'html'
|
8
9
|
|
10
|
+
# @option opts :css_class
|
11
|
+
# A css class to be used for the generated <pre> tag.
|
9
12
|
def initialize(opts={})
|
10
13
|
@css_class = opts[:css_class] || 'highlight'
|
11
14
|
end
|
12
15
|
|
16
|
+
# @yield the html output.
|
13
17
|
def stream(tokens, &b)
|
14
18
|
yield "<pre class=#{@css_class.inspect}>"
|
15
19
|
tokens.each do |tok, val|
|
@@ -1,11 +1,17 @@
|
|
1
1
|
module Rouge
|
2
2
|
module Formatters
|
3
|
+
# A formatter for 256-color terminals
|
3
4
|
class Terminal256 < Formatter
|
4
5
|
tag 'terminal256'
|
5
6
|
|
7
|
+
# @private
|
6
8
|
attr_reader :theme
|
9
|
+
|
10
|
+
|
11
|
+
# @option opts :theme
|
12
|
+
# (default is thankful_eyes) the theme to render with.
|
7
13
|
def initialize(opts={})
|
8
|
-
@theme = opts[:theme] ||
|
14
|
+
@theme = opts[:theme] || 'thankful_eyes'
|
9
15
|
@theme = Theme.find(@theme) if @theme.is_a? String
|
10
16
|
end
|
11
17
|
|
@@ -95,7 +101,7 @@ module Rouge
|
|
95
101
|
end
|
96
102
|
end
|
97
103
|
|
98
|
-
|
104
|
+
private
|
99
105
|
def escape(attrs)
|
100
106
|
return '' if attrs.empty?
|
101
107
|
"\e[#{attrs.join(';')}m"
|
data/lib/rouge/lexer.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
require 'strscan'
|
3
3
|
|
4
4
|
module Rouge
|
5
|
+
# @abstract
|
6
|
+
# A lexer transforms text into a stream of `[token, chunk]` pairs.
|
5
7
|
class Lexer
|
6
8
|
class << self
|
7
9
|
# Lexes `stream` with the given options. The lex is delegated to a
|
@@ -23,6 +25,20 @@ module Rouge
|
|
23
25
|
registry[name.to_s]
|
24
26
|
end
|
25
27
|
|
28
|
+
# Specify or get this lexer's description.
|
29
|
+
def desc(arg=:absent)
|
30
|
+
if arg == :absent
|
31
|
+
@desc
|
32
|
+
else
|
33
|
+
@desc = arg
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return a list of all lexers.
|
38
|
+
def all
|
39
|
+
registry.values.uniq
|
40
|
+
end
|
41
|
+
|
26
42
|
# Guess which lexer to use based on a hash of info.
|
27
43
|
#
|
28
44
|
# @option info :mimetype
|
@@ -82,6 +98,7 @@ module Rouge
|
|
82
98
|
best_match
|
83
99
|
end
|
84
100
|
|
101
|
+
# @private
|
85
102
|
def register(name, lexer)
|
86
103
|
registry[name.to_s] = lexer
|
87
104
|
end
|
@@ -100,7 +117,7 @@ module Rouge
|
|
100
117
|
return @tag if t.nil?
|
101
118
|
|
102
119
|
@tag = t.to_s
|
103
|
-
|
120
|
+
Lexer.register(@tag, self)
|
104
121
|
end
|
105
122
|
|
106
123
|
# Used to specify alternate names this lexer class may be found by.
|
@@ -113,10 +130,12 @@ module Rouge
|
|
113
130
|
#
|
114
131
|
# Lexer.find('eruby') # => Erb
|
115
132
|
def aliases(*args)
|
133
|
+
args.map!(&:to_s)
|
116
134
|
args.each { |arg| Lexer.register(arg, self) }
|
135
|
+
(@aliases ||= []).concat(args)
|
117
136
|
end
|
118
137
|
|
119
|
-
# Specify a list of filename globs associated with this lexer
|
138
|
+
# Specify a list of filename globs associated with this lexer.
|
120
139
|
#
|
121
140
|
# @example
|
122
141
|
# class Ruby < Lexer
|
@@ -144,16 +163,27 @@ module Rouge
|
|
144
163
|
|
145
164
|
# -*- instance methods -*- #
|
146
165
|
|
166
|
+
# Create a new lexer with the given options. Individual lexers may
|
167
|
+
# specify extra options. The only current globally accepted option
|
168
|
+
# is `:debug`.
|
169
|
+
#
|
170
|
+
# @option opts :debug
|
171
|
+
# Prints debug information to stdout. The particular info depends
|
172
|
+
# on the lexer in question. In regex lexers, this will log the
|
173
|
+
# state stack at the beginning of each step, along with each regex
|
174
|
+
# tried and each stream consumed. Try it, it's pretty useful.
|
147
175
|
def initialize(opts={})
|
148
176
|
options(opts)
|
149
177
|
end
|
150
178
|
|
179
|
+
# get and/or specify the options for this lexer.
|
151
180
|
def options(o={})
|
152
181
|
(@options ||= {}).merge!(o)
|
153
182
|
|
154
183
|
self.class.default_options.merge(@options)
|
155
184
|
end
|
156
185
|
|
186
|
+
# get or specify one option for this lexer
|
157
187
|
def option(k, v=:absent)
|
158
188
|
if v == :absent
|
159
189
|
options[k]
|
@@ -209,7 +239,7 @@ module Rouge
|
|
209
239
|
|
210
240
|
# @abstract
|
211
241
|
#
|
212
|
-
# Yield [token, chunk] pairs, given a prepared input stream. This
|
242
|
+
# Yield `[token, chunk]` pairs, given a prepared input stream. This
|
213
243
|
# must be implemented.
|
214
244
|
#
|
215
245
|
# @param [StringScanner] stream
|
@@ -220,7 +250,7 @@ module Rouge
|
|
220
250
|
|
221
251
|
# @abstract
|
222
252
|
#
|
223
|
-
#
|
253
|
+
# Return a number between 0 and 1 indicating the likelihood that
|
224
254
|
# the text given should be lexed with this lexer. The default
|
225
255
|
# implementation returns 0.
|
226
256
|
#
|
data/lib/rouge/lexers/c.rb
CHANGED
@@ -5,6 +5,8 @@ module Rouge
|
|
5
5
|
filenames '*.c', '*.h', '*.idc'
|
6
6
|
mimetypes 'text/x-chdr', 'text/x-csrc'
|
7
7
|
|
8
|
+
desc "The C programming language"
|
9
|
+
|
8
10
|
# optional comment or whitespace
|
9
11
|
ws = %r((?:\s|//.*?\n|/[*].*?[*]/)+)
|
10
12
|
id = /[a-zA-Z_][a-zA-Z0-9_]*/
|
@@ -55,6 +57,7 @@ module Rouge
|
|
55
57
|
rule /__(?:#{__reserved.join('|')})\b/, 'Keyword.Reserved'
|
56
58
|
rule /(?:true|false|NULL)\b/, 'Name.Builtin'
|
57
59
|
rule id, 'Name'
|
60
|
+
rule /\s+/m, 'Text'
|
58
61
|
end
|
59
62
|
|
60
63
|
state :case do
|
data/lib/rouge/lexers/cpp.rb
CHANGED
data/lib/rouge/lexers/css.rb
CHANGED
data/lib/rouge/lexers/diff.rb
CHANGED
data/lib/rouge/lexers/erb.rb
CHANGED
data/lib/rouge/lexers/factor.rb
CHANGED
data/lib/rouge/lexers/haml.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
module Rouge
|
2
2
|
module Lexers
|
3
|
+
# A lexer for the Haml templating system for Ruby.
|
4
|
+
# @see http://haml.info
|
3
5
|
class Haml < RegexLexer
|
6
|
+
desc "The Haml templating system for Ruby (haml.info)"
|
7
|
+
|
4
8
|
tag 'haml'
|
5
9
|
aliases 'HAML'
|
6
10
|
|
@@ -11,9 +15,10 @@ module Rouge
|
|
11
15
|
return 0.1 if text.start_with? '!!!'
|
12
16
|
end
|
13
17
|
|
14
|
-
# option :filters
|
15
|
-
# various filters should be
|
16
|
-
#
|
18
|
+
# @option opts :filters
|
19
|
+
# A hash of filter name to lexer of how various filters should be
|
20
|
+
# highlighted. By default, :javascript, :css, :ruby, and :erb
|
21
|
+
# are supported.
|
17
22
|
def initialize(opts={})
|
18
23
|
(opts.delete(:filters) || {}).each do |name, lexer|
|
19
24
|
unless lexer.respond_to? :lex
|
@@ -41,10 +46,10 @@ module Rouge
|
|
41
46
|
'css' => CSS.new(options),
|
42
47
|
'ruby' => ruby,
|
43
48
|
'erb' => ERB.new(options),
|
49
|
+
'markdown' => Markdown.new(options),
|
44
50
|
# TODO
|
45
51
|
# 'sass' => Sass.new(options),
|
46
52
|
# 'textile' => Textile.new(options),
|
47
|
-
# 'markdown' => Markdown.new(options),
|
48
53
|
# 'maruku' => Maruku.new(options),
|
49
54
|
}
|
50
55
|
end
|
data/lib/rouge/lexers/haskell.rb
CHANGED
data/lib/rouge/lexers/html.rb
CHANGED
data/lib/rouge/lexers/java.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Rouge
|
2
2
|
module Lexers
|
3
3
|
class Javascript < RegexLexer
|
4
|
+
desc "JavaScript, the browser scripting language"
|
5
|
+
|
4
6
|
tag 'javascript'
|
5
7
|
aliases 'js'
|
6
8
|
filenames '*.js'
|
@@ -94,6 +96,7 @@ module Rouge
|
|
94
96
|
end
|
95
97
|
|
96
98
|
class JSON < RegexLexer
|
99
|
+
desc "JavaScript Object Notation (json.org)"
|
97
100
|
tag 'json'
|
98
101
|
filenames '*.json'
|
99
102
|
mimetypes 'application/json'
|
@@ -102,7 +105,7 @@ module Rouge
|
|
102
105
|
# so I'd think this wouldn't be too bad, but for large documents this
|
103
106
|
# could mean doing two full lexes.
|
104
107
|
def self.analyze_text(text)
|
105
|
-
text.lexes_cleanly?(self)
|
108
|
+
return 0.8 if text =~ /\A\s*{/m && text.lexes_cleanly?(self)
|
106
109
|
end
|
107
110
|
|
108
111
|
state :root do
|
data/lib/rouge/lexers/make.rb
CHANGED
data/lib/rouge/lexers/perl.rb
CHANGED
data/lib/rouge/lexers/php.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Rouge
|
2
2
|
module Lexers
|
3
3
|
class PHP < TemplateLexer
|
4
|
+
desc "The PHP scripting language (php.net)"
|
4
5
|
tag 'php'
|
5
6
|
aliases 'php', 'php3', 'php4', 'php5'
|
6
7
|
filenames '*.php', '*.php[345]'
|
@@ -18,12 +19,15 @@ module Rouge
|
|
18
19
|
super(opts)
|
19
20
|
end
|
20
21
|
|
22
|
+
def self.builtins
|
23
|
+
load Pathname.new(__FILE__).dirname.join('php/builtins.rb')
|
24
|
+
self.builtins
|
25
|
+
end
|
26
|
+
|
21
27
|
def builtins
|
22
28
|
return [] unless @funcnamehighlighting
|
23
29
|
|
24
30
|
@builtins ||= Set.new.tap do |builtins|
|
25
|
-
require Pathname.new(__FILE__).dirname.join('php/builtins.rb')
|
26
|
-
|
27
31
|
self.class.builtins.each do |mod, fns|
|
28
32
|
next if @disabledmodules.include? mod
|
29
33
|
builtins.merge(fns)
|