haml 6.1.3 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Rakefile +3 -37
- data/haml.gemspec +1 -7
- data/lib/haml/attribute_builder.rb +122 -129
- data/lib/haml/util.rb +5 -4
- data/lib/haml/version.rb +1 -1
- metadata +3 -22
- data/ext/haml/extconf.rb +0 -10
- data/ext/haml/haml.c +0 -537
- 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: c1374065239926b78aa88c8a9669a4a97ea937ba078f4794be6d3d34c072472e
|
4
|
+
data.tar.gz: a99b6d11b903d2d9985e6e89d857b24c4ca5c31efe2a0c09d29cfea7b58a2057
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '05423907d445d38fbba24d1b08f6812b43a8bca544554b5ecc1d1190e87842cedf888cd4759f6d568cb861a0f6983e06610d57daa2233feafb0e29cce92c71b1'
|
7
|
+
data.tar.gz: e88712e3391749f5c893512eb595c912718476a7128773b4edd4aa19b191837ff3d6d154a18a0c8a42a107d6c04ce4ee6cd3189d6270210d9b4b5ded33def0dc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Haml Changelog
|
2
2
|
|
3
|
+
## 6.2.0
|
4
|
+
|
5
|
+
* Drop the C extension [#1146](https://github.com/haml/haml/issues/1146)
|
6
|
+
|
7
|
+
## 6.1.4
|
8
|
+
|
9
|
+
* Let `Haml::Util.escape_html` use `ERB::Escape` if available [#1145](https://github.com/haml/haml/issues/1145)
|
10
|
+
|
3
11
|
## 6.1.3
|
4
12
|
|
5
13
|
* Add `Haml::RailsTemplate#default_format` for Turbo compatibility [#1144](https://github.com/haml/haml/issues/1144)
|
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,159 @@ 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
|
-
else
|
32
|
-
buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
|
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'.freeze
|
22
|
+
buf << " id=#{quote}#{build_id(escape_attrs, *hash[key])}#{quote}"
|
23
|
+
when 'class'.freeze
|
24
|
+
buf << " class=#{quote}#{build_class(escape_attrs, *hash[key])}#{quote}"
|
25
|
+
when 'data'.freeze
|
26
|
+
buf << build_data(escape_attrs, quote, *hash[key])
|
27
|
+
when *boolean_attributes, /\Adata-/
|
28
|
+
build_boolean!(escape_attrs, quote, format, buf, key, hash[key])
|
29
|
+
else
|
30
|
+
buf << " #{key}=#{quote}#{escape_html(escape_attrs, hash[key].to_s)}#{quote}"
|
34
31
|
end
|
35
|
-
buf.join
|
36
32
|
end
|
33
|
+
buf.join
|
34
|
+
end
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
def build_id(escape_attrs, *values)
|
37
|
+
escape_html(escape_attrs, values.flatten.select { |v| v }.join('_'))
|
38
|
+
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
return escape_html(escape_attrs, value)
|
40
|
+
def build_class(escape_attrs, *values)
|
41
|
+
if values.size == 1
|
42
|
+
value = values.first
|
43
|
+
case
|
44
|
+
when value.is_a?(String)
|
45
|
+
# noop
|
46
|
+
when value.is_a?(Array)
|
47
|
+
value = value.flatten.select { |v| v }.map(&:to_s).uniq.join(' ')
|
48
|
+
when value
|
49
|
+
value = value.to_s
|
50
|
+
else
|
51
|
+
return ''
|
56
52
|
end
|
53
|
+
return escape_html(escape_attrs, value)
|
54
|
+
end
|
57
55
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
56
|
+
classes = []
|
57
|
+
values.each do |value|
|
58
|
+
case
|
59
|
+
when value.is_a?(String)
|
60
|
+
classes += value.split(' ')
|
61
|
+
when value.is_a?(Array)
|
62
|
+
classes += value.select { |v| v }
|
63
|
+
when value
|
64
|
+
classes << value.to_s
|
68
65
|
end
|
69
|
-
escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
|
70
66
|
end
|
67
|
+
escape_html(escape_attrs, classes.map(&:to_s).uniq.join(' '))
|
68
|
+
end
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
def build_data(escape_attrs, quote, *hashes)
|
71
|
+
build_data_attribute(:data, escape_attrs, quote, *hashes)
|
72
|
+
end
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
def build_aria(escape_attrs, quote, *hashes)
|
75
|
+
build_data_attribute(:aria, escape_attrs, quote, *hashes)
|
76
|
+
end
|
79
77
|
|
80
|
-
|
78
|
+
private
|
81
79
|
|
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
|
80
|
+
def build_data_attribute(key, escape_attrs, quote, *hashes)
|
81
|
+
attrs = []
|
82
|
+
if hashes.size > 1 && hashes.all? { |h| h.is_a?(Hash) }
|
83
|
+
data_value = merge_all_attrs(hashes)
|
84
|
+
else
|
85
|
+
data_value = hashes.last
|
102
86
|
end
|
87
|
+
hash = flatten_attributes(key => data_value)
|
103
88
|
|
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
|
89
|
+
hash.sort_by(&:first).each do |key, value|
|
90
|
+
case value
|
91
|
+
when true
|
92
|
+
attrs << " #{key}"
|
93
|
+
when nil, false
|
94
|
+
# noop
|
95
|
+
else
|
96
|
+
attrs << " #{key}=#{quote}#{escape_html(escape_attrs, value.to_s)}#{quote}"
|
121
97
|
end
|
122
|
-
flattened
|
123
98
|
end
|
99
|
+
attrs.join
|
100
|
+
end
|
101
|
+
|
102
|
+
def flatten_attributes(attributes)
|
103
|
+
flattened = {}
|
124
104
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
merged[key] ||= []
|
133
|
-
merged[key] << value
|
105
|
+
attributes.each do |key, value|
|
106
|
+
case value
|
107
|
+
when attributes
|
108
|
+
when Hash
|
109
|
+
flatten_attributes(value).each do |k, v|
|
110
|
+
if k.nil?
|
111
|
+
flattened[key] = v
|
134
112
|
else
|
135
|
-
|
113
|
+
flattened["#{key}-#{k.to_s.gsub(/_/, '-')}"] = v
|
136
114
|
end
|
137
115
|
end
|
116
|
+
else
|
117
|
+
flattened[key] = value if value
|
138
118
|
end
|
139
|
-
merged
|
140
119
|
end
|
120
|
+
flattened
|
121
|
+
end
|
141
122
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
123
|
+
def merge_all_attrs(hashes)
|
124
|
+
merged = {}
|
125
|
+
hashes.each do |hash|
|
126
|
+
unless hash.is_a?(Hash)
|
127
|
+
raise ArgumentError, "Non-hash object is given to attributes!"
|
128
|
+
end
|
129
|
+
hash.each do |key, value|
|
130
|
+
key = key.to_s
|
131
|
+
case key
|
132
|
+
when 'id'.freeze, 'class'.freeze, 'data'.freeze
|
133
|
+
merged[key] ||= []
|
134
|
+
merged[key] << value
|
148
135
|
else
|
149
|
-
|
136
|
+
merged[key] = value
|
150
137
|
end
|
151
|
-
when false, nil
|
152
|
-
# omitted
|
153
|
-
else
|
154
|
-
buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
|
155
138
|
end
|
156
139
|
end
|
140
|
+
merged
|
141
|
+
end
|
157
142
|
|
158
|
-
|
159
|
-
|
160
|
-
|
143
|
+
def build_boolean!(escape_attrs, quote, format, buf, key, value)
|
144
|
+
case value
|
145
|
+
when true
|
146
|
+
case format
|
147
|
+
when :xhtml
|
148
|
+
buf << " #{key}=#{quote}#{key}#{quote}"
|
161
149
|
else
|
162
|
-
|
150
|
+
buf << " #{key}"
|
163
151
|
end
|
152
|
+
when false, nil
|
153
|
+
# omitted
|
154
|
+
else
|
155
|
+
buf << " #{key}=#{quote}#{escape_html(escape_attrs, value)}#{quote}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def escape_html(escape_attrs, str)
|
160
|
+
if escape_attrs
|
161
|
+
Haml::Util.escape_html(str)
|
162
|
+
else
|
163
|
+
str
|
164
164
|
end
|
165
165
|
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
166
|
end
|
174
167
|
end
|
data/lib/haml/util.rb
CHANGED
@@ -14,15 +14,16 @@ module Haml
|
|
14
14
|
module Util
|
15
15
|
extend self
|
16
16
|
|
17
|
-
#
|
18
|
-
|
17
|
+
begin # Ruby 3.2+ or ERB 4+
|
18
|
+
require 'erb/escape'
|
19
|
+
|
20
|
+
define_singleton_method(:escape_html, ERB::Escape.instance_method(:html_escape))
|
21
|
+
rescue LoadError
|
19
22
|
require 'cgi/escape'
|
20
23
|
|
21
24
|
def self.escape_html(html)
|
22
25
|
CGI.escapeHTML(html.to_s)
|
23
26
|
end
|
24
|
-
else
|
25
|
-
require 'haml/haml' # Haml::Util.escape_html
|
26
27
|
end
|
27
28
|
|
28
29
|
# TODO: Remove unescape_interpolation's workaround and get rid of `respond_to?`.
|
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.
|
4
|
+
version: 6.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Natalie Weizenbaum
|
@@ -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
|
@@ -356,7 +337,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
356
337
|
- !ruby/object:Gem::Version
|
357
338
|
version: '0'
|
358
339
|
requirements: []
|
359
|
-
rubygems_version: 3.4.
|
340
|
+
rubygems_version: 3.4.10
|
360
341
|
signing_key:
|
361
342
|
specification_version: 4
|
362
343
|
summary: An elegant, structured (X)HTML/XML templating engine.
|
data/ext/haml/extconf.rb
DELETED
data/ext/haml/haml.c
DELETED
@@ -1,537 +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
|
-
rb_escape_html(RB_UNUSED_VAR(VALUE self), VALUE value)
|
82
|
-
{
|
83
|
-
return escape_html(to_s(value));
|
84
|
-
}
|
85
|
-
|
86
|
-
static VALUE
|
87
|
-
haml_build_id(VALUE escape_attrs, VALUE values)
|
88
|
-
{
|
89
|
-
VALUE attr_value;
|
90
|
-
|
91
|
-
values = rb_funcall(values, id_flatten, 0);
|
92
|
-
delete_falsey_values(values);
|
93
|
-
|
94
|
-
attr_value = rb_ary_join(values, str_underscore);
|
95
|
-
return escape_attribute(escape_attrs, attr_value);
|
96
|
-
}
|
97
|
-
|
98
|
-
static VALUE
|
99
|
-
haml_build_single_class(VALUE escape_attrs, VALUE value)
|
100
|
-
{
|
101
|
-
switch (TYPE(value)) {
|
102
|
-
case T_STRING:
|
103
|
-
break;
|
104
|
-
case T_ARRAY:
|
105
|
-
value = rb_funcall(value, id_flatten, 0);
|
106
|
-
delete_falsey_values(value);
|
107
|
-
value = rb_ary_join(value, str_space);
|
108
|
-
break;
|
109
|
-
default:
|
110
|
-
if (RTEST(value)) {
|
111
|
-
value = to_s(value);
|
112
|
-
} else {
|
113
|
-
return rb_str_new_cstr("");
|
114
|
-
}
|
115
|
-
break;
|
116
|
-
}
|
117
|
-
return escape_attribute(escape_attrs, value);
|
118
|
-
}
|
119
|
-
|
120
|
-
static VALUE
|
121
|
-
haml_build_multi_class(VALUE escape_attrs, VALUE values)
|
122
|
-
{
|
123
|
-
long i, j;
|
124
|
-
VALUE value, buf;
|
125
|
-
|
126
|
-
buf = rb_ary_new2(RARRAY_LEN(values));
|
127
|
-
|
128
|
-
for (i = 0; i < RARRAY_LEN(values); i++) {
|
129
|
-
value = rb_ary_entry(values, i);
|
130
|
-
switch (TYPE(value)) {
|
131
|
-
case T_STRING:
|
132
|
-
rb_ary_concat(buf, rb_str_split(value, " "));
|
133
|
-
break;
|
134
|
-
case T_ARRAY:
|
135
|
-
value = rb_funcall(value, id_flatten, 0);
|
136
|
-
delete_falsey_values(value);
|
137
|
-
for (j = 0; j < RARRAY_LEN(value); j++) {
|
138
|
-
rb_ary_push(buf, to_s(rb_ary_entry(value, j)));
|
139
|
-
}
|
140
|
-
break;
|
141
|
-
default:
|
142
|
-
if (RTEST(value)) {
|
143
|
-
rb_ary_push(buf, to_s(value));
|
144
|
-
}
|
145
|
-
break;
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
|
-
rb_funcall(buf, id_uniq_bang, 0);
|
150
|
-
|
151
|
-
return escape_attribute(escape_attrs, rb_ary_join(buf, str_space));
|
152
|
-
}
|
153
|
-
|
154
|
-
static VALUE
|
155
|
-
haml_build_class(VALUE escape_attrs, VALUE array)
|
156
|
-
{
|
157
|
-
if (RARRAY_LEN(array) == 1) {
|
158
|
-
return haml_build_single_class(escape_attrs, rb_ary_entry(array, 0));
|
159
|
-
} else {
|
160
|
-
return haml_build_multi_class(escape_attrs, array);
|
161
|
-
}
|
162
|
-
}
|
163
|
-
|
164
|
-
struct merge_data_attrs_var {
|
165
|
-
VALUE merged;
|
166
|
-
VALUE key_str;
|
167
|
-
};
|
168
|
-
|
169
|
-
static int
|
170
|
-
merge_data_attrs_i(VALUE key, VALUE value, VALUE ptr)
|
171
|
-
{
|
172
|
-
struct merge_data_attrs_var *arg = (struct merge_data_attrs_var *)ptr;
|
173
|
-
VALUE merged = arg->merged;
|
174
|
-
VALUE key_str = arg->key_str;
|
175
|
-
|
176
|
-
if (NIL_P(key)) {
|
177
|
-
rb_hash_aset(merged, key_str, value);
|
178
|
-
} else {
|
179
|
-
key = rb_str_concat(rb_str_concat(rb_str_dup(key_str), rb_str_new_cstr("-")), to_s(key));
|
180
|
-
rb_hash_aset(merged, key, value);
|
181
|
-
}
|
182
|
-
return ST_CONTINUE;
|
183
|
-
}
|
184
|
-
|
185
|
-
static VALUE
|
186
|
-
merge_data_attrs(VALUE values, VALUE key_str)
|
187
|
-
{
|
188
|
-
long i;
|
189
|
-
VALUE value, merged = rb_hash_new();
|
190
|
-
|
191
|
-
for (i = 0; i < RARRAY_LEN(values); i++) {
|
192
|
-
struct merge_data_attrs_var arg;
|
193
|
-
arg.merged = merged;
|
194
|
-
arg.key_str = key_str;
|
195
|
-
|
196
|
-
value = rb_ary_entry(values, i);
|
197
|
-
switch (TYPE(value)) {
|
198
|
-
case T_HASH:
|
199
|
-
rb_hash_foreach(value, merge_data_attrs_i, (VALUE)&arg);
|
200
|
-
break;
|
201
|
-
default:
|
202
|
-
rb_hash_aset(merged, key_str, value);
|
203
|
-
break;
|
204
|
-
}
|
205
|
-
}
|
206
|
-
return merged;
|
207
|
-
}
|
208
|
-
|
209
|
-
struct flatten_data_attrs_i2_arg {
|
210
|
-
VALUE flattened;
|
211
|
-
VALUE key;
|
212
|
-
};
|
213
|
-
|
214
|
-
static int
|
215
|
-
flatten_data_attrs_i2(VALUE k, VALUE v, VALUE ptr)
|
216
|
-
{
|
217
|
-
VALUE key;
|
218
|
-
struct flatten_data_attrs_i2_arg *arg = (struct flatten_data_attrs_i2_arg *)ptr;
|
219
|
-
|
220
|
-
if (!RTEST(v)) return ST_CONTINUE;
|
221
|
-
|
222
|
-
if (k == Qnil) {
|
223
|
-
rb_hash_aset(arg->flattened, arg->key, v);
|
224
|
-
} else {
|
225
|
-
key = rb_str_dup(arg->key);
|
226
|
-
rb_str_cat(key, "-", 1);
|
227
|
-
rb_str_concat(key, to_s(k));
|
228
|
-
|
229
|
-
rb_hash_aset(arg->flattened, key, v);
|
230
|
-
}
|
231
|
-
return ST_CONTINUE;
|
232
|
-
}
|
233
|
-
|
234
|
-
static VALUE flatten_data_attrs(VALUE attrs);
|
235
|
-
|
236
|
-
static int
|
237
|
-
flatten_data_attrs_i(VALUE key, VALUE value, VALUE flattened)
|
238
|
-
{
|
239
|
-
struct flatten_data_attrs_i2_arg arg;
|
240
|
-
key = hyphenate(to_s(key));
|
241
|
-
|
242
|
-
switch (TYPE(value)) {
|
243
|
-
case T_HASH:
|
244
|
-
value = flatten_data_attrs(value);
|
245
|
-
arg.key = key;
|
246
|
-
arg.flattened = flattened;
|
247
|
-
rb_hash_foreach(value, flatten_data_attrs_i2, (VALUE)(&arg));
|
248
|
-
break;
|
249
|
-
default:
|
250
|
-
if (RTEST(value)) rb_hash_aset(flattened, key, value);
|
251
|
-
break;
|
252
|
-
}
|
253
|
-
return ST_CONTINUE;
|
254
|
-
}
|
255
|
-
|
256
|
-
static VALUE
|
257
|
-
flatten_data_attrs(VALUE attrs)
|
258
|
-
{
|
259
|
-
VALUE flattened = rb_hash_new();
|
260
|
-
rb_hash_foreach(attrs, flatten_data_attrs_i, flattened);
|
261
|
-
|
262
|
-
return flattened;
|
263
|
-
}
|
264
|
-
|
265
|
-
static VALUE
|
266
|
-
haml_build_data(VALUE escape_attrs, VALUE quote, VALUE values, VALUE key_str)
|
267
|
-
{
|
268
|
-
long i;
|
269
|
-
VALUE attrs, buf, keys, key, value;
|
270
|
-
|
271
|
-
attrs = merge_data_attrs(values, key_str);
|
272
|
-
attrs = flatten_data_attrs(attrs);
|
273
|
-
keys = rb_ary_sort_bang(rb_funcall(attrs, id_keys, 0));
|
274
|
-
buf = rb_str_new("", 0);
|
275
|
-
|
276
|
-
for (i = 0; i < RARRAY_LEN(keys); i++) {
|
277
|
-
key = rb_ary_entry(keys, i);
|
278
|
-
value = rb_hash_aref(attrs, key);
|
279
|
-
|
280
|
-
switch (value) {
|
281
|
-
case Qtrue:
|
282
|
-
rb_str_concat(buf, str_space);
|
283
|
-
rb_str_concat(buf, key);
|
284
|
-
break;
|
285
|
-
case Qnil:
|
286
|
-
break; // noop
|
287
|
-
case Qfalse:
|
288
|
-
break; // noop
|
289
|
-
default:
|
290
|
-
rb_str_concat(buf, str_space);
|
291
|
-
rb_str_concat(buf, key);
|
292
|
-
rb_str_concat(buf, str_equal);
|
293
|
-
rb_str_concat(buf, quote);
|
294
|
-
rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
|
295
|
-
rb_str_concat(buf, quote);
|
296
|
-
break;
|
297
|
-
}
|
298
|
-
}
|
299
|
-
|
300
|
-
return buf;
|
301
|
-
}
|
302
|
-
|
303
|
-
static VALUE
|
304
|
-
parse_object_ref(VALUE object_ref)
|
305
|
-
{
|
306
|
-
return rb_funcall(mObjectRef, id_parse, 1, object_ref);
|
307
|
-
}
|
308
|
-
|
309
|
-
static int
|
310
|
-
merge_all_attrs_i(VALUE key, VALUE value, VALUE merged)
|
311
|
-
{
|
312
|
-
VALUE array;
|
313
|
-
|
314
|
-
key = to_s(key);
|
315
|
-
if (str_eq(key, "id", 2) || str_eq(key, "class", 5) || str_eq(key, "data", 4) || str_eq(key, "aria", 4)) {
|
316
|
-
array = rb_hash_aref(merged, key);
|
317
|
-
if (NIL_P(array)) {
|
318
|
-
array = rb_ary_new2(1);
|
319
|
-
rb_hash_aset(merged, key, array);
|
320
|
-
}
|
321
|
-
rb_ary_push(array, value);
|
322
|
-
} else {
|
323
|
-
rb_hash_aset(merged, key, value);
|
324
|
-
}
|
325
|
-
return ST_CONTINUE;
|
326
|
-
}
|
327
|
-
|
328
|
-
static VALUE
|
329
|
-
merge_all_attrs(VALUE hashes)
|
330
|
-
{
|
331
|
-
long i;
|
332
|
-
VALUE hash, merged = rb_hash_new();
|
333
|
-
|
334
|
-
for (i = 0; i < RARRAY_LEN(hashes); i++) {
|
335
|
-
hash = rb_ary_entry(hashes, i);
|
336
|
-
if (!RB_TYPE_P(hash, T_HASH)) {
|
337
|
-
rb_raise(rb_eArgError, "Non-hash object is given to attributes!");
|
338
|
-
}
|
339
|
-
rb_hash_foreach(hash, merge_all_attrs_i, merged);
|
340
|
-
}
|
341
|
-
return merged;
|
342
|
-
}
|
343
|
-
|
344
|
-
int
|
345
|
-
is_boolean_attribute(VALUE key, VALUE boolean_attributes)
|
346
|
-
{
|
347
|
-
if (str_eq(rb_str_substr(key, 0, 5), "data-", 5)) return 1;
|
348
|
-
if (str_eq(rb_str_substr(key, 0, 5), "aria-", 5)) return 1;
|
349
|
-
return RTEST(rb_ary_includes(boolean_attributes, key));
|
350
|
-
}
|
351
|
-
|
352
|
-
void
|
353
|
-
haml_build_for_id(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
354
|
-
{
|
355
|
-
rb_str_cat(buf, " id=", 4);
|
356
|
-
rb_str_concat(buf, quote);
|
357
|
-
rb_str_concat(buf, haml_build_id(escape_attrs, values));
|
358
|
-
rb_str_concat(buf, quote);
|
359
|
-
}
|
360
|
-
|
361
|
-
void
|
362
|
-
haml_build_for_class(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
363
|
-
{
|
364
|
-
rb_str_cat(buf, " class=", 7);
|
365
|
-
rb_str_concat(buf, quote);
|
366
|
-
rb_str_concat(buf, haml_build_class(escape_attrs, values));
|
367
|
-
rb_str_concat(buf, quote);
|
368
|
-
}
|
369
|
-
|
370
|
-
void
|
371
|
-
haml_build_for_data(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
372
|
-
{
|
373
|
-
rb_str_concat(buf, haml_build_data(escape_attrs, quote, values, str_data));
|
374
|
-
}
|
375
|
-
|
376
|
-
void
|
377
|
-
haml_build_for_aria(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE values)
|
378
|
-
{
|
379
|
-
rb_str_concat(buf, haml_build_data(escape_attrs, quote, values, str_aria));
|
380
|
-
}
|
381
|
-
|
382
|
-
void
|
383
|
-
haml_build_for_others(VALUE escape_attrs, VALUE quote, VALUE buf, VALUE key, VALUE value)
|
384
|
-
{
|
385
|
-
rb_str_cat(buf, " ", 1);
|
386
|
-
rb_str_concat(buf, key);
|
387
|
-
rb_str_cat(buf, "=", 1);
|
388
|
-
rb_str_concat(buf, quote);
|
389
|
-
rb_str_concat(buf, escape_attribute(escape_attrs, to_s(value)));
|
390
|
-
rb_str_concat(buf, quote);
|
391
|
-
}
|
392
|
-
|
393
|
-
void
|
394
|
-
haml_build_for_boolean(VALUE escape_attrs, VALUE quote, VALUE format, VALUE buf, VALUE key, VALUE value)
|
395
|
-
{
|
396
|
-
switch (value) {
|
397
|
-
case Qtrue:
|
398
|
-
rb_str_cat(buf, " ", 1);
|
399
|
-
rb_str_concat(buf, key);
|
400
|
-
if ((TYPE(format) == T_SYMBOL || TYPE(format) == T_STRING) && rb_to_id(format) == id_xhtml) {
|
401
|
-
rb_str_cat(buf, "=", 1);
|
402
|
-
rb_str_concat(buf, quote);
|
403
|
-
rb_str_concat(buf, key);
|
404
|
-
rb_str_concat(buf, quote);
|
405
|
-
}
|
406
|
-
break;
|
407
|
-
case Qfalse:
|
408
|
-
break; // noop
|
409
|
-
case Qnil:
|
410
|
-
break; // noop
|
411
|
-
default:
|
412
|
-
haml_build_for_others(escape_attrs, quote, buf, key, value);
|
413
|
-
break;
|
414
|
-
}
|
415
|
-
}
|
416
|
-
|
417
|
-
static VALUE
|
418
|
-
haml_build(VALUE escape_attrs, VALUE quote, VALUE format, VALUE boolean_attributes, VALUE object_ref, VALUE hashes)
|
419
|
-
{
|
420
|
-
long i;
|
421
|
-
VALUE attrs, buf, key, keys, value;
|
422
|
-
|
423
|
-
if (!NIL_P(object_ref)) rb_ary_push(hashes, parse_object_ref(object_ref));
|
424
|
-
attrs = merge_all_attrs(hashes);
|
425
|
-
buf = rb_str_new("", 0);
|
426
|
-
keys = rb_ary_sort_bang(rb_funcall(attrs, id_keys, 0));
|
427
|
-
|
428
|
-
for (i = 0; i < RARRAY_LEN(keys); i++) {
|
429
|
-
key = rb_ary_entry(keys, i);
|
430
|
-
value = rb_hash_aref(attrs, key);
|
431
|
-
if (str_eq(key, "id", 2)) {
|
432
|
-
haml_build_for_id(escape_attrs, quote, buf, value);
|
433
|
-
} else if (str_eq(key, "class", 5)) {
|
434
|
-
haml_build_for_class(escape_attrs, quote, buf, value);
|
435
|
-
} else if (str_eq(key, "data", 4)) {
|
436
|
-
haml_build_for_data(escape_attrs, quote, buf, value);
|
437
|
-
} else if (str_eq(key, "aria", 4)) {
|
438
|
-
haml_build_for_aria(escape_attrs, quote, buf, value);
|
439
|
-
} else if (is_boolean_attribute(key, boolean_attributes)) {
|
440
|
-
haml_build_for_boolean(escape_attrs, quote, format, buf, key, value);
|
441
|
-
} else {
|
442
|
-
haml_build_for_others(escape_attrs, quote, buf, key, value);
|
443
|
-
}
|
444
|
-
}
|
445
|
-
|
446
|
-
return buf;
|
447
|
-
}
|
448
|
-
|
449
|
-
static VALUE
|
450
|
-
rb_haml_build_id(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
451
|
-
{
|
452
|
-
VALUE array;
|
453
|
-
|
454
|
-
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
455
|
-
rb_scan_args(argc - 1, argv + 1, "*", &array);
|
456
|
-
|
457
|
-
return haml_build_id(argv[0], array);
|
458
|
-
}
|
459
|
-
|
460
|
-
static VALUE
|
461
|
-
rb_haml_build_class(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
462
|
-
{
|
463
|
-
VALUE array;
|
464
|
-
|
465
|
-
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
466
|
-
rb_scan_args(argc - 1, argv + 1, "*", &array);
|
467
|
-
|
468
|
-
return haml_build_class(argv[0], array);
|
469
|
-
}
|
470
|
-
|
471
|
-
static VALUE
|
472
|
-
rb_haml_build_aria(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
473
|
-
{
|
474
|
-
VALUE array;
|
475
|
-
|
476
|
-
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
|
477
|
-
rb_scan_args(argc - 2, argv + 2, "*", &array);
|
478
|
-
|
479
|
-
return haml_build_data(argv[0], argv[1], array, str_aria);
|
480
|
-
}
|
481
|
-
|
482
|
-
static VALUE
|
483
|
-
rb_haml_build_data(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
484
|
-
{
|
485
|
-
VALUE array;
|
486
|
-
|
487
|
-
rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
|
488
|
-
rb_scan_args(argc - 2, argv + 2, "*", &array);
|
489
|
-
|
490
|
-
return haml_build_data(argv[0], argv[1], array, str_data);
|
491
|
-
}
|
492
|
-
|
493
|
-
static VALUE
|
494
|
-
rb_haml_build(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
495
|
-
{
|
496
|
-
VALUE array;
|
497
|
-
|
498
|
-
rb_check_arity(argc, 5, UNLIMITED_ARGUMENTS);
|
499
|
-
rb_scan_args(argc - 5, argv + 5, "*", &array);
|
500
|
-
|
501
|
-
return haml_build(argv[0], argv[1], argv[2], argv[3], argv[4], array);
|
502
|
-
}
|
503
|
-
|
504
|
-
void
|
505
|
-
Init_haml(void)
|
506
|
-
{
|
507
|
-
VALUE mHaml, mUtil;
|
508
|
-
|
509
|
-
mHaml = rb_define_module("Haml");
|
510
|
-
mObjectRef = rb_define_module_under(mHaml, "ObjectRef");
|
511
|
-
mUtil = rb_define_module_under(mHaml, "Util");
|
512
|
-
mAttributeBuilder = rb_define_module_under(mHaml, "AttributeBuilder");
|
513
|
-
|
514
|
-
rb_define_singleton_method(mUtil, "escape_html", rb_escape_html, 1);
|
515
|
-
rb_define_singleton_method(mAttributeBuilder, "build", rb_haml_build, -1);
|
516
|
-
rb_define_singleton_method(mAttributeBuilder, "build_id", rb_haml_build_id, -1);
|
517
|
-
rb_define_singleton_method(mAttributeBuilder, "build_class", rb_haml_build_class, -1);
|
518
|
-
rb_define_singleton_method(mAttributeBuilder, "build_aria", rb_haml_build_aria, -1);
|
519
|
-
rb_define_singleton_method(mAttributeBuilder, "build_data", rb_haml_build_data, -1);
|
520
|
-
|
521
|
-
id_flatten = rb_intern("flatten");
|
522
|
-
id_keys = rb_intern("keys");
|
523
|
-
id_parse = rb_intern("parse");
|
524
|
-
id_prepend = rb_intern("prepend");
|
525
|
-
id_tr = rb_intern("tr");
|
526
|
-
id_uniq_bang = rb_intern("uniq!");
|
527
|
-
id_xhtml = rb_intern("xhtml");
|
528
|
-
|
529
|
-
// Consider using rb_interned_str() once we stop supporting Ruby 2.7.
|
530
|
-
rb_gc_register_mark_object(str_aria = rb_obj_freeze(rb_str_new_cstr("aria")));
|
531
|
-
rb_gc_register_mark_object(str_data = rb_obj_freeze(rb_str_new_cstr("data")));
|
532
|
-
rb_gc_register_mark_object(str_equal = rb_obj_freeze(rb_str_new_cstr("=")));
|
533
|
-
rb_gc_register_mark_object(str_hyphen = rb_obj_freeze(rb_str_new_cstr("-")));
|
534
|
-
rb_gc_register_mark_object(str_space = rb_obj_freeze(rb_str_new_cstr(" ")));
|
535
|
-
rb_gc_register_mark_object(str_underscore = rb_obj_freeze(rb_str_new_cstr("_")));
|
536
|
-
}
|
537
|
-
#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
|