From 67ea96820fbad9caecb04cd43f5fb484c27b1e62 Mon Sep 17 00:00:00 2001 From: Lanius Trolling Date: Fri, 23 Feb 2024 18:30:26 -0500 Subject: [PATCH] Fix HTML generation so it's a lot better now --- .../kotlin/info/mechyrdia/lore/parser.kt | 152 ++++++++++++------ .../info/mechyrdia/lore/parser_plain.kt | 18 ++- .../info/mechyrdia/lore/parser_reply.kt | 2 +- .../kotlin/info/mechyrdia/lore/parser_tags.kt | 131 +++++++++------ .../kotlin/info/mechyrdia/lore/parser_toc.kt | 32 ++-- 5 files changed, 208 insertions(+), 127 deletions(-) diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt index db20ec9..17230a0 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/parser.kt @@ -1,11 +1,15 @@ package info.mechyrdia.lore data class TextParserScope( - val write: Appendable, + val write: StringBuilder, val tags: TextParserTags, - val ctx: TContext + val ctx: TContext, ) +class TextParserInternalState { + var suppressEndParagraph: Boolean = false +} + sealed class InsideTag { abstract val tag: String @@ -15,12 +19,15 @@ sealed class InsideTag { sealed class TextParserState( val scope: TextParserScope, - val insideTags: List + val insideTags: List, + protected val internalState: TextParserInternalState, ) { abstract fun processCharacter(char: Char): TextParserState abstract fun processEndOfText() protected fun appendText(text: String) { + if (text.isEmpty()) return + scope.write.append( insideTags.foldRight(censorText(text)) { insideTag, t -> if (insideTag is InsideTag.IndirectTag) { @@ -31,18 +38,45 @@ sealed class TextParserState( } else t } ) + internalState.suppressEndParagraph = false } protected fun appendTextRaw(text: String) { + if (text.isEmpty()) return + scope.write.append(text) + internalState.suppressEndParagraph = false } - class Initial(scope: TextParserScope) : TextParserState(scope, listOf()) { + protected fun nextParagraph() { + val newline = if (insideTags.none { it is InsideTag.DirectTag }) { + if (internalState.suppressEndParagraph) + "

" + else + "

" + } else + "
" + + appendTextRaw(newline) + } + + protected fun cancelEndParagraph() { + internalState.suppressEndParagraph = true + } + + protected fun cancelStartParagraph() { + if (scope.write.endsWith("

")) + scope.write.deleteRange(scope.write.length - 3, scope.write.length) + } + + class Initial(scope: TextParserScope) : TextParserState(scope, listOf(), TextParserInternalState()) { override fun processCharacter(char: Char): TextParserState { return if (char == '[') - OpenTag(scope, "", insideTags) - else - PlainText(scope, "$char", insideTags) + OpenTag(scope, "", insideTags, internalState) + else { + appendTextRaw("

") + PlainText(scope, "$char", insideTags, internalState) + } } override fun processEndOfText() { @@ -50,118 +84,136 @@ sealed class TextParserState( } } - class PlainText(scope: TextParserScope, private val text: String, insideTags: List) : TextParserState(scope, insideTags) { + 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) - OpenTag(scope, "", insideTags) + OpenTag(scope, "", insideTags, internalState) } else if (char == '\n' && text.endsWith('\n')) { appendText(text.removeSuffix("\n")) - val newline = if (insideTags.none { it is InsideTag.DirectTag }) - "

" - else - "
" + nextParagraph() - appendTextRaw(newline) - PlainText(scope, "", insideTags) + PlainText(scope, "", insideTags, internalState) } else - PlainText(scope, text + char, insideTags) + PlainText(scope, text + char, insideTags, internalState) } override fun processEndOfText() { - appendText(text) + appendText(text.removeSuffix("\n")) + if (text.isNotBlank()) + appendTextRaw("

") } } - class NoFormatText(scope: TextParserScope, private val text: String, insideTags: List) : TextParserState(scope, insideTags) { + 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]")) { appendText(newText.removeSuffix("[/$NO_FORMAT_TAG]")) - PlainText(scope, "", insideTags) + PlainText(scope, "", insideTags, internalState) } else if (newText.endsWith('\n')) { appendText(newText.removeSuffix("\n")) appendTextRaw("
") - NoFormatText(scope, "", insideTags) + NoFormatText(scope, "", insideTags, internalState) } else - NoFormatText(scope, newText, insideTags) + NoFormatText(scope, newText, insideTags, internalState) } override fun processEndOfText() { - appendText(text) + appendText(text.removeSuffix("\n")) + if (text.isNotBlank()) + appendTextRaw("

") } } - class OpenTag(scope: TextParserScope, private val tag: String, insideTags: List) : TextParserState(scope, insideTags) { + 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)) - NoFormatText(scope, "", insideTags) - else when (val tagType = scope.tags[tag]) { - is TextParserTagType.Direct -> { - appendTextRaw(tagType.begin(null, scope.ctx)) - PlainText(scope, "", insideTags + InsideTag.DirectTag(tag)) - } + NoFormatText(scope, "", insideTags, internalState) + else { + val tagType = scope.tags[tag] + if (tagType?.isBlock == true) + cancelStartParagraph() - is TextParserTagType.Indirect -> PlainText(scope, "", insideTags + InsideTag.IndirectTag(tag, null)) - - else -> PlainText(scope, "[$tag]", insideTags) + when (tagType) { + is TextParserTagType.Direct -> { + appendTextRaw(tagType.begin(null, scope.ctx)) + PlainText(scope, "", insideTags + InsideTag.DirectTag(tag), internalState) + } + + is TextParserTagType.Indirect -> PlainText(scope, "", insideTags + InsideTag.IndirectTag(tag, null), internalState) + + else -> PlainText(scope, "[$tag]", insideTags, internalState) + } } } else if (char == '/' && tag == "") - CloseTag(scope, tag, insideTags) + CloseTag(scope, tag, insideTags, internalState) else if (char == '=' && tag != "") - TagParam(scope, tag, "", insideTags) + TagParam(scope, tag, "", insideTags, internalState) else - OpenTag(scope, tag + char, insideTags) + OpenTag(scope, tag + char, insideTags, internalState) } override fun processEndOfText() { appendText("[$tag") + appendTextRaw("

") } } - class TagParam(scope: TextParserScope, private val tag: String, private val param: String, insideTags: List) : TextParserState(scope, insideTags) { + 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 == ']') - when (val tagType = scope.tags[tag]) { + return if (char == ']') { + val tagType = scope.tags[tag] + if (tagType?.isBlock == true) + cancelStartParagraph() + + when (tagType) { is TextParserTagType.Direct -> { appendTextRaw(tagType.begin(param, scope.ctx)) - PlainText(scope, "", insideTags + InsideTag.DirectTag(tag)) + PlainText(scope, "", insideTags + InsideTag.DirectTag(tag), internalState) } - is TextParserTagType.Indirect -> PlainText(scope, "", insideTags + InsideTag.IndirectTag(tag, param)) + is TextParserTagType.Indirect -> PlainText(scope, "", insideTags + InsideTag.IndirectTag(tag, param), internalState) - else -> PlainText(scope, "[$tag=$param]", insideTags) + else -> PlainText(scope, "[$tag=$param]", insideTags, internalState) } - else - TagParam(scope, tag, param + char, insideTags) + } else + TagParam(scope, tag, param + char, insideTags, internalState) } override fun processEndOfText() { appendText("[$tag=$param") + appendTextRaw("

") } } - class CloseTag(scope: TextParserScope, private val tag: String, insideTags: List) : TextParserState(scope, insideTags) { + 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] - if (tagType is TextParserTagType.Direct && insideTags.lastOrNull()?.tag == tag) { + val nextState = if (tagType is TextParserTagType.Direct && insideTags.lastOrNull()?.tag == tag) { appendTextRaw(tagType.end(scope.ctx)) - PlainText(scope, "", insideTags.dropLast(1)) + PlainText(scope, "", insideTags.dropLast(1), internalState) } else if (insideTags.isNotEmpty() && (insideTags.last() as? InsideTag.IndirectTag)?.tag == tag) { - PlainText(scope, "", insideTags.dropLast(1)) + PlainText(scope, "", insideTags.dropLast(1), internalState) } else { appendText("[/$tag]") - PlainText(scope, "", insideTags) + PlainText(scope, "", insideTags, internalState) } - } else CloseTag(scope, tag + char, insideTags) + + if (tagType?.isBlock == true) + cancelEndParagraph() + + nextState + } else CloseTag(scope, tag + char, insideTags, internalState) } override fun processEndOfText() { appendText("[/$tag") + appendTextRaw("

") } } @@ -187,7 +239,7 @@ sealed class TextParserState( .fold>(Initial(TextParserScope(builder, tags, context))) { state, char -> state.processCharacter(char) }.processEndOfText() - return "

$builder

" + return "$builder" } } } diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_plain.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_plain.kt index b5a4459..42ff317 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_plain.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_plain.kt @@ -1,16 +1,19 @@ package info.mechyrdia.lore private val plainTextFormattingTag = TextParserTagType.Direct( + false, { _, _ -> "" }, { "" }, ) private val spacedFormattingTag = TextParserTagType.Direct( + true, { _, _ -> " " }, { " " }, ) -private val embeddedFormattingTag = TextParserTagType.Indirect { _, _, _ -> "" } +private val embeddedFormattingTag = TextParserTagType.Indirect(false) { _, _, _ -> "" } +private val embeddedBlockFormattingTag = TextParserTagType.Indirect(true) { _, _, _ -> "" } enum class TextParserFormattingTagPlainText(val type: TextParserTagType) { // Basic formatting @@ -18,8 +21,8 @@ enum class TextParserFormattingTagPlainText(val type: TextParserTagType) { I(plainTextFormattingTag), U(plainTextFormattingTag), S(plainTextFormattingTag), - SUP(spacedFormattingTag), - SUB(spacedFormattingTag), + SUP(plainTextFormattingTag), + SUB(plainTextFormattingTag), COLOR(plainTextFormattingTag), IPA(plainTextFormattingTag), CODE(plainTextFormattingTag), @@ -40,7 +43,7 @@ enum class TextParserFormattingTagPlainText(val type: TextParserTagType) { IMAGE(embeddedFormattingTag), MODEL(embeddedFormattingTag), AUDIO(embeddedFormattingTag), - QUIZ(embeddedFormattingTag), + QUIZ(embeddedBlockFormattingTag), // Lists UL(spacedFormattingTag), @@ -61,8 +64,8 @@ enum class TextParserFormattingTagPlainText(val type: TextParserTagType) { // Conlangs LANG(plainTextFormattingTag), - ALPHABET(embeddedFormattingTag), - VOCAB(embeddedFormattingTag), + ALPHABET(embeddedBlockFormattingTag), + VOCAB(embeddedBlockFormattingTag), ; companion object { @@ -103,8 +106,9 @@ enum class TextParserCommentTagsPlainText(val type: TextParserTagType) { REPLY( TextParserTagType.Direct( + false, { _, _ -> ">>" }, - { "" }, + { _ -> "" }, ) ), diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_reply.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_reply.kt index 8e96602..dab6cdf 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_reply.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_reply.kt @@ -15,7 +15,7 @@ class CommentRepliesBuilder { enum class TextParserReplyCounterTag(val type: TextParserTagType) { REPLY( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(false) { _, content, builder -> sanitizeId(content)?.let { id -> builder.addReplyTag(Id(id)) } diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_tags.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_tags.kt index f1dc72c..b25e631 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_tags.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_tags.kt @@ -8,12 +8,14 @@ import kotlinx.serialization.json.JsonPrimitive import java.io.File sealed class TextParserTagType { - data class Direct(val beginFunc: (String?, TContext) -> String, val endFunc: (TContext) -> String) : TextParserTagType() { + abstract val isBlock: Boolean + + data class Direct(override val isBlock: Boolean, val beginFunc: (String?, TContext) -> String, val endFunc: (TContext) -> String) : TextParserTagType() { fun begin(param: String?, context: TContext) = beginFunc(param, context) fun end(context: TContext) = endFunc(context) } - data class Indirect(val processFunc: (String?, String, TContext) -> String) : TextParserTagType() { + data class Indirect(override val isBlock: Boolean, val processFunc: (String?, String, TContext) -> String) : TextParserTagType() { fun process(param: String?, content: String, context: TContext) = processFunc(param, content, context) } } @@ -30,11 +32,12 @@ value class TextParserTags private constructor(private val tags: Map byIgnoringContext(tags: TextParserTags) = TextParserTags(tags.tags.mapValues { (_, tag) -> when (tag) { is TextParserTagType.Direct -> TextParserTagType.Direct( + tag.isBlock, { param, _ -> tag.begin(param, Unit) }, { _ -> tag.end(Unit) } ) - is TextParserTagType.Indirect -> TextParserTagType.Indirect { param, content, _ -> + is TextParserTagType.Indirect -> TextParserTagType.Indirect(tag.isBlock) { param, content, _ -> tag.process(param, content, Unit) } } @@ -48,140 +51,152 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { // Basic formatting B( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), I( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), U( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), S( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), SUP( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), SUB( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), COLOR( TextParserTagType.Direct( + false, { tagParam, _ -> val color = tagParam?.toIntOrNull(16)?.toString(16)?.padStart(6, '0') val style = color?.let { " style=\"color: #$it\"" } ?: "" "" }, - { "" }, + { _ -> "" }, ) ), IPA( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), CODE( TextParserTagType.Direct( + false, { _, _ -> "
" },
-			{ "
" }, + { _ -> "" }, ) ), H1( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> "

$content

" } ), H2( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> val anchor = headerContentToAnchor(content) "

$content

" } ), H3( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> val anchor = headerContentToAnchor(content) "

$content

" } ), H4( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> val anchor = headerContentToAnchor(content) "

$content

" } ), H5( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> val anchor = headerContentToAnchor(content) "
$content
" } ), H6( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> val anchor = headerContentToAnchor(content) "
$content
" } ), ALIGN( TextParserTagType.Direct( + true, { tagParam, _ -> val alignments = setOf("left", "center", "right", "justify") val alignment = tagParam?.takeIf { it in alignments } val styleAttr = alignment?.let { " style=\"text-align: $it\"" } ?: "" "" }, - { "" }, + { _ -> "" }, ) ), ASIDE( TextParserTagType.Direct( + true, { tagParam, _ -> val floats = setOf("left", "right") val float = tagParam?.takeIf { it in floats } ?: "right" "
" }, - { "
" }, + { _ -> "" }, ) ), BLOCKQUOTE( - TextParserTagType.Direct({ _, _ -> - "
" - }, { _ -> - "
" - }) + TextParserTagType.Direct( + true, + { _, _ -> "
" }, + { _ -> "
" } + ) ), // Metadata DESC( TextParserTagType.Direct( + false, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), THUMB( - TextParserTagType.Indirect { _, _, _ -> "" } + TextParserTagType.Indirect(true) { _, _, _ -> "" } ), // Resource showing IMAGE( - TextParserTagType.Indirect { tagParam, content, _ -> + TextParserTagType.Indirect(false) { tagParam, content, _ -> val imageUrl = sanitizeLink(content) val (width, height) = getSizeParam(tagParam) @@ -196,7 +211,7 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { } ), MODEL( - TextParserTagType.Indirect { tagParam, content, _ -> + TextParserTagType.Indirect(false) { tagParam, content, _ -> val modelUrl = sanitizeLink(content) val (width, height) = getSizeParam(tagParam) @@ -206,14 +221,14 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { } ), AUDIO( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(false) { _, content, _ -> val audioUrl = sanitizeLink(content) "" } ), QUIZ( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> val quizText = File(Configuration.CurrentConfiguration.quizDir).combineSafe("$content.json").readText() val quizJson = JsonStorageCodec.encodeToString(String.serializer(), quizText) @@ -224,62 +239,70 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { // Lists UL( TextParserTagType.Direct( + true, { _, _ -> "
    " }, - { "
" }, + { _ -> "" }, ) ), OL( TextParserTagType.Direct( + true, { _, _ -> "
    " }, - { "
" }, + { _ -> "" }, ) ), LI( TextParserTagType.Direct( + true, { _, _ -> "
  • " }, - { "
  • " }, + { _ -> "" }, ) ), // Tables TABLE( TextParserTagType.Direct( + true, { _, _ -> "" }, - { "
    " }, + { _ -> "" }, ) ), TR( TextParserTagType.Direct( + true, { _, _ -> "" }, - { "" }, + { _ -> "" }, ) ), TD( TextParserTagType.Direct( + true, { tagParam, _ -> val (width, height) = getSizeParam(tagParam) val sizeAttrs = getTableSizeAttributes(width, height) "" }, - { "" }, + { _ -> "" }, ) ), TH( TextParserTagType.Direct( + true, { tagParam, _ -> val (width, height) = getSizeParam(tagParam) val sizeAttrs = getTableSizeAttributes(width, height) "" }, - { "" }, + { _ -> "" }, ) ), // Hyperformatting LINK( TextParserTagType.Direct( + false, { tagParam, _ -> val param = tagParam?.let { TextParserState.censorText(it) } val url = param?.let { if (it.startsWith('/')) "/lore$it" else "./$it" } @@ -287,28 +310,29 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { "" }, - { "" }, + { _ -> "" }, ) ), EXTLINK( TextParserTagType.Direct( + false, { tagParam, _ -> val url = tagParam?.let { TextParserState.censorText(it) } val attr = url?.let { " href=\"$it\"" } ?: "" "" }, - { "" }, + { _ -> "" }, ) ), ANCHOR( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(false) { _, content, _ -> val anchor = sanitizeLink(content) "" } ), REDIRECT( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(false) { _, content, _ -> val target = TextParserState.censorText(content) val url = if (target.startsWith('/')) "/lore$target" else "./$target" val string = JsonPrimitive(url).toString() @@ -319,7 +343,7 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { // Conlangs LANG( - TextParserTagType.Indirect { tagParam, content, _ -> + TextParserTagType.Indirect(false) { tagParam, content, _ -> if (tagParam?.equals("tylan", ignoreCase = true) == true) { val uncensored = TextParserState.uncensorText(content) val tylan = TylanAlphabetFont.tylanToFontAlphabet(uncensored) @@ -338,7 +362,7 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { } ), ALPHABET( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> if (content.equals("mechyrdian", ignoreCase = true)) { """ |
    @@ -394,7 +418,7 @@ enum class TextParserFormattingTag(val type: TextParserTagType) { } ), VOCAB( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(true) { _, content, _ -> if (content.isBlank()) "" else { @@ -436,6 +460,7 @@ enum class TextParserCommentTags(val type: TextParserTagType) { TH(TextParserFormattingTag.TH.type), URL( TextParserTagType.Direct( + false, { tagParam, _ -> val url = tagParam?.let { TextParserState.censorText(it) } val attr = url?.let { " href=\"$it\" rel=\"ugc nofollow\"" } ?: "" @@ -449,7 +474,7 @@ enum class TextParserCommentTags(val type: TextParserTagType) { LANG(TextParserFormattingTag.LANG.type), IMGUR( - TextParserTagType.Indirect { tagParam, content, _ -> + TextParserTagType.Indirect(false) { tagParam, content, _ -> val imageUrl = sanitizeExtLink(content) val (width, height) = getSizeParam(tagParam) @@ -457,7 +482,7 @@ enum class TextParserCommentTags(val type: TextParserTagType) { } ), IMGBB( - TextParserTagType.Indirect { tagParam, content, _ -> + TextParserTagType.Indirect(false) { tagParam, content, _ -> val imageUrl = sanitizeExtLink(content) val (width, height) = getSizeParam(tagParam) @@ -466,7 +491,7 @@ enum class TextParserCommentTags(val type: TextParserTagType) { ), REPLY( - TextParserTagType.Indirect { _, content, _ -> + TextParserTagType.Indirect(false) { _, content, _ -> sanitizeId(content)?.let { id -> ">>$id" } ?: "[reply]$content[/reply]" @@ -474,11 +499,11 @@ enum class TextParserCommentTags(val type: TextParserTagType) { ), QUOTE( - TextParserTagType.Direct({ _, _ -> - "
    " - }, { _ -> - "
    " - }) + TextParserTagType.Direct( + true, + { _, _ -> "
    " }, + { _ -> "
    " } + ) ) ; diff --git a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_toc.kt b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_toc.kt index 4b82f0b..bc58291 100644 --- a/src/jvmMain/kotlin/info/mechyrdia/lore/parser_toc.kt +++ b/src/jvmMain/kotlin/info/mechyrdia/lore/parser_toc.kt @@ -54,55 +54,55 @@ class TableOfContentsBuilder { enum class TextParserToCBuilderTag(val type: TextParserTagType) { H1( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(true) { _, content, builder -> builder.addHeader(headerContentToLabel(content), 0, headerContentToAnchor(content)) - "[h1]$content[/h1]" + content } ), H2( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(true) { _, content, builder -> builder.addHeader(headerContentToLabel(content), 1, headerContentToAnchor(content)) - "[h2]$content[/h2]" + content } ), H3( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(true) { _, content, builder -> builder.addHeader(headerContentToLabel(content), 2, headerContentToAnchor(content)) - "[h3]$content[/h3]" + content } ), H4( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(true) { _, content, builder -> builder.addHeader(headerContentToLabel(content), 3, headerContentToAnchor(content)) - "[h4]$content[/h4]" + content } ), H5( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(true) { _, content, builder -> builder.addHeader(headerContentToLabel(content), 4, headerContentToAnchor(content)) - "[h5]$content[/h5]" + content } ), H6( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(true) { _, content, builder -> builder.addHeader(headerContentToLabel(content), 5, headerContentToAnchor(content)) - "[h6]$content[/h6]" + content } ), DESC( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(false) { _, content, builder -> builder.addDescription(descriptionContentToPlainText(content)) content } ), IMAGE( - TextParserTagType.Indirect { param, content, builder -> + TextParserTagType.Indirect(false) { param, content, builder -> builder.addImage(imagePathToOpenGraphValue(content)) - "[image=$param]$content[/image]" + "" } ), THUMB( - TextParserTagType.Indirect { _, content, builder -> + TextParserTagType.Indirect(false) { _, content, builder -> builder.addImage(imagePathToOpenGraphValue(content), true) "" } -- 2.25.1