diff options
author | Linnea Gräf <nea@nea.moe> | 2024-03-24 16:08:58 +0100 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2024-03-24 16:08:58 +0100 |
commit | 238dabfe06fade0cd9a2b0fc286bddc6a48151f6 (patch) | |
tree | 1d036a1f3141db0e6c8b587272a83c0d974f49b8 | |
parent | 4c0ac30dc82677b2b2db36d114b452fdea537a37 (diff) | |
download | blog-infra-238dabfe06fade0cd9a2b0fc286bddc6a48151f6.tar.gz blog-infra-238dabfe06fade0cd9a2b0fc286bddc6a48151f6.tar.bz2 blog-infra-238dabfe06fade0cd9a2b0fc286bddc6a48151f6.zip |
Add generic inline parse loop support
-rw-r--r-- | src/main/kotlin/moe/nea/blog/md/ItalicsParser.kt | 31 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea/blog/md/MarkdownParser.kt | 32 |
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> { |