xrb 0.10.2 → 0.11.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: e0bf51a6404c03e4c10d3a2ada0c804fdcc5df0daa1574d050811f617afcedbc
4
- data.tar.gz: 59f805082ef9ce5c561d774a3ee7692adbfa05555fd7780422a76e411b9bfbd4
3
+ metadata.gz: d6f3f374f9c7841a9aabbe4a4f30a598e8567d9357d0fef4113770b318fc76ed
4
+ data.tar.gz: 16aff80df195168a9a2ec179c79d8219d18eaebb344e94e6fe668ea814b4e02e
5
5
  SHA512:
6
- metadata.gz: 3d40c30425864483f9c5c51427cf658a6d155037c2af514891ebf4a10e419344bcb844c4ee5341c6593392a42da9b3550a33c29ba36d3c3ba0301b2d17a66c3b
7
- data.tar.gz: 2db7b9b57170efaafc057a1ab298a8a320954ef492c1181da26866087731ce34daf3c989e8dd5d4616deb808766fede23785ba699247270506bf6d08fe511137
6
+ metadata.gz: 90ba6bdffb495cd7356eb8818dd8649b2fcffddd903e756b4724cda48420fbea6ce9e6fa8a49ff8b3f084cca00783322d1ffd814e3cd00bcf93e07389e63385e
7
+ data.tar.gz: 52057eebbfee6c4b10c0258f2199c895f7a960f17bdae3892793a8e99647364d32868d2c7f91a5c6a6596db3d1d028fa0b2ed0f100a0af64db1c8aca524e753d
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,15 +72,19 @@ 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
@@ -96,14 +100,23 @@ module XRB
96
100
  super
97
101
  end
98
102
 
103
+ # The compiled code for the template.
104
+ # @returns [String] the compiled Ruby code.
99
105
  def code
100
106
  @code ||= compile!
101
107
  end
102
108
 
109
+ # The compiled template as a proc.
110
+ # @parameter scope [Object] The scope in which the template will be compiled.
111
+ # @returns [Proc] a proc that can be called with an output object.
103
112
  def compiled(scope = @binding.dup)
104
113
  @compiled ||= eval("\# frozen_string_literal: true\nproc{|#{OUT}|;#{code}}", scope, @buffer.path, 0).freeze
105
114
  end
106
115
 
116
+ # Renders the template to a string.
117
+ #
118
+ # @parameter scope [Object] The scope in which the template will be evaluated.
119
+ # @parameter output [String | Nil] The output string to append to.
107
120
  def to_string(scope = Object.new, output = nil)
108
121
  builder = Builder.new(output, encoding: code.encoding)
109
122
 
@@ -112,13 +125,29 @@ module XRB
112
125
  return builder.output
113
126
  end
114
127
 
128
+ # Renders the template to a buffer.
115
129
  def to_buffer(scope)
116
130
  Buffer.new(to_string(scope), path: @buffer.path)
117
131
  end
118
132
 
133
+ # 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.
134
+ #
135
+ # @parameter scope [Object] The scope in which the template will be evaluated.
136
+ # @returns [Proc] a proc that can be called with an output object.
119
137
  def to_proc(scope = @binding.dup)
120
138
  proc do |output|
121
139
  to_string(scope, output)
140
+ rescue Exception => error
141
+ # I find this a bit ugly but we only use this code path on errors, so it's not performance critical.
142
+ if output.method(:close_write).arity != 0
143
+ # Inform the output that an error occured and the output was not generated correctly.
144
+ output.close_write(error)
145
+ output = nil
146
+ end
147
+
148
+ raise
149
+ ensure
150
+ output&.close_write
122
151
  end
123
152
  end
124
153
 
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.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.10.2
4
+ version: 0.11.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-28 00:00:00.000000000 Z
43
+ date: 2024-10-30 00:00:00.000000000 Z
44
44
  dependencies: []
45
45
  description:
46
46
  email:
metadata.gz.sig CHANGED
Binary file