XRBSourceXRBBuilder

class Builder

Build markup quickly and efficiently.

Nested

Definitions

def self.fragment(output = nil, &block)

A helper to generate fragments of markup.

Implementation

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

def tag(name, attributes = {}, &block)

Append a tag to the output.

Implementation

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

def build_markup(builder)

Append the markup to the given output.

Implementation

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

attr :output

Signature

attribute Object

the output buffer.

def encoding

Signature

returns Encoding

the encoding of the output.

Implementation

def encoding
	@output.encoding
end

def to_str

Required for output to buffer.

Implementation

def to_str
	@output
end

def doctype(attributes = "html")

Append a doctype declaration to the output.

Implementation

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

def inline_tag(name, attributes = {}, &block)

Append a tag to the output without indentation or whitespace.

Implementation

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

def text(content)

Append text to the output, escaping it if necessary.

Implementation

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

def <<(content)

Append content to the output.

Implementation

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

def append(value)

Append pre-existing markup:

Implementation

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

def full_tag(name, attributes, indent_outer, indent_inner, &block)

A normal block level/container tag.

Implementation

def full_tag(name, attributes, indent_outer, indent_inner, &block)
	if block_given?
		if indent_outer
			@output << "\n" if @level.last > 0
			@output << indentation
		end
		
		tag = XRB::Tag.opened(name.to_s, attributes)
		tag.write_opening_tag(@output)
		@output << "\n" if indent_inner
		
		# The parent has one more child:
		@level[-1] += 1
		
		@level << 0
		
		yield
		
		children = @level.pop
		
		if indent_inner
			@output << "\n" if children > 0
			@output << indentation
		end
		
		tag.write_closing_tag(@output)
	else
		# The parent has one more child:
		@level[-1] += 1
		
		@output << indentation
		XRB::Tag.append_tag(@output, name.to_s, attributes, nil)
	end
end