blob: 02f9becfa290c4fd5116ae6948d6d4eeb8c36198 [file]
package text
fun appendableString(fn: Appendable.() -> Unit) = StringBuilder().apply { fn() }.toString()
/** Appendable with default char-sequence functions. */
interface CharAppendable : Appendable {
override fun append(csq: CharSequence?) = apply {
(csq ?: "null").forEach { append(it) }
}
override fun append(csq: CharSequence?, start: Int, end: Int) = apply {
append(csq?.subSequence(start, end))
}
}
fun printAppendable(fn: Appendable.() -> Unit) {
object : CharAppendable {
override fun append(csq: CharSequence?) = apply {
print(csq)
}
override fun append(c: Char) = apply {
print(c)
}
}.fn()
}
fun Appendable.appendIndented(fn: Appendable.() -> Unit) = also { appendable ->
object : CharAppendable {
var isIndentStart = false
override fun append(char: Char) = apply {
if (char == '\n') {
isIndentStart = true
} else if (isIndentStart) {
appendable.append(" ")
isIndentStart = false
}
appendable.append(char)
}
}.fn()
}
/** Appendable which pads with spaces or truncates to the given size. */
fun Appendable.appendFixedSize(size: Int, fn: Appendable.() -> Unit) = also { appendable ->
object : CharAppendable {
var remaining = size
override fun append(char: Char) = apply {
if (remaining > 0) {
appendable.append(char)
remaining--
}
}
fun pad() {
repeat(remaining) {
appendable.append(' ')
}
}
}.apply { fn() }.pad()
}
/** Appendable which appends ISO-control characters as dot '.' */
fun Appendable.appendNonISOControl(fn: Appendable.() -> Unit) = also { appendable ->
object : CharAppendable {
override fun append(char: Char) = apply {
appendable.append(char.takeIf { !it.isISOControl() } ?: '.')
}
}.fn()
}