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/engine.rb CHANGED
@@ -1,238 +1,53 @@
1
1
  # frozen_string_literal: true
2
-
3
- require 'forwardable'
4
-
2
+ require 'temple'
5
3
  require 'haml/parser'
6
4
  require 'haml/compiler'
7
- require 'haml/options'
8
- require 'haml/helpers'
9
- require 'haml/buffer'
10
- require 'haml/filters'
11
- require 'haml/error'
12
- require 'haml/temple_engine'
5
+ require 'haml/html'
6
+ require 'haml/escapable'
7
+ require 'haml/force_escapable'
8
+ require 'haml/dynamic_merger'
9
+ require 'haml/ambles'
13
10
 
14
11
  module Haml
15
- # This is the frontend for using Haml programmatically.
16
- # It can be directly used by the user by creating a
17
- # new instance and calling \{#render} to render the template.
18
- # For example:
19
- #
20
- # template = File.read('templates/really_cool_template.haml')
21
- # haml_engine = Haml::Engine.new(template)
22
- # output = haml_engine.render
23
- # puts output
24
- class Engine
25
- extend Forwardable
26
- include Haml::Util
27
-
28
- # The Haml::Options instance.
29
- # See {file:REFERENCE.md#options the Haml options documentation}.
30
- #
31
- # @return Haml::Options
32
- attr_accessor :options
33
-
34
- # The indentation used in the Haml document,
35
- # or `nil` if the indentation is ambiguous
36
- # (for example, for a single-level document).
37
- #
38
- # @return [String]
39
- attr_accessor :indentation
40
-
41
- # Tilt currently depends on these moved methods, provide a stable API
42
- def_delegators :compiler, :precompiled, :precompiled_method_return_value
43
-
44
- def options_for_buffer
45
- @options.for_buffer
46
- end
47
-
48
- # Precompiles the Haml template.
49
- #
50
- # @param template [String] The Haml template
51
- # @param options [{Symbol => Object}] An options hash;
52
- # see {file:REFERENCE.md#options the Haml options documentation}
53
- # @raise [Haml::Error] if there's a Haml syntax error in the template
54
- def initialize(template, options = {})
55
- # Reflect changes of `Haml::Options.defaults` to `Haml::TempleEngine` options, but `#initialize_encoding`
56
- # should be run against the arguemnt `options[:encoding]` for backward compatibility with old `Haml::Engine`.
57
- options = Options.defaults.dup.tap { |o| o.delete(:encoding) }.merge!(options)
58
- @options = Options.new(options)
59
-
60
- @template = check_haml_encoding(template) do |msg, line|
61
- raise Haml::Error.new(msg, line)
62
- end
63
-
64
- @temple_engine = TempleEngine.new(options)
65
- @temple_engine.compile(@template)
66
- end
67
-
68
- # Deprecated API for backword compatibility
69
- def compiler
70
- @temple_engine
71
- end
72
-
73
- # Processes the template and returns the result as a string.
74
- #
75
- # `scope` is the context in which the template is evaluated.
76
- # If it's a `Binding`, Haml uses it as the second argument to `Kernel#eval`;
77
- # otherwise, Haml just uses its `#instance_eval` context.
78
- #
79
- # Note that Haml modifies the evaluation context
80
- # (either the scope object or the `self` object of the scope binding).
81
- # It extends {Haml::Helpers}, and various instance variables are set
82
- # (all prefixed with `haml_`).
83
- # For example:
84
- #
85
- # s = "foobar"
86
- # Haml::Engine.new("%p= upcase").render(s) #=> "<p>FOOBAR</p>"
87
- #
88
- # # s now extends Haml::Helpers
89
- # s.respond_to?(:html_attrs) #=> true
90
- #
91
- # `locals` is a hash of local variables to make available to the template.
92
- # For example:
93
- #
94
- # Haml::Engine.new("%p= foo").render(Object.new, :foo => "Hello, world!") #=> "<p>Hello, world!</p>"
95
- #
96
- # If a block is passed to render,
97
- # that block is run when `yield` is called
98
- # within the template.
99
- #
100
- # Due to some Ruby quirks,
101
- # if `scope` is a `Binding` object and a block is given,
102
- # the evaluation context may not be quite what the user expects.
103
- # In particular, it's equivalent to passing `eval("self", scope)` as `scope`.
104
- # This won't have an effect in most cases,
105
- # but if you're relying on local variables defined in the context of `scope`,
106
- # they won't work.
107
- #
108
- # @param scope [Binding, Object] The context in which the template is evaluated
109
- # @param locals [{Symbol => Object}] Local variables that will be made available
110
- # to the template
111
- # @param block [#to_proc] A block that can be yielded to within the template
112
- # @return [String] The rendered template
113
- def render(scope = Object.new, locals = {}, &block)
114
- parent = scope.instance_variable_defined?(:@haml_buffer) ? scope.instance_variable_get(:@haml_buffer) : nil
115
- buffer = Haml::Buffer.new(parent, @options.for_buffer)
116
-
117
- if scope.is_a?(Binding)
118
- scope_object = eval("self", scope)
119
- scope = scope_object.instance_eval{binding} if block_given?
120
- else
121
- scope_object = scope
122
- scope = scope_object.instance_eval{binding}
123
- end
124
-
125
- set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
126
-
127
- scope_object.extend(Haml::Helpers)
128
- scope_object.instance_variable_set(:@haml_buffer, buffer)
129
- begin
130
- eval(@temple_engine.precompiled_with_return_value, scope, @options.filename, @options.line)
131
- rescue ::SyntaxError => e
132
- raise SyntaxError, e.message
133
- end
134
- ensure
135
- # Get rid of the current buffer
136
- scope_object.instance_variable_set(:@haml_buffer, buffer.upper) if buffer
137
- end
138
- alias_method :to_html, :render
139
-
140
- # Returns a proc that, when called,
141
- # renders the template and returns the result as a string.
142
- #
143
- # `scope` works the same as it does for render.
144
- #
145
- # The first argument of the returned proc is a hash of local variable names to values.
146
- # However, due to an unfortunate Ruby quirk,
147
- # the local variables which can be assigned must be pre-declared.
148
- # This is done with the `local_names` argument.
149
- # For example:
150
- #
151
- # # This works
152
- # Haml::Engine.new("%p= foo").render_proc(Object.new, :foo).call :foo => "Hello!"
153
- # #=> "<p>Hello!</p>"
154
- #
155
- # # This doesn't
156
- # Haml::Engine.new("%p= foo").render_proc.call :foo => "Hello!"
157
- # #=> NameError: undefined local variable or method `foo'
158
- #
159
- # The proc doesn't take a block; any yields in the template will fail.
160
- #
161
- # @param scope [Binding, Object] The context in which the template is evaluated
162
- # @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
163
- # @return [Proc] The proc that will run the template
164
- def render_proc(scope = Object.new, *local_names)
165
- if scope.is_a?(Binding)
166
- scope_object = eval("self", scope)
167
- else
168
- scope_object = scope
169
- scope = scope_object.instance_eval{binding}
170
- end
171
-
172
- begin
173
- str = @temple_engine.precompiled_with_ambles(local_names)
174
- eval(
175
- "Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {}; #{str}}\n",
176
- scope,
177
- @options.filename,
178
- @options.line
179
- )
180
- rescue ::SyntaxError => e
181
- raise SyntaxError, e.message
182
- end
183
- end
184
-
185
- # Defines a method on `object` with the given name
186
- # that renders the template and returns the result as a string.
187
- #
188
- # If `object` is a class or module,
189
- # the method will instead be defined as an instance method.
190
- # For example:
191
- #
192
- # t = Time.now
193
- # Haml::Engine.new("%p\n Today's date is\n .date= self.to_s").def_method(t, :render)
194
- # t.render #=> "<p>\n Today's date is\n <div class='date'>Fri Nov 23 18:28:29 -0800 2007</div>\n</p>\n"
195
- #
196
- # Haml::Engine.new(".upcased= upcase").def_method(String, :upcased_div)
197
- # "foobar".upcased_div #=> "<div class='upcased'>FOOBAR</div>\n"
198
- #
199
- # The first argument of the defined method is a hash of local variable names to values.
200
- # However, due to an unfortunate Ruby quirk,
201
- # the local variables which can be assigned must be pre-declared.
202
- # This is done with the `local_names` argument.
203
- # For example:
204
- #
205
- # # This works
206
- # obj = Object.new
207
- # Haml::Engine.new("%p= foo").def_method(obj, :render, :foo)
208
- # obj.render(:foo => "Hello!") #=> "<p>Hello!</p>"
209
- #
210
- # # This doesn't
211
- # obj = Object.new
212
- # Haml::Engine.new("%p= foo").def_method(obj, :render)
213
- # obj.render(:foo => "Hello!") #=> NameError: undefined local variable or method `foo'
214
- #
215
- # Note that Haml modifies the evaluation context
216
- # (either the scope object or the `self` object of the scope binding).
217
- # It extends {Haml::Helpers}, and various instance variables are set
218
- # (all prefixed with `haml_`).
219
- #
220
- # @param object [Object, Module] The object on which to define the method
221
- # @param name [String, Symbol] The name of the method to define
222
- # @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
223
- def def_method(object, name, *local_names)
224
- method = object.is_a?(Module) ? :module_eval : :instance_eval
12
+ class Engine < Temple::Engine
13
+ define_options(
14
+ :buffer_class,
15
+ generator: Temple::Generators::ArrayBuffer,
16
+ format: :html,
17
+ attr_quote: "'",
18
+ escape_html: true,
19
+ escape_attrs: true,
20
+ autoclose: %w(area base basefont br col command embed frame
21
+ hr img input isindex keygen link menuitem meta
22
+ param source track wbr),
23
+ filename: "",
24
+ disable_capture: false,
25
+ )
26
+
27
+ use Parser
28
+ use Compiler
29
+ use HTML
30
+ filter :StringSplitter
31
+ filter :StaticAnalyzer
32
+ use Escapable
33
+ use ForceEscapable
34
+ filter :ControlFlow
35
+ use Ambles
36
+ filter :MultiFlattener
37
+ filter :StaticMerger
38
+ use DynamicMerger
39
+ use :Generator, -> { options[:generator] }
40
+ end
225
41
 
226
- object.send(method, "def #{name}(_haml_locals = {}); #{@temple_engine.precompiled_with_ambles(local_names)}; end",
227
- @options.filename, @options.line)
42
+ # For backward compatibility of Tilt integration. TODO: We should deprecate this
43
+ # and let Tilt have a native support of Haml 6. At least it generates warnings now.
44
+ class TempleEngine < Engine
45
+ def compile(template)
46
+ @precompiled = call(template)
228
47
  end
229
48
 
230
- private
231
-
232
- def set_locals(locals, scope, scope_object)
233
- scope_object.instance_variable_set :@_haml_locals, locals
234
- set_locals = locals.keys.map { |k| "#{k} = @_haml_locals[#{k.inspect}]" }.join("\n")
235
- eval(set_locals, scope)
49
+ def precompiled_with_ambles(_local_names, after_preamble:)
50
+ "#{after_preamble.tr("\n", ';')}#{@precompiled}".dup
236
51
  end
237
52
  end
238
53
  end
data/lib/haml/error.rb CHANGED
@@ -1,65 +1,16 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module Haml
4
- # An exception raised by Haml code.
3
+ # TODO: unify Haml::Error (former Hamlit::Error) and Haml::HamlError (former Haml::Error)
5
4
  class Error < StandardError
6
-
7
- MESSAGES = {
8
- bad_script_indent: '"%s" is indented at wrong level: expected %d, but was at %d.',
9
- cant_run_filter: 'Can\'t run "%s" filter; you must require its dependencies first',
10
- cant_use_tabs_and_spaces: "Indentation can't use both tabs and spaces.",
11
- deeper_indenting: "The line was indented %d levels deeper than the previous line.",
12
- filter_not_defined: 'Filter "%s" is not defined.',
13
- gem_install_filter_deps: '"%s" filter\'s %s dependency missing: try installing it or adding it to your Gemfile',
14
- illegal_element: "Illegal element: classes and ids must have values.",
15
- illegal_nesting_content: "Illegal nesting: nesting within a tag that already has content is illegal.",
16
- illegal_nesting_header: "Illegal nesting: nesting within a header command is illegal.",
17
- illegal_nesting_line: "Illegal nesting: content can't be both given on the same line as %%%s and nested within it.",
18
- illegal_nesting_plain: "Illegal nesting: nesting within plain text is illegal.",
19
- illegal_nesting_self_closing: "Illegal nesting: nesting within a self-closing tag is illegal.",
20
- inconsistent_indentation: "Inconsistent indentation: %s used for indentation, but the rest of the document was indented using %s.",
21
- indenting_at_start: "Indenting at the beginning of the document is illegal.",
22
- install_haml_contrib: 'To use the "%s" filter, please install the haml-contrib gem.',
23
- invalid_attribute_list: 'Invalid attribute list: %s.',
24
- invalid_filter_name: 'Invalid filter name ":%s".',
25
- invalid_tag: 'Invalid tag: "%s".',
26
- missing_if: 'Got "%s" with no preceding "if"',
27
- no_ruby_code: "There's no Ruby code for %s to evaluate.",
28
- self_closing_content: "Self-closing tags can't have content.",
29
- unbalanced_brackets: 'Unbalanced brackets.',
30
- no_end: <<-END
31
- You don't need to use "- end" in Haml. Un-indent to close a block:
32
- - if foo?
33
- %strong Foo!
34
- - else
35
- Not foo.
36
- %p This line is un-indented, so it isn't part of the "if" block
37
- END
38
- }.freeze
39
-
40
- def self.message(key, *args)
41
- string = MESSAGES[key] or raise "[HAML BUG] No error messages for #{key}"
42
- (args.empty? ? string : string % args).rstrip
43
- end
44
-
45
- # The line of the template on which the error occurred.
46
- #
47
- # @return [Fixnum]
48
5
  attr_reader :line
49
6
 
50
- # @param message [String] The error message
51
- # @param line [Fixnum] See \{#line}
52
7
  def initialize(message = nil, line = nil)
53
8
  super(message)
54
9
  @line = line
55
10
  end
56
11
  end
57
12
 
58
- # SyntaxError is the type of exception raised when Haml encounters an
59
- # ill-formatted document.
60
- # It's not particularly interesting,
61
- # except in that it's a subclass of {Haml::Error}.
62
13
  class SyntaxError < Error; end
63
-
64
- class InvalidAttributeNameError < SyntaxError; end
14
+ class InternalError < Error; end
15
+ class FilterNotFound < Error; end
65
16
  end
@@ -1,77 +1,13 @@
1
1
  # frozen_string_literal: true
2
+ require 'haml/util'
2
3
 
3
4
  module Haml
4
- # Like Temple::Filters::Escapable, but with support for escaping by
5
- # Haml::Herlpers.html_escape and Haml::Herlpers.escape_once.
6
- class Escapable < Temple::Filter
7
- # Special value of `flag` to ignore html_safe?
8
- EscapeSafeBuffer = Struct.new(:value)
9
-
10
- def initialize(*)
5
+ class Escapable < Temple::Filters::Escapable
6
+ def initialize(opts = {})
11
7
  super
12
- @escape = false
13
- @escape_safe_buffer = false
14
- end
15
-
16
- def on_escape(flag, exp)
17
- old_escape, old_escape_safe_buffer = @escape, @escape_safe_buffer
18
- @escape_safe_buffer = flag.is_a?(EscapeSafeBuffer)
19
- @escape = @escape_safe_buffer ? flag.value : flag
20
- compile(exp)
21
- ensure
22
- @escape, @escape_safe_buffer = old_escape, old_escape_safe_buffer
23
- end
24
-
25
- # The same as Haml::AttributeBuilder.build_attributes
26
- def on_static(value)
27
- [:static,
28
- if @escape == :once
29
- escape_once(value)
30
- elsif @escape
31
- escape(value)
32
- else
33
- value
34
- end
35
- ]
36
- end
37
-
38
- # The same as Haml::AttributeBuilder.build_attributes
39
- def on_dynamic(value)
40
- [:dynamic,
41
- if @escape == :once
42
- escape_once_code(value)
43
- elsif @escape
44
- escape_code(value)
45
- else
46
- "(#{value}).to_s"
47
- end
48
- ]
49
- end
50
-
51
- private
52
-
53
- def escape_once(value)
54
- if @escape_safe_buffer
55
- ::Haml::Helpers.escape_once_without_haml_xss(value)
56
- else
57
- ::Haml::Helpers.escape_once(value)
58
- end
59
- end
60
-
61
- def escape(value)
62
- if @escape_safe_buffer
63
- ::Haml::Helpers.html_escape_without_haml_xss(value)
64
- else
65
- ::Haml::Helpers.html_escape(value)
66
- end
67
- end
68
-
69
- def escape_once_code(value)
70
- "::Haml::Helpers.escape_once#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))"
71
- end
72
-
73
- def escape_code(value)
74
- "::Haml::Helpers.html_escape#{('_without_haml_xss' if @escape_safe_buffer)}((#{value}))"
8
+ @escape_code = options[:escape_code] ||
9
+ "::Haml::Util.escape_html#{options[:use_html_safe] ? '_safe' : ''}((%s))"
10
+ @escaper = eval("proc {|v| #{@escape_code % 'v'} }")
75
11
  end
76
12
  end
77
13
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ require 'haml/util'
3
+
4
+ module Haml
5
+ class Filters
6
+ class Base
7
+ def initialize(options = {})
8
+ @format = options[:format]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Cdata < TextBase
5
+ def compile(node)
6
+ compile_cdata(node)
7
+ end
8
+
9
+ private
10
+
11
+ def compile_cdata(node)
12
+ temple = [:multi]
13
+ temple << [:static, "<![CDATA[\n"]
14
+ compile_text!(temple, node, ' ')
15
+ temple << [:static, "\n]]>"]
16
+ temple
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Coffee < TiltBase
5
+ def compile(node)
6
+ require 'tilt/coffee' if explicit_require?('coffee')
7
+ temple = [:multi]
8
+ temple << [:static, "<script>\n"]
9
+ temple << compile_with_tilt(node, 'coffee', indent_width: 2)
10
+ temple << [:static, "</script>"]
11
+ temple
12
+ end
13
+ end
14
+
15
+ CoffeeScript = Coffee
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Css < TextBase
5
+ def compile(node)
6
+ case @format
7
+ when :xhtml
8
+ compile_xhtml(node)
9
+ else
10
+ compile_html(node)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def compile_html(node)
17
+ temple = [:multi]
18
+ temple << [:static, "<style>\n"]
19
+ compile_text!(temple, node, ' ')
20
+ temple << [:static, "\n</style>"]
21
+ temple
22
+ end
23
+
24
+ def compile_xhtml(node)
25
+ temple = [:multi]
26
+ temple << [:static, "<style type='text/css'>\n /*<![CDATA[*/\n"]
27
+ compile_text!(temple, node, ' ')
28
+ temple << [:static, "\n /*]]>*/\n</style>"]
29
+ temple
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Erb < TiltBase
5
+ def compile(node)
6
+ compile_with_tilt(node, 'erb')
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Escaped < Base
5
+ def compile(node)
6
+ text = node.value[:text].rstrip
7
+ temple = compile_text(text)
8
+ [:escape, true, temple]
9
+ end
10
+
11
+ private
12
+
13
+ def compile_text(text)
14
+ if ::Haml::Util.contains_interpolation?(text)
15
+ [:dynamic, ::Haml::Util.unescape_interpolation(text)]
16
+ else
17
+ [:static, text]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Javascript < TextBase
5
+ def compile(node)
6
+ case @format
7
+ when :xhtml
8
+ compile_xhtml(node)
9
+ else
10
+ compile_html(node)
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def compile_html(node)
17
+ temple = [:multi]
18
+ temple << [:static, "<script>\n"]
19
+ compile_text!(temple, node, ' ')
20
+ temple << [:static, "\n</script>"]
21
+ temple
22
+ end
23
+
24
+ def compile_xhtml(node)
25
+ temple = [:multi]
26
+ temple << [:static, "<script type='text/javascript'>\n //<![CDATA[\n"]
27
+ compile_text!(temple, node, ' ')
28
+ temple << [:static, "\n //]]>\n</script>"]
29
+ temple
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # LESS support is deprecated since it requires therubyracer.gem,
3
+ # which is hard to maintain.
4
+ #
5
+ # It's not supported in Sprockets 3.0+ too.
6
+ # https://github.com/sstephenson/sprockets/pull/547
7
+ module Haml
8
+ class Filters
9
+ class Less < TiltBase
10
+ def compile(node)
11
+ require 'tilt/less' if explicit_require?('less')
12
+ temple = [:multi]
13
+ temple << [:static, "<style>\n"]
14
+ temple << compile_with_tilt(node, 'less', indent_width: 2)
15
+ temple << [:static, '</style>']
16
+ temple
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Markdown < TiltBase
5
+ def compile(node)
6
+ require 'tilt/redcarpet' if explicit_require?('markdown')
7
+ compile_with_tilt(node, 'markdown')
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require 'haml/string_splitter'
3
+
4
+ module Haml
5
+ class Filters
6
+ class Plain < Base
7
+ def compile(node)
8
+ text = node.value[:text]
9
+ text = text.rstrip unless ::Haml::Util.contains_interpolation?(text) # for compatibility
10
+ [:multi, *compile_plain(text)]
11
+ end
12
+
13
+ private
14
+
15
+ def compile_plain(text)
16
+ string_literal = ::Haml::Util.unescape_interpolation(text)
17
+ StringSplitter.compile(string_literal).map do |temple|
18
+ type, str = temple
19
+ case type
20
+ when :dynamic
21
+ [:escape, false, [:dynamic, str]]
22
+ else
23
+ temple
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module Haml
3
+ class Filters
4
+ class Preserve < Base
5
+ def compile(node)
6
+ text = node.value[:text].rstrip + "\n"
7
+ text = text.gsub("\n", '&#x000A;')
8
+ compile_text(text)
9
+ end
10
+
11
+ private
12
+
13
+ def compile_text(text)
14
+ if ::Haml::Util.contains_interpolation?(text)
15
+ [:dynamic, ::Haml::Util.unescape_interpolation(text)]
16
+ else
17
+ [:static, text]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end