--- /dev/null
+package info.mechyrdia.lore
+
+private val plainTextFormattingTag = TextParserTagType.Direct<Unit>(
+ { _, _ -> "" },
+ { "" },
+)
+
+private val spacedFormattingTag = TextParserTagType.Direct<Unit>(
+ { _, _ -> " " },
+ { " " },
+)
+
+private val embeddedFormattingTag = TextParserTagType.Indirect<Unit> { _, _, _ -> "" }
+
+enum class TextParserFormattingTagPlainText(val type: TextParserTagType<Unit>) {
+ // Basic formatting
+ B(plainTextFormattingTag),
+ I(plainTextFormattingTag),
+ U(plainTextFormattingTag),
+ S(plainTextFormattingTag),
+ SUP(spacedFormattingTag),
+ SUB(spacedFormattingTag),
+ COLOR(plainTextFormattingTag),
+ IPA(plainTextFormattingTag),
+ CODE(plainTextFormattingTag),
+ H1(plainTextFormattingTag),
+ H2(plainTextFormattingTag),
+ H3(plainTextFormattingTag),
+ H4(plainTextFormattingTag),
+ H5(plainTextFormattingTag),
+ H6(plainTextFormattingTag),
+ ALIGN(plainTextFormattingTag),
+ ASIDE(plainTextFormattingTag),
+ BLOCKQUOTE(spacedFormattingTag),
+
+ // Metadata
+ THUMB(embeddedFormattingTag),
+
+ // Resource showing
+ IMAGE(embeddedFormattingTag),
+ MODEL(embeddedFormattingTag),
+ AUDIO(embeddedFormattingTag),
+ QUIZ(embeddedFormattingTag),
+
+ // Lists
+ UL(spacedFormattingTag),
+ OL(spacedFormattingTag),
+ LI(spacedFormattingTag),
+
+ // Tables
+ TABLE(spacedFormattingTag),
+ TR(spacedFormattingTag),
+ TD(spacedFormattingTag),
+ TH(spacedFormattingTag),
+
+ // Hyperformatting
+ LINK(plainTextFormattingTag),
+ EXTLINK(plainTextFormattingTag),
+ ANCHOR(embeddedFormattingTag),
+ REDIRECT(embeddedFormattingTag),
+
+ // Conlangs
+ LANG(plainTextFormattingTag),
+ ALPHABET(embeddedFormattingTag),
+ ;
+
+ companion object {
+ val asTags: TextParserTags<Unit> by lazy {
+ TextParserTags(entries.associate { it.name to it.type })
+ }
+ }
+}
+
+enum class TextParserCommentTagsPlainText(val type: TextParserTagType<Unit>) {
+ B(plainTextFormattingTag),
+ I(plainTextFormattingTag),
+ U(plainTextFormattingTag),
+ S(plainTextFormattingTag),
+ SUP(spacedFormattingTag),
+ SUB(spacedFormattingTag),
+ IPA(plainTextFormattingTag),
+ CODE(plainTextFormattingTag),
+ COLOR(plainTextFormattingTag),
+
+ ALIGN(plainTextFormattingTag),
+ ASIDE(plainTextFormattingTag),
+
+ UL(spacedFormattingTag),
+ OL(spacedFormattingTag),
+ LI(spacedFormattingTag),
+
+ TABLE(spacedFormattingTag),
+ TR(spacedFormattingTag),
+ TD(spacedFormattingTag),
+ TH(spacedFormattingTag),
+ URL(spacedFormattingTag),
+
+ LANG(plainTextFormattingTag),
+
+ IMGUR(embeddedFormattingTag),
+ IMGBB(embeddedFormattingTag),
+
+ REPLY(
+ TextParserTagType.Direct(
+ { _, _ -> ">>" },
+ { "" },
+ )
+ ),
+
+ QUOTE(spacedFormattingTag)
+ ;
+
+ companion object {
+ val asTags: TextParserTags<Unit> by lazy {
+ TextParserTags(entries.associate { it.name to it.type })
+ }
+ }
+}
value class TextParserTags<TContext> private constructor(private val tags: Map<String, TextParserTagType<TContext>>) {
operator fun get(name: String) = tags[name.lowercase()]
+ operator fun plus(other: TextParserTags<TContext>) = TextParserTags(tags + other.tags)
+
companion object {
operator fun <TContext> invoke(tags: Map<String, TextParserTagType<TContext>>) = TextParserTags(tags.mapKeys { (name, _) -> name.lowercase() })
+
+ fun <TContext> byIgnoringContext(tags: TextParserTags<Unit>) = TextParserTags<TContext>(tags.tags.mapValues { (_, tag) ->
+ when (tag) {
+ is TextParserTagType.Direct -> TextParserTagType.Direct(
+ { param, _ -> tag.begin(param, Unit) },
+ { _ -> tag.end(Unit) }
+ )
+
+ is TextParserTagType.Indirect -> TextParserTagType.Indirect { param, content, _ ->
+ tag.process(param, content, Unit)
+ }
+ }
+ })
}
}
+fun <TContext> TextParserTags<Unit>.ignoreContext() = TextParserTags.byIgnoringContext<TContext>(this)
+
enum class TextParserFormattingTag(val type: TextParserTagType<Unit>) {
// Basic formatting
B(
;
companion object {
- val asTags: TextParserTags<Unit>
- get() = TextParserTags(entries.associate { it.name to it.type })
+ val asTags: TextParserTags<Unit> by lazy {
+ TextParserTags(entries.associate { it.name to it.type })
+ }
}
}
TR(TextParserFormattingTag.TR.type),
TD(TextParserFormattingTag.TD.type),
TH(TextParserFormattingTag.TH.type),
- URL(TextParserTagType.Direct(
- { tagParam, _ ->
- val url = tagParam?.let { TextParserState.censorText(it) }
- val attr = url?.let { " href=\"$it\" rel=\"ugc nofollow\"" } ?: ""
-
- "<a$attr>"
- },
- { "</a>" },
- )),
+ URL(
+ TextParserTagType.Direct(
+ { tagParam, _ ->
+ val url = tagParam?.let { TextParserState.censorText(it) }
+ val attr = url?.let { " href=\"$it\" rel=\"ugc nofollow\"" } ?: ""
+
+ "<a$attr>"
+ },
+ { "</a>" },
+ )
+ ),
LANG(TextParserFormattingTag.LANG.type),
;
companion object {
- val asTags: TextParserTags<Unit>
- get() = TextParserTags(entries.associate { it.name to it.type })
+ val asTags: TextParserTags<Unit> by lazy {
+ TextParserTags(entries.associate { it.name to it.type })
+ }
}
}
fun headerContentToAnchor(content: String) = headerContentToLabel(content).replace(NON_ANCHOR_CHAR, "-")
fun imagePathToOpenGraphValue(path: String) = "https://mechyrdia.info/assets/images/${sanitizeLink(path)}"
-fun descriptionContentToPlainText(content: String) = TextParserState.uncensorText(content.replace(INSIDE_TAG_TEXT, ""))
+fun descriptionContentToPlainText(content: String) = TextParserState.uncensorText(content)
+
+fun commentToPlainText(contentRaw: String) = TextParserState.uncensorText(TextParserState.parseText(contentRaw, TextParserCommentTagsPlainText.asTags, Unit).replace("<p>", "").replace("</p>", "").replace("<br/>", ""))