padrino-helpers 0.10.7 → 0.11.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 +7 -0
- data/lib/padrino-helpers.rb +2 -1
- data/lib/padrino-helpers/asset_tag_helpers.rb +57 -65
- data/lib/padrino-helpers/breadcrumb_helpers.rb +171 -0
- data/lib/padrino-helpers/form_builder/abstract_form_builder.rb +82 -24
- data/lib/padrino-helpers/form_helpers.rb +84 -17
- data/lib/padrino-helpers/format_helpers.rb +2 -1
- data/lib/padrino-helpers/locale/fr.yml +12 -12
- data/lib/padrino-helpers/locale/pt_br.yml +2 -2
- data/lib/padrino-helpers/output_helpers.rb +42 -2
- data/lib/padrino-helpers/output_helpers/erb_handler.rb +1 -1
- data/lib/padrino-helpers/output_helpers/slim_handler.rb +4 -5
- data/lib/padrino-helpers/render_helpers.rb +2 -2
- data/lib/padrino-helpers/tag_helpers.rb +33 -5
- data/padrino-helpers.gemspec +0 -0
- data/test/fixtures/markup_app/app.rb +13 -6
- data/test/fixtures/markup_app/views/capture_concat.erb +2 -2
- data/test/fixtures/markup_app/views/capture_concat.haml +2 -2
- data/test/fixtures/markup_app/views/capture_concat.slim +4 -5
- data/test/fixtures/markup_app/views/content_for.slim +4 -4
- data/test/fixtures/markup_app/views/content_tag.slim +5 -5
- data/test/fixtures/markup_app/views/current_engine.haml +1 -1
- data/test/fixtures/markup_app/views/fields_for.slim +13 -13
- data/test/fixtures/markup_app/views/form_for.slim +43 -43
- data/test/fixtures/markup_app/views/form_tag.slim +57 -57
- data/test/fixtures/markup_app/views/link_to.slim +2 -2
- data/test/fixtures/markup_app/views/mail_to.slim +2 -2
- data/test/fixtures/markup_app/views/meta_tag.slim +2 -2
- data/test/fixtures/markup_app/views/partials/_slim.slim +1 -1
- data/test/fixtures/markup_app/views/simple_partial.slim +1 -1
- data/test/fixtures/render_app/app.rb +3 -0
- data/test/test_asset_tag_helpers.rb +17 -4
- data/test/test_form_builder.rb +35 -1
- data/test/test_form_helpers.rb +29 -0
- data/test/test_format_helpers.rb +4 -0
- data/test/test_output_helpers.rb +5 -3
- data/test/test_tag_helpers.rb +11 -0
- metadata +10 -15
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Padrino
|
2
4
|
module Helpers
|
3
5
|
##
|
@@ -28,8 +30,8 @@ module Padrino
|
|
28
30
|
#
|
29
31
|
# @api public
|
30
32
|
def form_for(object, url, settings={}, &block)
|
31
|
-
|
32
|
-
form_tag(url, settings) {
|
33
|
+
instance = builder_instance(object, settings)
|
34
|
+
form_tag(url, settings) { capture_html(instance, &block) }
|
33
35
|
end
|
34
36
|
|
35
37
|
##
|
@@ -54,7 +56,7 @@ module Padrino
|
|
54
56
|
instance = builder_instance(object, settings)
|
55
57
|
fields_html = capture_html(instance, &block)
|
56
58
|
fields_html << instance.hidden_field(:id) if instance.send(:nested_object_id)
|
57
|
-
|
59
|
+
concat_safe_content fields_html
|
58
60
|
end
|
59
61
|
|
60
62
|
##
|
@@ -79,8 +81,9 @@ module Padrino
|
|
79
81
|
options.reverse_merge!(:method => 'post', :action => url)
|
80
82
|
options[:enctype] = 'multipart/form-data' if options.delete(:multipart)
|
81
83
|
options['accept-charset'] ||= 'UTF-8'
|
82
|
-
inner_form_html
|
83
|
-
inner_form_html
|
84
|
+
inner_form_html = hidden_form_method_field(desired_method)
|
85
|
+
inner_form_html << csrf_token_field
|
86
|
+
inner_form_html << mark_safe(capture_html(&block))
|
84
87
|
concat_content content_tag(:form, inner_form_html, options)
|
85
88
|
end
|
86
89
|
|
@@ -100,7 +103,7 @@ module Padrino
|
|
100
103
|
#
|
101
104
|
# @api semipublic
|
102
105
|
def hidden_form_method_field(desired_method)
|
103
|
-
return
|
106
|
+
return ActiveSupport::SafeBuffer.new if desired_method.blank? || desired_method.to_s =~ /get|post/i
|
104
107
|
hidden_field_tag(:_method, :value => desired_method)
|
105
108
|
end
|
106
109
|
|
@@ -125,8 +128,8 @@ module Padrino
|
|
125
128
|
def field_set_tag(*args, &block)
|
126
129
|
options = args.extract_options!
|
127
130
|
legend_text = args[0].is_a?(String) ? args.first : nil
|
128
|
-
legend_html = legend_text.blank? ?
|
129
|
-
field_set_content = legend_html + capture_html(&block)
|
131
|
+
legend_html = legend_text.blank? ? ActiveSupport::SafeBuffer.new : content_tag(:legend, legend_text)
|
132
|
+
field_set_content = legend_html + mark_safe(capture_html(&block))
|
130
133
|
concat_content content_tag(:fieldset, field_set_content, options)
|
131
134
|
end
|
132
135
|
|
@@ -199,10 +202,10 @@ module Padrino
|
|
199
202
|
}
|
200
203
|
}.join
|
201
204
|
|
202
|
-
contents =
|
205
|
+
contents = ActiveSupport::SafeBuffer.new
|
203
206
|
contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
|
204
207
|
contents << content_tag(:p, message) unless message.blank?
|
205
|
-
contents <<
|
208
|
+
contents << safe_content_tag(:ul, error_messages)
|
206
209
|
|
207
210
|
content_tag(:div, contents, html)
|
208
211
|
end
|
@@ -276,10 +279,11 @@ module Padrino
|
|
276
279
|
# @api public
|
277
280
|
def label_tag(name, options={}, &block)
|
278
281
|
options.reverse_merge!(:caption => "#{name.to_s.humanize}: ", :for => name)
|
279
|
-
caption_text = options.delete(:caption)
|
280
|
-
caption_text
|
282
|
+
caption_text = options.delete(:caption).html_safe
|
283
|
+
caption_text.safe_concat "<span class='required'>*</span> " if options.delete(:required)
|
284
|
+
|
281
285
|
if block_given? # label with inner content
|
282
|
-
label_content = caption_text
|
286
|
+
label_content = caption_text.concat capture_html(&block)
|
283
287
|
concat_content(content_tag(:label, label_content, options))
|
284
288
|
else # regular label
|
285
289
|
content_tag(:label, caption_text, options)
|
@@ -409,10 +413,10 @@ module Padrino
|
|
409
413
|
# # => <input name="age" min="18" max="120" step="1" type="number">
|
410
414
|
#
|
411
415
|
# @api public
|
412
|
-
def number_field_tag(name, options={})
|
416
|
+
def number_field_tag(name, options={})
|
413
417
|
input_tag(:number, options.reverse_merge(:name => name))
|
414
418
|
end
|
415
|
-
|
419
|
+
|
416
420
|
##
|
417
421
|
# Creates a telephone field input with the given name and options
|
418
422
|
#
|
@@ -452,7 +456,7 @@ module Padrino
|
|
452
456
|
def email_field_tag(name, options={})
|
453
457
|
input_tag(:email, options.reverse_merge(:name => name))
|
454
458
|
end
|
455
|
-
|
459
|
+
|
456
460
|
##
|
457
461
|
# Creates a search field input with the given name and options
|
458
462
|
#
|
@@ -573,6 +577,7 @@ module Padrino
|
|
573
577
|
#
|
574
578
|
# @api public
|
575
579
|
def file_field_tag(name, options={})
|
580
|
+
name = "#{name}[]" if options[:multiple]
|
576
581
|
options.reverse_merge!(:name => name)
|
577
582
|
input_tag(:file, options)
|
578
583
|
end
|
@@ -630,7 +635,7 @@ module Padrino
|
|
630
635
|
end
|
631
636
|
select_options_html = select_options_html.unshift(blank_option(prompt)) if select_options_html.is_a?(Array)
|
632
637
|
options.merge!(:name => "#{options[:name]}[]") if options[:multiple]
|
633
|
-
|
638
|
+
safe_content_tag(:select, select_options_html, options)
|
634
639
|
end
|
635
640
|
|
636
641
|
##
|
@@ -689,6 +694,68 @@ module Padrino
|
|
689
694
|
input_tag(:image, options)
|
690
695
|
end
|
691
696
|
|
697
|
+
# Constructs a hidden field containing a CSRF token.
|
698
|
+
#
|
699
|
+
# @param [String] token
|
700
|
+
# The token to use. Will be read from the session by default.
|
701
|
+
#
|
702
|
+
# @return [String] The hidden field with CSRF token as value.
|
703
|
+
#
|
704
|
+
# @example
|
705
|
+
# csrf_token_field
|
706
|
+
#
|
707
|
+
# @api public
|
708
|
+
def csrf_token_field(token = nil)
|
709
|
+
if defined? session
|
710
|
+
token ||= (session[:csrf] ||= SecureRandom.hex(32))
|
711
|
+
end
|
712
|
+
|
713
|
+
hidden_field_tag :authenticity_token, :value => token
|
714
|
+
end
|
715
|
+
|
716
|
+
##
|
717
|
+
# Creates a form containing a single button that submits to the url.
|
718
|
+
#
|
719
|
+
# @overload button_to(name, url, options={})
|
720
|
+
# @param [String] caption The text caption.
|
721
|
+
# @param [String] url The url href.
|
722
|
+
# @param [Hash] options The html options.
|
723
|
+
# @overload button_to(name, options={}, &block)
|
724
|
+
# @param [String] url The url href.
|
725
|
+
# @param [Hash] options The html options.
|
726
|
+
# @param [Proc] block The button content.
|
727
|
+
#
|
728
|
+
# @option options [Boolean] :multipart
|
729
|
+
# If true, this form will support multipart encoding.
|
730
|
+
# @option options [String] :remote
|
731
|
+
# Instructs ujs handler to handle the submit as ajax.
|
732
|
+
# @option options [Symbol] :method
|
733
|
+
# Instructs ujs handler to use different http method (i.e :post, :delete).
|
734
|
+
#
|
735
|
+
# @return [String] Form and button html with specified +options+.
|
736
|
+
#
|
737
|
+
# @example
|
738
|
+
# button_to 'Delete', url(:accounts_destroy, :id => account), :method => :delete, :class => :form
|
739
|
+
# # Generates:
|
740
|
+
# # <form class="form" action="/admin/accounts/destroy/2" method="post">
|
741
|
+
# # <input type="hidden" value="delete" name="_method" />
|
742
|
+
# # <input type="submit" value="Delete" />
|
743
|
+
# # </form>
|
744
|
+
#
|
745
|
+
# @api public
|
746
|
+
def button_to(*args, &block)
|
747
|
+
name, url = args[0], args[1]
|
748
|
+
options = args.extract_options!
|
749
|
+
options['data-remote'] = 'true' if options.delete(:remote)
|
750
|
+
if block_given?
|
751
|
+
form_tag(url, options, &block)
|
752
|
+
else
|
753
|
+
form_tag(url, options) do
|
754
|
+
submit_tag(name)
|
755
|
+
end
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
692
759
|
protected
|
693
760
|
|
694
761
|
##
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
module Padrino
|
2
3
|
module Helpers
|
3
4
|
###
|
@@ -373,7 +374,7 @@ module Padrino
|
|
373
374
|
def js_escape_html(html_content)
|
374
375
|
return '' unless html_content
|
375
376
|
javascript_mapping = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }
|
376
|
-
html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/)
|
377
|
+
html_content.gsub(/(\\|<\/|\r\n|[\n\r"'])/){|m| javascript_mapping[m]}
|
377
378
|
end
|
378
379
|
alias :escape_javascript :js_escape_html
|
379
380
|
end # FormatHelpers
|
@@ -27,25 +27,25 @@ fr:
|
|
27
27
|
format: "%n %u"
|
28
28
|
units:
|
29
29
|
byte:
|
30
|
-
one: "
|
31
|
-
other: "
|
32
|
-
kb: "
|
33
|
-
mb: "
|
34
|
-
gb: "
|
35
|
-
tb: "
|
30
|
+
one: "Octet"
|
31
|
+
other: "Octets"
|
32
|
+
kb: "Ko"
|
33
|
+
mb: "Mo"
|
34
|
+
gb: "Go"
|
35
|
+
tb: "To"
|
36
36
|
|
37
37
|
datetime:
|
38
38
|
distance_in_words:
|
39
39
|
half_a_minute: "une demi minute"
|
40
40
|
less_than_x_seconds:
|
41
|
-
one: "
|
42
|
-
other: "
|
41
|
+
one: "inférieur à une seconde"
|
42
|
+
other: "inférieur à %{count} secondes"
|
43
43
|
x_seconds:
|
44
44
|
one: "1 seconde"
|
45
45
|
other: "%{count} secondes"
|
46
46
|
less_than_x_minutes:
|
47
|
-
one: "
|
48
|
-
other: "
|
47
|
+
one: "inférieur à 1 minute"
|
48
|
+
other: "inférieur à %{count} minutes"
|
49
49
|
x_minutes:
|
50
50
|
one: "1 minute"
|
51
51
|
other: "%{count} minutes"
|
@@ -68,8 +68,8 @@ fr:
|
|
68
68
|
one: "plus d'un an"
|
69
69
|
other: "plus de %{count} ans"
|
70
70
|
almost_x_years:
|
71
|
-
one: "près d'un
|
72
|
-
other: "près de %{count}
|
71
|
+
one: "près d'un an"
|
72
|
+
other: "près de %{count} ans"
|
73
73
|
models:
|
74
74
|
errors:
|
75
75
|
template:
|
@@ -26,6 +26,8 @@ module Padrino
|
|
26
26
|
##
|
27
27
|
# Captures the html from a block of template code for any available handler.
|
28
28
|
#
|
29
|
+
# Be aware that trusting the html is up to the caller.
|
30
|
+
#
|
29
31
|
# @param [Object] *args
|
30
32
|
# Objects yield to the captured block
|
31
33
|
# @param [Proc] &block
|
@@ -37,6 +39,12 @@ module Padrino
|
|
37
39
|
# capture_html(&block) => "...html..."
|
38
40
|
# capture_html(object_for_block, &block) => "...html..."
|
39
41
|
#
|
42
|
+
# @example
|
43
|
+
# ActiveSupport::SafeBuffer.new + capture_html { "<foo>" }
|
44
|
+
# # => "<foo>"
|
45
|
+
# ActiveSupport::SafeBuffer.safe_concat + capture_html { "<foo>" }
|
46
|
+
# # => "<foo>"
|
47
|
+
#
|
40
48
|
# @api semipublic
|
41
49
|
def capture_html(*args, &block)
|
42
50
|
handler = find_proper_handler
|
@@ -53,7 +61,9 @@ module Padrino
|
|
53
61
|
##
|
54
62
|
# Outputs the given text to the templates buffer directly.
|
55
63
|
#
|
56
|
-
#
|
64
|
+
# The output might be subject to escaping, if it is not marked as safe.
|
65
|
+
#
|
66
|
+
# @param [String,SafeBuffer] text
|
57
67
|
# Text to concatenate to the buffer.
|
58
68
|
#
|
59
69
|
# @example
|
@@ -70,6 +80,21 @@ module Padrino
|
|
70
80
|
end
|
71
81
|
alias :concat :concat_content
|
72
82
|
|
83
|
+
##
|
84
|
+
# Outputs the given text to the templates buffer directly,
|
85
|
+
# assuming that it is safe.
|
86
|
+
#
|
87
|
+
# @param [String] text
|
88
|
+
# Text to concatenate to the buffer.
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# concat_safe_content("This will be output to the template buffer")
|
92
|
+
#
|
93
|
+
# @api semipublic
|
94
|
+
def concat_safe_content(text="")
|
95
|
+
concat_content text.html_safe
|
96
|
+
end
|
97
|
+
|
73
98
|
##
|
74
99
|
# Returns true if the block is from a supported template type; false otherwise.
|
75
100
|
# Used to determine if html should be returned or concatenated to the view.
|
@@ -146,7 +171,7 @@ module Padrino
|
|
146
171
|
def yield_content(key, *args)
|
147
172
|
blocks = content_blocks[key.to_sym]
|
148
173
|
return nil if blocks.empty?
|
149
|
-
blocks.map { |content| capture_html(*args, &content) }.join
|
174
|
+
mark_safe(blocks.map { |content| capture_html(*args, &content) }.join)
|
150
175
|
end
|
151
176
|
|
152
177
|
protected
|
@@ -170,6 +195,21 @@ module Padrino
|
|
170
195
|
def find_proper_handler
|
171
196
|
OutputHelpers.handlers.map { |h| h.new(self) }.find { |h| h.engines.include?(current_engine) && h.is_type? }
|
172
197
|
end
|
198
|
+
|
199
|
+
##
|
200
|
+
# Marks a String or a collection of Strings as safe. `nil` is accepted
|
201
|
+
# but ignored.
|
202
|
+
#
|
203
|
+
# @param [String, Array<String>] the values to be marked safe.
|
204
|
+
#
|
205
|
+
# @return [ActiveSupport::SafeBuffer, Array<ActiveSupport::SafeBuffer>]
|
206
|
+
def mark_safe(value)
|
207
|
+
if value.respond_to? :map!
|
208
|
+
value.map!{|v| v.html_safe if v }
|
209
|
+
else
|
210
|
+
value.html_safe if value
|
211
|
+
end
|
212
|
+
end
|
173
213
|
end # OutputHelpers
|
174
214
|
end # Helpers
|
175
215
|
end # Padrino
|
@@ -28,7 +28,7 @@ module Padrino
|
|
28
28
|
# @handler.capture_from_template(&block) => "...html..."
|
29
29
|
#
|
30
30
|
def capture_from_template(*args, &block)
|
31
|
-
self.output_buffer, _buf_was =
|
31
|
+
self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
|
32
32
|
block.call(*args)
|
33
33
|
ret = eval("@_out_buf", block.binding)
|
34
34
|
self.output_buffer = _buf_was
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# Make slim works with sinatra/padrino
|
2
|
-
Slim::Engine.set_default_options(:buffer => '@_out_buf', :generator => Temple::Generators::StringBuffer) if defined?(Slim)
|
3
2
|
|
4
3
|
module Padrino
|
5
4
|
module Helpers
|
@@ -31,9 +30,9 @@ module Padrino
|
|
31
30
|
# @handler.capture_from_template(&block) => "...html..."
|
32
31
|
#
|
33
32
|
def capture_from_template(*args, &block)
|
34
|
-
self.output_buffer, _buf_was =
|
33
|
+
self.output_buffer, _buf_was = ActiveSupport::SafeBuffer.new, self.output_buffer
|
35
34
|
block.call(*args)
|
36
|
-
ret = eval(
|
35
|
+
ret = eval("@_out_buf", block.binding)
|
37
36
|
self.output_buffer = _buf_was
|
38
37
|
ret
|
39
38
|
end
|
@@ -73,9 +72,9 @@ module Padrino
|
|
73
72
|
def output_buffer=(val)
|
74
73
|
template.instance_variable_set(:@_out_buf, val)
|
75
74
|
end
|
76
|
-
|
75
|
+
end # SlimHandler
|
77
76
|
|
78
|
-
|
77
|
+
OutputHelpers.register(SlimHandler)
|
79
78
|
end # OutputHelpers
|
80
79
|
end # Helpers
|
81
80
|
end # Padrino
|
@@ -46,12 +46,12 @@ module Padrino
|
|
46
46
|
counter += 1
|
47
47
|
options[:locals].merge!(object_name => member, "#{object_name}_counter".to_sym => counter)
|
48
48
|
render(explicit_engine, template_path, options.dup)
|
49
|
-
}.join("\n")
|
49
|
+
}.join("\n").html_safe
|
50
50
|
else
|
51
51
|
if member = options.delete(:object)
|
52
52
|
options[:locals].merge!(object_name => member)
|
53
53
|
end
|
54
|
-
render(explicit_engine, template_path, options.dup)
|
54
|
+
render(explicit_engine, template_path, options.dup).html_safe
|
55
55
|
end
|
56
56
|
end
|
57
57
|
alias :render_partial :partial
|
@@ -13,6 +13,12 @@ module Padrino
|
|
13
13
|
'"' => """
|
14
14
|
}
|
15
15
|
|
16
|
+
##
|
17
|
+
# Cached Regexp for escaping values to avoid rebuilding one
|
18
|
+
# on every escape operation.
|
19
|
+
#
|
20
|
+
ESCAPE_REGEXP = Regexp.union(*ESCAPE_VALUES.keys)
|
21
|
+
|
16
22
|
BOOLEAN_ATTRIBUTES = [
|
17
23
|
:autoplay,
|
18
24
|
:autofocus,
|
@@ -42,6 +48,12 @@ module Padrino
|
|
42
48
|
:confirm
|
43
49
|
]
|
44
50
|
|
51
|
+
##
|
52
|
+
# A html_safe newline string to avoid allocating a new on each
|
53
|
+
# concatenation.
|
54
|
+
#
|
55
|
+
NEWLINE = "\n".html_safe.freeze
|
56
|
+
|
45
57
|
##
|
46
58
|
# Creates an HTML tag with given name, content, and options
|
47
59
|
#
|
@@ -104,14 +116,30 @@ module Padrino
|
|
104
116
|
content = capture_html(&block)
|
105
117
|
end
|
106
118
|
|
107
|
-
content = content.join("\n") if content.respond_to?(:join)
|
108
|
-
|
109
119
|
options = parse_data_options(name, options)
|
110
120
|
attributes = tag_attributes(options)
|
111
|
-
output =
|
121
|
+
output = ActiveSupport::SafeBuffer.new
|
122
|
+
output.safe_concat "<#{name}#{attributes}>"
|
123
|
+
if content.respond_to?(:each) && !content.is_a?(String)
|
124
|
+
content.each { |c| output.concat c; output.safe_concat NEWLINE }
|
125
|
+
else
|
126
|
+
output.concat content
|
127
|
+
end
|
128
|
+
output.safe_concat "</#{name}>"
|
129
|
+
|
112
130
|
block_is_template?(block) ? concat_content(output) : output
|
113
131
|
end
|
114
132
|
|
133
|
+
##
|
134
|
+
# Like #content_tag, but assumes its input to be safe and doesn't
|
135
|
+
# escape. It also returns safe html.
|
136
|
+
#
|
137
|
+
# @see #content_tag
|
138
|
+
#
|
139
|
+
def safe_content_tag(name, content = nil, options = nil, &block)
|
140
|
+
mark_safe(content_tag(name, mark_safe(content), options, &block))
|
141
|
+
end
|
142
|
+
|
115
143
|
##
|
116
144
|
# Creates an HTML input field with the given type and options
|
117
145
|
#
|
@@ -200,7 +228,7 @@ module Padrino
|
|
200
228
|
def tag(name, options = nil, open = false)
|
201
229
|
options = parse_data_options(name, options)
|
202
230
|
attributes = tag_attributes(options)
|
203
|
-
"<#{name}#{attributes}#{open ? '>' : ' />'}"
|
231
|
+
"<#{name}#{attributes}#{open ? '>' : ' />'}".html_safe
|
204
232
|
end
|
205
233
|
|
206
234
|
private
|
@@ -226,7 +254,7 @@ module Padrino
|
|
226
254
|
# Escape tag values to their HTML/XML entities.
|
227
255
|
##
|
228
256
|
def escape_value(string)
|
229
|
-
string.to_s.gsub(
|
257
|
+
string.to_s.gsub(ESCAPE_REGEXP) { |c| ESCAPE_VALUES[c] }
|
230
258
|
end
|
231
259
|
|
232
260
|
##
|