generated from rnentjes/kotlin-server-web-empty
Add tests for nested unordered and checkbox lists, extend parser for indentation handling, and bump version to 2.0.0
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -45,3 +45,4 @@ bin/
|
||||
.kotlin
|
||||
kotlin-js-store
|
||||
gradle.properties
|
||||
.idea
|
||||
|
||||
@@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "nl.astraeus"
|
||||
version = "1.1.0"
|
||||
version = "2.0.0"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
package nl.astraeus.markdown.parser
|
||||
|
||||
data class ListItem(
|
||||
val text: String,
|
||||
val order: Int,
|
||||
val indentation: Int = 0
|
||||
)
|
||||
|
||||
data class CheckboxItem(
|
||||
val line: Int,
|
||||
val checked: Boolean,
|
||||
val text: String,
|
||||
val indentation: Int = 0
|
||||
)
|
||||
|
||||
sealed class MarkdownPart {
|
||||
@@ -66,7 +73,7 @@ sealed class MarkdownPart {
|
||||
) : MarkdownPart()
|
||||
|
||||
data class UnorderedList(
|
||||
val lines: List<Pair<Int, String>>,
|
||||
val lines: List<ListItem>,
|
||||
) : MarkdownPart()
|
||||
|
||||
data class CheckboxList(
|
||||
@@ -74,7 +81,7 @@ sealed class MarkdownPart {
|
||||
) : MarkdownPart()
|
||||
|
||||
data class OrderedList(
|
||||
val lines: List<String>,
|
||||
val lines: List<ListItem>,
|
||||
) : MarkdownPart()
|
||||
|
||||
data class CodeBlock(
|
||||
|
||||
@@ -11,17 +11,22 @@ enum class MarkdownType {
|
||||
}
|
||||
|
||||
fun markdown(text: String): List<MarkdownPart> {
|
||||
val lines = text.lines()
|
||||
val lines: MutableList<String> = text.lines().toMutableList()
|
||||
val parts = mutableListOf<MarkdownPart>()
|
||||
var language = ""
|
||||
var type = MarkdownType.PARAGRAPH
|
||||
var listIndex = 1
|
||||
var checkboxLine = 0
|
||||
var indentation = 0
|
||||
|
||||
var index = 0
|
||||
val buffer = StringBuilder()
|
||||
var checkboxList = mutableListOf<CheckboxItem>()
|
||||
|
||||
if (!lines.isEmpty() && lines.last().isNotEmpty()) {
|
||||
lines.add("")
|
||||
}
|
||||
|
||||
fun parseBuffer() {
|
||||
if (buffer.isNotBlank()) {
|
||||
parts.addAll(handleBuffer(type, buffer.toString(), language))
|
||||
@@ -46,7 +51,7 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
|| line.startsWith("#.")
|
||||
) {
|
||||
buffer.append("\n")
|
||||
buffer.append(line.substring(2))
|
||||
buffer.append(rawLine)
|
||||
} else {
|
||||
buffer.append(" ")
|
||||
buffer.append(line)
|
||||
@@ -56,7 +61,7 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
type == MarkdownType.CHECKBOX_LIST -> {
|
||||
if (line.isBlank()) {
|
||||
if (buffer.isNotBlank()) {
|
||||
addCheckbox(checkboxList, checkboxLine, buffer)
|
||||
addCheckbox(checkboxList, checkboxLine, buffer, indentation)
|
||||
}
|
||||
parts.add(MarkdownPart.CheckboxList(checkboxList))
|
||||
checkboxList = mutableListOf()
|
||||
@@ -64,10 +69,11 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
continue
|
||||
} else if (line.startsWith("- [ ]") || line.startsWith("- [x]")) {
|
||||
if (buffer.isNotBlank()) {
|
||||
addCheckbox(checkboxList, checkboxLine, buffer)
|
||||
addCheckbox(checkboxList, checkboxLine, buffer, indentation)
|
||||
}
|
||||
checkboxLine = index
|
||||
buffer.append(line)
|
||||
indentation = rawLine.countSpaces()
|
||||
} else {
|
||||
buffer.append(" ")
|
||||
buffer.append(line)
|
||||
@@ -133,7 +139,7 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
parseBuffer()
|
||||
type = MarkdownType.ORDERED_LIST
|
||||
listIndex = 2
|
||||
buffer.append(line.substring(2))
|
||||
buffer.append(rawLine)
|
||||
}
|
||||
|
||||
line.startsWith("- [ ]") || line.startsWith("- [x]") -> {
|
||||
@@ -141,6 +147,7 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
type = MarkdownType.CHECKBOX_LIST
|
||||
checkboxLine = index
|
||||
buffer.append(line)
|
||||
indentation = rawLine.countSpaces()
|
||||
}
|
||||
|
||||
line.startsWith("- ") || line.startsWith("* ") -> {
|
||||
@@ -189,14 +196,14 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
index++
|
||||
}
|
||||
|
||||
if (type == MarkdownType.CHECKBOX_LIST) {
|
||||
/* if (type == MarkdownType.CHECKBOX_LIST) {
|
||||
if (buffer.isNotBlank()) {
|
||||
addCheckbox(checkboxList, checkboxLine, buffer)
|
||||
addCheckbox(checkboxList, checkboxLine, buffer, indentation)
|
||||
}
|
||||
parts.add(MarkdownPart.CheckboxList(checkboxList))
|
||||
} else {
|
||||
parseBuffer()
|
||||
}
|
||||
}*/
|
||||
|
||||
return parts
|
||||
}
|
||||
@@ -204,14 +211,16 @@ fun markdown(text: String): List<MarkdownPart> {
|
||||
private fun addCheckbox(
|
||||
checkboxList: MutableList<CheckboxItem>,
|
||||
index: Int,
|
||||
buffer: StringBuilder
|
||||
buffer: StringBuilder,
|
||||
indentation: Int = 0
|
||||
) {
|
||||
if (buffer.length >= 5) {
|
||||
checkboxList.add(
|
||||
CheckboxItem(
|
||||
index,
|
||||
buffer.startsWith("- [x]"),
|
||||
buffer.substring(5).trim()
|
||||
buffer.substring(5).trim(),
|
||||
indentation
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@@ -248,17 +257,20 @@ private fun handleBuffer(
|
||||
}
|
||||
|
||||
MarkdownType.ORDERED_LIST -> {
|
||||
listOf(MarkdownPart.OrderedList(text.lines()))
|
||||
val lines = text.lines()
|
||||
val list = mutableListOf<ListItem>()
|
||||
|
||||
parseList(lines, list)
|
||||
|
||||
listOf(MarkdownPart.OrderedList(list))
|
||||
}
|
||||
|
||||
MarkdownType.UNORDERED_LIST -> {
|
||||
val lines = text.lines()
|
||||
val list = mutableListOf<Pair<Int, String>>()
|
||||
val list = mutableListOf<ListItem>()
|
||||
|
||||
parseList(lines, list)
|
||||
|
||||
for (line in lines) {
|
||||
val indent: Int = line.countSpaces()
|
||||
list.add((indent / 2) to line.substring(indent + 2))
|
||||
}
|
||||
listOf(MarkdownPart.UnorderedList(list))
|
||||
}
|
||||
|
||||
@@ -270,3 +282,23 @@ private fun handleBuffer(
|
||||
parseTable(text)
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseList(
|
||||
lines: List<String>,
|
||||
list: MutableList<ListItem>
|
||||
) {
|
||||
val orderMap = mutableMapOf<Int, Int>()
|
||||
|
||||
for (line in lines) {
|
||||
val indent: Int = line.countSpaces()
|
||||
val order = orderMap.getOrPut(indent) { 1 }
|
||||
list.add(
|
||||
ListItem(
|
||||
line.substring(indent + 2),
|
||||
order,
|
||||
indent
|
||||
)
|
||||
)
|
||||
orderMap[indent] = order + 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,22 @@ class ParseTest {
|
||||
printMarkdownParts(md)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUnorderedList2() {
|
||||
val input = """
|
||||
- First
|
||||
- Second
|
||||
- 2.1
|
||||
- 2.1.1
|
||||
- 2.1.1
|
||||
- 3
|
||||
""".trimIndent()
|
||||
|
||||
val md = markdown(input)
|
||||
|
||||
printMarkdownParts(md)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUnorderedListAlternative() {
|
||||
val input = """
|
||||
@@ -115,6 +131,9 @@ class ParseTest {
|
||||
More text
|
||||
-. Second
|
||||
More text
|
||||
-. Sub 1
|
||||
-. Sub 2
|
||||
-. Third
|
||||
|
||||
Another paragraph
|
||||
""".trimIndent()
|
||||
@@ -204,6 +223,33 @@ class ParseTest {
|
||||
printMarkdownParts(md)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckboxList4() {
|
||||
val input = """
|
||||
Dit is een text
|
||||
|
||||
- [ ] Not checked,
|
||||
with some more text here
|
||||
- [x] Checked!
|
||||
- [x] Checked,
|
||||
text it!
|
||||
|
||||
Nog 1:
|
||||
|
||||
- [ ] Not checked,
|
||||
with some more text here
|
||||
- [x] Checked!
|
||||
- [x] Checked,
|
||||
text it!
|
||||
|
||||
Meer text
|
||||
""".trimIndent()
|
||||
|
||||
val md = markdown(input)
|
||||
|
||||
printMarkdownParts(md)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testCheckboxListError() {
|
||||
|
||||
Reference in New Issue
Block a user