hamlit 2.9.3 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|