[DRE-commits] [ruby-rouge] 01/03: Imported Upstream version 2.0.1
Youhei SASAKI
uwabami-guest at moszumanska.debian.org
Tue Jun 21 12:54:38 UTC 2016
This is an automated email from the git hooks/post-receive script.
uwabami-guest pushed a commit to annotated tag debian/2.0.1-1
in repository ruby-rouge.
commit 24467873b189e1e731d8ced39075f3e50970f764
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date: Tue Jun 21 21:41:06 2016 +0900
Imported Upstream version 2.0.1
---
lib/rouge.rb | 13 +++
lib/rouge/cli.rb | 29 +++--
lib/rouge/demos/cfscript | 18 +++
lib/rouge/demos/kotlin | 3 +
lib/rouge/demos/pascal | 14 +++
lib/rouge/formatter.rb | 25 ++++
lib/rouge/formatters/html.rb | 99 ++--------------
lib/rouge/formatters/html_inline.rb | 22 ++++
lib/rouge/formatters/html_legacy.rb | 44 ++++++++
lib/rouge/formatters/html_linewise.rb | 27 +++++
lib/rouge/formatters/html_pygments.rb | 16 +++
lib/rouge/formatters/html_table.rb | 61 ++++++++++
lib/rouge/formatters/html_wrapper.rb | 11 --
lib/rouge/formatters/terminal256.rb | 12 +-
lib/rouge/guesser.rb | 46 ++++++++
lib/rouge/guessers/filename.rb | 25 ++++
lib/rouge/guessers/glob_mapping.rb | 46 ++++++++
lib/rouge/guessers/mimetype.rb | 14 +++
lib/rouge/guessers/modeline.rb | 42 +++++++
lib/rouge/guessers/source.rb | 39 +++++++
lib/rouge/lexer.rb | 96 ++--------------
lib/rouge/lexers/cfscript.rb | 153 +++++++++++++++++++++++++
lib/rouge/lexers/d.rb | 2 +-
lib/rouge/lexers/groovy.rb | 12 +-
lib/rouge/lexers/http.rb | 6 +-
lib/rouge/lexers/javascript.rb | 17 ++-
lib/rouge/lexers/kotlin.rb | 84 ++++++++++++++
lib/rouge/lexers/pascal.rb | 66 +++++++++++
lib/rouge/lexers/praat.rb | 207 ++++++++++++++++++----------------
lib/rouge/plugins/redcarpet.rb | 2 +-
lib/rouge/theme.rb | 10 +-
lib/rouge/themes/gruvbox.rb | 167 +++++++++++++++++++++++++++
lib/rouge/version.rb | 2 +-
33 files changed, 1113 insertions(+), 317 deletions(-)
diff --git a/lib/rouge.rb b/lib/rouge.rb
index 9cfd8d7..d1e9b9f 100644
--- a/lib/rouge.rb
+++ b/lib/rouge.rb
@@ -36,6 +36,13 @@ load load_dir.join('rouge/util.rb')
load load_dir.join('rouge/text_analyzer.rb')
load load_dir.join('rouge/token.rb')
+load load_dir.join('rouge/guesser.rb')
+load load_dir.join('rouge/guessers/glob_mapping.rb')
+load load_dir.join('rouge/guessers/modeline.rb')
+load load_dir.join('rouge/guessers/filename.rb')
+load load_dir.join('rouge/guessers/mimetype.rb')
+load load_dir.join('rouge/guessers/source.rb')
+
load load_dir.join('rouge/lexer.rb')
load load_dir.join('rouge/regex_lexer.rb')
load load_dir.join('rouge/template_lexer.rb')
@@ -47,6 +54,11 @@ end
load load_dir.join('rouge/formatter.rb')
load load_dir.join('rouge/formatters/html.rb')
+load load_dir.join('rouge/formatters/html_table.rb')
+load load_dir.join('rouge/formatters/html_pygments.rb')
+load load_dir.join('rouge/formatters/html_legacy.rb')
+load load_dir.join('rouge/formatters/html_linewise.rb')
+load load_dir.join('rouge/formatters/html_inline.rb')
load load_dir.join('rouge/formatters/terminal256.rb')
load load_dir.join('rouge/formatters/null.rb')
@@ -58,3 +70,4 @@ load load_dir.join('rouge/themes/github.rb')
load load_dir.join('rouge/themes/monokai.rb')
load load_dir.join('rouge/themes/molokai.rb')
load load_dir.join('rouge/themes/monokai_sublime.rb')
+load load_dir.join('rouge/themes/gruvbox.rb')
diff --git a/lib/rouge/cli.rb b/lib/rouge/cli.rb
index a319a6b..3e80190 100644
--- a/lib/rouge/cli.rb
+++ b/lib/rouge/cli.rb
@@ -13,9 +13,9 @@ module Rouge
def file
case input
when '-'
- $stdin
+ IO.new($stdin.fileno, 'r:utf-8')
when String
- File.new(input)
+ File.new(input, 'r:utf-8')
when ->(i){ i.respond_to? :read }
input
end
@@ -23,7 +23,7 @@ module Rouge
def read
@read ||= begin
- File.read(file, encoding: 'utf-8')
+ file.read
rescue => e
$stderr.puts "unable to open #{input}: #{e.message}"
exit 1
@@ -181,6 +181,8 @@ module Rouge
def self.parse(argv)
opts = {
:formatter => 'terminal256',
+ :theme => 'thankful_eyes',
+ :css_class => 'codehilite',
:input_file => '-',
:lexer_opts => {},
:formatter_opts => {},
@@ -195,12 +197,14 @@ module Rouge
opts[:mimetype] = argv.shift
when '--lexer', '-l'
opts[:lexer] = argv.shift
- when '--formatter', '-f'
+ when '--formatter-preset', '-f'
opts[:formatter] = argv.shift
+ when '--theme', '-t'
+ opts[:theme] = argv.shift
+ when '--css-class', '-c'
+ opts[:css_class] = argv.shift
when '--lexer-opts', '-L'
opts[:lexer_opts] = parse_cgi(argv.shift)
- when '--formatter-opts', '-F'
- opts[:formatter_opts] = parse_cgi(argv.shift)
when /^--/
error! "unknown option #{arg.inspect}"
else
@@ -246,10 +250,17 @@ module Rouge
@lexer_opts = opts[:lexer_opts]
- formatter_class = Formatter.find(opts[:formatter]) \
- or error! "unknown formatter #{opts[:formatter]}"
+ theme = Theme.find(opts[:theme]).new or error! "unknown theme #{opts[:theme]}"
- @formatter = formatter_class.new(opts[:formatter_opts])
+ @formatter = case opts[:formatter]
+ when 'terminal256' then Formatters::Terminal256.new(theme)
+ when 'html' then Formatters::HTML.new
+ when 'html-pygments' then Formatters::HTMLPygments.new(Formatters::HTML.new, opts[:css_class])
+ when 'html-inline' then Formatters::HTMLInline.new(theme)
+ when 'html-table' then Formatters::HTMLTable.new(Formatters::HTML.new)
+ else
+ error! "unknown formatter preset #{opts[:formatter]}"
+ end
end
def run
diff --git a/lib/rouge/demos/cfscript b/lib/rouge/demos/cfscript
new file mode 100644
index 0000000..9006416
--- /dev/null
+++ b/lib/rouge/demos/cfscript
@@ -0,0 +1,18 @@
+component accessors="true" {
+
+ property type="string" name="firstName" default="";
+ property string username;
+
+ function init(){
+ return this;
+ }
+
+ public any function submitOrder( required product, coupon="", boolean results=true ){
+
+ var foo = function( required string baz, x=true, y=false ){
+ return "bar!";
+ };
+
+ return foo;
+ }
+}
\ No newline at end of file
diff --git a/lib/rouge/demos/kotlin b/lib/rouge/demos/kotlin
new file mode 100644
index 0000000..a27b0db
--- /dev/null
+++ b/lib/rouge/demos/kotlin
@@ -0,0 +1,3 @@
+fun main(args: Array<String>) {
+ println("Hello, world!")
+}
diff --git a/lib/rouge/demos/pascal b/lib/rouge/demos/pascal
new file mode 100644
index 0000000..16be537
--- /dev/null
+++ b/lib/rouge/demos/pascal
@@ -0,0 +1,14 @@
+program FizzBuzz(output);
+var
+ i: Integer;
+begin
+ for i := 1 to 100 do
+ if i mod 15 = 0 then
+ WriteLn('FizzBuzz')
+ else if i mod 3 = 0 then
+ WriteLn('Fizz')
+ else if i mod 5 = 0 then
+ WriteLn('Buzz')
+ else
+ WriteLn(i)
+end.
diff --git a/lib/rouge/formatter.rb b/lib/rouge/formatter.rb
index 646ae8d..f089f02 100644
--- a/lib/rouge/formatter.rb
+++ b/lib/rouge/formatter.rb
@@ -25,6 +25,10 @@ module Rouge
new(opts).format(tokens, &b)
end
+ def initialize(opts={})
+ # pass
+ end
+
# Format a token stream.
def format(tokens, &b)
return stream(tokens, &b) if block_given?
@@ -46,5 +50,26 @@ module Rouge
def stream(tokens, &b)
raise 'abstract'
end
+
+ protected
+ def token_lines(tokens, &b)
+ return enum_for(:token_lines, tokens) unless block_given?
+
+ out = []
+ tokens.each do |tok, val|
+ val.scan /\n|[^\n]+/ do |s|
+ if s == "\n"
+ yield out
+ out = []
+ else
+ out << [tok, s]
+ end
+ end
+ end
+
+ # for inputs not ending in a newline
+ yield out if out.any?
+ end
+
end
end
diff --git a/lib/rouge/formatters/html.rb b/lib/rouge/formatters/html.rb
index cdc8a2d..88a66ac 100644
--- a/lib/rouge/formatters/html.rb
+++ b/lib/rouge/formatters/html.rb
@@ -9,109 +9,32 @@ module Rouge
class HTML < Formatter
tag 'html'
- # @option opts [String] :css_class ('highlight')
- # @option opts [true/false] :line_numbers (false)
- # @option opts [Rouge::CSSTheme] :inline_theme (nil)
- # @option opts [true/false] :wrap (true)
- #
- # Initialize with options.
- #
- # If `:inline_theme` is given, then instead of rendering the
- # tokens as <span> tags with CSS classes, the styles according to
- # the given theme will be inlined in "style" attributes. This is
- # useful for formats in which stylesheets are not available.
- #
- # Content will be wrapped in a tag (`div` if tableized, `pre` if
- # not) with the given `:css_class` unless `:wrap` is set to `false`.
- def initialize(opts={})
- @css_class = opts.fetch(:css_class, 'highlight')
- @css_class = " class=#{@css_class.inspect}" if @css_class
-
- @line_numbers = opts.fetch(:line_numbers, false)
- @start_line = opts.fetch(:start_line, 1)
- @inline_theme = opts.fetch(:inline_theme, nil)
- @inline_theme = Theme.find(@inline_theme).new if @inline_theme.is_a? String
-
- @wrap = opts.fetch(:wrap, true)
- end
-
# @yield the html output.
def stream(tokens, &b)
- if @line_numbers
- stream_tableized(tokens, &b)
- else
- stream_untableized(tokens, &b)
- end
+ tokens.each { |tok, val| yield span(tok, val) }
end
- private
- def stream_untableized(tokens, &b)
- yield "<pre#@css_class><code>" if @wrap
- tokens.each{ |tok, val| span(tok, val, &b) }
- yield "</code></pre>\n" if @wrap
+ def span(tok, val)
+ safe_span(tok, val.gsub(/[&<>]/, TABLE_FOR_ESCAPE_HTML))
end
- def stream_tableized(tokens)
- num_lines = 0
- last_val = ''
- formatted = ''
-
- tokens.each do |tok, val|
- last_val = val
- num_lines += val.scan(/\n/).size
- span(tok, val) { |str| formatted << str }
- end
+ def safe_span(tok, safe_val)
+ if tok == Token::Tokens::Text
+ safe_val
+ else
+ shortname = tok.shortname \
+ or raise "unknown token: #{tok.inspect} for #{safe_val.inspect}"
- # add an extra line for non-newline-terminated strings
- if last_val[-1] != "\n"
- num_lines += 1
- span(Token::Tokens::Text::Whitespace, "\n") { |str| formatted << str }
+ "<span class=\"#{shortname}\">#{safe_val}</span>"
end
-
- # generate a string of newline-separated line numbers for the gutter>
- numbers = %<<pre class="lineno">#{(@start_line..num_lines+ at start_line-1)
- .to_a.join("\n")}</pre>>
-
- yield "<div#@css_class>" if @wrap
- yield '<table style="border-spacing: 0"><tbody><tr>'
-
- # the "gl" class applies the style for Generic.Lineno
- yield '<td class="gutter gl" style="text-align: right">'
- yield numbers
- yield '</td>'
-
- yield '<td class="code">'
- yield '<pre>'
- yield formatted
- yield '</pre>'
- yield '</td>'
-
- yield "</tr></tbody></table>\n"
- yield "</div>\n" if @wrap
end
+ private
TABLE_FOR_ESCAPE_HTML = {
'&' => '&',
'<' => '<',
'>' => '>',
}
-
- def span(tok, val)
- val = val.gsub(/[&<>]/, TABLE_FOR_ESCAPE_HTML)
- shortname = tok.shortname or raise "unknown token: #{tok.inspect} for #{val.inspect}"
-
- if shortname.empty?
- yield val
- else
- if @inline_theme
- rules = @inline_theme.style_for(tok).rendered_rules
-
- yield "<span style=\"#{rules.to_a.join(';')}\">#{val}</span>"
- else
- yield "<span class=\"#{shortname}\">#{val}</span>"
- end
- end
- end
end
end
end
diff --git a/lib/rouge/formatters/html_inline.rb b/lib/rouge/formatters/html_inline.rb
new file mode 100644
index 0000000..a6a0a2f
--- /dev/null
+++ b/lib/rouge/formatters/html_inline.rb
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Formatters
+ class HTMLInline < HTML
+ tag 'html_inline'
+
+ def initialize(theme)
+ @theme = theme
+ end
+
+ def safe_span(tok, safe_val)
+ return safe_val if tok == Token::Tokens::Text
+
+ rules = @theme.style_for(tok).rendered_rules
+
+ "<span style=\"#{rules.to_a.join(';')}\">#{safe_val}</span>"
+ end
+ end
+ end
+end
+
diff --git a/lib/rouge/formatters/html_legacy.rb b/lib/rouge/formatters/html_legacy.rb
new file mode 100644
index 0000000..813cefb
--- /dev/null
+++ b/lib/rouge/formatters/html_legacy.rb
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*- #
+
+# stdlib
+require 'cgi'
+
+module Rouge
+ module Formatters
+ # Transforms a token stream into HTML output.
+ class HTMLLegacy < Formatter
+ tag 'html_legacy'
+
+ # @option opts [String] :css_class ('highlight')
+ # @option opts [true/false] :line_numbers (false)
+ # @option opts [Rouge::CSSTheme] :inline_theme (nil)
+ # @option opts [true/false] :wrap (true)
+ #
+ # Initialize with options.
+ #
+ # If `:inline_theme` is given, then instead of rendering the
+ # tokens as <span> tags with CSS classes, the styles according to
+ # the given theme will be inlined in "style" attributes. This is
+ # useful for formats in which stylesheets are not available.
+ #
+ # Content will be wrapped in a tag (`div` if tableized, `pre` if
+ # not) with the given `:css_class` unless `:wrap` is set to `false`.
+ def initialize(opts={})
+ @formatter = opts[:inline_theme] ? HTMLInline.new(opts[:inline_theme])
+ : HTML.new
+
+
+ @formatter = HTMLTable.new(@formatter, opts) if opts[:line_numbers]
+
+ if opts.fetch(:wrap, true)
+ @formatter = HTMLPygments.new(@formatter, opts.fetch(:css_class, 'codehilite'))
+ end
+ end
+
+ # @yield the html output.
+ def stream(tokens, &b)
+ @formatter.stream(tokens, &b)
+ end
+ end
+ end
+end
diff --git a/lib/rouge/formatters/html_linewise.rb b/lib/rouge/formatters/html_linewise.rb
new file mode 100644
index 0000000..55c8e72
--- /dev/null
+++ b/lib/rouge/formatters/html_linewise.rb
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Formatters
+ class HTMLLinewise < Formatter
+ def initialize(formatter, opts={})
+ @formatter = formatter
+ @class_format = opts.fetch(:class, 'line-%i')
+ end
+
+ def stream(tokens, &b)
+ token_lines(tokens) do |line|
+ yield "<div class=#{next_line_class}>"
+ line.each do |tok, val|
+ yield @formatter.span(tok, val)
+ end
+ yield '</div>'
+ end
+ end
+
+ def next_line_class
+ @lineno ||= 0
+ sprintf(@class_format, @lineno += 1).inspect
+ end
+ end
+ end
+end
diff --git a/lib/rouge/formatters/html_pygments.rb b/lib/rouge/formatters/html_pygments.rb
new file mode 100644
index 0000000..38c88c7
--- /dev/null
+++ b/lib/rouge/formatters/html_pygments.rb
@@ -0,0 +1,16 @@
+module Rouge
+ module Formatters
+ class HTMLPygments < Formatter
+ def initialize(inner, css_class='codehilite')
+ @inner = inner
+ @css_class = css_class
+ end
+
+ def stream(tokens, &b)
+ yield %<<pre class="#@css_class"><code>>
+ @inner.stream(tokens, &b)
+ yield "</code></pre>"
+ end
+ end
+ end
+end
diff --git a/lib/rouge/formatters/html_table.rb b/lib/rouge/formatters/html_table.rb
new file mode 100644
index 0000000..c440e34
--- /dev/null
+++ b/lib/rouge/formatters/html_table.rb
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Formatters
+ class HTMLTable < Formatter
+ tag 'html_table'
+
+ def initialize(inner, opts={})
+ @inner = inner
+ @start_line = opts.fetch(:start_line, 1)
+ @line_format = opts.fetch(:line_format, '%i')
+ @table_class = opts.fetch(:table_class, 'rouge-table')
+ @gutter_class = opts.fetch(:gutter_class, 'rouge-gutter')
+ @code_class = opts.fetch(:code_class, 'rouge-code')
+ end
+
+ def style(scope)
+ yield "#{scope} .rouge-table { border-spacing: 0 }"
+ yield "#{scope} .rouge-gutter { text-align: right }"
+ end
+
+ def stream(tokens, &b)
+ num_lines = 0
+ last_val = ''
+ formatted = ''
+
+ tokens.each do |tok, val|
+ last_val = val
+ num_lines += val.scan(/\n/).size
+ formatted << @inner.span(tok, val)
+ end
+
+ # add an extra line for non-newline-terminated strings
+ if last_val[-1] != "\n"
+ num_lines += 1
+ @inner.span(Token::Tokens::Text::Whitespace, "\n") { |str| formatted << str }
+ end
+
+ # generate a string of newline-separated line numbers for the gutter>
+ formatted_line_numbers = (@start_line..num_lines+ at start_line-1).map do |i|
+ sprintf("#{@line_format}", i) << "\n"
+ end.join('')
+
+ numbers = %<<pre class="lineno">#{formatted_line_numbers}</pre>>
+
+ yield %<<table class="#@table_class"><tbody><tr>>
+
+ # the "gl" class applies the style for Generic.Lineno
+ yield %<<td class="#@gutter_class gl">>
+ yield numbers
+ yield '</td>'
+
+ yield %<<td class="#@code_class"><pre>>
+ yield formatted
+ yield '</pre></td>'
+
+ yield "</tr></tbody></table>\n"
+ end
+ end
+ end
+end
diff --git a/lib/rouge/formatters/html_wrapper.rb b/lib/rouge/formatters/html_wrapper.rb
deleted file mode 100644
index d842099..0000000
--- a/lib/rouge/formatters/html_wrapper.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-module Rouge
- module Formatters
- class HTMLWrapper
- def initialize(open, formatter, close)
- @open = open
- @formatter = formatter
- @close = close
- end
- end
- end
-end
diff --git a/lib/rouge/formatters/terminal256.rb b/lib/rouge/formatters/terminal256.rb
index 165120d..b89d524 100644
--- a/lib/rouge/formatters/terminal256.rb
+++ b/lib/rouge/formatters/terminal256.rb
@@ -4,17 +4,13 @@ module Rouge
module Formatters
# A formatter for 256-color terminals
class Terminal256 < Formatter
- tag 'terminal256'
-
# @private
attr_reader :theme
-
- # @option opts :theme
- # (default is thankful_eyes) the theme to render with.
- def initialize(opts={})
- @theme = opts[:theme] || 'thankful_eyes'
- @theme = Theme.find(@theme) if @theme.is_a? String
+ # @argument theme
+ # the theme to render with.
+ def initialize(theme=nil)
+ @theme = theme || Themes::ThankfulEyes
end
def stream(tokens, &b)
diff --git a/lib/rouge/guesser.rb b/lib/rouge/guesser.rb
new file mode 100644
index 0000000..a857a22
--- /dev/null
+++ b/lib/rouge/guesser.rb
@@ -0,0 +1,46 @@
+module Rouge
+ class Guesser
+ def self.guess(guessers, lexers)
+ original_size = lexers.size
+
+ guessers.each do |g|
+ new_lexers = case g
+ when Guesser then g.filter(lexers)
+ when proc { |x| x.respond_to? :call } then g.call(lexers)
+ else raise "bad guesser: #{g}"
+ end
+
+ lexers = new_lexers && new_lexers.any? ? new_lexers : lexers
+ end
+
+ # if we haven't filtered the input at *all*,
+ # then we have no idea what language it is,
+ # so we bail and return [].
+ lexers.size < original_size ? lexers : []
+ end
+
+ def collect_best(lexers, opts={}, &scorer)
+ best = []
+ best_score = opts[:threshold]
+
+ lexers.each do |lexer|
+ score = scorer.call(lexer)
+
+ next if score.nil?
+
+ if best_score.nil? || score > best_score
+ best_score = score
+ best = [lexer]
+ elsif score == best_score
+ best << lexer
+ end
+ end
+
+ best
+ end
+
+ def filter(lexers)
+ raise 'abstract'
+ end
+ end
+end
diff --git a/lib/rouge/guessers/filename.rb b/lib/rouge/guessers/filename.rb
new file mode 100644
index 0000000..f26bc04
--- /dev/null
+++ b/lib/rouge/guessers/filename.rb
@@ -0,0 +1,25 @@
+module Rouge
+ module Guessers
+ class Filename < Guesser
+ attr_reader :fname
+ def initialize(filename)
+ @filename = filename
+ end
+
+ # returns a list of lexers that match the given filename with
+ # equal specificity (i.e. number of wildcards in the pattern).
+ # This helps disambiguate between, e.g. the Nginx lexer, which
+ # matches `nginx.conf`, and the Conf lexer, which matches `*.conf`.
+ # In this case, nginx will win because the pattern has no wildcards,
+ # while `*.conf` has one.
+ def filter(lexers)
+ mapping = {}
+ lexers.each do |lexer|
+ mapping[lexer.name] = lexer.filenames || []
+ end
+
+ GlobMapping.new(mapping, @filename).filter(lexers)
+ end
+ end
+ end
+end
diff --git a/lib/rouge/guessers/glob_mapping.rb b/lib/rouge/guessers/glob_mapping.rb
new file mode 100644
index 0000000..431fa5d
--- /dev/null
+++ b/lib/rouge/guessers/glob_mapping.rb
@@ -0,0 +1,46 @@
+module Rouge
+ module Guessers
+ # This class allows for custom behavior
+ # with glob -> lexer name mappings
+ class GlobMapping < Guesser
+ def self.by_pairs(mapping, filename)
+ glob_map = {}
+ mapping.each do |(glob, lexer_name)|
+ lexer = Lexer.find(lexer_name)
+
+ # ignore unknown lexers
+ next unless lexer
+
+ glob_map[lexer.name] ||= []
+ glob_map[lexer.name] << glob
+ end
+
+ new(glob_map, filename)
+ end
+
+ attr_reader :glob_map, :filename
+ def initialize(glob_map, filename)
+ @glob_map = glob_map
+ @filename = filename
+ end
+
+ def filter(lexers)
+ basename = File.basename(filename)
+
+ collect_best(lexers) do |lexer|
+ score = (@glob_map[lexer.name] || []).map do |pattern|
+ if test_pattern(pattern, basename)
+ # specificity is better the fewer wildcards there are
+ -pattern.scan(/[*?\[]/).size
+ end
+ end.compact.min
+ end
+ end
+
+ private
+ def test_pattern(pattern, path)
+ File.fnmatch?(pattern, path, File::FNM_DOTMATCH | File::FNM_CASEFOLD)
+ end
+ end
+ end
+end
diff --git a/lib/rouge/guessers/mimetype.rb b/lib/rouge/guessers/mimetype.rb
new file mode 100644
index 0000000..c5ef017
--- /dev/null
+++ b/lib/rouge/guessers/mimetype.rb
@@ -0,0 +1,14 @@
+module Rouge
+ module Guessers
+ class Mimetype < Guesser
+ attr_reader :mimetype
+ def initialize(mimetype)
+ @mimetype = mimetype
+ end
+
+ def filter(lexers)
+ lexers.select { |lexer| lexer.mimetypes.include? @mimetype }
+ end
+ end
+ end
+end
diff --git a/lib/rouge/guessers/modeline.rb b/lib/rouge/guessers/modeline.rb
new file mode 100644
index 0000000..ac08b5f
--- /dev/null
+++ b/lib/rouge/guessers/modeline.rb
@@ -0,0 +1,42 @@
+module Rouge
+ module Guessers
+ class Modeline < Guesser
+ # [jneen] regexen stolen from linguist
+ EMACS_MODELINE = /-\*-\s*(?:(?!mode)[\w-]+\s*:\s*(?:[\w+-]+)\s*;?\s*)*(?:mode\s*:)?\s*([\w+-]+)\s*(?:;\s*(?!mode)[\w-]+\s*:\s*[\w+-]+\s*)*;?\s*-\*-/i
+
+ # First form vim modeline
+ # [text]{white}{vi:|vim:|ex:}[white]{options}
+ # ex: 'vim: syntax=ruby'
+ VIM_MODELINE_1 = /(?:vim|vi|ex):\s*(?:ft|filetype|syntax)=(\w+)\s?/i
+
+ # Second form vim modeline (compatible with some versions of Vi)
+ # [text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text]
+ # ex: 'vim set syntax=ruby:'
+ VIM_MODELINE_2 = /(?:vim|vi|Vim|ex):\s*se(?:t)?.*\s(?:ft|filetype|syntax)=(\w+)\s?.*:/i
+
+ MODELINES = [EMACS_MODELINE, VIM_MODELINE_1, VIM_MODELINE_2]
+
+ def initialize(source, opts={})
+ @source = source
+ @lines = opts[:lines] || 5
+ end
+
+ def filter(lexers)
+ # don't bother reading the stream if we've already decided
+ return lexers if lexers.size == 1
+
+ source_text = @source
+ source_text = source_text.read if source_text.respond_to? :read
+
+ lines = source_text.split(/\r?\n/)
+
+ search_space = (lines.first(@lines) + lines.last(@lines)).join("\n")
+
+ matches = MODELINES.map { |re| re.match(search_space) }.compact
+ match_set = Set.new(matches.map { |m| m[1] })
+
+ lexers.select { |l| (Set.new([l.tag] + l.aliases) & match_set).any? }
+ end
+ end
+ end
+end
diff --git a/lib/rouge/guessers/source.rb b/lib/rouge/guessers/source.rb
new file mode 100644
index 0000000..5ee3c08
--- /dev/null
+++ b/lib/rouge/guessers/source.rb
@@ -0,0 +1,39 @@
+module Rouge
+ module Guessers
+ class Source < Guesser
+ attr_reader :source
+ def initialize(source)
+ @source = source
+ end
+
+ def filter(lexers)
+ # don't bother reading the input if
+ # we've already filtered to 1
+ return lexers if lexers.size == 1
+
+ # If we're filtering against *all* lexers, we only use confident return
+ # values from analyze_text. But if we've filtered down already, we can trust
+ # the analysis more.
+ threshold = lexers.size < 10 ? 0 : 0.5
+
+ source_text = case @source
+ when String
+ @source
+ when ->(s){ s.respond_to? :read }
+ @source.read
+ else
+ raise 'invalid source'
+ end
+
+ Lexer.assert_utf8!(source_text)
+
+ source_text = TextAnalyzer.new(source_text)
+
+ collect_best(lexers, threshold: threshold) do |lexer|
+ next unless lexer.methods(false).include? :analyze_text
+ lexer.analyze_text(source_text)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/rouge/lexer.rb b/lib/rouge/lexer.rb
index 6f0ad41..e213b95 100644
--- a/lib/rouge/lexer.rb
+++ b/lib/rouge/lexer.rb
@@ -109,26 +109,17 @@ module Rouge
# to use.
def guesses(info={})
mimetype, filename, source = info.values_at(:mimetype, :filename, :source)
- lexers = registry.values.uniq
- total_size = lexers.size
-
- lexers = filter_by_mimetype(lexers, mimetype) if mimetype
- return lexers if lexers.size == 1
-
- lexers = filter_by_filename(lexers, filename) if filename
- return lexers if lexers.size == 1
-
- if source
- # If we're filtering against *all* lexers, we only use confident return
- # values from analyze_text. But if we've filtered down already, we can trust
- # the analysis more.
- source_threshold = lexers.size < total_size ? 0 : 0.5
- return [best_by_source(lexers, source, source_threshold)].compact
- elsif lexers.size < total_size
- return lexers
- else
- return []
- end
+ custom_globs = info[:custom_globs]
+
+ guessers = (info[:guessers] || []).dup
+
+ guessers << Guessers::Mimetype.new(mimetype) if mimetype
+ guessers << Guessers::GlobMapping.by_pairs(custom_globs, filename) if custom_globs && filename
+ guessers << Guessers::Filename.new(filename) if filename
+ guessers << Guessers::Modeline.new(source) if source
+ guessers << Guessers::Source.new(source) if source
+
+ Guesser.guess(guessers, Lexer.all)
end
class AmbiguousGuess < StandardError
@@ -175,71 +166,6 @@ module Rouge
end
private
- def filter_by_mimetype(lexers, mt)
- filtered = lexers.select { |lexer| lexer.mimetypes.include? mt }
- filtered.any? ? filtered : lexers
- end
-
- # returns a list of lexers that match the given filename with
- # equal specificity (i.e. number of wildcards in the pattern).
- # This helps disambiguate between, e.g. the Nginx lexer, which
- # matches `nginx.conf`, and the Conf lexer, which matches `*.conf`.
- # In this case, nginx will win because the pattern has no wildcards,
- # while `*.conf` has one.
- def filter_by_filename(lexers, fname)
- fname = File.basename(fname)
-
- out = []
- best_seen = nil
- lexers.each do |lexer|
- score = lexer.filenames.map do |pattern|
- if File.fnmatch?(pattern, fname, File::FNM_DOTMATCH)
- # specificity is better the fewer wildcards there are
- pattern.scan(/[*?\[]/).size
- end
- end.compact.min
-
- next unless score
-
- if best_seen.nil? || score < best_seen
- best_seen = score
- out = [lexer]
- elsif score == best_seen
- out << lexer
- end
- end
-
- out.any? ? out : lexers
- end
-
- def best_by_source(lexers, source, threshold=0)
- source = case source
- when String
- source
- when ->(s){ s.respond_to? :read }
- source.read
- else
- raise 'invalid source'
- end
-
- assert_utf8!(source)
-
- source = TextAnalyzer.new(source)
-
- best_result = threshold
- best_match = nil
- lexers.each do |lexer|
- result = lexer.analyze_text(source) || 0
- return lexer if result == 1
-
- if result > best_result
- best_match = lexer
- best_result = result
- end
- end
-
- best_match
- end
protected
# @private
diff --git a/lib/rouge/lexers/cfscript.rb b/lib/rouge/lexers/cfscript.rb
new file mode 100644
index 0000000..d3f65a0
--- /dev/null
+++ b/lib/rouge/lexers/cfscript.rb
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Lexers
+
+ class Cfscript < RegexLexer
+ title "CFScript"
+ desc 'CFScript, the CFML scripting language'
+ tag 'cfscript'
+ aliases 'cfc'
+ filenames '*.cfc'
+
+ def self.keywords
+ @keywords ||= %w(
+ if else var xml default break switch do try catch throw in continue for return while required
+ )
+ end
+
+ def self.declarations
+ @declarations ||= %w(
+ component property function remote public package private
+ )
+ end
+
+ def self.types
+ @types ||= %w(
+ any array binary boolean component date guid numeric query string struct uuid void xml
+ )
+ end
+
+ constants = %w(application session client cookie super this variables arguments cgi)
+
+
+ operators = %w(\+\+ -- && \|\| <= >= < > == != mod eq lt gt lte gte not is and or xor eqv imp equal contains \? )
+ dotted_id = /[$a-zA-Z_][a-zA-Z0-9_.]*/
+
+ state :root do
+ mixin :comments_and_whitespace
+ rule /(?:#{operators.join('|')}|does not contain|greater than(?: or equal to)?|less than(?: or equal to)?)\b/i, Operator, :expr_start
+ rule %r([-<>+*%&|\^/!=]=?), Operator, :expr_start
+
+ rule /[(\[,]/, Punctuation, :expr_start
+ rule /;/, Punctuation, :statement
+ rule /[)\].]/, Punctuation
+
+ rule /[?]/ do
+ token Punctuation
+ push :ternary
+ push :expr_start
+ end
+
+ rule /[{}]/, Punctuation, :statement
+
+ rule /(?:#{constants.join('|')})\b/, Name::Constant
+ rule /(?:true|false|null)\b/, Keyword::Constant
+ rule /import\b/, Keyword::Namespace, :import
+ rule /(#{dotted_id})(\s*)(:)(\s*)/ do
+ groups Name, Text, Punctuation, Text
+ push :expr_start
+ end
+
+ rule /([A-Za-z_$][\w.]*)(\s*)(\()/ do |m|
+ if self.class.keywords.include? m[1]
+ token Keyword, m[1]
+ token Text, m[2]
+ token Punctuation, m[3]
+ else
+ token Name::Function, m[1]
+ token Text, m[2]
+ token Punctuation, m[3]
+ end
+ end
+
+ rule dotted_id do |m|
+ if self.class.declarations.include? m[0]
+ token Keyword::Declaration
+ push :expr_start
+ elsif self.class.keywords.include? m[0]
+ token Keyword
+ push :expr_start
+ elsif self.class.types.include? m[0]
+ token Keyword::Type
+ push :expr_start
+ else
+ token Name::Other
+ end
+ end
+
+ rule /[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, Num::Float
+ rule /0x[0-9a-fA-F]+/, Num::Hex
+ rule /[0-9]+/, Num::Integer
+ rule /"(\\\\|\\"|[^"])*"/, Str::Double
+ rule /'(\\\\|\\'|[^'])*'/, Str::Single
+
+ end
+
+ # same as java, broken out
+ state :comments_and_whitespace do
+ rule /\s+/, Text
+ rule %r(//.*?$), Comment::Single
+ rule %r(/\*.*?\*/)m, Comment::Multiline
+ end
+
+ state :expr_start do
+ mixin :comments_and_whitespace
+
+ rule /[{]/, Punctuation, :object
+
+ rule //, Text, :pop!
+ end
+
+ state :statement do
+
+ rule /[{}]/, Punctuation
+
+ mixin :expr_start
+ end
+
+ # object literals
+ state :object do
+ mixin :comments_and_whitespace
+ rule /[}]/ do
+ token Punctuation
+ push :expr_start
+ end
+
+ rule /(#{dotted_id})(\s*)(:)/ do
+ groups Name::Other, Text, Punctuation
+ push :expr_start
+ end
+
+ rule /:/, Punctuation
+ mixin :root
+ end
+
+ # ternary expressions, where <dotted_id>: is not a label!
+ state :ternary do
+ rule /:/ do
+ token Punctuation
+ goto :expr_start
+ end
+
+ mixin :root
+ end
+
+ state :import do
+ rule /\s+/m, Text
+ rule /[a-z0-9_.]+\*?/i, Name::Namespace, :pop!
+ end
+
+ end
+ end
+end
diff --git a/lib/rouge/lexers/d.rb b/lib/rouge/lexers/d.rb
index 8d80bba..a985e1d 100644
--- a/lib/rouge/lexers/d.rb
+++ b/lib/rouge/lexers/d.rb
@@ -9,7 +9,7 @@ module Rouge
mimetypes 'application/x-dsrc', 'text/x-dsrc'
title "D"
- desc 'The D programming language(dlag.org)'
+ desc 'The D programming language(dlang.org)'
keywords = %w(
abstract alias align asm assert auto body
diff --git a/lib/rouge/lexers/groovy.rb b/lib/rouge/lexers/groovy.rb
index 3b82c1c..130b641 100644
--- a/lib/rouge/lexers/groovy.rb
+++ b/lib/rouge/lexers/groovy.rb
@@ -57,10 +57,14 @@ module Rouge
rule /package\b/, Keyword::Namespace, :import
rule /import\b/, Keyword::Namespace, :import
- rule /"(\\\\|\\"|[^"])*"/, Str::Double
- rule /'(\\\\|\\'|[^'])*'/, Str::Single
- rule %r(\$/((?!/\$).)*/\$), Str
- rule %r(/(\\\\|\\"|[^/])*/), Str
+ # TODO: highlight backslash escapes
+ rule /""".*?"""/m, Str::Double
+ rule /'''.*?'''/m, Str::Single
+
+ rule /"(\\.|\\\n|.)*?"/, Str::Double
+ rule /'(\\.|\\\n|.)*?'/, Str::Single
+ rule %r(\$/(\$.|.)*?/\$)m, Str
+ rule %r(/(\\.|\\\n|.)*?/), Str
rule /'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'/, Str::Char
rule /(\.)([a-zA-Z_][a-zA-Z0-9_]*)/ do
groups Operator, Name::Attribute
diff --git a/lib/rouge/lexers/http.rb b/lib/rouge/lexers/http.rb
index 95be336..4ea1021 100644
--- a/lib/rouge/lexers/http.rb
+++ b/lib/rouge/lexers/http.rb
@@ -7,8 +7,8 @@ module Rouge
title "HTTP"
desc 'http requests and responses'
- def self.methods
- @methods ||= %w(GET POST PUT DELETE HEAD OPTIONS TRACE PATCH)
+ def self.http_methods
+ @http_methods ||= %w(GET POST PUT DELETE HEAD OPTIONS TRACE PATCH)
end
def content_lexer
@@ -24,7 +24,7 @@ module Rouge
state :root do
# request
rule %r(
- (#{HTTP.methods.join('|')})([ ]+) # method
+ (#{HTTP.http_methods.join('|')})([ ]+) # method
([^ ]+)([ ]+) # path
(HTTPS?)(/)(1[.][01])(\r?\n|$) # http version
)ox do
diff --git a/lib/rouge/lexers/javascript.rb b/lib/rouge/lexers/javascript.rb
index 7deed95..923a95c 100644
--- a/lib/rouge/lexers/javascript.rb
+++ b/lib/rouge/lexers/javascript.rb
@@ -2,6 +2,12 @@
module Rouge
module Lexers
+ # IMPORTANT NOTICE:
+ #
+ # Please do not copy this lexer and open a pull request
+ # for a new language. It will not get merged, you will
+ # be unhappy, and kittens will cry.
+ #
class Javascript < RegexLexer
title "JavaScript"
desc "JavaScript, the browser scripting language"
@@ -33,7 +39,10 @@ module Rouge
goto :regex
end
- rule /[{]/, Punctuation, :object
+ rule /[{]/ do
+ token Punctuation
+ goto :object
+ end
rule //, Text, :pop!
end
@@ -177,6 +186,12 @@ module Rouge
# object literals
state :object do
mixin :comments_and_whitespace
+
+ rule /[{]/ do
+ token Punctuation
+ push
+ end
+
rule /[}]/ do
token Punctuation
goto :statement
diff --git a/lib/rouge/lexers/kotlin.rb b/lib/rouge/lexers/kotlin.rb
new file mode 100644
index 0000000..5ce4542
--- /dev/null
+++ b/lib/rouge/lexers/kotlin.rb
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Lexers
+ class Kotlin < RegexLexer
+ title "Kotlin"
+ desc "Kotlin <http://kotlinlang.org>"
+
+ tag 'kotlin'
+ filenames '*.kt'
+ mimetypes 'text/x-kotlin'
+
+ keywords = %w(
+ abstract annotation as break by catch class companion const
+ constructor continue crossinline do dynamic else enum
+ external false final finally for fun get if import in infix
+ inline inner interface internal is lateinit noinline null
+ object open operator out override package private protected
+ public reified return sealed set super tailrec this throw
+ true try typealias typeof val var vararg when where while
+ yield
+ )
+
+ name = %r'@?[_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Nl}][\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Nl}\p{Nd}\p{Pc}\p{Cf}\p{Mn}\p{Mc}]*'
+
+ id = %r'(#{name}|`#{name}`)'
+
+ state :root do
+ rule %r'^\s*\[.*?\]', Name::Attribute
+ rule %r'[^\S\n]+', Text
+ rule %r'\\\n', Text # line continuation
+ rule %r'//.*?\n', Comment::Single
+ rule %r'/[*].*?[*]/'m, Comment::Multiline
+ rule %r'\n', Text
+ rule %r'::|!!|\?[:.]', Operator
+ rule %r"(\.\.)", Operator
+ rule %r'[~!%^&*()+=|\[\]:;,.<>/?-]', Punctuation
+ rule %r'[{}]', Punctuation
+ rule %r'@"(""|[^"])*"'m, Str
+ rule %r'""".*?"""'m, Str
+ rule %r'"(\\\\|\\"|[^"\n])*["\n]'m, Str
+ rule %r"'\\.'|'[^\\]'", Str::Char
+ rule %r"[0-9](\.[0-9]+)?([eE][+-][0-9]+)?[flFL]?|0[xX][0-9a-fA-F]+[Ll]?", Num
+ rule %r'(class)(\s+)(object)' do
+ groups Keyword, Text, Keyword
+ end
+ rule %r'(class|data\s+class|interface|object)(\s+)' do
+ groups Keyword::Declaration, Text
+ push :class
+ end
+ rule %r'(package|import)(\s+)' do
+ groups Keyword, Text
+ push :package
+ end
+ rule %r'(val|var)(\s+)' do
+ groups Keyword::Declaration, Text
+ push :property
+ end
+ rule %r'(fun)(\s+)' do
+ groups Keyword, Text
+ push :function
+ end
+ rule /(?:#{keywords.join('|')})\b/, Keyword
+ rule id, Name
+ end
+
+ state :package do
+ rule /\S+/, Name::Namespace, :pop!
+ end
+
+ state :class do
+ rule id, Name::Class, :pop!
+ end
+
+ state :property do
+ rule id, Name::Property, :pop!
+ end
+
+ state :function do
+ rule id, Name::Function, :pop!
+ end
+ end
+ end
+end
diff --git a/lib/rouge/lexers/pascal.rb b/lib/rouge/lexers/pascal.rb
new file mode 100644
index 0000000..98f06cd
--- /dev/null
+++ b/lib/rouge/lexers/pascal.rb
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Lexers
+ class Pascal < RegexLexer
+ tag 'pascal'
+ title "Pascal"
+ desc 'a procedural programming language commonly used as a teaching language.'
+ filenames '*.pas'
+
+ mimetypes 'text/x-pascal'
+
+ id = /@?[_a-z]\w*/i
+
+ keywords = %w(
+ absolute abstract all and and_then array as asm assembler attribute
+ begin bindable case class const constructor delay destructor div do
+ downto else end except exit export exports external far file finalization
+ finally for forward function goto if implementation import in inc index
+ inherited initialization inline interface interrupt is label library
+ message mod module near nil not object of on only operator or or_else
+ otherwise out overload override packed pascal pow private procedure program
+ property protected public published qualified raise read record register
+ repeat resident resourcestring restricted safecall segment set shl shr
+ stdcall stored string then threadvar to try type unit until uses value var
+ view virtual while with write writeln xor
+ )
+
+ keywords_type = %w(
+ ansichar ansistring bool boolean byte bytebool cardinal char comp currency
+ double dword extended int64 integer iunknown longbool longint longword pansichar
+ pansistring pbool pboolean pbyte pbytearray pcardinal pchar pcomp pcurrency
+ pdate pdatetime pdouble pdword pextended phandle pint64 pinteger plongint plongword
+ pointer ppointer pshortint pshortstring psingle psmallint pstring pvariant pwidechar
+ pwidestring pword pwordarray pwordbool real real48 shortint shortstring single
+ smallint string tclass tdate tdatetime textfile thandle tobject ttime variant
+ widechar widestring word wordbool
+ )
+
+ state :whitespace do
+ # Spaces
+ rule /\s+/m, Text
+ # // Comments
+ rule %r((//).*$\n?), Comment::Single
+ # -- Comments
+ rule %r((--).*$\n?), Comment::Single
+ # (* Comments *)
+ rule %r(\(\*.*?\*\))m, Comment::Multiline
+ # { Comments }
+ rule %r(\{.*?\})m, Comment::Multiline
+ end
+
+ state :root do
+ mixin :whitespace
+
+ rule %r{((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?}, Num
+ rule %r{[~!@#\$%\^&\*\(\)\+`\-={}\[\]:;<>\?,\.\/\|\\]}, Punctuation
+ rule %r{'([^']|'')*'}, Str
+ rule /(true|false|nil)\b/i, Name::Builtin
+ rule /\b(#{keywords.join('|')})\b/i, Keyword
+ rule /\b(#{keywords_type.join('|')})\b/i, Keyword::Type
+ rule id, Name
+ end
+ end
+ end
+end
diff --git a/lib/rouge/lexers/praat.rb b/lib/rouge/lexers/praat.rb
index 82b25f3..089340c 100644
--- a/lib/rouge/lexers/praat.rb
+++ b/lib/rouge/lexers/praat.rb
@@ -16,7 +16,7 @@ module Rouge
keywords = %w(
if then else elsif elif endif fi for from to endfor endproc while
- endwhile repeat until select plus minus demo assert stopwatch
+ endwhile repeat until select plus minus demo assert stopwatch
nocheck nowarn noprogress editor endeditor clearinfo
)
@@ -39,7 +39,7 @@ module Rouge
endSendPraat endsWith erb erbToHertz erf erfc exitScript exp
extractNumber fileReadable fisherP fisherQ floor gaussP gaussQ
hertzToBark hertzToErb hertzToMel hertzToSemitones imax imin
- incompleteBeta incompleteGammaP index index_regex invBinomialP
+ incompleteBeta incompleteGammaP index index_regex integer invBinomialP
invBinomialQ invChiSquareQ invFisherQ invGaussQ invSigmoid invStudentQ
length ln lnBeta lnGamma log10 log2 max melToHertz min minusObject
natural number numberOfColumns numberOfRows numberOfSelected
@@ -47,10 +47,10 @@ module Rouge
phonToDifferenceLimens plusObject positive randomBinomial randomGauss
randomInteger randomPoisson randomUniform real readFile removeObject
rindex rindex_regex round runScript runSystem runSystem_nocheck
- selectObject selected semitonesToHertz sentencetext sigmoid sin sinc
- sincpi sinh soundPressureToPhon sqrt startsWith studentP studentQ tan
- tanh variableExists word writeFile writeFileLine writeInfo
- writeInfoLine
+ selectObject selected semitonesToHertz sentence sentencetext sigmoid
+ sin sinc sincpi sinh soundPressureToPhon sqrt startsWith studentP
+ studentQ tan tanh text variableExists word writeFile writeFileLine
+ writeInfo writeInfoLine
)
functions_array = %w(
@@ -62,29 +62,31 @@ module Rouge
BarkFilter BarkSpectrogram CCA Categories Cepstrogram Cepstrum
Cepstrumc ChebyshevSeries ClassificationTable Cochleagram Collection
ComplexSpectrogram Configuration Confusion ContingencyTable Corpus
- Correlation Covariance CrossCorrelationTable CrossCorrelationTables DTW
- DataModeler Diagonalizer Discriminant Dissimilarity Distance
- Distributions DurationTier EEG ERP ERPTier EditCostsTable
- EditDistanceTable Eigen Excitation Excitations ExperimentMFC FFNet
- FeatureWeights FileInMemory FilesInMemory Formant FormantFilter
- FormantGrid FormantModeler FormantPoint FormantTier GaussianMixture HMM
- HMM_Observation HMM_ObservationSequence HMM_State HMM_StateSequence
- Harmonicity ISpline Index Intensity IntensityTier IntervalTier KNN
- KlattGrid KlattTable LFCC LPC Label LegendreSeries LinearRegression
- LogisticRegression LongSound Ltas MFCC MSpline ManPages Manipulation
- Matrix MelFilter MelSpectrogram MixingMatrix Movie Network OTGrammar
- OTHistory OTMulti PCA PairDistribution ParamCurve Pattern Permutation
- Photo Pitch PitchModeler PitchTier PointProcess Polygon Polynomial
- PowerCepstrogram PowerCepstrum Procrustes RealPoint RealTier ResultsMFC
- Roots SPINET SSCP SVD Salience ScalarProduct Similarity SimpleString
- SortedSetOfString Sound Speaker Spectrogram Spectrum SpectrumTier
- SpeechSynthesizer SpellingChecker Strings StringsIndex Table
- TableOfReal TextGrid TextInterval TextPoint TextTier Tier Transition
- VocalTract VocalTractTier Weight WordList
+ Correlation Covariance CrossCorrelationTable CrossCorrelationTableList
+ CrossCorrelationTables DTW DataModeler Diagonalizer Discriminant
+ Dissimilarity Distance Distributions DurationTier EEG ERP ERPTier
+ EditCostsTable EditDistanceTable Eigen Excitation Excitations
+ ExperimentMFC FFNet FeatureWeights FileInMemory FilesInMemory Formant
+ FormantFilter FormantGrid FormantModeler FormantPoint FormantTier
+ GaussianMixture HMM HMM_Observation HMM_ObservationSequence HMM_State
+ HMM_StateSequence HMMObservation HMMObservationSequence HMMState
+ HMMStateSequence Harmonicity ISpline Index Intensity IntensityTier
+ IntervalTier KNN KlattGrid KlattTable LFCC LPC Label LegendreSeries
+ LinearRegression LogisticRegression LongSound Ltas MFCC MSpline ManPages
+ Manipulation Matrix MelFilter MelSpectrogram MixingMatrix Movie Network
+ OTGrammar OTHistory OTMulti PCA PairDistribution ParamCurve Pattern
+ Permutation Photo Pitch PitchModeler PitchTier PointProcess Polygon
+ Polynomial PowerCepstrogram PowerCepstrum Procrustes RealPoint RealTier
+ ResultsMFC Roots SPINET SSCP SVD Salience ScalarProduct Similarity
+ SimpleString SortedSetOfString Sound Speaker Spectrogram Spectrum
+ SpectrumTier SpeechSynthesizer SpellingChecker Strings StringsIndex
+ Table TableOfReal TextGrid TextInterval TextPoint TextTier Tier
+ Transition VocalTract VocalTractTier Weight WordList
)
variables_numeric = %w(
- macintosh windows unix praatVersion pi e undefined
+ all average e left macintosh mono pi praatVersion right stereo
+ undefined unix windows
)
variables_string = %w(
@@ -93,6 +95,10 @@ module Rouge
defaultDirectory
)
+ object_attributes = %w(
+ ncol nrow xmin ymin xmax ymax nx ny dx dy
+ )
+
state :root do
rule /(\s+)(#.*?$)/ do
groups Text, Comment::Single
@@ -107,6 +113,7 @@ module Rouge
mixin :function_call
+ rule /\b(?:select all)\b/, Keyword
rule /\b(?:#{keywords.join('|')})\b/, Keyword
rule /(\bform\b)(\s+)([^\n]+)/ do
@@ -132,51 +139,25 @@ module Rouge
rule /\b(?=[A-Z])/, Text, :command
rule /(\.{3}|[)(,\$])/, Punctuation
- rule /./, Generic::Error
end
state :command do
rule /( ?[\w()-]+ ?)/, Keyword
- rule /'(?=.*')/, Literal::String::Interpol, :string_interpolated
- rule /\.{3}/, Keyword, :old_arguments
- rule /:/, Keyword, :comma_list
- rule /[\s\n]/, Text, :pop!
- end
+ mixin :string_interpolated
- state :function_call do
- rule /\b(#{functions_string.join('|')})\$(?=\s*[:(])/, Name::Function, :function
- rule /\b(#{functions_array.join('|')})#(?=\s*[:(])/, Name::Function, :function
- rule /\b(#{functions_numeric.join('|')})(?=\s*[:(])/, Name::Function, :function
- end
-
- state :old_arguments do
- rule /\n/ do
- token Text
+ rule /\.{3}/ do
+ token Keyword
pop!
- pop! unless state? :root
+ push :old_arguments
end
- mixin :function_call
- mixin :operator
- mixin :number
-
- rule /"/, Literal::String, :string
- rule /[^\n]/, Text
- end
-
- state :function do
- rule /\s+/, Text
-
rule /:/ do
- token Punctuation
- push :comma_list
- end
-
- rule /\s*\(/ do
- token Punctuation
+ token Keyword
pop!
push :comma_list
end
+
+ rule /[\s\n]/, Text, :pop!
end
state :procedure_call do
@@ -184,10 +165,14 @@ module Rouge
rule /([\w.]+)(:|\s*\()/ do
groups Name::Function, Punctuation
- push :comma_list
+ pop!
end
- rule /([\w.]+)/, Name::Function, :old_arguments
+ rule /([\w.]+)/ do
+ token Name::Function
+ pop!
+ push :old_arguments
+ end
end
state :procedure_definition do
@@ -204,16 +189,28 @@ module Rouge
end
end
+ state :function_call do
+ rule /\b(#{functions_string.join('|')})\$(?=\s*[:(])/, Name::Function, :function
+ rule /\b(#{functions_array.join('|')})#(?=\s*[:(])/, Name::Function, :function
+ rule /\b(#{functions_numeric.join('|')})(?=\s*[:(])/, Name::Function, :function
+ end
+
+ state :function do
+ rule /\s+/, Text
+
+ rule /(?::|\s*\()/ do
+ token Text
+ pop!
+ push :comma_list
+ end
+ end
+
state :comma_list do
rule /(\s*\n\s*)(\.{3})/ do
groups Text, Punctuation
end
- rule /\s*(\)|\]|\n)/ do
- token Punctuation
- pop!
- pop! unless state? :root
- end
+ rule /\s*[\])\n]/, Text, :pop!
rule /\s+/, Text
rule /"/, Literal::String, :string
@@ -224,9 +221,21 @@ module Rouge
mixin :operator
mixin :number
+ rule /[()]/, Text
rule /,/, Punctuation
end
+ state :old_arguments do
+ rule /\n/, Text, :pop!
+
+ mixin :variable_name
+ mixin :operator
+ mixin :number
+
+ rule /"/, Literal::String, :string
+ rule /[^\n]/, Text
+ end
+
state :number do
rule /\n/, Text, :pop!
rule /\b\d+(\.\d*)?([eE][-+]?\d+)?%?/, Literal::Number
@@ -237,43 +246,45 @@ module Rouge
mixin :number
rule /\b(?:#{variables_string.join('|')})\$/, Name::Builtin
- rule /\b(?:#{variables_numeric.join('|')})\b/, Name::Builtin
+ rule /\b(?:#{variables_numeric.join('|')})(?!\$)\b/, Name::Builtin
- rule /\b(Object|#{objects.join('|')})_\w+/, Name::Builtin, :object_attributes
-
- rule /\b((?:Object|#{objects.join('|')})_)(')/ do
- groups Name::Builtin, Literal::String::Interpol
- push :object_attributes
- push :string_interpolated
+ rule /\b(Object|#{objects.join('|')})_/ do
+ token Name::Builtin
+ push :object_reference
end
rule /\.?[a-z][a-zA-Z0-9_.]*(\$|#)?/, Text
- rule /[\[\]]/, Punctuation
- rule /'(?=.*')/, Literal::String::Interpol, :string_interpolated
+ rule /[\[\]]/, Text, :comma_list
+ mixin :string_interpolated
end
- state :object_attributes do
- rule /\.?(n(col|row)|[xy]min|[xy]max|[nd][xy])\b/, Name::Builtin, :pop!
- rule /(\.?(?:col|row)\$)(\[)/ do
- groups Name::Builtin, Punctuation
- push :variable_name
- end
- rule /(\$?)(\[)/ do
- groups Name::Builtin, Punctuation
- push :comma_list
- end
+ state :object_reference do
+ mixin :string_interpolated
+ rule /([a-z][a-zA-Z0-9_]*|\d+)/, Name::Builtin
+
+ rule /\.(#{object_attributes.join('|')})\b/, Name::Builtin, :pop!
+
+ rule /\$/, Name::Builtin
+ rule /\[/, Text, :pop!
+ end
+
+ state :operator do
+ # This rule incorrectly matches === or +++++, which are not operators
+ rule /([+\/*<>=!-]=?|[&*|][&*|]?|\^|<>)/, Operator
+ rule /(?<![\w.])(and|or|not|div|mod)(?![\w.])/, Operator::Word
end
state :string_interpolated do
- rule /\.?[_a-z][a-zA-Z0-9_.]*(?:[\$#]?(?:\[[a-zA-Z0-9,]+\])?|:[0-9]+)?/, Literal::String::Interpol
- rule /'/, Literal::String::Interpol, :pop!
+ rule /'[\._a-z][^\[\]'":]*(\[([\d,]+|"[\w\d,]+")\])?(:[0-9]+)?'/, Literal::String::Interpol
end
state :string_unquoted do
rule /\n\s*\.{3}/, Punctuation
rule /\n/, Text, :pop!
rule /\s/, Text
- rule /'(?=.*')/, Literal::String::Interpol, :string_interpolated
+
+ mixin :string_interpolated
+
rule /'/, Literal::String
rule /[^'\n]+/, Literal::String
end
@@ -281,12 +292,18 @@ module Rouge
state :string do
rule /\n\s*\.{3}/, Punctuation
rule /"/, Literal::String, :pop!
- rule /'(?=.*')/, Literal::String::Interpol, :string_interpolated
+
+ mixin :string_interpolated
+
rule /'/, Literal::String
rule /[^'"\n]+/, Literal::String
end
state :old_form do
+ rule /(\s+)(#.*?$)/ do
+ groups Text, Comment::Single
+ end
+
rule /\s+/, Text
rule /(optionmenu|choice)([ \t]+\S+:[ \t]+)/ do
@@ -296,11 +313,6 @@ module Rouge
rule /(option|button)([ \t]+)/ do
groups Keyword, Text
- push :number
- end
-
- rule /(option|button)([ \t]+)/ do
- groups Keyword, Text
push :string_unquoted
end
@@ -310,7 +322,7 @@ module Rouge
end
rule /(word)([ \t]+\S+[ \t]*)(\S+)?([ \t]+.*)?/ do
- groups Keyword, Text, Literal::String, Generic::Error
+ groups Keyword, Text, Literal::String, Text
end
rule /(boolean)(\s+\S+\s*)(0|1|"?(?:yes|no)"?)/ do
@@ -330,11 +342,6 @@ module Rouge
rule /\bendform\b/, Keyword, :pop!
end
- state :operator do
- # This rule incorrectly matches === or +++++, which are not operators
- rule /([+\/*<>=!-]=?|[&*|][&*|]?|\^|<>)/, Operator
- rule /\b(and|or|not|div|mod)\b/, Operator::Word
- end
end
end
end
diff --git a/lib/rouge/plugins/redcarpet.rb b/lib/rouge/plugins/redcarpet.rb
index f27511b..4ae513b 100644
--- a/lib/rouge/plugins/redcarpet.rb
+++ b/lib/rouge/plugins/redcarpet.rb
@@ -23,7 +23,7 @@ module Rouge
# override this method for custom formatting behavior
def rouge_formatter(lexer)
- Formatters::HTML.new(:css_class => "highlight #{lexer.tag}")
+ Formatters::HTMLLegacy.new(:css_class => "highlight #{lexer.tag}")
end
end
end
diff --git a/lib/rouge/theme.rb b/lib/rouge/theme.rb
index e35f689..d6d2ddf 100644
--- a/lib/rouge/theme.rb
+++ b/lib/rouge/theme.rb
@@ -63,6 +63,8 @@ module Rouge
end
end
+ def palette(*a) self.class.palette(*a) end
+
@styles = {}
def self.styles
@styles ||= InheritableHash.new(superclass.styles)
@@ -76,8 +78,6 @@ module Rouge
def style(*tokens)
style = tokens.last.is_a?(Hash) ? tokens.pop : {}
- style = Style.new(self, style)
-
tokens.each do |tok|
styles[tok] = style
end
@@ -85,7 +85,7 @@ module Rouge
def get_own_style(token)
token.token_chain.reverse_each do |anc|
- return styles[anc] if styles[anc]
+ return Style.new(self, styles[anc]) if styles[anc]
end
nil
@@ -96,7 +96,7 @@ module Rouge
end
def base_style
- styles[Token::Tokens::Text]
+ get_own_style(Token::Tokens::Text)
end
def name(n=nil)
@@ -150,7 +150,7 @@ module Rouge
yield "#{@scope} table pre { margin: 0; }"
styles.each do |tok, style|
- style.render(css_selector(tok), &b)
+ Style.new(self, style).render(css_selector(tok), &b)
end
end
diff --git a/lib/rouge/themes/gruvbox.rb b/lib/rouge/themes/gruvbox.rb
new file mode 100644
index 0000000..330803d
--- /dev/null
+++ b/lib/rouge/themes/gruvbox.rb
@@ -0,0 +1,167 @@
+# -*- coding: utf-8 -*- #
+
+# TODO how are we going to handle soft/hard contrast?
+
+module Rouge
+ module Themes
+ # Based on https://github.com/morhetz/gruvbox, with help from
+ # https://github.com/daveyarwood/gruvbox-pygments
+ class Gruvbox < CSSTheme
+ name 'gruvbox'
+
+ # global Gruvbox colours {{{
+ C_dark0_hard = '#1d2021'
+ C_dark0 ='#282828'
+ C_dark0_soft = '#32302f'
+ C_dark1 = '#3c3836'
+ C_dark2 = '#504945'
+ C_dark3 = '#665c54'
+ C_dark4 = '#7c6f64'
+ C_dark4_256 = '#7c6f64'
+
+ C_gray_245 = '#928374'
+ C_gray_244 = '#928374'
+
+ C_light0_hard = '#f9f5d7'
+ C_light0 = '#fbf1c7'
+ C_light0_soft = '#f2e5bc'
+ C_light1 = '#ebdbb2'
+ C_light2 = '#d5c4a1'
+ C_light3 = '#bdae93'
+ C_light4 = '#a89984'
+ C_light4_256 = '#a89984'
+
+ C_bright_red = '#fb4934'
+ C_bright_green = '#b8bb26'
+ C_bright_yellow = '#fabd2f'
+ C_bright_blue = '#83a598'
+ C_bright_purple = '#d3869b'
+ C_bright_aqua = '#8ec07c'
+ C_bright_orange = '#fe8019'
+
+ C_neutral_red = '#cc241d'
+ C_neutral_green = '#98971a'
+ C_neutral_yellow = '#d79921'
+ C_neutral_blue = '#458588'
+ C_neutral_purple = '#b16286'
+ C_neutral_aqua = '#689d6a'
+ C_neutral_orange = '#d65d0e'
+
+ C_faded_red = '#9d0006'
+ C_faded_green = '#79740e'
+ C_faded_yellow = '#b57614'
+ C_faded_blue = '#076678'
+ C_faded_purple = '#8f3f71'
+ C_faded_aqua = '#427b58'
+ C_faded_orange = '#af3a03'
+ # }}}
+
+ extend HasModes
+
+ def self.light!
+ mode :dark # indicate that there is a dark variant
+ mode! :light
+ end
+
+ def self.dark!
+ mode :light # indicate that there is a light variant
+ mode! :dark
+ end
+
+ def self.make_dark!
+ palette bg0: C_dark0
+ palette bg1: C_dark1
+ palette bg2: C_dark2
+ palette bg3: C_dark3
+ palette bg4: C_dark4
+
+ palette gray: C_gray_245
+
+ palette fg0: C_light0
+ palette fg1: C_light1
+ palette fg2: C_light2
+ palette fg3: C_light3
+ palette fg4: C_light4
+
+ palette fg4_256: C_light4_256
+
+ palette red: C_bright_red
+ palette green: C_bright_green
+ palette yellow: C_bright_yellow
+ palette blue: C_bright_blue
+ palette purple: C_bright_purple
+ palette aqua: C_bright_aqua
+ palette orange: C_bright_orange
+
+ end
+
+ def self.make_light!
+ palette bg0: C_light0
+ palette bg1: C_light1
+ palette bg2: C_light2
+ palette bg3: C_light3
+ palette bg4: C_light4
+
+ palette gray: C_gray_244
+
+ palette fg0: C_dark0
+ palette fg1: C_dark1
+ palette fg2: C_dark2
+ palette fg3: C_dark3
+ palette fg4: C_dark4
+
+ palette fg4_256: C_dark4_256
+
+ palette red: C_faded_red
+ palette green: C_faded_green
+ palette yellow: C_faded_yellow
+ palette blue: C_faded_blue
+ palette purple: C_faded_purple
+ palette aqua: C_faded_aqua
+ palette orange: C_faded_orange
+ end
+
+ dark!
+ mode :light
+
+ style Text, :fg => :fg0, :bg => :bg0
+ style Error, :fg => :red, :bg => :bg0, :bold => true
+ style Comment, :fg => :gray, :italic => true
+
+ style Comment::Preproc, :fg => :aqua
+
+ style Name::Tag, :fg => :red
+
+ style Operator,
+ Punctuation, :fg => :fg0
+
+ style Generic::Inserted, :fg => :green, :bg => :bg0
+ style Generic::Deleted, :fg => :red, :bg => :bg0
+ style Generic::Heading, :fg => :green, :bold => true
+
+ style Keyword, :fg => :red
+ style Keyword::Constant, :fg => :purple
+ style Keyword::Type, :fg => :yellow
+
+ style Keyword::Declaration, :fg => :orange
+
+ style Literal::String,
+ Literal::String::Interpol,
+ Literal::String::Regex, :fg => :green, :italic => true
+
+ style Literal::String::Escape, :fg => :orange
+
+ style Name::Namespace,
+ Name::Class, :fg => :aqua
+
+ style Name::Constant, :fg => :purple
+
+ style Name::Attribute, :fg => :green
+
+ style Literal::Number, :fg => :purple
+
+ style Literal::String::Symbol, :fg => :blue
+
+ end
+ end
+end
diff --git a/lib/rouge/version.rb b/lib/rouge/version.rb
index fb9c97c..053b168 100644
--- a/lib/rouge/version.rb
+++ b/lib/rouge/version.rb
@@ -2,6 +2,6 @@
module Rouge
def self.version
- "1.11.0"
+ "2.0.1"
end
end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-rouge.git
More information about the Pkg-ruby-extras-commits
mailing list