質問編集履歴

1

自己解決時に利用したコードを記載いたしました。

2020/04/30 00:10

投稿

Liao
Liao

スコア9

test CHANGED
File without changes
test CHANGED
@@ -135,3 +135,207 @@
135
135
  Kotlin version: 1.3.72
136
136
 
137
137
  Android Studio を使用しています。
138
+
139
+
140
+
141
+ ###自己解決時に参考にしたコード
142
+
143
+ ```Kotlin
144
+
145
+ interface Element {
146
+
147
+ fun render(builder: StringBuilder, indent: String)
148
+
149
+ }
150
+
151
+
152
+
153
+ class TextElement(private val text: String) : Element {
154
+
155
+ override fun render(builder: StringBuilder, indent: String) {
156
+
157
+ builder.append("$indent$text\n")
158
+
159
+ }
160
+
161
+ }
162
+
163
+
164
+
165
+ @DslMarker
166
+
167
+ annotation class HtmlTagMarker
168
+
169
+
170
+
171
+ @HtmlTagMarker
172
+
173
+ abstract class Tag(val name: String) : Element {
174
+
175
+ val children = arrayListOf<Element>()
176
+
177
+ val attributes = hashMapOf<String, String>()
178
+
179
+
180
+
181
+ protected fun <T : Element> initTag(tag: T, init: T.() -> Unit): T {
182
+
183
+ tag.init()
184
+
185
+ children.add(tag)
186
+
187
+ return tag
188
+
189
+ }
190
+
191
+ override fun render(builder: StringBuilder, indent: String) {
192
+
193
+ builder.append("$indent<$name${renderAttributes()}>\n")
194
+
195
+ for (c in children) {
196
+
197
+ c.render(builder, "$indent ")
198
+
199
+ }
200
+
201
+ builder.append("$indent</$name>\n")
202
+
203
+ }
204
+
205
+
206
+
207
+ private fun renderAttributes(): String {
208
+
209
+ val builder = StringBuilder()
210
+
211
+ for ((attr, value) in attributes) {
212
+
213
+ builder.append(" $attr=\"$value\"")
214
+
215
+ }
216
+
217
+ return builder.toString()
218
+
219
+ }
220
+
221
+ override fun toString(): String {
222
+
223
+ val builder = StringBuilder()
224
+
225
+ render(builder, "")
226
+
227
+ return builder.toString()
228
+
229
+ }
230
+
231
+ }
232
+
233
+ abstract class TagWithText(name: String) : Tag(name) {
234
+
235
+ operator fun String.unaryPlus() {
236
+
237
+ children.add(TextElement(this))
238
+
239
+ }
240
+
241
+ }
242
+
243
+
244
+
245
+ class HTML : TagWithText("html") {
246
+
247
+ fun head(init: Head.() -> Unit) = initTag(Head(), init)
248
+
249
+
250
+
251
+ fun body(init: Body.() -> Unit) = initTag(Body(), init)
252
+
253
+ }
254
+
255
+
256
+
257
+ class Head : TagWithText("head") {
258
+
259
+ fun title(init: Title.() -> Unit) = initTag(Title(), init)
260
+
261
+ }
262
+
263
+
264
+
265
+ class Title : TagWithText("title")
266
+
267
+
268
+
269
+ abstract class BodyTag(name: String) : TagWithText(name) {
270
+
271
+ fun b(init: B.() -> Unit) = initTag(B(), init)
272
+
273
+ fun p(init: P.() -> Unit) = initTag(P(), init)
274
+
275
+ fun h1(init: H1.() -> Unit) = initTag(H1(), init)
276
+
277
+ fun a(href: String, init: A.() -> Unit) {
278
+
279
+ val a = initTag(A(), init)
280
+
281
+ a.href = href
282
+
283
+ }
284
+
285
+ }
286
+
287
+ class Body : BodyTag("body")
288
+
289
+ class B : BodyTag("b")
290
+
291
+ class P : BodyTag("p")
292
+
293
+ class H1 : BodyTag("h1")
294
+
295
+
296
+
297
+ class A : BodyTag("a") {
298
+
299
+ var href: String
300
+
301
+ get() = attributes["href"]!!
302
+
303
+ set(value) {
304
+
305
+ attributes["href"] = value
306
+
307
+ }
308
+
309
+ }
310
+
311
+
312
+
313
+ fun html(init: HTML.() -> Unit): HTML {
314
+
315
+ val html = HTML()
316
+
317
+ html.init()
318
+
319
+ return html
320
+
321
+ }
322
+
323
+ ```
324
+
325
+ このコードの
326
+
327
+ ```
328
+
329
+ abstract class TagWithText(name: String) : Tag(name) {
330
+
331
+ operator fun String.unaryPlus() {
332
+
333
+ children.add(TextElement(this))
334
+
335
+ }
336
+
337
+ }
338
+
339
+ ```
340
+
341
+ という部分を参考にいたしました。