118 lines
2.7 KiB
Kotlin
Vendored
118 lines
2.7 KiB
Kotlin
Vendored
package html
|
|
|
|
import java.util.*
|
|
|
|
interface Factory<T> {
|
|
fun create() : T
|
|
}
|
|
|
|
interface Element
|
|
|
|
class TextElement(val text : String) : Element
|
|
|
|
abstract class Tag(val name : String) : Element {
|
|
val children = ArrayList<Element>()
|
|
val attributes = HashMap<String, String>()
|
|
|
|
protected fun <T : Element> initTag(<warning>init</warning> : T.() -> Unit) : T
|
|
{
|
|
val tag = <error>T</error>.<error>create</error>()
|
|
<error>tag</error>.<error>init</error>()
|
|
children.add(<error>tag</error>)
|
|
return <error>tag</error>
|
|
}
|
|
}
|
|
|
|
abstract class TagWithText(name : String) : Tag(name) {
|
|
operator fun String.unaryPlus() {
|
|
children.add(TextElement(this))
|
|
}
|
|
}
|
|
|
|
class HTML() : TagWithText("html") {
|
|
companion object : Factory<HTML> {
|
|
override fun create() = HTML()
|
|
}
|
|
|
|
fun head(init : Head.() -> Unit) = initTag<Head>(init)
|
|
|
|
fun body(init : Body.() -> Unit) = initTag<Body>(init)
|
|
}
|
|
|
|
class Head() : TagWithText("head") {
|
|
companion object : Factory<Head> {
|
|
override fun create() = Head()
|
|
}
|
|
|
|
fun title(init : Title.() -> Unit) = initTag<Title>(init)
|
|
}
|
|
|
|
class Title() : TagWithText("title")
|
|
|
|
abstract class BodyTag(name : String) : TagWithText(name) {
|
|
}
|
|
|
|
class Body() : BodyTag("body") {
|
|
companion object : Factory<Body> {
|
|
override fun create() = Body()
|
|
}
|
|
|
|
fun b(init : B.() -> Unit) = initTag<B>(init)
|
|
fun p(init : P.() -> Unit) = initTag<P>(init)
|
|
fun h1(init : H1.() -> Unit) = initTag<H1>(init)
|
|
fun a(href : String, init : A.() -> Unit) {
|
|
val a = initTag<A>(init)
|
|
a.href = href
|
|
}
|
|
}
|
|
|
|
class B() : BodyTag("b")
|
|
class P() : BodyTag("p")
|
|
class H1() : BodyTag("h1")
|
|
class A() : BodyTag("a") {
|
|
var href : String?
|
|
get() = attributes["href"]
|
|
set(value) {
|
|
if (value != null)
|
|
attributes["href"] = value
|
|
}
|
|
}
|
|
|
|
operator fun MutableMap<String, String>.set(key : String, value : String) = this.put(key, value)
|
|
|
|
fun html(init : HTML.() -> Unit) : HTML {
|
|
val html = HTML()
|
|
html.init()
|
|
return html
|
|
}
|
|
|
|
fun result(args : Array<String>) =
|
|
html {
|
|
head {
|
|
title {+"XML encoding with Groovy"}
|
|
}
|
|
body {
|
|
h1 {+"XML encoding with Groovy"}
|
|
p {+"this format can be used as an alternative markup to XML"}
|
|
|
|
// an element with attributes and text content
|
|
a(href = "https://groovy.codehaus.org") {+"Groovy"}
|
|
|
|
// mixed content
|
|
p {
|
|
+"This is some"
|
|
b {+"mixed"}
|
|
+"text. For more see the"
|
|
a(href = "https://groovy.codehaus.org") {+"Groovy"}
|
|
+"project"
|
|
}
|
|
p {+"some text"}
|
|
|
|
// content generated by
|
|
p {
|
|
for (arg in args)
|
|
+arg
|
|
}
|
|
}
|
|
}
|