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
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Sass < TiltBase
5
+ def compile(node)
6
+ require 'tilt/sass' if explicit_require?('sass')
7
+ temple = [:multi]
8
+ temple << [:static, "<style>\n"]
9
+ temple << compile_with_tilt(node, 'sass', indent_width: 2)
10
+ temple << [:static, "</style>"]
11
+ temple
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Scss < TiltBase
5
+ def compile(node)
6
+ require 'tilt/sass' if explicit_require?('scss')
7
+ temple = [:multi]
8
+ temple << [:static, "<style>\n"]
9
+ temple << compile_with_tilt(node, 'scss', indent_width: 2)
10
+ temple << [:static, "</style>"]
11
+ temple
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class TextBase < Base
5
+ def compile_text!(temple, node, prefix)
6
+ text = node.value[:text].rstrip.gsub(/^/, prefix)
7
+ if ::Haml::Util.contains_interpolation?(node.value[:text])
8
+ # original: Haml::Filters#compile
9
+ text = ::Haml::Util.unescape_interpolation(text).gsub(/(\\+)n/) do |s|
10
+ escapes = $1.size
11
+ next s if escapes % 2 == 0
12
+ "#{'\\' * (escapes - 1)}\n"
13
+ end
14
+ text.prepend("\n")
15
+ temple << [:dynamic, text]
16
+ else
17
+ node.value[:text].split("\n").size.times do
18
+ temple << [:newline]
19
+ end
20
+ temple << [:static, text]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ require 'tilt'
3
+
4
+ module Haml
5
+ class Filters
6
+ class TiltBase < Base
7
+ def self.render(name, source, indent_width: 0)
8
+ text = ::Tilt["t.#{name}"].new { source }.render
9
+ return text if indent_width == 0
10
+ text.gsub!(/^/, ' ' * indent_width)
11
+ end
12
+
13
+ def explicit_require?(needed_registration)
14
+ Gem::Version.new(Tilt::VERSION) >= Gem::Version.new('2.0.0') &&
15
+ !Tilt.registered?(needed_registration)
16
+ end
17
+
18
+ private
19
+
20
+ def compile_with_tilt(node, name, indent_width: 0)
21
+ if ::Haml::Util.contains_interpolation?(node.value[:text])
22
+ dynamic_compile(node, name, indent_width: indent_width)
23
+ else
24
+ static_compile(node, name, indent_width: indent_width)
25
+ end
26
+ end
27
+
28
+ def static_compile(node, name, indent_width: 0)
29
+ temple = [:multi, [:static, TiltBase.render(name, node.value[:text], indent_width: indent_width)]]
30
+ node.value[:text].split("\n").size.times do
31
+ temple << [:newline]
32
+ end
33
+ temple
34
+ end
35
+
36
+ def dynamic_compile(node, name, indent_width: 0)
37
+ # original: Haml::Filters#compile
38
+ text = ::Haml::Util.unescape_interpolation(node.value[:text]).gsub(/(\\+)n/) do |s|
39
+ escapes = $1.size
40
+ next s if escapes % 2 == 0
41
+ "#{'\\' * (escapes - 1)}\n"
42
+ end
43
+ text.prepend("\n").sub!(/\n"\z/, '"')
44
+
45
+ [:dynamic, "::Haml::Filters::TiltBase.render('#{name}', #{text}, indent_width: #{indent_width})"]
46
+ end
47
+ end
48
+ end
49
+ end
data/lib/haml/filters.rb CHANGED
@@ -1,398 +1,75 @@
1
- # frozen_string_literal: false
2
- require "tilt"
1
+ # frozen_string_literal: true
2
+ require 'haml/filters/base'
3
+ require 'haml/filters/text_base'
4
+ require 'haml/filters/tilt_base'
5
+ require 'haml/filters/coffee'
6
+ require 'haml/filters/css'
7
+ require 'haml/filters/erb'
8
+ require 'haml/filters/escaped'
9
+ require 'haml/filters/javascript'
10
+ require 'haml/filters/less'
11
+ require 'haml/filters/markdown'
12
+ require 'haml/filters/plain'
13
+ require 'haml/filters/preserve'
14
+ require 'haml/filters/ruby'
15
+ require 'haml/filters/sass'
16
+ require 'haml/filters/scss'
17
+ require 'haml/filters/cdata'
3
18
 
4
19
  module Haml
5
- # The module containing the default Haml filters,
6
- # as well as the base module, {Haml::Filters::Base}.
7
- #
8
- # @see Haml::Filters::Base
9
- module Filters
20
+ class Filters
21
+ @registered = {}
10
22
 
11
- extend self
23
+ class << self
24
+ attr_reader :registered
12
25
 
13
- # @return [{String => Haml::Filters::Base}] a hash mapping filter names to
14
- # classes.
15
- attr_reader :defined
16
- @defined = {}
17
-
18
- # Loads an external template engine from
19
- # [Tilt](https://github.com/rtomayko/tilt) as a filter. This method is used
20
- # internally by Haml to set up filters for Sass, SCSS, Less, Coffeescript,
21
- # and others. It's left public to make it easy for developers to add their
22
- # own Tilt-based filters if they choose.
23
- #
24
- # @return [Module] The generated filter.
25
- # @param [Hash] options Options for generating the filter module.
26
- # @option options [Boolean] :precompiled Whether the filter should be
27
- # precompiled. Erb, Nokogiri and Builder use this, for example.
28
- # @option options [Class] :template_class The Tilt template class to use,
29
- # in the event it can't be inferred from an extension.
30
- # @option options [String] :extension The extension associated with the
31
- # content, for example "markdown". This lets Tilt choose the preferred
32
- # engine when there are more than one.
33
- # @option options [String,Array<String>] :alias Any aliases for the filter.
34
- # For example, :coffee is also available as :coffeescript.
35
- # @option options [String] :extend The name of a module to extend when
36
- # defining the filter. Defaults to "Plain". This allows filters such as
37
- # Coffee to "inherit" from Javascript, wrapping its output in script tags.
38
- # @since 4.0
39
- def register_tilt_filter(name, options = {})
40
- if constants.map(&:to_s).include?(name.to_s)
41
- raise "#{name} filter already defined"
42
- end
43
-
44
- filter = const_set(name, Module.new)
45
- filter.extend const_get(options[:extend] || "Plain")
46
- filter.extend TiltFilter
47
- filter.extend PrecompiledTiltFilter if options.has_key? :precompiled
48
-
49
- if options.has_key? :template_class
50
- filter.template_class = options[:template_class]
51
- else
52
- filter.tilt_extension = options.fetch(:extension) { name.downcase }
53
- end
54
-
55
- # All ":coffeescript" as alias for ":coffee", etc.
56
- if options.has_key?(:alias)
57
- [options[:alias]].flatten.each {|x| Filters.defined[x.to_s] = filter}
58
- end
59
- filter
60
- end
61
-
62
- # Removes a filter from Haml. If the filter was removed, it returns
63
- # the Module that was removed upon success, or nil on failure. If you try
64
- # to redefine a filter, Haml will raise an error. Use this method first to
65
- # explicitly remove the filter before redefining it.
66
- # @return Module The filter module that has been removed
67
- # @since 4.0
68
- def remove_filter(name)
69
- defined.delete name.to_s.downcase
70
- if constants.map(&:to_s).include?(name.to_s)
71
- remove_const name.to_sym
72
- end
73
- end
74
-
75
- # The base module for Haml filters.
76
- # User-defined filters should be modules including this module.
77
- # The name of the filter is taken by downcasing the module name.
78
- # For instance, if the module is named `FooBar`, the filter will be `:foobar`.
79
- #
80
- # A user-defined filter should override either \{#render} or {\#compile}.
81
- # \{#render} is the most common.
82
- # It takes a string, the filter source,
83
- # and returns another string, the result of the filter.
84
- # For example, the following will define a filter named `:sass`:
85
- #
86
- # module Haml::Filters::Sass
87
- # include Haml::Filters::Base
88
- #
89
- # def render(text)
90
- # ::Sass::Engine.new(text).render
91
- # end
92
- # end
93
- #
94
- # For details on overriding \{#compile}, see its documentation.
95
- #
96
- # Note that filters overriding \{#render} automatically support `#{}`
97
- # for interpolating Ruby code.
98
- # Those overriding \{#compile} will need to add such support manually
99
- # if it's desired.
100
- module Base
101
- # This method is automatically called when {Base} is included in a module.
102
- # It automatically defines a filter
103
- # with the downcased name of that module.
104
- # For example, if the module is named `FooBar`, the filter will be `:foobar`.
105
- #
106
- # @param base [Module, Class] The module that this is included in
107
- def self.included(base)
108
- Filters.defined[base.name.split("::").last.downcase] = base
109
- base.extend(base)
110
- end
111
-
112
- # Takes the source text that should be passed to the filter
113
- # and returns the result of running the filter on that string.
114
- #
115
- # This should be overridden in most individual filter modules
116
- # to render text with the given filter.
117
- # If \{#compile} is overridden, however, \{#render} doesn't need to be.
118
- #
119
- # @param text [String] The source text for the filter to process
120
- # @return [String] The filtered result
121
- # @raise [Haml::Error] if it's not overridden
122
- def render(text)
123
- raise Error.new("#{self.inspect}#render not defined!")
124
- end
125
-
126
- # Same as \{#render}, but takes a {Haml::Engine} options hash as well.
127
- # It's only safe to rely on options made available in {Haml::Engine#options\_for\_buffer}.
128
- #
129
- # @see #render
130
- # @param text [String] The source text for the filter to process
131
- # @return [String] The filtered result
132
- # @raise [Haml::Error] if it or \{#render} isn't overridden
133
- def render_with_options(text, options)
134
- render(text)
135
- end
136
-
137
- # Same as \{#compile}, but requires the necessary files first.
138
- # *This is used by {Haml::Engine} and is not intended to be overridden or used elsewhere.*
139
- #
140
- # @see #compile
141
- def internal_compile(*args)
142
- compile(*args)
143
- end
144
-
145
- # This should be overridden when a filter needs to have access to the Haml
146
- # evaluation context. Rather than applying a filter to a string at
147
- # compile-time, \{#compile} uses the {Haml::Compiler} instance to compile
148
- # the string to Ruby code that will be executed in the context of the
149
- # active Haml template.
150
- #
151
- # Warning: the {Haml::Compiler} interface is neither well-documented
152
- # nor guaranteed to be stable.
153
- # If you want to make use of it, you'll probably need to look at the
154
- # source code and should test your filter when upgrading to new Haml
155
- # versions.
156
- #
157
- # @param compiler [Haml::Compiler] The compiler instance
158
- # @param text [String] The text of the filter
159
- # @raise [Haml::Error] if none of \{#compile}, \{#render}, and
160
- # \{#render_with_options} are overridden
161
- def compile(compiler, text)
162
- filter = self
163
- compiler.instance_eval do
164
- if contains_interpolation?(text)
165
- return if options[:suppress_eval]
166
-
167
- text = unescape_interpolation(text, options[:escape_html]).gsub(/(\\+)n/) do |s|
168
- escapes = $1.size
169
- next s if escapes % 2 == 0
170
- "#{'\\' * (escapes - 1)}\n"
171
- end
172
- # We need to add a newline at the beginning to get the
173
- # filter lines to line up (since the Haml filter contains
174
- # a line that doesn't show up in the source, namely the
175
- # filter name). Then we need to escape the trailing
176
- # newline so that the whole filter block doesn't take up
177
- # too many.
178
- text = %[\n#{text.sub(/\n"\Z/, "\\n\"")}]
179
- push_script <<RUBY.rstrip, :escape_html => false
180
- find_and_preserve(#{filter.inspect}.render_with_options(#{text}, _hamlout.options))
181
- RUBY
182
- return
183
- end
184
-
185
- rendered = Haml::Helpers::find_and_preserve(filter.render_with_options(text, compiler.options), compiler.options[:preserve])
186
- rendered.rstrip!
187
- push_text("#{rendered}\n")
188
- end
189
- end
190
- end
191
-
192
- # Does not parse the filtered text.
193
- # This is useful for large blocks of text without HTML tags, when you don't
194
- # want lines starting with `.` or `-` to be parsed.
195
- module Plain
196
- include Base
197
-
198
- # @see Base#render
199
- def render(text); text; end
200
- end
201
-
202
- # Surrounds the filtered text with `<script>` and CDATA tags. Useful for
203
- # including inline Javascript.
204
- module Javascript
205
- include Base
206
-
207
- # @see Base#render_with_options
208
- def render_with_options(text, options)
209
- indent = options[:cdata] ? ' ' : ' ' # 4 or 2 spaces
210
- if options[:format] == :html5
211
- type = ''
212
- else
213
- type = " type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}"
214
- end
215
-
216
- text = text.rstrip
217
- text.gsub!("\n", "\n#{indent}")
218
-
219
- %!<script#{type}>\n#{" //<![CDATA[\n" if options[:cdata]}#{indent}#{text}\n#{" //]]>\n" if options[:cdata]}</script>!
220
- end
221
- end
222
-
223
- # Surrounds the filtered text with `<style>` and CDATA tags. Useful for
224
- # including inline CSS.
225
- module Css
226
- include Base
227
-
228
- # @see Base#render_with_options
229
- def render_with_options(text, options)
230
- indent = options[:cdata] ? ' ' : ' ' # 4 or 2 spaces
231
- if options[:format] == :html5
232
- type = ''
233
- else
234
- type = " type=#{options[:attr_wrapper]}text/css#{options[:attr_wrapper]}"
26
+ def remove_filter(name)
27
+ registered.delete(name.to_s.downcase.to_sym)
28
+ if constants.map(&:to_s).include?(name.to_s)
29
+ remove_const name.to_sym
235
30
  end
236
-
237
- text = text.rstrip
238
- text.gsub!("\n", "\n#{indent}")
239
-
240
- %(<style#{type}>\n#{" /*<![CDATA[*/\n" if options[:cdata]}#{indent}#{text}\n#{" /*]]>*/\n" if options[:cdata]}</style>)
241
31
  end
242
- end
243
-
244
- # Surrounds the filtered text with CDATA tags.
245
- module Cdata
246
- include Base
247
-
248
- # @see Base#render
249
- def render(text)
250
- text = "\n#{text}"
251
- text.rstrip!
252
- text.gsub!("\n", "\n ")
253
- "<![CDATA[#{text}\n]]>"
254
- end
255
- end
256
32
 
257
- # Works the same as {Plain}, but HTML-escapes the text before placing it in
258
- # the document.
259
- module Escaped
260
- include Base
33
+ private
261
34
 
262
- # @see Base#render
263
- def render(text)
264
- Haml::Helpers.html_escape text
35
+ def register(name, compiler)
36
+ registered[name] = compiler
265
37
  end
266
38
  end
267
39
 
268
- # Parses the filtered text with the normal Ruby interpreter. Creates an IO
269
- # object named `haml_io`, anything written to it is output into the Haml
270
- # document. In previous version this filter redirected any output to `$stdout`
271
- # to the Haml document, this was not threadsafe and has been removed, you
272
- # should use `haml_io` instead.
273
- #
274
- # Not available if the {file:REFERENCE.md#suppress_eval-option `:suppress_eval`}
275
- # option is set to true. The Ruby code is evaluated in the same context as
276
- # the Haml template.
277
- module Ruby
278
- include Base
279
- require 'stringio'
280
-
281
- # @see Base#compile
282
- def compile(compiler, text)
283
- return if compiler.options[:suppress_eval]
284
- compiler.instance_eval do
285
- push_silent "#{<<-FIRST.tr("\n", ';')}#{text}#{<<-LAST.tr("\n", ';')}"
286
- begin
287
- haml_io = StringIO.new(_hamlout.buffer, 'a')
288
- FIRST
289
- ensure
290
- haml_io.close
291
- haml_io = nil
292
- end
293
- LAST
294
- end
295
- end
40
+ register :coffee, Coffee
41
+ register :coffeescript, CoffeeScript
42
+ register :css, Css
43
+ register :erb, Erb
44
+ register :escaped, Escaped
45
+ register :javascript, Javascript
46
+ register :less, Less
47
+ register :markdown, Markdown
48
+ register :plain, Plain
49
+ register :preserve, Preserve
50
+ register :ruby, Ruby
51
+ register :sass, Sass
52
+ register :scss, Scss
53
+ register :cdata, Cdata
54
+
55
+ def initialize(options = {})
56
+ @options = options
57
+ @compilers = {}
296
58
  end
297
59
 
298
- # Inserts the filtered text into the template with whitespace preserved.
299
- # `preserve`d blocks of text aren't indented, and newlines are replaced with
300
- # the HTML escape code for newlines, to preserve nice-looking output.
301
- #
302
- # @see Haml::Helpers#preserve
303
- module Preserve
304
- include Base
305
-
306
- # @see Base#render
307
- def render(text)
308
- Haml::Helpers.preserve text
309
- end
60
+ def compile(node)
61
+ node.value[:text] ||= ''
62
+ find_compiler(node).compile(node)
310
63
  end
311
64
 
312
- # @private
313
- module TiltFilter
314
- extend self
315
- attr_accessor :tilt_extension, :options
316
- attr_writer :template_class
65
+ private
317
66
 
318
- def template_class
319
- (@template_class if defined? @template_class) or begin
320
- @template_class = Tilt["t.#{tilt_extension}"] or
321
- raise Error.new(Error.message(:cant_run_filter, tilt_extension))
322
- rescue LoadError => e
323
- dep = e.message.split('--').last.strip
324
- raise Error.new(Error.message(:gem_install_filter_deps, tilt_extension, dep))
325
- end
326
- end
67
+ def find_compiler(node)
68
+ name = node.value[:name].to_sym
69
+ compiler = Filters.registered[name]
70
+ raise FilterNotFound.new("FilterCompiler for '#{name}' was not found", node.line.to_i - 1) unless compiler
327
71
 
328
- def self.extended(base)
329
- base.options = {}
330
- # There's a bug in 1.9.2 where the same parse tree cannot be shared
331
- # across several singleton classes -- this bug is fixed in 1.9.3.
332
- # We work around this by using a string eval instead of a block eval
333
- # so that a new parse tree is created for each singleton class.
334
- base.instance_eval %Q{
335
- include Base
336
-
337
- def render_with_options(text, compiler_options)
338
- text = template_class.new(nil, 1, options) {text}.render
339
- super(text, compiler_options)
340
- end
341
- }
342
- end
343
- end
344
-
345
- # @private
346
- module PrecompiledTiltFilter
347
- def precompiled(text)
348
- template_class.new(nil, 1, options) { text }.send(:precompiled, {}).first
349
- end
350
-
351
- def compile(compiler, text)
352
- return if compiler.options[:suppress_eval]
353
- compiler.send(:push_script, precompiled(text))
354
- end
355
- end
356
-
357
- # @!parse module Sass; end
358
- register_tilt_filter "Sass", :extend => "Css"
359
-
360
- # @!parse module Scss; end
361
- register_tilt_filter "Scss", :extend => "Css"
362
-
363
- # @!parse module Less; end
364
- register_tilt_filter "Less", :extend => "Css"
365
-
366
- # @!parse module Markdown; end
367
- register_tilt_filter "Markdown"
368
-
369
- # @!parse module Erb; end
370
- register_tilt_filter "Erb", :precompiled => true
371
-
372
- # @!parse module Coffee; end
373
- register_tilt_filter "Coffee", :alias => "coffeescript", :extend => "Javascript"
374
-
375
- # Parses the filtered text with ERB.
376
- # Not available if the {file:REFERENCE.md#suppress_eval-option
377
- # `:suppress_eval`} option is set to true. Embedded Ruby code is evaluated
378
- # in the same context as the Haml template.
379
- module Erb
380
- class << self
381
- def precompiled(text)
382
- #workaround for https://github.com/rtomayko/tilt/pull/183
383
- require 'erubis' if (defined?(::Erubis) && !defined?(::Erubis::Eruby))
384
- super.sub(/^#coding:.*?\n/, '')
385
- end
386
- end
72
+ @compilers[name] ||= compiler.new(@options)
387
73
  end
388
74
  end
389
75
  end
390
-
391
- # These filters have been demoted to Haml Contrib but are still included by
392
- # default in Haml 4.0. Still, we rescue from load error if for some reason
393
- # haml-contrib is not installed.
394
- begin
395
- require "haml/filters/maruku"
396
- require "haml/filters/textile"
397
- rescue LoadError
398
- end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require 'haml/escapable'
3
+
4
+ module Haml
5
+ # This module allows Temple::Filter to dispatch :fescape on `#compile`.
6
+ module FescapeDispathcer
7
+ def on_fescape(flag, exp)
8
+ [:fescape, flag, compile(exp)]
9
+ end
10
+ end
11
+ ::Temple::Filter.include FescapeDispathcer
12
+
13
+ # Unlike Haml::Escapable, this escapes value even if it's html_safe.
14
+ class ForceEscapable < Escapable
15
+ def initialize(opts = {})
16
+ super
17
+ @escape_code = options[:escape_code] || "::Haml::Util.escape_html((%s))"
18
+ @escaper = eval("proc {|v| #{@escape_code % 'v'} }")
19
+ end
20
+
21
+ alias_method :on_fescape, :on_escape
22
+
23
+ # ForceEscapable doesn't touch :escape expression.
24
+ # This method is not used if it's inserted after Haml::Escapable.
25
+ def on_escape(flag, exp)
26
+ [:escape, flag, compile(exp)]
27
+ end
28
+ end
29
+ end