public extension PureXML.Emitting { /// Explicit emitter options. The default is pretty-printed output with /// two-space indentation and a self-closing tag for empty elements, and no /// XML declaration. /// Which quote character delimits attribute values in the output. enum QuoteStyle: Equatable, Hashable, Sendable { case double case single var character: Character { self == .double ? "\"" : "'" } } /// How much to escape in text content beyond the markup-significant /// characters `&`, `<`, and `>`. enum TextEscaping: Equatable, Hashable, Sendable { /// Escape only `&`, `<`, and `>` (the safe default). case standard /// Additionally escape a carriage return as ` `, so it survives the /// parser's end-of-line normalization (which folds a literal `\r` or /// `\r\n` to `\n`) and the text round-trips byte for byte. case roundTrip var escapesCarriageReturn: Bool { self == .roundTrip } } struct Options: Equatable, Hashable, Sendable { /// Whether to indent nested elements onto their own lines. public var prettyPrint: Bool /// The indentation unit used when ``prettyPrint`` is enabled. public var indent: String /// The quote character that delimits attribute values. public var attributeQuote: QuoteStyle /// The line terminator inserted by pretty-printing and after the /// declaration. A line feed by default; set to `\r\n` for CRLF output. public var lineEnding: String /// Whether childless elements collapse to ``. public var selfCloseEmptyElements: Bool /// Whether to emit a CDATA section's content as escaped text rather than as /// a `` section. public var cdataAsText: Bool /// How much to escape in text content beyond `&`, `<`, and `>`. The default /// is the minimal-safe set; ``TextEscaping/roundTrip`` also escapes a /// carriage return so it is preserved across a parse. public var textEscaping: TextEscaping /// Whether to escape every non-ASCII character as a numeric character /// reference, so the output is pure ASCII (libxml2's character-reference /// encoding). public var asciiOnly: Bool /// Whether to emit an `` declaration (libxml2 emits one by /// default when saving a document; PureXML defaults to off for fragments). public var includeXMLDeclaration: Bool /// The version written in the declaration. public var xmlVersion: String /// The encoding name written in the declaration, or nil to omit it. public var encodingName: String? /// The `standalone` flag written in the declaration, or nil to omit it. public var standalone: Bool? public init( prettyPrint: Bool = true, indent: String = " ", attributeQuote: QuoteStyle = .double, lineEnding: String = "\n", selfCloseEmptyElements: Bool = true, cdataAsText: Bool = false, textEscaping: TextEscaping = .standard, asciiOnly: Bool = false, includeXMLDeclaration: Bool = false, xmlVersion: String = "1.0", encodingName: String? = "UTF-8", standalone: Bool? = nil, ) { self.prettyPrint = prettyPrint self.indent = indent self.attributeQuote = attributeQuote self.lineEnding = lineEnding self.selfCloseEmptyElements = selfCloseEmptyElements self.cdataAsText = cdataAsText self.textEscaping = textEscaping self.asciiOnly = asciiOnly self.includeXMLDeclaration = includeXMLDeclaration self.xmlVersion = xmlVersion self.encodingName = encodingName self.standalone = standalone } /// Pretty-printed output with two-space indentation. public static let `default` = Options() /// Single-line output with no inserted whitespace. public static let compact = Options(prettyPrint: false) /// The `` declaration string, or nil when not requested. var xmlDeclaration: String? { guard includeXMLDeclaration else { return nil } var declaration = "" } } }