hamlit 1.3.2 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/hamlit/compilers/text.rb +79 -2
- data/lib/hamlit/version.rb +1 -1
- data/spec/hamlit/engine/text_spec.rb +18 -2
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9be0ee09a4585d8c871901afad043298e8eae2bc
|
4
|
+
data.tar.gz: f1a8f5bbbdaa2994e209a959b4ba2a1162c76317
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e3d51b40f28322634436597711f45d3dade9c5ad252302fb593bda6996bf27c8ab2b1b644054971606e5c79627a4df4768d4745987272597dec0e814b6b77b
|
7
|
+
data.tar.gz: a3f96912395ad6b3ec047ae332e202b72c385fc28af8dcd7fac35488ba66175ca453ae2286a98b22afaf98dfa4d3132c3aedd22a0a8e73e34ee97e8aee26d835
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,91 @@
|
|
1
|
+
require 'hamlit/concerns/escapable'
|
2
|
+
require 'hamlit/concerns/included'
|
1
3
|
require 'hamlit/concerns/string_interpolation'
|
2
4
|
|
3
5
|
module Hamlit
|
4
6
|
module Compilers
|
5
7
|
module Text
|
8
|
+
extend Concerns::Included
|
6
9
|
include Concerns::StringInterpolation
|
7
10
|
|
11
|
+
included do
|
12
|
+
include Concerns::Escapable
|
13
|
+
end
|
14
|
+
|
15
|
+
# To ask ripper to consider a given text as string literal,
|
16
|
+
# I change "foo" to "%!foo!".
|
17
|
+
# This constant is the candidates for the literal surrounder.
|
18
|
+
STRING_MARKERS = %w[' " ! @ $ % ^ & * | =].freeze
|
19
|
+
|
20
|
+
# Return static and dynamic temple ast.
|
21
|
+
# It splits expression to optimize because string interpolation is slow.
|
8
22
|
def on_haml_text(exp)
|
9
|
-
return
|
23
|
+
return static_text(exp) unless contains_interpolation?(exp)
|
24
|
+
|
25
|
+
marker = find_string_marker(exp)
|
26
|
+
return [:dynamic, string_literal(exp)] unless marker
|
27
|
+
|
28
|
+
open_pos, close_pos = find_interpolation(exp, marker)
|
29
|
+
return static_text(exp) unless open_pos && close_pos
|
30
|
+
|
31
|
+
pre = exp.byteslice(0...open_pos)
|
32
|
+
body = exp.byteslice((open_pos + 2)...close_pos)
|
33
|
+
post = exp.byteslice((close_pos + 1)...exp.bytesize)
|
34
|
+
[:multi, [:static, pre], escape_html([:dynamic, body]), on_haml_text(post)]
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_interpolation(exp, marker)
|
38
|
+
return unless contains_interpolation?(exp)
|
39
|
+
|
40
|
+
offset = 2 # 2 is the length of '%' and marker
|
41
|
+
open_pos = nil
|
42
|
+
close_pos = nil
|
43
|
+
open_count = 0
|
44
|
+
literal = literalify_string(exp, marker)
|
45
|
+
|
46
|
+
Ripper.lex(literal).each do |(row, col), type, str|
|
47
|
+
case type
|
48
|
+
when :on_embexpr_beg
|
49
|
+
open_pos = calc_position(exp, row, col, offset) if open_count == 0
|
50
|
+
open_count += 1
|
51
|
+
when :on_embexpr_end
|
52
|
+
open_count -= 1
|
53
|
+
return [open_pos, calc_position(exp, row, col, offset)] if open_count == 0
|
54
|
+
end
|
55
|
+
open_count
|
56
|
+
end
|
57
|
+
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# :static can't treat backslash properly
|
64
|
+
def static_text(exp)
|
65
|
+
return [:dynamic, string_literal(exp)] if exp.include?('\\')
|
66
|
+
[:static, exp]
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_string_marker(text)
|
70
|
+
STRING_MARKERS.each do |marker|
|
71
|
+
return marker unless text.include?(marker)
|
72
|
+
end
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def literalify_string(exp, marker)
|
77
|
+
"%#{marker}#{exp}#{marker}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def calc_position(exp, row, col, offset)
|
81
|
+
return col - offset if row <= 1
|
10
82
|
|
11
|
-
|
83
|
+
pos = col
|
84
|
+
lines = exp.split("\n")
|
85
|
+
(0..(row - 2)).each do |row_index|
|
86
|
+
pos += lines[row_index].bytesize + 1
|
87
|
+
end
|
88
|
+
pos
|
12
89
|
end
|
13
90
|
end
|
14
91
|
end
|
data/lib/hamlit/version.rb
CHANGED
@@ -6,8 +6,8 @@ describe Hamlit::Engine do
|
|
6
6
|
a#{{ a: 3 }}
|
7
7
|
<ht#{2}ml>
|
8
8
|
HAML
|
9
|
-
a3aa" [
|
10
|
-
a{:a
|
9
|
+
a3aa" ["1", 2] b " !
|
10
|
+
a{:a=>3}
|
11
11
|
<ht2ml>
|
12
12
|
HTML
|
13
13
|
end
|
@@ -42,5 +42,21 @@ describe Hamlit::Engine do
|
|
42
42
|
it 'leaves empty spaces after backslash' do
|
43
43
|
expect(render_string('\ a')).to eq(" a\n")
|
44
44
|
end
|
45
|
+
|
46
|
+
describe 'string interpolation' do
|
47
|
+
specify { assert_render('#{}', "\n") }
|
48
|
+
specify { assert_render('1#{}', "1\n") }
|
49
|
+
specify { assert_render('1#{2}', "12\n") }
|
50
|
+
specify { assert_render('1#{2', "1\#{2\n") }
|
51
|
+
specify { assert_render('}#{1}', "}1\n") }
|
52
|
+
specify { assert_render('#{1}2', "12\n") }
|
53
|
+
specify { assert_render('1#{ "2#{3}4" }5', "12345\n") }
|
54
|
+
specify { assert_render('#{1}2#{3}4#{5}6#{7}8#{9}', "123456789\n") }
|
55
|
+
specify { assert_render(%q{'"!@$%^&*|=#{1}1#{1}2}, %Q{'"!@$%^&*|=1112\n}) }
|
56
|
+
specify { assert_render('あ#{1}', "あ1\n") }
|
57
|
+
specify { assert_render('あ#{"い"}う', "あいう\n") }
|
58
|
+
specify { assert_render('a#{"<b>"}c', "a<b>c\n") }
|
59
|
+
specify { assert_render(":plain\n あ\n \#{'い'}", "あ\nい\n\n") }
|
60
|
+
end
|
45
61
|
end
|
46
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hamlit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: escape_utils
|
@@ -569,4 +569,3 @@ test_files:
|
|
569
569
|
- spec/rails/vendor/assets/javascripts/.keep
|
570
570
|
- spec/rails/vendor/assets/stylesheets/.keep
|
571
571
|
- spec/spec_helper.rb
|
572
|
-
has_rdoc:
|