hamlit 1.7.2 → 2.0.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/.gitignore +4 -3
- data/.gitmodules +3 -0
- data/.travis.yml +25 -37
- data/CHANGELOG.md +18 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +23 -2
- data/README.md +106 -48
- data/REFERENCE.md +222 -0
- data/Rakefile +77 -19
- 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/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/tags.haml +3 -0
- data/benchmark/ext/build_data.rb +15 -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/{benchmarks → benchmark/slim}/context.rb +2 -4
- data/benchmark/slim/run-benchmarks.rb +94 -0
- data/{benchmarks → benchmark/slim}/view.erb +3 -3
- data/{benchmarks → benchmark/slim}/view.haml +0 -0
- data/{benchmarks/view.escaped.slim → benchmark/slim/view.slim} +1 -1
- data/benchmark/string_interpolation.haml +2 -0
- data/benchmark/utils/benchmark_ips_extension.rb +43 -0
- data/bin/bench +85 -0
- data/bin/clone +14 -0
- data/bin/console +11 -0
- data/bin/lineprof +48 -0
- data/bin/ruby +3 -0
- data/bin/setup +7 -0
- data/bin/stackprof +27 -0
- data/{test → bin/test} +6 -10
- data/{bin → exe}/hamlit +0 -0
- data/ext/hamlit/extconf.rb +14 -0
- data/ext/hamlit/hamlit.c +512 -0
- data/ext/hamlit/houdini/.gitignore +3 -0
- data/ext/hamlit/houdini/COPYING +7 -0
- data/ext/hamlit/houdini/Makefile +79 -0
- data/ext/hamlit/houdini/README.md +59 -0
- data/ext/hamlit/houdini/buffer.c +249 -0
- data/ext/hamlit/houdini/buffer.h +113 -0
- data/ext/hamlit/houdini/houdini.h +46 -0
- data/ext/hamlit/houdini/houdini_href_e.c +115 -0
- data/ext/hamlit/houdini/houdini_html_e.c +90 -0
- data/ext/hamlit/houdini/houdini_html_u.c +122 -0
- data/ext/hamlit/houdini/houdini_js_e.c +90 -0
- data/ext/hamlit/houdini/houdini_js_u.c +60 -0
- data/ext/hamlit/houdini/houdini_uri_e.c +107 -0
- data/ext/hamlit/houdini/houdini_uri_u.c +68 -0
- data/ext/hamlit/houdini/houdini_xml_e.c +136 -0
- data/ext/hamlit/houdini/html_unescape.gperf +258 -0
- data/ext/hamlit/houdini/html_unescape.h +754 -0
- data/ext/hamlit/houdini/tools/build_table.py +13 -0
- data/ext/hamlit/houdini/tools/build_tables.c +51 -0
- data/ext/hamlit/houdini/tools/wikipedia_table.txt +2025 -0
- data/hamlit.gemspec +30 -31
- data/lib/hamlit.rb +3 -1
- data/lib/hamlit/attribute_builder.rb +12 -0
- data/lib/hamlit/cli.rb +44 -43
- data/lib/hamlit/compiler.rb +92 -16
- data/lib/hamlit/compiler/attribute_compiler.rb +148 -0
- data/lib/hamlit/compiler/children_compiler.rb +111 -0
- data/lib/hamlit/compiler/comment_compiler.rb +36 -0
- data/lib/hamlit/compiler/doctype_compiler.rb +45 -0
- data/lib/hamlit/compiler/script_compiler.rb +97 -0
- data/lib/hamlit/compiler/silent_script_compiler.rb +24 -0
- data/lib/hamlit/compiler/tag_compiler.rb +69 -0
- data/lib/hamlit/engine.rb +12 -7
- data/lib/hamlit/error.rb +14 -0
- data/lib/hamlit/escapable.rb +12 -0
- data/lib/hamlit/filters.rb +65 -0
- data/lib/hamlit/filters/base.rb +4 -62
- data/lib/hamlit/filters/coffee.rb +9 -7
- data/lib/hamlit/filters/css.rb +25 -8
- data/lib/hamlit/filters/erb.rb +4 -6
- data/lib/hamlit/filters/escaped.rb +11 -9
- data/lib/hamlit/filters/javascript.rb +25 -8
- data/lib/hamlit/filters/less.rb +9 -7
- data/lib/hamlit/filters/markdown.rb +5 -6
- data/lib/hamlit/filters/plain.rb +11 -15
- data/lib/hamlit/filters/preserve.rb +15 -5
- data/lib/hamlit/filters/ruby.rb +3 -5
- data/lib/hamlit/filters/sass.rb +9 -7
- data/lib/hamlit/filters/scss.rb +9 -7
- data/lib/hamlit/filters/text_base.rb +24 -0
- data/lib/hamlit/filters/tilt_base.rb +47 -0
- data/lib/hamlit/hash_parser.rb +107 -0
- data/lib/hamlit/html.rb +9 -6
- data/lib/hamlit/identity.rb +12 -0
- data/lib/hamlit/object_ref.rb +29 -0
- data/lib/hamlit/parser.rb +25 -142
- data/lib/hamlit/parser/MIT-LICENSE +20 -0
- data/lib/hamlit/parser/README.md +28 -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 +801 -0
- data/lib/hamlit/parser/haml_util.rb +283 -0
- data/lib/hamlit/parser/haml_xss_mods.rb +109 -0
- data/lib/hamlit/{helpers.rb → rails_helpers.rb} +2 -7
- data/lib/hamlit/rails_template.rb +30 -0
- data/lib/hamlit/railtie.rb +1 -12
- data/lib/hamlit/ruby_expression.rb +31 -0
- data/lib/hamlit/static_analyzer.rb +49 -0
- data/lib/hamlit/string_interpolation.rb +69 -0
- data/lib/hamlit/template.rb +8 -0
- data/lib/hamlit/utils.rb +9 -0
- data/lib/hamlit/version.rb +1 -1
- metadata +116 -324
- data/.rspec +0 -2
- data/benchmarks/benchmark.rb +0 -110
- data/benchmarks/view.slim +0 -17
- data/doc/README.md +0 -19
- data/doc/engine/indent.md +0 -48
- data/doc/engine/new_attribute.md +0 -77
- data/doc/engine/old_attributes.md +0 -198
- data/doc/engine/silent_script.md +0 -97
- data/doc/engine/tag.md +0 -48
- data/doc/engine/text.md +0 -64
- data/doc/faml/README.md +0 -16
- data/doc/faml/engine/indent.md +0 -48
- data/doc/faml/engine/old_attributes.md +0 -111
- data/doc/faml/engine/silent_script.md +0 -97
- data/doc/faml/engine/text.md +0 -59
- data/doc/faml/filters/erb.md +0 -24
- data/doc/faml/filters/javascript.md +0 -27
- data/doc/faml/filters/less.md +0 -57
- data/doc/faml/filters/plain.md +0 -25
- data/doc/filters/erb.md +0 -31
- data/doc/filters/javascript.md +0 -83
- data/doc/filters/less.md +0 -57
- data/doc/filters/markdown.md +0 -31
- data/doc/filters/plain.md +0 -25
- data/doc/haml/README.md +0 -15
- data/doc/haml/engine/new_attribute.md +0 -77
- data/doc/haml/engine/old_attributes.md +0 -142
- data/doc/haml/engine/tag.md +0 -48
- data/doc/haml/engine/text.md +0 -29
- data/doc/haml/filters/erb.md +0 -26
- data/doc/haml/filters/javascript.md +0 -76
- data/doc/haml/filters/markdown.md +0 -31
- data/lib/hamlit/attribute.rb +0 -78
- data/lib/hamlit/compilers/attributes.rb +0 -108
- data/lib/hamlit/compilers/comment.rb +0 -13
- data/lib/hamlit/compilers/doctype.rb +0 -39
- data/lib/hamlit/compilers/filter.rb +0 -53
- data/lib/hamlit/compilers/new_attribute.rb +0 -115
- data/lib/hamlit/compilers/old_attribute.rb +0 -241
- data/lib/hamlit/compilers/runtime_attribute.rb +0 -58
- data/lib/hamlit/compilers/script.rb +0 -31
- data/lib/hamlit/compilers/strip.rb +0 -19
- data/lib/hamlit/compilers/text.rb +0 -111
- data/lib/hamlit/concerns/attribute_builder.rb +0 -22
- data/lib/hamlit/concerns/balanceable.rb +0 -68
- data/lib/hamlit/concerns/deprecation.rb +0 -20
- data/lib/hamlit/concerns/error.rb +0 -31
- data/lib/hamlit/concerns/escapable.rb +0 -17
- data/lib/hamlit/concerns/included.rb +0 -28
- data/lib/hamlit/concerns/indentable.rb +0 -117
- data/lib/hamlit/concerns/lexable.rb +0 -32
- data/lib/hamlit/concerns/line_reader.rb +0 -62
- data/lib/hamlit/concerns/registerable.rb +0 -24
- data/lib/hamlit/concerns/string_interpolation.rb +0 -48
- data/lib/hamlit/concerns/whitespace.rb +0 -91
- data/lib/hamlit/filters/tilt.rb +0 -41
- data/lib/hamlit/parsers/attribute.rb +0 -71
- data/lib/hamlit/parsers/comment.rb +0 -30
- data/lib/hamlit/parsers/doctype.rb +0 -18
- data/lib/hamlit/parsers/filter.rb +0 -18
- data/lib/hamlit/parsers/multiline.rb +0 -58
- data/lib/hamlit/parsers/script.rb +0 -126
- data/lib/hamlit/parsers/tag.rb +0 -83
- data/lib/hamlit/parsers/text.rb +0 -28
- data/lib/hamlit/temple.rb +0 -9
- data/release +0 -6
- data/spec/Rakefile +0 -72
- data/spec/hamlit/engine/comment_spec.rb +0 -56
- data/spec/hamlit/engine/doctype_spec.rb +0 -19
- data/spec/hamlit/engine/error_spec.rb +0 -135
- data/spec/hamlit/engine/indent_spec.rb +0 -42
- data/spec/hamlit/engine/multiline_spec.rb +0 -44
- data/spec/hamlit/engine/new_attribute_spec.rb +0 -110
- data/spec/hamlit/engine/old_attributes_spec.rb +0 -404
- data/spec/hamlit/engine/script_spec.rb +0 -116
- data/spec/hamlit/engine/silent_script_spec.rb +0 -213
- data/spec/hamlit/engine/tag_spec.rb +0 -295
- data/spec/hamlit/engine/text_spec.rb +0 -239
- data/spec/hamlit/engine_spec.rb +0 -58
- data/spec/hamlit/filters/coffee_spec.rb +0 -60
- data/spec/hamlit/filters/css_spec.rb +0 -33
- data/spec/hamlit/filters/erb_spec.rb +0 -16
- data/spec/hamlit/filters/javascript_spec.rb +0 -82
- data/spec/hamlit/filters/less_spec.rb +0 -37
- data/spec/hamlit/filters/markdown_spec.rb +0 -30
- data/spec/hamlit/filters/plain_spec.rb +0 -15
- data/spec/hamlit/filters/ruby_spec.rb +0 -24
- data/spec/hamlit/filters/sass_spec.rb +0 -33
- data/spec/hamlit/filters/scss_spec.rb +0 -37
- data/spec/hamlit/haml_spec.rb +0 -910
- data/spec/rails/.gitignore +0 -18
- data/spec/rails/.rspec +0 -2
- data/spec/rails/Gemfile +0 -19
- data/spec/rails/README.rdoc +0 -28
- data/spec/rails/Rakefile +0 -6
- data/spec/rails/app/assets/images/.keep +0 -0
- data/spec/rails/app/assets/javascripts/application.js +0 -15
- data/spec/rails/app/assets/stylesheets/application.css +0 -15
- data/spec/rails/app/controllers/application_controller.rb +0 -8
- data/spec/rails/app/controllers/concerns/.keep +0 -0
- data/spec/rails/app/controllers/users_controller.rb +0 -23
- data/spec/rails/app/helpers/application_helper.rb +0 -2
- data/spec/rails/app/mailers/.keep +0 -0
- data/spec/rails/app/models/.keep +0 -0
- data/spec/rails/app/models/concerns/.keep +0 -0
- data/spec/rails/app/views/application/index.html.haml +0 -18
- data/spec/rails/app/views/layouts/application.html.haml +0 -12
- data/spec/rails/app/views/users/capture.html.haml +0 -5
- data/spec/rails/app/views/users/capture_haml.html.haml +0 -5
- data/spec/rails/app/views/users/form.html.haml +0 -2
- data/spec/rails/app/views/users/helpers.html.haml +0 -10
- data/spec/rails/app/views/users/index.html.haml +0 -9
- data/spec/rails/app/views/users/inline.html.haml +0 -6
- data/spec/rails/app/views/users/old_attributes.html.haml +0 -5
- data/spec/rails/app/views/users/safe_buffer.html.haml +0 -4
- data/spec/rails/app/views/users/whitespace.html.haml +0 -4
- data/spec/rails/bin/bundle +0 -3
- data/spec/rails/bin/rails +0 -8
- data/spec/rails/bin/rake +0 -8
- data/spec/rails/bin/setup +0 -29
- data/spec/rails/bin/spring +0 -15
- data/spec/rails/config.ru +0 -4
- data/spec/rails/config/application.rb +0 -34
- data/spec/rails/config/boot.rb +0 -3
- data/spec/rails/config/database.yml +0 -25
- data/spec/rails/config/environment.rb +0 -5
- data/spec/rails/config/environments/development.rb +0 -41
- data/spec/rails/config/environments/production.rb +0 -79
- data/spec/rails/config/environments/test.rb +0 -42
- data/spec/rails/config/initializers/assets.rb +0 -11
- data/spec/rails/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails/config/initializers/cookies_serializer.rb +0 -3
- data/spec/rails/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/rails/config/initializers/inflections.rb +0 -16
- data/spec/rails/config/initializers/mime_types.rb +0 -4
- data/spec/rails/config/initializers/session_store.rb +0 -3
- data/spec/rails/config/initializers/wrap_parameters.rb +0 -14
- data/spec/rails/config/locales/en.yml +0 -24
- data/spec/rails/config/routes.rb +0 -16
- data/spec/rails/config/secrets.yml +0 -22
- data/spec/rails/db/schema.rb +0 -16
- data/spec/rails/db/seeds.rb +0 -7
- data/spec/rails/lib/assets/.keep +0 -0
- data/spec/rails/lib/tasks/.keep +0 -0
- data/spec/rails/log/.keep +0 -0
- data/spec/rails/public/404.html +0 -67
- data/spec/rails/public/422.html +0 -67
- data/spec/rails/public/500.html +0 -66
- data/spec/rails/public/favicon.ico +0 -0
- data/spec/rails/public/robots.txt +0 -5
- data/spec/rails/spec/hamlit_spec.rb +0 -123
- data/spec/rails/spec/rails_helper.rb +0 -56
- data/spec/rails/spec/spec_helper.rb +0 -91
- data/spec/rails/vendor/assets/javascripts/.keep +0 -0
- data/spec/rails/vendor/assets/stylesheets/.keep +0 -0
- data/spec/spec_helper.rb +0 -36
- data/spec/spec_helper/document_generator.rb +0 -93
- data/spec/spec_helper/render_helper.rb +0 -120
- data/spec/spec_helper/test_case.rb +0 -55
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
require 'hamlit/attribute'
|
|
2
|
-
require 'hamlit/concerns/string_interpolation'
|
|
3
|
-
|
|
4
|
-
# This module compiles :runtime sexp. It is a special version of
|
|
5
|
-
# old-style attribute which is built on runtime.
|
|
6
|
-
module Hamlit
|
|
7
|
-
module Compilers
|
|
8
|
-
module RuntimeAttribute
|
|
9
|
-
include Concerns::StringInterpolation
|
|
10
|
-
|
|
11
|
-
# This is used for compiling only runtime attribute in Compilers::Attribute.
|
|
12
|
-
def on_runtime(str)
|
|
13
|
-
compile_runtime_attribute(str)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Given html attrs, merge classes and ids to :dynamic_attribute.
|
|
17
|
-
def merge_runtime_attributes(attrs)
|
|
18
|
-
merge_targets = filter_attrs(attrs, 'id', 'class')
|
|
19
|
-
dynamic_attr = attrs.find { |exp, *args| exp == :runtime }
|
|
20
|
-
|
|
21
|
-
attrs -= merge_targets
|
|
22
|
-
attrs.delete(dynamic_attr)
|
|
23
|
-
|
|
24
|
-
base = decompile_temple_attrs(merge_targets)
|
|
25
|
-
[compile_runtime_attribute(dynamic_attr.last, base), *attrs]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
def compile_runtime_attribute(str, base = nil)
|
|
31
|
-
str = str.gsub(/(\A\{|\}\Z)/, '')
|
|
32
|
-
quote = options[:attr_quote].inspect
|
|
33
|
-
code = "::Hamlit::Attribute.build(#{[quote, base, str].compact.join(', ')})"
|
|
34
|
-
[:dynamic, code]
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def has_runtime_attribute?(attrs)
|
|
38
|
-
attrs.any? do |exp, *args|
|
|
39
|
-
exp == :runtime
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Given attrs in temple ast, return an attribute as hash literal.
|
|
44
|
-
def decompile_temple_attrs(attrs)
|
|
45
|
-
literal = '{'
|
|
46
|
-
attrs.each do |html, attr, name, (type, value)|
|
|
47
|
-
case type
|
|
48
|
-
when :static
|
|
49
|
-
literal += ":#{name}=>#{string_literal(value)},"
|
|
50
|
-
when :dynamic
|
|
51
|
-
literal += ":#{name}=>#{value},"
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
literal.gsub(/,\Z/, '') + '}'
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
require 'hamlit/concerns/escapable'
|
|
2
|
-
require 'hamlit/concerns/included'
|
|
3
|
-
|
|
4
|
-
module Hamlit
|
|
5
|
-
module Compilers
|
|
6
|
-
module Script
|
|
7
|
-
extend Concerns::Included
|
|
8
|
-
|
|
9
|
-
included do
|
|
10
|
-
include Concerns::Escapable
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def on_haml_script(code, options, *exps)
|
|
14
|
-
variable = result_identifier
|
|
15
|
-
|
|
16
|
-
assign = [:code, "#{variable} = #{code}"]
|
|
17
|
-
result = escape_html([:dynamic, variable], options[:force_escape])
|
|
18
|
-
result = [:dynamic, variable] if options[:disable_escape]
|
|
19
|
-
[:multi, assign, *exps.map { |exp| compile(exp) }, compile(result)]
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def result_identifier
|
|
25
|
-
@id_auto_increment ||= -1
|
|
26
|
-
@id_auto_increment += 1
|
|
27
|
-
"_hamlit_compiler#{@id_auto_increment}"
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
require 'hamlit/concerns/whitespace'
|
|
2
|
-
|
|
3
|
-
# This module is created to compile [:haml, :strip],
|
|
4
|
-
# which is sexp for whitespace inner removal.module Hamlit
|
|
5
|
-
module Hamlit
|
|
6
|
-
module Compilers
|
|
7
|
-
module Strip
|
|
8
|
-
include Concerns::Whitespace
|
|
9
|
-
|
|
10
|
-
def on_haml_strip(*exps)
|
|
11
|
-
exps = exps.dup
|
|
12
|
-
remove_first_space!(exps)
|
|
13
|
-
remove_last_space!(exps)
|
|
14
|
-
|
|
15
|
-
on_multi(*exps)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
require 'hamlit/concerns/error'
|
|
2
|
-
require 'hamlit/concerns/escapable'
|
|
3
|
-
require 'hamlit/concerns/included'
|
|
4
|
-
require 'hamlit/concerns/lexable'
|
|
5
|
-
require 'hamlit/concerns/string_interpolation'
|
|
6
|
-
|
|
7
|
-
module Hamlit
|
|
8
|
-
module Compilers
|
|
9
|
-
module Text
|
|
10
|
-
extend Concerns::Included
|
|
11
|
-
include Concerns::Error
|
|
12
|
-
include Concerns::Lexable
|
|
13
|
-
include Concerns::StringInterpolation
|
|
14
|
-
|
|
15
|
-
included do
|
|
16
|
-
include Concerns::Escapable
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# To ask ripper to consider a given text as string literal,
|
|
20
|
-
# I change "foo" to "%!foo!".
|
|
21
|
-
# This constant is the candidates for the literal surrounder.
|
|
22
|
-
STRING_MARKERS = %w[' " ! @ $ % ^ & * | =].freeze
|
|
23
|
-
|
|
24
|
-
# Return static and dynamic temple ast.
|
|
25
|
-
# It splits expression to optimize because string interpolation is slow.
|
|
26
|
-
def on_haml_text(exp, escape_html = true)
|
|
27
|
-
return syntax_error('Unbalanced brackets.') unless valid_interpolation?(exp)
|
|
28
|
-
return static_text(exp) unless contains_interpolation?(exp)
|
|
29
|
-
|
|
30
|
-
marker = find_string_marker(exp)
|
|
31
|
-
return [:dynamic, string_literal(exp)] unless marker
|
|
32
|
-
|
|
33
|
-
open_pos, close_pos = find_interpolation(exp, marker)
|
|
34
|
-
return static_text(exp) unless open_pos && close_pos
|
|
35
|
-
|
|
36
|
-
pre = exp.byteslice(0...open_pos)
|
|
37
|
-
body = exp.byteslice((open_pos + 2)...close_pos)
|
|
38
|
-
post = exp.byteslice((close_pos + 1)...exp.bytesize)
|
|
39
|
-
|
|
40
|
-
body_ast = escape_html ? escape_html([:dynamic, body]) : [:dynamic, body]
|
|
41
|
-
[:multi, [:static, pre], body_ast, on_haml_text(post)]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def find_interpolation(exp, marker)
|
|
45
|
-
return unless contains_interpolation?(exp)
|
|
46
|
-
|
|
47
|
-
offset = 2 # 2 is the length of '%' and marker
|
|
48
|
-
open_pos = nil
|
|
49
|
-
open_count = 0
|
|
50
|
-
literal = literalify_string(exp, marker)
|
|
51
|
-
|
|
52
|
-
Ripper.lex(literal).each do |(row, col), type, str|
|
|
53
|
-
case type
|
|
54
|
-
when :on_embexpr_beg
|
|
55
|
-
open_pos = shifted_position(exp, row, col, offset) if open_count == 0
|
|
56
|
-
open_count += 1
|
|
57
|
-
when :on_embexpr_end
|
|
58
|
-
open_count -= 1
|
|
59
|
-
return [open_pos, shifted_position(exp, row, col, offset)] if open_count == 0
|
|
60
|
-
end
|
|
61
|
-
open_count
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
nil
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
private
|
|
68
|
-
|
|
69
|
-
def valid_interpolation?(exp)
|
|
70
|
-
marker = find_string_marker(exp)
|
|
71
|
-
return true unless marker # give up checking
|
|
72
|
-
|
|
73
|
-
literal = literalify_string(exp, marker)
|
|
74
|
-
open_count = 0
|
|
75
|
-
|
|
76
|
-
Ripper.lex(literal).each do |_, type, str|
|
|
77
|
-
case type
|
|
78
|
-
when :on_embexpr_beg
|
|
79
|
-
open_count += 1
|
|
80
|
-
when :on_embexpr_end
|
|
81
|
-
open_count -= 1
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
open_count == 0
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# :static can't treat backslash properly
|
|
88
|
-
def static_text(exp)
|
|
89
|
-
return [:dynamic, string_literal(exp)] if exp.include?('\\')
|
|
90
|
-
[:static, exp]
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def find_string_marker(text)
|
|
94
|
-
STRING_MARKERS.each do |marker|
|
|
95
|
-
return marker unless text.include?(marker)
|
|
96
|
-
end
|
|
97
|
-
nil
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def literalify_string(exp, marker)
|
|
101
|
-
"%#{marker}#{exp}#{marker}"
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# In this compiler, only first line is shifted 2 chars.
|
|
105
|
-
def shifted_position(exp, row, col, offset)
|
|
106
|
-
return col - offset if row <= 1
|
|
107
|
-
convert_position(exp, row, col)
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Hamlit
|
|
2
|
-
module Concerns
|
|
3
|
-
module AttributeBuilder
|
|
4
|
-
def flatten_attributes(attributes)
|
|
5
|
-
flattened = {}
|
|
6
|
-
|
|
7
|
-
attributes.each do |key, value|
|
|
8
|
-
case value
|
|
9
|
-
when Hash
|
|
10
|
-
flatten_attributes(value).each do |k, v|
|
|
11
|
-
k = k.to_s.gsub(/_/, '-')
|
|
12
|
-
flattened["#{key}-#{k}"] = v if v
|
|
13
|
-
end
|
|
14
|
-
else
|
|
15
|
-
flattened[key] = value if value
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
flattened
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require 'ripper'
|
|
2
|
-
require 'hamlit/concerns/lexable'
|
|
3
|
-
|
|
4
|
-
module Hamlit
|
|
5
|
-
module Concerns
|
|
6
|
-
module Balanceable
|
|
7
|
-
include Lexable
|
|
8
|
-
|
|
9
|
-
def fetch_balanced_braces(all_tokens)
|
|
10
|
-
fetch_balanced_tokens(all_tokens, :on_lbrace, :on_rbrace)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def fetch_balanced_parentheses(all_tokens)
|
|
14
|
-
fetch_balanced_tokens(all_tokens, :on_lparen, :on_rparen)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def fetch_balanced_embexprs(all_tokens, start_count: 0)
|
|
18
|
-
fetch_balanced_tokens(all_tokens, :on_embexpr_beg, :on_embexpr_end, start_count: start_count)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def balanced_braces_exist?(tokens)
|
|
22
|
-
balanced_tokens_exist?(tokens, :on_lbrace, :on_rbrace)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def balanced_parens_exist?(tokens)
|
|
26
|
-
balanced_tokens_exist?(tokens, :on_lparen, :on_rparen)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def balanced_embexprs_exist?(tokens, start_count: 0)
|
|
30
|
-
balanced_tokens_exist?(tokens, :on_embexpr_beg, :on_embexpr_end, start_count: start_count)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def fetch_balanced_tokens(all_tokens, open_token, close_token, start_count: 0)
|
|
36
|
-
tokens = []
|
|
37
|
-
open_count = start_count
|
|
38
|
-
|
|
39
|
-
all_tokens.each_with_index do |token, index|
|
|
40
|
-
case type_of(token)
|
|
41
|
-
when open_token then open_count += 1
|
|
42
|
-
when close_token then open_count -= 1
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
tokens << token
|
|
46
|
-
break if open_count == 0
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
tokens
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def balanced_tokens_exist?(tokens, open_token, close_token, start_count: 0)
|
|
53
|
-
open_count = start_count
|
|
54
|
-
|
|
55
|
-
tokens.each do |token|
|
|
56
|
-
case type_of(token)
|
|
57
|
-
when open_token then open_count += 1
|
|
58
|
-
when close_token then open_count -= 1
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
break if open_count == 0
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
open_count == 0
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# A module to suppress deprecation warnings by temple.
|
|
2
|
-
# These deprecated options are specified in haml-spec.
|
|
3
|
-
module Hamlit
|
|
4
|
-
module Concerns
|
|
5
|
-
module Deprecation
|
|
6
|
-
DEPCATED_OPTIONS = %i[html4 html5].freeze
|
|
7
|
-
|
|
8
|
-
def initialize(opts = {})
|
|
9
|
-
super rewrite_deprecated_options(opts)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# Temple's warning is noisy in haml-spec.
|
|
13
|
-
def rewrite_deprecated_options(options)
|
|
14
|
-
options = options.dup
|
|
15
|
-
options[:format] = :html if DEPCATED_OPTIONS.include?(options[:format])
|
|
16
|
-
options
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
module Hamlit
|
|
2
|
-
class SyntaxError < StandardError; end
|
|
3
|
-
class CompileError < StandardError; end
|
|
4
|
-
|
|
5
|
-
module Concerns
|
|
6
|
-
module Error
|
|
7
|
-
# Template engine should raise Exception on runtime to
|
|
8
|
-
# show template's error backtrace.
|
|
9
|
-
def syntax_error(message)
|
|
10
|
-
code = %Q{raise Hamlit::SyntaxError.new(%q{#{message}})}
|
|
11
|
-
[:code, code]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def syntax_error!(message)
|
|
15
|
-
raise Hamlit::SyntaxError.new(message)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def copmile_error!(message)
|
|
19
|
-
raise CompileError.new(message)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def assert_scan!(scanner, regexp)
|
|
23
|
-
result = scanner.scan(regexp)
|
|
24
|
-
unless result
|
|
25
|
-
raise CompileError.new("Expected to scan #{regexp} but got nil")
|
|
26
|
-
end
|
|
27
|
-
result
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require 'hamlit/concerns/included'
|
|
2
|
-
|
|
3
|
-
module Hamlit
|
|
4
|
-
module Concerns
|
|
5
|
-
module Escapable
|
|
6
|
-
extend Included
|
|
7
|
-
|
|
8
|
-
included do
|
|
9
|
-
define_options escape_html: false
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def escape_html(exp, force_escape = false)
|
|
13
|
-
[:escape, force_escape || @options[:escape_html], exp]
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Mini ActiveSupport::Concern
|
|
2
|
-
module Hamlit
|
|
3
|
-
module Concerns
|
|
4
|
-
class MultipleIncludedBlocks < StandardError
|
|
5
|
-
def initialize
|
|
6
|
-
super "Cannot define multiple 'included' blocks for a Concern"
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
module Included
|
|
11
|
-
def self.extended(klass)
|
|
12
|
-
klass.class_eval do
|
|
13
|
-
def self.included(base = nil, &block)
|
|
14
|
-
if block_given?
|
|
15
|
-
raise MultipleIncludedBlocks if defined?(@_included_block)
|
|
16
|
-
|
|
17
|
-
@_included_block = block
|
|
18
|
-
return
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
base.instance_exec(&@_included_block) if defined?(@_included_block)
|
|
22
|
-
super
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
require 'hamlit/concerns/error'
|
|
2
|
-
|
|
3
|
-
module Hamlit
|
|
4
|
-
EOF = -1
|
|
5
|
-
|
|
6
|
-
module Concerns
|
|
7
|
-
module Indentable
|
|
8
|
-
include Concerns::Error
|
|
9
|
-
|
|
10
|
-
def reset_indent
|
|
11
|
-
@indent_logs = []
|
|
12
|
-
@current_indent = 0
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# Return nearest line's indent level since next line. This method ignores
|
|
16
|
-
# empty line. It returns -1 if next_line does not exist.
|
|
17
|
-
def next_indent
|
|
18
|
-
return 1 if !defined?(@indent_space) && fetch_indent(next_line).length > 0
|
|
19
|
-
count_indent(next_line)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def with_indented(&block)
|
|
23
|
-
@current_indent += 1
|
|
24
|
-
block.call
|
|
25
|
-
ensure
|
|
26
|
-
@current_indent -= 1
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def count_indent(line)
|
|
30
|
-
return EOF unless line
|
|
31
|
-
return 0 if indent_rule == 0
|
|
32
|
-
|
|
33
|
-
line.match(/\A[ \t]+/).to_s.length / indent_rule
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def same_indent?(line)
|
|
37
|
-
return false unless line
|
|
38
|
-
count_indent(line) == @current_indent
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Validate current line's indentation
|
|
42
|
-
def validate_indentation!(ast)
|
|
43
|
-
return true unless next_line
|
|
44
|
-
|
|
45
|
-
indent = fetch_indent(next_line)
|
|
46
|
-
if indent.include?(' ') && indent.include?("\t")
|
|
47
|
-
syntax_error!("Indentation can't use both tabs and spaces.")
|
|
48
|
-
end
|
|
49
|
-
@indent_logs << indent
|
|
50
|
-
|
|
51
|
-
if !defined?(@indent_space) && @indent_logs.last != ''
|
|
52
|
-
@indent_space = @indent_logs.last
|
|
53
|
-
end
|
|
54
|
-
validate_indentation_consistency!(indent)
|
|
55
|
-
reject_too_deep_indentation!
|
|
56
|
-
|
|
57
|
-
next_indent < @current_indent
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def has_block?
|
|
61
|
-
return false unless next_line
|
|
62
|
-
return fetch_indent(next_line).length > 0 unless defined?(@indent_space)
|
|
63
|
-
|
|
64
|
-
next_indent > @current_indent
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
private
|
|
68
|
-
|
|
69
|
-
# Validate the template is using consitent indentation, 2 spaces or a tab.
|
|
70
|
-
def validate_indentation_consistency!(indent)
|
|
71
|
-
return false if indent.empty?
|
|
72
|
-
return false if !defined?(@indent_space) || @indent_space.empty?
|
|
73
|
-
|
|
74
|
-
unless acceptable_indent?(indent)
|
|
75
|
-
syntax_error!("Inconsistent indentation: #{indent_label(indent)} used for indentation, "\
|
|
76
|
-
"but the rest of the document was indented using #{indent_label(@indent_space)}.")
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def acceptable_indent?(indent)
|
|
81
|
-
indent = indent.dup
|
|
82
|
-
while indent.match(/^#{@indent_space}/)
|
|
83
|
-
indent.gsub!(/^#{@indent_space}/, '')
|
|
84
|
-
end
|
|
85
|
-
indent.empty?
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def reject_too_deep_indentation!
|
|
89
|
-
return if next_indent <= @current_indent
|
|
90
|
-
|
|
91
|
-
if @indent_logs.length == 1
|
|
92
|
-
syntax_error!('Indenting at the beginning of the document is illegal.')
|
|
93
|
-
else
|
|
94
|
-
syntax_error!("The line was indented #{next_indent - count_indent(current_line)} levels deeper than the previous line.")
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def indent_label(indent)
|
|
99
|
-
return %Q{"#{indent}"} if indent.include?(' ') && indent.include?("\t")
|
|
100
|
-
|
|
101
|
-
label = indent.include?(' ') ? 'space' : 'tab'
|
|
102
|
-
length = indent.match(/[ \t]+/).to_s.length
|
|
103
|
-
|
|
104
|
-
"#{length} #{label}#{'s' if length > 1}"
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def indent_rule
|
|
108
|
-
return 0 unless defined?(@indent_space)
|
|
109
|
-
@indent_space.length
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def fetch_indent(str)
|
|
113
|
-
str.match(/^[ \t]+/).to_s
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|