summaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/blog/md
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-03-24 16:08:58 +0100
committerLinnea Gräf <nea@nea.moe>2024-03-24 16:08:58 +0100
commit238dabfe06fade0cd9a2b0fc286bddc6a48151f6 (patch)
tree1d036a1f3141db0e6c8b587272a83c0d974f49b8 /src/main/kotlin/moe/nea/blog/md
parent4c0ac30dc82677b2b2db36d114b452fdea537a37 (diff)
downloadblog-infra-238dabfe06fade0cd9a2b0fc286bddc6a48151f6.tar.gz
blog-infra-238dabfe06fade0cd9a2b0fc286bddc6a48151f6.tar.bz2
blog-infra-238dabfe06fade0cd9a2b0fc286bddc6a48151f6.zip
Add generic inline parse loop support
Diffstat (limited to 'src/main/kotlin/moe/nea/blog/md')
-rw-r--r--src/main/kotlin/moe/nea/blog/md/ItalicsParser.kt31
-rw-r--r--src/main/kotlin/moe/nea/blog/md/MarkdownParser.kt32
2 files changed, 31 insertions, 32 deletions
diff --git a/src/main/kotlin/moe/nea/blog/md/ItalicsParser.kt b/src/main/kotlin/moe/nea/blog/md/ItalicsParser.kt
index d3c9d5d..9f60200 100644
--- a/src/main/kotlin/moe/nea/blog/md/ItalicsParser.kt
+++ b/src/main/kotlin/moe/nea/blog/md/ItalicsParser.kt
@@ -17,19 +17,10 @@ object ItalicsParser : InlineParser {
if (firstStarCount < 1 || firstStarCount > 3) error("Invalid italics/bold sequence")
- val isBold = firstStarCount >= 2
- val isItalics = (firstStarCount % 2) == 1
-
- val firstSequence = mutableListOf<MarkdownFormat>()
- var remainingText = text.substring(firstStarCount)
- var lastToken: MarkdownFormat = Begin() // TODO: dedicated begin token
- while (remainingText.isNotEmpty()) {
- val (element, next) = parser.parseInlineTextOnce(lastToken, remainingText)
- remainingText = next
- lastToken = element
- firstSequence.add(element)
- if (element !is Whitespace && next.startsWith("*")) break
- }
+ var (firstSequence, remainingText) = parser.parseInlineTextUntil(
+ text.substring(firstStarCount),
+ Begin()
+ ) { lookback, remaining -> lookback !is Whitespace && remaining.startsWith("*") } // TODO: free standing *
var secondStarCount = 0
while (secondStarCount in remainingText.indices) {
@@ -51,15 +42,11 @@ object ItalicsParser : InlineParser {
return Pair(firstElement, remainingText)
}
- val secondSequence = mutableListOf<MarkdownFormat>()
- lastToken = Begin()
- while (remainingText.isNotEmpty()) {
- val (element, next) = parser.parseInlineTextOnce(lastToken, remainingText)
- remainingText = next
- lastToken = element
- secondSequence.add(element)
- if (element !is Whitespace && next.startsWith("*")) break
+ // TODO: better begin
+ val (secondSequence, _remainingText) = parser.parseInlineTextUntil(remainingText, Begin()) { lookback, remaining ->
+ lookback !is Whitespace && remaining.startsWith("*")
}
+ remainingText = _remainingText
var thirdStarCount = 0
while (thirdStarCount in remainingText.indices) {
@@ -75,7 +62,7 @@ object ItalicsParser : InlineParser {
if (thirdStarCount != firstStarCount - secondStarCount) {
error("Invalid italics/bold sequence")
}
- var secondElement = parser.collapseInlineFormat(secondSequence, false)
+ val secondElement = parser.collapseInlineFormat(secondSequence, false)
var combined: MarkdownFormat = FormatSequence(firstElement, secondElement)
if (thirdStarCount == 1)
combined = Italics(combined)
diff --git a/src/main/kotlin/moe/nea/blog/md/MarkdownParser.kt b/src/main/kotlin/moe/nea/blog/md/MarkdownParser.kt
index 144eeda..19a4e99 100644
--- a/src/main/kotlin/moe/nea/blog/md/MarkdownParser.kt
+++ b/src/main/kotlin/moe/nea/blog/md/MarkdownParser.kt
@@ -50,6 +50,25 @@ class MarkdownParser(source: String) {
return line.substring(blockIndents)
}
+ fun parseInlineTextUntil(
+ text: String,
+ initialLookback: MarkdownFormat,
+ breakout: (lookback: MarkdownFormat, remaining: String) -> Boolean
+ ): Pair<List<MarkdownFormat>, String> {
+ val seq = mutableListOf<MarkdownFormat>()
+ var remaining = text
+ var lastToken: MarkdownFormat = initialLookback
+ while (remaining.isNotEmpty()) {
+ val (tok, next) = parseInlineTextOnce(lastToken, remaining)
+ seq.add(tok)
+ lastToken = tok
+ remaining = next
+ if (breakout(tok, next))
+ break
+ }
+ return seq to remaining
+ }
+
fun parseInlineTextOnce(lookback: MarkdownFormat, text: String): Pair<MarkdownFormat, String> {
val parser = inlineParsers.find { it.detect(lookback, text) }
if (parser != null)
@@ -66,16 +85,9 @@ class MarkdownParser(source: String) {
}
fun parseInlineText(text: String): MarkdownFormat {
- val seq = mutableListOf<MarkdownFormat>()
- var remaining = text
- var lastToken: MarkdownFormat = Begin()
- while (remaining.isNotEmpty()) {
- val (tok, next) = parseInlineTextOnce(lastToken, remaining)
- seq.add(tok)
- lastToken = tok
- remaining = next
- }
- return collapseInlineFormat(seq, true)
+ val (tokens, rest) = parseInlineTextUntil(text, Begin()) { _, _ -> false }
+ require(rest.isEmpty())
+ return collapseInlineFormat(tokens, true)
}
private fun expandMarkdownFormats(sequence: List<MarkdownFormat>): List<MarkdownFormat> {