commonMain.xml.XmlElement.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kanvas-jvm Show documentation
Show all versions of kanvas-jvm Show documentation
A collection of drawing/charting utilities
The newest version!
package com.juul.krayon.kanvas.xml
private const val INDENTATION_STEP = " "
internal class XmlElement(
val id: Id,
) {
constructor(id: String) : this(id.toId())
private val attributes = mutableMapOf()
private val contents = mutableListOf()
fun setAttribute(id: Id, value: EscapedString) = apply {
attributes[id] = value
}
fun setAttribute(id: String, value: String) = setAttribute(id.toId(), value.escape())
fun setAttribute(id: String, value: Double, formatter: NumberFormatter) = setAttribute(id, formatter(value))
fun setAttribute(id: String, value: Float, formatter: NumberFormatter) = setAttribute(id, formatter(value))
fun setAttribute(id: String, value: Int, formatter: NumberFormatter) = setAttribute(id, formatter(value))
fun setAttribute(id: String, value: Long, formatter: NumberFormatter) = setAttribute(id, formatter(value))
fun unsetAttribute(id: Id) = apply {
attributes.remove(id)
}
fun unsetAttribute(id: String) = unsetAttribute(id.toId())
fun addContent(content: Content) = apply {
this.contents += content
}
fun addContent(text: EscapedString) = addContent(Content.Text(text))
fun addContent(child: XmlElement) = addContent(Content.Child(child))
sealed class Content {
data class Child(val child: XmlElement) : Content()
data class Text(val text: EscapedString) : Content()
}
override fun toString(): String = toString(0)
private fun StringBuilder.indent(depth: Int) {
for (i in 0 until depth) {
append(INDENTATION_STEP)
}
}
private fun toString(depth: Int): String = buildString {
indent(depth)
append("<$id")
for (attribute in attributes) {
append(" ${attribute.key}=\"${attribute.value}\"")
}
if (contents.isEmpty()) {
append(" />")
} else {
append(">")
for (content in contents) {
appendLine()
when (content) {
is Content.Child -> append(content.child.toString(depth + 1))
is Content.Text -> {
indent(depth + 1)
append(content.text)
}
}
}
appendLine()
indent(depth)
append("$id>")
}
}
}