haml 5.0.4 → 6.0.0

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