From eb4ebcbbe80c5382a5a983685346dfabb54bbe4c Mon Sep 17 00:00:00 2001 From: minad Date: Mon, 1 Nov 2010 01:17:39 +0100 Subject: [PATCH] Temple::HTML::Pretty --- lib/temple.rb | 1 + lib/temple/filters/escape_html.rb | 28 +++++++++---- lib/temple/html/fast.rb | 9 ++-- lib/temple/html/pretty.rb | 68 +++++++++++++++++++++++++++++++ lib/temple/mixins.rb | 18 ++++---- 5 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 lib/temple/html/pretty.rb diff --git a/lib/temple.rb b/lib/temple.rb index c5a50e4..3c9e8e8 100644 --- a/lib/temple.rb +++ b/lib/temple.rb @@ -26,5 +26,6 @@ module Filters module HTML autoload :Fast, 'temple/html/fast' + autoload :Pretty, 'temple/html/pretty' end end diff --git a/lib/temple/filters/escape_html.rb b/lib/temple/filters/escape_html.rb index 84822e4..f213229 100644 --- a/lib/temple/filters/escape_html.rb +++ b/lib/temple/filters/escape_html.rb @@ -1,14 +1,26 @@ module Temple module Filters class EscapeHTML < Filter - def on_escape(type, value) - case type - when :static - value = options[:user_html_safe] ? escape_html_safe(value) : escape_html(value) - when :dynamic - value = "Temple::Utils.escape_html#{options[:use_html_safe] ? '_safe' : ''}((#{value}))" - end - [type, value] + temple_dispatch :escape, :html + + def on_escape_static(value) + [:static, options[:user_html_safe] ? escape_html_safe(value) : escape_html(value)] + end + + def on_escape_dynamic(value) + [:dynamic, "Temple::Utils.escape_html#{options[:use_html_safe] ? '_safe' : ''}((#{value}))"] + end + + def on_html_staticattrs(*attrs) + [:html, :staticattrs, *attrs.map {|k,v| [k, compile!(v)] }] + end + + def on_html_comment(content) + [:html, :comment, compile!(content)] + end + + def on_html_tag(name, attrs, closed, content) + [:html, :tag, name, compile!(attrs), closed, compile!(content)] end end end diff --git a/lib/temple/html/fast.rb b/lib/temple/html/fast.rb index e630dc1..6791c07 100644 --- a/lib/temple/html/fast.rb +++ b/lib/temple/html/fast.rb @@ -72,17 +72,17 @@ def on_html_doctype(type) def on_html_comment(content) [:multi, - [:static, ""]] + [:static, '-->']] end def on_html_tag(name, attrs, closed, content) closed ||= options[:autoclose].include?(name) raise "Closed tag #{name} has content" if closed && !empty_exp?(content) result = [:multi, [:static, "<#{name}"], compile!(attrs)] - result << [:static, " /"] if closed && xhtml? - result << [:static, ">"] << compile!(content) + result << [:static, ' /'] if closed && xhtml? + result << [:static, '>'] << compile!(content) result << [:static, ""] if !closed result end @@ -113,4 +113,3 @@ def on_html_staticattrs(*attrs) end end end - diff --git a/lib/temple/html/pretty.rb b/lib/temple/html/pretty.rb new file mode 100644 index 0000000..ff925bd --- /dev/null +++ b/lib/temple/html/pretty.rb @@ -0,0 +1,68 @@ +module Temple + module HTML + class Pretty < Fast + set_default_options :indent => ' ', + :pretty => true + + INDENT_TAGS = %w(base div form head html img input li link meta ol + script style table tbody td th thead title tr ul).freeze + + def initialize(opts = {}) + super + @last = nil + @stack = [] + end + + def on_static(content) + if options[:pretty] + @last = nil + [:static, content.gsub("\n", indent)] + else + [:static, content] + end + end + + def on_dynamic(content) + if options[:pretty] + @last = nil + [:dynamic, %{(#{content}).to_s.gsub("\n", #{indent.inspect})}] + else + [:dynamic, content] + end + end + + def on_html_comment(content) + return super if !options[:pretty] + [:multi, [:static, indent], super] + end + + def on_html_tag(name, attrs, closed, content) + return super if !options[:pretty] + + closed ||= options[:autoclose].include?(name) + raise "Closed tag #{name} has content" if closed && !empty_exp?(content) + + result = [:multi, [:static, "#{tag_indent(name)}<#{name}"], compile!(attrs)] + result << [:static, ' /'] if closed && xhtml? + result << [:static, '>'] + + @stack << name + @last = name + result << compile!(content) + @stack.pop + + result << [:static, "#{tag_indent(name)}"] if !closed + @last = name + result + end + + def indent + @stack.include?('pre') ? '' : ("\n" + ((options[:indent] || '') * @stack.size)) + end + + def tag_indent(name) + @last && (INDENT_TAGS.include?(@last) || INDENT_TAGS.include?(name)) ? indent : '' + end + end + end +end diff --git a/lib/temple/mixins.rb b/lib/temple/mixins.rb index 5b99e41..1e460f2 100644 --- a/lib/temple/mixins.rb +++ b/lib/temple/mixins.rb @@ -27,14 +27,16 @@ def on_capture(name, exp) end module ClassMethods - def temple_dispatch(base) - class_eval %{def on_#{base}(type, *args) - if respond_to?("on_" #{base.to_s.inspect} "_\#{type}") - send("on_" #{base.to_s.inspect} "_\#{type}", *args) - else - [:#{base}, type, *args] - end - end} + def temple_dispatch(*bases) + bases.each do |base| + class_eval %{def on_#{base}(type, *args) + if respond_to?("on_" #{base.to_s.inspect} "_\#{type}") + send("on_" #{base.to_s.inspect} "_\#{type}", *args) + else + [:#{base}, type, *args] + end + end} + end end end end