hamlit 0.1.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 +7 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +34 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +23 -0
- data/README.md +45 -0
- data/Rakefile +34 -0
- data/benchmarks/benchmark.rb +94 -0
- data/benchmarks/context.rb +13 -0
- data/benchmarks/view.erb +23 -0
- data/benchmarks/view.haml +18 -0
- data/benchmarks/view.rbhtml +23 -0
- data/benchmarks/view.slim +17 -0
- data/bin/hamlit +6 -0
- data/hamlit.gemspec +40 -0
- data/lib/hamlit/attribute.rb +31 -0
- data/lib/hamlit/cli.rb +89 -0
- data/lib/hamlit/compiler.rb +24 -0
- data/lib/hamlit/compilers/attributes.rb +78 -0
- data/lib/hamlit/compilers/comment.rb +13 -0
- data/lib/hamlit/compilers/doctype.rb +39 -0
- data/lib/hamlit/compilers/dynamic.rb +9 -0
- data/lib/hamlit/compilers/filter.rb +53 -0
- data/lib/hamlit/compilers/new_attribute.rb +107 -0
- data/lib/hamlit/compilers/old_attribute.rb +147 -0
- data/lib/hamlit/compilers/preserve.rb +10 -0
- data/lib/hamlit/compilers/script.rb +31 -0
- data/lib/hamlit/compilers/strip.rb +30 -0
- data/lib/hamlit/compilers/text.rb +15 -0
- data/lib/hamlit/concerns/attribute_builder.rb +21 -0
- data/lib/hamlit/concerns/balanceable.rb +59 -0
- data/lib/hamlit/concerns/deprecation.rb +20 -0
- data/lib/hamlit/concerns/error.rb +27 -0
- data/lib/hamlit/concerns/escapable.rb +17 -0
- data/lib/hamlit/concerns/included.rb +28 -0
- data/lib/hamlit/concerns/indentable.rb +53 -0
- data/lib/hamlit/concerns/line_reader.rb +60 -0
- data/lib/hamlit/concerns/registerable.rb +24 -0
- data/lib/hamlit/concerns/ripperable.rb +20 -0
- data/lib/hamlit/concerns/string_interpolation.rb +48 -0
- data/lib/hamlit/engine.rb +42 -0
- data/lib/hamlit/filters/base.rb +44 -0
- data/lib/hamlit/filters/coffee.rb +12 -0
- data/lib/hamlit/filters/css.rb +34 -0
- data/lib/hamlit/filters/erb.rb +11 -0
- data/lib/hamlit/filters/escaped.rb +19 -0
- data/lib/hamlit/filters/javascript.rb +34 -0
- data/lib/hamlit/filters/less.rb +12 -0
- data/lib/hamlit/filters/markdown.rb +11 -0
- data/lib/hamlit/filters/plain.rb +21 -0
- data/lib/hamlit/filters/preserve.rb +11 -0
- data/lib/hamlit/filters/ruby.rb +11 -0
- data/lib/hamlit/filters/sass.rb +12 -0
- data/lib/hamlit/filters/scss.rb +12 -0
- data/lib/hamlit/filters/tilt.rb +41 -0
- data/lib/hamlit/helpers.rb +38 -0
- data/lib/hamlit/html/pretty.rb +49 -0
- data/lib/hamlit/html/ugly.rb +10 -0
- data/lib/hamlit/parser.rb +123 -0
- data/lib/hamlit/parsers/attribute.rb +52 -0
- data/lib/hamlit/parsers/comment.rb +27 -0
- data/lib/hamlit/parsers/doctype.rb +18 -0
- data/lib/hamlit/parsers/filter.rb +18 -0
- data/lib/hamlit/parsers/multiline.rb +54 -0
- data/lib/hamlit/parsers/script.rb +93 -0
- data/lib/hamlit/parsers/tag.rb +71 -0
- data/lib/hamlit/parsers/text.rb +11 -0
- data/lib/hamlit/parsers/whitespace.rb +38 -0
- data/lib/hamlit/railtie.rb +21 -0
- data/lib/hamlit/template.rb +9 -0
- data/lib/hamlit/version.rb +3 -0
- data/lib/hamlit.rb +8 -0
- data/spec/Rakefile +79 -0
- data/spec/hamlit/compilers/script_spec.rb +46 -0
- data/spec/hamlit/engine/comment_spec.rb +29 -0
- data/spec/hamlit/engine/doctype_spec.rb +19 -0
- data/spec/hamlit/engine/error_spec.rb +47 -0
- data/spec/hamlit/engine/multiline_spec.rb +44 -0
- data/spec/hamlit/engine/new_attribute_spec.rb +19 -0
- data/spec/hamlit/engine/old_attributes_spec.rb +85 -0
- data/spec/hamlit/engine/preservation_spec.rb +11 -0
- data/spec/hamlit/engine/script_spec.rb +87 -0
- data/spec/hamlit/engine/silent_script_spec.rb +135 -0
- data/spec/hamlit/engine/tag_spec.rb +210 -0
- data/spec/hamlit/engine/text_spec.rb +29 -0
- data/spec/hamlit/engine_spec.rb +20 -0
- data/spec/hamlit/filters/coffee_spec.rb +41 -0
- data/spec/hamlit/filters/css_spec.rb +33 -0
- data/spec/hamlit/filters/erb_spec.rb +16 -0
- data/spec/hamlit/filters/javascript_spec.rb +82 -0
- data/spec/hamlit/filters/less_spec.rb +22 -0
- data/spec/hamlit/filters/markdown_spec.rb +28 -0
- data/spec/hamlit/filters/ruby_spec.rb +24 -0
- data/spec/hamlit/filters/sass_spec.rb +37 -0
- data/spec/hamlit/filters/scss_spec.rb +21 -0
- data/spec/hamlit/ugly_spec.rb +912 -0
- data/spec/rails/.gitignore +17 -0
- data/spec/rails/.rspec +2 -0
- data/spec/rails/Gemfile +19 -0
- data/spec/rails/Gemfile.lock +177 -0
- data/spec/rails/README.rdoc +28 -0
- data/spec/rails/Rakefile +6 -0
- data/spec/rails/app/assets/images/.keep +0 -0
- data/spec/rails/app/assets/javascripts/application.js +15 -0
- data/spec/rails/app/assets/stylesheets/application.css +15 -0
- data/spec/rails/app/controllers/application_controller.rb +8 -0
- data/spec/rails/app/controllers/concerns/.keep +0 -0
- data/spec/rails/app/controllers/users_controller.rb +20 -0
- data/spec/rails/app/helpers/application_helper.rb +2 -0
- data/spec/rails/app/mailers/.keep +0 -0
- data/spec/rails/app/models/.keep +0 -0
- data/spec/rails/app/models/concerns/.keep +0 -0
- data/spec/rails/app/views/application/index.html.haml +15 -0
- data/spec/rails/app/views/layouts/application.html.haml +12 -0
- data/spec/rails/app/views/users/capture.html.haml +5 -0
- data/spec/rails/app/views/users/capture_haml.html.haml +5 -0
- data/spec/rails/app/views/users/form.html.haml +2 -0
- data/spec/rails/app/views/users/helpers.html.haml +1 -0
- data/spec/rails/app/views/users/index.html.haml +9 -0
- data/spec/rails/app/views/users/safe_buffer.html.haml +4 -0
- data/spec/rails/bin/bundle +3 -0
- data/spec/rails/bin/rails +8 -0
- data/spec/rails/bin/rake +8 -0
- data/spec/rails/bin/setup +29 -0
- data/spec/rails/bin/spring +15 -0
- data/spec/rails/config/application.rb +34 -0
- data/spec/rails/config/boot.rb +3 -0
- data/spec/rails/config/database.yml +25 -0
- data/spec/rails/config/environment.rb +5 -0
- data/spec/rails/config/environments/development.rb +41 -0
- data/spec/rails/config/environments/production.rb +79 -0
- data/spec/rails/config/environments/test.rb +42 -0
- data/spec/rails/config/initializers/assets.rb +11 -0
- data/spec/rails/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails/config/initializers/cookies_serializer.rb +3 -0
- data/spec/rails/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/rails/config/initializers/inflections.rb +16 -0
- data/spec/rails/config/initializers/mime_types.rb +4 -0
- data/spec/rails/config/initializers/session_store.rb +3 -0
- data/spec/rails/config/initializers/wrap_parameters.rb +14 -0
- data/spec/rails/config/locales/en.yml +23 -0
- data/spec/rails/config/routes.rb +13 -0
- data/spec/rails/config/secrets.yml +22 -0
- data/spec/rails/config.ru +4 -0
- data/spec/rails/db/schema.rb +16 -0
- data/spec/rails/db/seeds.rb +7 -0
- data/spec/rails/lib/assets/.keep +0 -0
- data/spec/rails/lib/tasks/.keep +0 -0
- data/spec/rails/log/.keep +0 -0
- data/spec/rails/public/404.html +67 -0
- data/spec/rails/public/422.html +67 -0
- data/spec/rails/public/500.html +66 -0
- data/spec/rails/public/favicon.ico +0 -0
- data/spec/rails/public/robots.txt +5 -0
- data/spec/rails/spec/hamlit_spec.rb +87 -0
- data/spec/rails/spec/rails_helper.rb +56 -0
- data/spec/rails/spec/spec_helper.rb +91 -0
- data/spec/rails/vendor/assets/javascripts/.keep +0 -0
- data/spec/rails/vendor/assets/stylesheets/.keep +0 -0
- data/spec/spec_helper.rb +48 -0
- metadata +560 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 8594e7acaa30584a12d923e97b4b7a21b407f054
|
|
4
|
+
data.tar.gz: 03eb5ce30ba76ac8c46df2f7b62dff6674569d22
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f32944cc0f55a3f4aad6c4bf0bc52e36e7a1a24dd57963af0bbf575c1fa50d542d6e63d690c9067d65134fa2ae2f9877b770ae96357ae64d5b91977c05b6590a
|
|
7
|
+
data.tar.gz: fb37bdf58c61dfcd68807df744ca705b865225074fd147bbd339560cf4242ec1713977d02b2084d924343e8b4ec08383534934379dc47fd2cc99ade73f486a72
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
language: ruby
|
|
2
|
+
rvm:
|
|
3
|
+
- 2.0.0
|
|
4
|
+
- 2.1
|
|
5
|
+
- 2.2
|
|
6
|
+
sudo: false
|
|
7
|
+
cache: bundler
|
|
8
|
+
script:
|
|
9
|
+
- "bundle exec rake $TASK"
|
|
10
|
+
gemfile:
|
|
11
|
+
- Gemfile
|
|
12
|
+
- spec/rails/Gemfile
|
|
13
|
+
env:
|
|
14
|
+
- TASK=spec
|
|
15
|
+
- TASK=rails:spec
|
|
16
|
+
- TASK=bench TIME=10
|
|
17
|
+
matrix:
|
|
18
|
+
allow_failures:
|
|
19
|
+
- env: TASK=bench TIME=10
|
|
20
|
+
exclude:
|
|
21
|
+
- env: TASK=spec
|
|
22
|
+
gemfile: spec/rails/Gemfile
|
|
23
|
+
- env: TASK=rails:spec
|
|
24
|
+
gemfile: Gemfile
|
|
25
|
+
- env: TASK=bench TIME=10
|
|
26
|
+
gemfile: spec/rails/Gemfile
|
|
27
|
+
- rvm: 2.1
|
|
28
|
+
env: TASK=rails:spec
|
|
29
|
+
- rvm: 2.1
|
|
30
|
+
env: TASK=bench TIME=10
|
|
31
|
+
- rvm: 2.0.0
|
|
32
|
+
env: TASK=rails:spec
|
|
33
|
+
- rvm: 2.0.0
|
|
34
|
+
env: TASK=bench TIME=10
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright (c) 2015 Takashi Kokubun
|
|
2
|
+
Copyright (c) 2006-2009 Hampton Catlin and Natalie Weizenbaum
|
|
3
|
+
|
|
4
|
+
MIT License
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
7
|
+
a copy of this software and associated documentation files (the
|
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
12
|
+
the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be
|
|
15
|
+
included in all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Hamlit [](https://travis-ci.org/k0kubun/hamlit)
|
|
2
|
+
|
|
3
|
+
Hamlit is a high performance [haml](https://github.com/haml/haml) implementation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'hamlit'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
or just replace `gem "haml"` with `gem "hamlit"`.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
### Fast rendering
|
|
17
|
+
|
|
18
|
+
Hamlit's rendering is **8.47x times faster** than original haml.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
hamlit: 133922.9 i/s
|
|
22
|
+
erubis: 123464.1 i/s - 1.08x slower
|
|
23
|
+
slim: 110404.3 i/s - 1.21x slower
|
|
24
|
+
faml: 92009.3 i/s - 1.46x slower
|
|
25
|
+
haml: 15810.4 i/s - 8.47x slower
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
[This benchmark](https://github.com/k0kubun/hamlit/blob/74ede1101f228828e343ceb1af481c45eaf0a1dd/benchmarks/benchmark.rb)
|
|
29
|
+
is the same as [slim-template/slim](https://github.com/slim-template/slim)'s one for fairness.
|
|
30
|
+
([The result on travis CI](https://travis-ci.org/k0kubun/hamlit/jobs/56403724))
|
|
31
|
+
|
|
32
|
+
### Better parser
|
|
33
|
+
|
|
34
|
+
Haml's attribute parser is not so good. For example, raises syntax error for `%a{ b: '}' }`.
|
|
35
|
+
Hamlit's attribute parser is implemented with Ripper, which is an official lexer for Ruby,
|
|
36
|
+
so it can able to parse such an attribute.
|
|
37
|
+
|
|
38
|
+
### Passing haml-spec
|
|
39
|
+
|
|
40
|
+
[haml/haml-spec](https://github.com/haml/haml-spec) is a basic suite of tests for Haml interpreters.
|
|
41
|
+
For all test cases in haml-spec, Hamlit behaves the same as Haml (ugly mode only, which is used on production).
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
MIT License
|
data/Rakefile
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
2
|
+
|
|
3
|
+
desc 'Run benchmarks'
|
|
4
|
+
task :bench do
|
|
5
|
+
exit system('bundle exec ruby benchmarks/benchmark.rb')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
desc 'Run RSpec code examples'
|
|
9
|
+
task :spec do
|
|
10
|
+
exit system('bundle exec rspec --pattern spec/hamlit/**{,/\*/\*\*\}/\*_spec.rb')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
namespace :spec do
|
|
14
|
+
namespace :update do
|
|
15
|
+
desc 'Generate converted ugly haml-spec'
|
|
16
|
+
task :ugly do
|
|
17
|
+
system('cd spec && rake ugly')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc 'Generate converted pretty haml-spec'
|
|
21
|
+
task :pretty do
|
|
22
|
+
system('cd spec && rake pretty')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
namespace :rails do
|
|
28
|
+
desc 'Run Rails specs'
|
|
29
|
+
task :spec do
|
|
30
|
+
exit system('cd spec/rails && rake spec')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
task default: [:spec, 'rails:spec']
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'), File.dirname(__FILE__))
|
|
4
|
+
|
|
5
|
+
require_relative './context'
|
|
6
|
+
require 'benchmark/ips'
|
|
7
|
+
|
|
8
|
+
require 'erb'
|
|
9
|
+
require 'erubis'
|
|
10
|
+
require 'faml'
|
|
11
|
+
require 'haml'
|
|
12
|
+
require 'slim'
|
|
13
|
+
require 'tenjin'
|
|
14
|
+
require 'tilt'
|
|
15
|
+
require 'hamlit'
|
|
16
|
+
|
|
17
|
+
class Benchmarks
|
|
18
|
+
def initialize(time)
|
|
19
|
+
@time = time
|
|
20
|
+
@benches = []
|
|
21
|
+
@versions = {}
|
|
22
|
+
|
|
23
|
+
@erb_code = File.read(File.dirname(__FILE__) + '/view.erb')
|
|
24
|
+
@haml_code = File.read(File.dirname(__FILE__) + '/view.haml')
|
|
25
|
+
@slim_code = File.read(File.dirname(__FILE__) + '/view.slim')
|
|
26
|
+
@rbhtml_path = File.dirname(__FILE__) + '/view.rbhtml'
|
|
27
|
+
|
|
28
|
+
init_compiled_benches
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def init_compiled_benches
|
|
32
|
+
erb = ERB.new(@erb_code)
|
|
33
|
+
erubis = Erubis::Eruby.new(@erb_code)
|
|
34
|
+
fast_erubis = Erubis::FastEruby.new(@erb_code)
|
|
35
|
+
haml_ugly = Haml::Engine.new(@haml_code, format: :html5, ugly: true)
|
|
36
|
+
tenjin = Tenjin::Engine.new.get_template(@rbhtml_path)
|
|
37
|
+
|
|
38
|
+
context = Context.new
|
|
39
|
+
|
|
40
|
+
haml_ugly.def_method(context, :run_haml_ugly)
|
|
41
|
+
context.instance_eval %{
|
|
42
|
+
def run_erb; #{erb.src}; end
|
|
43
|
+
def run_erubis; #{erubis.src}; end
|
|
44
|
+
def run_temple_erb; #{Temple::ERB::Engine.new.call @erb_code}; end
|
|
45
|
+
def run_fast_erubis; #{fast_erubis.src}; end
|
|
46
|
+
def run_slim_ugly; #{Slim::Engine.new.call @slim_code}; end
|
|
47
|
+
def run_faml; #{Faml::Engine.new.call @haml_code}; end
|
|
48
|
+
def run_tenjin; _buf = ''; #{tenjin.script}; end
|
|
49
|
+
def run_hamlit; #{Hamlit::Engine.new.call @haml_code}; end
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
bench('hamlit', Hamlit::VERSION) { context.run_hamlit }
|
|
53
|
+
bench('erubis', Erubis::VERSION) { context.run_erubis }
|
|
54
|
+
bench('slim', Slim::VERSION) { context.run_slim_ugly }
|
|
55
|
+
bench('faml', Faml::VERSION) { context.run_faml }
|
|
56
|
+
bench('haml', Haml::VERSION) { context.run_haml_ugly }
|
|
57
|
+
|
|
58
|
+
if ENV['ALL']
|
|
59
|
+
erb_version = ERB.version.match(/\[([^ ]+)/)[1]
|
|
60
|
+
bench('tenjin', Tenjin::RELEASE) { context.run_tenjin }
|
|
61
|
+
bench('fast erubis', Erubis::VERSION) { context.run_fast_erubis }
|
|
62
|
+
bench('temple erb', Temple::VERSION) { context.run_temple_erb }
|
|
63
|
+
bench('erb', erb_version) { context.run_erb }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def run
|
|
68
|
+
show_versions
|
|
69
|
+
result = Benchmark.ips do |x|
|
|
70
|
+
x.config(time: @time, warmup: 2)
|
|
71
|
+
@benches.each do |name, block|
|
|
72
|
+
x.report(name, &block)
|
|
73
|
+
end
|
|
74
|
+
x.compare!
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def bench(name, version, &block)
|
|
81
|
+
@benches.push([name, block])
|
|
82
|
+
@versions[name] = version
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def show_versions
|
|
86
|
+
puts 'Versions ' + '-' * 40
|
|
87
|
+
@versions.each do |name, version|
|
|
88
|
+
printf "%20s %10s\n", name, "v#{version}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
time = (ENV['TIME'] || 5).to_i
|
|
94
|
+
Benchmarks.new(time).run
|
data/benchmarks/view.erb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE HTML>
|
|
2
|
+
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<title>Simple Benchmark</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<h1><%= header %></h1>
|
|
9
|
+
<% unless item.empty? %>
|
|
10
|
+
<ul>
|
|
11
|
+
<% for i in item %>
|
|
12
|
+
<% if i[:current] %>
|
|
13
|
+
<li><strong><%= i[:name] %></strong></li>
|
|
14
|
+
<% else %>
|
|
15
|
+
<li><a href="<%= i[:url] %>"><%= i[:name] %></a></li>
|
|
16
|
+
<% end %>
|
|
17
|
+
<% end %>
|
|
18
|
+
</ul>
|
|
19
|
+
<% else %>
|
|
20
|
+
<p>The list is empty.</p>
|
|
21
|
+
<% end %>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
!!! html
|
|
2
|
+
|
|
3
|
+
%html
|
|
4
|
+
%head
|
|
5
|
+
%title Simple Benchmark
|
|
6
|
+
%body
|
|
7
|
+
%h1= header
|
|
8
|
+
- unless item.empty?
|
|
9
|
+
%ul
|
|
10
|
+
- for i in item
|
|
11
|
+
- if i[:current]
|
|
12
|
+
%li
|
|
13
|
+
%strong= i[:name]
|
|
14
|
+
- else
|
|
15
|
+
%li
|
|
16
|
+
%a{:href => i[:url]}= i[:name]
|
|
17
|
+
- else
|
|
18
|
+
%p The list is empty.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE HTML>
|
|
2
|
+
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<title>Simple Benchmark</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<h1>#{ header }</h1>
|
|
9
|
+
<?rb unless item.empty? ?>
|
|
10
|
+
<ul>
|
|
11
|
+
<?rb for i in item ?>
|
|
12
|
+
<?rb if i[:current] ?>
|
|
13
|
+
<li><strong>#{ i[:name] }</strong></li>
|
|
14
|
+
<?rb else ?>
|
|
15
|
+
<li><a href="#{ i[:url] }">#{ i[:name] }</a></li>
|
|
16
|
+
<?rb end ?>
|
|
17
|
+
<?rb end ?>
|
|
18
|
+
</ul>
|
|
19
|
+
<?rb else ?>
|
|
20
|
+
<p>The list is empty.</p>
|
|
21
|
+
<?rb end ?>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
doctype html
|
|
2
|
+
html
|
|
3
|
+
head
|
|
4
|
+
title Simple Benchmark
|
|
5
|
+
body
|
|
6
|
+
h1 == header
|
|
7
|
+
- unless item.empty?
|
|
8
|
+
ul
|
|
9
|
+
- for i in item
|
|
10
|
+
- if i[:current]
|
|
11
|
+
li
|
|
12
|
+
strong == i[:name]
|
|
13
|
+
- else
|
|
14
|
+
li
|
|
15
|
+
a href==i[:url] == i[:name]
|
|
16
|
+
- else
|
|
17
|
+
p The list is empty.
|
data/bin/hamlit
ADDED
data/hamlit.gemspec
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'hamlit/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "hamlit"
|
|
8
|
+
spec.version = Hamlit::VERSION
|
|
9
|
+
spec.authors = ["Takashi Kokubun"]
|
|
10
|
+
spec.email = ["takashikkbn@gmail.com"]
|
|
11
|
+
spec.summary = %q{Yet another haml implementation}
|
|
12
|
+
spec.description = %q{Yet another haml implementation}
|
|
13
|
+
spec.homepage = "https://github.com/k0kubun/hamlit"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_dependency "temple"
|
|
22
|
+
spec.add_dependency "thor"
|
|
23
|
+
spec.add_dependency "tilt"
|
|
24
|
+
spec.add_development_dependency "benchmark-ips"
|
|
25
|
+
spec.add_development_dependency "bundler"
|
|
26
|
+
spec.add_development_dependency "coffee-script"
|
|
27
|
+
spec.add_development_dependency "erubis"
|
|
28
|
+
spec.add_development_dependency "faml"
|
|
29
|
+
spec.add_development_dependency "haml"
|
|
30
|
+
spec.add_development_dependency "less"
|
|
31
|
+
spec.add_development_dependency "pry"
|
|
32
|
+
spec.add_development_dependency "rake"
|
|
33
|
+
spec.add_development_dependency "redcarpet"
|
|
34
|
+
spec.add_development_dependency "rspec", ">= 3"
|
|
35
|
+
spec.add_development_dependency "sass"
|
|
36
|
+
spec.add_development_dependency "slim"
|
|
37
|
+
spec.add_development_dependency "tenjin"
|
|
38
|
+
spec.add_development_dependency "therubyracer"
|
|
39
|
+
spec.add_development_dependency "unindent"
|
|
40
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'hamlit/concerns/attribute_builder'
|
|
2
|
+
require 'temple/utils'
|
|
3
|
+
|
|
4
|
+
# Hamlit::Attribute is a module to compile old-style attributes which
|
|
5
|
+
# can be compiled only on runtime. If you write old-style attributes
|
|
6
|
+
# which is not valid as Ruby hash, the attributes are compiled on runtime.
|
|
7
|
+
#
|
|
8
|
+
# Note that you should avoid writing such a template for performance.
|
|
9
|
+
module Hamlit
|
|
10
|
+
class Attribute
|
|
11
|
+
include Concerns::AttributeBuilder
|
|
12
|
+
|
|
13
|
+
def self.build(quote, attributes)
|
|
14
|
+
builder = self.new(quote)
|
|
15
|
+
builder.build(attributes)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(quote)
|
|
19
|
+
@quote = quote
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def build(attributes)
|
|
23
|
+
result = ''
|
|
24
|
+
flatten_attributes(attributes).each do |key, value|
|
|
25
|
+
escaped = Temple::Utils.escape_html(value)
|
|
26
|
+
result += " #{key}=#{@quote}#{escaped}#{@quote}"
|
|
27
|
+
end
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/hamlit/cli.rb
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'hamlit'
|
|
2
|
+
require 'thor'
|
|
3
|
+
|
|
4
|
+
module Hamlit
|
|
5
|
+
class CLI < Thor
|
|
6
|
+
IGNORED_COMPILERS = ['HTML'].freeze
|
|
7
|
+
|
|
8
|
+
desc 'render HAML', 'Render haml template'
|
|
9
|
+
option :ugly, type: :boolean, aliases: ['-u']
|
|
10
|
+
def render(file)
|
|
11
|
+
code = generate_code(file)
|
|
12
|
+
puts eval(code)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'compile HAML', 'Show generated rendering code'
|
|
16
|
+
option :ugly, type: :boolean, aliases: ['-u']
|
|
17
|
+
def compile(file)
|
|
18
|
+
code = generate_code(file)
|
|
19
|
+
puts code
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
desc 'temple HAML', 'Show a compile result of hamlit AST'
|
|
23
|
+
option :ugly, type: :boolean, aliases: ['-u']
|
|
24
|
+
def temple(file)
|
|
25
|
+
pp generate_temple_ast(file)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
desc 'parse HAML', 'Show parse result'
|
|
29
|
+
def parse(file)
|
|
30
|
+
pp generate_hamlit_ast(file)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# Flexible default_task, compatible with haml's CLI
|
|
36
|
+
def method_missing(*args)
|
|
37
|
+
return super(*args) if args.length > 1
|
|
38
|
+
|
|
39
|
+
render(args.first.to_s)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def generate_code(file)
|
|
43
|
+
template = File.read(file)
|
|
44
|
+
Hamlit::Engine.new(options).call(template)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def generate_temple_ast(file)
|
|
48
|
+
chain = Hamlit::Engine.chain.map(&:first).map(&:to_s)
|
|
49
|
+
compilers = chain.select do |compiler|
|
|
50
|
+
compiler =~ /\AHamlit::/ && !ignored_compilers.include?(compiler)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
template = File.read(file)
|
|
54
|
+
compilers.inject(template) do |exp, compiler|
|
|
55
|
+
Module.const_get(compiler).new(options).call(exp)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def generate_hamlit_ast(file)
|
|
60
|
+
template = File.read(file)
|
|
61
|
+
Hamlit::Parser.new.call(template)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Enable colored pretty printing only for development environment.
|
|
65
|
+
# I don't think it is a good idea to add pry as runtime dependency
|
|
66
|
+
# just for debug color printing.
|
|
67
|
+
def pp(arg)
|
|
68
|
+
begin
|
|
69
|
+
require 'pry'
|
|
70
|
+
Pry::ColorPrinter.pp(arg)
|
|
71
|
+
rescue LoadError
|
|
72
|
+
require 'pp'
|
|
73
|
+
super(arg)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def ignored_compilers
|
|
78
|
+
IGNORED_COMPILERS.map { |name| "Hamlit::#{name}" }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def options
|
|
82
|
+
symbolize_keys(super)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def symbolize_keys(hash)
|
|
86
|
+
{}.tap { |h| hash.each { |k, v| h[k.to_sym] = v } }
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'hamlit/compilers/attributes'
|
|
2
|
+
require 'hamlit/compilers/comment'
|
|
3
|
+
require 'hamlit/compilers/doctype'
|
|
4
|
+
require 'hamlit/compilers/dynamic'
|
|
5
|
+
require 'hamlit/compilers/filter'
|
|
6
|
+
require 'hamlit/compilers/preserve'
|
|
7
|
+
require 'hamlit/compilers/script'
|
|
8
|
+
require 'hamlit/compilers/strip'
|
|
9
|
+
require 'hamlit/compilers/text'
|
|
10
|
+
require 'temple/html/filter'
|
|
11
|
+
|
|
12
|
+
module Hamlit
|
|
13
|
+
class Compiler < Temple::HTML::Filter
|
|
14
|
+
include Compilers::Attributes
|
|
15
|
+
include Compilers::Comment
|
|
16
|
+
include Compilers::Doctype
|
|
17
|
+
include Compilers::Dynamic
|
|
18
|
+
include Compilers::Filter
|
|
19
|
+
include Compilers::Preserve
|
|
20
|
+
include Compilers::Script
|
|
21
|
+
include Compilers::Strip
|
|
22
|
+
include Compilers::Text
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'hamlit/compilers/new_attribute'
|
|
2
|
+
require 'hamlit/compilers/old_attribute'
|
|
3
|
+
require 'hamlit/concerns/included'
|
|
4
|
+
|
|
5
|
+
module Hamlit
|
|
6
|
+
module Compilers
|
|
7
|
+
module Attributes
|
|
8
|
+
extend Concerns::Included
|
|
9
|
+
include Compilers::NewAttribute
|
|
10
|
+
include Compilers::OldAttribute
|
|
11
|
+
|
|
12
|
+
included do
|
|
13
|
+
define_options :format, :attr_quote
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def on_haml_attrs(*attrs)
|
|
17
|
+
attrs = compile_attributes(attrs)
|
|
18
|
+
attrs = join_ids(attrs)
|
|
19
|
+
attrs = combine_classes(attrs)
|
|
20
|
+
attrs = pull_class_first(attrs)
|
|
21
|
+
[:html, :attrs, *attrs]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def compile_attributes(exps)
|
|
27
|
+
attrs = []
|
|
28
|
+
exps.each do |exp|
|
|
29
|
+
case exp
|
|
30
|
+
when /\A\(.+\)\Z/
|
|
31
|
+
attrs += compile_new_attribute(exp)
|
|
32
|
+
when /\A{.+}\Z/
|
|
33
|
+
attrs += compile_old_attribute(exp)
|
|
34
|
+
else
|
|
35
|
+
attrs << compile(exp)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
attrs
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def pull_class_first(attrs)
|
|
42
|
+
class_attrs = filter_attrs(attrs, 'class')
|
|
43
|
+
combine_classes(class_attrs) + (attrs - class_attrs)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def combine_classes(attrs)
|
|
47
|
+
class_attrs = filter_attrs(attrs, 'class')
|
|
48
|
+
return attrs if class_attrs.length <= 1
|
|
49
|
+
|
|
50
|
+
values = class_attrs.map(&:last).sort_by(&:last)
|
|
51
|
+
[[:html, :attr, 'class', [:multi, *insert_static(values, ' ')]]] + (attrs - class_attrs)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def join_ids(attrs)
|
|
55
|
+
id_attrs = filter_attrs(attrs, 'id')
|
|
56
|
+
return attrs if id_attrs.length <= 1
|
|
57
|
+
|
|
58
|
+
values = attrs.map(&:last)
|
|
59
|
+
[[:html, :attr, 'id', [:multi, *insert_static(values, '_')]]] + (attrs - id_attrs)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def filter_attrs(attrs, target)
|
|
63
|
+
class_attrs = attrs.select do |html, attr, name, content|
|
|
64
|
+
name == target
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def insert_static(array, str)
|
|
69
|
+
result = []
|
|
70
|
+
array.each_with_index do |value, index|
|
|
71
|
+
result << [:static, str] if index > 0
|
|
72
|
+
result << value
|
|
73
|
+
end
|
|
74
|
+
result
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Hamlit
|
|
2
|
+
module Compilers
|
|
3
|
+
module Comment
|
|
4
|
+
def on_haml_comment(condition, exps)
|
|
5
|
+
content = [:multi]
|
|
6
|
+
content << [:static, "#{condition}>\n"]
|
|
7
|
+
content += exps.map { |exp| compile(exp) }
|
|
8
|
+
content << [:static, "<![endif]"]
|
|
9
|
+
[:html, :comment, content]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|