coderay 0.9.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|