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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f46fa9efe505104cd9dbf51194e8a1cc21bf4219
4
- data.tar.gz: 9d4482ab58838d4a8050e3f598aad02072cc14b6
3
+ metadata.gz: 9be0ee09a4585d8c871901afad043298e8eae2bc
4
+ data.tar.gz: f1a8f5bbbdaa2994e209a959b4ba2a1162c76317
5
5
  SHA512:
6
- metadata.gz: 83051f74ebe3b2621ebc9439b678f1a2b967163a36354cfa0503de403736930b2fd7dd18bfcc49e6690b83bb970e629afde447b8ac4c3df889c07dcb992dc0fb
7
- data.tar.gz: 4b07f8bca0e0ac486fb5c1313a6a70677bd7d6a68954304703f2244f5c537d4ba025537135d13d6a01fe84ba61d7e83125c06717ba6373b087fa925525052315
6
+ metadata.gz: e2e3d51b40f28322634436597711f45d3dade9c5ad252302fb593bda6996bf27c8ab2b1b644054971606e5c79627a4df4768d4745987272597dec0e814b6b77b
7
+ data.tar.gz: a3f96912395ad6b3ec047ae332e202b72c385fc28af8dcd7fac35488ba66175ca453ae2286a98b22afaf98dfa4d3132c3aedd22a0a8e73e34ee97e8aee26d835
@@ -1,3 +1,11 @@
1
+ ## v1.4.1
2
+
3
+ - Fix code mistake in 1.4.0
4
+
5
+ ## v1.4.0 (yanked)
6
+
7
+ - Escape interpolated string in plain text
8
+
1
9
  ## v1.3.2
2
10
 
3
11
  - Render `begin`, `rescue` and `ensure`
@@ -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 [:static, exp] unless contains_interpolation?(exp)
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
- [:dynamic, string_literal(exp)]
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
@@ -1,3 +1,3 @@
1
1
  module Hamlit
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.1"
3
3
  end
@@ -6,8 +6,8 @@ describe Hamlit::Engine do
6
6
  a#{{ a: 3 }}
7
7
  <ht#{2}ml>
8
8
  HAML
9
- a3aa" ["1", 2] b " !
10
- a{:a=>3}
9
+ a3aa" [&quot;1&quot;, 2] b " !
10
+ a{:a=&gt;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&lt;b&gt;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.3.2
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-30 00:00:00.000000000 Z
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: