hamlit 2.10.0 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +17 -11
  4. data/CHANGELOG.md +45 -1
  5. data/Gemfile +1 -7
  6. data/LICENSE.txt +26 -23
  7. data/REFERENCE.md +13 -4
  8. data/bin/bench +2 -2
  9. data/bin/update-haml +125 -0
  10. data/ext/hamlit/hamlit.c +0 -1
  11. data/lib/hamlit/attribute_builder.rb +2 -2
  12. data/lib/hamlit/attribute_compiler.rb +3 -3
  13. data/lib/hamlit/compiler/children_compiler.rb +18 -4
  14. data/lib/hamlit/compiler/comment_compiler.rb +8 -5
  15. data/lib/hamlit/filters/escaped.rb +1 -1
  16. data/lib/hamlit/filters/markdown.rb +1 -0
  17. data/lib/hamlit/filters/preserve.rb +1 -1
  18. data/lib/hamlit/filters/text_base.rb +1 -1
  19. data/lib/hamlit/filters/tilt_base.rb +1 -1
  20. data/lib/hamlit/html.rb +8 -0
  21. data/lib/hamlit/parser.rb +6 -2
  22. data/lib/hamlit/parser/haml_attribute_builder.rb +164 -0
  23. data/lib/hamlit/parser/haml_buffer.rb +20 -130
  24. data/lib/hamlit/parser/haml_compiler.rb +1 -553
  25. data/lib/hamlit/parser/haml_error.rb +29 -25
  26. data/lib/hamlit/parser/haml_escapable.rb +1 -0
  27. data/lib/hamlit/parser/haml_generator.rb +1 -0
  28. data/lib/hamlit/parser/haml_helpers.rb +41 -59
  29. data/lib/hamlit/parser/{haml_xss_mods.rb → haml_helpers/xss_mods.rb} +20 -15
  30. data/lib/hamlit/parser/haml_options.rb +53 -66
  31. data/lib/hamlit/parser/haml_parser.rb +103 -71
  32. data/lib/hamlit/parser/haml_temple_engine.rb +123 -0
  33. data/lib/hamlit/parser/haml_util.rb +10 -40
  34. data/lib/hamlit/rails_template.rb +1 -1
  35. data/lib/hamlit/string_splitter.rb +1 -0
  36. data/lib/hamlit/template.rb +1 -1
  37. data/lib/hamlit/temple_line_counter.rb +31 -0
  38. data/lib/hamlit/version.rb +1 -1
  39. metadata +10 -6
  40. data/lib/hamlit/parser/MIT-LICENSE +0 -20
  41. 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
 
@@ -14,7 +14,7 @@ end
14
14
  module Hamlit
15
15
  Template = Temple::Templates::Tilt.create(
16
16
  Hamlit::Engine,
17
- register_as: :haml,
17
+ register_as: [:haml, :hamlit],
18
18
  )
19
19
 
20
20
  module TemplateExtension
@@ -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.10.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.10.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-09-15 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.