haml 6.1.4 → 6.2.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/CHANGELOG.md +9 -1
- data/FAQ.md +1 -1
- data/README.md +5 -5
- data/REFERENCE.md +25 -29
- data/Rakefile +3 -37
- data/haml.gemspec +1 -7
- data/lib/haml/attribute_builder.rb +124 -129
- data/lib/haml/version.rb +1 -1
- metadata +3 -22
- data/ext/haml/extconf.rb +0 -10
- data/ext/haml/haml.c +0 -529
- data/ext/haml/hescape.c +0 -108
- data/ext/haml/hescape.h +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28980224aeb7aaf767631d85d1a25371bd1e1fd78b87afa34ba5e300ee397126
|
4
|
+
data.tar.gz: c6e6cf4c766238cf501eb7695d75bc973746010a0c11bc90bce88d51d3d6b20d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42427402b30e767c124156562de33826ba7e16905a71ee38d494182bb0bd2f7f29135c1fd736702932ca656b94d3fdf8503e5829bd1d4cf62928eb3703261123
|
7
|
+
data.tar.gz: a8786a46da773e42d90bca9c29a9003a07be1a0b0f4ef2ad8ce7af117566ea96e891bc13ec22ccb5ab3ad0b6c62be8f247c7ac5b9db279c2f21cd0e4b3d06576
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Haml Changelog
|
2
2
|
|
3
|
+
## 6.2.1
|
4
|
+
|
5
|
+
* Fix v6.2.0's bug in rendering dynamic `aria` attributes [#1149](https://github.com/haml/haml/issues/1149)
|
6
|
+
|
7
|
+
## 6.2.0
|
8
|
+
|
9
|
+
* Drop the C extension [#1146](https://github.com/haml/haml/issues/1146)
|
10
|
+
|
3
11
|
## 6.1.4
|
4
12
|
|
5
13
|
* Let `Haml::Util.escape_html` use `ERB::Escape` if available [#1145](https://github.com/haml/haml/issues/1145)
|
@@ -1444,7 +1452,7 @@ Haml 2.2 introduces a new syntax for attributes
|
|
1444
1452
|
based on the HTML syntax.
|
1445
1453
|
For example:
|
1446
1454
|
|
1447
|
-
%a(href="
|
1455
|
+
%a(href="https://haml.info" title="Haml's so cool!")
|
1448
1456
|
%img(src="/images/haml.png" alt="Haml")
|
1449
1457
|
|
1450
1458
|
There are two main reasons for this.
|
data/FAQ.md
CHANGED
@@ -141,7 +141,7 @@ For other plugins, a little searching will probably turn up a way to fix them as
|
|
141
141
|
|
142
142
|
## You still haven't answered my question!
|
143
143
|
|
144
|
-
Sorry! Try looking at the [Haml](
|
144
|
+
Sorry! Try looking at the [Haml](https://haml.info/docs/yardoc/file.REFERENCE.html) reference,
|
145
145
|
If you can't find an answer there,
|
146
146
|
feel free to ask in `#haml` on irc.freenode.net
|
147
147
|
or send an email to the [mailing list](http://groups.google.com/group/haml).
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Haml
|
2
2
|
|
3
|
-
[](
|
3
|
+
[](https://rubygems.org/gems/haml)
|
4
4
|
[](https://github.com/haml/haml/actions/workflows/test.yml)
|
5
5
|
[](https://codeclimate.com/github/haml/haml)
|
6
6
|
[](https://inch-ci.org/github/haml/haml)
|
@@ -31,7 +31,7 @@ to compile it to HTML. For more information on these commands, check out
|
|
31
31
|
haml --help
|
32
32
|
~~~
|
33
33
|
|
34
|
-
To use Haml programmatically, check out the [YARD documentation](
|
34
|
+
To use Haml programmatically, check out the [YARD documentation](https://haml.info/docs/yardoc/).
|
35
35
|
|
36
36
|
## Using Haml with Rails
|
37
37
|
|
@@ -120,7 +120,7 @@ output the result. You can even use control statements like `if` and `while`:
|
|
120
120
|
~~~
|
121
121
|
|
122
122
|
Haml provides far more tools than those presented here. Check out the [reference
|
123
|
-
documentation](
|
123
|
+
documentation](https://haml.info/docs/yardoc/file.REFERENCE.html)
|
124
124
|
for full details.
|
125
125
|
|
126
126
|
### Indentation
|
@@ -132,7 +132,7 @@ can't be mixed, and the same number of tabs or spaces must be used throughout.
|
|
132
132
|
## Contributing
|
133
133
|
|
134
134
|
Contributions are welcomed, but before you get started please read the
|
135
|
-
[guidelines](
|
135
|
+
[guidelines](https://haml.info/development.html#contributing).
|
136
136
|
|
137
137
|
After forking and then cloning the repo locally, install Bundler and then use it
|
138
138
|
to install the development gem dependencies:
|
@@ -182,7 +182,7 @@ but still consults on language issues.
|
|
182
182
|
[Natalie Weizenbaum](http://nex-3.com) was for many years the primary developer
|
183
183
|
and architect of the "modern" Ruby implementation of Haml.
|
184
184
|
|
185
|
-
[Norman Clarke](
|
185
|
+
[Norman Clarke](https://github.com/norman) was the primary maintainer of Haml from 2012 to 2016.
|
186
186
|
|
187
187
|
## License
|
188
188
|
|
data/REFERENCE.md
CHANGED
@@ -1200,40 +1200,36 @@ You can also define your own filters.
|
|
1200
1200
|
|
1201
1201
|
The simplest example of a filter might be something like:
|
1202
1202
|
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
Haml::Filters.registered[:hello] ||= HelloFilter
|
1211
|
-
```
|
1203
|
+
class HelloFilter < Haml::Filters::Base
|
1204
|
+
def compile(_node)
|
1205
|
+
[:static, "hello world"]
|
1206
|
+
end
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
Haml::Filters.registered[:hello] ||= HelloFilter
|
1212
1210
|
|
1213
1211
|
A more complex example:
|
1214
1212
|
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1213
|
+
class BetterFilter < Haml::Filters::Base
|
1214
|
+
def compile(node)
|
1215
|
+
temple = [:multi]
|
1216
|
+
temple << [:static, "hello "]
|
1217
|
+
temple << compile_text(node.value[:text])
|
1218
|
+
temple << [:static, " world"]
|
1219
|
+
temple
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
private
|
1223
|
+
def compile_text(text)
|
1224
|
+
if ::Haml::Util.contains_interpolation?(text)
|
1225
|
+
[:dynamic, ::Haml::Util.unescape_interpolation(text)]
|
1226
|
+
else
|
1227
|
+
[:static, text]
|
1228
|
+
end
|
1229
|
+
end
|
1231
1230
|
end
|
1232
|
-
end
|
1233
|
-
end
|
1234
1231
|
|
1235
|
-
Haml::Filters.registered[:better] ||= BetterFilter
|
1236
|
-
```
|
1232
|
+
Haml::Filters.registered[:better] ||= BetterFilter
|
1237
1233
|
|
1238
1234
|
See {Haml::Filters} for examples.
|
1239
1235
|
|
data/Rakefile
CHANGED
@@ -1,39 +1,5 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
-
|
3
|
-
#
|
4
|
-
# Prepend DevKit into compilation phase
|
5
|
-
#
|
6
|
-
if Gem.win_platform?
|
7
|
-
desc 'Activates DevKit'
|
8
|
-
task :devkit do
|
9
|
-
begin
|
10
|
-
require 'devkit'
|
11
|
-
rescue LoadError
|
12
|
-
abort 'Failed to load DevKit required for compilation'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
task compile: :devkit
|
16
|
-
end
|
17
|
-
|
18
2
|
require 'rake/testtask'
|
19
|
-
if /java/ === RUBY_PLATFORM
|
20
|
-
# require 'rake/javaextensiontask'
|
21
|
-
# Rake::JavaExtensionTask.new(:haml) do |ext|
|
22
|
-
# ext.ext_dir = 'ext/java'
|
23
|
-
# ext.lib_dir = 'lib/haml'
|
24
|
-
# end
|
25
|
-
|
26
|
-
task :compile do
|
27
|
-
# dummy for now
|
28
|
-
end
|
29
|
-
else
|
30
|
-
require 'rake/extensiontask'
|
31
|
-
Rake::ExtensionTask.new(:haml) do |ext|
|
32
|
-
ext.lib_dir = 'lib/haml'
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
Dir['benchmark/*.rake'].each { |b| import(b) }
|
37
3
|
|
38
4
|
Rake::TestTask.new do |t|
|
39
5
|
t.libs << 'lib' << 'test'
|
@@ -42,10 +8,10 @@ Rake::TestTask.new do |t|
|
|
42
8
|
t.test_files = files
|
43
9
|
t.verbose = true
|
44
10
|
end
|
45
|
-
task test
|
11
|
+
task :test
|
46
12
|
|
47
13
|
desc 'bench task for CI'
|
48
|
-
task bench
|
14
|
+
task :bench do
|
49
15
|
if ENV['SLIM_BENCH'] == '1'
|
50
16
|
cmd = %w[bundle exec ruby benchmark/slim/run-benchmarks.rb]
|
51
17
|
else
|
@@ -79,4 +45,4 @@ task(:doc => 'doc:sass') {sh "yard"}
|
|
79
45
|
desc "Generate documentation incrementally"
|
80
46
|
task(:redoc) {sh "yard -c"}
|
81
47
|
|
82
|
-
task default:
|
48
|
+
task default: :test
|
data/haml.gemspec
CHANGED
@@ -21,12 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.metadata = { 'rubygems_mfa_required' => 'true' }
|
23
23
|
|
24
|
-
|
25
|
-
spec.platform = 'java'
|
26
|
-
else
|
27
|
-
spec.extensions = ['ext/haml/extconf.rb']
|
28
|
-
spec.required_ruby_version = '>= 2.1.0'
|
29
|
-
end
|
24
|
+
spec.required_ruby_version = '>= 2.1.0'
|
30
25
|
|
31
26
|
spec.add_dependency 'temple', '>= 0.8.2'
|
32
27
|
spec.add_dependency 'thor'
|
@@ -41,7 +36,6 @@ Gem::Specification.new do |spec|
|
|
41
36
|
spec.add_development_dependency 'minitest-reporters', '~> 1.1'
|
42
37
|
spec.add_development_dependency 'rails', '>= 4.0'
|
43
38
|
spec.add_development_dependency 'rake'
|
44
|
-
spec.add_development_dependency 'rake-compiler'
|
45
39
|
spec.add_development_dependency 'sass'
|
46
40
|
spec.add_development_dependency 'slim'
|
47
41
|
spec.add_development_dependency 'string_template'
|
@@ -9,166 +9,161 @@ module Haml::AttributeBuilder
|
|
9
9
|
itemscope allowfullscreen default inert sortable
|
10
10
|
truespeed typemustmatch download].freeze
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
12
|
+
class << self
|
13
|
+
def build(escape_attrs, quote, format, boolean_attributes, object_ref, *hashes)
|
14
|
+
hashes << Haml::ObjectRef.parse(object_ref) if object_ref
|
15
|
+
buf = []
|
16
|
+
hash = merge_all_attrs(hashes)
|
17
|
+
|
18
|
+
keys = hash.keys.sort!
|
19
|
+
keys.each do |key|
|
20
|
+
case key
|
21
|
+
when 'id'
|
22
|
+
buf << " id=#{quote}#{build_id(escape_attrs, *hash[key])}#{quote}"
|
23
|
+
when 'class'
|
24
|
+
buf << " class=#{quote}#{build_class(escape_attrs, *hash[key])}#{quote}"
|
25
|
+
when 'data'
|
26
|
+
buf << build_data(escape_attrs, quote, *hash[key])
|
27
|
+
when 'aria'
|
28
|
+
buf << build_aria(escape_attrs, quote, *hash[key])
|
29
|
+
when *boolean_attributes, /\Adata-/
|
30
|
+
build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
|
31
|
+
else
|
32
|
+
buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
|
34
33
|
end
|
35
|
-
buf.join
|
36
34
|
end
|
35
|
+
buf.join
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def build_id(escape_attrs, *values)
|
39
|
+
escape_html(escape_attrs, values.flatten.select { |v| v }.join('_'))
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
return escape_html(escape_attrs, value)
|
42
|
+
def build_class(escape_attrs, *values)
|
43
|
+
if values.size == 1
|
44
|
+
value = values.first
|
45
|
+
case
|
46
|
+
when value.is_a?(String)
|
47
|
+
# noop
|
48
|
+
when value.is_a?(Array)
|
49
|
+
value = value.flatten.select { |v| v }.map(&:to_s).uniq.join(' ')
|
50
|
+
when value
|
51
|
+
value = value.to_s
|
52
|
+
else
|
53
|
+
return ''
|
56
54
|
end
|
55
|
+
return escape_html(escape_attrs, value)
|
56
|
+
end
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
58
|
+
classes = []
|
59
|
+
values.each do |value|
|
60
|
+
case
|
61
|
+
when value.is_a?(String)
|
62
|
+
classes += value.split(' ')
|
63
|
+
when value.is_a?(Array)
|
64
|
+
classes += value.select { |v| v }
|
65
|
+
when value
|
66
|
+
classes << value.to_s
|
68
67
|
end
|
69
|
-
escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
|
70
68
|
end
|
69
|
+
escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
|
70
|
+
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
def build_data(escape_attrs, quote, *hashes)
|
73
|
+
build_data_attribute(:data, escape_attrs, quote, *hashes)
|
74
|
+
end
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
def build_aria(escape_attrs, quote, *hashes)
|
77
|
+
build_data_attribute(:aria, escape_attrs, quote, *hashes)
|
78
|
+
end
|
79
79
|
|
80
|
-
|
80
|
+
private
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
hash = flatten_attributes(key => data_value)
|
90
|
-
|
91
|
-
hash.sort_by(&:first).each do |key, value|
|
92
|
-
case value
|
93
|
-
when true
|
94
|
-
attrs << " #{key}"
|
95
|
-
when nil, false
|
96
|
-
# noop
|
97
|
-
else
|
98
|
-
attrs << " #{key}=#{quote}#{escape_html(escape_attrs, value.to_s)}#{quote}"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
attrs.join
|
82
|
+
def build_data_attribute(key, escape_attrs, quote, *hashes)
|
83
|
+
attrs = []
|
84
|
+
if hashes.size > 1 && hashes.all? { |h| h.is_a?(Hash) }
|
85
|
+
data_value = merge_all_attrs(hashes)
|
86
|
+
else
|
87
|
+
data_value = hashes.last
|
102
88
|
end
|
89
|
+
hash = flatten_attributes(key => data_value)
|
103
90
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
if k.nil?
|
113
|
-
flattened[key] = v
|
114
|
-
else
|
115
|
-
flattened["#{key}-#{k.to_s.gsub(/_/, '-')}"] = v
|
116
|
-
end
|
117
|
-
end
|
118
|
-
else
|
119
|
-
flattened[key] = value if value
|
120
|
-
end
|
91
|
+
hash.sort_by(&:first).each do |key, value|
|
92
|
+
case value
|
93
|
+
when true
|
94
|
+
attrs << " #{key}"
|
95
|
+
when nil, false
|
96
|
+
# noop
|
97
|
+
else
|
98
|
+
attrs << " #{key}=#{quote}#{escape_html(escape_attrs, value.to_s)}#{quote}"
|
121
99
|
end
|
122
|
-
flattened
|
123
100
|
end
|
101
|
+
attrs.join
|
102
|
+
end
|
103
|
+
|
104
|
+
def flatten_attributes(attributes)
|
105
|
+
flattened = {}
|
124
106
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
merged[key] ||= []
|
133
|
-
merged[key] << value
|
107
|
+
attributes.each do |key, value|
|
108
|
+
case value
|
109
|
+
when attributes
|
110
|
+
when Hash
|
111
|
+
flatten_attributes(value).each do |k, v|
|
112
|
+
if k.nil?
|
113
|
+
flattened[key] = v
|
134
114
|
else
|
135
|
-
|
115
|
+
flattened["#{key}-#{k.to_s.gsub(/_/, '-')}"] = v
|
136
116
|
end
|
137
117
|
end
|
118
|
+
else
|
119
|
+
flattened[key] = value if value
|
138
120
|
end
|
139
|
-
merged
|
140
121
|
end
|
122
|
+
flattened
|
123
|
+
end
|
141
124
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
125
|
+
def merge_all_attrs(hashes)
|
126
|
+
merged = {}
|
127
|
+
hashes.each do |hash|
|
128
|
+
unless hash.is_a?(Hash)
|
129
|
+
raise ArgumentError, "Non-hash object is given to attributes!"
|
130
|
+
end
|
131
|
+
hash.each do |key, value|
|
132
|
+
key = key.to_s
|
133
|
+
case key
|
134
|
+
when 'id', 'class', 'data', 'aria'
|
135
|
+
merged[key] ||= []
|
136
|
+
merged[key] << value
|
148
137
|
else
|
149
|
-
|
138
|
+
merged[key] = value
|
150
139
|
end
|
151
|
-
when false, nil
|
152
|
-
# omitted
|
153
|
-
else
|
154
|
-
buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
|
155
140
|
end
|
156
141
|
end
|
142
|
+
merged
|
143
|
+
end
|
157
144
|
|
158
|
-
|
159
|
-
|
160
|
-
|
145
|
+
def build_boolean!(escape_attrs, quote, format, buf, key, value)
|
146
|
+
case value
|
147
|
+
when true
|
148
|
+
case format
|
149
|
+
when :xhtml
|
150
|
+
buf << " #{key}=#{quote}#{key}#{quote}"
|
161
151
|
else
|
162
|
-
|
152
|
+
buf << " #{key}"
|
163
153
|
end
|
154
|
+
when false, nil
|
155
|
+
# omitted
|
156
|
+
else
|
157
|
+
buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def escape_html(escape_attrs, str)
|
162
|
+
if escape_attrs
|
163
|
+
Haml::Util.escape_html(str)
|
164
|
+
else
|
165
|
+
str
|
164
166
|
end
|
165
167
|
end
|
166
|
-
else
|
167
|
-
# Haml::AttributeBuilder.build
|
168
|
-
# Haml::AttributeBuilder.build_id
|
169
|
-
# Haml::AttributeBuilder.build_class
|
170
|
-
# Haml::AttributeBuilder.build_data
|
171
|
-
# Haml::AttributeBuilder.build_aria
|
172
|
-
require 'haml/haml'
|
173
168
|
end
|
174
169
|
end
|
data/lib/haml/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.1
|
4
|
+
version: 6.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Natalie Weizenbaum
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: exe
|
14
14
|
cert_chain: []
|
15
|
-
date: 2023-
|
15
|
+
date: 2023-10-04 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: temple
|
@@ -182,20 +182,6 @@ dependencies:
|
|
182
182
|
- - ">="
|
183
183
|
- !ruby/object:Gem::Version
|
184
184
|
version: '0'
|
185
|
-
- !ruby/object:Gem::Dependency
|
186
|
-
name: rake-compiler
|
187
|
-
requirement: !ruby/object:Gem::Requirement
|
188
|
-
requirements:
|
189
|
-
- - ">="
|
190
|
-
- !ruby/object:Gem::Version
|
191
|
-
version: '0'
|
192
|
-
type: :development
|
193
|
-
prerelease: false
|
194
|
-
version_requirements: !ruby/object:Gem::Requirement
|
195
|
-
requirements:
|
196
|
-
- - ">="
|
197
|
-
- !ruby/object:Gem::Version
|
198
|
-
version: '0'
|
199
185
|
- !ruby/object:Gem::Dependency
|
200
186
|
name: sass
|
201
187
|
requirement: !ruby/object:Gem::Requirement
|
@@ -258,8 +244,7 @@ email:
|
|
258
244
|
- ronnie@dio.jp
|
259
245
|
executables:
|
260
246
|
- haml
|
261
|
-
extensions:
|
262
|
-
- ext/haml/extconf.rb
|
247
|
+
extensions: []
|
263
248
|
extra_rdoc_files: []
|
264
249
|
files:
|
265
250
|
- ".github/FUNDING.yml"
|
@@ -280,10 +265,6 @@ files:
|
|
280
265
|
- bin/stackprof
|
281
266
|
- bin/test
|
282
267
|
- exe/haml
|
283
|
-
- ext/haml/extconf.rb
|
284
|
-
- ext/haml/haml.c
|
285
|
-
- ext/haml/hescape.c
|
286
|
-
- ext/haml/hescape.h
|
287
268
|
- haml.gemspec
|
288
269
|
- lib/haml.rb
|
289
270
|
- lib/haml/ambles.rb
|
data/ext/haml/extconf.rb
DELETED
data/ext/haml/haml.c
DELETED
@@ -1,529 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <ruby/encoding.h>
|
3
|
-
#ifndef TRUFFLERUBY
|
4
|
-
#include "hescape.h"
|
5
|
-
#include "string.h"
|
6
|
-
|
7
|
-
VALUE mAttributeBuilder, mObjectRef;
|
8
|
-
static ID id_flatten, id_keys, id_parse, id_prepend, id_tr, id_uniq_bang;
|
9
|
-
static ID id_xhtml;
|
10
|
-
|
11
|
-
static VALUE str_aria, str_data, str_equal, str_hyphen, str_space, str_underscore;
|
12
|
-
|
13
|
-
static void
|
14
|
-
delete_falsey_values(VALUE values)
|
15
|
-
{
|
16
|
-
VALUE value;
|
17
|
-
long i;
|
18
|
-
|
19
|
-
for (i = RARRAY_LEN(values) - 1; 0 <= i; i--) {
|
20
|
-
value = rb_ary_entry(values, i);
|
21
|
-
if (!RTEST(value)) {
|
22
|
-
rb_ary_delete_at(values, i);
|
23
|
-
}
|
24
|
-
}
|
25
|
-
}
|
26
|
-
|
27
|
-
static int
|
28
|
-
str_eq(VALUE str, const char *cstr, long n)
|
29
|
-
{
|
30
|
-
return RSTRING_LEN(str) == n && memcmp(RSTRING_PTR(str), cstr, n) == 0;
|
31
|
-
}
|
32
|
-
|
33
|
-
static VALUE
|
34
|
-
to_s(VALUE value)
|
35
|
-
{
|
36
|
-
return rb_convert_type(value, T_STRING, "String", "to_s");
|
37
|
-
}
|
38
|
-
|
39
|
-
static VALUE
|
40
|
-
hyphenate(VALUE str)
|
41
|
-
{
|
42
|
-
long i;
|
43
|
-
|
44
|
-
if (OBJ_FROZEN(str)) str = rb_str_dup(str);
|
45
|
-
|
46
|
-
for (i = 0; i < RSTRING_LEN(str); i++) {
|
47
|
-
if (RSTRING_PTR(str)[i] == '_') {
|
48
|
-
rb_str_update(str, i, 1, str_hyphen);
|
49
|
-
}
|
50
|
-
}
|
51
|
-
return str;
|
52
|
-
}
|
53
|
-
|
54
|
-
static VALUE
|
55
|
-
escape_html(VALUE str)
|
56
|
-
{
|
57
|
-
char *buf;
|
58
|
-
unsigned int size;
|
59
|
-
Check_Type(str, T_STRING);
|
60
|
-
|
61
|
-
size = hesc_escape_html(&buf, RSTRING_PTR(str), RSTRING_LEN(str));
|
62
|
-
if (size > RSTRING_LEN(str)) {
|
63
|
-
str = rb_enc_str_new(buf, size, rb_utf8_encoding());
|
64
|
-
free((void *)buf);
|
65
|
-
}
|
66
|
-
|
67
|
-
return str;
|
68
|
-
}
|
69
|
-
|
70
|
-
static VALUE
|
71
|
-
escape_attribute(VALUE escape_attrs, VALUE str)
|
72
|
-
{
|
73
|
-
if (RTEST(escape_attrs)) {
|
74
|
-
return escape_html(str);
|
75
|
-
} else {
|
76
|
-
return str;
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
static VALUE
|
81
|
-
haml_build_id(VALUE escape_attrs, VALUE values)
|
82
|
-
{
|
83
|
-
VALUE attr_value;
|
84
|
-
|
85
|
-
values = rb_funcall(values, id_flatten, 0);
|
86
|
-
delete_falsey_values(values);
|
87
|
-
|
88
|
-
attr_value = rb_ary_join(values, str_underscore);
|
89
|
-
return escape_attribute(escape_attrs, attr_value);
|
90
|
-
}
|
91
|
-
|
92
|
-
static VALUE
|
93
|
-
haml_build_single_class(VALUE escape_attrs, VALUE value)
|
94
|
-
{
|
95
|
-
switch (TYPE(value)) {
|
96
|
-
case T_STRING:
|
97
|
-
break;
|
98
|
-
case T_ARRAY:
|
99
|
-
value = rb_funcall(value, id_flatten, 0);
|
100
|
-
delete_falsey_values(value);
|
101
|
-
value = rb_ary_join(value, str_space);
|
102
|
-
break;
|
103
|
-
default:
|
104
|
-
if (RTEST(value)) {
|
105
|
-
value = to_s(value);
|
106
|
-
} else {
|
107
|
-
return rb_str_new_cstr("");
|
108
|
-
}
|
109
|
-
break;
|
110
|
-
}
|
111
|
-
return escape_attribute(escape_attrs, value);
|
112
|
-
}
|
113
|
-
|
114
|
-
static VALUE
|
115
|
-
haml_build_multi_class(VALUE escape_attrs, VALUE values)
|
116
|
-
{
|
117
|
-
long i, j;
|
118
|
-
VALUE value, buf;
|
119
|
-
|
120
|
-
buf = rb_ary_new2(RARRAY_LEN(values));
|
121
|
-
|
122
|
-
for (i = 0; i < RARRAY_LEN(values); i++) {
|
123
|
-
value = rb_ary_entry(values, i);
|
124
|
-
switch (TYPE(value)) {
|
125
|
-
case T_STRING:
|
126
|
-
rb_ary_concat(buf, rb_str_split(value, " "));
|
127
|
-
break;
|
128
|
-
case T_ARRAY:
|
129
|
-
value = rb_funcall(value, id_flatten, 0);
|
130
|
-
delete_falsey_values(value);
|
131
|
-
for (j = 0; j < RARRAY_LEN(value); j++) {
|
132
|
-
rb_ary_push(buf, to_s(rb_ary_entry(value, j)));
|
133
|
-
}
|
134
|
-
break;
|
135
|
-
default:
|
136
|
-
if (RTEST(value)) {
|
137
|
-
rb_ary_push(buf, to_s(value));
|
138
|
-
}
|
139
|
-
break;
|
140
|
-
}
|
141
|
-
}
|
142
|
-
|
143
|
-
rb_funcall(buf, id_uniq_bang, 0);
|
144
|
-
|
145
|
-
return escape_attribute(escape_attrs, rb_ary_join(buf, str_space));
|
146
|
-
}
|
147
|
-
|
148
|
-
static VALUE
|
149
|
-
haml_build_class(VALUE escape_attrs, VALUE array)
|
150
|
-
{
|
151
|
-
if (RARRAY_LEN(array) == 1) {
|
152
|
-
return haml_build_single_class(escape_attrs, rb_ary_entry(array, 0));
|
153
|
-
} else {
|
154
|
-
return haml_build_multi_class(escape_attrs, array);
|
155
|
-
}
|
156
|
-
}
|
157
|
-
|
158
|
-
struct merge_data_attrs_var {
|
159
|
-
VALUE merged;
|
160
|
-
VALUE key_str;
|
161
|
-
};
|
162
|
-
|
163
|
-
static int
|
164
|
-
merge_data_attrs_i(VALUE key, VALUE value, VALUE ptr)
|
165
|
-
{
|
166
|
-
struct merge_data_attrs_var *arg = (struct merge_data_attrs_var *)ptr;
|
167
|
-
VALUE merged = arg->merged;
|
168
|
-
VALUE key_str = arg->key_str;
|
169
|
-
|
170
|
-
if (NIL_P(key)) {
|
171
|
-
rb_hash_aset(merged, key_str, value);
|
172
|
-
} else {
|
173
|
-
key = rb_str_concat(rb_str_concat(rb_str_dup(key_str), rb_str_new_cstr("-")), to_s(key));
|
174
|
-
rb_hash_aset(merged, key, value);
|
175
|
-
}
|
176
|
-
return ST_CONTINUE;
|
177
|
-
}
|
178
|
-
|
179
|
-
static VALUE
|
180
|
-
merge_data_attrs(VALUE values, VALUE key_str)
|
181
|
-
{
|
182
|
-
long i;
|
183
|
-
VALUE value, merged = rb_hash_new();
|
184
|
-
|
185
|
-
for (i = 0; i < RARRAY_LEN(values); i++) {
|
186
|
-
struct merge_data_attrs_var arg;
|
187
|
-
arg.merged = merged;
|
188
|
-
arg.key_str = key_str;
|
189
|
-
|
190
|
-
value = rb_ary_entry(values, i);
|
191
|
-
switch (TYPE(value)) {
|
192
|
-
case T_HASH:
|
193
|
-
rb_hash_foreach(value, merge_data_attrs_i, (VALUE)&arg);
|
194
|
-
break;
|
195
|
-
default:
|
196
|
-
rb_hash_aset(merged, key_str, value);
|
197
|
-
break;
|
198
|
-
}
|
199
|
-
}
|
200
|
-
return merged;
|
201
|
-
}
|
202
|
-
|
203
|
-
struct flatten_data_attrs_i2_arg {
|
204
|
-
VALUE flattened;
|
205
|
-
VALUE key;
|
206
|
-
};
|
207
|
-
|
208
|
-
static int
|
209
|
-
flatten_data_attrs_i2(VALUE k, VALUE v, VALUE ptr)
|
210
|
-
{
|
211
|
-
VALUE key;
|
212
|
-
struct flatten_data_attrs_i2_arg *arg = (struct flatten_data_attrs_i2_arg *)ptr;
|
213
|
-
|
214
|
-
if (!RTEST(v)) return ST_CONTINUE;
|
215
|
-
|
216
|
-
if (k == Qnil) {
|
217
|
-
rb_hash_aset(arg->flattened, arg->key, v);
|
218
|
-
} else {
|
219
|
-
key = rb_str_dup(arg->key);
|
220
|
-
rb_str_cat(key, "-", 1);
|
221
|
-
rb_str_concat(key, to_s(k));
|
222
|
-
|
223
|
-
rb_hash_aset(arg->flattened, key, v);
|
224
|
-
}
|
225
|
-
return ST_CONTINUE;
|
226
|
-
}
|
227
|
-
|
228
|
-
static VALUE flatten_data_attrs(VALUE attrs);
|
229
|
-
|
230
|
-
static int
|
231
|
-
flatten_data_attrs_i(VALUE key, VALUE value, VALUE flattened)
|
232
|
-
{
|
233
|
-
struct flatten_data_attrs_i2_arg arg;
|
234
|
-
key = hyphenate(to_s(key));
|
235
|
-
|
236
|
-
switch (TYPE(value)) {
|
237
|
-
case T_HASH:
|
238
|
-
value = flatten_data_attrs(value);
|
239
|
-
arg.key = key;
|
240
|
-
arg.flattened = flattened;
|
241
|
-
rb_hash_foreach(value, flatten_data_attrs_i2, (VALUE)(&arg));
|
242
|
-
break;
|
243
|
-
default:
|
244
|
-
if (RTEST(value)) rb_hash_aset(flattened, key, value);
|
245
|
-
break;
|
246
|
-
}
|
247
|
-
return ST_CONTINUE;
|
248
|
-
}
|
249
|
-
|
250
|
-
static VALUE
|
251
|
-
flatten_data_attrs(VALUE attrs)
|
252
|
-
{
|
253
|
-
VALUE flattened = rb_hash_new();
|
254
|
-
rb_hash_foreach(attrs, flatten_data_attrs_i, flattened);
|
255
|
-
|
256
|
-
return flattened;
|
257
|
-
}
|
258
|
-
|
259
|
-
static VALUE
|
260
|
-
haml_build_data(VALUE escape_attrs, VALUE quote, VALUE values, VALUE key_str)
|
261
|
-
{
|
262
|
-
long i;
|
263
|
-
VALUE attrs, buf, keys, key, value;
|
264
|
-
|
265
|
-
attrs = merge_data_attrs(values, key_str);
|
266
|
-
attrs = flatten_data_attrs(attrs);
|
267
|
-
keys = rb_ary_sort_bang(rb_funcall(attrs, id_keys, 0));
|
268
|
-
buf = rb_str_new("", 0);
|
269
|
-
|
270
|
-
for (i = 0; i < RARRAY_LEN(keys); i++) {
|
271
|
-
key = rb_ary_entry(keys, i);
|
272
|
-
value = rb_hash_aref(attrs, key);
|
273
|
-
|
274
|
-
switch (value) {
|
275
|
-
case Qtrue:
|
276
|
-
rb_str_concat(buf, str_space);
|
277
|
-
rb_str_concat(buf, key);
|
278
|
-
break;
|
279
|
-
case Qnil:
|
280
|
-
break; // noop
|
281
|
-
case Qfalse:
|
282
|
-
break; // noop
|
283
|
-
default:
|
284
|
-
rb_str_concat(buf, str_space);
|
285
|
-
rb_str_concat(buf, key);
|
286
|
-
rb_str_concat(buf, str_equal);
|
287
|
-
rb_str_concat(buf, quote);
|
288
|
-
rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
|
289
|
-
rb_str_concat(buf, quote);
|
290
|
-
break;
|
291
|
-
}
|
292
|
-
}
|
293
|
-
|
294
|
-
return buf;
|
295
|
-
}
|
296
|
-
|
297
|
-
static VALUE
|
298
|
-
parse_object_ref(VALUE object_ref)
|
299
|
-
{
|
300
|
-
return rb_funcall(mObjectRef, id_parse, 1, object_ref);
|
301
|
-
}
|
302
|
-
|
303
|
-
static int
|
304
|
-
merge_all_attrs_i(VALUE key, VALUE value, VALUE merged)
|
305
|
-
{
|
306
|
-
VALUE array;
|
307
|
-
|
308
|
-
key = to_s(key);
|
309
|
-
if (str_eq(key, "id", 2) || str_eq(key, "class", 5) || str_eq(key, "data", 4) || str_eq(key, "aria", 4)) {
|
310
|
-
array = rb_hash_aref(merged, key);
|
311
|
-
if (NIL_P(array)) {
|
312
|
-
array = rb_ary_new2(1);
|
313
|
-
rb_hash_aset(merged, key, array);
|
314
|
-
}
|
315
|
-
rb_ary_push(array, value);
|
316
|
-
} else {
|
317
|
-
rb_hash_aset(merged, key, value);
|
318
|
-
}
|
319
|
-
return ST_CONTINUE;
|
320
|
-
}
|
321
|
-
|
322
|
-
static VALUE
|
323
|
-
merge_all_attrs(VALUE hashes)
|
324
|
-
{
|
325
|
-
long i;
|
326
|
-
VALUE hash, merged = rb_hash_new();
|
327
|
-
|
328
|
-
for (i = 0; i < RARRAY_LEN(hashes); i++) {
|
329
|
-
hash = rb_ary_entry(hashes, i);
|
330
|
-
if (!RB_TYPE_P(hash, T_HASH)) {
|
331
|
-
rb_raise(rb_eArgError, "Non-hash object is given to attributes!");
|
332
|
-
}
|
333
|
-
rb_hash_foreach(hash, merge_all_attrs_i, merged);
|
334
|
-
}
|
335
|
-
return merged;
|
336
|
-
}
|
337
|
-
|
338
|
-
int
|
339
|
-
is_boolean_attribute(VALUE key, VALUE boolean_attributes)
|
340
|
-
{
|
341
|
-
if (str_eq(rb_str_substr(key, 0, 5), "data-", 5)) return 1;
|
342
|
-
if (str_eq(rb_str_substr(key, 0, 5), "aria-", 5)) return 1;
|
343
|
-
return RTEST(rb_ary_includes(boolean_attributes, key));
|
344
|
-
}
|
345
|
-
|
346
|
-
void
|
347
|
-
haml_build_for_id(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
348
|
-
{
|
349
|
-
rb_str_cat(buf, " id=", 4);
|
350
|
-
rb_str_concat(buf, quote);
|
351
|
-
rb_str_concat(buf, haml_build_id(escape_attrs, values));
|
352
|
-
rb_str_concat(buf, quote);
|
353
|
-
}
|
354
|
-
|
355
|
-
void
|
356
|
-
haml_build_for_class(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
357
|
-
{
|
358
|
-
rb_str_cat(buf, " class=", 7);
|
359
|
-
rb_str_concat(buf, quote);
|
360
|
-
rb_str_concat(buf, haml_build_class(escape_attrs, values));
|
361
|
-
rb_str_concat(buf, quote);
|
362
|
-
}
|
363
|
-
|
364
|
-
void
|
365
|
-
haml_build_for_data(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
366
|
-
{
|
367
|
-
rb_str_concat(buf, haml_build_data(escape_attrs, quote, values, str_data));
|
368
|
-
}
|
369
|
-
|
370
|
-
void
|
371
|
-
haml_build_for_aria(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
372
|
-
{
|
373
|
-
rb_str_concat(buf, haml_build_data(escape_attrs, quote, values, str_aria));
|
374
|
-
}
|
375
|
-
|
376
|
-
void
|
377
|
-
haml_build_for_others(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE key, VALUE value)
|
378
|
-
{
|
379
|
-
rb_str_cat(buf, " ", 1);
|
380
|
-
rb_str_concat(buf, key);
|
381
|
-
rb_str_cat(buf, "=", 1);
|
382
|
-
rb_str_concat(buf, quote);
|
383
|
-
rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
|
384
|
-
rb_str_concat(buf, quote);
|
385
|
-
}
|
386
|
-
|
387
|
-
void
|
388
|
-
haml_build_for_boolean(VALUE escape_attrs, VALUE quote, VALUE format, VALUE buf, VALUE key, VALUE value)
|
389
|
-
{
|
390
|
-
switch (value) {
|
391
|
-
case Qtrue:
|
392
|
-
rb_str_cat(buf, " ", 1);
|
393
|
-
rb_str_concat(buf, key);
|
394
|
-
if ((TYPE(format) == T_SYMBOL || TYPE(format) == T_STRING) && rb_to_id(format) == id_xhtml) {
|
395
|
-
rb_str_cat(buf, "=", 1);
|
396
|
-
rb_str_concat(buf, quote);
|
397
|
-
rb_str_concat(buf, key);
|
398
|
-
rb_str_concat(buf, quote);
|
399
|
-
}
|
400
|
-
break;
|
401
|
-
case Qfalse:
|
402
|
-
break; // noop
|
403
|
-
case Qnil:
|
404
|
-
break; // noop
|
405
|
-
default:
|
406
|
-
haml_build_for_others(escape_attrs, quote, buf, key, value);
|
407
|
-
break;
|
408
|
-
}
|
409
|
-
}
|
410
|
-
|
411
|
-
static VALUE
|
412
|
-
haml_build(VALUE escape_attrs, VALUE quote, VALUE format, VALUE boolean_attributes, VALUE object_ref, VALUE hashes)
|
413
|
-
{
|
414
|
-
long i;
|
415
|
-
VALUE attrs, buf, key, keys, value;
|
416
|
-
|
417
|
-
if (!NIL_P(object_ref)) rb_ary_push(hashes, parse_object_ref(object_ref));
|
418
|
-
attrs = merge_all_attrs(hashes);
|
419
|
-
buf = rb_str_new("", 0);
|
420
|
-
keys = rb_ary_sort_bang(rb_funcall(attrs, id_keys, 0));
|
421
|
-
|
422
|
-
for (i = 0; i < RARRAY_LEN(keys); i++) {
|
423
|
-
key = rb_ary_entry(keys, i);
|
424
|
-
value = rb_hash_aref(attrs, key);
|
425
|
-
if (str_eq(key, "id", 2)) {
|
426
|
-
haml_build_for_id(escape_attrs, quote, buf, value);
|
427
|
-
} else if (str_eq(key, "class", 5)) {
|
428
|
-
haml_build_for_class(escape_attrs, quote, buf, value);
|
429
|
-
} else if (str_eq(key, "data", 4)) {
|
430
|
-
haml_build_for_data(escape_attrs, quote, buf, value);
|
431
|
-
} else if (str_eq(key, "aria", 4)) {
|
432
|
-
haml_build_for_aria(escape_attrs, quote, buf, value);
|
433
|
-
} else if (is_boolean_attribute(key, boolean_attributes)) {
|
434
|
-
haml_build_for_boolean(escape_attrs, quote, format, buf, key, value);
|
435
|
-
} else {
|
436
|
-
haml_build_for_others(escape_attrs, quote, buf, key, value);
|
437
|
-
}
|
438
|
-
}
|
439
|
-
|
440
|
-
return buf;
|
441
|
-
}
|
442
|
-
|
443
|
-
static VALUE
|
444
|
-
rb_haml_build_id(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
445
|
-
{
|
446
|
-
VALUE array;
|
447
|
-
|
448
|
-
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
449
|
-
rb_scan_args(argc - 1, argv + 1, "*", &array);
|
450
|
-
|
451
|
-
return haml_build_id(argv[0], array);
|
452
|
-
}
|
453
|
-
|
454
|
-
static VALUE
|
455
|
-
rb_haml_build_class(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
456
|
-
{
|
457
|
-
VALUE array;
|
458
|
-
|
459
|
-
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
460
|
-
rb_scan_args(argc - 1, argv + 1, "*", &array);
|
461
|
-
|
462
|
-
return haml_build_class(argv[0], array);
|
463
|
-
}
|
464
|
-
|
465
|
-
static VALUE
|
466
|
-
rb_haml_build_aria(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
467
|
-
{
|
468
|
-
VALUE array;
|
469
|
-
|
470
|
-
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
|
471
|
-
rb_scan_args(argc - 2, argv + 2, "*", &array);
|
472
|
-
|
473
|
-
return haml_build_data(argv[0], argv[1], array, str_aria);
|
474
|
-
}
|
475
|
-
|
476
|
-
static VALUE
|
477
|
-
rb_haml_build_data(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
478
|
-
{
|
479
|
-
VALUE array;
|
480
|
-
|
481
|
-
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
|
482
|
-
rb_scan_args(argc - 2, argv + 2, "*", &array);
|
483
|
-
|
484
|
-
return haml_build_data(argv[0], argv[1], array, str_data);
|
485
|
-
}
|
486
|
-
|
487
|
-
static VALUE
|
488
|
-
rb_haml_build(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
489
|
-
{
|
490
|
-
VALUE array;
|
491
|
-
|
492
|
-
rb_check_arity(argc, 5, UNLIMITED_ARGUMENTS);
|
493
|
-
rb_scan_args(argc - 5, argv + 5, "*", &array);
|
494
|
-
|
495
|
-
return haml_build(argv[0], argv[1], argv[2], argv[3], argv[4], array);
|
496
|
-
}
|
497
|
-
|
498
|
-
void
|
499
|
-
Init_haml(void)
|
500
|
-
{
|
501
|
-
VALUE mHaml;
|
502
|
-
|
503
|
-
mHaml = rb_define_module("Haml");
|
504
|
-
mObjectRef = rb_define_module_under(mHaml, "ObjectRef");
|
505
|
-
mAttributeBuilder = rb_define_module_under(mHaml, "AttributeBuilder");
|
506
|
-
|
507
|
-
rb_define_singleton_method(mAttributeBuilder, "build", rb_haml_build, -1);
|
508
|
-
rb_define_singleton_method(mAttributeBuilder, "build_id", rb_haml_build_id, -1);
|
509
|
-
rb_define_singleton_method(mAttributeBuilder, "build_class", rb_haml_build_class, -1);
|
510
|
-
rb_define_singleton_method(mAttributeBuilder, "build_aria", rb_haml_build_aria, -1);
|
511
|
-
rb_define_singleton_method(mAttributeBuilder, "build_data", rb_haml_build_data, -1);
|
512
|
-
|
513
|
-
id_flatten = rb_intern("flatten");
|
514
|
-
id_keys = rb_intern("keys");
|
515
|
-
id_parse = rb_intern("parse");
|
516
|
-
id_prepend = rb_intern("prepend");
|
517
|
-
id_tr = rb_intern("tr");
|
518
|
-
id_uniq_bang = rb_intern("uniq!");
|
519
|
-
id_xhtml = rb_intern("xhtml");
|
520
|
-
|
521
|
-
// Consider using rb_interned_str() once we stop supporting Ruby 2.7.
|
522
|
-
rb_gc_register_mark_object(str_aria = rb_obj_freeze(rb_str_new_cstr("aria")));
|
523
|
-
rb_gc_register_mark_object(str_data = rb_obj_freeze(rb_str_new_cstr("data")));
|
524
|
-
rb_gc_register_mark_object(str_equal = rb_obj_freeze(rb_str_new_cstr("=")));
|
525
|
-
rb_gc_register_mark_object(str_hyphen = rb_obj_freeze(rb_str_new_cstr("-")));
|
526
|
-
rb_gc_register_mark_object(str_space = rb_obj_freeze(rb_str_new_cstr(" ")));
|
527
|
-
rb_gc_register_mark_object(str_underscore = rb_obj_freeze(rb_str_new_cstr("_")));
|
528
|
-
}
|
529
|
-
#endif
|
data/ext/haml/hescape.c
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
#include <stdio.h>
|
2
|
-
#include <string.h>
|
3
|
-
#include <stdlib.h>
|
4
|
-
#include "hescape.h"
|
5
|
-
|
6
|
-
static const char *ESCAPED_STRING[] = {
|
7
|
-
"",
|
8
|
-
""",
|
9
|
-
"&",
|
10
|
-
"'",
|
11
|
-
"<",
|
12
|
-
">",
|
13
|
-
};
|
14
|
-
|
15
|
-
// This is strlen(ESCAPED_STRING[x]) optimized specially.
|
16
|
-
// Mapping: 1 => 6, 2 => 5, 3 => 5, 4 => 4, 5 => 4
|
17
|
-
#define ESC_LEN(x) ((13 - x) / 2)
|
18
|
-
|
19
|
-
/*
|
20
|
-
* Given ASCII-compatible character, return index of ESCAPED_STRING.
|
21
|
-
*
|
22
|
-
* " (34) => 1 (")
|
23
|
-
* & (38) => 2 (&)
|
24
|
-
* ' (39) => 3 (')
|
25
|
-
* < (60) => 4 (<)
|
26
|
-
* > (62) => 5 (>)
|
27
|
-
*/
|
28
|
-
static const char HTML_ESCAPE_TABLE[] = {
|
29
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
30
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
31
|
-
0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0,
|
32
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0,
|
33
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
34
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
35
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
36
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
37
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
38
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
39
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
40
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
41
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
42
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
43
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
44
|
-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
45
|
-
};
|
46
|
-
|
47
|
-
static char*
|
48
|
-
ensure_allocated(char *buf, size_t size, size_t *asize)
|
49
|
-
{
|
50
|
-
size_t new_size;
|
51
|
-
|
52
|
-
if (size < *asize)
|
53
|
-
return buf;
|
54
|
-
|
55
|
-
if (*asize == 0) {
|
56
|
-
new_size = size;
|
57
|
-
} else {
|
58
|
-
new_size = *asize;
|
59
|
-
}
|
60
|
-
|
61
|
-
// Increase buffer size by 1.5x if realloced multiple times.
|
62
|
-
while (new_size < size)
|
63
|
-
new_size = (new_size << 1) - (new_size >> 1);
|
64
|
-
|
65
|
-
// Round allocation up to multiple of 8.
|
66
|
-
new_size = (new_size + 7) & ~7;
|
67
|
-
|
68
|
-
*asize = new_size;
|
69
|
-
return realloc(buf, new_size);
|
70
|
-
}
|
71
|
-
|
72
|
-
size_t
|
73
|
-
hesc_escape_html(char **dest, const char *buf, size_t size)
|
74
|
-
{
|
75
|
-
size_t asize = 0, esc_i = 0, esize = 0, i = 0, rbuf_end = 0;
|
76
|
-
const char *esc;
|
77
|
-
char *rbuf = NULL;
|
78
|
-
|
79
|
-
while (i < size) {
|
80
|
-
// Loop here to skip non-escaped characters fast.
|
81
|
-
while (i < size && (esc_i = HTML_ESCAPE_TABLE[(unsigned char)buf[i]]) == 0)
|
82
|
-
i++;
|
83
|
-
|
84
|
-
if (i < size && esc_i) {
|
85
|
-
esc = ESCAPED_STRING[esc_i];
|
86
|
-
rbuf = ensure_allocated(rbuf, sizeof(char) * (size + esize + ESC_LEN(esc_i) + 1), &asize);
|
87
|
-
|
88
|
-
// Copy pending characters and escaped string.
|
89
|
-
memmove(rbuf + rbuf_end, buf + (rbuf_end - esize), i - (rbuf_end - esize));
|
90
|
-
memmove(rbuf + i + esize, esc, ESC_LEN(esc_i));
|
91
|
-
rbuf_end = i + esize + ESC_LEN(esc_i);
|
92
|
-
esize += ESC_LEN(esc_i) - 1;
|
93
|
-
}
|
94
|
-
i++;
|
95
|
-
}
|
96
|
-
|
97
|
-
if (rbuf_end == 0) {
|
98
|
-
// Return given buf and size if there are no escaped characters.
|
99
|
-
*dest = (char *)buf;
|
100
|
-
return size;
|
101
|
-
} else {
|
102
|
-
// Copy pending characters including NULL character.
|
103
|
-
memmove(rbuf + rbuf_end, buf + (rbuf_end - esize), (size + 1) - (rbuf_end - esize));
|
104
|
-
|
105
|
-
*dest = rbuf;
|
106
|
-
return size + esize;
|
107
|
-
}
|
108
|
-
}
|
data/ext/haml/hescape.h
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
#ifndef HESCAPE_H
|
2
|
-
#define HESCAPE_H
|
3
|
-
|
4
|
-
#include <sys/types.h>
|
5
|
-
|
6
|
-
/*
|
7
|
-
* Replace characters according to the following rules.
|
8
|
-
* Note that this function can handle only ASCII-compatible string.
|
9
|
-
*
|
10
|
-
* " => "
|
11
|
-
* & => &
|
12
|
-
* ' => '
|
13
|
-
* < => <
|
14
|
-
* > => >
|
15
|
-
*
|
16
|
-
* @return size of dest. If it's larger than len, dest is required to be freed.
|
17
|
-
*/
|
18
|
-
extern size_t hesc_escape_html(char **dest, const char *src, size_t size);
|
19
|
-
|
20
|
-
#endif
|