@@ -6,7 +6,7 @@ defmodule EEx.Tokenizer do
6
6
@ type column :: non_neg_integer
7
7
@ type marker :: '=' | '/' | '|' | ''
8
8
@ type token ::
9
- { :text , content }
9
+ { :text , line , column , content }
10
10
| { :expr | :start_expr | :middle_expr | :end_expr , line , column , marker , content }
11
11
| { :eof , line , column }
12
12
@@ -17,7 +17,7 @@ defmodule EEx.Tokenizer do
17
17
18
18
It returns {:ok, list} with the following tokens:
19
19
20
- * `{:text, content}`
20
+ * `{:text, line, column, content}`
21
21
* `{:expr, line, column, marker, content}`
22
22
* `{:start_expr, line, column, marker, content}`
23
23
* `{:middle_expr, line, column, marker, content}`
@@ -36,8 +36,11 @@ defmodule EEx.Tokenizer do
36
36
def tokenize ( list , line , column , opts )
37
37
when is_list ( list ) and is_integer ( line ) and line >= 0 and is_integer ( column ) and column >= 0 do
38
38
column = opts . indentation + column
39
- { list , line , column } = ( opts . trim && trim_init ( list , line , column ) ) || { list , line , column }
40
- tokenize ( list , line , column , opts , [ ] , [ ] )
39
+
40
+ { list , line , column } =
41
+ ( opts . trim && trim_init ( list , line , column , opts ) ) || { list , line , column }
42
+
43
+ tokenize ( list , line , column , opts , [ { line , column } ] , [ ] )
41
44
end
42
45
43
46
defp tokenize ( '<%%' ++ t , line , column , opts , buffer , acc ) do
@@ -53,7 +56,8 @@ defmodule EEx.Tokenizer do
53
56
{ rest , new_line , new_column , buffer } =
54
57
trim_if_needed ( rest , new_line , new_column , opts , buffer )
55
58
56
- tokenize ( rest , new_line , new_column , opts , buffer , acc )
59
+ acc = tokenize_text ( buffer , acc )
60
+ tokenize ( rest , new_line , new_column , opts , [ { new_line , new_column } ] , acc )
57
61
end
58
62
end
59
63
@@ -76,7 +80,7 @@ defmodule EEx.Tokenizer do
76
80
77
81
acc = tokenize_text ( buffer , acc )
78
82
final = { key , line , column , marker , expr }
79
- tokenize ( rest , new_line , new_column , opts , [ ] , [ final | acc ] )
83
+ tokenize ( rest , new_line , new_column , opts , [ { new_line , new_column } ] , [ final | acc ] )
80
84
end
81
85
end
82
86
@@ -164,49 +168,67 @@ defmodule EEx.Tokenizer do
164
168
# Tokenize the buffered text by appending
165
169
# it to the given accumulator.
166
170
167
- defp tokenize_text ( [ ] , acc ) do
171
+ defp tokenize_text ( [ { _line , _column } ] , acc ) do
168
172
acc
169
173
end
170
174
171
175
defp tokenize_text ( buffer , acc ) do
172
- [ { :text , Enum . reverse ( buffer ) } | acc ]
176
+ [ { line , column } | buffer ] = Enum . reverse ( buffer )
177
+ [ { :text , line , column , buffer } | acc ]
173
178
end
174
179
175
180
defp trim_if_needed ( rest , line , column , opts , buffer ) do
176
181
if opts . trim do
177
182
buffer = trim_left ( buffer , 0 )
178
- { rest , line , column } = trim_right ( rest , line , column , 0 )
183
+ { rest , line , column } = trim_right ( rest , line , column , 0 , opts )
179
184
{ rest , line , column , buffer }
180
185
else
181
186
{ rest , line , column , buffer }
182
187
end
183
188
end
184
189
185
- defp trim_init ( [ h | t ] , line , column ) when h in @ spaces , do: trim_init ( t , line , column + 1 )
186
- defp trim_init ( [ ?\r , ?\n | t ] , line , _column ) , do: trim_init ( t , line + 1 , 1 )
187
- defp trim_init ( [ ?\n | t ] , line , _column ) , do: trim_init ( t , line + 1 , 1 )
188
- defp trim_init ( [ ?< , ?% | _ ] = rest , line , column ) , do: { rest , line , column }
189
- defp trim_init ( _ , _ , _ ) , do: false
190
+ defp trim_init ( [ h | t ] , line , column , opts ) when h in @ spaces ,
191
+ do: trim_init ( t , line , column + 1 , opts )
192
+
193
+ defp trim_init ( [ ?\r , ?\n | t ] , line , _column , opts ) ,
194
+ do: trim_init ( t , line + 1 , opts . indentation + 1 , opts )
195
+
196
+ defp trim_init ( [ ?\n | t ] , line , _column , opts ) ,
197
+ do: trim_init ( t , line + 1 , opts . indentation + 1 , opts )
198
+
199
+ defp trim_init ( [ ?< , ?% | _ ] = rest , line , column , _opts ) ,
200
+ do: { rest , line , column }
201
+
202
+ defp trim_init ( _ , _ , _ , _ ) , do: false
190
203
191
204
defp trim_left ( buffer , count ) do
192
- case trim_whitespace ( buffer ) do
193
- [ ?\n , ?\r | rest ] -> trim_left ( rest , count + 1 )
194
- [ ?\n | rest ] -> trim_left ( rest , count + 1 )
205
+ case trim_whitespace ( buffer , 0 ) do
206
+ { [ ?\n , ?\r | rest ] , _ } -> trim_left ( rest , count + 1 )
207
+ { [ ?\n | rest ] , _ } -> trim_left ( rest , count + 1 )
195
208
_ when count > 0 -> [ ?\n | buffer ]
196
209
_ -> buffer
197
210
end
198
211
end
199
212
200
- defp trim_right ( rest , line , column , count ) do
201
- case trim_whitespace ( rest ) do
202
- [ ?\r , ?\n | rest ] -> trim_right ( rest , line + 1 , 1 , count + 1 )
203
- [ ?\n | rest ] -> trim_right ( rest , line + 1 , 1 , count + 1 )
204
- [ ] -> { [ ] , line , column + length ( rest ) }
205
- _ when count > 0 -> { [ ?\n | rest ] , line - 1 , column }
206
- _ -> { rest , line , column }
213
+ defp trim_right ( rest , line , column , last_column , opts ) do
214
+ case trim_whitespace ( rest , column ) do
215
+ { [ ?\r , ?\n | rest ] , column } ->
216
+ trim_right ( rest , line + 1 , opts . indentation + 1 , column + 1 , opts )
217
+
218
+ { [ ?\n | rest ] , column } ->
219
+ trim_right ( rest , line + 1 , opts . indentation + 1 , column , opts )
220
+
221
+ { [ ] , column } ->
222
+ { [ ] , line , column }
223
+
224
+ _ when last_column > 0 ->
225
+ { [ ?\n | rest ] , line - 1 , last_column }
226
+
227
+ _ ->
228
+ { rest , line , column }
207
229
end
208
230
end
209
231
210
- defp trim_whitespace ( [ h | t ] ) when h in @ spaces , do: trim_whitespace ( t )
211
- defp trim_whitespace ( list ) , do: list
232
+ defp trim_whitespace ( [ h | t ] , column ) when h in @ spaces , do: trim_whitespace ( t , column + 1 )
233
+ defp trim_whitespace ( list , column ) , do: { list , column }
212
234
end
0 commit comments