summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/coderay/scanners/go.rb96
-rw-r--r--lib/coderay/styles/alpha.rb2
2 files changed, 53 insertions, 45 deletions
diff --git a/lib/coderay/scanners/go.rb b/lib/coderay/scanners/go.rb
index a66a5e3..49d24c2 100644
--- a/lib/coderay/scanners/go.rb
+++ b/lib/coderay/scanners/go.rb
@@ -1,12 +1,12 @@
module CodeRay
module Scanners
-
+
# Scanner for Go, copy from c
class Go < Scanner
-
+
register_for :go
file_extension 'go'
-
+
# http://golang.org/ref/spec#Keywords
KEYWORDS = [
'break', 'default', 'func', 'interface', 'select',
@@ -15,7 +15,7 @@ module Scanners
'const', 'fallthrough', 'if', 'range', 'type',
'continue', 'for', 'import', 'return', 'var',
] # :nodoc:
-
+
# http://golang.org/ref/spec#Types
PREDEFINED_TYPES = [
'bool',
@@ -26,63 +26,64 @@ module Scanners
'byte', 'rune', 'string', 'error',
'uint', 'int', 'uintptr',
] # :nodoc:
-
+
PREDEFINED_CONSTANTS = [
'nil', 'iota',
'true', 'false',
] # :nodoc:
-
+
DIRECTIVES = [
'go_no_directive', # Seems no directive concept in Go?
] # :nodoc:
-
+
IDENT_KIND = WordList.new(:ident).
add(KEYWORDS, :keyword).
add(PREDEFINED_TYPES, :predefined_type).
add(DIRECTIVES, :directive).
add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc:
-
+
ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc:
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc:
-
- protected
-
+
+ protected
+
def scan_tokens encoder, options
-
+
state = :initial
label_expected = true
case_expected = false
label_expected_before_preproc_line = nil
in_preproc_line = false
-
+
until eos?
-
+
case state
-
+
when :initial
-
+
if match = scan(/ \s+ | \\\n /x)
if in_preproc_line && match != "\\\n" && match.index(?\n)
in_preproc_line = false
+ case_expected = false
label_expected = label_expected_before_preproc_line
end
encoder.text_token match, :space
-
+
elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
encoder.text_token match, :comment
-
+
elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x)
- label_expected = match =~ /[;\{\}]/
if case_expected
label_expected = true if match == ':'
case_expected = false
end
encoder.text_token match, :operator
-
+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
kind = IDENT_KIND[match]
if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/)
kind = :label
+ label_expected = false
match << matched
else
label_expected = false
@@ -94,7 +95,7 @@ module Scanners
end
end
encoder.text_token match, kind
-
+
elsif match = scan(/L?"/)
encoder.begin_group :string
if match[0] == ?L
@@ -103,45 +104,52 @@ module Scanners
end
encoder.text_token match, :delimiter
state = :string
-
+
+ elsif match = scan(/ ` ([^`]+)? (`)? /x)
+ encoder.begin_group :shell
+ encoder.text_token '`', :delimiter
+ encoder.text_token self[1], :content if self[1]
+ encoder.text_token self[2], :delimiter if self[2]
+ encoder.end_group :shell
+
elsif match = scan(/ \# \s* if \s* 0 /x)
match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos?
encoder.text_token match, :comment
-
+
elsif match = scan(/#[ \t]*(\w*)/)
encoder.text_token match, :preprocessor
in_preproc_line = true
label_expected_before_preproc_line = label_expected
state = :include_expected if self[1] == 'include'
-
+
elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
label_expected = false
encoder.text_token match, :char
-
+
elsif match = scan(/\$/)
encoder.text_token match, :ident
-
+
elsif match = scan(/0[xX][0-9A-Fa-f]+/)
label_expected = false
encoder.text_token match, :hex
-
+
elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/)
label_expected = false
encoder.text_token match, :octal
-
+
elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/)
label_expected = false
encoder.text_token match, :integer
-
+
elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
label_expected = false
encoder.text_token match, :float
-
+
else
encoder.text_token getch, :error
-
+
end
-
+
when :string
if match = scan(/[^\\\n"]+/)
encoder.text_token match, :content
@@ -154,42 +162,42 @@ module Scanners
encoder.text_token match, :char
elsif match = scan(/ \\ | $ /x)
encoder.end_group :string
- encoder.text_token match, :error
+ encoder.text_token match, :error unless match.empty?
state = :initial
label_expected = false
else
raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
end
-
+
when :include_expected
if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
encoder.text_token match, :include
state = :initial
-
+
elsif match = scan(/\s+/)
encoder.text_token match, :space
state = :initial if match.index ?\n
-
+
else
state = :initial
-
+
end
-
+
else
raise_inspect 'Unknown state', encoder
-
+
end
-
+
end
-
+
if state == :string
encoder.end_group :string
end
-
+
encoder
end
-
+
end
-
+
end
end
diff --git a/lib/coderay/styles/alpha.rb b/lib/coderay/styles/alpha.rb
index ff85ecc..f4e9d7d 100644
--- a/lib/coderay/styles/alpha.rb
+++ b/lib/coderay/styles/alpha.rb
@@ -107,7 +107,7 @@ table.CodeRay td { padding: 2px 4px; vertical-align: top; }
.operator { }
.predefined { color:#369; font-weight:bold }
.predefined-constant { color:#069 }
-.predefined-type { color:#0a5; font-weight:bold }
+.predefined-type { color:#0a8; font-weight:bold }
.preprocessor { color:#579 }
.pseudo-class { color:#00C; font-weight:bold }
.regexp { background-color:hsla(300,100%,50%,0.06); }