hamlit 2.11.0 → 2.13.0

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +17 -11
  4. data/CHANGELOG.md +29 -1
  5. data/Gemfile +1 -7
  6. data/LICENSE.txt +26 -23
  7. data/REFERENCE.md +4 -4
  8. data/bin/update-haml +125 -0
  9. data/ext/hamlit/hamlit.c +0 -1
  10. data/lib/hamlit/attribute_builder.rb +2 -2
  11. data/lib/hamlit/attribute_compiler.rb +3 -3
  12. data/lib/hamlit/compiler/children_compiler.rb +18 -4
  13. data/lib/hamlit/compiler/comment_compiler.rb +1 -0
  14. data/lib/hamlit/filters/escaped.rb +1 -1
  15. data/lib/hamlit/filters/markdown.rb +1 -0
  16. data/lib/hamlit/filters/preserve.rb +1 -1
  17. data/lib/hamlit/filters/text_base.rb +1 -1
  18. data/lib/hamlit/filters/tilt_base.rb +1 -1
  19. data/lib/hamlit/parser.rb +6 -2
  20. data/lib/hamlit/parser/haml_attribute_builder.rb +164 -0
  21. data/lib/hamlit/parser/haml_buffer.rb +20 -130
  22. data/lib/hamlit/parser/haml_compiler.rb +1 -553
  23. data/lib/hamlit/parser/haml_error.rb +29 -25
  24. data/lib/hamlit/parser/haml_escapable.rb +1 -0
  25. data/lib/hamlit/parser/haml_generator.rb +1 -0
  26. data/lib/hamlit/parser/haml_helpers.rb +41 -59
  27. data/lib/hamlit/parser/{haml_xss_mods.rb → haml_helpers/xss_mods.rb} +20 -15
  28. data/lib/hamlit/parser/haml_options.rb +53 -66
  29. data/lib/hamlit/parser/haml_parser.rb +103 -71
  30. data/lib/hamlit/parser/haml_temple_engine.rb +123 -0
  31. data/lib/hamlit/parser/haml_util.rb +10 -40
  32. data/lib/hamlit/rails_template.rb +1 -1
  33. data/lib/hamlit/string_splitter.rb +1 -0
  34. data/lib/hamlit/temple_line_counter.rb +31 -0
  35. data/lib/hamlit/version.rb +1 -1
  36. metadata +10 -6
  37. data/lib/hamlit/parser/MIT-LICENSE +0 -20
  38. data/lib/hamlit/parser/README.md +0 -30
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temple'
4
+ require 'hamlit/parser/haml_escapable'
5
+ require 'hamlit/parser/haml_generator'
6
+
7
+ module Hamlit
8
+ class HamlTempleEngine < Temple::Engine
9
+ define_options(
10
+ attr_wrapper: "'",
11
+ autoclose: %w(area base basefont br col command embed frame
12
+ hr img input isindex keygen link menuitem meta
13
+ param source track wbr),
14
+ encoding: nil,
15
+ escape_attrs: true,
16
+ escape_html: false,
17
+ escape_filter_interpolations: nil,
18
+ filename: '(haml)',
19
+ format: :html5,
20
+ hyphenate_data_attrs: true,
21
+ line: 1,
22
+ mime_type: 'text/html',
23
+ preserve: %w(textarea pre code),
24
+ remove_whitespace: false,
25
+ suppress_eval: false,
26
+ cdata: false,
27
+ parser_class: ::Hamlit::HamlParser,
28
+ compiler_class: ::Hamlit::HamlCompiler,
29
+ trace: false,
30
+ filters: {},
31
+ )
32
+
33
+ use :Parser, -> { options[:parser_class] }
34
+ use :Compiler, -> { options[:compiler_class] }
35
+ use HamlEscapable
36
+ filter :ControlFlow
37
+ filter :MultiFlattener
38
+ filter :StaticMerger
39
+ use HamlGenerator
40
+
41
+ def compile(template)
42
+ initialize_encoding(template, options[:encoding])
43
+ @precompiled = call(template)
44
+ end
45
+
46
+ # The source code that is evaluated to produce the Haml document.
47
+ #
48
+ # This is automatically converted to the correct encoding
49
+ # (see {file:REFERENCE.md#encodings the `:encoding` option}).
50
+ #
51
+ # @return [String]
52
+ def precompiled
53
+ encoding = Encoding.find(@encoding || '')
54
+ return @precompiled.dup.force_encoding(encoding) if encoding == Encoding::ASCII_8BIT
55
+ return @precompiled.encode(encoding)
56
+ end
57
+
58
+ def precompiled_with_return_value
59
+ "#{precompiled};#{precompiled_method_return_value}".dup
60
+ end
61
+
62
+ # The source code that is evaluated to produce the Haml document.
63
+ #
64
+ # This is automatically converted to the correct encoding
65
+ # (see {file:REFERENCE.md#encodings the `:encoding` option}).
66
+ #
67
+ # @return [String]
68
+ def precompiled_with_ambles(local_names, after_preamble: '')
69
+ preamble = <<END.tr("\n", ';')
70
+ begin
71
+ extend Hamlit::HamlHelpers
72
+ _hamlout = @haml_buffer = Hamlit::HamlBuffer.new(haml_buffer, #{HamlOptions.new(options).for_buffer.inspect})
73
+ _erbout = _hamlout.buffer
74
+ #{after_preamble}
75
+ END
76
+ postamble = <<END.tr("\n", ';')
77
+ #{precompiled_method_return_value}
78
+ ensure
79
+ @haml_buffer = @haml_buffer.upper if @haml_buffer
80
+ end
81
+ END
82
+ "#{preamble}#{locals_code(local_names)}#{precompiled}#{postamble}".dup
83
+ end
84
+
85
+ private
86
+
87
+ def initialize_encoding(template, given_value)
88
+ if given_value
89
+ @encoding = given_value
90
+ else
91
+ @encoding = Encoding.default_internal || template.encoding
92
+ end
93
+ end
94
+
95
+ # Returns the string used as the return value of the precompiled method.
96
+ # This method exists so it can be monkeypatched to return modified values.
97
+ def precompiled_method_return_value
98
+ "_erbout"
99
+ end
100
+
101
+ def locals_code(names)
102
+ names = names.keys if Hash === names
103
+
104
+ names.map do |name|
105
+ # Can't use || because someone might explicitly pass in false with a symbol
106
+ sym_local = "_haml_locals[#{inspect_obj(name.to_sym)}]"
107
+ str_local = "_haml_locals[#{inspect_obj(name.to_s)}]"
108
+ "#{name} = #{sym_local}.nil? ? #{str_local} : #{sym_local};"
109
+ end.join
110
+ end
111
+
112
+ def inspect_obj(obj)
113
+ case obj
114
+ when String
115
+ %Q!"#{obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]}}"!
116
+ when Symbol
117
+ ":#{inspect_obj(obj.to_s)}"
118
+ else
119
+ obj.inspect
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  begin
4
4
  require 'erubis/tiny'
@@ -126,7 +126,7 @@ MSG
126
126
  def inspect_obj(obj)
127
127
  case obj
128
128
  when String
129
- %Q!"#{obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...-1]}}"!
129
+ %Q!"#{obj.gsub(/[\x00-\x7F]+/) {|s| s.dump[1...-1]}}"!
130
130
  when Symbol
131
131
  ":#{inspect_obj(obj.to_s)}"
132
132
  else
@@ -166,7 +166,7 @@ MSG
166
166
  # and the rest of the string.
167
167
  # `["Foo (Bar (Baz bang) bop)", " (Bang (bop bip))"]` in the example above.
168
168
  def balance(scanner, start, finish, count = 0)
169
- str = ''
169
+ str = ''.dup
170
170
  scanner = StringScanner.new(scanner) unless scanner.is_a? StringScanner
171
171
  regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]", Regexp::MULTILINE)
172
172
  while scanner.scan(regexp)
@@ -198,12 +198,9 @@ MSG
198
198
  /#[\{$@]/ === str
199
199
  end
200
200
 
201
- # Original Haml::Util.unescape_interpolation
202
- # ex) slow_unescape_interpolation('foo#{bar}baz"', escape_html: true)
203
- # #=> "\"foo\#{::Hamlit::HamlHelpers.html_escape((bar))}baz\\\"\""
204
- def slow_unescape_interpolation(str, escape_html = nil)
205
- res = ''
206
- rest = ::Hamlit::HamlUtil.handle_interpolation str.dump do |scan|
201
+ def unescape_interpolation(str, escape_html = nil)
202
+ res = ''.dup
203
+ rest = Hamlit::HamlUtil.handle_interpolation str.dump do |scan|
207
204
  escapes = (scan[2].size - 1) / 2
208
205
  char = scan[3] # '{', '@' or '$'
209
206
  res << scan.matched[0...-3 - escapes]
@@ -215,36 +212,9 @@ MSG
215
212
  else
216
213
  scan.scan(/\w+/)
217
214
  end
218
- content = eval('"' + interpolated + '"')
219
- content.prepend(char) if char == '@' || char == '$'
220
- content = "::Hamlit::HamlHelpers.html_escape((#{content}))" if escape_html
221
-
222
- res << "\#{#{content}}"
223
- end
224
- end
225
- res + rest
226
- end
227
-
228
- # Customized Haml::Util.unescape_interpolation to handle escape by Hamlit.
229
- # It wraps double quotes to given `str` with escaping `"`.
230
- #
231
- # ex) unescape_interpolation('foo#{bar}baz"') #=> "\"foo\#{bar}baz\\\"\""
232
- def unescape_interpolation(str)
233
- res = ''
234
- rest = ::Hamlit::HamlUtil.handle_interpolation str.dump do |scan|
235
- escapes = (scan[2].size - 1) / 2
236
- char = scan[3] # '{', '@' or '$'
237
- res << scan.matched[0...-3 - escapes]
238
- if escapes % 2 == 1
239
- res << "\##{char}"
240
- else
241
- interpolated = if char == '{'
242
- balance(scan, ?{, ?}, 1)[0][0...-1]
243
- else
244
- scan.scan(/\w+/)
245
- end
246
- content = eval('"' + interpolated + '"')
247
- content.prepend(char) if char == '@' || char == '$'
215
+ content = eval("\"#{interpolated}\"")
216
+ content = "#{char}#{content}" if char == '@' || char == '$'
217
+ content = "Hamlit::HamlHelpers.html_escape((#{content}))" if escape_html
248
218
 
249
219
  res << "\#{#{content}}"
250
220
  end
@@ -264,7 +234,7 @@ MSG
264
234
  scanner = StringScanner.new(str.dup.force_encoding(Encoding::ASCII_8BIT))
265
235
  bom = scanner.scan(/\xEF\xBB\xBF/n)
266
236
  return bom unless scanner.scan(/-\s*#\s*/n)
267
- if coding = try_parse_haml_emacs_magic_comment(scanner)
237
+ if (coding = try_parse_haml_emacs_magic_comment(scanner))
268
238
  return bom, coding
269
239
  end
270
240
 
@@ -44,7 +44,7 @@ module Hamlit
44
44
 
45
45
  # https://github.com/haml/haml/blob/4.0.7/lib/haml/template.rb
46
46
  module HamlHelpers
47
- require 'hamlit/parser/haml_xss_mods'
47
+ require 'hamlit/parser/haml_helpers/xss_mods'
48
48
  include Hamlit::HamlHelpers::XssMods
49
49
  end
50
50
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'ripper'
2
3
  require 'hamlit/ruby_expression'
3
4
 
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module Hamlit
3
+ # A module to count lines of expected code. This would be faster than actual code generation
4
+ # and counting newlines in it.
5
+ module TempleLineCounter
6
+ class UnexpectedExpression < StandardError; end
7
+
8
+ def self.count_lines(exp)
9
+ type, *args = exp
10
+ case type
11
+ when :multi
12
+ args.map { |a| count_lines(a) }.reduce(:+) || 0
13
+ when :dynamic, :code
14
+ args.first.count("\n")
15
+ when :static
16
+ 0 # It has not real newline "\n" but escaped "\\n".
17
+ when :case
18
+ arg, *cases = args
19
+ arg.count("\n") + cases.map do |cond, e|
20
+ (cond == :else ? 0 : cond.count("\n")) + count_lines(e)
21
+ end.reduce(:+)
22
+ when :escape
23
+ count_lines(args[1])
24
+ when :newline
25
+ 1
26
+ else
27
+ raise UnexpectedExpression.new("[HAML BUG] Unexpected Temple expression '#{type}' is given!")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Hamlit
3
- VERSION = '2.11.0'
3
+ VERSION = '2.13.0'
4
4
  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: 2.11.0
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-13 00:00:00.000000000 Z
11
+ date: 2020-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: temple
@@ -303,6 +303,7 @@ files:
303
303
  - bin/setup
304
304
  - bin/stackprof
305
305
  - bin/test
306
+ - bin/update-haml
306
307
  - exe/hamlit
307
308
  - ext/hamlit/extconf.rb
308
309
  - ext/hamlit/hamlit.c
@@ -348,22 +349,25 @@ files:
348
349
  - lib/hamlit/identity.rb
349
350
  - lib/hamlit/object_ref.rb
350
351
  - lib/hamlit/parser.rb
351
- - lib/hamlit/parser/MIT-LICENSE
352
- - lib/hamlit/parser/README.md
352
+ - lib/hamlit/parser/haml_attribute_builder.rb
353
353
  - lib/hamlit/parser/haml_buffer.rb
354
354
  - lib/hamlit/parser/haml_compiler.rb
355
355
  - lib/hamlit/parser/haml_error.rb
356
+ - lib/hamlit/parser/haml_escapable.rb
357
+ - lib/hamlit/parser/haml_generator.rb
356
358
  - lib/hamlit/parser/haml_helpers.rb
359
+ - lib/hamlit/parser/haml_helpers/xss_mods.rb
357
360
  - lib/hamlit/parser/haml_options.rb
358
361
  - lib/hamlit/parser/haml_parser.rb
362
+ - lib/hamlit/parser/haml_temple_engine.rb
359
363
  - lib/hamlit/parser/haml_util.rb
360
- - lib/hamlit/parser/haml_xss_mods.rb
361
364
  - lib/hamlit/rails_helpers.rb
362
365
  - lib/hamlit/rails_template.rb
363
366
  - lib/hamlit/railtie.rb
364
367
  - lib/hamlit/ruby_expression.rb
365
368
  - lib/hamlit/string_splitter.rb
366
369
  - lib/hamlit/template.rb
370
+ - lib/hamlit/temple_line_counter.rb
367
371
  - lib/hamlit/utils.rb
368
372
  - lib/hamlit/version.rb
369
373
  homepage: https://github.com/k0kubun/hamlit
@@ -385,7 +389,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
385
389
  - !ruby/object:Gem::Version
386
390
  version: '0'
387
391
  requirements: []
388
- rubygems_version: 3.0.3
392
+ rubygems_version: 3.1.2
389
393
  signing_key:
390
394
  specification_version: 4
391
395
  summary: High Performance Haml Implementation
@@ -1,20 +0,0 @@
1
- Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,30 +0,0 @@
1
- # lib/hamlit/parser/haml\_\*.rb
2
-
3
- Hamlit::HamlFoo is originally Haml::Foo in haml gem.
4
-
5
- This directory is NOT intended to be updated other than following Haml's changes.
6
-
7
- ## License
8
-
9
- lib/hamlit/parser/haml\_\*.rb is:
10
-
11
- Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
12
-
13
- Permission is hereby granted, free of charge, to any person obtaining
14
- a copy of this software and associated documentation files (the
15
- "Software"), to deal in the Software without restriction, including
16
- without limitation the rights to use, copy, modify, merge, publish,
17
- distribute, sublicense, and/or sell copies of the Software, and to
18
- permit persons to whom the Software is furnished to do so, subject to
19
- the following conditions:
20
-
21
- The above copyright notice and this permission notice shall be
22
- included in all copies or substantial portions of the Software.
23
-
24
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.