haml 5.2.2 → 6.0.0.beta.1

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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/test.yml +13 -9
  4. data/.gitignore +16 -16
  5. data/CHANGELOG.md +13 -3
  6. data/Gemfile +18 -11
  7. data/MIT-LICENSE +1 -1
  8. data/README.md +13 -19
  9. data/Rakefile +95 -93
  10. data/bin/bench +66 -0
  11. data/bin/console +11 -0
  12. data/bin/ruby +3 -0
  13. data/bin/setup +7 -0
  14. data/bin/stackprof +27 -0
  15. data/bin/test +24 -0
  16. data/exe/haml +6 -0
  17. data/ext/haml/extconf.rb +10 -0
  18. data/ext/haml/haml.c +537 -0
  19. data/ext/haml/hescape.c +108 -0
  20. data/ext/haml/hescape.h +20 -0
  21. data/haml.gemspec +39 -37
  22. data/lib/haml/ambles.rb +20 -0
  23. data/lib/haml/attribute_builder.rb +135 -179
  24. data/lib/haml/attribute_compiler.rb +85 -194
  25. data/lib/haml/attribute_parser.rb +86 -126
  26. data/lib/haml/cli.rb +154 -0
  27. data/lib/haml/compiler/children_compiler.rb +126 -0
  28. data/lib/haml/compiler/comment_compiler.rb +39 -0
  29. data/lib/haml/compiler/doctype_compiler.rb +46 -0
  30. data/lib/haml/compiler/script_compiler.rb +116 -0
  31. data/lib/haml/compiler/silent_script_compiler.rb +24 -0
  32. data/lib/haml/compiler/tag_compiler.rb +76 -0
  33. data/lib/haml/compiler.rb +63 -296
  34. data/lib/haml/dynamic_merger.rb +67 -0
  35. data/lib/haml/engine.rb +42 -227
  36. data/lib/haml/error.rb +3 -52
  37. data/lib/haml/escapable.rb +6 -70
  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 +49 -0
  54. data/lib/haml/filters.rb +54 -378
  55. data/lib/haml/force_escapable.rb +29 -0
  56. data/lib/haml/haml_error.rb +66 -0
  57. data/lib/haml/helpers.rb +3 -697
  58. data/lib/haml/html.rb +22 -0
  59. data/lib/haml/identity.rb +13 -0
  60. data/lib/haml/object_ref.rb +30 -0
  61. data/lib/haml/parser.rb +179 -49
  62. data/lib/haml/rails_helpers.rb +51 -0
  63. data/lib/haml/rails_template.rb +55 -0
  64. data/lib/haml/railtie.rb +7 -45
  65. data/lib/haml/ruby_expression.rb +32 -0
  66. data/lib/haml/string_splitter.rb +20 -0
  67. data/lib/haml/template.rb +15 -34
  68. data/lib/haml/temple_line_counter.rb +2 -1
  69. data/lib/haml/util.rb +17 -15
  70. data/lib/haml/version.rb +1 -2
  71. data/lib/haml.rb +8 -20
  72. metadata +211 -57
  73. data/.gitmodules +0 -3
  74. data/.yardopts +0 -22
  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 -182
  80. data/lib/haml/exec.rb +0 -347
  81. data/lib/haml/generator.rb +0 -42
  82. data/lib/haml/helpers/action_view_extensions.rb +0 -60
  83. data/lib/haml/helpers/action_view_mods.rb +0 -132
  84. data/lib/haml/helpers/action_view_xss_mods.rb +0 -60
  85. data/lib/haml/helpers/safe_erubi_template.rb +0 -20
  86. data/lib/haml/helpers/safe_erubis_template.rb +0 -33
  87. data/lib/haml/helpers/xss_mods.rb +0 -114
  88. data/lib/haml/options.rb +0 -273
  89. data/lib/haml/plugin.rb +0 -54
  90. data/lib/haml/sass_rails_filter.rb +0 -47
  91. data/lib/haml/template/options.rb +0 -27
  92. data/lib/haml/temple_engine.rb +0 -124
  93. data/yard/default/.gitignore +0 -1
  94. data/yard/default/fulldoc/html/css/common.sass +0 -15
  95. data/yard/default/layout/html/footer.erb +0 -12
data/lib/haml/helpers.rb CHANGED
@@ -1,709 +1,15 @@
1
1
  # frozen_string_literal: true
2
-
3
- require 'erb'
4
-
5
2
  module Haml
6
- # This module contains various helpful methods to make it easier to do various tasks.
7
- # {Haml::Helpers} is automatically included in the context
8
- # that a Haml template is parsed in, so all these methods are at your
9
- # disposal from within the template.
10
3
  module Helpers
11
- # An object that raises an error when \{#to\_s} is called.
12
- # It's used to raise an error when the return value of a helper is used
13
- # when it shouldn't be.
14
- class ErrorReturn
15
- def initialize(method)
16
- @message = <<MESSAGE
17
- #{method} outputs directly to the Haml template.
18
- Disregard its return value and use the - operator,
19
- or use capture_haml to get the value as a String.
20
- MESSAGE
21
- end
22
-
23
- # Raises an error.
24
- #
25
- # @raise [Haml::Error] The error
26
- def to_s
27
- raise Haml::Error.new(@message)
28
- rescue Haml::Error => e
29
- e.backtrace.shift
30
-
31
- # If the ErrorReturn is used directly in the template,
32
- # we don't want Haml's stuff to get into the backtrace,
33
- # so we get rid of the format_script line.
34
- #
35
- # We also have to subtract one from the Haml line number
36
- # since the value is passed to format_script the line after
37
- # it's actually used.
38
- if e.backtrace.first =~ /^\(eval\):\d+:in `format_script/
39
- e.backtrace.shift
40
- e.backtrace.first.gsub!(/^\(haml\):(\d+)/) {|s| "(haml):#{$1.to_i - 1}"}
41
- end
42
- raise e
43
- end
44
-
45
- # @return [String] A human-readable string representation
46
- def inspect
47
- "Haml::Helpers::ErrorReturn(#{@message.inspect})"
48
- end
49
- end
50
-
51
- self.extend self
52
-
53
- @@action_view_defined = false
54
-
55
- # @return [Boolean] Whether or not ActionView is loaded
56
- def self.action_view?
57
- @@action_view_defined
58
- end
59
-
60
- # Note: this does **not** need to be called when using Haml helpers
61
- # normally in Rails.
62
- #
63
- # Initializes the current object as though it were in the same context
64
- # as a normal ActionView instance using Haml.
65
- # This is useful if you want to use the helpers in a context
66
- # other than the normal setup with ActionView.
67
- # For example:
68
- #
69
- # context = Object.new
70
- # class << context
71
- # include Haml::Helpers
72
- # end
73
- # context.init_haml_helpers
74
- # context.haml_tag :p, "Stuff"
75
- #
76
- def init_haml_helpers
77
- @haml_buffer = Haml::Buffer.new(haml_buffer, Options.new.for_buffer)
78
- nil
79
- end
80
-
81
- # Runs a block of code in a non-Haml context
82
- # (i.e. \{#is\_haml?} will return false).
83
- #
84
- # This is mainly useful for rendering sub-templates such as partials in a non-Haml language,
85
- # particularly where helpers may behave differently when run from Haml.
86
- #
87
- # Note that this is automatically applied to Rails partials.
88
- #
89
- # @yield A block which won't register as Haml
90
- def non_haml
91
- was_active = @haml_buffer.active?
92
- @haml_buffer.active = false
93
- yield
94
- ensure
95
- @haml_buffer.active = was_active
96
- end
97
-
98
- # Uses \{#preserve} to convert any newlines inside whitespace-sensitive tags
99
- # into the HTML entities for endlines.
100
- #
101
- # @param tags [Array<String>] Tags that should have newlines escaped
102
- #
103
- # @overload find_and_preserve(input, tags = haml_buffer.options[:preserve])
104
- # Escapes newlines within a string.
105
- #
106
- # @param input [String] The string within which to escape newlines
107
- # @overload find_and_preserve(tags = haml_buffer.options[:preserve])
108
- # Escapes newlines within a block of Haml code.
109
- #
110
- # @yield The block within which to escape newlines
111
- def find_and_preserve(input = nil, tags = haml_buffer.options[:preserve], &block)
112
- return find_and_preserve(capture_haml(&block), input || tags) if block
113
- tags = tags.map { |tag| Regexp.escape(tag) }.join('|')
114
- re = /<(#{tags})([^>]*)>(.*?)(<\/\1>)/im
115
- input.to_s.gsub(re) do |s|
116
- s =~ re # Can't rely on $1, etc. existing since Rails' SafeBuffer#gsub is incompatible
117
- "<#{$1}#{$2}>#{preserve($3)}</#{$1}>"
118
- end
119
- end
120
-
121
- # Takes any string, finds all the newlines, and converts them to
122
- # HTML entities so they'll render correctly in
123
- # whitespace-sensitive tags without screwing up the indentation.
124
- #
125
- # @overload preserve(input)
126
- # Escapes newlines within a string.
127
- #
128
- # @param input [String] The string within which to escape all newlines
129
- # @overload preserve
130
- # Escapes newlines within a block of Haml code.
131
- #
132
- # @yield The block within which to escape newlines
133
- def preserve(input = nil, &block)
134
- return preserve(capture_haml(&block)) if block
4
+ def self.preserve(input)
135
5
  s = input.to_s.chomp("\n")
136
6
  s.gsub!(/\n/, '&#x000A;')
137
7
  s.delete!("\r")
138
8
  s
139
9
  end
140
- alias_method :flatten, :preserve
141
-
142
- # Takes an `Enumerable` object and a block
143
- # and iterates over the enum,
144
- # yielding each element to a Haml block
145
- # and putting the result into `<li>` elements.
146
- # This creates a list of the results of the block.
147
- # For example:
148
- #
149
- # = list_of([['hello'], ['yall']]) do |i|
150
- # = i[0]
151
- #
152
- # Produces:
153
- #
154
- # <li>hello</li>
155
- # <li>yall</li>
156
- #
157
- # And:
158
- #
159
- # = list_of({:title => 'All the stuff', :description => 'A book about all the stuff.'}) do |key, val|
160
- # %h3= key.humanize
161
- # %p= val
162
- #
163
- # Produces:
164
- #
165
- # <li>
166
- # <h3>Title</h3>
167
- # <p>All the stuff</p>
168
- # </li>
169
- # <li>
170
- # <h3>Description</h3>
171
- # <p>A book about all the stuff.</p>
172
- # </li>
173
- #
174
- # While:
175
- #
176
- # = list_of(["Home", "About", "Contact", "FAQ"], {class: "nav", role: "nav"}) do |item|
177
- # %a{ href="#" }= item
178
- #
179
- # Produces:
180
- #
181
- # <li class='nav' role='nav'>
182
- # <a href='#'>Home</a>
183
- # </li>
184
- # <li class='nav' role='nav'>
185
- # <a href='#'>About</a>
186
- # </li>
187
- # <li class='nav' role='nav'>
188
- # <a href='#'>Contact</a>
189
- # </li>
190
- # <li class='nav' role='nav'>
191
- # <a href='#'>FAQ</a>
192
- # </li>
193
- #
194
- # `[[class", "nav"], [role", "nav"]]` could have been used instead of `{class: "nav", role: "nav"}` (or any enumerable collection where each pair of items responds to #to_s)
195
- #
196
- # @param enum [Enumerable] The list of objects to iterate over
197
- # @param [Enumerable<#to_s,#to_s>] opts Each key/value pair will become an attribute pair for each list item element.
198
- # @yield [item] A block which contains Haml code that goes within list items
199
- # @yieldparam item An element of `enum`
200
- def list_of(enum, opts={}, &block)
201
- opts_attributes = opts.map { |k, v| " #{k}='#{v}'" }.join
202
- enum.map do |i|
203
- result = capture_haml(i, &block)
204
-
205
- if result.count("\n") > 1
206
- result.gsub!("\n", "\n ")
207
- result = "\n #{result.strip}\n"
208
- else
209
- result.strip!
210
- end
211
-
212
- %Q!<li#{opts_attributes}>#{result}</li>!
213
- end.join("\n")
214
- end
215
-
216
- # Returns a hash containing default assignments for the `xmlns`, `lang`, and `xml:lang`
217
- # attributes of the `html` HTML element.
218
- # For example,
219
- #
220
- # %html{html_attrs}
221
- #
222
- # becomes
223
- #
224
- # <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-US' lang='en-US'>
225
- #
226
- # @param lang [String] The value of `xml:lang` and `lang`
227
- # @return [{#to_s => String}] The attribute hash
228
- def html_attrs(lang = 'en-US')
229
- if haml_buffer.options[:format] == :xhtml
230
- {:xmlns => "http://www.w3.org/1999/xhtml", 'xml:lang' => lang, :lang => lang}
231
- else
232
- {:lang => lang}
233
- end
234
- end
235
-
236
- # Increments the number of tabs the buffer automatically adds
237
- # to the lines of the template.
238
- # For example:
239
- #
240
- # %h1 foo
241
- # - tab_up
242
- # %p bar
243
- # - tab_down
244
- # %strong baz
245
- #
246
- # Produces:
247
- #
248
- # <h1>foo</h1>
249
- # <p>bar</p>
250
- # <strong>baz</strong>
251
- #
252
- # @param i [Fixnum] The number of tabs by which to increase the indentation
253
- # @see #tab_down
254
- def tab_up(i = 1)
255
- haml_buffer.tabulation += i
256
- end
257
-
258
- # Decrements the number of tabs the buffer automatically adds
259
- # to the lines of the template.
260
- #
261
- # @param i [Fixnum] The number of tabs by which to decrease the indentation
262
- # @see #tab_up
263
- def tab_down(i = 1)
264
- haml_buffer.tabulation -= i
265
- end
266
-
267
- # Sets the number of tabs the buffer automatically adds
268
- # to the lines of the template,
269
- # but only for the duration of the block.
270
- # For example:
271
- #
272
- # %h1 foo
273
- # - with_tabs(2) do
274
- # %p bar
275
- # %strong baz
276
- #
277
- # Produces:
278
- #
279
- # <h1>foo</h1>
280
- # <p>bar</p>
281
- # <strong>baz</strong>
282
- #
283
- #
284
- # @param i [Fixnum] The number of tabs to use
285
- # @yield A block in which the indentation will be `i` spaces
286
- def with_tabs(i)
287
- old_tabs = haml_buffer.tabulation
288
- haml_buffer.tabulation = i
289
- yield
290
- ensure
291
- haml_buffer.tabulation = old_tabs
292
- end
293
-
294
- # Surrounds a block of Haml code with strings,
295
- # with no whitespace in between.
296
- # For example:
297
- #
298
- # = surround '(', ')' do
299
- # %a{:href => "food"} chicken
300
- #
301
- # Produces:
302
- #
303
- # (<a href='food'>chicken</a>)
304
- #
305
- # and
306
- #
307
- # = surround '*' do
308
- # %strong angry
309
- #
310
- # Produces:
311
- #
312
- # *<strong>angry</strong>*
313
- #
314
- # @param front [String] The string to add before the Haml
315
- # @param back [String] The string to add after the Haml
316
- # @yield A block of Haml to surround
317
- def surround(front, back = front, &block)
318
- output = capture_haml(&block)
319
-
320
- "#{front}#{output.chomp}#{back}\n"
321
- end
322
-
323
- # Prepends a string to the beginning of a Haml block,
324
- # with no whitespace between.
325
- # For example:
326
- #
327
- # = precede '*' do
328
- # %span.small Not really
329
- #
330
- # Produces:
331
- #
332
- # *<span class='small'>Not really</span>
333
- #
334
- # @param str [String] The string to add before the Haml
335
- # @yield A block of Haml to prepend to
336
- def precede(str, &block)
337
- "#{str}#{capture_haml(&block).chomp}\n"
338
- end
339
-
340
- # Appends a string to the end of a Haml block,
341
- # with no whitespace between.
342
- # For example:
343
- #
344
- # click
345
- # = succeed '.' do
346
- # %a{:href=>"thing"} here
347
- #
348
- # Produces:
349
- #
350
- # click
351
- # <a href='thing'>here</a>.
352
- #
353
- # @param str [String] The string to add after the Haml
354
- # @yield A block of Haml to append to
355
- def succeed(str, &block)
356
- "#{capture_haml(&block).chomp}#{str}\n"
357
- end
358
-
359
- # Captures the result of a block of Haml code,
360
- # gets rid of the excess indentation,
361
- # and returns it as a string.
362
- # For example, after the following,
363
- #
364
- # .foo
365
- # - foo = capture_haml(13) do |a|
366
- # %p= a
367
- #
368
- # the local variable `foo` would be assigned to `"<p>13</p>\n"`.
369
- #
370
- # @param args [Array] Arguments to pass into the block
371
- # @yield [args] A block of Haml code that will be converted to a string
372
- # @yieldparam args [Array] `args`
373
- def capture_haml(*args, &block)
374
- buffer = eval('if defined? _hamlout then _hamlout else nil end', block.binding) || haml_buffer
375
- with_haml_buffer(buffer) do
376
- position = haml_buffer.buffer.length
377
-
378
- haml_buffer.capture_position = position
379
- value = block.call(*args)
380
-
381
- captured = haml_buffer.buffer.slice!(position..-1)
382
-
383
- if captured == '' and value != haml_buffer.buffer
384
- captured = (value.is_a?(String) ? value : nil)
385
- end
386
-
387
- captured
388
- end
389
- ensure
390
- haml_buffer.capture_position = nil
391
- end
392
-
393
- # Outputs text directly to the Haml buffer, with the proper indentation.
394
- #
395
- # @param text [#to_s] The text to output
396
- def haml_concat(text = "")
397
- haml_internal_concat text
398
- ErrorReturn.new("haml_concat")
399
- end
400
-
401
- # Internal method to write directly to the buffer with control of
402
- # whether the first line should be indented, and if there should be a
403
- # final newline.
404
- #
405
- # Lines added will have the proper indentation. This can be controlled
406
- # for the first line.
407
- #
408
- # Used by #haml_concat and #haml_tag.
409
- #
410
- # @param text [#to_s] The text to output
411
- # @param newline [Boolean] Whether to add a newline after the text
412
- # @param indent [Boolean] Whether to add indentation to the first line
413
- def haml_internal_concat(text = "", newline = true, indent = true)
414
- if haml_buffer.tabulation == 0
415
- haml_buffer.buffer << "#{text}#{"\n" if newline}"
416
- else
417
- haml_buffer.buffer << %[#{haml_indent if indent}#{text.to_s.gsub("\n", "\n#{haml_indent}")}#{"\n" if newline}]
418
- end
419
- end
420
- private :haml_internal_concat
421
-
422
- # Allows writing raw content. `haml_internal_concat_raw` isn't
423
- # effected by XSS mods. Used by #haml_tag to write the actual tags.
424
- alias :haml_internal_concat_raw :haml_internal_concat
425
-
426
- # @return [String] The indentation string for the current line
427
- def haml_indent
428
- ' ' * haml_buffer.tabulation
429
- end
430
-
431
- # Creates an HTML tag with the given name and optionally text and attributes.
432
- # Can take a block that will run between the opening and closing tags.
433
- # If the block is a Haml block or outputs text using \{#haml\_concat},
434
- # the text will be properly indented.
435
- #
436
- # `name` can be a string using the standard Haml class/id shorthand
437
- # (e.g. "span#foo.bar", "#foo").
438
- # Just like standard Haml tags, these class and id values
439
- # will be merged with manually-specified attributes.
440
- #
441
- # `flags` is a list of symbol flags
442
- # like those that can be put at the end of a Haml tag
443
- # (`:/`, `:<`, and `:>`).
444
- # Currently, only `:/` and `:<` are supported.
445
- #
446
- # `haml_tag` outputs directly to the buffer;
447
- # its return value should not be used.
448
- # If you need to get the results as a string,
449
- # use \{#capture\_haml\}.
450
- #
451
- # For example,
452
- #
453
- # haml_tag :table do
454
- # haml_tag :tr do
455
- # haml_tag 'td.cell' do
456
- # haml_tag :strong, "strong!"
457
- # haml_concat "data"
458
- # end
459
- # haml_tag :td do
460
- # haml_concat "more_data"
461
- # end
462
- # end
463
- # end
464
- #
465
- # outputs
466
- #
467
- # <table>
468
- # <tr>
469
- # <td class='cell'>
470
- # <strong>
471
- # strong!
472
- # </strong>
473
- # data
474
- # </td>
475
- # <td>
476
- # more_data
477
- # </td>
478
- # </tr>
479
- # </table>
480
- #
481
- # @param name [#to_s] The name of the tag
482
- #
483
- # @overload haml_tag(name, *rest, attributes = {})
484
- # @yield The block of Haml code within the tag
485
- # @overload haml_tag(name, text, *flags, attributes = {})
486
- # @param text [#to_s] The text within the tag
487
- # @param flags [Array<Symbol>] Haml end-of-tag flags
488
- def haml_tag(name, *rest, &block)
489
- ret = ErrorReturn.new("haml_tag")
490
-
491
- text = rest.shift.to_s unless [Symbol, Hash, NilClass].any? {|t| rest.first.is_a? t}
492
- flags = []
493
- flags << rest.shift while rest.first.is_a? Symbol
494
- attrs = (rest.shift || {})
495
- attrs.keys.each {|key| attrs[key.to_s] = attrs.delete(key)} unless attrs.empty?
496
- name, attrs = merge_name_and_attributes(name.to_s, attrs)
497
-
498
- attributes = Haml::AttributeBuilder.build_attributes(haml_buffer.html?,
499
- haml_buffer.options[:attr_wrapper],
500
- haml_buffer.options[:escape_attrs],
501
- haml_buffer.options[:hyphenate_data_attrs],
502
- attrs)
503
-
504
- if text.nil? && block.nil? && (haml_buffer.options[:autoclose].include?(name) || flags.include?(:/))
505
- haml_internal_concat_raw "<#{name}#{attributes}#{' /' if haml_buffer.options[:format] == :xhtml}>"
506
- return ret
507
- end
508
-
509
- if flags.include?(:/)
510
- raise Error.new(Error.message(:self_closing_content)) if text
511
- raise Error.new(Error.message(:illegal_nesting_self_closing)) if block
512
- end
513
-
514
- tag = "<#{name}#{attributes}>"
515
- end_tag = "</#{name}>"
516
- if block.nil?
517
- text = text.to_s
518
- if text.include?("\n")
519
- haml_internal_concat_raw tag
520
- tab_up
521
- haml_internal_concat text
522
- tab_down
523
- haml_internal_concat_raw end_tag
524
- else
525
- haml_internal_concat_raw tag, false
526
- haml_internal_concat text, false, false
527
- haml_internal_concat_raw end_tag, true, false
528
- end
529
- return ret
530
- end
531
-
532
- if text
533
- raise Error.new(Error.message(:illegal_nesting_line, name))
534
- end
535
-
536
- if flags.include?(:<)
537
- haml_internal_concat_raw tag, false
538
- haml_internal_concat "#{capture_haml(&block).strip}", false, false
539
- haml_internal_concat_raw end_tag, true, false
540
- return ret
541
- end
542
-
543
- haml_internal_concat_raw tag
544
- tab_up
545
- block.call
546
- tab_down
547
- haml_internal_concat_raw end_tag
548
-
549
- ret
550
- end
551
10
 
552
- # Conditionally wrap a block in an element. If `condition` is `true` then
553
- # this method renders the tag described by the arguments in `tag` (using
554
- # \{#haml_tag}) with the given block inside, otherwise it just renders the block.
555
- #
556
- # For example,
557
- #
558
- # - haml_tag_if important, '.important' do
559
- # %p
560
- # A (possibly) important paragraph.
561
- #
562
- # will produce
563
- #
564
- # <div class='important'>
565
- # <p>
566
- # A (possibly) important paragraph.
567
- # </p>
568
- # </div>
569
- #
570
- # if `important` is truthy, and just
571
- #
572
- # <p>
573
- # A (possibly) important paragraph.
574
- # </p>
575
- #
576
- # otherwise.
577
- #
578
- # Like \{#haml_tag}, `haml_tag_if` outputs directly to the buffer and its
579
- # return value should not be used. Use \{#capture_haml} if you need to use
580
- # its results as a string.
581
- #
582
- # @param condition The condition to test to determine whether to render
583
- # the enclosing tag
584
- # @param tag Definition of the enclosing tag. See \{#haml_tag} for details
585
- # (specifically the form that takes a block)
586
- def haml_tag_if(condition, *tag)
587
- if condition
588
- haml_tag(*tag){ yield }
589
- else
590
- yield
591
- end
592
- ErrorReturn.new("haml_tag_if")
11
+ def preserve(input)
12
+ Helpers.preserve(input)
593
13
  end
594
-
595
- # Characters that need to be escaped to HTML entities from user input
596
- HTML_ESCAPE = {'&' => '&amp;', '<' => '&lt;', '>' => '&gt;', '"' => '&quot;', "'" => '&#39;'}.freeze
597
-
598
- HTML_ESCAPE_REGEX = /['"><&]/
599
-
600
- # Returns a copy of `text` with ampersands, angle brackets and quotes
601
- # escaped into HTML entities.
602
- #
603
- # Note that if ActionView is loaded and XSS protection is enabled
604
- # (as is the default for Rails 3.0+, and optional for version 2.3.5+),
605
- # this won't escape text declared as "safe".
606
- #
607
- # @param text [String] The string to sanitize
608
- # @return [String] The sanitized string
609
- def html_escape(text)
610
- CGI.escapeHTML(text.to_s)
611
- end
612
-
613
- # Always escape text regardless of html_safe?
614
- alias_method :html_escape_without_haml_xss, :html_escape
615
-
616
- HTML_ESCAPE_ONCE_REGEX = /['"><]|&(?!(?:[a-zA-Z]+|#(?:\d+|[xX][0-9a-fA-F]+));)/
617
-
618
- # Escapes HTML entities in `text`, but without escaping an ampersand
619
- # that is already part of an escaped entity.
620
- #
621
- # @param text [String] The string to sanitize
622
- # @return [String] The sanitized string
623
- def escape_once(text)
624
- text = text.to_s
625
- text.gsub(HTML_ESCAPE_ONCE_REGEX, HTML_ESCAPE)
626
- end
627
-
628
- # Always escape text once regardless of html_safe?
629
- alias_method :escape_once_without_haml_xss, :escape_once
630
-
631
- # Returns whether or not the current template is a Haml template.
632
- #
633
- # This function, unlike other {Haml::Helpers} functions,
634
- # also works in other `ActionView` templates,
635
- # where it will always return false.
636
- #
637
- # @return [Boolean] Whether or not the current template is a Haml template
638
- def is_haml?
639
- !@haml_buffer.nil? && @haml_buffer.active?
640
- end
641
-
642
- # Returns whether or not `block` is defined directly in a Haml template.
643
- #
644
- # @param block [Proc] A Ruby block
645
- # @return [Boolean] Whether or not `block` is defined directly in a Haml template
646
- def block_is_haml?(block)
647
- eval('!!defined?(_hamlout)', block.binding)
648
- end
649
-
650
- private
651
-
652
- # Parses the tag name used for \{#haml\_tag}
653
- # and merges it with the Ruby attributes hash.
654
- def merge_name_and_attributes(name, attributes_hash = {})
655
- # skip merging if no ids or classes found in name
656
- return name, attributes_hash unless name =~ /^(.+?)?([\.#].*)$/
657
-
658
- return $1 || "div", AttributeBuilder.merge_attributes!(
659
- Haml::Parser.parse_class_and_id($2), attributes_hash)
660
- end
661
-
662
- # Runs a block of code with the given buffer as the currently active buffer.
663
- #
664
- # @param buffer [Haml::Buffer] The Haml buffer to use temporarily
665
- # @yield A block in which the given buffer should be used
666
- def with_haml_buffer(buffer)
667
- @haml_buffer, old_buffer = buffer, @haml_buffer
668
- old_buffer.active, old_was_active = false, old_buffer.active? if old_buffer
669
- @haml_buffer.active, was_active = true, @haml_buffer.active?
670
- yield
671
- ensure
672
- @haml_buffer.active = was_active
673
- old_buffer.active = old_was_active if old_buffer
674
- @haml_buffer = old_buffer
675
- end
676
-
677
- # The current {Haml::Buffer} object.
678
- #
679
- # @return [Haml::Buffer]
680
- def haml_buffer
681
- @haml_buffer if defined? @haml_buffer
682
- end
683
-
684
- # Gives a proc the same local `_hamlout` and `_erbout` variables
685
- # that the current template has.
686
- #
687
- # @param proc [#call] The proc to bind
688
- # @return [Proc] A new proc with the new variables bound
689
- def haml_bind_proc(&proc)
690
- _hamlout = haml_buffer
691
- #double assignment is to avoid warnings
692
- _erbout = _erbout = _hamlout.buffer
693
- proc { |*args| proc.call(*args) }
694
- end
695
- end
696
- end
697
-
698
- # @private
699
- class Object
700
- # Haml overrides various `ActionView` helpers,
701
- # which call an \{#is\_haml?} method
702
- # to determine whether or not the current context object
703
- # is a proper Haml context.
704
- # Because `ActionView` helpers may be included in non-`ActionView::Base` classes,
705
- # it's a good idea to define \{#is\_haml?} for all objects.
706
- def is_haml?
707
- false
708
14
  end
709
15
  end