coderay 0.9.8 → 1.0.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.
- data/{lib/README → README_INDEX.rdoc} +10 -21
- data/Rakefile +6 -6
- data/bin/coderay +193 -64
- data/lib/coderay.rb +61 -105
- data/lib/coderay/duo.rb +17 -21
- data/lib/coderay/encoder.rb +100 -112
- data/lib/coderay/encoders/_map.rb +12 -7
- data/lib/coderay/encoders/comment_filter.rb +12 -30
- data/lib/coderay/encoders/count.rb +29 -11
- data/lib/coderay/encoders/debug.rb +32 -20
- data/lib/coderay/encoders/div.rb +13 -9
- data/lib/coderay/encoders/filter.rb +34 -51
- data/lib/coderay/encoders/html.rb +155 -161
- data/lib/coderay/encoders/html/css.rb +4 -9
- data/lib/coderay/encoders/html/numbering.rb +115 -0
- data/lib/coderay/encoders/html/output.rb +22 -70
- data/lib/coderay/encoders/json.rb +59 -45
- data/lib/coderay/encoders/lines_of_code.rb +12 -57
- data/lib/coderay/encoders/null.rb +6 -14
- data/lib/coderay/encoders/page.rb +13 -9
- data/lib/coderay/encoders/span.rb +13 -9
- data/lib/coderay/encoders/statistic.rb +58 -39
- data/lib/coderay/encoders/terminal.rb +179 -0
- data/lib/coderay/encoders/text.rb +31 -17
- data/lib/coderay/encoders/token_kind_filter.rb +111 -0
- data/lib/coderay/encoders/xml.rb +19 -18
- data/lib/coderay/encoders/yaml.rb +37 -9
- data/lib/coderay/for_redcloth.rb +4 -4
- data/lib/coderay/helpers/file_type.rb +127 -246
- data/lib/coderay/helpers/gzip.rb +41 -0
- data/lib/coderay/helpers/plugin.rb +241 -306
- data/lib/coderay/helpers/word_list.rb +65 -126
- data/lib/coderay/scanner.rb +173 -156
- data/lib/coderay/scanners/_map.rb +18 -17
- data/lib/coderay/scanners/c.rb +63 -77
- data/lib/coderay/scanners/clojure.rb +217 -0
- data/lib/coderay/scanners/cpp.rb +71 -84
- data/lib/coderay/scanners/css.rb +103 -120
- data/lib/coderay/scanners/debug.rb +47 -44
- data/lib/coderay/scanners/delphi.rb +70 -76
- data/lib/coderay/scanners/diff.rb +141 -50
- data/lib/coderay/scanners/erb.rb +81 -0
- data/lib/coderay/scanners/groovy.rb +104 -113
- data/lib/coderay/scanners/haml.rb +168 -0
- data/lib/coderay/scanners/html.rb +181 -110
- data/lib/coderay/scanners/java.rb +73 -75
- data/lib/coderay/scanners/java/builtin_types.rb +2 -0
- data/lib/coderay/scanners/java_script.rb +90 -101
- data/lib/coderay/scanners/json.rb +40 -53
- data/lib/coderay/scanners/php.rb +123 -147
- data/lib/coderay/scanners/python.rb +93 -91
- data/lib/coderay/scanners/raydebug.rb +66 -0
- data/lib/coderay/scanners/ruby.rb +343 -326
- data/lib/coderay/scanners/ruby/patterns.rb +40 -106
- data/lib/coderay/scanners/ruby/string_state.rb +71 -0
- data/lib/coderay/scanners/sql.rb +80 -66
- data/lib/coderay/scanners/text.rb +26 -0
- data/lib/coderay/scanners/xml.rb +1 -1
- data/lib/coderay/scanners/yaml.rb +74 -73
- data/lib/coderay/style.rb +10 -7
- data/lib/coderay/styles/_map.rb +3 -3
- data/lib/coderay/styles/alpha.rb +143 -0
- data/lib/coderay/token_kinds.rb +90 -0
- data/lib/coderay/tokens.rb +102 -277
- data/lib/coderay/tokens_proxy.rb +55 -0
- data/lib/coderay/version.rb +3 -0
- data/test/functional/basic.rb +200 -18
- data/test/functional/examples.rb +130 -0
- data/test/functional/for_redcloth.rb +15 -8
- data/test/functional/suite.rb +9 -6
- metadata +103 -123
- data/FOLDERS +0 -53
- data/bin/coderay_stylesheet +0 -4
- data/lib/coderay/encoders/html/numerization.rb +0 -133
- data/lib/coderay/encoders/term.rb +0 -158
- data/lib/coderay/encoders/token_class_filter.rb +0 -84
- data/lib/coderay/helpers/gzip_simple.rb +0 -123
- data/lib/coderay/scanners/nitro_xhtml.rb +0 -136
- data/lib/coderay/scanners/plaintext.rb +0 -20
- data/lib/coderay/scanners/rhtml.rb +0 -78
- data/lib/coderay/scanners/scheme.rb +0 -145
- data/lib/coderay/styles/cycnus.rb +0 -152
- data/lib/coderay/styles/murphy.rb +0 -134
- data/lib/coderay/token_classes.rb +0 -86
- data/test/functional/load_plugin_scanner.rb +0 -11
- data/test/functional/vhdl.rb +0 -126
- data/test/functional/word_list.rb +0 -79
@@ -1,62 +1,65 @@
|
|
1
1
|
module CodeRay
|
2
2
|
module Scanners
|
3
|
-
|
3
|
+
|
4
4
|
# = Debug Scanner
|
5
|
+
#
|
6
|
+
# Interprets the output of the Encoders::Debug encoder.
|
5
7
|
class Debug < Scanner
|
6
|
-
|
7
|
-
include Streamable
|
8
|
+
|
8
9
|
register_for :debug
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
title 'CodeRay Token Dump Import'
|
11
|
+
|
12
12
|
protected
|
13
|
-
|
14
|
-
|
13
|
+
|
14
|
+
def scan_tokens encoder, options
|
15
|
+
|
15
16
|
opened_tokens = []
|
16
|
-
|
17
|
+
|
17
18
|
until eos?
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
elsif scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) \) /x)
|
27
|
-
kind = self[1].to_sym
|
28
|
-
match = self[2].gsub(/\\(.)/, '\1')
|
29
|
-
|
30
|
-
elsif scan(/ (\w+) < /x)
|
31
|
-
kind = self[1].to_sym
|
32
|
-
opened_tokens << kind
|
33
|
-
match = :open
|
34
|
-
|
35
|
-
elsif !opened_tokens.empty? && scan(/ > /x)
|
36
|
-
kind = opened_tokens.pop || :error
|
37
|
-
match = :close
|
38
|
-
|
39
|
-
else
|
19
|
+
|
20
|
+
if match = scan(/\s+/)
|
21
|
+
encoder.text_token match, :space
|
22
|
+
|
23
|
+
elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) \)? /x)
|
24
|
+
kind = self[1].to_sym
|
25
|
+
match = self[2].gsub(/\\(.)/m, '\1')
|
26
|
+
unless TokenKinds.has_key? kind
|
40
27
|
kind = :error
|
41
|
-
|
42
|
-
|
28
|
+
match = matched
|
43
29
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
30
|
+
encoder.text_token match, kind
|
31
|
+
|
32
|
+
elsif match = scan(/ (\w+) ([<\[]) /x)
|
33
|
+
kind = self[1].to_sym
|
34
|
+
opened_tokens << kind
|
35
|
+
case self[2]
|
36
|
+
when '<'
|
37
|
+
encoder.begin_group kind
|
38
|
+
when '['
|
39
|
+
encoder.begin_line kind
|
40
|
+
else
|
41
|
+
raise 'CodeRay bug: This case should not be reached.'
|
42
|
+
end
|
43
|
+
|
44
|
+
elsif !opened_tokens.empty? && match = scan(/ > /x)
|
45
|
+
encoder.end_group opened_tokens.pop
|
46
|
+
|
47
|
+
elsif !opened_tokens.empty? && match = scan(/ \] /x)
|
48
|
+
encoder.end_line opened_tokens.pop
|
49
|
+
|
50
|
+
else
|
51
|
+
encoder.text_token getch, :space
|
52
|
+
|
49
53
|
end
|
50
|
-
raise_inspect 'Empty token', tokens unless match
|
51
|
-
|
52
|
-
tokens << [match, kind]
|
53
54
|
|
54
55
|
end
|
55
56
|
|
56
|
-
|
57
|
+
encoder.end_group opened_tokens.pop until opened_tokens.empty?
|
58
|
+
|
59
|
+
encoder
|
57
60
|
end
|
58
|
-
|
61
|
+
|
59
62
|
end
|
60
|
-
|
63
|
+
|
61
64
|
end
|
62
65
|
end
|
@@ -1,12 +1,15 @@
|
|
1
1
|
module CodeRay
|
2
2
|
module Scanners
|
3
3
|
|
4
|
+
# Scanner for the Delphi language (Object Pascal).
|
5
|
+
#
|
6
|
+
# Alias: +pascal+
|
4
7
|
class Delphi < Scanner
|
5
|
-
|
8
|
+
|
6
9
|
register_for :delphi
|
7
10
|
file_extension 'pas'
|
8
11
|
|
9
|
-
|
12
|
+
KEYWORDS = [
|
10
13
|
'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class',
|
11
14
|
'const', 'constructor', 'destructor', 'dispinterface', 'div', 'do',
|
12
15
|
'downto', 'else', 'end', 'except', 'exports', 'file', 'finalization',
|
@@ -16,9 +19,9 @@ module Scanners
|
|
16
19
|
'procedure', 'program', 'property', 'raise', 'record', 'repeat',
|
17
20
|
'resourcestring', 'set', 'shl', 'shr', 'string', 'then', 'threadvar',
|
18
21
|
'to', 'try', 'type', 'unit', 'until', 'uses', 'var', 'while', 'with',
|
19
|
-
'xor', 'on'
|
20
|
-
]
|
21
|
-
|
22
|
+
'xor', 'on',
|
23
|
+
] # :nodoc:
|
24
|
+
|
22
25
|
DIRECTIVES = [
|
23
26
|
'absolute', 'abstract', 'assembler', 'at', 'automated', 'cdecl',
|
24
27
|
'contains', 'deprecated', 'dispid', 'dynamic', 'export',
|
@@ -27,121 +30,112 @@ module Scanners
|
|
27
30
|
'package', 'pascal', 'platform', 'private', 'protected', 'public',
|
28
31
|
'published', 'read', 'readonly', 'register', 'reintroduce',
|
29
32
|
'requires', 'resident', 'safecall', 'stdcall', 'stored', 'varargs',
|
30
|
-
'virtual', 'write', 'writeonly'
|
31
|
-
]
|
32
|
-
|
33
|
-
IDENT_KIND = CaseIgnoringWordList.new(:ident).
|
34
|
-
add(RESERVED_WORDS, :reserved).
|
35
|
-
add(DIRECTIVES, :directive)
|
33
|
+
'virtual', 'write', 'writeonly',
|
34
|
+
] # :nodoc:
|
36
35
|
|
37
|
-
|
38
|
-
add(
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
IDENT_KIND = WordList::CaseIgnoring.new(:ident).
|
37
|
+
add(KEYWORDS, :keyword).
|
38
|
+
add(DIRECTIVES, :directive) # :nodoc:
|
39
|
+
|
40
|
+
NAME_FOLLOWS = WordList::CaseIgnoring.new(false).
|
41
|
+
add(%w(procedure function .)) # :nodoc:
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def scan_tokens encoder, options
|
46
|
+
|
43
47
|
state = :initial
|
44
48
|
last_token = ''
|
45
|
-
|
49
|
+
|
46
50
|
until eos?
|
47
|
-
|
48
|
-
kind = nil
|
49
|
-
match = nil
|
50
|
-
|
51
|
+
|
51
52
|
if state == :initial
|
52
53
|
|
53
|
-
if scan(/ \s+ /x)
|
54
|
-
|
54
|
+
if match = scan(/ \s+ /x)
|
55
|
+
encoder.text_token match, :space
|
55
56
|
next
|
56
57
|
|
57
|
-
elsif scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx)
|
58
|
-
|
58
|
+
elsif match = scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx)
|
59
|
+
encoder.text_token match, :preprocessor
|
59
60
|
next
|
60
61
|
|
61
|
-
elsif scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx)
|
62
|
-
|
62
|
+
elsif match = scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx)
|
63
|
+
encoder.text_token match, :comment
|
63
64
|
next
|
64
65
|
|
65
66
|
elsif match = scan(/ <[>=]? | >=? | :=? | [-+=*\/;,@\^|\(\)\[\]] | \.\. /x)
|
66
|
-
|
67
|
+
encoder.text_token match, :operator
|
67
68
|
|
68
69
|
elsif match = scan(/\./)
|
69
|
-
|
70
|
-
if last_token == 'end'
|
71
|
-
tokens << [match, kind]
|
72
|
-
next
|
73
|
-
end
|
70
|
+
encoder.text_token match, :operator
|
71
|
+
next if last_token == 'end'
|
74
72
|
|
75
73
|
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
|
76
|
-
|
74
|
+
encoder.text_token match, NAME_FOLLOWS[last_token] ? :ident : IDENT_KIND[match]
|
77
75
|
|
78
|
-
elsif match =
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
elsif match = skip(/ ' ( [^\n']|'' ) (?:'|$) /x)
|
77
|
+
encoder.begin_group :char
|
78
|
+
encoder.text_token "'", :delimiter
|
79
|
+
encoder.text_token self[1], :content
|
80
|
+
encoder.text_token "'", :delimiter
|
81
|
+
encoder.end_group :char
|
84
82
|
next
|
85
83
|
|
86
84
|
elsif match = scan(/ ' /x)
|
87
|
-
|
85
|
+
encoder.begin_group :string
|
86
|
+
encoder.text_token match, :delimiter
|
88
87
|
state = :string
|
89
|
-
kind = :delimiter
|
90
88
|
|
91
|
-
elsif scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x)
|
92
|
-
|
89
|
+
elsif match = scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x)
|
90
|
+
encoder.text_token match, :char
|
93
91
|
|
94
|
-
elsif scan(/ \$ [0-9A-Fa-f]+ /x)
|
95
|
-
|
92
|
+
elsif match = scan(/ \$ [0-9A-Fa-f]+ /x)
|
93
|
+
encoder.text_token match, :hex
|
96
94
|
|
97
|
-
elsif scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x)
|
98
|
-
|
95
|
+
elsif match = scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x)
|
96
|
+
encoder.text_token match, :integer
|
97
|
+
|
98
|
+
elsif match = scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x)
|
99
|
+
encoder.text_token match, :float
|
99
100
|
|
100
|
-
elsif scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x)
|
101
|
-
kind = :float
|
102
|
-
|
103
101
|
else
|
104
|
-
|
105
|
-
|
106
|
-
|
102
|
+
encoder.text_token getch, :error
|
103
|
+
next
|
104
|
+
|
107
105
|
end
|
108
106
|
|
109
107
|
elsif state == :string
|
110
|
-
if scan(/[^\n']+/)
|
111
|
-
|
112
|
-
elsif scan(/''/)
|
113
|
-
|
114
|
-
elsif scan(/'/)
|
115
|
-
|
116
|
-
|
108
|
+
if match = scan(/[^\n']+/)
|
109
|
+
encoder.text_token match, :content
|
110
|
+
elsif match = scan(/''/)
|
111
|
+
encoder.text_token match, :char
|
112
|
+
elsif match = scan(/'/)
|
113
|
+
encoder.text_token match, :delimiter
|
114
|
+
encoder.end_group :string
|
117
115
|
state = :initial
|
118
116
|
next
|
119
|
-
elsif scan(/\n/)
|
120
|
-
|
121
|
-
|
117
|
+
elsif match = scan(/\n/)
|
118
|
+
encoder.end_group :string
|
119
|
+
encoder.text_token match, :space
|
122
120
|
state = :initial
|
123
121
|
else
|
124
|
-
raise "else case \' reached; %p not handled." % peek(1),
|
122
|
+
raise "else case \' reached; %p not handled." % peek(1), encoder
|
125
123
|
end
|
126
124
|
|
127
125
|
else
|
128
|
-
raise 'else-case reached',
|
126
|
+
raise 'else-case reached', encoder
|
129
127
|
|
130
128
|
end
|
131
129
|
|
132
|
-
match ||= matched
|
133
|
-
if $CODERAY_DEBUG and not kind
|
134
|
-
raise_inspect 'Error token %p in line %d' %
|
135
|
-
[[match, kind], line], tokens, state
|
136
|
-
end
|
137
|
-
raise_inspect 'Empty token', tokens unless match
|
138
|
-
|
139
130
|
last_token = match
|
140
|
-
tokens << [match, kind]
|
141
131
|
|
142
132
|
end
|
143
133
|
|
144
|
-
|
134
|
+
if state == :string
|
135
|
+
encoder.end_group state
|
136
|
+
end
|
137
|
+
|
138
|
+
encoder
|
145
139
|
end
|
146
140
|
|
147
141
|
end
|
@@ -1,25 +1,43 @@
|
|
1
1
|
module CodeRay
|
2
2
|
module Scanners
|
3
3
|
|
4
|
+
# Scanner for output of the diff command.
|
5
|
+
#
|
6
|
+
# Alias: +patch+
|
4
7
|
class Diff < Scanner
|
5
8
|
|
6
9
|
register_for :diff
|
7
10
|
title 'diff output'
|
8
11
|
|
9
|
-
|
12
|
+
DEFAULT_OPTIONS = {
|
13
|
+
:highlight_code => true,
|
14
|
+
:inline_diff => true,
|
15
|
+
}
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
require 'coderay/helpers/file_type'
|
20
|
+
|
21
|
+
def scan_tokens encoder, options
|
10
22
|
|
11
23
|
line_kind = nil
|
12
24
|
state = :initial
|
25
|
+
deleted_lines = 0
|
26
|
+
scanners = Hash.new do |h, lang|
|
27
|
+
h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true
|
28
|
+
end
|
29
|
+
content_scanner = scanners[:plain]
|
30
|
+
content_scanner_entry_state = nil
|
13
31
|
|
14
32
|
until eos?
|
15
|
-
kind = match = nil
|
16
33
|
|
17
34
|
if match = scan(/\n/)
|
35
|
+
deleted_lines = 0 unless line_kind == :delete
|
18
36
|
if line_kind
|
19
|
-
|
37
|
+
encoder.end_line line_kind
|
20
38
|
line_kind = nil
|
21
39
|
end
|
22
|
-
|
40
|
+
encoder.text_token match, :space
|
23
41
|
next
|
24
42
|
end
|
25
43
|
|
@@ -27,81 +45,154 @@ module Scanners
|
|
27
45
|
|
28
46
|
when :initial
|
29
47
|
if match = scan(/--- |\+\+\+ |=+|_+/)
|
30
|
-
|
31
|
-
|
48
|
+
encoder.begin_line line_kind = :head
|
49
|
+
encoder.text_token match, :head
|
50
|
+
if match = scan(/.*?(?=$|[\t\n\x00]| \(revision)/)
|
51
|
+
encoder.text_token match, :filename
|
52
|
+
if options[:highlight_code]
|
53
|
+
file_type = FileType.fetch(match, :text)
|
54
|
+
file_type = :text if file_type == :diff
|
55
|
+
content_scanner = scanners[file_type]
|
56
|
+
content_scanner_entry_state = nil
|
57
|
+
end
|
58
|
+
end
|
32
59
|
next unless match = scan(/.+/)
|
33
|
-
|
60
|
+
encoder.text_token match, :plain
|
34
61
|
elsif match = scan(/Index: |Property changes on: /)
|
35
|
-
|
36
|
-
|
62
|
+
encoder.begin_line line_kind = :head
|
63
|
+
encoder.text_token match, :head
|
37
64
|
next unless match = scan(/.+/)
|
38
|
-
|
65
|
+
encoder.text_token match, :plain
|
39
66
|
elsif match = scan(/Added: /)
|
40
|
-
|
41
|
-
|
67
|
+
encoder.begin_line line_kind = :head
|
68
|
+
encoder.text_token match, :head
|
42
69
|
next unless match = scan(/.+/)
|
43
|
-
|
70
|
+
encoder.text_token match, :plain
|
44
71
|
state = :added
|
45
|
-
elsif match = scan(/\\
|
46
|
-
|
47
|
-
tokens << [match, :change]
|
48
|
-
next unless match = scan(/.+/)
|
49
|
-
kind = :plain
|
72
|
+
elsif match = scan(/\\ .*/)
|
73
|
+
encoder.text_token match, :comment
|
50
74
|
elsif match = scan(/@@(?>[^@\n]*)@@/)
|
75
|
+
content_scanner.state = :initial unless match?(/\n\+/)
|
76
|
+
content_scanner_entry_state = nil
|
51
77
|
if check(/\n|$/)
|
52
|
-
|
78
|
+
encoder.begin_line line_kind = :change
|
53
79
|
else
|
54
|
-
|
80
|
+
encoder.begin_group :change
|
55
81
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
82
|
+
encoder.text_token match[0,2], :change
|
83
|
+
encoder.text_token match[2...-2], :plain
|
84
|
+
encoder.text_token match[-2,2], :change
|
85
|
+
encoder.end_group :change unless line_kind
|
60
86
|
next unless match = scan(/.+/)
|
61
|
-
|
87
|
+
if options[:highlight_code]
|
88
|
+
content_scanner.tokenize match, :tokens => encoder
|
89
|
+
else
|
90
|
+
encoder.text_token match, :plain
|
91
|
+
end
|
92
|
+
next
|
62
93
|
elsif match = scan(/\+/)
|
63
|
-
|
64
|
-
|
94
|
+
encoder.begin_line line_kind = :insert
|
95
|
+
encoder.text_token match, :insert
|
65
96
|
next unless match = scan(/.+/)
|
66
|
-
|
97
|
+
if options[:highlight_code]
|
98
|
+
content_scanner.tokenize match, :tokens => encoder
|
99
|
+
else
|
100
|
+
encoder.text_token match, :plain
|
101
|
+
end
|
102
|
+
next
|
67
103
|
elsif match = scan(/-/)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
104
|
+
deleted_lines += 1
|
105
|
+
encoder.begin_line line_kind = :delete
|
106
|
+
encoder.text_token match, :delete
|
107
|
+
if options[:inline_diff] && deleted_lines == 1 && check(/(?>.*)\n\+(?>.*)$(?!\n\+)/)
|
108
|
+
content_scanner_entry_state = content_scanner.state
|
109
|
+
skip(/(.*)\n\+(.*)$/)
|
110
|
+
head, deletion, insertion, tail = diff self[1], self[2]
|
111
|
+
pre, deleted, post = content_scanner.tokenize [head, deletion, tail], :tokens => Tokens.new
|
112
|
+
encoder.tokens pre
|
113
|
+
unless deleted.empty?
|
114
|
+
encoder.begin_group :eyecatcher
|
115
|
+
encoder.tokens deleted
|
116
|
+
encoder.end_group :eyecatcher
|
117
|
+
end
|
118
|
+
encoder.tokens post
|
119
|
+
encoder.end_line line_kind
|
120
|
+
encoder.text_token "\n", :space
|
121
|
+
encoder.begin_line line_kind = :insert
|
122
|
+
encoder.text_token '+', :insert
|
123
|
+
content_scanner.state = content_scanner_entry_state || :initial
|
124
|
+
pre, inserted, post = content_scanner.tokenize [head, insertion, tail], :tokens => Tokens.new
|
125
|
+
encoder.tokens pre
|
126
|
+
unless inserted.empty?
|
127
|
+
encoder.begin_group :eyecatcher
|
128
|
+
encoder.tokens inserted
|
129
|
+
encoder.end_group :eyecatcher
|
130
|
+
end
|
131
|
+
encoder.tokens post
|
132
|
+
elsif match = scan(/.*/)
|
133
|
+
if options[:highlight_code]
|
134
|
+
if deleted_lines == 1
|
135
|
+
content_scanner_entry_state = content_scanner.state
|
136
|
+
end
|
137
|
+
content_scanner.tokenize match, :tokens => encoder unless match.empty?
|
138
|
+
if !match?(/\n-/)
|
139
|
+
if match?(/\n\+/)
|
140
|
+
content_scanner.state = content_scanner_entry_state || :initial
|
141
|
+
end
|
142
|
+
content_scanner_entry_state = nil
|
143
|
+
end
|
144
|
+
else
|
145
|
+
encoder.text_token match, :plain
|
146
|
+
end
|
147
|
+
end
|
148
|
+
next
|
149
|
+
elsif match = scan(/ .*/)
|
150
|
+
if options[:highlight_code]
|
151
|
+
content_scanner.tokenize match, :tokens => encoder
|
152
|
+
else
|
153
|
+
encoder.text_token match, :plain
|
154
|
+
end
|
155
|
+
next
|
156
|
+
elsif match = scan(/.+/)
|
157
|
+
encoder.begin_line line_kind = :comment
|
158
|
+
encoder.text_token match, :plain
|
77
159
|
else
|
78
160
|
raise_inspect 'else case rached'
|
79
161
|
end
|
80
162
|
|
81
163
|
when :added
|
82
164
|
if match = scan(/ \+/)
|
83
|
-
|
84
|
-
|
165
|
+
encoder.begin_line line_kind = :insert
|
166
|
+
encoder.text_token match, :insert
|
85
167
|
next unless match = scan(/.+/)
|
86
|
-
|
168
|
+
encoder.text_token match, :plain
|
87
169
|
else
|
88
170
|
state = :initial
|
89
171
|
next
|
90
172
|
end
|
91
173
|
end
|
92
174
|
|
93
|
-
match ||= matched
|
94
|
-
if $CODERAY_DEBUG and not kind
|
95
|
-
raise_inspect 'Error token %p in line %d' %
|
96
|
-
[[match, kind], line], tokens
|
97
|
-
end
|
98
|
-
raise_inspect 'Empty token', tokens unless match
|
99
|
-
|
100
|
-
tokens << [match, kind]
|
101
175
|
end
|
102
176
|
|
103
|
-
|
104
|
-
|
177
|
+
encoder.end_line line_kind if line_kind
|
178
|
+
|
179
|
+
encoder
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def diff a, b
|
185
|
+
# i will be the index of the leftmost difference from the left.
|
186
|
+
i_max = [a.size, b.size].min
|
187
|
+
i = 0
|
188
|
+
i += 1 while i < i_max && a[i] == b[i]
|
189
|
+
# j_min will be the index of the leftmost difference from the right.
|
190
|
+
j_min = i - i_max
|
191
|
+
# j will be the index of the rightmost difference from the right which
|
192
|
+
# does not precede the leftmost one from the left.
|
193
|
+
j = -1
|
194
|
+
j -= 1 while j >= j_min && a[j] == b[j]
|
195
|
+
return a[0...i], a[i..j], b[i..j], (j < -1) ? a[j+1..-1] : ''
|
105
196
|
end
|
106
197
|
|
107
198
|
end
|