Coverage Summary for Class: FootnoteBlockParser (io.heapy.kotmark.ext.footnotes.internal)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| FootnoteBlockParser |
100%
(6/6)
|
100%
(4/4)
|
100%
(13/13)
|
100%
(56/56)
|
| FootnoteBlockParser$Factory |
100%
(2/2)
|
73.1%
(19/26)
|
96.2%
(25/26)
|
98.2%
(109/111)
|
| Total |
100%
(8/8)
|
76.7%
(23/30)
|
97.4%
(38/39)
|
98.8%
(165/167)
|
package io.heapy.kotmark.ext.footnotes.internal
import io.heapy.kotmark.ext.footnotes.FootnoteDefinition
import io.heapy.kotmark.node.Block
import io.heapy.kotmark.node.DefinitionMap
import io.heapy.kotmark.parser.block.AbstractBlockParser
import io.heapy.kotmark.parser.block.BlockContinue
import io.heapy.kotmark.parser.block.BlockParserFactory
import io.heapy.kotmark.parser.block.BlockStart
import io.heapy.kotmark.parser.block.MatchedBlockParser
import io.heapy.kotmark.parser.block.ParserState
import io.heapy.kotmark.text.Characters
class FootnoteBlockParser(
label: String,
) : AbstractBlockParser() {
private val definition = FootnoteDefinition(label)
override val block: Block
get() = definition
override fun isContainer(): Boolean = true
override fun canContain(childBlock: Block): Boolean = true
override fun tryContinue(parserState: ParserState): BlockContinue? =
when {
parserState.indent >= 4 -> BlockContinue.AtColumn(4)
parserState.isBlank -> BlockContinue.AtIndex(parserState.index)
else -> null
}
override val definitions: List<DefinitionMap<*>>
get() =
listOf(
DefinitionMap(FootnoteDefinition::class).apply {
putIfAbsent(definition.label, definition)
},
)
class Factory : BlockParserFactory {
override fun tryStart(
state: ParserState,
matchedBlockParser: MatchedBlockParser,
): BlockStart? {
if (state.indent >= 4) {
return BlockStart.none()
}
var index = state.nextNonSpaceIndex
val content = state.line.content
if (index >= content.length || content[index] != '[' || index + 1 >= content.length) {
return BlockStart.none()
}
index++
if (content[index] != '^' || index + 1 >= content.length) {
return BlockStart.none()
}
index++
val labelStart = index
while (index < content.length) {
when (content[index]) {
']' ->
if (
index > labelStart &&
index + 1 < content.length &&
content[index + 1] == ':'
) {
val label = content.subSequence(labelStart, index).toString()
val afterSpaces =
Characters.skipSpaceTab(content, index + 2, content.length)
return BlockStart.of(FootnoteBlockParser(label)).atIndex(afterSpaces)
} else {
return BlockStart.none()
}
' ', '\r', '\n', '\u0000', '\t' -> return BlockStart.none()
}
index++
}
return BlockStart.none()
}
}
}