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