haml 5.2.2 → 6.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/workflows/test.yml +13 -14
  4. data/.gitignore +16 -16
  5. data/.yardopts +0 -3
  6. data/CHANGELOG.md +116 -3
  7. data/Gemfile +18 -11
  8. data/MIT-LICENSE +1 -1
  9. data/README.md +17 -23
  10. data/REFERENCE.md +69 -145
  11. data/Rakefile +48 -81
  12. data/bin/bench +66 -0
  13. data/bin/console +11 -0
  14. data/bin/ruby +3 -0
  15. data/bin/setup +7 -0
  16. data/bin/stackprof +27 -0
  17. data/bin/test +24 -0
  18. data/exe/haml +6 -0
  19. data/ext/haml/extconf.rb +10 -0
  20. data/ext/haml/haml.c +537 -0
  21. data/ext/haml/hescape.c +108 -0
  22. data/ext/haml/hescape.h +20 -0
  23. data/haml.gemspec +39 -37
  24. data/lib/haml/ambles.rb +20 -0
  25. data/lib/haml/attribute_builder.rb +134 -179
  26. data/lib/haml/attribute_compiler.rb +85 -194
  27. data/lib/haml/attribute_parser.rb +92 -126
  28. data/lib/haml/cli.rb +154 -0
  29. data/lib/haml/compiler/children_compiler.rb +155 -0
  30. data/lib/haml/compiler/comment_compiler.rb +51 -0
  31. data/lib/haml/compiler/doctype_compiler.rb +46 -0
  32. data/lib/haml/compiler/script_compiler.rb +114 -0
  33. data/lib/haml/compiler/silent_script_compiler.rb +24 -0
  34. data/lib/haml/compiler/tag_compiler.rb +76 -0
  35. data/lib/haml/compiler.rb +63 -296
  36. data/lib/haml/dynamic_merger.rb +67 -0
  37. data/lib/haml/engine.rb +48 -227
  38. data/lib/haml/error.rb +5 -4
  39. data/lib/haml/escape.rb +13 -0
  40. data/lib/haml/escape_any.rb +21 -0
  41. data/lib/haml/filters/base.rb +12 -0
  42. data/lib/haml/filters/cdata.rb +20 -0
  43. data/lib/haml/filters/coffee.rb +17 -0
  44. data/lib/haml/filters/css.rb +33 -0
  45. data/lib/haml/filters/erb.rb +10 -0
  46. data/lib/haml/filters/escaped.rb +22 -0
  47. data/lib/haml/filters/javascript.rb +33 -0
  48. data/lib/haml/filters/less.rb +20 -0
  49. data/lib/haml/filters/markdown.rb +11 -0
  50. data/lib/haml/filters/plain.rb +29 -0
  51. data/lib/haml/filters/preserve.rb +22 -0
  52. data/lib/haml/filters/ruby.rb +10 -0
  53. data/lib/haml/filters/sass.rb +15 -0
  54. data/lib/haml/filters/scss.rb +15 -0
  55. data/lib/haml/filters/text_base.rb +25 -0
  56. data/lib/haml/filters/tilt_base.rb +59 -0
  57. data/lib/haml/filters.rb +54 -378
  58. data/lib/haml/force_escape.rb +29 -0
  59. data/lib/haml/helpers.rb +3 -697
  60. data/lib/haml/html.rb +22 -0
  61. data/lib/haml/identity.rb +13 -0
  62. data/lib/haml/object_ref.rb +35 -0
  63. data/lib/haml/parser.rb +157 -22
  64. data/lib/haml/rails_helpers.rb +53 -0
  65. data/lib/haml/rails_template.rb +57 -0
  66. data/lib/haml/railtie.rb +3 -46
  67. data/lib/haml/ruby_expression.rb +32 -0
  68. data/lib/haml/string_splitter.rb +140 -0
  69. data/lib/haml/template.rb +15 -34
  70. data/lib/haml/temple_line_counter.rb +2 -1
  71. data/lib/haml/util.rb +18 -15
  72. data/lib/haml/version.rb +1 -2
  73. data/lib/haml/whitespace.rb +8 -0
  74. data/lib/haml.rb +8 -20
  75. metadata +211 -55
  76. data/.gitmodules +0 -3
  77. data/TODO +0 -24
  78. data/benchmark.rb +0 -70
  79. data/bin/haml +0 -9
  80. data/lib/haml/.gitattributes +0 -1
  81. data/lib/haml/buffer.rb +0 -182
  82. data/lib/haml/escapable.rb +0 -77
  83. data/lib/haml/exec.rb +0 -347
  84. data/lib/haml/generator.rb +0 -42
  85. data/lib/haml/helpers/action_view_extensions.rb +0 -60
  86. data/lib/haml/helpers/action_view_mods.rb +0 -132
  87. data/lib/haml/helpers/action_view_xss_mods.rb +0 -60
  88. data/lib/haml/helpers/safe_erubi_template.rb +0 -20
  89. data/lib/haml/helpers/safe_erubis_template.rb +0 -33
  90. data/lib/haml/helpers/xss_mods.rb +0 -114
  91. data/lib/haml/options.rb +0 -273
  92. data/lib/haml/plugin.rb +0 -54
  93. data/lib/haml/sass_rails_filter.rb +0 -47
  94. data/lib/haml/template/options.rb +0 -27
  95. data/lib/haml/temple_engine.rb +0 -124
  96. data/yard/default/.gitignore +0 -1
  97. data/yard/default/fulldoc/html/css/common.sass +0 -15
  98. data/yard/default/layout/html/footer.erb +0 -12
data/REFERENCE.md CHANGED
@@ -30,7 +30,7 @@ The first step for all of these is to install the Haml gem:
30
30
 
31
31
  To run Haml from the command line, just use
32
32
 
33
- haml input.haml output.html
33
+ haml render input.haml > output.html
34
34
 
35
35
  Use `haml --help` for full documentation.
36
36
 
@@ -68,24 +68,6 @@ may be compiled to:
68
68
  </div>
69
69
  </div>
70
70
 
71
- ### Rails XSS Protection
72
-
73
- Haml supports Rails' XSS protection scheme, which was introduced in Rails 2.3.5+
74
- and is enabled by default in 3.0.0+. If it's enabled, Haml's
75
- {Haml::Options#escape_html `:escape_html`} option is set to `true` by default -
76
- like in ERB, all strings printed to a Haml template are escaped by default. Also
77
- like ERB, strings marked as HTML safe are not escaped. Haml also has [its own
78
- syntax for printing a raw string to the template](#unescaping_html).
79
-
80
- If the `:escape_html` option is set to false when XSS protection is enabled,
81
- Haml doesn't escape Ruby strings by default. However, if a string marked
82
- HTML-safe is passed to [Haml's escaping syntax](#escaping_html), it won't be
83
- escaped.
84
-
85
- Finally, all the {Haml::Helpers Haml helpers} that return strings that are known
86
- to be HTML safe are marked as such. In addition, string input is escaped unless
87
- it's HTML safe.
88
-
89
71
  ### Ruby Module
90
72
 
91
73
  Haml can also be used completely separately from Rails and ActionView. To do
@@ -93,10 +75,10 @@ this, install the gem with RubyGems:
93
75
 
94
76
  gem install haml
95
77
 
96
- You can then use it by including the "haml" gem in Ruby code, and using
97
- {Haml::Engine} like so:
78
+ You can then use it by including the `haml` gem in Ruby code, and using
79
+ {Haml::Template} like so:
98
80
 
99
- engine = Haml::Engine.new("%p Haml code!")
81
+ engine = Haml::Template.new { "%p Haml code!" }
100
82
  engine.render #=> "<p>Haml code!</p>\n"
101
83
 
102
84
  ### Options
@@ -104,50 +86,26 @@ You can then use it by including the "haml" gem in Ruby code, and using
104
86
  Haml understands various configuration options that affect its performance and
105
87
  output.
106
88
 
107
- In Rails, options can be set by setting the {Haml::Template#options Haml::Template.options}
108
- hash in an initializer:
89
+ In Rails, options can be set by using `Haml::RailsTemplate.set_options` in an initializer:
109
90
 
110
91
  ```ruby
111
92
  # config/initializers/haml.rb
112
- Haml::Template.options[:format] = :html5
113
-
114
- # Avoid escaping attributes which are already escaped
115
- Haml::Template.options[:escape_attrs] = :once
93
+ Haml::RailsTemplate.set_options(escape_html: false)
116
94
  ```
117
95
 
118
- Outside Rails, you can set them by configuring them globally in
119
- Haml::Options.defaults:
96
+ Outside Rails, you can set them by configuring them globally in `Haml::Template.options`:
120
97
 
121
98
  ```ruby
122
- Haml::Options.defaults[:format] = :html5
99
+ Haml::Template.options[:escape_html] = false
123
100
  ```
124
101
 
125
102
  In sinatra specifically, you can set them in global config with:
126
103
  ```ruby
127
- set :haml, { escape_html: true }
104
+ set :haml, { escape_html: false }
128
105
  ```
129
106
 
130
- Finally, you can also set them by passing an options hash to
131
- {Haml::Engine#initialize}. For the complete list of available options, please
132
- see {Haml::Options}.
133
-
134
- ### Encodings
135
-
136
- Haml supports the same sorts of
137
- encoding-declaration comments that Ruby does. Although both Ruby and Haml
138
- support several different styles, the easiest it just to add `-# coding:
139
- encoding-name` at the beginning of the Haml template (it must come before all
140
- other lines). This will tell Haml that the template is encoded using the named
141
- encoding.
142
-
143
- By default, the HTML generated by Haml has the same encoding as the Haml
144
- template. However, if `Encoding.default_internal` is set, Haml will attempt to
145
- use that instead. In addition, the {Haml::Options#encoding `:encoding` option}
146
- can be used to specify an output encoding manually.
147
-
148
- Note that, like Ruby, Haml does not support templates encoded in UTF-16 or
149
- UTF-32, since these encodings are not compatible with ASCII. It is possible to
150
- use these as the output encoding, though.
107
+ Finally, you can also set them by passing an options hash to `Haml::Engine.new` or `Haml::Template.new`.
108
+ For the complete list of available options, please see `Haml::Engine`.
151
109
 
152
110
  ## Plain Text
153
111
 
@@ -325,49 +283,6 @@ Haml also supports Ruby's new hash syntax:
325
283
 
326
284
  %a{title: @title, href: href} Stuff
327
285
 
328
- #### Attribute Methods
329
-
330
- A Ruby method call that returns a hash can be substituted for the hash contents.
331
- For example, {Haml::Helpers} defines the following method:
332
-
333
- def html_attrs(lang = 'en-US')
334
- {:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang}
335
- end
336
-
337
- This can then be used in Haml, like so:
338
-
339
- %html{html_attrs('fr-fr')}
340
-
341
- This is compiled to:
342
-
343
- <html lang='fr-fr' xml:lang='fr-fr' xmlns='http://www.w3.org/1999/xhtml'>
344
- </html>
345
-
346
- You can use as many such attribute methods as you want by separating them with
347
- commas, like a Ruby argument list. All the hashes will be merged together, from
348
- left to right. For example, if you defined
349
-
350
- def hash1
351
- {:bread => 'white', :filling => 'peanut butter and jelly'}
352
- end
353
-
354
- def hash2
355
- {:bread => 'whole wheat'}
356
- end
357
-
358
- then
359
-
360
- %sandwich{hash1, hash2, :delicious => 'true'}/
361
-
362
- would compile to:
363
-
364
- <sandwich bread='whole wheat' delicious='true' filling='peanut butter and jelly' />
365
-
366
- Note that the Haml attributes list has the same syntax as a Ruby method call.
367
- This means that any attribute methods must come before the hash literal.
368
-
369
- Attribute methods aren't supported for HTML-style attributes.
370
-
371
286
  #### Boolean Attributes
372
287
 
373
288
  Some attributes, such as "checked" for `input` tags or "selected" for `option`
@@ -404,24 +319,38 @@ or using `true` and `false`:
404
319
 
405
320
  %input(selected=true)
406
321
 
322
+ This feature works only for attributes that are included in
323
+ [`Haml::AttributeBuilder::BOOLEAN_ATTRIBUTES`](lib/haml/attribute_builder.rb),
324
+ as well as `data-` and `aria-` attributes.
325
+
326
+ %input{'data-hidden' => false}
327
+ %input{'aria-hidden' => false}
328
+ %input{'xyz-hidden' => false}
329
+
330
+ will render as:
331
+
332
+ <input>
333
+ <input>
334
+ <input xyz-hidden='false'>
335
+
336
+
407
337
  <!-- The title to the next section (Prefixed Attributes) has changed. This
408
338
  <a> tag is so old links to here still work. -->
409
339
  <a id="html5_custom_data_attributes" style="border:0;"></a>
410
340
 
411
- #### Prefixed Attributes
341
+ #### Data Attributes
412
342
 
413
343
  HTML5 allows for adding
414
344
  [custom non-visible data attributes](http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
415
345
  to elements using attribute names beginning with `data-`. The
416
346
  [Accessible Rich Internet Applications](http://www.w3.org/WAI/intro/aria)
417
- specification makes use of attributes beginning with `aria-`. There are also
418
- frameworks that use non-standard attributes with a common prefix.
347
+ specification makes use of attributes beginning with `aria-`.
419
348
 
420
349
  Haml can help generate collections of attributes that share a prefix like
421
- these. Any entry in an attribute hash that has a Hash as its value is expanded
422
- into a series of attributes, one for each key/value pair in the hash, with the
423
- attribute name formed by joining the “parent” key name to the key name with a
424
- hyphen.
350
+ these. Any entry in an `data` or `aria` attribute hash that has a Hash as its
351
+ value is expanded into a series of attributes, one for each key/value pair in
352
+ the hash, with the attribute name formed by joining the “parent” key name to
353
+ the key name with a hyphen. This works only for `data` or `aria`.
425
354
 
426
355
  For example:
427
356
 
@@ -993,7 +922,7 @@ is compiled to:
993
922
 
994
923
  ### Whitespace Preservation: `~` {#tilde}
995
924
 
996
- `~` works just like `=`, except that it runs {Haml::Helpers#find\_and\_preserve}
925
+ `~` works just like `=`, except that it runs {Haml::Helpers.preserve}
997
926
  on its input. For example,
998
927
 
999
928
  ~ "Foo\n<pre>Bar\nBaz</pre>"
@@ -1154,9 +1083,6 @@ is compiled to
1154
1083
  <p>I <strong>really</strong> prefer <em>raspberry</em> jam.</p>
1155
1084
  </div>
1156
1085
 
1157
- Note that `#{}` interpolation within filters is HTML-escaped if you specify true to
1158
- {Haml::Options#escape_filter_interpolations `:escape_filter_interpolations`} option.
1159
-
1160
1086
  The functionality of some filters such as Markdown can be provided by many
1161
1087
  different libraries. Usually you don't have to worry about this - you can just
1162
1088
  load the gem of your choice and Haml will automatically use it.
@@ -1271,43 +1197,48 @@ default. This filter is implemented using Tilt.
1271
1197
 
1272
1198
  ### Custom Filters
1273
1199
 
1274
- You can also define your own filters. See {Haml::Filters} for details.
1275
-
1276
- ## Helper Methods {#helper-methods}
1277
-
1278
- Sometimes you need to manipulate whitespace in a more precise fashion than what
1279
- the whitespace removal methods allow. There are a few helper methods that are
1280
- useful when dealing with inline content. All these methods take a Haml block to
1281
- modify.
1200
+ You can also define your own filters.
1201
+ `Haml::Filters::YourCustomFilter#compile` should return
1202
+ [a Temple expression](https://github.com/judofyr/temple/blob/master/EXPRESSIONS.md).
1282
1203
 
1283
- ### surround {#surround}
1204
+ The simplest example of a filter might be something like:
1284
1205
 
1285
- Surrounds a Haml block with text. Expects 1 or 2 string arguments used to
1286
- surround the Haml block. If a second argument is not provided, the first
1287
- argument is used as the second.
1288
-
1289
- = surround "(", ")" do
1290
- = link_to "learn more", "#"
1291
-
1292
- ### precede {#precede}
1206
+ ```ruby
1207
+ class HelloFilter < Haml::Filters::Base
1208
+ def compile(_node)
1209
+ [:static, "hello world"]
1210
+ end
1211
+ end
1293
1212
 
1294
- Prepends a Haml block with text. Expects 1 argument.
1213
+ Haml::Filters.registered[:hello] ||= HelloFilter
1214
+ ```
1295
1215
 
1296
- = precede "*" do
1297
- %span Required
1216
+ A more complex complex example
1298
1217
 
1299
- ### succeed {#succeed}
1218
+ ```ruby
1219
+ class BetterFilter < Haml::Filters::Base
1220
+ def compile(node)
1221
+ temple = [:multi]
1222
+ temple << [:static, "hello "]
1223
+ temple << compile_text(node.value[:text])
1224
+ temple << [:static, " world"]
1225
+ temple
1226
+ end
1227
+
1228
+ private
1229
+ def compile_text(text)
1230
+ if ::Haml::Util.contains_interpolation?(text)
1231
+ [:dynamic, ::Haml::Util.unescape_interpolation(text)]
1232
+ else
1233
+ [:static, text]
1234
+ end
1235
+ end
1236
+ end
1300
1237
 
1301
- Appends a Haml block with text. Expects 1 argument.
1238
+ Haml::Filters.registered[:better] ||= BetterFilter
1239
+ ```
1302
1240
 
1303
- Begin by
1304
- = succeed "," do
1305
- = link_to "filling out your profile", "#"
1306
- = succeed "," do
1307
- = link_to "adding a bio", "#"
1308
- and
1309
- = succeed "." do
1310
- = link_to "inviting friends", "#"
1241
+ See {Haml::Filters} for examples.
1311
1242
 
1312
1243
  ## Multiline: `|` {#multiline}
1313
1244
 
@@ -1367,14 +1298,7 @@ Haml won't try to re-format the indentation.
1367
1298
  Literal `textarea` and `pre` tags automatically preserve content given through
1368
1299
  `=`. Dynamically-generated `textarea`s and `pre`s can't be preserved
1369
1300
  automatically, and so should be passed through
1370
- {Haml::Helpers#find\_and\_preserve} or the [`~` command](#tilde), which has the
1301
+ {Haml::Helpers.preserve} or the [`~` command](#tilde), which has the
1371
1302
  same effect.
1372
1303
 
1373
1304
  Blocks of literal text can be preserved using the [`:preserve` filter](#preserve-filter).
1374
-
1375
- ## Helpers
1376
-
1377
- Haml offers a bunch of helpers that are useful for doing stuff like preserving
1378
- whitespace, creating nicely indented output for user-defined helpers, and other
1379
- useful things. The helpers are all documented in the {Haml::Helpers} and
1380
- {Haml::Helpers::ActionViewExtensions} modules.
data/Rakefile CHANGED
@@ -1,36 +1,57 @@
1
- require "rake/clean"
2
- require "rake/testtask"
3
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+
3
+ #
4
+ # Prepend DevKit into compilation phase
5
+ #
6
+ if Gem.win_platform?
7
+ desc 'Activates DevKit'
8
+ task :devkit do
9
+ begin
10
+ require 'devkit'
11
+ rescue LoadError
12
+ abort 'Failed to load DevKit required for compilation'
13
+ end
14
+ end
15
+ task compile: :devkit
16
+ end
4
17
 
5
- task :default => :test
18
+ require 'rake/testtask'
19
+ if /java/ === RUBY_PLATFORM
20
+ # require 'rake/javaextensiontask'
21
+ # Rake::JavaExtensionTask.new(:haml) do |ext|
22
+ # ext.ext_dir = 'ext/java'
23
+ # ext.lib_dir = 'lib/haml'
24
+ # end
6
25
 
7
- # FIXME: Redefining :test task to run test/options_test.rb in isolated process since it depends on whether Rails is loaded or not.
8
- # Remove this task when we finished changing escape_html option to be true by default.
9
- isolated_test = Rake::TestTask.new do |t|
10
- t.libs << 'test'
11
- t.test_files = %w[test/options_test.rb]
12
- t.warning = true
13
- t.verbose = true
14
- end
15
- Rake::TestTask.new do |t|
16
- t.libs << 'test'
17
- t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] + Dir['test/cases/*_test.rb'] - isolated_test.file_list
18
- t.warning = true
19
- t.verbose = true
26
+ task :compile do
27
+ # dummy for now
28
+ end
29
+ else
30
+ require 'rake/extensiontask'
31
+ Rake::ExtensionTask.new(:haml) do |ext|
32
+ ext.lib_dir = 'lib/haml'
33
+ end
20
34
  end
21
35
 
22
- CLEAN.replace %w(pkg doc coverage .yardoc test/haml vendor)
36
+ Dir['benchmark/*.rake'].each { |b| import(b) }
23
37
 
24
- desc "Benchmark Haml against ERB. TIMES=n sets the number of runs, default is 1000."
25
- task :benchmark do
26
- sh "ruby benchmark.rb #{ENV['TIMES']}"
38
+ Rake::TestTask.new do |t|
39
+ t.libs << 'lib' << 'test'
40
+ files = Dir['test/haml/**/*_test.rb']
41
+ t.ruby_opts = %w[-rtest_helper]
42
+ t.test_files = files
43
+ t.verbose = true
27
44
  end
28
-
29
- task :submodules do
30
- if File.exist?(File.dirname(__FILE__) + "/.git")
31
- sh %{git submodule sync}
32
- sh %{git submodule update --init --recursive}
45
+ task test: :compile
46
+
47
+ desc 'bench task for CI'
48
+ task bench: :compile do
49
+ if ENV['SLIM_BENCH'] == '1'
50
+ cmd = %w[bundle exec ruby benchmark/slim/run-benchmarks.rb]
51
+ else
52
+ cmd = ['bin/bench', 'bench', ('-c' if ENV['COMPILE'] == '1'), *ENV['TEMPLATE'].split(',')].compact
33
53
  end
54
+ exit system(*cmd)
34
55
  end
35
56
 
36
57
  namespace :doc do
@@ -58,58 +79,4 @@ task(:doc => 'doc:sass') {sh "yard"}
58
79
  desc "Generate documentation incrementally"
59
80
  task(:redoc) {sh "yard -c"}
60
81
 
61
- desc <<END
62
- Profile Haml.
63
- TIMES=n sets the number of runs. Defaults to 1000.
64
- FILE=str sets the file to profile. Defaults to 'standard'
65
- OUTPUT=str sets the ruby-prof output format.
66
- Can be Flat, CallInfo, or Graph. Defaults to Flat. Defaults to Flat.
67
- END
68
- task :profile do
69
- times = (ENV['TIMES'] || '1000').to_i
70
- file = ENV['FILE'] || 'test/templates/standard.haml'
71
-
72
- require 'bundler/setup'
73
- require 'ruby-prof'
74
- require 'haml'
75
- file = File.read(File.expand_path("../#{file}", __FILE__))
76
- obj = Object.new
77
- Haml::Engine.new(file).def_method(obj, :render)
78
- result = RubyProf.profile { times.times { obj.render } }
79
-
80
- RubyProf.const_get("#{(ENV['OUTPUT'] || 'Flat').capitalize}Printer").new(result).print
81
- end
82
-
83
- def gemfiles
84
- @gemfiles ||= Dir[File.dirname(__FILE__) + '/test/gemfiles/Gemfile.*'].reject {|f| f =~ /\.lock$/}
85
- end
86
-
87
- def with_each_gemfile
88
- gemfiles.each do |gemfile|
89
- Bundler.with_clean_env do
90
- puts "Using gemfile: #{gemfile}"
91
- ENV['BUNDLE_GEMFILE'] = gemfile
92
- yield
93
- end
94
- end
95
- end
96
-
97
- namespace :test do
98
- namespace :bundles do
99
- desc "Install all dependencies necessary to test Haml."
100
- task :install do
101
- with_each_gemfile {sh "bundle"}
102
- end
103
-
104
- desc "Update all dependencies for testing Haml."
105
- task :update do
106
- with_each_gemfile {sh "bundle update"}
107
- end
108
- end
109
-
110
- desc "Test all supported versions of rails. This takes a while."
111
- task :rails_compatibility => 'test:bundles:install' do
112
- with_each_gemfile {sh "bundle exec rake test"}
113
- end
114
- task :rc => :rails_compatibility
115
- end
82
+ task default: %w[compile test]
data/bin/bench ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'haml'
5
+ require 'thor'
6
+ require 'benchmark/ips'
7
+ require_relative '../benchmark/utils/benchmark_ips_extension'
8
+
9
+ class Bench < Thor
10
+ class_option :show_template, type: :boolean, aliases: ['-t']
11
+
12
+ desc 'bench HAML', 'Benchmark haml template'
13
+ option :compile, type: :boolean, aliases: ['-c']
14
+ option :show_code, type: :boolean, aliases: ['-s']
15
+ def bench(*files)
16
+ files.each { |file| render(file) }
17
+ files.each { |file| compile(file) if options[:compile] }
18
+ files.each { |file| code(file) if options[:show_code] }
19
+ end
20
+
21
+ desc 'compile HAML', 'Benchmark compilation'
22
+ def compile(file)
23
+ puts "#{?= * 49}\n Compilation: #{file}\n#{?= * 49}"
24
+ haml = File.read(file)
25
+
26
+ Benchmark.ips do |x|
27
+ x.report("haml v#{Haml::VERSION}") { Haml::Engine.new.call(haml) }
28
+ x.compare!
29
+ end
30
+ end
31
+
32
+ desc 'render HAML', 'Benchmark rendering'
33
+ def render(file)
34
+ puts "#{?= * 49}\n Rendering: #{file}\n#{?= * 49}"
35
+ haml = File.read(file)
36
+ puts haml + "\n" if options[:show_template]
37
+ object = Object.new
38
+ ruby_file = file.gsub(/\.haml\z/, '.rb')
39
+ if File.exist?(ruby_file)
40
+ object.instance_eval(File.read(ruby_file))
41
+ end
42
+
43
+ object.instance_eval "def haml; #{Haml::Engine.new.call(haml)}; end"
44
+
45
+ Benchmark.ips do |x|
46
+ x.report("haml v#{Haml::VERSION}") { object.haml }
47
+ x.compare!
48
+ end
49
+ end
50
+
51
+ desc 'code HAML', 'Show compiled code'
52
+ def code(file)
53
+ haml = File.read(file)
54
+ puts "\n#{?= * 49}\n Haml Source: #{file}\n#{?= * 49}"
55
+ puts Haml::Engine.new.call(haml)
56
+ end
57
+
58
+ private
59
+
60
+ def method_missing(*args)
61
+ return super if args.length > 1
62
+ render(args.first.to_s)
63
+ end
64
+ end
65
+
66
+ Bench.start
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'hamlit'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require 'pry'
11
+ Pry.start
data/bin/ruby ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ bundle exec ruby -Ilib:test -rtest_helper $@
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/bin/stackprof ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'hamlit'
5
+ require 'stackprof'
6
+
7
+ def open_flamegraph(report)
8
+ temp = `mktemp /tmp/stackflame-XXXXXXXX`.strip
9
+ data_path = "#{temp}.js"
10
+ system("mv #{temp} #{data_path}")
11
+
12
+ File.open(data_path, 'w') do |f|
13
+ report.print_flamegraph(f)
14
+ end
15
+
16
+ viewer_path = File.join(`bundle show stackprof`.strip, 'lib/stackprof/flamegraph/viewer.html')
17
+ url = "file://#{viewer_path}?data=#{data_path}"
18
+ system(%Q[osascript -e 'open location "#{url}"'])
19
+ end
20
+
21
+ haml = File.read(ARGV.first)
22
+ StackProf.start(mode: :wall, interval: 1, raw: false)
23
+ Hamlit::Engine.new.call(haml)
24
+ StackProf.stop
25
+
26
+ report = StackProf::Report.new(StackProf.results)
27
+ report.print_text(false)
data/bin/test ADDED
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+
3
+ VERSIONS=(
4
+ 2.1.10
5
+ 2.2.5
6
+ 2.3.1
7
+ )
8
+
9
+ set -e
10
+ trap 'echo "${VERSIONS[2]}" > .ruby-version' 0
11
+
12
+ function test_with() {
13
+ version=$1
14
+ rbenv local $version
15
+ if ! bundle check > /dev/null; then
16
+ bundle install
17
+ fi
18
+ ruby -v
19
+ bundle exec rake test
20
+ }
21
+
22
+ for version in ${VERSIONS[@]}; do
23
+ test_with $version
24
+ done
data/exe/haml ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path('../lib', __dir__)
4
+ require 'haml/cli'
5
+
6
+ Haml::CLI.start(ARGV)
@@ -0,0 +1,10 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << ' -Wall -Wextra'
4
+
5
+ $srcs = %w[
6
+ haml.c
7
+ hescape.c
8
+ ]
9
+
10
+ create_makefile('haml/haml')