mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Merged text now possible. To make blocks of multiline text work, push_silent now takes a tag when it is being
used as a one liner, allowing it to close itself so push_text can stop worrying about potential one liner pending situation. Same goes for opening non pre-rendered tags which can now close their own content after determining one liner status. Extra complexity there pays off in multi line plain text now being easy to dump. Sequential push_texts are now merged into single multi line calls, next step is merging pre-rendered open tags and close tags. git-svn-id: svn://hamptoncatlin.com/haml/trunk@553 7063305b-7217-0410-af8c-cdc13e5119b9
This commit is contained in:
parent
c1d5fb52e3
commit
ab1dffda9e
3 changed files with 82 additions and 23 deletions
|
@ -42,7 +42,7 @@ module Haml
|
|||
|
||||
# Renders +text+ with the proper tabulation. This also deals with
|
||||
# making a possible one-line tag one line or not.
|
||||
def push_text(text, tabulation)
|
||||
def push_text(text, tab_change = 0)
|
||||
if @one_liner_pending && Buffer.one_liner?(text)
|
||||
@buffer << text
|
||||
else
|
||||
|
@ -50,13 +50,18 @@ module Haml
|
|||
@buffer << "\n"
|
||||
@one_liner_pending = false
|
||||
end
|
||||
@buffer << "#{tabs(tabulation)}#{text}\n"
|
||||
if(@tabulation > 0)
|
||||
text.gsub!(/^/m, ' ')
|
||||
end
|
||||
|
||||
@buffer << "#{text}"
|
||||
end
|
||||
@real_tabs += tab_change
|
||||
end
|
||||
|
||||
# Properly formats the output of a script that was run in the
|
||||
# instance_eval.
|
||||
def push_script(result, tabulation, flattened)
|
||||
def push_script(result, tabulation, flattened, close_tag = nil)
|
||||
if flattened
|
||||
result = Haml::Helpers.find_and_preserve(result)
|
||||
end
|
||||
|
@ -67,8 +72,25 @@ module Haml
|
|||
result = result[0...-1]
|
||||
end
|
||||
|
||||
result = result.gsub("\n", "\n#{tabs(tabulation)}")
|
||||
push_text result, tabulation
|
||||
if @one_liner_pending && Buffer.one_liner?(result)
|
||||
@buffer << result
|
||||
@buffer << "</#{close_tag}>\n"
|
||||
@one_liner_pending = false
|
||||
@real_tabs -= 1
|
||||
else
|
||||
if @one_liner_pending
|
||||
@buffer << "\n"
|
||||
tabulation += 1
|
||||
end
|
||||
|
||||
result = result.gsub("\n", "\n#{tabs(tabulation)}")
|
||||
@buffer << "#{tabs(tabulation)}#{result}\n"
|
||||
|
||||
if @one_liner_pending
|
||||
@one_liner_pending = false
|
||||
@buffer << "#{tabs(tabulation-1)}</#{close_tag}>\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
@ -81,7 +103,7 @@ module Haml
|
|||
|
||||
# Takes the various information about the opening tag for an
|
||||
# element, formats it, and adds it to the buffer.
|
||||
def open_tag(name, tabulation, atomic, try_one_line, class_id, obj_ref, attributes_hash)
|
||||
def open_tag(name, tabulation, atomic, try_one_line, class_id, obj_ref, content, attributes_hash)
|
||||
attributes = class_id
|
||||
if attributes_hash
|
||||
attributes_hash.keys.each { |key| attributes_hash[key.to_s] = attributes_hash.delete(key) }
|
||||
|
@ -99,7 +121,16 @@ module Haml
|
|||
str = ">\n"
|
||||
end
|
||||
@buffer << "#{tabs(tabulation)}<#{name}#{build_attributes(attributes)}#{str}"
|
||||
@real_tabs += 1
|
||||
if content
|
||||
if Buffer.one_liner?(content)
|
||||
@buffer << "#{content}</#{name}>\n"
|
||||
else
|
||||
@buffer << "\n#{tabs(@real_tabs+1)}#{content}\n#{tabs(@real_tabs)}</#{name}>\n"
|
||||
end
|
||||
@one_liner_pending = false
|
||||
else
|
||||
@real_tabs += 1
|
||||
end
|
||||
end
|
||||
|
||||
def self.merge_attrs(to, from)
|
||||
|
@ -117,11 +148,12 @@ module Haml
|
|||
|
||||
# Creates a closing tag with the given name.
|
||||
def close_tag(name, tabulation)
|
||||
@real_tabs = tabulation
|
||||
if @one_liner_pending
|
||||
@buffer << "</#{name}>\n"
|
||||
@one_liner_pending = false
|
||||
else
|
||||
push_text("</#{name}>", tabulation)
|
||||
push_text("#{' ' * tabulation}</#{name}>\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -159,7 +191,6 @@ module Haml
|
|||
@@tab_cache = {}
|
||||
# Gets <tt>count</tt> tabs. Mostly for internal use.
|
||||
def tabs(count)
|
||||
@real_tabs = count
|
||||
tabs = count + @tabulation
|
||||
' ' * tabs
|
||||
@@tab_cache[tabs] ||= ' ' * tabs
|
||||
|
|
|
@ -467,6 +467,8 @@ END
|
|||
# Evaluates <tt>text</tt> in the context of <tt>@scope_object</tt>, but
|
||||
# does not output the result.
|
||||
def push_silent(text, add_index = false, can_suppress = false)
|
||||
flush_merged_text
|
||||
|
||||
unless (can_suppress && options[:suppress_eval])
|
||||
if add_index
|
||||
@precompiled << "@haml_lineno = #{@index}\n#{text}\n"
|
||||
|
@ -479,9 +481,22 @@ END
|
|||
|
||||
# Adds <tt>text</tt> to <tt>@buffer</tt> with appropriate tabulation
|
||||
# without parsing it.
|
||||
def push_text(text)
|
||||
@precompiled << "_hamlout.push_text(#{text.dump}, #{@output_tabs})\n"
|
||||
def push_text(text, tab_change = 0)
|
||||
@merged_text ||= ''
|
||||
@merged_text << "#{' ' * @output_tabs}#{text}\n"
|
||||
@tab_change ||= 0
|
||||
@tab_change += tab_change
|
||||
end
|
||||
|
||||
def flush_merged_text
|
||||
if @merged_text && !@merged_text.empty?
|
||||
args = @merged_text.dump
|
||||
args += ", #{@tab_change}" if @tab_change != 0
|
||||
@precompiled << "_hamlout.push_text(#{args})\n"
|
||||
@merged_text = nil
|
||||
@tab_change = 0
|
||||
end
|
||||
end
|
||||
|
||||
# Renders a block of text as plain text.
|
||||
# Also checks for an illegally opened block.
|
||||
|
@ -504,10 +519,12 @@ END
|
|||
#
|
||||
# If <tt>flattened</tt> is true, Haml::Helpers#find_and_flatten is run on
|
||||
# the result before it is added to <tt>@buffer</tt>
|
||||
def push_script(text, flattened)
|
||||
def push_script(text, flattened, close_tag = nil)
|
||||
flush_merged_text
|
||||
|
||||
unless options[:suppress_eval]
|
||||
push_silent("haml_temp = #{text}", true)
|
||||
out = "haml_temp = _hamlout.push_script(haml_temp, #{@output_tabs}, #{flattened})\n"
|
||||
out = "haml_temp = _hamlout.push_script(haml_temp, #{@output_tabs}, #{flattened}, #{close_tag.inspect})\n"
|
||||
if @block_opened
|
||||
push_and_tabulate([:loud, out])
|
||||
else
|
||||
|
@ -519,6 +536,8 @@ END
|
|||
# Causes <tt>text</tt> to be evaluated, and Haml::Helpers#find_and_flatten
|
||||
# to be run on it afterwards.
|
||||
def push_flat_script(text)
|
||||
flush_merged_text
|
||||
|
||||
if text.empty?
|
||||
raise SyntaxError.new("Tag has no content.")
|
||||
else
|
||||
|
@ -555,6 +574,8 @@ END
|
|||
# Puts a line in <tt>@precompiled</tt> that will add the closing tag of
|
||||
# the most recently opened tag.
|
||||
def close_tag(tag)
|
||||
flush_merged_text
|
||||
|
||||
@output_tabs -= 1
|
||||
@template_tabs -= 1
|
||||
@precompiled << "_hamlout.close_tag(#{tag.dump}, #{@output_tabs})\n"
|
||||
|
@ -571,7 +592,7 @@ END
|
|||
@output_tabs -= 1
|
||||
@template_tabs -= 1
|
||||
close_tag = has_conditional ? "<![endif]-->" : "-->"
|
||||
push_text(close_tag)
|
||||
push_text(close_tag, -1)
|
||||
end
|
||||
|
||||
# Closes a loud Ruby block.
|
||||
|
@ -699,6 +720,8 @@ END
|
|||
# Parses a line that will render as an XHTML tag, and adds the code that will
|
||||
# render that tag to <tt>@precompiled</tt>.
|
||||
def render_tag(line)
|
||||
flush_merged_text
|
||||
|
||||
matched = false
|
||||
line.scan(TAG_REGEX) do |tag_name, attributes, attributes_hash, object_ref, action, value|
|
||||
matched = true
|
||||
|
@ -718,6 +741,11 @@ END
|
|||
flattened = (action == '~')
|
||||
|
||||
value_exists = !value.empty?
|
||||
if value_exists && parse && @options[:suppress_eval]
|
||||
parse = false
|
||||
value = ''
|
||||
end
|
||||
|
||||
literal_attributes = parse_literal_hash(attributes_hash)
|
||||
attributes_hash = "{nil}" if attributes_hash.nil? || literal_attributes || @options[:suppress_eval]
|
||||
object_ref = "nil" if object_ref.nil? || @options[:suppress_eval]
|
||||
|
@ -761,20 +789,20 @@ END
|
|||
push_silent "_hamlout.open_prerendered_tag(#{open_tag.dump}, #{@output_tabs}, #{parse.inspect}, #{tag_closed.inspect})"
|
||||
return if tag_closed
|
||||
else
|
||||
push_silent "_hamlout.open_tag(#{tag_name.inspect}, #{@output_tabs}, #{atomic.inspect}, #{value_exists.inspect}, #{attributes.inspect}, #{object_ref}, #{attributes_hash[1...-1]})", true
|
||||
content = !value_exists || parse ? 'nil' : value.dump
|
||||
push_silent "_hamlout.open_tag(#{tag_name.inspect}, #{@output_tabs}, #{atomic.inspect}, #{value_exists.inspect}, #{attributes.inspect}, #{object_ref}, #{content}, #{attributes_hash[1...-1]})", true
|
||||
end
|
||||
|
||||
unless atomic
|
||||
push_and_tabulate([:element, tag_name])
|
||||
@output_tabs += 1
|
||||
unless value_exists
|
||||
push_and_tabulate([:element, tag_name])
|
||||
@output_tabs += 1
|
||||
end
|
||||
|
||||
if value_exists
|
||||
if parse
|
||||
push_script(value, flattened)
|
||||
else
|
||||
push_text(value)
|
||||
push_script(value, flattened, tag_name)
|
||||
end
|
||||
close
|
||||
elsif flattened
|
||||
raise SyntaxError.new("Tag has no content.")
|
||||
end
|
||||
|
@ -807,7 +835,7 @@ END
|
|||
close_tag = conditional ? "<![endif]-->" : "-->"
|
||||
push_text("#{text_out}#{content} #{close_tag}")
|
||||
else
|
||||
push_text(text_out)
|
||||
push_text(text_out, 1)
|
||||
@output_tabs += 1
|
||||
push_and_tabulate([:comment, !conditional.nil?])
|
||||
if !content.empty?
|
||||
|
|
|
@ -101,7 +101,7 @@ class EngineTest < Test::Unit::TestCase
|
|||
|
||||
# Make sure the method called will return junk unless recompiled
|
||||
method_name = Haml::Engine.send(:class_variable_get, '@@method_names')[template]
|
||||
Haml::Engine::CompiledTemplates.module_eval "def #{method_name}(stuff); @haml_stack[-1].push_text 'NOT RECOMPILED', 0; end"
|
||||
Haml::Engine::CompiledTemplates.module_eval "def #{method_name}(stuff); @haml_stack[-1].push_text(\"NOT RECOMPILED\n\"); end"
|
||||
|
||||
assert_equal("NOT RECOMPILED\n", render(template, :locals => { :text => "first time" }))
|
||||
assert_equal("<p>first time</p>\n", render(template, :locals => { :text => "first time", :foo => 'bar' }))
|
||||
|
|
Loading…
Add table
Reference in a new issue