hamlit 2.9.3 → 2.10.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -1
- data/CHANGELOG.md +26 -0
- data/Gemfile +6 -4
- data/REFERENCE.md +7 -1
- data/benchmark/dynamic_merger/benchmark.rb +25 -0
- data/benchmark/dynamic_merger/hello.haml +50 -0
- data/benchmark/dynamic_merger/hello.string +50 -0
- data/bin/bench +1 -1
- data/ext/hamlit/hamlit.c +2 -0
- data/hamlit.gemspec +4 -2
- data/lib/hamlit/attribute_builder.rb +3 -1
- data/lib/hamlit/attribute_compiler.rb +3 -1
- data/lib/hamlit/compiler/script_compiler.rb +4 -0
- data/lib/hamlit/compiler/tag_compiler.rb +4 -2
- data/lib/hamlit/dynamic_merger.rb +67 -0
- data/lib/hamlit/engine.rb +4 -3
- data/lib/hamlit/string_splitter.rb +9 -78
- data/lib/hamlit/utils.rb +3 -1
- data/lib/hamlit/version.rb +1 -1
- metadata +41 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 430b8a37db72797f5e809b12d83872c4d224fa61fea3c761b0f8862118b000c6
|
4
|
+
data.tar.gz: e7a8a2766ae263f8081c2209df44813bf16f69d07edaf02c5dd2826dd6345b46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa28798199b8c7981fa690420f5a045e8e1619f459e48fead5e85b100697f7a0bbb2dae0dc016c5e847c6a0e41fc10fdcdfc06de6950dfbdc3f5d3dabaf9eb51
|
7
|
+
data.tar.gz: b98674075aa2922d8bd76cb765a7f0d4df9f3b323387ddb2bb16c9eddbfa7db89ca1256b72c548c191b947669b530224c52cf743a81972677ed7f6fd123ca995
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -17,7 +17,9 @@ matrix:
|
|
17
17
|
env: TASK=test
|
18
18
|
- rvm: ruby-head
|
19
19
|
env: TASK=test
|
20
|
-
- rvm: jruby-9.
|
20
|
+
- rvm: jruby-9.2.8.0
|
21
|
+
env: TASK=test
|
22
|
+
- rvm: truffleruby
|
21
23
|
env: TASK=test
|
22
24
|
- rvm: 2.6.0
|
23
25
|
env: TASK=bench TEMPLATE=benchmark/boolean_attribute.haml,benchmark/class_attribute.haml,benchmark/id_attribute.haml,benchmark/data_attribute.haml,benchmark/common_attribute.haml
|
data/CHANGELOG.md
CHANGED
@@ -4,18 +4,44 @@ All notable changes to this project will be documented in this file. This
|
|
4
4
|
project adheres to [Semantic Versioning](http://semver.org/). This change log is based upon
|
5
5
|
[keep-a-changelog](https://github.com/olivierlacan/keep-a-changelog).
|
6
6
|
|
7
|
+
## [2.10.0](https://github.com/k0kubun/hamlit/compare/v2.9.5...v2.10.0) - 2019-09-15
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Optimize template rendering by exploiting string interpolation [#146](https://github.com/k0kubun/hamlit/issues/146)
|
12
|
+
- Exploiting pre-allocation of string interpolation introduced in Ruby 2.5 [ruby/ruby#1626](https://github.com/ruby/ruby/pull/1626)
|
13
|
+
- Require temple.gem >= 0.8.2
|
14
|
+
|
15
|
+
## [2.9.5](https://github.com/k0kubun/hamlit/compare/v2.9.4...v2.9.5) - 2019-09-08
|
16
|
+
|
17
|
+
### Added
|
18
|
+
|
19
|
+
- Supported `:plain` filter in truffleruby
|
20
|
+
|
21
|
+
## [2.9.4](https://github.com/k0kubun/hamlit/compare/v2.9.3...v2.9.4) - 2019-09-08
|
22
|
+
|
23
|
+
### Added
|
24
|
+
|
25
|
+
- Experimental support of truffleruby [#145](https://github.com/k0kubun/hamlit/issues/145).
|
26
|
+
|
7
27
|
## [2.9.3](https://github.com/k0kubun/hamlit/compare/v2.9.2...v2.9.3) - 2019-04-09
|
8
28
|
|
29
|
+
### Fixed
|
30
|
+
|
9
31
|
- Fix deprecation warning on Rails 6 [#138](https://github.com/k0kubun/hamlit/issues/138).
|
10
32
|
*Thanks to @r7kamura*
|
11
33
|
|
12
34
|
## [2.9.2](https://github.com/k0kubun/hamlit/compare/v2.9.1...v2.9.2) - 2018-11-30
|
13
35
|
|
36
|
+
### Fixed
|
37
|
+
|
14
38
|
- Fix possible `autoload` failure of dependency [#131](https://github.com/k0kubun/hamlit/issues/131).
|
15
39
|
*Thanks to @wimrijnders*
|
16
40
|
|
17
41
|
## [2.9.1](https://github.com/k0kubun/hamlit/compare/v2.9.0...v2.9.1) - 2018-11-01
|
18
42
|
|
43
|
+
### Added
|
44
|
+
|
19
45
|
- Start supporting JRuby [#100](https://github.com/k0kubun/hamlit/issues/100).
|
20
46
|
|
21
47
|
## [2.9.0](https://github.com/k0kubun/hamlit/compare/v2.8.10...v2.9.0) - 2018-10-16
|
data/Gemfile
CHANGED
@@ -14,15 +14,17 @@ end
|
|
14
14
|
|
15
15
|
gem 'benchmark-ips', '2.3.0'
|
16
16
|
gem 'maxitest'
|
17
|
+
gem 'pry'
|
17
18
|
|
18
19
|
if /java/ === RUBY_PLATFORM # JRuby
|
19
20
|
gem 'pandoc-ruby'
|
20
21
|
else
|
21
|
-
gem '
|
22
|
-
gem 'redcarpet', github: 'vmg/redcarpet' # To resolve circular require warning
|
22
|
+
gem 'redcarpet'
|
23
23
|
|
24
|
-
if RUBY_PLATFORM !~ /mswin|mingw/
|
25
|
-
|
24
|
+
if RUBY_PLATFORM !~ /mswin|mingw/ && RUBY_ENGINE != 'truffleruby'
|
25
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0') # Travis cannot compile ruby.h with C++
|
26
|
+
gem 'faml'
|
27
|
+
end
|
26
28
|
gem 'stackprof'
|
27
29
|
end
|
28
30
|
end
|
data/REFERENCE.md
CHANGED
99
99
|
(`foo` is not removed). This design allows us to reduce string concatenation and
|
100
100
|
is the only difference between Faml and Hamlit.
|
101
101
|
|
102
|
+
You may be also interested in
|
103
|
+
[hamlit/hamlit-boolean\_attributes](https://github.com/hamlit/hamlit-boolean_attributes).
|
104
|
+
|
102
105
|
## 5 Types of Attributes
|
103
106
|
|
104
107
|
Haml has 3 types of attributes: id, class and others.
|
@@ -181,7 +184,10 @@ defer reversed ismap seamless muted required autofocus novalidate formnovalidate
|
|
181
184
|
itemscope allowfullscreen default inert sortable truespeed typemustmatch
|
182
185
|
```
|
183
186
|
|
184
|
-
|
187
|
+
If you want to customize the list of boolean attributes, you can use
|
188
|
+
[hamlit/hamlit-boolean\_attributes](https://github.com/hamlit/hamlit-boolean_attributes).
|
189
|
+
|
190
|
+
"aria-\*" and "data-\*" are also regarded as boolean.
|
185
191
|
|
186
192
|
### other attributes
|
187
193
|
No hyphenation and boolean support. `false` is rendered as "false" (like Rails helpers).
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Original: https://github.com/amatsuda/string_template/blob/master/benchmark.rb
|
2
|
+
require 'benchmark_driver'
|
3
|
+
|
4
|
+
Benchmark.driver(repeat_count: 8) do |x|
|
5
|
+
x.prelude %{
|
6
|
+
require 'rails'
|
7
|
+
require 'action_view'
|
8
|
+
require 'string_template'
|
9
|
+
StringTemplate::Railtie.run_initializers
|
10
|
+
require 'hamlit'
|
11
|
+
Hamlit::Railtie.run_initializers
|
12
|
+
Hamlit::RailsTemplate.set_options(escape_html: false, generator: Temple::Generators::ArrayBuffer)
|
13
|
+
require 'action_view/base'
|
14
|
+
|
15
|
+
(view = Class.new(ActionView::Base).new(ActionView::LookupContext.new(''))).instance_variable_set(:@world, 'world!')
|
16
|
+
|
17
|
+
# compile template
|
18
|
+
hello = 'benchmark/dynamic_merger/hello'
|
19
|
+
view.render(template: hello, handlers: 'string')
|
20
|
+
view.render(template: hello, handlers: 'haml')
|
21
|
+
}
|
22
|
+
x.report 'string', %{ view.render(template: hello, handlers: 'string') }
|
23
|
+
x.report 'hamlit', %{ view.render(template: hello, handlers: 'haml') }
|
24
|
+
x.loop_count 100_000
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
hello, #{ @world }
|
2
|
+
hello, #{ @world }
|
3
|
+
hello, #{ @world }
|
4
|
+
hello, #{ @world }
|
5
|
+
hello, #{ @world }
|
6
|
+
hello, #{ @world }
|
7
|
+
hello, #{ @world }
|
8
|
+
hello, #{ @world }
|
9
|
+
hello, #{ @world }
|
10
|
+
hello, #{ @world }
|
11
|
+
hello, #{ @world }
|
12
|
+
hello, #{ @world }
|
13
|
+
hello, #{ @world }
|
14
|
+
hello, #{ @world }
|
15
|
+
hello, #{ @world }
|
16
|
+
hello, #{ @world }
|
17
|
+
hello, #{ @world }
|
18
|
+
hello, #{ @world }
|
19
|
+
hello, #{ @world }
|
20
|
+
hello, #{ @world }
|
21
|
+
hello, #{ @world }
|
22
|
+
hello, #{ @world }
|
23
|
+
hello, #{ @world }
|
24
|
+
hello, #{ @world }
|
25
|
+
hello, #{ @world }
|
26
|
+
hello, #{ @world }
|
27
|
+
hello, #{ @world }
|
28
|
+
hello, #{ @world }
|
29
|
+
hello, #{ @world }
|
30
|
+
hello, #{ @world }
|
31
|
+
hello, #{ @world }
|
32
|
+
hello, #{ @world }
|
33
|
+
hello, #{ @world }
|
34
|
+
hello, #{ @world }
|
35
|
+
hello, #{ @world }
|
36
|
+
hello, #{ @world }
|
37
|
+
hello, #{ @world }
|
38
|
+
hello, #{ @world }
|
39
|
+
hello, #{ @world }
|
40
|
+
hello, #{ @world }
|
41
|
+
hello, #{ @world }
|
42
|
+
hello, #{ @world }
|
43
|
+
hello, #{ @world }
|
44
|
+
hello, #{ @world }
|
45
|
+
hello, #{ @world }
|
46
|
+
hello, #{ @world }
|
47
|
+
hello, #{ @world }
|
48
|
+
hello, #{ @world }
|
49
|
+
hello, #{ @world }
|
50
|
+
hello, #{ @world }
|
@@ -0,0 +1,50 @@
|
|
1
|
+
hello, #{ @world }
|
2
|
+
hello, #{ @world }
|
3
|
+
hello, #{ @world }
|
4
|
+
hello, #{ @world }
|
5
|
+
hello, #{ @world }
|
6
|
+
hello, #{ @world }
|
7
|
+
hello, #{ @world }
|
8
|
+
hello, #{ @world }
|
9
|
+
hello, #{ @world }
|
10
|
+
hello, #{ @world }
|
11
|
+
hello, #{ @world }
|
12
|
+
hello, #{ @world }
|
13
|
+
hello, #{ @world }
|
14
|
+
hello, #{ @world }
|
15
|
+
hello, #{ @world }
|
16
|
+
hello, #{ @world }
|
17
|
+
hello, #{ @world }
|
18
|
+
hello, #{ @world }
|
19
|
+
hello, #{ @world }
|
20
|
+
hello, #{ @world }
|
21
|
+
hello, #{ @world }
|
22
|
+
hello, #{ @world }
|
23
|
+
hello, #{ @world }
|
24
|
+
hello, #{ @world }
|
25
|
+
hello, #{ @world }
|
26
|
+
hello, #{ @world }
|
27
|
+
hello, #{ @world }
|
28
|
+
hello, #{ @world }
|
29
|
+
hello, #{ @world }
|
30
|
+
hello, #{ @world }
|
31
|
+
hello, #{ @world }
|
32
|
+
hello, #{ @world }
|
33
|
+
hello, #{ @world }
|
34
|
+
hello, #{ @world }
|
35
|
+
hello, #{ @world }
|
36
|
+
hello, #{ @world }
|
37
|
+
hello, #{ @world }
|
38
|
+
hello, #{ @world }
|
39
|
+
hello, #{ @world }
|
40
|
+
hello, #{ @world }
|
41
|
+
hello, #{ @world }
|
42
|
+
hello, #{ @world }
|
43
|
+
hello, #{ @world }
|
44
|
+
hello, #{ @world }
|
45
|
+
hello, #{ @world }
|
46
|
+
hello, #{ @world }
|
47
|
+
hello, #{ @world }
|
48
|
+
hello, #{ @world }
|
49
|
+
hello, #{ @world }
|
50
|
+
hello, #{ @world }
|
data/bin/bench
CHANGED
@@ -25,7 +25,7 @@ class Bench < Thor
|
|
25
25
|
haml = File.read(file)
|
26
26
|
|
27
27
|
Benchmark.ips do |x|
|
28
|
-
x.report("haml v#{Haml::VERSION}") { Haml::Engine.new(haml, escape_html: true, escape_attrs: true
|
28
|
+
x.report("haml v#{Haml::VERSION}") { Haml::Engine.new(haml, escape_html: true, escape_attrs: true).precompiled }
|
29
29
|
x.report("faml v#{Faml::VERSION}") { Faml::Engine.new.call(haml) }
|
30
30
|
x.report("hamlit v#{Hamlit::VERSION}") { Hamlit::Engine.new.call(haml) }
|
31
31
|
x.compare!
|
data/ext/hamlit/hamlit.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <ruby/encoding.h>
|
3
|
+
#ifndef TRUFFLERUBY
|
3
4
|
#include "hescape.h"
|
4
5
|
#include "string.h"
|
5
6
|
|
@@ -551,3 +552,4 @@ Init_hamlit(void)
|
|
551
552
|
rb_const_set(mAttributeBuilder, id_space, rb_obj_freeze(rb_str_new_cstr(" ")));
|
552
553
|
rb_const_set(mAttributeBuilder, id_underscore, rb_obj_freeze(rb_str_new_cstr("_")));
|
553
554
|
}
|
555
|
+
#endif
|
data/hamlit.gemspec
CHANGED
@@ -26,10 +26,11 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.required_ruby_version = '>= 2.1.0'
|
27
27
|
end
|
28
28
|
|
29
|
-
spec.add_dependency 'temple', '>= 0.8.
|
29
|
+
spec.add_dependency 'temple', '>= 0.8.2'
|
30
30
|
spec.add_dependency 'thor'
|
31
31
|
spec.add_dependency 'tilt'
|
32
32
|
|
33
|
+
spec.add_development_dependency 'benchmark_driver'
|
33
34
|
spec.add_development_dependency 'bundler'
|
34
35
|
spec.add_development_dependency 'coffee-script'
|
35
36
|
spec.add_development_dependency 'erubi'
|
@@ -37,9 +38,10 @@ Gem::Specification.new do |spec|
|
|
37
38
|
spec.add_development_dependency 'less'
|
38
39
|
spec.add_development_dependency 'minitest-reporters', '~> 1.1'
|
39
40
|
spec.add_development_dependency 'rails', '>= 4.0.0'
|
40
|
-
spec.add_development_dependency 'rake'
|
41
|
+
spec.add_development_dependency 'rake'
|
41
42
|
spec.add_development_dependency 'rake-compiler'
|
42
43
|
spec.add_development_dependency 'sass'
|
43
44
|
spec.add_development_dependency 'slim'
|
45
|
+
spec.add_development_dependency 'string_template'
|
44
46
|
spec.add_development_dependency 'unindent'
|
45
47
|
end
|
@@ -9,7 +9,9 @@ module Hamlit::AttributeBuilder
|
|
9
9
|
itemscope allowfullscreen default inert sortable
|
10
10
|
truespeed typemustmatch download].freeze
|
11
11
|
|
12
|
-
|
12
|
+
# Java extension is not implemented for JRuby yet.
|
13
|
+
# TruffleRuby does not implement `rb_ary_sort_bang`, etc.
|
14
|
+
if /java/ === RUBY_PLATFORM || RUBY_ENGINE == 'truffleruby'
|
13
15
|
class << self
|
14
16
|
def build(escape_attrs, quote, format, object_ref, *hashes)
|
15
17
|
hashes << Hamlit::ObjectRef.parse(object_ref) if object_ref
|
@@ -14,7 +14,9 @@ module Hamlit
|
|
14
14
|
|
15
15
|
def compile(node)
|
16
16
|
hashes = []
|
17
|
-
|
17
|
+
if node.value[:object_ref] != :nil || !Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
|
18
|
+
return runtime_compile(node)
|
19
|
+
end
|
18
20
|
node.value[:attributes_hashes].each do |attribute_str|
|
19
21
|
hash = AttributeParser.parse(attribute_str)
|
20
22
|
return runtime_compile(node) unless hash
|
@@ -11,6 +11,10 @@ module Hamlit
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def compile(node, &block)
|
14
|
+
unless Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
|
15
|
+
return dynamic_compile(node, &block)
|
16
|
+
end
|
17
|
+
|
14
18
|
no_children = node.children.empty?
|
15
19
|
case
|
16
20
|
when no_children && node.value[:escape_interpolation]
|
@@ -28,8 +28,10 @@ module Hamlit
|
|
28
28
|
nil
|
29
29
|
when node.value[:parse]
|
30
30
|
return compile_interpolated_plain(node) if node.value[:escape_interpolation]
|
31
|
-
|
32
|
-
|
31
|
+
if Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
|
32
|
+
return delegate_optimization(node) if RubyExpression.string_literal?(node.value[:value])
|
33
|
+
return delegate_optimization(node) if Temple::StaticAnalyzer.static?(node.value[:value])
|
34
|
+
end
|
33
35
|
|
34
36
|
var = @identity.generate
|
35
37
|
[:multi,
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hamlit
|
3
|
+
# Compile [:multi, [:static, 'foo'], [:dynamic, 'bar']] to [:dynamic, '"foo#{bar}"']
|
4
|
+
class DynamicMerger < Temple::Filter
|
5
|
+
def on_multi(*exps)
|
6
|
+
exps = exps.dup
|
7
|
+
result = [:multi]
|
8
|
+
buffer = []
|
9
|
+
|
10
|
+
until exps.empty?
|
11
|
+
type, arg = exps.first
|
12
|
+
if type == :dynamic && arg.count("\n") == 0
|
13
|
+
buffer << exps.shift
|
14
|
+
elsif type == :static && exps.size > (count = arg.count("\n")) &&
|
15
|
+
exps[1, count].all? { |e| e == [:newline] }
|
16
|
+
(1 + count).times { buffer << exps.shift }
|
17
|
+
elsif type == :newline && exps.size > (count = count_newline(exps)) &&
|
18
|
+
exps[count].first == :static && count == exps[count].last.count("\n")
|
19
|
+
(count + 1).times { buffer << exps.shift }
|
20
|
+
else
|
21
|
+
result.concat(merge_dynamic(buffer))
|
22
|
+
buffer = []
|
23
|
+
result << compile(exps.shift)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
result.concat(merge_dynamic(buffer))
|
27
|
+
|
28
|
+
result.size == 2 ? result[1] : result
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def merge_dynamic(exps)
|
34
|
+
# Merge exps only when they have both :static and :dynamic
|
35
|
+
unless exps.any? { |type,| type == :static } && exps.any? { |type,| type == :dynamic }
|
36
|
+
return exps
|
37
|
+
end
|
38
|
+
|
39
|
+
strlit_body = String.new
|
40
|
+
exps.each do |type, arg|
|
41
|
+
case type
|
42
|
+
when :static
|
43
|
+
strlit_body << arg.dump.sub!(/\A"/, '').sub!(/"\z/, '').gsub('\n', "\n")
|
44
|
+
when :dynamic
|
45
|
+
strlit_body << "\#{#{arg}}"
|
46
|
+
when :newline
|
47
|
+
# newline is added by `gsub('\n', "\n")`
|
48
|
+
else
|
49
|
+
raise "unexpected type #{type.inspect} is given to #merge_dynamic"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
[[:dynamic, "%Q\0#{strlit_body}\0"]]
|
53
|
+
end
|
54
|
+
|
55
|
+
def count_newline(exps)
|
56
|
+
count = 0
|
57
|
+
exps.each do |exp|
|
58
|
+
if exp == [:newline]
|
59
|
+
count += 1
|
60
|
+
else
|
61
|
+
return count
|
62
|
+
end
|
63
|
+
end
|
64
|
+
return count
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/hamlit/engine.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
require 'temple'
|
3
3
|
require 'hamlit/parser'
|
4
4
|
require 'hamlit/compiler'
|
5
|
+
require 'hamlit/html'
|
5
6
|
require 'hamlit/escapable'
|
6
7
|
require 'hamlit/force_escapable'
|
7
|
-
require 'hamlit/
|
8
|
-
require 'hamlit/string_splitter'
|
8
|
+
require 'hamlit/dynamic_merger'
|
9
9
|
|
10
10
|
module Hamlit
|
11
11
|
class Engine < Temple::Engine
|
@@ -25,13 +25,14 @@ module Hamlit
|
|
25
25
|
use Parser
|
26
26
|
use Compiler
|
27
27
|
use HTML
|
28
|
-
|
28
|
+
filter :StringSplitter
|
29
29
|
filter :StaticAnalyzer
|
30
30
|
use Escapable
|
31
31
|
use ForceEscapable
|
32
32
|
filter :ControlFlow
|
33
33
|
filter :MultiFlattener
|
34
34
|
filter :StaticMerger
|
35
|
+
use DynamicMerger
|
35
36
|
use :Generator, -> { options[:generator] }
|
36
37
|
end
|
37
38
|
end
|
@@ -2,87 +2,18 @@ require 'ripper'
|
|
2
2
|
require 'hamlit/ruby_expression'
|
3
3
|
|
4
4
|
module Hamlit
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
[]
|
10
|
-
tokens = Ripper.lex(code.strip)
|
11
|
-
tokens.pop while tokens.last && %i[on_comment on_sp].include?(tokens.last[1])
|
12
|
-
|
13
|
-
if tokens.size < 2
|
14
|
-
raise Hamlit::InternalError.new("Expected token size >= 2 but got: #{tokens.size}")
|
15
|
-
end
|
16
|
-
compile_tokens!(exps, tokens)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def strip_quotes!(tokens)
|
23
|
-
_, type, beg_str = tokens.shift
|
24
|
-
if type != :on_tstring_beg
|
25
|
-
raise Hamlit::InternalError.new("Expected :on_tstring_beg but got: #{type}")
|
26
|
-
end
|
27
|
-
|
28
|
-
_, type, end_str = tokens.pop
|
29
|
-
if type != :on_tstring_end
|
30
|
-
raise Hamlit::InternalError.new("Expected :on_tstring_end but got: #{type}")
|
31
|
-
end
|
32
|
-
|
33
|
-
[beg_str, end_str]
|
34
|
-
end
|
35
|
-
|
36
|
-
def compile_tokens!(exps, tokens)
|
37
|
-
beg_str, end_str = strip_quotes!(tokens)
|
38
|
-
|
39
|
-
until tokens.empty?
|
40
|
-
_, type, str = tokens.shift
|
41
|
-
|
42
|
-
case type
|
43
|
-
when :on_tstring_content
|
44
|
-
exps << [:static, eval("#{beg_str}#{str}#{end_str}")]
|
45
|
-
when :on_embexpr_beg
|
46
|
-
embedded = shift_balanced_embexpr(tokens)
|
47
|
-
exps << [:dynamic, embedded] unless embedded.empty?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def shift_balanced_embexpr(tokens)
|
53
|
-
String.new.tap do |embedded|
|
54
|
-
embexpr_open = 1
|
55
|
-
|
56
|
-
until tokens.empty?
|
57
|
-
_, type, str = tokens.shift
|
58
|
-
case type
|
59
|
-
when :on_embexpr_beg
|
60
|
-
embexpr_open += 1
|
61
|
-
when :on_embexpr_end
|
62
|
-
embexpr_open -= 1
|
63
|
-
break if embexpr_open == 0
|
64
|
-
end
|
65
|
-
|
66
|
-
embedded << str
|
67
|
-
end
|
68
|
-
end
|
5
|
+
module StringSplitter
|
6
|
+
# `code` param must be valid string literal
|
7
|
+
def self.compile(code)
|
8
|
+
unless Ripper.respond_to?(:lex) # truffleruby doesn't have Ripper.lex
|
9
|
+
return [[:dynamic, code]]
|
69
10
|
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def on_dynamic(code)
|
73
|
-
return [:dynamic, code] unless RubyExpression.string_literal?(code)
|
74
|
-
return [:dynamic, code] if code.include?("\n")
|
75
11
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
temple << [:static, content]
|
81
|
-
when :dynamic
|
82
|
-
temple << on_dynamic(content)
|
83
|
-
end
|
12
|
+
begin
|
13
|
+
Temple::Filters::StringSplitter.compile(code)
|
14
|
+
rescue Temple::FilterError => e
|
15
|
+
raise Hamlit::InternalError.new(e.message)
|
84
16
|
end
|
85
|
-
temple
|
86
17
|
end
|
87
18
|
end
|
88
19
|
end
|
data/lib/hamlit/utils.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Hamlit
|
3
3
|
module Utils
|
4
|
-
|
4
|
+
# Java extension is not implemented for JRuby yet.
|
5
|
+
# TruffleRuby does not implement `rb_ary_sort_bang`, etc.
|
6
|
+
if /java/ === RUBY_PLATFORM || RUBY_ENGINE == 'truffleruby'
|
5
7
|
require 'cgi/escape'
|
6
8
|
|
7
9
|
def self.escape_html(html)
|
data/lib/hamlit/version.rb
CHANGED
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.
|
4
|
+
version: 2.10.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-
|
11
|
+
date: 2019-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: temple
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.8.
|
19
|
+
version: 0.8.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.8.
|
26
|
+
version: 0.8.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: benchmark_driver
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,16 +168,16 @@ dependencies:
|
|
154
168
|
name: rake
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
|
-
- - "
|
171
|
+
- - ">="
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
173
|
+
version: '0'
|
160
174
|
type: :development
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
|
-
- - "
|
178
|
+
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
180
|
+
version: '0'
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: rake-compiler
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,6 +220,20 @@ dependencies:
|
|
206
220
|
- - ">="
|
207
221
|
- !ruby/object:Gem::Version
|
208
222
|
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: string_template
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
238
|
name: unindent
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -247,6 +275,9 @@ files:
|
|
247
275
|
- benchmark/dynamic_attributes/data_attribute.haml
|
248
276
|
- benchmark/dynamic_attributes/id_attribute.haml
|
249
277
|
- benchmark/dynamic_boolean_attribute.haml
|
278
|
+
- benchmark/dynamic_merger/benchmark.rb
|
279
|
+
- benchmark/dynamic_merger/hello.haml
|
280
|
+
- benchmark/dynamic_merger/hello.string
|
250
281
|
- benchmark/etc/attribute_builder.haml
|
251
282
|
- benchmark/etc/real_sample.haml
|
252
283
|
- benchmark/etc/real_sample.rb
|
@@ -290,6 +321,7 @@ files:
|
|
290
321
|
- lib/hamlit/compiler/script_compiler.rb
|
291
322
|
- lib/hamlit/compiler/silent_script_compiler.rb
|
292
323
|
- lib/hamlit/compiler/tag_compiler.rb
|
324
|
+
- lib/hamlit/dynamic_merger.rb
|
293
325
|
- lib/hamlit/engine.rb
|
294
326
|
- lib/hamlit/error.rb
|
295
327
|
- lib/hamlit/escapable.rb
|
@@ -353,8 +385,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
353
385
|
- !ruby/object:Gem::Version
|
354
386
|
version: '0'
|
355
387
|
requirements: []
|
356
|
-
|
357
|
-
rubygems_version: 2.7.6
|
388
|
+
rubygems_version: 3.0.3
|
358
389
|
signing_key:
|
359
390
|
specification_version: 4
|
360
391
|
summary: High Performance Haml Implementation
|