xrb 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 262e952884557bc231200ca4a520519e9372d5c0aec682bbd92685258a16d115
4
- data.tar.gz: c994e66e6a2c440f0e6ff36a5d964995081e17ab4c79792564d42862c306dc98
3
+ metadata.gz: 83ba083dbccd5e6f56df768104a6dc63860cc1dd0bf1aa52ce2928a881a3dd96
4
+ data.tar.gz: 2922616d417867c3fc7790fe871fec4846605fb1a8656354ac8c5ccab1470abb
5
5
  SHA512:
6
- metadata.gz: 006b40e77f38cf875163408b443d7f55a5a464a9658ec812071db7aa196133335281cad0ae9c80f1badbdffe77914660b59592dc0d33b99323d91bae19bad9de
7
- data.tar.gz: 8b3dcfb6bee297abfbd1dacf583aed9eddfc0ec61ec99840b9096dccad01446683095394305a44b7eb63e726abc23563bd4f085f39e62afa656aedf45c186961
6
+ metadata.gz: e191c69bf8043e5e195cdb798da3f23582cf391992c9a19f56dd96313c3783ded8adda3aef1151fa79b922cb9f388d3e3906af0f6781c028c8bccba3615f1645
7
+ data.tar.gz: 6c7ae41f9ac7da195976263054f112f57cb89e6cbd689006998b042ac23346b21ce6f38fc451cc0911d1b2a4134bacfa5c51051b52c2e90891a9e691a91ac12e
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)
@@ -26,6 +24,14 @@ module XRB
26
24
  self.new(name, false, attributes)
27
25
  end
28
26
 
27
+ def append_markup(output)
28
+ self.write(output)
29
+ end
30
+
31
+ def build_markup(builder)
32
+ self.append_markup(builder.output)
33
+ end
34
+
29
35
  def [] key
30
36
  attributes[key]
31
37
  end
@@ -80,7 +86,7 @@ module XRB
80
86
  else
81
87
  buffer << '>'
82
88
  unless content == true
83
- Markup.append(buffer, content)
89
+ content.append_markup(buffer)
84
90
  end
85
91
  buffer << '</' << name.to_s << '>'
86
92
  end
@@ -108,7 +114,7 @@ module XRB
108
114
  buffer << ' ' << attribute_key.to_s
109
115
  else
110
116
  buffer << ' ' << attribute_key.to_s << '="'
111
- Markup.append(buffer, value)
117
+ value.append_markup(buffer)
112
118
  buffer << '"'
113
119
  end
114
120
  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.1"
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.1
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