kotlinx.html
kotlinx.html copied to clipboard
How to print content of a html extension function
❔
I often need to use html functions (fun FlowContent.foo() {) without a parent node, I just want to get the html as text. This is what I came up with, just wondering if there was a standard/cleaner way of doing this.
import kotlinx.html.*
import kotlinx.html.stream.HTMLStreamBuilder
import kotlinx.html.stream.createHTML
fun main() {
println(createHTML(false).span { foo() }) // <span><div>asdf</div></span>
println(getHTML(false) { foo() }) // <div>asdf</div>
}
fun FlowContent.foo() {
div { +"asdf" }
}
fun getHTML(
prettyPrint: Boolean = true,
fn: CommonAttributeGroupFacadeFlowInteractivePhrasingContent.() -> Unit
): String {
val c = Fakesumer(prettyPrint)
return object : HTMLTag("FAKE", c, emptyMap, null, true, false),
CommonAttributeGroupFacadeFlowInteractivePhrasingContent {}.visitAndFinalize(c, fn).toString()
}
class Fakesumer(
prettyPrint: Boolean = true,
val consumer: HTMLStreamBuilder<StringBuilder> = HTMLStreamBuilder(
StringBuilder(1234),
prettyPrint,
false
)
) : TagConsumer<StringBuilder> by consumer {
var firstTag: Tag? = null
override fun onTagStart(tag: Tag) {
if (firstTag == null) {
firstTag = tag
return
}
consumer.onTagStart(tag)
}
override fun onTagEnd(tag: Tag) {
if (tag === firstTag) return
consumer.onTagStart(tag)
}
}
Also, whats the receiver for a html extension function that can be used in any context?
Does this not work? https://github.com/Kotlin/kotlinx.html/blob/c862d78f1c80a6f40bdaf05f25aa058ad4537358/src/commonMain/kotlin/stream.kt#L139
I don't understand, I want to be able to create an html extension function but also use it independently, this is the only way I can see.
This works for me:
val htmlFragment = createHTML()
.filter { if (it.tagName in listOf("html", "body")) SKIP else PASS }
.html {
body {
builder()
}
}
The builder is defined as FlowContent.() -> Unit, but anything that you can put in a body should work.
It's based on the interceptor example in the Wiki