Documentation
¶
Overview ¶
Package builder is a pure-Go (CGO=0), MRI-faithful reimplementation of Ruby's `builder` gem — Builder::XmlMarkup, the programmatic XML/markup generator.
Ruby drives Builder through method_missing: `xml.person { xml.name("Alice") }` turns the missing method name into an element name. Go has no method_missing, so this package exposes the same emitter through an explicit, dynamic API that a host (go-embedded-ruby / rbgo) drives:
- XmlMarkup.Tag is the general element emitter — the Go equivalent of Ruby's `xml.tag!`. The rbgo binding maps a Ruby `method_missing(name, …)` straight onto Tag(name, …), so the element name comes from the missing method just as in MRI.
- XmlMarkup.Element is a small typed convenience over Tag for the common name+attrs+content shape.
- XmlMarkup.Text, XmlMarkup.CData, XmlMarkup.Comment, XmlMarkup.Instruct, XmlMarkup.Declare and XmlMarkup.Append mirror Builder's `text!`, `cdata!`, `comment!`, `instruct!`, `declare!` and `<<`.
The bytes it emits are byte-for-byte identical to builder 3.3.0 running on MRI (Ruby >= 4.0), validated by a differential oracle against the gem.
Index ¶
- type Attr
- type Attrs
- type Option
- type Raw
- type Symbol
- type Value
- type XmlMarkup
- func (x *XmlMarkup) Append(v Value) string
- func (x *XmlMarkup) Block(name string, attrs Attrs, fn func(*XmlMarkup)) string
- func (x *XmlMarkup) CData(text string) string
- func (x *XmlMarkup) Comment(text string) string
- func (x *XmlMarkup) Declare(inst string, args ...any) string
- func (x *XmlMarkup) Element(name string, attrs Attrs, content Value) string
- func (x *XmlMarkup) Instruct(directive string, attrs Attrs) string
- func (x *XmlMarkup) NS(ns, name string, args ...any) string
- func (x *XmlMarkup) Tag(name string, args ...any) string
- func (x *XmlMarkup) Target() string
- func (x *XmlMarkup) Text(v Value) string
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Attr ¶
type Attr struct {
Key string
Value Value // rendered with Ruby to_s then attribute-escaped; nil -> ""
}
Attr is a single XML attribute. Builder takes attributes as a Ruby Hash, whose insertion order is preserved in the emitted markup; an ordered slice of Attr reproduces that exactly and avoids Go map's random iteration order.
type Option ¶
type Option func(*XmlMarkup)
Option configures a new XmlMarkup.
func WithIndent ¶
WithIndent sets the number of spaces emitted per nesting level, matching Builder::XmlMarkup.new(indent: n). Zero (the default) emits everything on a single line with no newlines.
func WithMargin ¶
WithMargin sets the initial indentation level (Builder's margin: option), so the whole document is shifted right by margin*indent spaces. It has no effect unless an indent is also set.
func WithTarget ¶
WithTarget directs output to an external *strings.Builder rather than the emitter's own buffer — the Go equivalent of Builder's target: option, which also lets one builder feed another. XmlMarkup.Target still returns the same accumulated text.
type Raw ¶
type Raw string
Raw is markup inserted verbatim, with no escaping — the Go equivalent of Ruby's `xml << "<i>raw</i>"`. Text!/content strings are always escaped; wrap a string in Raw to bypass that.
type Symbol ¶
type Symbol string
Symbol is a Ruby Symbol. As element content or an attribute value it renders as its bare name (Ruby's Symbol#to_s), then XML-escaped like a string.
type Value ¶
type Value = any
Value is any Ruby value the builder accepts as element content, text, or an attribute value. The rbgo host maps its own object.Value to and from this small, fixed set; the emitter itself never touches a Ruby runtime.
The concrete shapes that carry meaning are:
nil -> no content (self-closing tag) / a nil attribute value string -> text, XML-escaped Symbol -> a bare name (Ruby to_s), XML-escaped like a string bool -> "true" / "false" int, int64, ... -> decimal integer *big.Int -> arbitrary-precision integer float64, float32 -> Ruby Float#to_s Raw -> pre-formatted markup inserted verbatim (the `<<` path)
Any other Go value is stringified with valueToString's fallback (Sprint), so the host can hand through a type it has already rendered.
type XmlMarkup ¶
type XmlMarkup struct {
// contains filtered or unexported fields
}
XmlMarkup is a Builder::XmlMarkup emitter. Create one with New; write to it with the element and special methods; read the accumulated document with XmlMarkup.Target. It is not safe for concurrent use.
func New ¶
New creates an XmlMarkup emitter. With no options it behaves like Builder::XmlMarkup.new: no indentation, double-quoted attributes, UTF-8.
func (*XmlMarkup) Append ¶
Append inserts markup verbatim, with no escaping — Builder's `xml << str`.
func (*XmlMarkup) Block ¶
Block emits an element whose body is produced by fn — the block form, xml.name { … }. Attributes are optional.
func (*XmlMarkup) CData ¶
CData wraps text in a CDATA section — Builder's cdata!. A literal "]]>" in the text is split as "]]]]><![CDATA[>" so it cannot terminate the section early, exactly as the gem does. The text itself is not escaped.
func (*XmlMarkup) Comment ¶
Comment emits an XML comment — Builder's comment!. The text is not escaped (the gem does not escape comment bodies).
func (*XmlMarkup) Declare ¶
Declare emits a markup declaration such as a DOCTYPE — Builder's declare!. Each arg is emitted per its type: a Symbol (an unquoted identifier, e.g. Sym("html")) prints bare, a string prints double-quoted, and a func (func() or func(*XmlMarkup)) is the internal-subset block, emitted between " [" and "]" with its body nested one level deeper. Other values print double-quoted via to_s.
func (*XmlMarkup) Element ¶
Element is a typed convenience over [Tag] for the frequent name+attrs+content shape. A nil content self-closes the tag; a non-nil content (including "") is emitted as escaped text.
func (*XmlMarkup) Instruct ¶
Instruct emits a processing instruction — Builder's instruct!. Called with no directive it emits the XML declaration <?xml version="1.0" encoding="UTF-8"?>; callers may override version/encoding/standalone (and add more attrs) via opts. A non-"xml" directive emits <?directive …?> with the given attributes.
func (*XmlMarkup) NS ¶
NS is Builder's namespace shorthand xml.tag!(:ns, :name, …): it joins the namespace prefix and local name with a colon, then behaves like [Tag].
func (*XmlMarkup) Tag ¶
Tag emits an element, the general form equivalent to Ruby's xml.tag!(name, …) (and to what method_missing dispatches to for xml.<name>(…)). Arguments after the name are interpreted like Builder does:
- an Attrs (or a lone Attr) supplies attributes; several are merged;
- a nil is ignored (Builder only records it under explicit-nil handling, which this emitter, like the gem's default, does not enable);
- a func(*XmlMarkup) or func() is the nested block; and
- anything else is text content (multiple are concatenated).
Mixing a text argument with a block panics with the same message MRI raises (ArgumentError: "XmlMarkup cannot mix a text argument with a block"). With neither text nor block the tag self-closes (<name/>); an empty string counts as text, so xml.Tag("a", "") emits <a></a>, matching the gem.
The rbgo binding calls Tag with the element name taken from the intercepted Ruby method_missing symbol, so element naming comes straight from Ruby.
