xrb 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 262e952884557bc231200ca4a520519e9372d5c0aec682bbd92685258a16d115
4
- data.tar.gz: c994e66e6a2c440f0e6ff36a5d964995081e17ab4c79792564d42862c306dc98
3
+ metadata.gz: 7576d5a9614c5ca657109b06f71b2091717cf0919be858527dd7d2d259162327
4
+ data.tar.gz: 57ecf941224ddd1b6fc7da50efc01d6a1f09c8ed63fe03249b183e171c9bf25d
5
5
  SHA512:
6
- metadata.gz: 006b40e77f38cf875163408b443d7f55a5a464a9658ec812071db7aa196133335281cad0ae9c80f1badbdffe77914660b59592dc0d33b99323d91bae19bad9de
7
- data.tar.gz: 8b3dcfb6bee297abfbd1dacf583aed9eddfc0ec61ec99840b9096dccad01446683095394305a44b7eb63e726abc23563bd4f085f39e62afa656aedf45c186961
6
+ metadata.gz: c694e8def7354e1f1c74006349faa3ccf931f056bba6d89ab564cfc998b484880ef9e87f168ecb11751156d03fb5dee216402d670fb426d40151db6a9f1a884c
7
+ data.tar.gz: a040bd3bfa83f9e3583585e79cb801d71334c978b1222f06a7be258bf936ef14ac6bd918cd4c03828a77c4956e0c539846b829957bd27bb9e3b173777a2ffefc
checksums.yaml.gz.sig CHANGED
Binary file
Binary file
data/ext/escape.o CHANGED
Binary file
data/ext/tag.o CHANGED
Binary file
data/ext/xrb/escape.c CHANGED
@@ -2,18 +2,6 @@
2
2
  #include "escape.h"
3
3
  #include <assert.h>
4
4
 
5
- inline static int XRB_Markup_is_markup(VALUE value) {
6
- if (RB_IMMEDIATE_P(value))
7
- return 0;
8
-
9
- // This is a short-cut:
10
- if (rb_class_of(value) == rb_XRB_MarkupString) {
11
- return 1;
12
- }
13
-
14
- return rb_funcall(value, id_is_a, 1, rb_XRB_Markup) == Qtrue;
15
- }
16
-
17
5
  VALUE XRB_MarkupString_raw(VALUE self, VALUE string) {
18
6
  string = rb_str_dup(string);
19
7
 
@@ -91,7 +79,7 @@ static inline VALUE XRB_Markup_append_buffer(VALUE buffer, const char * s, const
91
79
  }
92
80
 
93
81
  // Escape and append a string to the output buffer.
94
- VALUE XRB_Markup_append_string(VALUE buffer, VALUE string) {
82
+ static VALUE XRB_Markup_append_string(VALUE buffer, VALUE string) {
95
83
  const char * begin = RSTRING_PTR(string);
96
84
  const char * end = begin + RSTRING_LEN(string);
97
85
 
@@ -103,37 +91,26 @@ VALUE XRB_Markup_append_string(VALUE buffer, VALUE string) {
103
91
  return XRB_Markup_append_buffer(buffer, s, p, end);
104
92
  }
105
93
 
106
- VALUE XRB_Markup_append_slow(VALUE self, VALUE output, VALUE value) {
107
- // if (value == Qnil) return Qnil;
94
+ // Append self to the output buffer efficiently, escaping special characters.
95
+ VALUE XRB_Markup_append_markup(VALUE self, VALUE output) {
96
+ if (self == Qnil) return output;
97
+
98
+ VALUE value = self;
108
99
 
109
- if (!XRB_Markup_is_markup(value)) {
100
+ // Ensure value is a string:
101
+ if (rb_type(value) != T_STRING) {
110
102
  value = rb_funcall(value, id_to_s, 0);
111
- value = XRB_Markup_escape_string(Qnil, value);
103
+ rb_string_value(&value);
112
104
  }
113
105
 
114
- rb_funcall(output, id_concat, 1, value);
115
-
116
- return output;
117
- }
118
-
119
- VALUE XRB_Markup_append(VALUE self, VALUE output, VALUE value) {
120
- if (value == Qnil) return Qnil;
121
-
122
106
  if (RB_TYPE_P(output, T_STRING)) {
123
- rb_str_modify(output);
124
- } else {
125
- return XRB_Markup_append_slow(self, output, value);
126
- }
127
-
128
- // The output buffer is a string, so we can append directly:
129
- if (XRB_Markup_is_markup(value)) {
130
- rb_str_append(output, value);
131
- } else {
132
- if (rb_type(value) != T_STRING) {
133
- value = rb_funcall(value, id_to_s, 0);
134
- }
135
-
107
+ // Fast path:
108
+ rb_str_modify_expand(output, RSTRING_LEN(value));
136
109
  XRB_Markup_append_string(output, value);
110
+ } else {
111
+ // Slow path (generates temporary strings):
112
+ value = XRB_Markup_escape_string(Qnil, value);
113
+ rb_funcall(output, id_concat, 1, value);
137
114
  }
138
115
 
139
116
  return output;
@@ -160,14 +137,8 @@ VALUE XRB_Markup_escape_string(VALUE self, VALUE string) {
160
137
  }
161
138
 
162
139
  void Init_XRB_escape(void) {
163
- rb_XRB_MarkupString = rb_define_class_under(rb_XRB, "MarkupString", rb_cString);
164
- rb_include_module(rb_XRB_MarkupString, rb_XRB_Markup);
165
-
166
- rb_undef_method(rb_class_of(rb_XRB_Markup), "escape_string");
167
- rb_define_singleton_method(rb_XRB_Markup, "escape_string", XRB_Markup_escape_string, 1);
168
-
169
- rb_undef_method(rb_class_of(rb_XRB_Markup), "append");
170
- rb_define_singleton_method(rb_XRB_Markup, "append", XRB_Markup_append, 2);
140
+ rb_undef_method(rb_XRB_Markup, "append_markup");
141
+ rb_define_method(rb_XRB_Markup, "append_markup", XRB_Markup_append_markup, 1);
171
142
 
172
143
  rb_undef_method(rb_class_of(rb_XRB_Markup), "raw");
173
144
  rb_define_singleton_method(rb_XRB_Markup, "raw", XRB_MarkupString_raw, 1);
data/ext/xrb/escape.h CHANGED
@@ -9,7 +9,7 @@ void Init_XRB_escape(void);
9
9
  VALUE XRB_MarkupString_raw(VALUE self, VALUE string);
10
10
 
11
11
  // Append any value to the output buffer efficiently, escaping entities as needed.
12
- VALUE XRB_Markup_append(VALUE self, VALUE buffer, VALUE value);
12
+ VALUE XRB_Markup_append_markup(VALUE self, VALUE buffer);
13
13
 
14
14
  // Escape any entities in the given string. If no entities were found, might return the original string.
15
15
  VALUE XRB_Markup_escape_string(VALUE self, VALUE string);
data/ext/xrb/tag.c CHANGED
@@ -67,7 +67,7 @@ static void XRB_Tag_append_tag_attribute(VALUE buffer, VALUE key, VALUE value, V
67
67
 
68
68
  if (value != Qtrue) {
69
69
  rb_str_cat_cstr(buffer, "=\"");
70
- XRB_Markup_append(Qnil, buffer, value);
70
+ XRB_Markup_append_markup(value, buffer);
71
71
  rb_str_cat_cstr(buffer, "\"");
72
72
  }
73
73
  }
@@ -160,7 +160,7 @@ VALUE XRB_Tag_append_tag_string(VALUE self, VALUE buffer, VALUE name, VALUE attr
160
160
  rb_str_cat_cstr(buffer, ">");
161
161
 
162
162
  if (content != Qtrue) {
163
- XRB_Markup_append(self, buffer, content);
163
+ XRB_Markup_append_markup(content, buffer);
164
164
  }
165
165
 
166
166
  rb_str_cat_cstr(buffer, "</");
data/ext/xrb/xrb.c CHANGED
@@ -51,6 +51,7 @@ void Init_XRB_Extension(void) {
51
51
 
52
52
  rb_XRB = rb_define_module("XRB");
53
53
  rb_XRB_Markup = rb_define_module_under(rb_XRB, "Markup");
54
+ rb_XRB_MarkupString = rb_define_class_under(rb_XRB, "MarkupString", rb_cString);
54
55
  rb_XRB_Native = rb_define_module_under(rb_XRB, "Native");
55
56
 
56
57
  Init_XRB_escape();
data/ext/xrb.o CHANGED
Binary file
data/lib/xrb/builder.rb CHANGED
@@ -9,8 +9,6 @@ require_relative 'tag'
9
9
  module XRB
10
10
  # Build markup quickly and efficiently.
11
11
  class Builder
12
- include Markup
13
-
14
12
  INDENT = "\t"
15
13
 
16
14
  class Fragment
@@ -19,18 +17,20 @@ module XRB
19
17
  @builder = nil
20
18
  end
21
19
 
22
- def call(builder)
20
+ def append_markup(output)
21
+ builder = Builder.new(output)
22
+
23
+ self.build_markup(builder)
24
+
25
+ return builder.output
26
+ end
27
+
28
+ def build_markup(builder)
23
29
  @block.call(builder)
24
30
  end
25
31
 
26
32
  def to_s
27
- unless @builder
28
- @builder = Builder.new
29
-
30
- self.call(@builder)
31
- end
32
-
33
- return @builder.to_s
33
+ self.append_markup(nil)
34
34
  end
35
35
 
36
36
  def == other
@@ -84,6 +84,10 @@ module XRB
84
84
  @children = [0]
85
85
  end
86
86
 
87
+ def build_markup(builder)
88
+ builder.append(@output)
89
+ end
90
+
87
91
  attr :output
88
92
 
89
93
  def encoding
@@ -149,7 +153,7 @@ module XRB
149
153
  @output << indentation
150
154
  end
151
155
 
152
- Markup.append(@output, content)
156
+ content.build_markup(self)
153
157
 
154
158
  if @indent
155
159
  @output << "\n"
@@ -161,15 +165,7 @@ module XRB
161
165
  end
162
166
 
163
167
  def <<(content)
164
- return unless content
165
-
166
- if content.is_a?(Fragment)
167
- inline! do
168
- content.call(self)
169
- end
170
- else
171
- Markup.append(@output, content)
172
- end
168
+ content&.build_markup(self)
173
169
  end
174
170
 
175
171
  # Append pre-existing markup:
data/lib/xrb/markup.rb CHANGED
@@ -8,32 +8,33 @@ require 'cgi'
8
8
  module XRB
9
9
  # A wrapper which indicates that `value` can be appended to the output buffer without any changes.
10
10
  module Markup
11
- # Converts special characters `<`, `>`, `&`, and `"` into their equivalent entities.
12
- # @return [String] May return the original string if no changes were made.
13
- def self.escape_string(string)
14
- CGI.escape_html(string)
11
+ def self.raw(string)
12
+ MarkupString.raw(string)
15
13
  end
16
14
 
17
- # Appends a string to the output buffer, escaping if if necessary.
18
- def self.append(buffer, value)
19
- if value.is_a? Markup
20
- buffer << value
21
- elsif value
22
- buffer << self.escape_string(value.to_s)
23
- end
15
+ def self.append(output, value)
16
+ value.append_markup(output)
17
+ end
18
+
19
+ def append_markup(output)
20
+ output << ::CGI.escape_html(self.to_s)
21
+ end
22
+
23
+ def build_markup(builder)
24
+ append_markup(builder.output)
24
25
  end
25
26
  end
26
27
 
28
+ ::Object.prepend(Markup)
29
+
27
30
  # Initialized from text which is escaped to use HTML entities.
28
31
  class MarkupString < String
29
- include Markup
30
-
31
32
  # @param string [String] the string value itself.
32
33
  # @param escape [Boolean] whether or not to escape the string.
33
34
  def initialize(string = nil, escape = true)
34
35
  if string
35
36
  if escape
36
- string = Markup.escape_string(string)
37
+ string = ::CGI.escape_html(string)
37
38
  end
38
39
 
39
40
  super(string)
@@ -52,6 +53,10 @@ module XRB
52
53
  def html_safe?
53
54
  true
54
55
  end
56
+
57
+ def append_markup(output)
58
+ output << self
59
+ end
55
60
  end
56
61
 
57
62
  module Script
data/lib/xrb/tag.rb CHANGED
@@ -8,8 +8,6 @@ require_relative 'markup'
8
8
  module XRB
9
9
  # This represents an individual SGML tag, e.g. <a>, </a> or <a />, with attributes. Attribute values must be escaped.
10
10
  Tag = Struct.new(:name, :closed, :attributes) do
11
- include XRB::Markup
12
-
13
11
  def self.split(qualified_name)
14
12
  if i = qualified_name.index(':')
15
13
  return qualified_name.slice(0...i), qualified_name.slice(i+1..-1)
@@ -80,7 +78,7 @@ module XRB
80
78
  else
81
79
  buffer << '>'
82
80
  unless content == true
83
- Markup.append(buffer, content)
81
+ content.append_markup(buffer)
84
82
  end
85
83
  buffer << '</' << name.to_s << '>'
86
84
  end
@@ -108,7 +106,7 @@ module XRB
108
106
  buffer << ' ' << attribute_key.to_s
109
107
  else
110
108
  buffer << ' ' << attribute_key.to_s << '="'
111
- Markup.append(buffer, value)
109
+ value.append_markup(buffer)
112
110
  buffer << '"'
113
111
  end
114
112
  end
data/lib/xrb/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2012-2024, by Samuel Williams.
5
5
 
6
6
  module XRB
7
- VERSION = "0.9.0"
7
+ VERSION = "0.10.0"
8
8
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -40,7 +40,7 @@ cert_chain:
40
40
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
41
41
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
42
42
  -----END CERTIFICATE-----
43
- date: 2024-10-26 00:00:00.000000000 Z
43
+ date: 2024-10-27 00:00:00.000000000 Z
44
44
  dependencies: []
45
45
  description:
46
46
  email:
metadata.gz.sig CHANGED
Binary file