Skip to content

Commit cf38ee2

Browse files
committed
more fixes
1 parent 581c52d commit cf38ee2

File tree

1 file changed

+55
-32
lines changed

1 file changed

+55
-32
lines changed

lib/coderay/scanners/liquid.rb

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ module Scanners
33

44
class Liquid < Scanner
55

6+
require 'csv'
7+
68
register_for :liquid
79

810
DIRECTIVE_KEYWORDS = /endlist|list|endfor|for|endwrap|wrap|endif|if|endunless|unless|elsif|assignlist|assign|cycle|capture|end|capture|fill|endiflist|iflist|else/
@@ -11,20 +13,20 @@ class Liquid < Scanner
1113

1214
DIRECTIVE_PREPOSITIONS= /contains|in|#{MATH}/
1315

14-
FILTER_KEYWORDS = /#{FILTER_WITH_VALUE_KEYWORDS}|textilize|capitalize|downcase|upcase|first|last|sort|map|size|escape_once|escape|strip_html|strip_newlines|newline_to_br/
15-
1616
FILTER_WITH_VALUE_KEYWORDS = /date|replace_first|replace|remove_first|remove_first|remove|minus|times|divided_by|modulo|mod|split|join|truncatewords|truncate|prepend|append/
1717

18-
SELECTOR_KEYWORDS = /in|with|snippet|script|content_item|folder|widget|wrapper|category|asset_folder|asset/
18+
FILTER_KEYWORDS = /#{FILTER_WITH_VALUE_KEYWORDS}|textilize|capitalize|downcase|upcase|first|last|sort|map|size|escape_once|escape|strip_html|strip_newlines|newline_to_br/
1919

20-
DIRECTIVE_KEYS = /#{SELECTOR_KEYWORDS}|tabs|items_per_tab/
20+
SELECTOR_KEYWORDS = /in|with|snippet|script|content_item|folder|widget|wrapper|category|asset_folder|asset/
2121

2222
LIQUID_DIRECTIVE_BLOCK = /
2323
{{1,2}%
2424
(.*?)
2525
%}{1,2}
2626
/x
2727

28+
KEY_VALUE_REGEX = /(\w+)(:)(\w+|".*"|'.*?')/
29+
2830
def setup
2931
@html_scanner = CodeRay.scanner(:html, tokens: @tokens, keep_tokens: true, keep_state: true)
3032
end
@@ -35,43 +37,69 @@ def scan_spaces(encoder)
3537
end
3638
end
3739

38-
def scan_key_value_pair(encoder, options, match)
39-
scan_spaces(encoder)
40-
if match =~ /#{SELECTOR_KEYWORDS}/
41-
encoder.text_token match, :directive
40+
def scan_string(encoder, substring)
41+
if substring and string_array = substring.match(/('|")(.+)('|")/)
42+
delimiter = string_array.captures[0]
43+
contents = string_array.captures[1]
44+
delimiter_2 = string_array.captures[2]
45+
46+
encoder.begin_group :string
47+
encoder.text_token delimiter, :delimiter
48+
encoder.text_token contents, :contents
49+
encoder.text_token delimiter, :delimiter
50+
encoder.end_group :string
51+
52+
true
4253
else
43-
encoder.text_token match, :key
54+
false
4455
end
45-
if delimiter = scan(/:/)
46-
encoder.text_token delimiter, :delimiter
47-
scan_spaces(encoder)
56+
end
57+
58+
def scan_csv_list(encoder, list)
59+
CSV.parse(list) do |row|
60+
column_index = 0
61+
row.each do |value|
62+
column_index += 1
63+
unless scan_string(encoder, value)
64+
encoder.text_token value, :value
65+
end
66+
unless column_index >= row.length
67+
encoder.text_token ',', :delimiter
68+
end
69+
end
4870
end
49-
if value = scan(/\w+/)
50-
encoder.text_token value, :value
51-
elsif value = scan(/('\S+')|("\w+")/)
52-
encoder.text_token value, :string
71+
end
72+
73+
def scan_key_value_pair(encoder, options, match)
74+
scan_spaces(encoder)
75+
if match = check(/#{KEY_VALUE_REGEX}/)
76+
key = scan(/\w+/)
77+
delimiter, values = scan(/(:)(\S+)|(".*?")|('.*?')/).match(/(:)(\S+)|(".*?")|('.*?')/).captures
78+
79+
if key =~ /#{SELECTOR_KEYWORDS}/
80+
encoder.text_token key, :directive
81+
else
82+
encoder.text_token key, :key
83+
end
84+
85+
encoder.text_token delimiter, :delimiter
86+
scan_csv_list(encoder, values)
87+
true
88+
else
89+
false
5390
end
5491
end
5592

5693
def scan_selector(encoder, options, match)
5794
scan_spaces(encoder)
58-
Rails.logger.debug 'DEBUG: Looking for a selector'
59-
if match = scan(/#{DIRECTIVE_KEYS}/)
60-
if peek(1) == ':'
61-
Rails.logger.debug "DEBUG: Peek: #{peek(5)}"
62-
Rails.logger.debug 'DEBUG: Selector keyword found'
63-
scan_key_value_pair(encoder, options, match)
64-
else
65-
encoder.text_token match, :variable
66-
end
95+
if scan_key_value_pair(encoder, options, match)
6796
scan_selector(encoder, options, match)
6897
else
6998
false
7099
end
71100
end
72101

73102
def scan_directive(encoder, options, match)
74-
Rails.logger.debug 'DEBUG: Scanning directive'
75103
encoder.text_token match, :tag
76104
state = :liquid
77105
scan_spaces(encoder)
@@ -106,9 +134,7 @@ def scan_directive(encoder, options, match)
106134
def scan_output_filters(encoder, options, match)
107135
encoder.text_token match, :operator
108136
scan_spaces(encoder)
109-
if match = scan(/#{FILTER_WITH_VALUE_KEYWORDS}/)
110-
scan_key_value_pair(encoder, options, match)
111-
elsif directive = scan(/#{FILTER_KEYWORDS}/)
137+
if !scan_key_value_pair(encoder, options, match) and directive = scan(/#{FILTER_KEYWORDS}/)
112138
encoder.text_token directive, :directive
113139
end
114140
if next_filter = scan(/\s\|\s/)
@@ -117,7 +143,6 @@ def scan_output_filters(encoder, options, match)
117143
end
118144

119145
def scan_output(encoder, options, match)
120-
Rails.logger.debug 'DEBUG: Scanning output'
121146
encoder.text_token match, :tag
122147
state = :liquid
123148
scan_spaces(encoder)
@@ -135,12 +160,10 @@ def scan_output(encoder, options, match)
135160
end
136161

137162
def scan_tokens(encoder, options)
138-
Rails.logger.debug "DEBUG: Scan started: #{self.string}"
139163
state = :initial
140164

141165
until eos?
142166
if (match = scan_until(/(?=({{2,3}|{{1,2}%))/) || scan_rest) and not match.empty? and state != :liquid
143-
Rails.logger.debug "DEBUG: HTML scanning: #{match}"
144167
@html_scanner.tokenize(match, tokens: encoder)
145168
state = :initial
146169
scan_spaces(encoder)

0 commit comments

Comments
 (0)