haml 5.1.2 → 6.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/workflows/test.yml +36 -0
  4. data/.gitignore +16 -15
  5. data/.yardopts +0 -3
  6. data/CHANGELOG.md +189 -1
  7. data/FAQ.md +1 -1
  8. data/Gemfile +20 -12
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +10 -17
  11. data/REFERENCE.md +129 -164
  12. data/Rakefile +15 -89
  13. data/bin/bench +66 -0
  14. data/bin/console +11 -0
  15. data/bin/ruby +3 -0
  16. data/bin/setup +7 -0
  17. data/bin/stackprof +27 -0
  18. data/bin/test +24 -0
  19. data/exe/haml +6 -0
  20. data/haml.gemspec +34 -35
  21. data/lib/haml/ambles.rb +20 -0
  22. data/lib/haml/attribute_builder.rb +131 -133
  23. data/lib/haml/attribute_compiler.rb +91 -182
  24. data/lib/haml/attribute_parser.rb +92 -126
  25. data/lib/haml/cli.rb +154 -0
  26. data/lib/haml/compiler/children_compiler.rb +155 -0
  27. data/lib/haml/compiler/comment_compiler.rb +51 -0
  28. data/lib/haml/compiler/doctype_compiler.rb +52 -0
  29. data/lib/haml/compiler/script_compiler.rb +114 -0
  30. data/lib/haml/compiler/silent_script_compiler.rb +24 -0
  31. data/lib/haml/compiler/tag_compiler.rb +76 -0
  32. data/lib/haml/compiler.rb +63 -296
  33. data/lib/haml/dynamic_merger.rb +67 -0
  34. data/lib/haml/engine.rb +48 -227
  35. data/lib/haml/error.rb +5 -4
  36. data/lib/haml/escape.rb +13 -0
  37. data/lib/haml/escape_any.rb +21 -0
  38. data/lib/haml/filters/base.rb +12 -0
  39. data/lib/haml/filters/cdata.rb +20 -0
  40. data/lib/haml/filters/coffee.rb +17 -0
  41. data/lib/haml/filters/css.rb +33 -0
  42. data/lib/haml/filters/erb.rb +10 -0
  43. data/lib/haml/filters/escaped.rb +22 -0
  44. data/lib/haml/filters/javascript.rb +33 -0
  45. data/lib/haml/filters/less.rb +20 -0
  46. data/lib/haml/filters/markdown.rb +11 -0
  47. data/lib/haml/filters/plain.rb +29 -0
  48. data/lib/haml/filters/preserve.rb +22 -0
  49. data/lib/haml/filters/ruby.rb +10 -0
  50. data/lib/haml/filters/sass.rb +15 -0
  51. data/lib/haml/filters/scss.rb +15 -0
  52. data/lib/haml/filters/text_base.rb +25 -0
  53. data/lib/haml/filters/tilt_base.rb +59 -0
  54. data/lib/haml/filters.rb +54 -378
  55. data/lib/haml/force_escape.rb +29 -0
  56. data/lib/haml/helpers.rb +3 -691
  57. data/lib/haml/html.rb +22 -0
  58. data/lib/haml/identity.rb +13 -0
  59. data/lib/haml/object_ref.rb +35 -0
  60. data/lib/haml/parser.rb +190 -27
  61. data/lib/haml/rails_helpers.rb +53 -0
  62. data/lib/haml/rails_template.rb +62 -0
  63. data/lib/haml/railtie.rb +3 -41
  64. data/lib/haml/ruby_expression.rb +32 -0
  65. data/lib/haml/string_splitter.rb +140 -0
  66. data/lib/haml/template.rb +15 -34
  67. data/lib/haml/temple_line_counter.rb +2 -1
  68. data/lib/haml/util.rb +20 -16
  69. data/lib/haml/version.rb +1 -2
  70. data/lib/haml/whitespace.rb +8 -0
  71. data/lib/haml.rb +8 -20
  72. metadata +205 -53
  73. data/.gitmodules +0 -3
  74. data/.travis.yml +0 -97
  75. data/TODO +0 -24
  76. data/benchmark.rb +0 -70
  77. data/bin/haml +0 -9
  78. data/lib/haml/.gitattributes +0 -1
  79. data/lib/haml/buffer.rb +0 -238
  80. data/lib/haml/escapable.rb +0 -50
  81. data/lib/haml/exec.rb +0 -347
  82. data/lib/haml/generator.rb +0 -42
  83. data/lib/haml/helpers/action_view_extensions.rb +0 -60
  84. data/lib/haml/helpers/action_view_mods.rb +0 -132
  85. data/lib/haml/helpers/action_view_xss_mods.rb +0 -60
  86. data/lib/haml/helpers/safe_erubi_template.rb +0 -20
  87. data/lib/haml/helpers/safe_erubis_template.rb +0 -33
  88. data/lib/haml/helpers/xss_mods.rb +0 -111
  89. data/lib/haml/options.rb +0 -273
  90. data/lib/haml/plugin.rb +0 -37
  91. data/lib/haml/sass_rails_filter.rb +0 -47
  92. data/lib/haml/template/options.rb +0 -27
  93. data/lib/haml/temple_engine.rb +0 -123
  94. data/yard/default/.gitignore +0 -1
  95. data/yard/default/fulldoc/html/css/common.sass +0 -15
  96. 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,43 +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
- # config/initializers/haml.rb
111
- Haml::Template.options[:format] = :html5
91
+ ```ruby
92
+ # config/initializers/haml.rb
93
+ Haml::RailsTemplate.set_options(escape_html: false)
94
+ ```
112
95
 
113
- Outside Rails, you can set them by configuring them globally in
114
- Haml::Options.defaults:
96
+ Outside Rails, you can set them by configuring them globally in `Haml::Template.options`:
115
97
 
116
- Haml::Options.defaults[:format] = :html5
98
+ ```ruby
99
+ Haml::Template.options[:escape_html] = false
100
+ ```
117
101
 
118
102
  In sinatra specifically, you can set them in global config with:
119
103
  ```ruby
120
- set :haml, { escape_html: true }
104
+ set :haml, { escape_html: false }
121
105
  ```
122
106
 
123
- Finally, you can also set them by passing an options hash to
124
- {Haml::Engine#initialize}. For the complete list of available options, please
125
- see {Haml::Options}.
126
-
127
- ### Encodings
128
-
129
- Haml supports the same sorts of
130
- encoding-declaration comments that Ruby does. Although both Ruby and Haml
131
- support several different styles, the easiest it just to add `-# coding:
132
- encoding-name` at the beginning of the Haml template (it must come before all
133
- other lines). This will tell Haml that the template is encoded using the named
134
- encoding.
135
-
136
- By default, the HTML generated by Haml has the same encoding as the Haml
137
- template. However, if `Encoding.default_internal` is set, Haml will attempt to
138
- use that instead. In addition, the {Haml::Options#encoding `:encoding` option}
139
- can be used to specify an output encoding manually.
140
-
141
- Note that, like Ruby, Haml does not support templates encoded in UTF-16 or
142
- UTF-32, since these encodings are not compatible with ASCII. It is possible to
143
- 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`.
144
109
 
145
110
  ## Plain Text
146
111
 
@@ -215,10 +180,10 @@ closing tags for any element.
215
180
 
216
181
  ### Attributes: `{}` or `()` {#attributes}
217
182
 
218
- Brackets represent a Ruby hash that is used for specifying the attributes of an
183
+ Braces represent a Ruby hash that is used for specifying the attributes of an
219
184
  element. It is literally evaluated as a Ruby hash, so logic will work in it and
220
185
  local variables may be used. Quote characters within the attribute will be
221
- replaced by appropriate escape sequences. The hash is placed after the tag is
186
+ replaced with appropriate escape sequences. The hash is placed after the tag is
222
187
  defined. For example:
223
188
 
224
189
  %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
@@ -228,15 +193,19 @@ is compiled to:
228
193
  <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'></html>
229
194
 
230
195
  Attribute hashes can also be stretched out over multiple lines to accommodate
231
- many attributes. However, newlines may only be placed immediately after commas.
232
- For example:
196
+ many attributes.
233
197
 
234
- %script{:type => "text/javascript",
235
- :src => "javascripts/script_#{2 + 7}"}
198
+ %script{
199
+ "type": text/javascript",
200
+ "src": javascripts/script_#{2 + 7}",
201
+ "data": {
202
+ "controller": "reporter",
203
+ },
204
+ }
236
205
 
237
206
  is compiled to:
238
207
 
239
- <script src='javascripts/script_9' type='text/javascript'></script>
208
+ <script src='javascripts/script_9' type='text/javascript' data-controller='reporter'></script>
240
209
 
241
210
  #### `:class` and `:id` Attributes {#class-and-id-attributes}
242
211
 
@@ -278,7 +247,7 @@ could render as either of:
278
247
  #### HTML-style Attributes: `()`
279
248
 
280
249
  Haml also supports a terser, less Ruby-specific attribute syntax based on HTML's
281
- attributes. These are used with parentheses instead of brackets, like so:
250
+ attributes. These are used with parentheses instead of braces, like so:
282
251
 
283
252
  %html(xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en")
284
253
 
@@ -314,49 +283,6 @@ Haml also supports Ruby's new hash syntax:
314
283
 
315
284
  %a{title: @title, href: href} Stuff
316
285
 
317
- #### Attribute Methods
318
-
319
- A Ruby method call that returns a hash can be substituted for the hash contents.
320
- For example, {Haml::Helpers} defines the following method:
321
-
322
- def html_attrs(lang = 'en-US')
323
- {:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang}
324
- end
325
-
326
- This can then be used in Haml, like so:
327
-
328
- %html{html_attrs('fr-fr')}
329
-
330
- This is compiled to:
331
-
332
- <html lang='fr-fr' xml:lang='fr-fr' xmlns='http://www.w3.org/1999/xhtml'>
333
- </html>
334
-
335
- You can use as many such attribute methods as you want by separating them with
336
- commas, like a Ruby argument list. All the hashes will be merged together, from
337
- left to right. For example, if you defined
338
-
339
- def hash1
340
- {:bread => 'white', :filling => 'peanut butter and jelly'}
341
- end
342
-
343
- def hash2
344
- {:bread => 'whole wheat'}
345
- end
346
-
347
- then
348
-
349
- %sandwich{hash1, hash2, :delicious => 'true'}/
350
-
351
- would compile to:
352
-
353
- <sandwich bread='whole wheat' delicious='true' filling='peanut butter and jelly' />
354
-
355
- Note that the Haml attributes list has the same syntax as a Ruby method call.
356
- This means that any attribute methods must come before the hash literal.
357
-
358
- Attribute methods aren't supported for HTML-style attributes.
359
-
360
286
  #### Boolean Attributes
361
287
 
362
288
  Some attributes, such as "checked" for `input` tags or "selected" for `option`
@@ -393,24 +319,38 @@ or using `true` and `false`:
393
319
 
394
320
  %input(selected=true)
395
321
 
322
+ This feature works only for attributes that are included in
323
+ [`Haml::AttributeBuilder::BOOLEAN_ATTRIBUTES`](https://github.com/haml/haml/blob/main/lib/haml/attribute_builder.rb#L5),
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
+
396
337
  <!-- The title to the next section (Prefixed Attributes) has changed. This
397
338
  <a> tag is so old links to here still work. -->
398
339
  <a id="html5_custom_data_attributes" style="border:0;"></a>
399
340
 
400
- #### Prefixed Attributes
341
+ #### Data Attributes
401
342
 
402
343
  HTML5 allows for adding
403
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)
404
345
  to elements using attribute names beginning with `data-`. The
405
346
  [Accessible Rich Internet Applications](http://www.w3.org/WAI/intro/aria)
406
- specification makes use of attributes beginning with `aria-`. There are also
407
- frameworks that use non-standard attributes with a common prefix.
347
+ specification makes use of attributes beginning with `aria-`.
408
348
 
409
349
  Haml can help generate collections of attributes that share a prefix like
410
- these. Any entry in an attribute hash that has a Hash as its value is expanded
411
- into a series of attributes, one for each key/value pair in the hash, with the
412
- attribute name formed by joining the “parent” key name to the key name with a
413
- 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`.
414
354
 
415
355
  For example:
416
356
 
@@ -420,7 +360,7 @@ will render as:
420
360
 
421
361
  <a data-author-id='123' data-category='7' href='/posts'>Posts By Author</a>
422
362
 
423
- Notice that the underscore in `author_id` was replaced by a hyphen. If you wish
363
+ Notice that the underscore in `author_id` was replaced with a hyphen. If you wish
424
364
  to suppress this behavior, you can set Haml's
425
365
  {Haml::Options#hyphenate_data_attrs `:hyphenate_data_attrs` option} to `false`,
426
366
  and the output will be rendered as:
@@ -517,6 +457,24 @@ and is compiled to:
517
457
  </div>
518
458
  </div>
519
459
 
460
+ #### Class Name Merging and Ordering
461
+
462
+ Class names are ordered in the following way:
463
+
464
+ 1) Tag identifiers in order (aka, ".alert.me" => "alert me")
465
+ 2) Classes appearing in HTML-style attributes
466
+ 3) Classes appearing in Hash-style attributes
467
+
468
+ For instance, this is a complicated and unintuitive test case illustrating the ordering
469
+
470
+ .foo.moo{:class => ['bar', 'alpha']}(class='baz')
471
+
472
+ The resulting HTML would be as follows:
473
+
474
+ <div class='foo moo baz bar alpha'></div>
475
+
476
+ *Versions of Haml prior to 5.0 would alphabetically sort class names.*
477
+
520
478
  ### Empty (void) Tags: `/`
521
479
 
522
480
  The forward slash character, when placed at the end of a tag definition, causes
@@ -853,7 +811,7 @@ is compiled to:
853
811
 
854
812
  ## Ruby Evaluation
855
813
 
856
- ### Inserting Ruby: `=`
814
+ ### Inserting Ruby: `=` {#inserting_ruby}
857
815
 
858
816
  The equals character is followed by Ruby code. This code is evaluated and the
859
817
  output is inserted into the document. For example:
@@ -964,7 +922,7 @@ is compiled to:
964
922
 
965
923
  ### Whitespace Preservation: `~` {#tilde}
966
924
 
967
- `~` works just like `=`, except that it runs {Haml::Helpers#find\_and\_preserve}
925
+ `~` works just like `=`, except that it runs {Haml::Helpers.preserve}
968
926
  on its input. For example,
969
927
 
970
928
  ~ "Foo\n<pre>Bar\nBaz</pre>"
@@ -1034,7 +992,7 @@ most code but you may have errors with code like the following:
1034
992
 
1035
993
  %span #{'{'}
1036
994
 
1037
- This code will generate a syntax error, complaining about unbalanced brackets.
995
+ This code will generate a syntax error, complaining about unbalanced braces.
1038
996
  In cases like this, the recommended workaround is output the code as a Ruby
1039
997
  string to force Haml to parse the code with Ruby.
1040
998
 
@@ -1125,9 +1083,6 @@ is compiled to
1125
1083
  <p>I <strong>really</strong> prefer <em>raspberry</em> jam.</p>
1126
1084
  </div>
1127
1085
 
1128
- Note that `#{}` interpolation within filters is HTML-escaped if you specify true to
1129
- {Haml::Options#escape_filter_interpolations `:escape_filter_interpolations`} option.
1130
-
1131
1086
  The functionality of some filters such as Markdown can be provided by many
1132
1087
  different libraries. Usually you don't have to worry about this - you can just
1133
1088
  load the gem of your choice and Haml will automatically use it.
@@ -1138,7 +1093,7 @@ uses to implement many of its filters:
1138
1093
 
1139
1094
  Tilt.prefer Tilt::RedCarpetTemplate
1140
1095
 
1141
- See the [Tilt documentation](https://github.com/rtomayko/tilt#fallback-mode) for
1096
+ See the [Tilt documentation](https://github.com/rtomayko/tilt) for
1142
1097
  more info.
1143
1098
 
1144
1099
  Haml comes with the following filters defined:
@@ -1190,7 +1145,7 @@ implemented using Tilt.
1190
1145
 
1191
1146
  ### `:maruku` {#maruku-filter}
1192
1147
 
1193
- Parses the filtered text with [Maruku](https://github.com/nex3/maruku), which
1148
+ Parses the filtered text with [Maruku](https://github.com/bhollis/maruku), which
1194
1149
  has some non-standard extensions to Markdown.
1195
1150
 
1196
1151
  As of Haml 4.0, this filter is defined in [Haml
@@ -1213,11 +1168,8 @@ HTML escape code for newlines, to preserve nice-looking output. See also
1213
1168
 
1214
1169
  ### `:ruby` {#ruby-filter}
1215
1170
 
1216
- Parses the filtered text with the normal Ruby interpreter. Creates an `IO`
1217
- object named `haml_io`, anything written to it is output into the Haml document.
1218
- Not available if the {Haml::Options#suppress_eval `:suppress_eval`} option is
1219
- set to true. The Ruby code is evaluated in the same context as the Haml
1220
- template.
1171
+ Parses the filtered text with the normal Ruby interpreter.
1172
+ The Ruby code is evaluated in the same context as the Haml template.
1221
1173
 
1222
1174
  ### `:sass` {#sass-filter}
1223
1175
 
@@ -1242,43 +1194,44 @@ default. This filter is implemented using Tilt.
1242
1194
 
1243
1195
  ### Custom Filters
1244
1196
 
1245
- You can also define your own filters. See {Haml::Filters} for details.
1197
+ You can also define your own filters.
1198
+ `Haml::Filters::YourCustomFilter#compile` should return
1199
+ [a Temple expression](https://github.com/judofyr/temple/blob/master/EXPRESSIONS.md).
1246
1200
 
1247
- ## Helper Methods {#helper-methods}
1201
+ The simplest example of a filter might be something like:
1248
1202
 
1249
- Sometimes you need to manipulate whitespace in a more precise fashion than what
1250
- the whitespace removal methods allow. There are a few helper methods that are
1251
- useful when dealing with inline content. All these methods take a Haml block to
1252
- modify.
1253
-
1254
- ### surround {#surround}
1255
-
1256
- Surrounds a Haml block with text. Expects 1 or 2 string arguments used to
1257
- surround the Haml block. If a second argument is not provided, the first
1258
- argument is used as the second.
1259
-
1260
- = surround "(", ")" do
1261
- = link_to "learn more", "#"
1262
-
1263
- ### precede {#precede}
1264
-
1265
- Prepends a Haml block with text. Expects 1 argument.
1266
-
1267
- = precede "*" do
1268
- %span Required
1269
-
1270
- ### succeed {#succeed}
1203
+ class HelloFilter < Haml::Filters::Base
1204
+ def compile(_node)
1205
+ [:static, "hello world"]
1206
+ end
1207
+ end
1208
+
1209
+ Haml::Filters.registered[:hello] ||= HelloFilter
1210
+
1211
+ A more complex example:
1212
+
1213
+ class BetterFilter < Haml::Filters::Base
1214
+ def compile(node)
1215
+ temple = [:multi]
1216
+ temple << [:static, "hello "]
1217
+ temple << compile_text(node.value[:text])
1218
+ temple << [:static, " world"]
1219
+ temple
1220
+ end
1221
+
1222
+ private
1223
+ def compile_text(text)
1224
+ if ::Haml::Util.contains_interpolation?(text)
1225
+ [:dynamic, ::Haml::Util.unescape_interpolation(text)]
1226
+ else
1227
+ [:static, text]
1228
+ end
1229
+ end
1230
+ end
1271
1231
 
1272
- Appends a Haml block with text. Expects 1 argument.
1232
+ Haml::Filters.registered[:better] ||= BetterFilter
1273
1233
 
1274
- Begin by
1275
- = succeed "," do
1276
- = link_to "filling out your profile", "#"
1277
- = succeed "," do
1278
- = link_to "adding a bio", "#"
1279
- and
1280
- = succeed "." do
1281
- = link_to "inviting friends", "#"
1234
+ See {Haml::Filters} for examples.
1282
1235
 
1283
1236
  ## Multiline: `|` {#multiline}
1284
1237
 
@@ -1323,9 +1276,9 @@ that just need a lot of template information.
1323
1276
  So data structures and functions that require lots of arguments
1324
1277
  can be wrapped over multiple lines,
1325
1278
  as long as each line but the last ends in a comma
1326
- (see [Inserting Ruby](#inserting_ruby_)).
1279
+ (see [Inserting Ruby](#inserting_ruby)).
1327
1280
 
1328
- ## Whitespace Preservation
1281
+ ## Whitespace Preservation {#whitespace_preservation}
1329
1282
 
1330
1283
  Sometimes you don't want Haml to indent all your text.
1331
1284
  For example, tags like `pre` and `textarea` are whitespace-sensitive;
@@ -1338,14 +1291,26 @@ Haml won't try to re-format the indentation.
1338
1291
  Literal `textarea` and `pre` tags automatically preserve content given through
1339
1292
  `=`. Dynamically-generated `textarea`s and `pre`s can't be preserved
1340
1293
  automatically, and so should be passed through
1341
- {Haml::Helpers#find\_and\_preserve} or the [`~` command](#tilde), which has the
1294
+ {Haml::Helpers.preserve} or the [`~` command](#tilde), which has the
1342
1295
  same effect.
1343
1296
 
1344
1297
  Blocks of literal text can be preserved using the [`:preserve` filter](#preserve-filter).
1345
1298
 
1346
- ## Helpers
1299
+ ## Turbo
1347
1300
 
1348
- Haml offers a bunch of helpers that are useful for doing stuff like preserving
1349
- whitespace, creating nicely indented output for user-defined helpers, and other
1350
- useful things. The helpers are all documented in the {Haml::Helpers} and
1351
- {Haml::Helpers::ActionViewExtensions} modules.
1301
+ For people using Turbo-rails and Haml 6+ need to either:
1302
+ * follow the naming convention with the html format (ie. ensure any `.haml` files end `.html.haml`), or
1303
+ * add a monkey patch as follows:
1304
+
1305
+ ```rb
1306
+ # config/initializers/haml.rb
1307
+ require "haml/rails_template"
1308
+
1309
+ module Haml
1310
+ class RailsTemplate
1311
+ def default_format
1312
+ :html
1313
+ end
1314
+ end
1315
+ end
1316
+ ```
data/Rakefile CHANGED
@@ -1,43 +1,23 @@
1
- require "rake/clean"
2
- require "rake/testtask"
3
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
4
3
 
5
- task :default => :test
6
-
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
4
  Rake::TestTask.new do |t|
16
- t.libs << 'test'
17
- t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] - isolated_test.file_list
18
- t.warning = true
5
+ t.libs << 'lib' << 'test'
6
+ files = Dir['test/haml/**/*_test.rb']
7
+ t.ruby_opts = %w[-rtest_helper]
8
+ t.test_files = files
19
9
  t.verbose = true
20
10
  end
11
+ task :test
21
12
 
22
- CLEAN.replace %w(pkg doc coverage .yardoc test/haml vendor)
23
-
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']}"
27
- end
28
-
29
- task :set_coverage_env do
30
- ENV["COVERAGE"] = "true"
31
- end
32
-
33
- desc "Run Simplecov"
34
- task :coverage => [:set_coverage_env, :test]
35
-
36
- task :submodules do
37
- if File.exist?(File.dirname(__FILE__) + "/.git")
38
- sh %{git submodule sync}
39
- sh %{git submodule update --init --recursive}
13
+ desc 'bench task for CI'
14
+ task :bench do
15
+ if ENV['SLIM_BENCH'] == '1'
16
+ cmd = %w[bundle exec ruby benchmark/slim/run-benchmarks.rb]
17
+ else
18
+ cmd = ['bin/bench', 'bench', ('-c' if ENV['COMPILE'] == '1'), *ENV['TEMPLATE'].split(',')].compact
40
19
  end
20
+ exit system(*cmd)
41
21
  end
42
22
 
43
23
  namespace :doc do
@@ -65,58 +45,4 @@ task(:doc => 'doc:sass') {sh "yard"}
65
45
  desc "Generate documentation incrementally"
66
46
  task(:redoc) {sh "yard -c"}
67
47
 
68
- desc <<END
69
- Profile Haml.
70
- TIMES=n sets the number of runs. Defaults to 1000.
71
- FILE=str sets the file to profile. Defaults to 'standard'
72
- OUTPUT=str sets the ruby-prof output format.
73
- Can be Flat, CallInfo, or Graph. Defaults to Flat. Defaults to Flat.
74
- END
75
- task :profile do
76
- times = (ENV['TIMES'] || '1000').to_i
77
- file = ENV['FILE'] || 'test/templates/standard.haml'
78
-
79
- require 'bundler/setup'
80
- require 'ruby-prof'
81
- require 'haml'
82
- file = File.read(File.expand_path("../#{file}", __FILE__))
83
- obj = Object.new
84
- Haml::Engine.new(file).def_method(obj, :render)
85
- result = RubyProf.profile { times.times { obj.render } }
86
-
87
- RubyProf.const_get("#{(ENV['OUTPUT'] || 'Flat').capitalize}Printer").new(result).print
88
- end
89
-
90
- def gemfiles
91
- @gemfiles ||= Dir[File.dirname(__FILE__) + '/test/gemfiles/Gemfile.*'].reject {|f| f =~ /\.lock$/}
92
- end
93
-
94
- def with_each_gemfile
95
- gemfiles.each do |gemfile|
96
- Bundler.with_clean_env do
97
- puts "Using gemfile: #{gemfile}"
98
- ENV['BUNDLE_GEMFILE'] = gemfile
99
- yield
100
- end
101
- end
102
- end
103
-
104
- namespace :test do
105
- namespace :bundles do
106
- desc "Install all dependencies necessary to test Haml."
107
- task :install do
108
- with_each_gemfile {sh "bundle"}
109
- end
110
-
111
- desc "Update all dependencies for testing Haml."
112
- task :update do
113
- with_each_gemfile {sh "bundle update"}
114
- end
115
- end
116
-
117
- desc "Test all supported versions of rails. This takes a while."
118
- task :rails_compatibility => 'test:bundles:install' do
119
- with_each_gemfile {sh "bundle exec rake test"}
120
- end
121
- task :rc => :rails_compatibility
122
- end
48
+ task default: :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