From e273a26c9b7f0a9dd9f8847cfc65e69453fa5905 Mon Sep 17 00:00:00 2001 From: Secozzi <49240133+Secozzi@users.noreply.github.com> Date: Sun, 13 Apr 2025 18:30:04 +0200 Subject: [PATCH] Use simpler markdown flavour in manga description (#2000) --- CHANGELOG.md | 1 + .../manga/components/MangaInfoHeader.kt | 12 +++- .../manga/components/MarkdownRender.kt | 67 ++++++++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15f9280c6..c01bdca36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co - Add user manga notes ([@imkunet](https://github.com/imkunet), [@AntsyLich](https://github.com/AntsyLich)) ([#428](https://github.com/mihonapp/mihon/pull/428)) - Fix user notes not restoring when manga doesn't exist in DB ([@AntsyLich](https://github.com/AntsyLich)) ([#1945](https://github.com/mihonapp/mihon/pull/1945)) - Add markdown support for manga descriptions ([@Secozzi](https://github.com/Secozzi)) ([#1948](https://github.com/mihonapp/mihon/pull/1948)) + - Use simpler markdown flavour ([@Secozzi](https://github.com/Secozzi)) ([#2000](https://github.com/mihonapp/mihon/pull/2000)) - Add Nord Theme ([@Riztard](https://github.com/Riztard)) ([#1951](https://github.com/mihonapp/mihon/pull/1951)) - Option to keep read manga when clearing database ([@AwkwardPeak7](https://github.com/AwkwardPeak7)) ([#1979](https://github.com/mihonapp/mihon/pull/1979)) diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt index b33db64e8..daf8695da 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt @@ -555,6 +555,14 @@ private fun ColumnScope.MangaContentInfo( } private val descriptionAnnotator = markdownAnnotator( + annotate = { content, child -> + if (child.type in DISALLOWED_MARKDOWN_TYPES) { + append(content.substring(child.startOffset, child.endOffset)) + return@markdownAnnotator true + } + + false + }, config = markdownAnnotatorConfig( eolAsNewLine = true, ), @@ -592,8 +600,8 @@ private fun MangaSummary( ) MarkdownRender( content = description, - annotator = descriptionAnnotator, modifier = Modifier.secondaryItemAlpha(), + annotator = descriptionAnnotator, ) } }, @@ -607,8 +615,8 @@ private fun MangaSummary( SelectionContainer { MarkdownRender( content = description, - annotator = descriptionAnnotator, modifier = Modifier.secondaryItemAlpha(), + annotator = descriptionAnnotator, ) } } diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MarkdownRender.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MarkdownRender.kt index 4d4278b81..6b50855d8 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MarkdownRender.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MarkdownRender.kt @@ -19,23 +19,42 @@ import com.mikepenz.markdown.compose.elements.MarkdownOrderedList import com.mikepenz.markdown.compose.elements.MarkdownTable import com.mikepenz.markdown.compose.elements.MarkdownTableHeader import com.mikepenz.markdown.compose.elements.MarkdownTableRow +import com.mikepenz.markdown.compose.elements.MarkdownText import com.mikepenz.markdown.compose.elements.listDepth import com.mikepenz.markdown.m3.Markdown import com.mikepenz.markdown.m3.markdownTypography import com.mikepenz.markdown.model.MarkdownAnnotator import com.mikepenz.markdown.model.markdownAnnotator import com.mikepenz.markdown.model.markdownPadding +import org.intellij.markdown.MarkdownTokenTypes.Companion.HTML_TAG +import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor +import org.intellij.markdown.flavours.commonmark.CommonMarkMarkerProcessor +import org.intellij.markdown.flavours.gfm.table.GitHubTableMarkerProvider +import org.intellij.markdown.parser.MarkerProcessor +import org.intellij.markdown.parser.MarkerProcessorFactory +import org.intellij.markdown.parser.ProductionHolder +import org.intellij.markdown.parser.constraints.CommonMarkdownConstraints +import org.intellij.markdown.parser.constraints.MarkdownConstraints +import org.intellij.markdown.parser.markerblocks.MarkerBlockProvider +import org.intellij.markdown.parser.markerblocks.providers.AtxHeaderProvider +import org.intellij.markdown.parser.markerblocks.providers.BlockQuoteProvider +import org.intellij.markdown.parser.markerblocks.providers.CodeBlockProvider +import org.intellij.markdown.parser.markerblocks.providers.CodeFenceProvider +import org.intellij.markdown.parser.markerblocks.providers.HorizontalRuleProvider +import org.intellij.markdown.parser.markerblocks.providers.ListMarkerProvider +import org.intellij.markdown.parser.markerblocks.providers.SetextHeaderProvider import tachiyomi.presentation.core.components.material.padding @Composable fun MarkdownRender( content: String, - annotator: MarkdownAnnotator = markdownAnnotator(), modifier: Modifier = Modifier, + annotator: MarkdownAnnotator = markdownAnnotator(), ) { Markdown( content = content, annotator = annotator, + flavour = SimpleMarkdownFlavourDescriptor, typography = mihonMarkdownTypography(), padding = mihonMarkdownPadding(), components = mihonMarkdownComponents(), @@ -127,4 +146,50 @@ private fun mihonMarkdownComponents() = markdownComponents( }, ) }, + custom = { type, model -> + if (type in DISALLOWED_MARKDOWN_TYPES) { + MarkdownText( + content = model.content.substring(model.node.startOffset, model.node.endOffset), + style = model.typography.text, + ) + } + }, +) + +private object SimpleMarkdownFlavourDescriptor : CommonMarkFlavourDescriptor() { + override val markerProcessorFactory: MarkerProcessorFactory = SimpleMarkdownProcessFactory +} + +private object SimpleMarkdownProcessFactory : MarkerProcessorFactory { + override fun createMarkerProcessor(productionHolder: ProductionHolder): MarkerProcessor<*> { + return SimpleMarkdownMarkerProcessor(productionHolder, CommonMarkdownConstraints.BASE) + } +} + +/** + * Like `CommonMarkFlavour`, but with html blocks and reference links removed and + * table support added + */ +private class SimpleMarkdownMarkerProcessor( + productionHolder: ProductionHolder, + constraints: MarkdownConstraints, +) : CommonMarkMarkerProcessor(productionHolder, constraints) { + private val markerBlockProviders = listOf( + CodeBlockProvider(), + HorizontalRuleProvider(), + CodeFenceProvider(), + SetextHeaderProvider(), + BlockQuoteProvider(), + ListMarkerProvider(), + AtxHeaderProvider(), + GitHubTableMarkerProvider(), + ) + + override fun getMarkerBlockProviders(): List> { + return markerBlockProviders + } +} + +val DISALLOWED_MARKDOWN_TYPES = arrayOf( + HTML_TAG, )