@@ -123,6 +123,40 @@ def visit_silent_script(node)
123123
124124 LiteralHashValue = Struct . new ( :value )
125125
126+ # When formatting a tag, there are a lot of different kinds of things that
127+ # can be printed out. There's the tag name, the attributes, the content,
128+ # etc. This object is responsible for housing all of those parts.
129+ class PartList
130+ attr_reader :node , :parts
131+
132+ def initialize ( node )
133+ @node = node
134+ @parts = [ ]
135+ end
136+
137+ def <<( part )
138+ parts << part
139+ end
140+
141+ def empty?
142+ parts . empty?
143+ end
144+
145+ def format ( q )
146+ if empty? && node . value [ :name ] == "div"
147+ # If we don't have any other parts to print and the tag is a div
148+ # then we need to make sure to add that to the beginning. Otherwise
149+ # it's implied by the presence of other operators.
150+ q . text ( "%div" )
151+ else
152+ parts . inject ( 0 ) do |align , part |
153+ part . format ( q , align )
154+ align + part . length
155+ end
156+ end
157+ end
158+ end
159+
126160 class PlainPart < Struct . new ( :value )
127161 def format ( q , align )
128162 q . text ( value )
@@ -227,7 +261,7 @@ def self.hash_value(value)
227261
228262 # Visit a tag node.
229263 def visit_tag ( node )
230- parts = [ ]
264+ parts = PartList . new ( node )
231265
232266 # If we have a tag that isn't a div, then we need to print out that
233267 # name of that tag first. If it is a div, first we'll check if there
@@ -266,6 +300,7 @@ def visit_tag(node)
266300 node . value [ :attributes ] . reject do |key , _ |
267301 key == "class" || key == "id"
268302 end
303+
269304 parts << HashAttributesPart . new ( static ) if static . any?
270305
271306 # If there are dynamic attributes that don't use the newer syntax, then
@@ -300,55 +335,32 @@ def visit_tag(node)
300335
301336 # If there is a value part, then we're going to print slightly
302337 # differently as the value goes after the tag declaration.
303- if node . value [ :value ]
304- return (
305- with_children ( node ) do
306- q . group do
307- align = 0
308-
309- parts . each do |part |
310- part . format ( q , align )
311- align += part . length
312- end
313- end
314-
315- q . indent do
316- # Split between the declaration of the tag and the contents of the
317- # tag.
318- q . breakable ( "" )
319-
320- if node . value [ :parse ] && node . value [ :value ] . match? ( /#[{$@]/ )
321- # There's a weird case here where if the value includes
322- # interpolation and it's marked as { parse: true }, then we
323- # don't actually want the = prefix, and we want to remove extra
324- # escaping.
325- q . if_break { q . text ( "" ) } . if_flat { q . text ( " " ) }
326- q . text ( node . value [ :value ] [ 1 ...-1 ] . gsub ( /\\ "/ , "\" " ) )
327- elsif node . value [ :parse ]
328- q . text ( "= " )
329- q . text ( node . value [ :value ] )
330- else
331- q . if_break { q . text ( "" ) } . if_flat { q . text ( " " ) }
332- q . text ( node . value [ :value ] )
333- end
338+ if ( value = node . value [ :value ] ) && !value . empty?
339+ with_children ( node ) do
340+ q . group { parts . format ( q ) }
341+ q . indent do
342+ # Split between the declaration of the tag and the contents of the
343+ # tag.
344+ q . breakable ( "" )
345+
346+ if node . value [ :parse ] && value . match? ( /#[{$@]/ )
347+ # There's a weird case here where if the value includes
348+ # interpolation and it's marked as { parse: true }, then we
349+ # don't actually want the = prefix, and we want to remove extra
350+ # escaping.
351+ q . if_break { q . text ( "" ) } . if_flat { q . text ( " " ) }
352+ q . text ( value [ 1 ...-1 ] . gsub ( /\\ "/ , "\" " ) )
353+ elsif node . value [ :parse ]
354+ q . text ( "= " )
355+ q . text ( value )
356+ else
357+ q . if_break { q . text ( "" ) } . if_flat { q . text ( " " ) }
358+ q . text ( value )
334359 end
335360 end
336- )
337- end
338-
339- # In case none of the other if statements have matched and we're
340- # printing a div, we need to explicitly add it back into the array.
341- if parts . empty? && node . value [ :name ] == "div"
342- parts << PlainPart . new ( "%div" )
343- end
344-
345- with_children ( node ) do
346- align = 0
347-
348- parts . each do |part |
349- part . format ( q , align )
350- align += part . length
351361 end
362+ else
363+ with_children ( node ) { parts . format ( q ) }
352364 end
353365 end
354366
0 commit comments