summaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/blog/md/ext/NoteBlocks.kt
blob: a1f977f54fdbd1a8c3e6d7318bc327d787e56217 (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.ext

import moe.nea.blog.gen.DefHtmlFragmentGenerator
import moe.nea.blog.gen.HtmlDsl
import moe.nea.blog.gen.MD2HtmlGenerator
import moe.nea.blog.md.BlockParser
import moe.nea.blog.md.MarkdownBlock
import moe.nea.blog.md.MarkdownParser
import moe.nea.blog.util.indent
import moe.nea.blog.util.indentSize
import java.io.PrintStream

data class NoteBlock(val noteType: String, val child: MarkdownBlock) : MarkdownBlock {
	override fun debugFormat(indent: Int, printStream: PrintStream) {
		printStream.indent(indent)
		printStream.println("<note type=\"$noteType\">")

		child.debugFormat(indent + 2, printStream)

		printStream.indent(indent)
		printStream.println("</note>")
	}
}

object NoteBlockGenerator : DefHtmlFragmentGenerator<NoteBlock>() {
	override fun HtmlDsl.makeHtml(generator: MD2HtmlGenerator, node: NoteBlock) {
		element("div", mapOf("class" to "note-${node.noteType}"), generator.generateHtml(node.child))
	}
}

object NoteBlockParser : BlockParser {
	override fun detect(line: String): Boolean {
		return line.startsWith("!!!")
	}

	override fun parse(parser: MarkdownParser): MarkdownBlock {
		val line = parser.consumeLine()!!
		val noteType = line.substring(3).trim()
		while ((parser.peekLine() ?: error("Unterminated !!! note")).isBlank()) {
			parser.consumeLine()
		}
		val indent = parser.peekLine()!!.indentSize()!!
		require(indent > 0) { "!!! note not indented" }
		parser.pushIndent(indent)
		val list = mutableListOf<MarkdownBlock>()
		while (true) {
			val block = parser.readChildBlock() ?: break
			list.add(block)
		}
		parser.popIndent()
		return NoteBlock(noteType, parser.mergeBlocks(list))
	}

	override val prio: Int
		get() = 10

}