1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Refactor filters

This commit is contained in:
Takashi Kokubun 2015-03-29 03:15:46 +09:00
parent 172bb2bfc6
commit 321758e62c
8 changed files with 152 additions and 126 deletions

View file

@ -2,6 +2,7 @@ require 'hamlit/concerns/included'
require 'hamlit/concerns/registerable' require 'hamlit/concerns/registerable'
require 'hamlit/filters/css' require 'hamlit/filters/css'
require 'hamlit/filters/escaped' require 'hamlit/filters/escaped'
require 'hamlit/filters/javascript'
require 'hamlit/filters/plain' require 'hamlit/filters/plain'
require 'hamlit/filters/preserve' require 'hamlit/filters/preserve'
@ -15,6 +16,7 @@ module Hamlit
register :css, Filters::Css register :css, Filters::Css
register :escaped, Filters::Escaped register :escaped, Filters::Escaped
register :javascript, Filters::Javascript
register :plain, Filters::Plain register :plain, Filters::Plain
register :preserve, Filters::Preserve register :preserve, Filters::Preserve
end end

View file

@ -31,16 +31,20 @@ module Hamlit
def read_lines def read_lines
lines = [] lines = []
spaces = ' ' * (@current_indent * 2)
while read_line? while read_line?
lines << @lines[@current_lineno + 1].gsub(/\A#{spaces}/, '') lines << @lines[@current_lineno + 1]
@current_lineno += 1 @current_lineno += 1
end end
lines trim_lines(lines)
end end
private private
def trim_lines(lines)
size = (lines.first || '').index(/[^\s]/) || 0
lines.map { |line| line.gsub(/\A {#{size}}/, '') }
end
def read_line? def read_line?
return true if count_indent(next_line, strict: false) >= @current_indent return true if count_indent(next_line, strict: false) >= @current_indent

View file

@ -0,0 +1,33 @@
module Hamlit
module Filters
class Base
def compile(lines)
raise NotImplementedError
end
private
def compile_lines(lines, indent_width: 0)
base = (lines.first || '').index(/[^\s]/) || 0
width = indent_width - base
width = 0 if width < 0
lines = strip_last(lines).map do |line|
' ' * width + line
end
text = lines.join("\n") + "\n"
text
end
# NOTE: empty line is reserved for preserve filter.
def strip_last(lines)
lines = lines.dup
while lines.last && lines.last.length == 0
lines.delete_at(-1)
end
lines
end
end
end
end

View file

@ -1,31 +1,14 @@
require 'hamlit/filters/base'
module Hamlit module Hamlit
module Filters module Filters
class Css class Css < Base
def compile(lines) def compile(lines)
ast = [:haml, :text, compile_lines(lines, indent_width: 2)] ast = [:haml, :text, compile_lines(lines, indent_width: 2)]
ast = [:multi, [:static, "\n"], ast] ast = [:multi, [:static, "\n"], ast]
ast = [:html, :tag, 'style', [:html, :attrs], ast] ast = [:html, :tag, 'style', [:html, :attrs], ast]
ast ast
end end
private
def compile_lines(lines, indent_width: 0)
text = strip_last(lines).map { |line|
' ' * indent_width + line
}.join("\n")
text += "\n" if text.length > 0
text
end
# NOTE: empty line is reserved for preserve filter.
def strip_last(lines)
lines = lines.dup
while lines.last && lines.last.length == 0
lines.delete_at(-1)
end
lines
end
end end
end end
end end

View file

@ -0,0 +1,14 @@
require 'hamlit/filters/base'
module Hamlit
module Filters
class Javascript < Base
def compile(lines)
ast = [:haml, :text, compile_lines(lines, indent_width: 2)]
ast = [:multi, [:static, "\n"], ast]
ast = [:html, :tag, 'script', [:html, :attrs], ast]
ast
end
end
end
end

View file

@ -1,11 +1,13 @@
require 'hamlit/filters/base'
module Hamlit module Hamlit
module Filters module Filters
class Plain class Plain < Base
def compile(lines) def compile(lines)
ast = [:multi] ast = [:multi]
text = strip_last(lines).join("\n") text = compile_lines(lines)
text.gsub!(/\n\Z/, '') unless string_interpolated?(text)
ast << [:haml, :text, text] ast << [:haml, :text, text]
ast << [:static, "\n"] if string_interpolated?(text)
ast ast
end end
@ -14,14 +16,6 @@ module Hamlit
def string_interpolated?(text) def string_interpolated?(text)
text =~ /\#{[^\#{}]*}/ text =~ /\#{[^\#{}]*}/
end end
def strip_last(lines)
lines = lines.dup
while lines.last && lines.last.length == 0
lines.delete_at(-1)
end
lines
end
end end
end end
end end

View file

@ -1,12 +1,8 @@
require 'hamlit/helpers'
module Hamlit module Hamlit
module Filters module Filters
class Preserve class Preserve
def compile(lines) def compile(lines)
ast = [:multi] [:multi, [:haml, :text, lines.join('&#x000A;')]]
ast << [:haml, :text, lines.join('&#x000A;')]
ast
end end
end end
end end

View file

@ -1,82 +1,82 @@
# describe Hamlit::Filters::Javascript do describe Hamlit::Filters::Javascript do
# describe '#compile' do describe '#compile' do
# it 'just renders script tag for empty filter' do it 'just renders script tag for empty filter' do
# assert_render(<<-HAML, <<-HTML) assert_render(<<-HAML, <<-HTML)
# before before
# :javascript :javascript
# after after
# HAML HAML
# before before
# <script> <script>
#
# </script> </script>
# after after
# HTML HTML
# end end
#
# it 'compiles javascript filter' do it 'compiles javascript filter' do
# assert_render(<<-HAML, <<-HTML) assert_render(<<-HAML, <<-HTML)
# before before
# :javascript :javascript
# alert('hello'); alert('hello');
# after after
# HAML HAML
# before before
# <script> <script>
# alert('hello'); alert('hello');
# </script> </script>
# after after
# HTML HTML
# end end
#
# it 'accepts illegal indentation' do it 'accepts illegal indentation' do
# assert_render(<<-HAML, <<-HTML) assert_render(<<-HAML, <<-HTML)
# :javascript :javascript
# if { if {
# alert('hello'); alert('hello');
# } }
# :javascript :javascript
# if { if {
# alert('hello'); alert('hello');
# } }
# HAML HAML
# <script> <script>
# if { if {
# alert('hello'); alert('hello');
# } }
# </script> </script>
# <script> <script>
# if { if {
# alert('hello'); alert('hello');
# } }
# </script> </script>
# HTML HTML
# end end
#
# it 'accepts illegal indentation' do it 'accepts illegal indentation' do
# assert_render(<<-HAML, <<-HTML) assert_render(<<-HAML, <<-HTML)
# :javascript :javascript
# if { if {
# alert('a'); alert('a');
# } }
# HAML HAML
# <script> <script>
# if { if {
# alert('a'); alert('a');
# } }
# </script> </script>
# HTML HTML
# end end
#
# it 'parses string interpolation' do it 'parses string interpolation' do
# assert_render(<<-'HAML', <<-HTML) assert_render(<<-'HAML', <<-HTML)
# :javascript :javascript
# var a = #{[1, 2]}; var a = #{[1, 2]};
# HAML HAML
# <script> <script>
# var a = [1, 2]; var a = [1, 2];
# </script> </script>
# HTML HTML
# end end
# end end
# end end