mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Make plain text parser better
This is very difficult for me to implement. Original implementation is Haml::Util in https://github.com/haml/haml. Thanks for MIT License.
This commit is contained in:
parent
773d1cf8f3
commit
2998f95ea5
4 changed files with 53 additions and 11 deletions
|
@ -1,4 +1,5 @@
|
||||||
Copyright (c) 2015 Takashi Kokubun
|
Copyright (c) 2015 Takashi Kokubun
|
||||||
|
Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
# NOTE: This compiler has an extremely bad effect for performance.
|
require 'hamlit/concerns/string_literal'
|
||||||
|
|
||||||
|
# FIXME: This compiler has an extremely bad effect for performance.
|
||||||
# We should optimize this.
|
# We should optimize this.
|
||||||
module Hamlit
|
module Hamlit
|
||||||
module Compilers
|
module Compilers
|
||||||
module Text
|
module Text
|
||||||
|
include Concerns::StringLiteral
|
||||||
|
|
||||||
def on_haml_text(exp)
|
def on_haml_text(exp)
|
||||||
compile_text(exp)
|
[:dynamic, string_literal(exp)]
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# FIXME: This can't parse '!'
|
|
||||||
def compile_text(exp)
|
|
||||||
[:dynamic, "%Q!#{exp}!"]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
44
lib/hamlit/concerns/string_literal.rb
Normal file
44
lib/hamlit/concerns/string_literal.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
module Hamlit
|
||||||
|
module Concerns
|
||||||
|
module StringLiteral
|
||||||
|
def string_literal(str)
|
||||||
|
unescape_interpolation(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def unescape_interpolation(str)
|
||||||
|
res = ''
|
||||||
|
rest = handle_interpolation(str.inspect) do |scan|
|
||||||
|
escapes = (scan[2].size - 1) / 2
|
||||||
|
res << scan.matched[0...-3 - escapes]
|
||||||
|
if escapes % 2 == 1
|
||||||
|
res << '#{'
|
||||||
|
else
|
||||||
|
content = eval('"' + balance(scan, ?{, ?}, 1)[0][0...-1] + '"')
|
||||||
|
res << '#{' + content + '}'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
res + rest
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_interpolation(str)
|
||||||
|
scan = StringScanner.new(str)
|
||||||
|
yield scan while scan.scan(/(.*?)(\\*)\#\{/)
|
||||||
|
scan.rest
|
||||||
|
end
|
||||||
|
|
||||||
|
def balance(scanner, start, finish, count = 0)
|
||||||
|
str = ''
|
||||||
|
scanner = StringScanner.new(scanner) unless scanner.is_a? StringScanner
|
||||||
|
regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]", Regexp::MULTILINE)
|
||||||
|
while scanner.scan(regexp)
|
||||||
|
str << scanner.matched
|
||||||
|
count += 1 if scanner.matched[-1] == start
|
||||||
|
count -= 1 if scanner.matched[-1] == finish
|
||||||
|
return [str.strip, scanner.rest] if count == 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,11 +2,11 @@ describe Hamlit::Engine do
|
||||||
describe 'text' do
|
describe 'text' do
|
||||||
it 'renders string interpolation' do
|
it 'renders string interpolation' do
|
||||||
assert_render(<<-'HAML', <<-HTML)
|
assert_render(<<-'HAML', <<-HTML)
|
||||||
#{ "a#{3}a" }a" #{[1, 2]} b
|
#{ "a#{3}a" }a" #{["1", 2]} b " !
|
||||||
a#{{ a: 3 }}
|
a#{{ a: 3 }}
|
||||||
<ht#{2}ml>
|
<ht#{2}ml>
|
||||||
HAML
|
HAML
|
||||||
a3aa" [1, 2] b
|
a3aa" ["1", 2] b " !
|
||||||
a{:a=>3}
|
a{:a=>3}
|
||||||
<ht2ml>
|
<ht2ml>
|
||||||
HTML
|
HTML
|
||||||
|
|
Loading…
Reference in a new issue