hamlit 2.9.3
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 +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +45 -0
- data/CHANGELOG.md +676 -0
- data/Gemfile +28 -0
- data/LICENSE.txt +44 -0
- data/README.md +150 -0
- data/REFERENCE.md +266 -0
- data/Rakefile +117 -0
- data/benchmark/boolean_attribute.haml +6 -0
- data/benchmark/class_attribute.haml +5 -0
- data/benchmark/common_attribute.haml +3 -0
- data/benchmark/data_attribute.haml +4 -0
- data/benchmark/dynamic_attributes/boolean_attribute.haml +4 -0
- data/benchmark/dynamic_attributes/class_attribute.haml +4 -0
- data/benchmark/dynamic_attributes/common_attribute.haml +2 -0
- data/benchmark/dynamic_attributes/data_attribute.haml +2 -0
- data/benchmark/dynamic_attributes/id_attribute.haml +2 -0
- data/benchmark/dynamic_boolean_attribute.haml +4 -0
- data/benchmark/etc/attribute_builder.haml +5 -0
- data/benchmark/etc/real_sample.haml +888 -0
- data/benchmark/etc/real_sample.rb +11 -0
- data/benchmark/etc/static_analyzer.haml +1 -0
- data/benchmark/etc/string_interpolation.haml +2 -0
- data/benchmark/etc/tags.haml +3 -0
- data/benchmark/etc/tags_loop.haml +2 -0
- data/benchmark/ext/build_data.rb +17 -0
- data/benchmark/ext/build_id.rb +13 -0
- data/benchmark/id_attribute.haml +3 -0
- data/benchmark/plain.haml +4 -0
- data/benchmark/script.haml +4 -0
- data/benchmark/slim/LICENSE +21 -0
- data/benchmark/slim/context.rb +11 -0
- data/benchmark/slim/run-benchmarks.rb +94 -0
- data/benchmark/slim/view.erb +23 -0
- data/benchmark/slim/view.haml +18 -0
- data/benchmark/slim/view.slim +17 -0
- data/benchmark/utils/benchmark_ips_extension.rb +43 -0
- data/bin/bench +77 -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/hamlit +6 -0
- data/ext/hamlit/extconf.rb +10 -0
- data/ext/hamlit/hamlit.c +553 -0
- data/ext/hamlit/hescape.c +108 -0
- data/ext/hamlit/hescape.h +20 -0
- data/hamlit.gemspec +45 -0
- data/lib/hamlit.rb +11 -0
- data/lib/hamlit/attribute_builder.rb +173 -0
- data/lib/hamlit/attribute_compiler.rb +123 -0
- data/lib/hamlit/attribute_parser.rb +110 -0
- data/lib/hamlit/cli.rb +130 -0
- data/lib/hamlit/compiler.rb +97 -0
- data/lib/hamlit/compiler/children_compiler.rb +112 -0
- data/lib/hamlit/compiler/comment_compiler.rb +36 -0
- data/lib/hamlit/compiler/doctype_compiler.rb +46 -0
- data/lib/hamlit/compiler/script_compiler.rb +102 -0
- data/lib/hamlit/compiler/silent_script_compiler.rb +24 -0
- data/lib/hamlit/compiler/tag_compiler.rb +74 -0
- data/lib/hamlit/engine.rb +37 -0
- data/lib/hamlit/error.rb +15 -0
- data/lib/hamlit/escapable.rb +13 -0
- data/lib/hamlit/filters.rb +75 -0
- data/lib/hamlit/filters/base.rb +12 -0
- data/lib/hamlit/filters/cdata.rb +20 -0
- data/lib/hamlit/filters/coffee.rb +17 -0
- data/lib/hamlit/filters/css.rb +33 -0
- data/lib/hamlit/filters/erb.rb +10 -0
- data/lib/hamlit/filters/escaped.rb +22 -0
- data/lib/hamlit/filters/javascript.rb +33 -0
- data/lib/hamlit/filters/less.rb +20 -0
- data/lib/hamlit/filters/markdown.rb +10 -0
- data/lib/hamlit/filters/plain.rb +29 -0
- data/lib/hamlit/filters/preserve.rb +22 -0
- data/lib/hamlit/filters/ruby.rb +10 -0
- data/lib/hamlit/filters/sass.rb +15 -0
- data/lib/hamlit/filters/scss.rb +15 -0
- data/lib/hamlit/filters/text_base.rb +25 -0
- data/lib/hamlit/filters/tilt_base.rb +49 -0
- data/lib/hamlit/force_escapable.rb +29 -0
- data/lib/hamlit/helpers.rb +15 -0
- data/lib/hamlit/html.rb +14 -0
- data/lib/hamlit/identity.rb +13 -0
- data/lib/hamlit/object_ref.rb +30 -0
- data/lib/hamlit/parser.rb +49 -0
- data/lib/hamlit/parser/MIT-LICENSE +20 -0
- data/lib/hamlit/parser/README.md +30 -0
- data/lib/hamlit/parser/haml_buffer.rb +348 -0
- data/lib/hamlit/parser/haml_compiler.rb +553 -0
- data/lib/hamlit/parser/haml_error.rb +61 -0
- data/lib/hamlit/parser/haml_helpers.rb +727 -0
- data/lib/hamlit/parser/haml_options.rb +286 -0
- data/lib/hamlit/parser/haml_parser.rb +800 -0
- data/lib/hamlit/parser/haml_util.rb +288 -0
- data/lib/hamlit/parser/haml_xss_mods.rb +109 -0
- data/lib/hamlit/rails_helpers.rb +51 -0
- data/lib/hamlit/rails_template.rb +59 -0
- data/lib/hamlit/railtie.rb +10 -0
- data/lib/hamlit/ruby_expression.rb +32 -0
- data/lib/hamlit/string_splitter.rb +88 -0
- data/lib/hamlit/template.rb +28 -0
- data/lib/hamlit/utils.rb +18 -0
- data/lib/hamlit/version.rb +4 -0
- metadata +361 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hamlit
|
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 Hamlit
|
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 Hamlit
|
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 Hamlit
|
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 ::Hamlit::HamlUtil.contains_interpolation?(text)
|
15
|
+
[:dynamic, ::Hamlit::HamlUtil.slow_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 Hamlit
|
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 Hamlit
|
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 'hamlit/string_splitter'
|
3
|
+
|
4
|
+
module Hamlit
|
5
|
+
class Filters
|
6
|
+
class Plain < Base
|
7
|
+
def compile(node)
|
8
|
+
text = node.value[:text]
|
9
|
+
text = text.rstrip unless ::Hamlit::HamlUtil.contains_interpolation?(text) # for compatibility
|
10
|
+
[:multi, *compile_plain(text)]
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def compile_plain(text)
|
16
|
+
string_literal = ::Hamlit::HamlUtil.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 Hamlit
|
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 ::Hamlit::HamlUtil.contains_interpolation?(text)
|
15
|
+
[:dynamic, ::Hamlit::HamlUtil.slow_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 Hamlit
|
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 Hamlit
|
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 Hamlit
|
3
|
+
class Filters
|
4
|
+
class TextBase < Base
|
5
|
+
def compile_text!(temple, node, prefix)
|
6
|
+
text = node.value[:text].rstrip.gsub(/^/, prefix)
|
7
|
+
if ::Hamlit::HamlUtil.contains_interpolation?(node.value[:text])
|
8
|
+
# original: Haml::Filters#compile
|
9
|
+
text = ::Hamlit::HamlUtil.slow_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 Hamlit
|
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 ::Hamlit::HamlUtil.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 = ::Hamlit::HamlUtil.slow_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, "::Hamlit::Filters::TiltBase.render('#{name}', #{text}, indent_width: #{indent_width})"]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'hamlit/escapable'
|
3
|
+
|
4
|
+
module Hamlit
|
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 Hamlit::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] || "::Hamlit::Utils.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 Hamlit::Escapable.
|
25
|
+
def on_escape(flag, exp)
|
26
|
+
[:escape, flag, compile(exp)]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hamlit
|
3
|
+
module Helpers
|
4
|
+
extend self
|
5
|
+
|
6
|
+
# The same as original Haml::Helpers#preserve without block support.
|
7
|
+
def preserve(input)
|
8
|
+
# https://github.com/haml/haml/blob/4.1.0.beta.1/lib/haml/helpers.rb#L130-L133
|
9
|
+
s = input.to_s.chomp("\n")
|
10
|
+
s.gsub!(/\n/, '
')
|
11
|
+
s.delete!("\r")
|
12
|
+
s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/hamlit/html.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hamlit
|
3
|
+
class HTML < Temple::HTML::Fast
|
4
|
+
DEPRECATED_FORMATS = %i[html4 html5].freeze
|
5
|
+
|
6
|
+
def initialize(opts = {})
|
7
|
+
if DEPRECATED_FORMATS.include?(opts[:format])
|
8
|
+
opts = opts.dup
|
9
|
+
opts[:format] = :html
|
10
|
+
end
|
11
|
+
super(opts)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Hamlit
|
3
|
+
module ObjectRef
|
4
|
+
class << self
|
5
|
+
def parse(args)
|
6
|
+
object, prefix = args
|
7
|
+
return {} unless object
|
8
|
+
|
9
|
+
suffix = underscore(object.class)
|
10
|
+
{
|
11
|
+
'class' => [prefix, suffix].compact.join('_'),
|
12
|
+
'id' => [prefix, suffix, object.id || 'new'].compact.join('_'),
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Haml::Buffer.underscore
|
19
|
+
def underscore(camel_cased_word)
|
20
|
+
word = camel_cased_word.to_s.dup
|
21
|
+
word.gsub!(/::/, '_')
|
22
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
23
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
24
|
+
word.tr!('-', '_')
|
25
|
+
word.downcase!
|
26
|
+
word
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|