haml 5.2.2 → 6.1.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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/test.yml +13 -14
- data/.gitignore +16 -16
- data/.yardopts +0 -3
- data/CHANGELOG.md +116 -3
- data/Gemfile +18 -11
- data/MIT-LICENSE +1 -1
- data/README.md +17 -23
- data/REFERENCE.md +69 -145
- data/Rakefile +48 -81
- data/bin/bench +66 -0
- data/bin/console +11 -0
- data/bin/ruby +3 -0
- data/bin/setup +7 -0
- data/bin/stackprof +27 -0
- data/bin/test +24 -0
- data/exe/haml +6 -0
- data/ext/haml/extconf.rb +10 -0
- data/ext/haml/haml.c +537 -0
- data/ext/haml/hescape.c +108 -0
- data/ext/haml/hescape.h +20 -0
- data/haml.gemspec +39 -37
- data/lib/haml/ambles.rb +20 -0
- data/lib/haml/attribute_builder.rb +134 -179
- data/lib/haml/attribute_compiler.rb +85 -194
- data/lib/haml/attribute_parser.rb +92 -126
- data/lib/haml/cli.rb +154 -0
- data/lib/haml/compiler/children_compiler.rb +155 -0
- data/lib/haml/compiler/comment_compiler.rb +51 -0
- data/lib/haml/compiler/doctype_compiler.rb +46 -0
- data/lib/haml/compiler/script_compiler.rb +114 -0
- data/lib/haml/compiler/silent_script_compiler.rb +24 -0
- data/lib/haml/compiler/tag_compiler.rb +76 -0
- data/lib/haml/compiler.rb +63 -296
- data/lib/haml/dynamic_merger.rb +67 -0
- data/lib/haml/engine.rb +48 -227
- data/lib/haml/error.rb +5 -4
- data/lib/haml/escape.rb +13 -0
- data/lib/haml/escape_any.rb +21 -0
- data/lib/haml/filters/base.rb +12 -0
- data/lib/haml/filters/cdata.rb +20 -0
- data/lib/haml/filters/coffee.rb +17 -0
- data/lib/haml/filters/css.rb +33 -0
- data/lib/haml/filters/erb.rb +10 -0
- data/lib/haml/filters/escaped.rb +22 -0
- data/lib/haml/filters/javascript.rb +33 -0
- data/lib/haml/filters/less.rb +20 -0
- data/lib/haml/filters/markdown.rb +11 -0
- data/lib/haml/filters/plain.rb +29 -0
- data/lib/haml/filters/preserve.rb +22 -0
- data/lib/haml/filters/ruby.rb +10 -0
- data/lib/haml/filters/sass.rb +15 -0
- data/lib/haml/filters/scss.rb +15 -0
- data/lib/haml/filters/text_base.rb +25 -0
- data/lib/haml/filters/tilt_base.rb +59 -0
- data/lib/haml/filters.rb +54 -378
- data/lib/haml/force_escape.rb +29 -0
- data/lib/haml/helpers.rb +3 -697
- data/lib/haml/html.rb +22 -0
- data/lib/haml/identity.rb +13 -0
- data/lib/haml/object_ref.rb +35 -0
- data/lib/haml/parser.rb +157 -22
- data/lib/haml/rails_helpers.rb +53 -0
- data/lib/haml/rails_template.rb +57 -0
- data/lib/haml/railtie.rb +3 -46
- data/lib/haml/ruby_expression.rb +32 -0
- data/lib/haml/string_splitter.rb +140 -0
- data/lib/haml/template.rb +15 -34
- data/lib/haml/temple_line_counter.rb +2 -1
- data/lib/haml/util.rb +18 -15
- data/lib/haml/version.rb +1 -2
- data/lib/haml/whitespace.rb +8 -0
- data/lib/haml.rb +8 -20
- metadata +211 -55
- data/.gitmodules +0 -3
- data/TODO +0 -24
- data/benchmark.rb +0 -70
- data/bin/haml +0 -9
- data/lib/haml/.gitattributes +0 -1
- data/lib/haml/buffer.rb +0 -182
- data/lib/haml/escapable.rb +0 -77
- data/lib/haml/exec.rb +0 -347
- data/lib/haml/generator.rb +0 -42
- data/lib/haml/helpers/action_view_extensions.rb +0 -60
- data/lib/haml/helpers/action_view_mods.rb +0 -132
- data/lib/haml/helpers/action_view_xss_mods.rb +0 -60
- data/lib/haml/helpers/safe_erubi_template.rb +0 -20
- data/lib/haml/helpers/safe_erubis_template.rb +0 -33
- data/lib/haml/helpers/xss_mods.rb +0 -114
- data/lib/haml/options.rb +0 -273
- data/lib/haml/plugin.rb +0 -54
- data/lib/haml/sass_rails_filter.rb +0 -47
- data/lib/haml/template/options.rb +0 -27
- data/lib/haml/temple_engine.rb +0 -124
- data/yard/default/.gitignore +0 -1
- data/yard/default/fulldoc/html/css/common.sass +0 -15
- data/yard/default/layout/html/footer.erb +0 -12
data/lib/haml/engine.rb
CHANGED
@@ -1,238 +1,59 @@
|
|
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/
|
8
|
-
require 'haml/
|
9
|
-
require 'haml/
|
10
|
-
require 'haml/
|
11
|
-
require 'haml/
|
12
|
-
require 'haml/
|
5
|
+
require 'haml/html'
|
6
|
+
require 'haml/string_splitter'
|
7
|
+
require 'haml/escape'
|
8
|
+
require 'haml/escape_any'
|
9
|
+
require 'haml/force_escape'
|
10
|
+
require 'haml/dynamic_merger'
|
11
|
+
require 'haml/ambles'
|
12
|
+
require 'haml/whitespace'
|
13
13
|
|
14
14
|
module Haml
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
15
|
+
class Engine < Temple::Engine
|
16
|
+
define_options(
|
17
|
+
:buffer_class,
|
18
|
+
generator: Temple::Generators::StringBuffer,
|
19
|
+
format: :html,
|
20
|
+
attr_quote: "'",
|
21
|
+
escape_html: true,
|
22
|
+
escape_attrs: true,
|
23
|
+
autoclose: %w(area base basefont br col command embed frame
|
24
|
+
hr img input isindex keygen link menuitem meta
|
25
|
+
param source track wbr),
|
26
|
+
filename: "",
|
27
|
+
disable_capture: false,
|
28
|
+
remove_whitespace: false,
|
29
|
+
)
|
30
|
+
|
31
|
+
use Parser
|
32
|
+
use Compiler
|
33
|
+
use HTML
|
34
|
+
use StringSplitter
|
35
|
+
filter :StaticAnalyzer
|
36
|
+
use Escape
|
37
|
+
use EscapeAny
|
38
|
+
use ForceEscape
|
39
|
+
filter :ControlFlow
|
40
|
+
use Ambles
|
41
|
+
filter :MultiFlattener
|
42
|
+
use Whitespace
|
43
|
+
filter :StaticMerger
|
44
|
+
use DynamicMerger
|
45
|
+
use :Generator, -> { options[:generator] }
|
46
|
+
end
|
225
47
|
|
226
|
-
|
227
|
-
|
48
|
+
# For backward compatibility of Tilt integration. TODO: We should deprecate this
|
49
|
+
# and let Tilt have a native support of Haml 6. At least it generates warnings now.
|
50
|
+
class TempleEngine < Engine
|
51
|
+
def compile(template)
|
52
|
+
@precompiled = call(template)
|
228
53
|
end
|
229
54
|
|
230
|
-
|
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)
|
55
|
+
def precompiled_with_ambles(_local_names, after_preamble:)
|
56
|
+
"#{after_preamble.tr("\n", ';')}#{@precompiled}".dup
|
236
57
|
end
|
237
58
|
end
|
238
59
|
end
|
data/lib/haml/error.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
module Haml
|
4
|
-
# An exception raised by Haml code.
|
5
3
|
class Error < StandardError
|
6
|
-
|
7
4
|
MESSAGES = {
|
8
5
|
bad_script_indent: '"%s" is indented at wrong level: expected %d, but was at %d.',
|
9
6
|
cant_run_filter: 'Can\'t run "%s" filter; you must require its dependencies first',
|
@@ -61,5 +58,9 @@ END
|
|
61
58
|
# except in that it's a subclass of {Haml::Error}.
|
62
59
|
class SyntaxError < Error; end
|
63
60
|
|
64
|
-
|
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
|
65
66
|
end
|
data/lib/haml/escape.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'haml/util'
|
3
|
+
|
4
|
+
module Haml
|
5
|
+
class Escape < Temple::Filters::Escapable
|
6
|
+
def initialize(opts = {})
|
7
|
+
super
|
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'} }")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'haml/escape'
|
3
|
+
|
4
|
+
module Haml
|
5
|
+
# This module allows Temple::Filter to dispatch :fescape on `#compile`.
|
6
|
+
module EscapeanyDispathcer
|
7
|
+
def on_escapeany(flag, exp)
|
8
|
+
[:escapeany, flag, compile(exp)]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
::Temple::Filter.include EscapeanyDispathcer
|
12
|
+
|
13
|
+
# Unlike Haml::Escape, this calls to_s when not escaped.
|
14
|
+
class EscapeAny < Escape
|
15
|
+
alias_method :on_escapeany, :on_escape
|
16
|
+
|
17
|
+
def on_dynamic(value)
|
18
|
+
[:dynamic, @escape ? @escape_code % value : "(#{value}).to_s"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
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,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,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", '
')
|
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,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
|