@@ -79,15 +79,15 @@ defmodule EEx.Compiler do
7979 { :error , message <> code_snippet ( state . source , state . indentation , meta ) , meta }
8080
8181 { :ok , expr , new_line , new_column , rest } ->
82- { key , expr } =
82+ { key , expr , extra_meta } =
8383 case :elixir_tokenizer . tokenize ( expr , 1 , file: "eex" , check_terminators: false ) do
8484 { :ok , _line , _column , _warnings , rev_tokens , [ ] } ->
8585 # We ignore warnings because the code will be tokenized
8686 # again later with the right line+column info
8787 token_key ( rev_tokens , expr )
8888
8989 { :error , _ , _ , _ , _ } ->
90- { :expr , expr }
90+ { :expr , expr , % { } }
9191 end
9292
9393 marker =
@@ -102,8 +102,8 @@ defmodule EEx.Compiler do
102102 marker
103103 end
104104
105- token = { key , marker , expr , % { line: line , column: column } }
106- trim_and_tokenize ( rest , new_line , new_column , state , buffer , acc , & [ token | & 1 ] )
105+ token = { key , marker , expr , Map . merge ( % { line: line , column: column } , extra_meta ) }
106+ trim_and_tokenize ( rest , new_line , new_column , state , buffer , acc , & merge_token ( token , & 1 ) )
107107 end
108108 end
109109
@@ -127,6 +127,27 @@ defmodule EEx.Compiler do
127127 tokenize ( rest , line , column , state , [ { line , column } ] , fun . ( acc ) )
128128 end
129129
130+ # Merge middle expressions separated only by whitespace so the whitespace is
131+ # part of the Elixir expression, not a separate EEx body.
132+ defp merge_token (
133+ { :middle_expr , ~c" " , chars , meta } ,
134+ [ { :text , text , text_meta } , { :middle_expr , ~c" " , prev_chars , prev_meta } | acc ]
135+ ) do
136+ if only_spaces? ( text ) and clause_block_identifier? ( prev_meta ) do
137+ [ { :middle_expr , ~c" " , prev_chars ++ text ++ chars , prev_meta } | acc ]
138+ else
139+ [
140+ { :middle_expr , ~c" " , chars , meta } ,
141+ { :text , text , text_meta } ,
142+ { :middle_expr , ~c" " , prev_chars , prev_meta } | acc
143+ ]
144+ end
145+ end
146+
147+ defp merge_token ( token , acc ) do
148+ [ token | acc ]
149+ end
150+
130151 # Retrieve marker for <%
131152
132153 defp retrieve_marker ( [ marker | t ] ) when marker in [ ?= , ?/ , ?| ] do
@@ -177,31 +198,31 @@ defmodule EEx.Compiler do
177198 defp token_key ( rev_tokens , expr ) do
178199 case { Enum . reverse ( rev_tokens ) , drop_eol ( rev_tokens ) } do
179200 { [ { :end , _ } | _ ] , [ { :do , _ } | _ ] } ->
180- { :middle_expr , expr }
201+ { :middle_expr , expr , % { } }
181202
182203 { _ , [ { :do , _ } | _ ] } ->
183- { :start_expr , maybe_append_space ( expr ) }
204+ { :start_expr , maybe_append_space ( expr ) , % { } }
184205
185- { _ , [ { :block_identifier , _ , _ } | _ ] } ->
186- { :middle_expr , maybe_append_space ( expr ) }
206+ { _ , [ { :block_identifier , _ , identifier } | _ ] } ->
207+ { :middle_expr , maybe_append_space ( expr ) , % { block_identifier: identifier } }
187208
188209 { [ { :end , _ } | _ ] , [ { :stab_op , _ , _ } | _ ] } ->
189- { :middle_expr , expr }
210+ { :middle_expr , expr , % { } }
190211
191212 { _ , [ { :stab_op , _ , _ } | reverse_tokens ] } ->
192213 fn_index = Enum . find_index ( reverse_tokens , & match? ( { :fn , _ } , & 1 ) ) || :infinity
193214 end_index = Enum . find_index ( reverse_tokens , & match? ( { :end , _ } , & 1 ) ) || :infinity
194215
195216 if end_index > fn_index do
196- { :start_expr , expr }
217+ { :start_expr , expr , % { } }
197218 else
198- { :middle_expr , expr }
219+ { :middle_expr , expr , % { } }
199220 end
200221
201222 { tokens , _ } ->
202223 case Enum . drop_while ( tokens , & closing_bracket? / 1 ) do
203- [ { :end , _ } | _ ] -> { :end_expr , expr }
204- _ -> { :expr , expr }
224+ [ { :end , _ } | _ ] -> { :end_expr , expr , % { } }
225+ _ -> { :expr , expr , % { } }
205226 end
206227 end
207228 end
@@ -476,6 +497,12 @@ defmodule EEx.Compiler do
476497 Enum . all? ( chars , & ( & 1 in @ all_spaces ) )
477498 end
478499
500+ defp clause_block_identifier? ( % { block_identifier: identifier } ) do
501+ identifier in [ :else , :rescue , :catch ]
502+ end
503+
504+ defp clause_block_identifier? ( _meta ) , do: false
505+
479506 # Changes placeholder to real expression
480507
481508 defp insert_quoted ( { :__EEX__ , _ , [ key ] } , quoted ) do
0 commit comments