I made a code to draw a vector graphic image using HTML Tag <svg>
but I'am stuck while writing a code that received multiple shapes at once through the list.
abstract class S(val x: Int, val y: Int, val w: Int, val h: Int,
val style: String = "background-color:lightgray") : Renderable {
abstract fun toDef(): String
override fun render(notebook: Notebook) = HTML("""
<svg width="${w}" height="${h}" style="${style}">
${toDef()}
</svg>
""")
}
// Rectangle
class R(x: Int, y: Int, val width: Int, val height: Int, val fill: String
) : S(x, y, x width, y height) {
override fun toDef() : String =
"""<rect x=${x} y=${y} width=${width} height=${height} fill=${fill} style="opacity: 0.5"/>"""
}
// Circle
class C(val cx: Int, val cy: Int, val r: Int, val fill: String
) : S(cx-r, cy-r, cx r, cy r) {
override fun toDef() : String =
"""<circle cx=${cx} cy=${cy} r=${r} fill=${fill} style="opacity:0.5"/>"""
}
S is an abstract class that basically has information on the rectangular area occupied by the shape.
R and C are classes corresponding to the rectangular and circular tags of SVG, respectively.
And below code is a code that allows to receive a list(various R and C) and express them in a rectangular area through the toDef() method.
class S_Group(val obj: List<S>
) : S(0, 0, 200, 200) {
override fun toDef() = "" // what should i use?
}
At first, I thought I could use for loop and get() method of the list, but I realized that toDef() is a string action, so I couldn't do this.
Next, I was wondering if I could use Lamda Expression like below, but it didn't work.
"${o(::toDef())}"
get Error Message:
This syntax is reserved for future use; to call a reference, enclose it in parentheses: (foo::bar)(args)
I couldn't think of any other ideas, so I referred to several questions from stackoverflow and read Kotlin Docs, but I still don't know.
Is there any idea to fill toDef() method of S_Group?
Input and Output Exam:
Input:
val R1 = R(10,20,80,100,"green")
val C1 = C(0,30,30,"red")S_Group( listOf(R1, C1) )
Output what i want:
Present Output:
CodePudding user response:
You have to somehow combine the values of your list item's toDef
results, but the way you combine them is up to you.
For instance, you can use joinToString this way:
class S_Group(val obj: List<S>) : S(0, 0, 200, 200) {
override fun toDef() = obj.joinToString { it.toDef() }
}
By default, joinToString
called like this will create a string by concatenating all the results of toDef()
of each element, and insert ,
between each. You can further customize the separator, prefix, and suffix by using more parameters of joinToString
.
EDIT: I just realized you're generating HTML tags, so you probably want to set the separator to ""
instead of the default ", "