Class: XRB::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/xrb/builder.rb,
lib/xrb/template.rb

Overview

Build markup quickly and efficiently.

Defined Under Namespace

Classes: Fragment

Constant Summary collapse

INDENT =
"\t"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output = nil, indent: true, encoding: Encoding::UTF_8) ⇒ Builder

Initialize a builder which appends markup to the given output buffer.



95
96
97
98
99
100
101
102
103
104
# File 'lib/xrb/builder.rb', line 95

def initialize(output = nil, indent: true, encoding: Encoding::UTF_8)
	# This field gets togged in #inline so we keep track of it separately from @indentation.
	@indent = indent
	
	# We don't need to use MarkupString here as Builder itself is considered markup and should be inserted directly into the output stream.
	@output = output || MarkupString.new.force_encoding(encoding)
	
	@level = [0]
	@children = [0]
end

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



112
113
114
# File 'lib/xrb/builder.rb', line 112

def output
  @output
end

Class Method Details

.fragment(output = nil, &block) ⇒ Object

A helper to generate fragments of markup.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/xrb/builder.rb', line 63

def self.fragment(output = nil, &block)
	if output.is_a?(Binding)
		output = Template.buffer(output)
	end
	
	if output.nil?
		return Fragment.new(block)
	end
	
	block.call(output)
	
	# We explicitly return nil here as we don't want to append the output twice.
	return nil
end

.tag(name, content, **attributes) ⇒ Object

Create a markup fragment containing a single inline tag.



83
84
85
86
87
88
89
# File 'lib/xrb/builder.rb', line 83

def self.tag(name, content, **attributes)
	self.fragment do |builder|
		builder.inline(name, attributes) do
			builder.text(content)
		end
	end
end

Instance Method Details

#<<(content) ⇒ Object

Append content to the output.



203
204
205
# File 'lib/xrb/builder.rb', line 203

def <<(content)
	content&.build_markup(self)
end

#==(other) ⇒ Object

Compare the generated output with another string-like object.



129
130
131
# File 'lib/xrb/builder.rb', line 129

def == other
	@output == String(other)
end

#append(value) ⇒ Object

Append pre-existing markup:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/xrb/builder.rb', line 208

def append(value)
	return unless value
	
	# The parent has one more child:
	@level[-1] += 1
	
	if @indent
		value.each_line.with_index do |line, i|
			@output << indentation << line
		end
	else
		@output << value
	end
end

#build_markup(builder) ⇒ Object

Append the markup to the given output.



107
108
109
# File 'lib/xrb/builder.rb', line 107

def build_markup(builder)
	builder.append(@output)
end

#capture(*arguments, &block) ⇒ Object

Capture markup generated by a block using this builder as its output.



24
25
26
# File 'lib/xrb/template.rb', line 24

def capture(*arguments, &block)
	Template.capture(*arguments, output: self, &block)
end

#doctype(attributes = "html") ⇒ Object

Append a doctype declaration to the output.



144
145
146
# File 'lib/xrb/builder.rb', line 144

def doctype(attributes = "html")
	@output << "<!doctype #{attributes}>\n"
end

#encodingObject



115
116
117
# File 'lib/xrb/builder.rb', line 115

def encoding
	@output.encoding
end

#indentationObject

Compute the indentation for the current nesting level.



135
136
137
138
139
140
141
# File 'lib/xrb/builder.rb', line 135

def indentation
	if @indent
		INDENT * (@level.size - 1)
	else
		""
	end
end

#inline!Object

Temporarily disable indentation while yielding to the block.



170
171
172
173
174
175
176
177
# File 'lib/xrb/builder.rb', line 170

def inline!
	original_indent = @indent
	@indent = false
	
	yield
ensure
	@indent = original_indent
end

#inline_tag(name, attributes = {}, &block) ⇒ Object Also known as: inline

Append a tag to the output without indentation or whitespace.



154
155
156
157
158
159
160
161
162
163
# File 'lib/xrb/builder.rb', line 154

def inline_tag(name, attributes = {}, &block)
	original_indent = @indent
	
	full_tag(name, attributes, @indent, false) do
		@indent = false
		yield if block_given?
	end
ensure
	@indent = original_indent
end

#raw(content) ⇒ Object

Append unescaped content directly to the output buffer.



198
199
200
# File 'lib/xrb/builder.rb', line 198

def raw(content)
	@output << content
end

#tag(name, attributes = {}, &block) ⇒ Object

Append a tag to the output.



149
150
151
# File 'lib/xrb/builder.rb', line 149

def tag(name, attributes = {}, &block)
	full_tag(name, attributes, @indent, @indent, &block)
end

#text(content) ⇒ Object

Append text to the output, escaping it if necessary.



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/xrb/builder.rb', line 180

def text(content)
	return unless content
	
	if @indent
		@output << "\n" if @level.last > 0
		@output << indentation
	end
	
	content.build_markup(self)
	
	if @indent
		@output << "\n"
	end
end

#the output buffer.=(outputbuffer. = (value)) ⇒ Object



112
# File 'lib/xrb/builder.rb', line 112

attr :output

#to_strObject Also known as: to_s

Required for output to buffer.



120
121
122
# File 'lib/xrb/builder.rb', line 120

def to_str
	@output
end