hamlit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/k0kubun/hamlit.svg?branch=master)](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
|