From: Lanius Trolling Date: Wed, 6 Mar 2024 23:41:43 +0000 (-0500) Subject: Rework indirect tag code X-Git-Url: https://gitweb.starshipfights.net/?a=commitdiff_plain;h=1c97ed73ac7bd8900c7c9099c159b7e02a5e7b38;p=factbooks Rework indirect tag code --- diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt index d3379c1..26ea99d 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt @@ -10,16 +10,9 @@ class TextParserInternalState { var suppressEndParagraph: Boolean = false } -sealed class InsideTag { - abstract val tag: String - - data class DirectTag(override val tag: String) : InsideTag() - data class IndirectTag(override val tag: String, val param: String?) : InsideTag() -} - sealed class TextParserState( val scope: TextParserScope, - val insideTags: List, + val insideTags: List, protected val internalState: TextParserInternalState, ) { abstract fun processCharacter(char: Char): TextParserState @@ -28,16 +21,7 @@ sealed class TextParserState( protected fun appendText(text: String) { if (text.isEmpty()) return - scope.write.append( - insideTags.foldRight(censorText(text)) { insideTag, t -> - if (insideTag is InsideTag.IndirectTag) { - val (tag, param) = insideTag - (scope.tags[tag] as? TextParserTagType.Indirect) - ?.process(param, t, scope.ctx) - ?: "[$tag${param?.let { "=$it" } ?: ""}]$t[/$tag]" - } else t - } - ) + scope.write.append(censorText(text)) internalState.suppressEndParagraph = false } @@ -49,7 +33,7 @@ sealed class TextParserState( } protected fun nextParagraph() { - val newline = if (insideTags.none { it is InsideTag.DirectTag }) { + val newline = if (insideTags.isEmpty()) { if (internalState.suppressEndParagraph) "

" else @@ -89,7 +73,7 @@ sealed class TextParserState( } } - class PlainText(scope: TextParserScope, private val text: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { + class PlainText(scope: TextParserScope, private val text: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { override fun processCharacter(char: Char): TextParserState { return if (char == '[') { appendText(text) @@ -111,7 +95,7 @@ sealed class TextParserState( } } - class NoFormatText(scope: TextParserScope, private val text: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { + class NoFormatText(scope: TextParserScope, private val text: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { override fun processCharacter(char: Char): TextParserState { val newText = text + char return if (newText.endsWith("[/$NO_FORMAT_TAG]")) { @@ -132,7 +116,28 @@ sealed class TextParserState( } } - class OpenTag(scope: TextParserScope, private val tag: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { + class InsideIndirectTag(scope: TextParserScope, private val tagName: String, private val tagType: TextParserTagType.Indirect, private val param: String?, private val text: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { + override fun processCharacter(char: Char): TextParserState { + val newText = text + char + return if (newText.endsWith("[/$tagName]")) { + appendTextRaw(tagType.process(param, censorText(newText.removeSuffix("[/$tagName]")), scope.ctx)) + + if (tagType.isBlock) + cancelEndParagraph() + + PlainText(scope, "", insideTags, internalState) + } else + InsideIndirectTag(scope, tagName, tagType, param, newText, insideTags, internalState) + } + + override fun processEndOfText() { + appendTextRaw(tagType.process(param, censorText(text), scope.ctx)) + if (text.isNotBlank()) + lastParagraph() + } + } + + class OpenTag(scope: TextParserScope, private val tag: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { override fun processCharacter(char: Char): TextParserState { return if (char == ']') { if (tag.equals(NO_FORMAT_TAG, ignoreCase = true)) @@ -145,10 +150,10 @@ sealed class TextParserState( when (tagType) { is TextParserTagType.Direct -> { appendTextRaw(tagType.begin(null, scope.ctx)) - PlainText(scope, "", insideTags + InsideTag.DirectTag(tag), internalState) + PlainText(scope, "", insideTags + tag, internalState) } - is TextParserTagType.Indirect -> PlainText(scope, "", insideTags + InsideTag.IndirectTag(tag, null), internalState) + is TextParserTagType.Indirect -> InsideIndirectTag(scope, tag, tagType, null, "", insideTags, internalState) else -> PlainText(scope, "[$tag]", insideTags, internalState) } @@ -167,7 +172,7 @@ sealed class TextParserState( } } - class TagParam(scope: TextParserScope, private val tag: String, private val param: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { + class TagParam(scope: TextParserScope, private val tag: String, private val param: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { override fun processCharacter(char: Char): TextParserState { return if (char == ']') { val tagType = scope.tags[tag] @@ -177,10 +182,10 @@ sealed class TextParserState( when (tagType) { is TextParserTagType.Direct -> { appendTextRaw(tagType.begin(param, scope.ctx)) - PlainText(scope, "", insideTags + InsideTag.DirectTag(tag), internalState) + PlainText(scope, "", insideTags + tag, internalState) } - is TextParserTagType.Indirect -> PlainText(scope, "", insideTags + InsideTag.IndirectTag(tag, param), internalState) + is TextParserTagType.Indirect -> InsideIndirectTag(scope, tag, tagType, param, "", insideTags, internalState) else -> PlainText(scope, "[$tag=$param]", insideTags, internalState) } @@ -194,15 +199,12 @@ sealed class TextParserState( } } - class CloseTag(scope: TextParserScope, private val tag: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { + class CloseTag(scope: TextParserScope, private val tag: String, insideTags: List, internalState: TextParserInternalState) : TextParserState(scope, insideTags, internalState) { override fun processCharacter(char: Char): TextParserState { return if (char == ']') { val tagType = scope.tags[tag] - val nextState = if (tagType is TextParserTagType.Direct && insideTags.lastOrNull()?.tag == tag) { + val nextState = if (tagType is TextParserTagType.Direct && insideTags.lastOrNull() == tag) { appendTextRaw(tagType.end(scope.ctx)) - - PlainText(scope, "", insideTags.dropLast(1), internalState) - } else if (insideTags.isNotEmpty() && (insideTags.last() as? InsideTag.IndirectTag)?.tag == tag) { PlainText(scope, "", insideTags.dropLast(1), internalState) } else { appendText("[/$tag]")