xrb 0.10.2 → 0.11.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: e0bf51a6404c03e4c10d3a2ada0c804fdcc5df0daa1574d050811f617afcedbc
4
- data.tar.gz: 59f805082ef9ce5c561d774a3ee7692adbfa05555fd7780422a76e411b9bfbd4
3
+ metadata.gz: f497d0775b88ade42679be817f6f04d3c618e4e6bad4122d8d46f7041ef5a2bb
4
+ data.tar.gz: 40a87237bbe2f4d9ae5eabf143b7345eec4ceb14fa0636a9f25f2c5f0c8b1fbe
5
5
  SHA512:
6
- metadata.gz: 3d40c30425864483f9c5c51427cf658a6d155037c2af514891ebf4a10e419344bcb844c4ee5341c6593392a42da9b3550a33c29ba36d3c3ba0301b2d17a66c3b
7
- data.tar.gz: 2db7b9b57170efaafc057a1ab298a8a320954ef492c1181da26866087731ce34daf3c989e8dd5d4616deb808766fede23785ba699247270506bf6d08fe511137
6
+ metadata.gz: 88f8bd3e9d0cc1d8762ec2ff0c0943324db9046d6df103ec633a9752366c008a5ba6ed75aed132700c0235d15fae23312a554a3276b918ae27da495f86df5d1a
7
+ data.tar.gz: 9212116a1f523a7630d92a56ebbcd8f83dee2af4c1228f2b75648440bc582859303d37d2a3c2cab02b399cc1e53ea1ce476c67f5da3030363c41ab78fc246ab3
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/xrb/buffer.rb CHANGED
@@ -4,40 +4,68 @@
4
4
  # Copyright, 2016-2024, by Samuel Williams.
5
5
 
6
6
  module XRB
7
+ # Represents a string buffer with a given path.
7
8
  class Buffer
9
+ # Create a new buffer from a string.
10
+ # @parameter string [String] the string to use as the buffer.
11
+ # @parameter path [String] the path to use for the buffer.
8
12
  def initialize(string, path: "<string>")
9
13
  @string = string
10
14
  @path = path
11
15
  end
12
16
 
17
+ # @attribute [String] the path name of the buffer.
13
18
  attr :path
14
19
 
20
+ def freeze
21
+ return self if frozen?
22
+
23
+ @string.freeze
24
+ @path.freeze
25
+
26
+ super
27
+ end
28
+
29
+ # @returns [Encoding] the encoding of the buffer.
15
30
  def encoding
16
31
  @string.encoding
17
32
  end
18
33
 
34
+ # @returns [String] the content of the buffer.
19
35
  def read
20
36
  @string
21
37
  end
22
38
 
39
+ # Create a buffer from the specified file.
40
+ # @parameter path [String] the path to load the file from.
41
+ # @returns [Buffer] a buffer with the contents of the specified path.
23
42
  def self.load_file(path)
24
43
  FileBuffer.new(path).freeze
25
44
  end
26
45
 
46
+ # Create a buffer from the specified string.
47
+ # @parameter string [String] the string to load into the buffer.
48
+ # @returns [Buffer] a buffer with the contents of the specified string.
27
49
  def self.load(string)
28
50
  Buffer.new(string).freeze
29
51
  end
30
52
 
53
+ # @returns [Buffer] itself.
31
54
  def to_buffer
32
55
  self
33
56
  end
34
57
  end
35
58
 
59
+ # Represents a file buffer with a given path.
36
60
  class FileBuffer
61
+ # Create a new file buffer from a file path.
62
+ # @parameter path [String] the path to the file.
37
63
  def initialize(path)
38
64
  @path = path
65
+ @cache = nil
39
66
  end
40
67
 
68
+ # Freeze the buffer, caching the contents of the file.
41
69
  def freeze
42
70
  return self if frozen?
43
71
 
@@ -46,27 +74,38 @@ module XRB
46
74
  super
47
75
  end
48
76
 
77
+ # @attribute [String] the path name of the buffer.
49
78
  attr :path
50
79
 
80
+ # @returns [Encoding] the encoding of the buffer.
51
81
  def encoding
52
82
  read.encoding
53
83
  end
54
84
 
85
+ # Read the contents of the file into the buffer.
86
+ # @returns [String] the content of the buffer.
55
87
  def read
56
88
  @cache ||= File.read(@path).freeze
57
89
  end
58
90
 
91
+ # @returns [Buffer] a buffer with the contents of the file.
59
92
  def to_buffer
60
93
  Buffer.new(self.read, @path)
61
94
  end
62
95
  end
63
96
 
97
+ # Represents an IO buffer with a given path.
64
98
  class IOBuffer
99
+ # Create a new IO buffer from an IO object.
100
+ # @parameter io [IO] the IO object to use as the buffer.
101
+ # @parameter path [String] the path to use for the buffer.
65
102
  def initialize(io, path: io.inspect)
66
103
  @io = io
67
104
  @path = path
105
+ @cache = nil
68
106
  end
69
107
 
108
+ # Freeze the buffer, caching the contents of the IO object.
70
109
  def freeze
71
110
  return self if frozen?
72
111
 
@@ -75,21 +114,31 @@ module XRB
75
114
  super
76
115
  end
77
116
 
117
+ # @attribute [String] the path name of the buffer.
78
118
  attr :path
79
119
 
120
+ # @returns [Encoding] the encoding of the buffer.
80
121
  def encoding
81
122
  read.encoding
82
123
  end
83
124
 
125
+ # Read the contents of the IO object into the buffer.
84
126
  def read
85
- @cache ||= @io.read.freeze
127
+ unless @cache
128
+ @cache = @io.read.freeze
129
+ @io.close
130
+ end
131
+
132
+ return @cache
86
133
  end
87
134
 
135
+ # @returns [Buffer] a buffer with the contents of the IO object.
88
136
  def to_buffer
89
137
  Buffer.new(self.read, path: @path)
90
138
  end
91
139
  end
92
140
 
141
+ # Convert the given value to a buffer.
93
142
  def self.Buffer(value)
94
143
  case value
95
144
  when String
data/lib/xrb/builder.rb CHANGED
@@ -11,12 +11,16 @@ module XRB
11
11
  class Builder
12
12
  INDENT = "\t"
13
13
 
14
+ # Represents a lazy fragment of markup that can be generated on demand.
14
15
  class Fragment
16
+ # Initialize the fragment with a block that will be called to generate the markup.
17
+ # @parameter block [Proc] the block that will be called to generate the markup.
15
18
  def initialize(block)
16
19
  @block = block
17
20
  @builder = nil
18
21
  end
19
22
 
23
+ # Append the markup to the given output.
20
24
  def append_markup(output)
21
25
  builder = Builder.new(output)
22
26
 
@@ -25,19 +29,25 @@ module XRB
25
29
  return builder.output
26
30
  end
27
31
 
32
+ # Build the markup using the given builder.
28
33
  def build_markup(builder)
29
34
  @block.call(builder)
30
35
  end
31
36
 
37
+ # Convert the fragment to a string.
38
+ # @returns [MarkupString] the markup generated by the fragment.
32
39
  def to_s
33
40
  self.append_markup(nil)
34
41
  end
35
42
 
43
+ # Compare the fragment to another object as a string. Primarily useful for testing.
36
44
  def == other
37
45
  # This is a bit of a hack... but is required for existing specs to pass:
38
46
  self.to_s == other.to_s
39
47
  end
40
48
 
49
+ # Assuming the fragment is generated in the context of a template being rendered, append the fragment to the output buffer.
50
+ # @parameter block [Proc] the block which is within the scope of the template being rendered.
41
51
  def >> block
42
52
  if block
43
53
  Template.buffer(block.binding) << self
@@ -84,12 +94,15 @@ module XRB
84
94
  @children = [0]
85
95
  end
86
96
 
97
+ # Append the markup to the given output.
87
98
  def build_markup(builder)
88
99
  builder.append(@output)
89
100
  end
90
101
 
102
+ # @attribute [Object] the output buffer.
91
103
  attr :output
92
104
 
105
+ # @returns [Encoding] the encoding of the output.
93
106
  def encoding
94
107
  @output.encoding
95
108
  end
@@ -113,16 +126,17 @@ module XRB
113
126
  end
114
127
  end
115
128
 
129
+ # Append a doctype declaration to the output.
116
130
  def doctype(attributes = "html")
117
131
  @output << "<!doctype #{attributes}>\n"
118
132
  end
119
133
 
120
- # Begin a block tag.
134
+ # Append a tag to the output.
121
135
  def tag(name, attributes = {}, &block)
122
136
  full_tag(name, attributes, @indent, @indent, &block)
123
137
  end
124
138
 
125
- # Begin an inline tag.
139
+ # Append a tag to the output without indentation or whitespace.
126
140
  def inline_tag(name, attributes = {}, &block)
127
141
  original_indent = @indent
128
142
 
@@ -145,6 +159,7 @@ module XRB
145
159
  @indent = original_indent
146
160
  end
147
161
 
162
+ # Append text to the output, escaping it if necessary.
148
163
  def text(content)
149
164
  return unless content
150
165
 
@@ -164,6 +179,7 @@ module XRB
164
179
  @output << content
165
180
  end
166
181
 
182
+ # Append content to the output.
167
183
  def <<(content)
168
184
  content&.build_markup(self)
169
185
  end
data/lib/xrb/template.rb CHANGED
@@ -41,7 +41,7 @@ module XRB
41
41
  return output.to_str
42
42
  end
43
43
 
44
- # Returns the buffer used for capturing output.
44
+ # @returns [Object] the buffer used for capturing output.
45
45
  def self.buffer(binding)
46
46
  binding.local_variable_get(OUT)
47
47
  end
@@ -72,19 +72,24 @@ module XRB
72
72
  end
73
73
  end
74
74
 
75
+ # Load a template from a file.
75
76
  def self.load_file(path, **options)
76
77
  self.new(FileBuffer.new(path), **options).freeze
77
78
  end
78
79
 
80
+ # Load a template from a string.
79
81
  def self.load(string, *arguments, **options)
80
82
  self.new(Buffer.new(string), **options).freeze
81
83
  end
82
84
 
83
- # @param binding [Binding] The binding in which the template is compiled. e.g. `TOPLEVEL_BINDING`.
85
+ # Initialize a new template.
86
+ # @parameter buffer [Buffer] The buffer containing the template.
87
+ # @parameter binding [Binding] The binding in which the template is compiled. e.g. `TOPLEVEL_BINDING`.
84
88
  def initialize(buffer, binding: BINDING)
85
89
  @buffer = buffer
86
90
  @binding = binding
87
91
 
92
+ @code = nil
88
93
  @compiled = nil
89
94
  end
90
95
 
@@ -96,14 +101,23 @@ module XRB
96
101
  super
97
102
  end
98
103
 
104
+ # The compiled code for the template.
105
+ # @returns [String] the compiled Ruby code.
99
106
  def code
100
107
  @code ||= compile!
101
108
  end
102
109
 
110
+ # The compiled template as a proc.
111
+ # @parameter scope [Object] The scope in which the template will be compiled.
112
+ # @returns [Proc] a proc that can be called with an output object.
103
113
  def compiled(scope = @binding.dup)
104
114
  @compiled ||= eval("\# frozen_string_literal: true\nproc{|#{OUT}|;#{code}}", scope, @buffer.path, 0).freeze
105
115
  end
106
116
 
117
+ # Renders the template to a string.
118
+ #
119
+ # @parameter scope [Object] The scope in which the template will be evaluated.
120
+ # @parameter output [String | Nil] The output string to append to.
107
121
  def to_string(scope = Object.new, output = nil)
108
122
  builder = Builder.new(output, encoding: code.encoding)
109
123
 
@@ -112,13 +126,29 @@ module XRB
112
126
  return builder.output
113
127
  end
114
128
 
129
+ # Renders the template to a buffer.
115
130
  def to_buffer(scope)
116
131
  Buffer.new(to_string(scope), path: @buffer.path)
117
132
  end
118
133
 
134
+ # Convert the template to a proc that can be called with an output object. The proc renders the template using `to_string` and writes the output to the given output object. The output should implement `<<` and `close_write(error = nil)` methods.
135
+ #
136
+ # @parameter scope [Object] The scope in which the template will be evaluated.
137
+ # @returns [Proc] a proc that can be called with an output object.
119
138
  def to_proc(scope = @binding.dup)
120
139
  proc do |output|
121
140
  to_string(scope, output)
141
+ rescue Exception => error
142
+ # I find this a bit ugly but we only use this code path on errors, so it's not performance critical.
143
+ if output.method(:close_write).arity != 0
144
+ # Inform the output that an error occured and the output was not generated correctly.
145
+ output.close_write(error)
146
+ output = nil
147
+ end
148
+
149
+ raise
150
+ ensure
151
+ output&.close_write
122
152
  end
123
153
  end
124
154
 
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.10.2"
7
+ VERSION = "0.11.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.10.2
4
+ version: 0.11.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-28 00:00:00.000000000 Z
43
+ date: 2024-11-13 00:00:00.000000000 Z
44
44
  dependencies: []
45
45
  description:
46
46
  email:
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubygems_version: 3.5.11
117
+ rubygems_version: 3.5.22
118
118
  signing_key:
119
119
  specification_version: 4
120
120
  summary: A fast native templating system that compiles directly to Ruby code.
metadata.gz.sig CHANGED
Binary file