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

Accept string interpolation in sass filter

This commit is contained in:
Takashi Kokubun 2015-03-30 17:16:32 +09:00
parent da2fc7c729
commit d2ed383d86
6 changed files with 70 additions and 26 deletions

View file

@ -1,21 +1,15 @@
require 'hamlit/concerns/string_literal'
require 'hamlit/concerns/string_interpolation'
module Hamlit
module Compilers
module Text
include Concerns::StringLiteral
include Concerns::StringInterpolation
def on_haml_text(exp)
return [:static, exp] unless contains_interpolation?(exp)
[:dynamic, string_literal(exp)]
end
private
def contains_interpolation?(str)
/#[\{$@]/ === str
end
end
end
end

View file

@ -1,10 +1,14 @@
module Hamlit
module Concerns
module StringLiteral
module StringInterpolation
def string_literal(str)
unescape_interpolation(str)
end
def contains_interpolation?(str)
/#[\{$@]/ === str
end
private
def unescape_interpolation(str)

View file

@ -3,7 +3,12 @@ module Hamlit
class Base
attr_reader :options
def initialize(options)
def self.indent_source(source, indent_width: 0)
lines = source.split("\n")
self.new.compile_lines(lines, indent_width: indent_width)
end
def initialize(options = {})
@options = options
end
@ -11,8 +16,6 @@ module Hamlit
raise NotImplementedError
end
private
def compile_lines(lines, indent_width: 0)
base = (lines.first || '').index(/[^\s]/) || 0
width = indent_width - base
@ -26,6 +29,8 @@ module Hamlit
text
end
private
# NOTE: empty line is reserved for preserve filter.
def strip_last(lines)
lines = lines.dup

View file

@ -1,21 +1,11 @@
require 'tilt'
require 'hamlit/filters/base'
require 'hamlit/filters/tilt'
module Hamlit
module Filters
class Sass < Base
class Sass < Filters::Tilt
def compile(lines)
result = compile_with_tilt(lines)
content = [:multi, [:static, "\n"], result]
[:html, :tag, 'style', [:html, :attrs], content]
end
private
def compile_with_tilt(lines)
source = lines.join("\n")
result = ::Tilt['t.sass'].new { source }.render
[:static, compile_lines(result.split("\n"), indent_width: 2)]
ast = [:html, :tag, 'style', [:html, :attrs]]
compile_with_tilt('sass', lines.join("\n"), ast)
end
end
end

View file

@ -0,0 +1,33 @@
require 'tilt'
require 'hamlit/concerns/string_interpolation'
require 'hamlit/filters/base'
module Hamlit
module Filters
class Tilt < Filters::Base
include Concerns::StringInterpolation
def self.render(name, source)
result = ::Tilt["t.#{name}"].new { source }.render
indent_source(result, indent_width: 2)
end
private
def compile_with_tilt(name, source, ast)
return runtime_compile(name, source, ast) if contains_interpolation?(source)
result = [:static, Filters::Tilt.render(name, source)]
content = [:multi, [:static, "\n"], result]
ast << content
end
def runtime_compile(name, source, ast)
literal = string_literal(source)
code = "::Hamlit::Filters::Tilt.render(#{name.inspect}, #{literal})"
content = [:multi, [:static, "\n"], [:dynamic, code]]
ast << content
end
end
end
end

View file

@ -15,5 +15,23 @@ describe Hamlit::Filters::Sass do
</style>
HTML
end
it 'renders sass filter with string interpolation' do
assert_render(<<-'HAML', <<-HTML)
- width = 1200
- height = 800
:sass
.users_controller
.show_action
width: #{width}px
height: #{height}px
HAML
<style>
.users_controller .show_action {
width: 1200px;
height: 800px; }
</style>
HTML
end
end
end