summaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/blog/md/ListParser.kt
blob: 8175c1ab5457bee4dff3f4c7979bfa160fdc8fa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package moe.nea.blog.md

import moe.nea.blog.util.indentSize

object ListParser : BlockParser {
    override fun detect(line: String): Boolean {
        return line.matches(" *[*+-] .*".toRegex())
    }

    override fun parse(parser: MarkdownParser): MarkdownBlock {
        val line = parser.peekLine()!!
        val indentSize = line.indentSize()!!
        val prefix = line.substring(0, indentSize + 2)
        var bypassLineIndex = parser.getLineIndex()
        val indentDepth = parser.getIndent()
        val processor = LinePreProcessor.whileIgnoringFirst(indentDepth) { lineIndex, line ->
            if (line.startsWith(prefix)) {
                if (bypassLineIndex == lineIndex) {
                    " ".repeat(indentSize + 2) + line.substring(indentSize + 2)
                } else {
                    null
                }
            } else {
                line
            }
        }
        parser.pushPreProcessor(processor)
        parser.pushIndent(indentSize + 2)

        val listItems = mutableListOf<MarkdownBlock>()

        while (true) {
            bypassLineIndex = parser.getLineIndex()
            val elements = mutableListOf<MarkdownBlock>()
            while (true) {
                val child = parser.readChildBlock() ?: break
                elements.add(child)
            }
            parser.popPreProcessor()
            parser.popIndent()
            val realLine = parser.peekLine()
            parser.pushPreProcessor(processor)
            parser.pushIndent(indentSize + 2)
            listItems.add(parser.mergeBlocks(elements))
            if (realLine == null || !realLine.startsWith(prefix)) {
                break
            }
        }

        parser.popIndent()
        parser.popPreProcessor()
        return MDList(listItems)
    }

    override val prio: Int
        get() = 10
}