@@ -6,7 +6,7 @@ defmodule EEx.Tokenizer do
66 @ type column :: non_neg_integer
77 @ type marker :: '=' | '/' | '|' | ''
88 @ type token ::
9- { :text , content }
9+ { :text , line , column , content }
1010 | { :expr | :start_expr | :middle_expr | :end_expr , line , column , marker , content }
1111 | { :eof , line , column }
1212
@@ -17,7 +17,7 @@ defmodule EEx.Tokenizer do
1717
1818 It returns {:ok, list} with the following tokens:
1919
20- * `{:text, content}`
20+ * `{:text, line, column, content}`
2121 * `{:expr, line, column, marker, content}`
2222 * `{:start_expr, line, column, marker, content}`
2323 * `{:middle_expr, line, column, marker, content}`
@@ -36,8 +36,11 @@ defmodule EEx.Tokenizer do
3636 def tokenize ( list , line , column , opts )
3737 when is_list ( list ) and is_integer ( line ) and line >= 0 and is_integer ( column ) and column >= 0 do
3838 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 } ] , [ ] )
4144 end
4245
4346 defp tokenize ( '<%%' ++ t , line , column , opts , buffer , acc ) do
@@ -53,7 +56,8 @@ defmodule EEx.Tokenizer do
5356 { rest , new_line , new_column , buffer } =
5457 trim_if_needed ( rest , new_line , new_column , opts , buffer )
5558
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 )
5761 end
5862 end
5963
@@ -76,7 +80,7 @@ defmodule EEx.Tokenizer do
7680
7781 acc = tokenize_text ( buffer , acc )
7882 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 ] )
8084 end
8185 end
8286
@@ -164,49 +168,67 @@ defmodule EEx.Tokenizer do
164168 # Tokenize the buffered text by appending
165169 # it to the given accumulator.
166170
167- defp tokenize_text ( [ ] , acc ) do
171+ defp tokenize_text ( [ { _line , _column } ] , acc ) do
168172 acc
169173 end
170174
171175 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 ]
173178 end
174179
175180 defp trim_if_needed ( rest , line , column , opts , buffer ) do
176181 if opts . trim do
177182 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 )
179184 { rest , line , column , buffer }
180185 else
181186 { rest , line , column , buffer }
182187 end
183188 end
184189
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
190203
191204 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 )
195208 _ when count > 0 -> [ ?\n | buffer ]
196209 _ -> buffer
197210 end
198211 end
199212
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 }
207229 end
208230 end
209231
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 }
212234end
0 commit comments