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/filters/css'
require 'hamlit/filters/escaped'
require 'hamlit/filters/javascript'
require 'hamlit/filters/plain'
require 'hamlit/filters/preserve'
@ -13,10 +14,11 @@ module Hamlit
included do
extend Concerns::Registerable
register :css, Filters::Css
register :escaped, Filters::Escaped
register :plain, Filters::Plain
register :preserve, Filters::Preserve
register :css, Filters::Css
register :escaped, Filters::Escaped
register :javascript, Filters::Javascript
register :plain, Filters::Plain
register :preserve, Filters::Preserve
end
def on_haml_filter(name, lines)

View file

@ -30,17 +30,21 @@ module Hamlit
end
def read_lines
lines = []
spaces = ' ' * (@current_indent * 2)
lines = []
while read_line?
lines << @lines[@current_lineno + 1].gsub(/\A#{spaces}/, '')
lines << @lines[@current_lineno + 1]
@current_lineno += 1
end
lines
trim_lines(lines)
end
private
def trim_lines(lines)
size = (lines.first || '').index(/[^\s]/) || 0
lines.map { |line| line.gsub(/\A {#{size}}/, '') }
end
def read_line?
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 Filters
class Css
class Css < Base
def compile(lines)
ast = [:haml, :text, compile_lines(lines, indent_width: 2)]
ast = [:multi, [:static, "\n"], ast]
ast = [:html, :tag, 'style', [:html, :attrs], ast]
ast
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

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 Filters
class Plain
class Plain < Base
def compile(lines)
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 << [:static, "\n"] if string_interpolated?(text)
ast
end
@ -14,14 +16,6 @@ module Hamlit
def string_interpolated?(text)
text =~ /\#{[^\#{}]*}/
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

View file

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

View file

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