From c45663f4ad352bbcf083c3da2c480fe500469fe4 Mon Sep 17 00:00:00 2001 From: imashnake0 Date: Sun, 18 Feb 2024 04:07:29 -0500 Subject: [PATCH] Revert "Stole `compose-markdown`" This reverts commit 03252a73119b3173e2f6f491f3b738213f9cb3eb. --- compose-markdown/build.gradle.kts | 41 -- compose-markdown/src/main/AndroidManifest.xml | 3 - .../core/markdown/MarkdownDocument.kt | 243 ---------- .../markdown/components/MarkdownBlockQuote.kt | 51 -- .../markdown/components/MarkdownCodeBlock.kt | 35 -- .../markdown/components/MarkdownHeading.kt | 40 -- .../markdown/components/MarkdownHtmlBlock.kt | 25 - .../core/markdown/components/MarkdownList.kt | 96 ---- .../markdown/components/MarkdownParagraph.kt | 32 -- .../core/markdown/components/MarkdownRule.kt | 13 - .../components/MarkdownSpanNodeExt.kt | 127 ----- .../core/markdown/components/MarkdownTable.kt | 51 -- .../core/markdown/generator/MarkdownNode.kt | 234 ---------- .../generator/MarkdownNodeGenerator.kt | 305 ------------ .../core/markdown/style/BlockQuoteStyle.kt | 19 - .../core/markdown/style/CodeBlockStyle.kt | 19 - .../core/markdown/style/Material3Ext.kt | 88 ---- .../core/markdown/style/TextStyles.kt | 43 -- .../core/markdown/style/TextUnitSize.kt | 14 - .../core/markdown/MarkdownNodeBuilders.kt | 128 ------ .../markdown/MarkdownNodeGeneratorTest.kt | 434 ------------------ gradle/libs.versions.toml | 5 - profile/build.gradle.kts | 1 - settings.gradle.kts | 1 - 24 files changed, 2048 deletions(-) delete mode 100644 compose-markdown/build.gradle.kts delete mode 100644 compose-markdown/src/main/AndroidManifest.xml delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/MarkdownDocument.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownBlockQuote.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownCodeBlock.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHeading.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHtmlBlock.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownList.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownParagraph.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownRule.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownSpanNodeExt.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownTable.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNode.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNodeGenerator.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/BlockQuoteStyle.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/CodeBlockStyle.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/Material3Ext.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextStyles.kt delete mode 100644 compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextUnitSize.kt delete mode 100644 compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeBuilders.kt delete mode 100644 compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeGeneratorTest.kt diff --git a/compose-markdown/build.gradle.kts b/compose-markdown/build.gradle.kts deleted file mode 100644 index 7e2261b5..00000000 --- a/compose-markdown/build.gradle.kts +++ /dev/null @@ -1,41 +0,0 @@ -plugins { - alias(libs.plugins.android.library) - alias(libs.plugins.kotlin) - - alias(libs.plugins.detekt) -} - -android { - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - - buildFeatures { - compose = true - } - - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() - } - - namespace = "com.imashnake.animite.compose.markdown" -} - -kotlin { - jvmToolchain(17) -} - -dependencies { - implementation(libs.bundles.compose) - - implementation(libs.intellij.markdown) - implementation(libs.coil.compose) - implementation(libs.coil.gif) - implementation(libs.coil.svg) - - debugImplementation(libs.compose.ui.tooling) - implementation(libs.compose.ui.toolingPreview) -} diff --git a/compose-markdown/src/main/AndroidManifest.xml b/compose-markdown/src/main/AndroidManifest.xml deleted file mode 100644 index fbb2ef83..00000000 --- a/compose-markdown/src/main/AndroidManifest.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/MarkdownDocument.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/MarkdownDocument.kt deleted file mode 100644 index d039c4c5..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/MarkdownDocument.kt +++ /dev/null @@ -1,243 +0,0 @@ -package com.nasdroid.core.markdown - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.TextUnit -import androidx.compose.ui.unit.dp -import com.nasdroid.core.markdown.components.MarkdownBlockQuote -import com.nasdroid.core.markdown.components.MarkdownCodeBlock -import com.nasdroid.core.markdown.components.MarkdownHeading -import com.nasdroid.core.markdown.components.MarkdownHtmlBlock -import com.nasdroid.core.markdown.components.MarkdownOrderedList -import com.nasdroid.core.markdown.components.MarkdownParagraph -import com.nasdroid.core.markdown.components.MarkdownRule -import com.nasdroid.core.markdown.components.MarkdownTable -import com.nasdroid.core.markdown.components.MarkdownUnorderedList -import com.nasdroid.core.markdown.generator.MarkdownBlockQuote -import com.nasdroid.core.markdown.generator.MarkdownCodeBlock -import com.nasdroid.core.markdown.generator.MarkdownHeading -import com.nasdroid.core.markdown.generator.MarkdownHtmlBlock -import com.nasdroid.core.markdown.generator.MarkdownNode -import com.nasdroid.core.markdown.generator.MarkdownNodeGenerator -import com.nasdroid.core.markdown.generator.MarkdownOrderedList -import com.nasdroid.core.markdown.generator.MarkdownParagraph -import com.nasdroid.core.markdown.generator.MarkdownRule -import com.nasdroid.core.markdown.generator.MarkdownTable -import com.nasdroid.core.markdown.generator.MarkdownUnorderedList -import com.nasdroid.core.markdown.style.BlockQuoteStyle -import com.nasdroid.core.markdown.style.CodeBlockStyle -import com.nasdroid.core.markdown.style.TextStyleModifiers -import com.nasdroid.core.markdown.style.TextStyles -import com.nasdroid.core.markdown.style.m3BlockQuoteStyle -import com.nasdroid.core.markdown.style.m3CodeBlockStyle -import com.nasdroid.core.markdown.style.m3TextStyleModifiers -import com.nasdroid.core.markdown.style.m3TextStyles -import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor -import org.intellij.markdown.parser.MarkdownParser - -/** - * Displays a Markdown document. - */ -@Composable -fun MarkdownDocument( - markdown: String, - textStyles: TextStyles, - textStyleModifiers: TextStyleModifiers, - blockQuoteStyle: BlockQuoteStyle, - codeBlockStyle: CodeBlockStyle, - modifier: Modifier = Modifier, - sectionSpacing: Dp = textStyles.textStyle.fontSize.toDp() -) { - val parsedMarkdownNodes = remember(markdown) { - val flavor = GFMFlavourDescriptor() - val tree = MarkdownParser(flavor).buildMarkdownTreeFromString(markdown) - MarkdownNodeGenerator(markdown, tree).generateNodes() - } - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(sectionSpacing) - ) { - parsedMarkdownNodes.forEach { - MarkdownNode( - node = it, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - blockQuoteStyle = blockQuoteStyle, - codeBlockStyle = codeBlockStyle - ) - } - } -} - -@Composable -internal fun TextUnit.toDp(): Dp { - return with(LocalDensity.current) { - this@toDp.toPx().toDp() - } -} - -@Composable -internal fun MarkdownNode( - node: MarkdownNode, - textStyles: TextStyles, - textStyleModifiers: TextStyleModifiers, - blockQuoteStyle: BlockQuoteStyle, - codeBlockStyle: CodeBlockStyle, - modifier: Modifier = Modifier -) { - when (node) { - is MarkdownBlockQuote -> MarkdownBlockQuote( - blockQuote = node, - style = blockQuoteStyle, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - codeBlockStyle = codeBlockStyle, - modifier = modifier, - ) - is MarkdownCodeBlock -> MarkdownCodeBlock( - codeBlock = node, - style = codeBlockStyle, - textStyle = textStyles.textStyle.copy(fontFamily = FontFamily.Monospace), - modifier = modifier, - ) - is MarkdownHeading -> MarkdownHeading( - heading = node, - modifier = modifier, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - ) - is MarkdownOrderedList -> MarkdownOrderedList( - list = node, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - blockQuoteStyle = blockQuoteStyle, - codeBlockStyle = codeBlockStyle, - modifier = modifier - ) - is MarkdownParagraph -> MarkdownParagraph( - paragraph = node, - textStyle = textStyles.textStyle, - textStyleModifiers = textStyleModifiers, - modifier = modifier - ) - MarkdownRule -> MarkdownRule(modifier = modifier) - is MarkdownTable -> MarkdownTable( - table = node, - textStyle = textStyles.textStyle, - textStyleModifiers = textStyleModifiers, - modifier = modifier - ) - is MarkdownHtmlBlock -> MarkdownHtmlBlock( - htmlBlock = node, - textStyle = textStyles.textStyle, - modifier = modifier - ) - is MarkdownUnorderedList -> MarkdownUnorderedList( - list = node, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - blockQuoteStyle = blockQuoteStyle, - codeBlockStyle = codeBlockStyle, - modifier = modifier - ) - } -} - -@Preview(showBackground = true, heightDp = 1900) -@Composable -fun MarkdownTextPreview() { - MarkdownDocument(markdown = """ - # H1 - H1 - == - ## H2 - H2 - -- - ### H3 - #### H4 - ##### H5 - ###### H6 - - One line - - Two - lines - - _italics_ - *italics* - - __bold__ - **bold** - - ~~strikethrough~~ - - [anilist link](https://anilist.co/) - https://anilist.co/ - - - ![anilist icon](https://anilist.co/img/icons/icon.svg) - ![image](https://picsum.photos/50) - - --- - *** - - > block quote - - >> nested block quote - - table | with | content - --- | --- | --- - content | content | content - - - Bulleted - - List - - * Bulleted - * List - - + Bulleted - + List - - + Nested - + List - - 1. Numbered - 2. List - - 6. Numbered - 9. List - - * Mixed - 1. List - + Containing - 2. Different - * Types - - `inline code` - - block - code - - ``` - block - code - ``` - """.trimIndent(), - textStyles = m3TextStyles(), - textStyleModifiers = m3TextStyleModifiers(), - blockQuoteStyle = m3BlockQuoteStyle(), - codeBlockStyle = m3CodeBlockStyle(), - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(16.dp)) -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownBlockQuote.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownBlockQuote.kt deleted file mode 100644 index 9cd358e5..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownBlockQuote.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.nasdroid.core.markdown.MarkdownNode -import com.nasdroid.core.markdown.generator.MarkdownBlockQuote -import com.nasdroid.core.markdown.style.BlockQuoteStyle -import com.nasdroid.core.markdown.style.CodeBlockStyle -import com.nasdroid.core.markdown.style.TextStyleModifiers -import com.nasdroid.core.markdown.style.TextStyles -import com.nasdroid.core.markdown.toDp - -/** - * Displays a [MarkdownBlockQuote]. A block quote is a visually distinct section in a document, - * usually used to reference external sources. - */ -@Composable -fun MarkdownBlockQuote( - blockQuote: MarkdownBlockQuote, - style: BlockQuoteStyle, - textStyles: TextStyles, - textStyleModifiers: TextStyleModifiers, - codeBlockStyle: CodeBlockStyle, - modifier: Modifier = Modifier, -) { - Box( - modifier = Modifier - .background(style.background, style.shape) - .then(modifier) - ) { - Column( - modifier = Modifier.padding(style.innerPadding), - verticalArrangement = Arrangement.spacedBy(textStyles.textStyle.fontSize.toDp()) - ) { - blockQuote.children.forEach { - MarkdownNode( - node = it, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - blockQuoteStyle = style, - codeBlockStyle = codeBlockStyle - ) - } - } - } -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownCodeBlock.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownCodeBlock.kt deleted file mode 100644 index 4a8c8613..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownCodeBlock.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.text.BasicText -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextStyle -import com.nasdroid.core.markdown.generator.MarkdownCodeBlock -import com.nasdroid.core.markdown.style.CodeBlockStyle - -/** - * Displays a [MarkdownCodeBlock]. A code block is a visually distinct section of text, usually used - * to show code. - */ -@Composable -fun MarkdownCodeBlock( - codeBlock: MarkdownCodeBlock, - style: CodeBlockStyle, - textStyle: TextStyle, - modifier: Modifier = Modifier, -) { - Box( - modifier = Modifier - .background(style.background, style.shape) - .then(modifier) - ) { - BasicText( - text = codeBlock.code, - style = textStyle, - modifier = Modifier.padding(style.innerPadding) - ) - } -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHeading.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHeading.kt deleted file mode 100644 index 71ceb3b5..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHeading.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.text.BasicText -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.sp -import com.nasdroid.core.markdown.generator.MarkdownHeading -import com.nasdroid.core.markdown.style.TextStyleModifiers -import com.nasdroid.core.markdown.style.TextStyles -import com.nasdroid.core.markdown.style.TextUnitSize - -/** - * Displays a [MarkdownHeading]. A heading is a higher emphasis paragraph, usually used to separate - * a document into sections. - */ -@Composable -fun MarkdownHeading( - heading: MarkdownHeading, - textStyles: TextStyles, - textStyleModifiers: TextStyleModifiers, - modifier: Modifier = Modifier -) { - val (annotatedString, inlineContent) = remember(heading, textStyles) { - val textStyle = when (heading.size) { - MarkdownHeading.Size.Headline1 -> textStyles.headline1 - MarkdownHeading.Size.Headline2 -> textStyles.headline2 - MarkdownHeading.Size.Headline3 -> textStyles.headline3 - MarkdownHeading.Size.Headline4 -> textStyles.headline4 - MarkdownHeading.Size.Headline5 -> textStyles.headline5 - MarkdownHeading.Size.Headline6 -> textStyles.headline6 - } - heading.children.buildTextWithContent(textStyle, textStyleModifiers, TextUnitSize(100.sp, 100.sp)) - } - BasicText( - text = annotatedString, - modifier = modifier, - inlineContent = inlineContent - ) -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHtmlBlock.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHtmlBlock.kt deleted file mode 100644 index d379dba1..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownHtmlBlock.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.text.BasicText -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextStyle -import com.nasdroid.core.markdown.generator.MarkdownHtmlBlock - -/** - * Displays a [MarkdownHtmlBlock]. An HTML block is a block of text that is formatted with HTML. - * Unfortunately we don't (yet) render this HTML to anything useful, so we just display the raw - * text. - */ -@Composable -fun MarkdownHtmlBlock( - htmlBlock: MarkdownHtmlBlock, - textStyle: TextStyle, - modifier: Modifier = Modifier -) { - BasicText( - text = htmlBlock.text, - style = textStyle, - modifier = modifier - ) -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownList.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownList.kt deleted file mode 100644 index 81e0aa7b..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownList.kt +++ /dev/null @@ -1,96 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.text.BasicText -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.nasdroid.core.markdown.MarkdownNode -import com.nasdroid.core.markdown.generator.MarkdownOrderedList -import com.nasdroid.core.markdown.generator.MarkdownUnorderedList -import com.nasdroid.core.markdown.style.BlockQuoteStyle -import com.nasdroid.core.markdown.style.CodeBlockStyle -import com.nasdroid.core.markdown.style.TextStyleModifiers -import com.nasdroid.core.markdown.style.TextStyles - -private const val ORDERED_LIST_PREFIX_LENGTH = 3 - -/** - * Displays a [MarkdownOrderedList]. An ordered list is a list where each item is prefixed with its - * index in the list. - */ -@Composable -fun MarkdownOrderedList( - list: MarkdownOrderedList, - textStyles: TextStyles, - textStyleModifiers: TextStyleModifiers, - blockQuoteStyle: BlockQuoteStyle, - codeBlockStyle: CodeBlockStyle, - modifier: Modifier = Modifier, -) { - Column(modifier) { - list.listItems.forEachIndexed { index, markdownNode -> - Row( - horizontalArrangement = Arrangement.spacedBy(4.dp), - verticalAlignment = Alignment.Top - ) { - BasicText( - text = "${index + 1}".padStart(ORDERED_LIST_PREFIX_LENGTH) + ".", - style = textStyles.textStyle - ) - Column { - markdownNode.content.forEach { - MarkdownNode( - node = it, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - blockQuoteStyle = blockQuoteStyle, - codeBlockStyle = codeBlockStyle - ) - } - } - } - } - } -} - -/** - * Displays a [MarkdownUnorderedList]. An unordered list is a list where each item is prefixed with - * a bullet of some description. - */ -@Composable -fun MarkdownUnorderedList( - list: MarkdownUnorderedList, - textStyles: TextStyles, - textStyleModifiers: TextStyleModifiers, - blockQuoteStyle: BlockQuoteStyle, - codeBlockStyle: CodeBlockStyle, - modifier: Modifier = Modifier, -) { - Column(modifier) { - list.listItems.forEach { markdownNode -> - Row( - horizontalArrangement = Arrangement.spacedBy(4.dp) - ) { - BasicText( - text = "\t\u2022", - style = textStyles.textStyle - ) - Column { - markdownNode.content.forEach { - MarkdownNode( - node = it, - textStyles = textStyles, - textStyleModifiers = textStyleModifiers, - blockQuoteStyle = blockQuoteStyle, - codeBlockStyle = codeBlockStyle - ) - } - } - } - } - } -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownParagraph.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownParagraph.kt deleted file mode 100644 index 256e6235..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownParagraph.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.text.BasicText -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.sp -import com.nasdroid.core.markdown.generator.MarkdownParagraph -import com.nasdroid.core.markdown.style.TextStyleModifiers -import com.nasdroid.core.markdown.style.TextUnitSize - -/** - * Displays a [MarkdownParagraph]. A paragraph is a group of "spans". Spans are stylized sections of - * text, but can also include inline images and links. - */ -@Composable -fun MarkdownParagraph( - paragraph: MarkdownParagraph, - textStyle: TextStyle, - textStyleModifiers: TextStyleModifiers, - modifier: Modifier = Modifier, -) { - val (annotatedString, inlineContent) = remember(paragraph) { - paragraph.children.buildTextWithContent(textStyle, textStyleModifiers, TextUnitSize(100.sp, 100.sp)) - } - BasicText( - text = annotatedString, - modifier = modifier, - inlineContent = inlineContent - ) -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownRule.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownRule.kt deleted file mode 100644 index b6d5ff9d..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownRule.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.material3.HorizontalDivider -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -/** - * Displays a Markdown Rule. A rule is a horizontal line, usually used to separate content. - */ -@Composable -fun MarkdownRule(modifier: Modifier = Modifier) { - HorizontalDivider(modifier) -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownSpanNodeExt.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownSpanNodeExt.kt deleted file mode 100644 index e4000518..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownSpanNodeExt.kt +++ /dev/null @@ -1,127 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.text.InlineTextContent -import androidx.compose.foundation.text.appendInlineContent -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.ExperimentalTextApi -import androidx.compose.ui.text.Placeholder -import androidx.compose.ui.text.PlaceholderVerticalAlign -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.UrlAnnotation -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.withAnnotation -import androidx.compose.ui.text.withStyle -import coil.compose.AsyncImage -import coil.decode.ImageDecoderDecoder -import coil.decode.SvgDecoder -import coil.request.ImageRequest -import com.nasdroid.core.markdown.generator.MarkdownCodeSpan -import com.nasdroid.core.markdown.generator.MarkdownEol -import com.nasdroid.core.markdown.generator.MarkdownImage -import com.nasdroid.core.markdown.generator.MarkdownLink -import com.nasdroid.core.markdown.generator.MarkdownSpanNode -import com.nasdroid.core.markdown.generator.MarkdownText -import com.nasdroid.core.markdown.generator.MarkdownWhitespace -import com.nasdroid.core.markdown.style.TextStyleModifiers -import com.nasdroid.core.markdown.style.TextUnitSize - -/** - * Maps a list of [MarkdownSpanNode]s to a [TextWithContent] for use in a Text Composable. - */ -fun List.buildTextWithContent( - textStyles: TextStyle, - textStyleModifiers: TextStyleModifiers, - imageSize: TextUnitSize, -): TextWithContent { - val content = mutableMapOf() - val text = buildAnnotatedString { - this@buildTextWithContent.forEach { node -> - if (node is MarkdownImage) { - content[node.imageUrl] = InlineTextContent( - // TODO auto-size the content - https://issuetracker.google.com/issues/294110693 - placeholder = Placeholder(imageSize.width, imageSize.height, PlaceholderVerticalAlign.TextBottom) - ) { contentDescription -> - val request = when { - node.imageUrl.endsWith("svg") -> ImageRequest.Builder(LocalContext.current) - .data(node.imageUrl) - .decoderFactory(SvgDecoder.Factory()) - .crossfade(true) - .build() - node.imageUrl.endsWith("gif") -> ImageRequest.Builder(LocalContext.current) - .data(node.imageUrl) - .decoderFactory(ImageDecoderDecoder.Factory()) - .crossfade(true) - .build() - else -> ImageRequest.Builder(LocalContext.current) - .data(node.imageUrl) - .crossfade(true) - .build() - } - AsyncImage( - model = request, - contentDescription = contentDescription, - modifier = Modifier.fillMaxSize() - ) - } - } - append(node.toAnnotatedString(textStyles,textStyleModifiers)) - } - } - return TextWithContent(text, content) -} - -/** - * Describes an [AnnotatedString], along with a map describing inline content within the annotated - * string. - * - * @property text The [AnnotatedString] to be displayed. - * @property content The map containing [InlineTextContent]s to be displayed. - */ -data class TextWithContent( - val text: AnnotatedString, - val content: Map -) - -@OptIn(ExperimentalTextApi::class) -internal fun MarkdownSpanNode.toAnnotatedString( - textStyle: TextStyle, - textStyleModifiers: TextStyleModifiers, -): AnnotatedString { - return when (this) { - is MarkdownCodeSpan -> AnnotatedString( - text = text, - spanStyle = textStyleModifiers.code(textStyle).toSpanStyle() - ) - is MarkdownImage -> buildAnnotatedString { - appendInlineContent(imageUrl, contentDescription) - } - is MarkdownLink -> buildAnnotatedString { - withAnnotation(UrlAnnotation(url)) { - withStyle(textStyleModifiers.link(textStyle).toSpanStyle()) { - displayText.forEach { - append(it.toAnnotatedString(textStyle, textStyleModifiers)) - } - } - } - } - is MarkdownText -> AnnotatedString( - text = this.text, - spanStyle = textStyle - .maybeLet(isBold, textStyleModifiers.bold) - .maybeLet(isItalics, textStyleModifiers.italics) - .maybeLet(isStrikethrough, textStyleModifiers.strikethrough) - .toSpanStyle() - ) - MarkdownWhitespace -> AnnotatedString(" ", textStyle.toSpanStyle()) - MarkdownEol -> AnnotatedString("\n", textStyle.toSpanStyle()) - } -} - -internal inline fun T.maybeLet(condition: Boolean, block: (T) -> T): T { - return this.let { - if (condition) block(it) else it - } -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownTable.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownTable.kt deleted file mode 100644 index f19ae137..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/components/MarkdownTable.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.nasdroid.core.markdown.components - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextStyle -import com.nasdroid.core.markdown.generator.MarkdownTable -import com.nasdroid.core.markdown.style.TextStyleModifiers - -/** - * Displays a [MarkdownTable]. A table is a grid of labelled rows and columns that contain - * paragraphs. - */ -@Composable -fun MarkdownTable( - table: MarkdownTable, - textStyle: TextStyle, - textStyleModifiers: TextStyleModifiers, - modifier: Modifier = Modifier, -) { - Column(modifier) { - // Add headers - Row { - table.columns.forEach { - MarkdownParagraph( - paragraph = it.header, - textStyle = textStyle, - textStyleModifiers = textStyleModifiers, - modifier = Modifier.weight(1f) - ) - } - } - MarkdownRule() - table.columns.first().cells.forEachIndexed { index, _ -> - Row { - table.columns.forEach { - MarkdownParagraph( - paragraph = it.cells[index], - textStyle = textStyle, - textStyleModifiers = textStyleModifiers, - modifier = Modifier.weight(1f) - ) - } - } - if (index < table.columns.first().cells.lastIndex) { - MarkdownRule() - } - } - } -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNode.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNode.kt deleted file mode 100644 index 5707bb47..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNode.kt +++ /dev/null @@ -1,234 +0,0 @@ -package com.nasdroid.core.markdown.generator - -/** - * Encapsulates all possible content types within a Markdown document. - */ -sealed interface MarkdownNode - -/** - * Encapsulates all possible span nodes in a Markdown document. A span node is a stylized element - * contained within a block of text, like a paragraph. - */ -sealed interface MarkdownSpanNode - -/** - * Describes a Markdown paragraph. A paragraph is a collection of spans that make up a block of text. - * - * See [Paragraphs](https://commonmark.org/help/tutorial/03-paragraphs.html) for a how-to, or - * [MarkdownSpanNode] for possible span types. - * - * @property children The list of [MarkdownSpanNode]s this paragraph contains. - */ -data class MarkdownParagraph( - val children: List -) : MarkdownNode - -/** - * Describes a Markdown block quote. A block quote is a fully-formatted Markdown section that is - * visually distinct from the rest of the document, usually used to indicate a quote. - * - * See [Blockquotes](https://commonmark.org/help/tutorial/05-blockquotes.html) for a how-to. - * - * @property children The list of [MarkdownNode]s contained within the block quote. - */ -data class MarkdownBlockQuote( - val children: List -) : MarkdownNode - -/** - * Represents a Markdown rule. A rule is a horizontal line spanning the width of the document, - * usually used to separate content. - */ -data object MarkdownRule : MarkdownNode - -/** - * Represents whitespace in a Markdown Span. - */ -data object MarkdownWhitespace : MarkdownSpanNode - -/** - * Represents a line end in a Markdown Span. - */ -data object MarkdownEol: MarkdownSpanNode - -/** - * Describes Markdown code block. A code block is a visually distinct section of non-formattable - * text, usually used to display code. - * - * See [Code](https://commonmark.org/help/tutorial/09-code.html) for a how-to. - * - * @property code The contents of the code block. - * @property language The language the code is written in, if specified. - */ -data class MarkdownCodeBlock( - val code: String, - val language: String? -): MarkdownNode - -/** - * Describes a Markdown heading. A heading is a line of stylized text, typically larger than the - * main file content, used to denote the start of a section. - * - * See [Headings](https://commonmark.org/help/tutorial/04-headings.html) for a how-to. - * - * @property children A list of [MarkdownSpanNode]s that are contained in this heading. - * @property size The [Size] of the heading. - */ -data class MarkdownHeading( - val children: List, - val size: Size, -) : MarkdownNode { - - /** - * Represents a Markdown heading size. [Headline1] is the largest size, while [Headline6] is the - * smallest. - */ - enum class Size { - Headline1, - Headline2, - Headline3, - Headline4, - Headline5, - Headline6, - } -} - -/** - * Describes a Markdown image. An image is an inline rich media preview. - * - * See [Images](https://commonmark.org/help/tutorial/08-images.html) for a how-to. - * - * @property imageUrl The URL used to load the image. This may be relative to the URL of the - * Markdown document. - * @property contentDescription The content description of the image. This is used to describe the - * image. - * @property titleText Optional accompanying text for the image. This can be used to provide - * additional context. - */ -data class MarkdownImage( - val imageUrl: String, - val contentDescription: String, - val titleText: String?, -) : MarkdownSpanNode - -/** - * Describes a Markdown link. A link is a clickable text element that navigates the user to the - * specified URL. - * - * See [Links](https://commonmark.org/help/tutorial/07-links.html) for a how-to. - * - * @property displayText The [MarkdownSpanNode]s that are displayed to the user representing this link. - * @property titleText Optional accompanying text for the link. This can be used to provide - * additional context. - * @property url The link that users should be navigated to upon clicking. - */ -data class MarkdownLink( - val displayText: List, - val titleText: String?, - val url: String, -) : MarkdownSpanNode - -/** - * Describes a Markdown text. A text is a span element that can be displayed with various emphasis. - * - * See [Emphasis](https://commonmark.org/help/tutorial/02-emphasis.html) for a how-to. - * - * @property text The content of the text span. - * @property isBold Whether the text span is bold. - * @property isItalics Whether the text span is italicized. - * @property isStrikethrough Whether the text span is stricken through. - */ -data class MarkdownText( - val text: String, - val isBold: Boolean, - val isItalics: Boolean, - val isStrikethrough: Boolean, -) : MarkdownSpanNode - -/** - * Describes a Markdown code span. A code span is a text element that is visually distinct from the - * surrounding content, and is displayed in a monospace font. - * - * See [Code](https://commonmark.org/help/tutorial/09-code.html) for a how-to. - * - * @property text The text contained within the code span. - */ -data class MarkdownCodeSpan( - val text: String, -): MarkdownSpanNode - -/** - * Describes a Markdown table. A table is a grid of Markdown paragraphs, grouped into columns. - * - * @property columns The list of [Column]s contained in this table. - */ -data class MarkdownTable( - val columns: List -) : MarkdownNode { - - /** - * Describes a single column within a Markdown table. A column contains a header, and a series - * of data cells to be displayed under said header. - * - * @property header The [MarkdownParagraph] header content. - * @property cells The list of [MarkdownParagraph]s cell contents. - * @property alignment The text alignment for this column. - */ - data class Column( - val header: MarkdownParagraph, - val cells: List, - val alignment: Alignment - ) - - /** - * Represents all possible text alignments for table cell text. - */ - enum class Alignment { - LEFT, - CENTER, - RIGHT - } -} - -/** - * Describes a Markdown ordered list. An ordered list is a list of formatted text, displayed as a - * numbered (ordered) list. - * - * See [Lists](https://commonmark.org/help/tutorial/06-lists.html) for a how-to. - * - * @property listItems A list of [MarkdownNode]s this list contains. - */ -data class MarkdownOrderedList( - val listItems: List -) : MarkdownNode - -/** - * Describes a Markdown unordered list. An unordered list is a list of formatted text, displayed as - * a bulleted (unordered) list. - * - * See [Lists](https://commonmark.org/help/tutorial/06-lists.html) for a how-to. - * - * @property listItems A list of [MarkdownNode]s this list contains. - */ -data class MarkdownUnorderedList( - val listItems: List -) : MarkdownNode - -/** - * Describes a single item contained within a Markdown list. List items can contain a number of - * sub-items, for example it could contain one paragraph followed by one (nested) list. - * - * @property content A list of [MarkdownNode]s that this list item contains. - */ -data class MarkdownListItem( - val content: List -) - -/** - * Describes a block of HTML-formatted text contained within a Markdown document. - * - * @property text The HTML-formatted text that makes up the block. - */ -data class MarkdownHtmlBlock( - val text: String -) : MarkdownNode diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNodeGenerator.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNodeGenerator.kt deleted file mode 100644 index 119d4a7a..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/generator/MarkdownNodeGenerator.kt +++ /dev/null @@ -1,305 +0,0 @@ -package com.nasdroid.core.markdown.generator - -import org.intellij.markdown.MarkdownElementTypes -import org.intellij.markdown.MarkdownTokenTypes -import org.intellij.markdown.ast.ASTNode -import org.intellij.markdown.ast.getTextInNode -import org.intellij.markdown.flavours.gfm.GFMElementTypes -import org.intellij.markdown.flavours.gfm.GFMTokenTypes - -/** - * A class that takes a Markdown document and its parsed [ASTNode], and produces a type-safe - * representation of the document tree. See [MarkdownNode] for possible types. - */ -class MarkdownNodeGenerator( - private val allFileText: String, - private val rootNode: ASTNode -) { - init { - check(rootNode.type == MarkdownElementTypes.MARKDOWN_FILE) { - "The root node provided must be of type MARKDOWN_FILE, but it was ${rootNode.type}" - } - } - - /** - * Generates a list of [MarkdownNode]s from the data provided at construction time. - */ - fun generateNodes(): List { - return rootNode.children.mapNotNull { parseGenericNode(it) } - } - - private fun parseGenericNode(astNode: ASTNode): MarkdownNode? { - return when (astNode.type) { - MarkdownElementTypes.ATX_1, - MarkdownElementTypes.ATX_2, - MarkdownElementTypes.ATX_3, - MarkdownElementTypes.ATX_4, - MarkdownElementTypes.ATX_5, - MarkdownElementTypes.ATX_6, - MarkdownElementTypes.SETEXT_1, - MarkdownElementTypes.SETEXT_2 -> parseHeaderNode(astNode) - MarkdownElementTypes.PARAGRAPH -> parseParagraphNode(astNode) - MarkdownElementTypes.BLOCK_QUOTE -> parseBlockQuote(astNode) - MarkdownTokenTypes.EOL, - MarkdownTokenTypes.WHITE_SPACE -> null // Ignored in generic nodes, the renderer should handle it. - MarkdownTokenTypes.HORIZONTAL_RULE -> MarkdownRule - MarkdownElementTypes.CODE_BLOCK, - MarkdownElementTypes.CODE_FENCE -> parseCodeBlock(astNode) - GFMElementTypes.TABLE -> parseTable(astNode) - MarkdownElementTypes.UNORDERED_LIST -> parseUnorderedList(astNode) - MarkdownElementTypes.ORDERED_LIST -> parseOrderedList(astNode) - MarkdownElementTypes.HTML_BLOCK -> MarkdownHtmlBlock(astNode.getTextInNode(allFileText).toString()) - else -> error("Unknown node type ${astNode.type}") - } - } - - private fun parseUnorderedList(astNode: ASTNode): MarkdownUnorderedList { - val listItems = astNode.children - .filter { it.type == MarkdownElementTypes.LIST_ITEM } - .map { listItemNode -> - MarkdownListItem( - content = listItemNode.children.drop(1) - .mapNotNull { parseGenericNode(it) } - ) - } - return MarkdownUnorderedList(listItems) - } - - private fun parseOrderedList(astNode: ASTNode): MarkdownOrderedList { - val list = parseUnorderedList(astNode) - return MarkdownOrderedList(list.listItems) - } - - private fun parseTable(astNode: ASTNode): MarkdownTable { - val headers = astNode.children[0].children.filter { it.type == GFMTokenTypes.CELL } - val bodyNodes = astNode.children - .filter { it.type == GFMElementTypes.ROW } - val columns = headers.mapIndexed { index: Int, headerNode: ASTNode -> - val columnCellNodes = bodyNodes - .map { row -> row.children.filter { it.type == GFMTokenTypes.CELL }[index] } - MarkdownTable.Column( - header = parseParagraphNode(headerNode), - alignment = MarkdownTable.Alignment.LEFT, - cells = columnCellNodes.map { parseParagraphNode(it) } - ) - } - return MarkdownTable(columns) - } - - private fun parseCodeBlock(astNode: ASTNode): MarkdownCodeBlock { - val language = astNode.children - .firstOrNull { it.type == MarkdownTokenTypes.FENCE_LANG } - ?.getTextInNode(allFileText) - ?.toString() - val code = astNode.children - .filterNot { - it.type == MarkdownTokenTypes.CODE_FENCE_START || - it.type == MarkdownTokenTypes.CODE_FENCE_END || - it.type == MarkdownTokenTypes.FENCE_LANG - } - .joinToString(separator = "") { node -> - if (node.type == MarkdownTokenTypes.EOL) { - "\n" - } else { - node.getTextInNode(allFileText) - } - } - .trim('\n') - .trimIndent() - return MarkdownCodeBlock(code, language) - } - - private fun parseBlockQuote(astNode: ASTNode): MarkdownBlockQuote { - return MarkdownBlockQuote( - children = astNode.children - .filterNot { it.type == MarkdownTokenTypes.BLOCK_QUOTE } - .mapNotNull { parseGenericNode(it) } - ) - } - - private fun parseParagraphNode(astNode: ASTNode): MarkdownParagraph { - val parsedChildren = astNode.children - .dropWhile { it.type == MarkdownTokenTypes.WHITE_SPACE } - .dropLastWhile { it.type == MarkdownTokenTypes.WHITE_SPACE } - .map { childNode -> parseSpanNode(childNode) } - return MarkdownParagraph(children = parsedChildren) - } - - private fun parseSpanNode(astNode: ASTNode): MarkdownSpanNode { - return when (astNode.type) { - MarkdownElementTypes.STRONG, - GFMElementTypes.STRIKETHROUGH, - MarkdownTokenTypes.TEXT, - MarkdownTokenTypes.SETEXT_CONTENT, - MarkdownTokenTypes.ATX_CONTENT, - MarkdownTokenTypes.HTML_TAG, - MarkdownTokenTypes.HTML_BLOCK_CONTENT, - MarkdownTokenTypes.COLON, - MarkdownElementTypes.EMPH -> parseTextNode(astNode) - MarkdownTokenTypes.WHITE_SPACE -> MarkdownWhitespace - MarkdownTokenTypes.EOL -> MarkdownEol - GFMTokenTypes.GFM_AUTOLINK, - MarkdownElementTypes.INLINE_LINK, - MarkdownElementTypes.AUTOLINK -> parseLinkNode(astNode) - MarkdownElementTypes.IMAGE -> parseImageNode(astNode) - MarkdownElementTypes.CODE_SPAN -> parseCodeSpan(astNode) - else -> error("Unsure how to handle type ${astNode.type} inside a PARAGRAPH") - } - } - private fun parseCodeSpan(astNode: ASTNode): MarkdownCodeSpan { - val text = astNode.children - .filterNot { it.type == MarkdownTokenTypes.BACKTICK } - .joinToString(separator = "") { it.getTextInNode(allFileText) } - return MarkdownCodeSpan(text) - } - - private fun parseImageNode(astNode: ASTNode): MarkdownImage { - val imageLink = astNode.children[1] - val link = parseLinkNode(imageLink) - - return MarkdownImage( - imageUrl = link.url, - contentDescription = link.displayText.joinToString(separator = " ") { (it as MarkdownText).text }, - titleText = link.titleText - ) - } - - private fun parseHeaderNode(astNode: ASTNode): MarkdownHeading { - return when (astNode.type) { - MarkdownElementTypes.SETEXT_1, - MarkdownElementTypes.ATX_1 -> MarkdownHeading( - children = astNode.children - .filterNot { - it.type == MarkdownTokenTypes.SETEXT_1 || - it.type == MarkdownTokenTypes.EOL || - it.type == MarkdownTokenTypes.ATX_HEADER - } - .map { parseSpanNode(it) }, - size = MarkdownHeading.Size.Headline1, - ) - MarkdownElementTypes.SETEXT_2, - MarkdownElementTypes.ATX_2 -> MarkdownHeading( - children = astNode.children - .filterNot { - it.type == MarkdownTokenTypes.SETEXT_2 || - it.type == MarkdownTokenTypes.EOL || - it.type == MarkdownTokenTypes.ATX_HEADER - } - .map { parseSpanNode(it) }, - size = MarkdownHeading.Size.Headline2, - ) - MarkdownElementTypes.ATX_3 -> MarkdownHeading( - children = astNode.children - .filterNot { it.type == MarkdownTokenTypes.ATX_HEADER } - .map { parseSpanNode(it) }, - size = MarkdownHeading.Size.Headline3, - ) - MarkdownElementTypes.ATX_4 -> MarkdownHeading( - children = astNode.children - .filterNot { it.type == MarkdownTokenTypes.ATX_HEADER } - .map { parseSpanNode(it) }, - size = MarkdownHeading.Size.Headline4, - ) - MarkdownElementTypes.ATX_5 -> MarkdownHeading( - children = astNode.children - .filterNot { it.type == MarkdownTokenTypes.ATX_HEADER } - .map { parseSpanNode(it) }, - size = MarkdownHeading.Size.Headline5, - ) - MarkdownElementTypes.ATX_6 -> MarkdownHeading( - children = astNode.children - .filterNot { it.type == MarkdownTokenTypes.ATX_HEADER } - .map { parseSpanNode(it) }, - size = MarkdownHeading.Size.Headline6, - ) - else -> error("Unsure how to handle header type ${astNode.type}") - } - } - - private fun parseTextNode(astNode: ASTNode): MarkdownText { - return when (astNode.type) { - MarkdownTokenTypes.SETEXT_CONTENT, - MarkdownTokenTypes.ATX_CONTENT, - MarkdownTokenTypes.HTML_TAG, - MarkdownTokenTypes.HTML_BLOCK_CONTENT, - MarkdownTokenTypes.COLON, - MarkdownTokenTypes.TEXT -> MarkdownText( - text = astNode.getTextInNode(allFileText).trim().toString(), - isBold = false, - isItalics = false, - isStrikethrough = false - ) - MarkdownElementTypes.STRONG, - GFMElementTypes.STRIKETHROUGH, - MarkdownElementTypes.EMPH -> MarkdownText( - text = astNode.children - .filter { it.type == MarkdownTokenTypes.TEXT || it.type == MarkdownTokenTypes.WHITE_SPACE } - .joinToString { it.getTextInNode(allFileText) }, - isBold = astNode.type == MarkdownElementTypes.STRONG, - isItalics = astNode.type == MarkdownElementTypes.EMPH, - isStrikethrough = astNode.type == GFMElementTypes.STRIKETHROUGH, - ) - else -> error("Unsure how to handle text type ${astNode.type} ") - } - } - - private fun parseLinkNode(astNode: ASTNode): MarkdownLink { - return when (astNode.type) { - MarkdownElementTypes.AUTOLINK -> { - val url = astNode.children - .filter { it.type == MarkdownTokenTypes.AUTOLINK } - .joinToString(separator = "") { it.getTextInNode(allFileText) } - MarkdownLink( - displayText = listOf( - MarkdownText( - text = url, - isBold = false, - isItalics = false, - isStrikethrough = false - ) - ), - url = url, - titleText = null - ) - } - MarkdownElementTypes.INLINE_LINK -> { - val link = astNode.children - .first { it.type == MarkdownElementTypes.LINK_DESTINATION } - .getTextInNode(allFileText) - val label = astNode.children - .first { it.type == MarkdownElementTypes.LINK_TEXT } - .children - .filterNot { it.type == MarkdownTokenTypes.LBRACKET || it.type == MarkdownTokenTypes.RBRACKET } - .map { parseSpanNode(it) } - val titleText = astNode.children - .firstOrNull { it.type == MarkdownElementTypes.LINK_TITLE } - ?.children - ?.first { it.type == MarkdownTokenTypes.TEXT } - ?.getTextInNode(allFileText) - MarkdownLink( - displayText = label, - url = link.toString(), - titleText = titleText?.toString() - ) - } - GFMTokenTypes.GFM_AUTOLINK -> { - val url = astNode.getTextInNode(allFileText).toString() - MarkdownLink( - displayText = listOf( - MarkdownText( - text = url, - isBold = false, - isItalics = false, - isStrikethrough = false - ) - ), - url = url, - titleText = null - ) - } - else -> { - error("Unsure how to handle link type ${astNode.type}") - } - } - } -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/BlockQuoteStyle.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/BlockQuoteStyle.kt deleted file mode 100644 index d5eef2c1..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/BlockQuoteStyle.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.nasdroid.core.markdown.style - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape - -/** - * Describes how a Markdown block quote should appear. - * - * @property background The color of the code block background. - * @property shape The shape of the code block. - * @property innerPadding The padding between the edge of the block quote bounds and the content - * inside it. - */ -data class BlockQuoteStyle( - val background: Color, - val shape: Shape, - val innerPadding: PaddingValues -) diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/CodeBlockStyle.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/CodeBlockStyle.kt deleted file mode 100644 index 5893e3f9..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/CodeBlockStyle.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.nasdroid.core.markdown.style - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape - -/** - * Describes how a Markdown code block should appear. - * - * @property background The color of the code block background. - * @property shape The shape of the code block. - * @property innerPadding The padding between the edge of the block quote bounds and the content - * inside it. - */ -data class CodeBlockStyle( - val background: Color, - val shape: Shape, - val innerPadding: PaddingValues = PaddingValues() -) diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/Material3Ext.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/Material3Ext.kt deleted file mode 100644 index 36e6ec69..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/Material3Ext.kt +++ /dev/null @@ -1,88 +0,0 @@ -@file:Suppress("ForbiddenImport") -package com.nasdroid.core.markdown.style - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.unit.dp - -/** - * Constructs a [TextStyles] using recommended defaults from your Material 3 theme. - */ -@Composable -fun m3TextStyles( - textColor: Color = LocalContentColor.current, - textStyle: TextStyle = MaterialTheme.typography.bodyLarge.copy(color = textColor), - headline1: TextStyle = MaterialTheme.typography.displaySmall.copy(color = textColor), - headline2: TextStyle = MaterialTheme.typography.headlineLarge.copy(color = textColor), - headline3: TextStyle = MaterialTheme.typography.headlineMedium.copy(color = textColor), - headline4: TextStyle = MaterialTheme.typography.headlineSmall.copy(color = textColor), - headline5: TextStyle = MaterialTheme.typography.titleLarge.copy(color = textColor), - headline6: TextStyle = MaterialTheme.typography.titleMedium.copy(color = textColor), -): TextStyles { - return TextStyles( - textStyle = textStyle, - headline1 = headline1, - headline2 = headline2, - headline3 = headline3, - headline4 = headline4, - headline5 = headline5, - headline6 = headline6, - ) -} - -/** - * Constructs a [TextStyleModifiers] using recommended defaults from your Material 3 theme. - */ -@Composable -fun m3TextStyleModifiers( - linkColor: Color = MaterialTheme.colorScheme.primary -): TextStyleModifiers { - return TextStyleModifiers( - bold = { it.copy(fontWeight = FontWeight.Bold) }, - italics = { it.copy(fontStyle = FontStyle.Italic) }, - strikethrough = { it.copy(textDecoration = TextDecoration.LineThrough) }, - link = { it.copy(color = linkColor, textDecoration = TextDecoration.Underline) }, - code = { it.copy(fontFamily = FontFamily.Monospace) } - ) -} - -/** - * Constructs a [BlockQuoteStyle] using recommended defaults for your Material 3 theme. - */ -@Composable -fun m3BlockQuoteStyle( - background: Color = MaterialTheme.colorScheme.surfaceVariant, - shape: Shape = MaterialTheme.shapes.medium, - innerPadding: PaddingValues = PaddingValues(8.dp) -): BlockQuoteStyle { - return BlockQuoteStyle( - background = background, - shape = shape, - innerPadding = innerPadding - ) -} - -/** - * Constructs a [CodeBlockStyle] using recommended defaults for your Material 3 theme. - */ -@Composable -fun m3CodeBlockStyle( - background: Color = MaterialTheme.colorScheme.surfaceVariant, - shape: Shape = MaterialTheme.shapes.medium, - innerPadding: PaddingValues = PaddingValues(8.dp) -): CodeBlockStyle { - return CodeBlockStyle( - background = background, - shape = shape, - innerPadding = innerPadding - ) -} diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextStyles.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextStyles.kt deleted file mode 100644 index bd08e876..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextStyles.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.nasdroid.core.markdown.style - -import androidx.compose.ui.text.TextStyle - -/** - * Describes the base set of text styles that can be rendered in the Markdown document. For - * additional formatting, see [TextStyleModifiers]. - * - * @property textStyle The standard text style. This is used for paragraphs. - * @property headline1 The largest possible headline style. - * @property headline2 The second largest possible headline style. - * @property headline3 The third largest possible headline style. - * @property headline4 The third smallest possible headline style. - * @property headline5 The second smallest possible headline style. - * @property headline6 The smallest possible headline style. - */ -data class TextStyles( - val textStyle: TextStyle, - val headline1: TextStyle, - val headline2: TextStyle, - val headline3: TextStyle, - val headline4: TextStyle, - val headline5: TextStyle, - val headline6: TextStyle, -) - -/** - * Provides functions to modify a [TextStyle], producing a style for a particular text format. It is - * recommended to modify the provided TextStyle, which may already be stylized for other formatting. - * - * @property bold A function that produces a [TextStyle] for bold text. - * @property italics A function that produces a [TextStyle] for italicized text. - * @property strikethrough A function that produces a [TextStyle] for strikethrough text. - * @property link A function that produces a [TextStyle] for clickable link text. - * @property code A function that produces a [TextStyle] for inline code text. - */ -data class TextStyleModifiers( - val bold: (TextStyle) -> TextStyle, - val italics: (TextStyle) -> TextStyle, - val strikethrough: (TextStyle) -> TextStyle, - val link: (TextStyle) -> TextStyle, - val code: (TextStyle) -> TextStyle, -) diff --git a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextUnitSize.kt b/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextUnitSize.kt deleted file mode 100644 index 1277888d..00000000 --- a/compose-markdown/src/main/kotlin/com/nasdroid/core/markdown/style/TextUnitSize.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.nasdroid.core.markdown.style - -import androidx.compose.ui.unit.TextUnit - -/** - * Describes the size of an element rendered inline with text. - * - * @property width The width of the element. - * @property height THe height of the element. - */ -data class TextUnitSize( - val width: TextUnit, - val height: TextUnit, -) diff --git a/compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeBuilders.kt b/compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeBuilders.kt deleted file mode 100644 index 839d3543..00000000 --- a/compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeBuilders.kt +++ /dev/null @@ -1,128 +0,0 @@ -package com.nasdroid.core.markdown - -import com.nasdroid.core.markdown.generator.MarkdownBlockQuote -import com.nasdroid.core.markdown.generator.MarkdownCodeBlock -import com.nasdroid.core.markdown.generator.MarkdownCodeSpan -import com.nasdroid.core.markdown.generator.MarkdownHeading -import com.nasdroid.core.markdown.generator.MarkdownImage -import com.nasdroid.core.markdown.generator.MarkdownLink -import com.nasdroid.core.markdown.generator.MarkdownListItem -import com.nasdroid.core.markdown.generator.MarkdownNode -import com.nasdroid.core.markdown.generator.MarkdownOrderedList -import com.nasdroid.core.markdown.generator.MarkdownParagraph -import com.nasdroid.core.markdown.generator.MarkdownSpanNode -import com.nasdroid.core.markdown.generator.MarkdownTable -import com.nasdroid.core.markdown.generator.MarkdownText -import com.nasdroid.core.markdown.generator.MarkdownUnorderedList - -object MarkdownNodeBuilders { - fun markdownUnorderedList(vararg listItems: MarkdownListItem): MarkdownUnorderedList { - return MarkdownUnorderedList(listItems.toList()) - } - - fun markdownOrderedList(vararg listItems: MarkdownListItem): MarkdownOrderedList { - return MarkdownOrderedList(listItems.toList()) - } - - fun markdownListItem(vararg content: MarkdownNode): MarkdownListItem { - return MarkdownListItem(content.toList()) - } - - fun markdownTable( - vararg columns: MarkdownTable.Column - ): MarkdownTable { - return MarkdownTable(columns.toList()) - } - - fun markdownTableColumn( - header: MarkdownParagraph, - alignment: MarkdownTable.Alignment = MarkdownTable.Alignment.LEFT, - vararg cells: MarkdownParagraph - ): MarkdownTable.Column { - return MarkdownTable.Column( - header = header, - alignment = alignment, - cells = cells.toList() - ) - } - - fun markdownImage( - contentDescription: String, - imageUrl: String, - titleText: String? = null - ): MarkdownImage { - return MarkdownImage( - imageUrl = imageUrl, - contentDescription = contentDescription, - titleText = titleText - ) - } - - fun markdownCodeBlock( - text: String, - language: String? = null - ): MarkdownCodeBlock { - return MarkdownCodeBlock( - code = text, - language = language - ) - } - - fun markdownBlockQuote( - vararg children: MarkdownNode - ): MarkdownBlockQuote { - return MarkdownBlockQuote( - children = children.toList() - ) - } - - fun markdownParagraph( - vararg children: MarkdownSpanNode - ): MarkdownParagraph { - return MarkdownParagraph( - children = children.toList() - ) - } - - fun markdownCodeSpan( - text: String - ): MarkdownCodeSpan { - return MarkdownCodeSpan(text) - } - - fun markdownText( - text: String, - isBold: Boolean = false, - isItalics: Boolean = false, - isStrikethrough: Boolean = false, - ): MarkdownText { - return MarkdownText( - text = text, - isBold = isBold, - isItalics = isItalics, - isStrikethrough = isStrikethrough - ) - } - - fun markdownLink( - link: String, - text: List = listOf(markdownText(link)), - altText: String? = null - ): MarkdownLink { - return MarkdownLink( - displayText = text, - url = link, - titleText = altText - ) - } - - fun markdownHeader( - size: MarkdownHeading.Size, - vararg children: MarkdownSpanNode - ): MarkdownHeading { - return MarkdownHeading( - children = children.toList(), - size = size - ) - } -} diff --git a/compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeGeneratorTest.kt b/compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeGeneratorTest.kt deleted file mode 100644 index 8fa6f823..00000000 --- a/compose-markdown/src/test/kotlin/com/nasdroid/core/markdown/MarkdownNodeGeneratorTest.kt +++ /dev/null @@ -1,434 +0,0 @@ -package com.nasdroid.core.markdown - -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownBlockQuote -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownCodeBlock -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownCodeSpan -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownHeader -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownImage -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownOrderedList -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownParagraph -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownTable -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownTableColumn -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownText -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownUnorderedList -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownLink -import com.nasdroid.core.markdown.MarkdownNodeBuilders.markdownListItem -import com.nasdroid.core.markdown.generator.MarkdownEol -import com.nasdroid.core.markdown.generator.MarkdownHeading -import com.nasdroid.core.markdown.generator.MarkdownNode -import com.nasdroid.core.markdown.generator.MarkdownNodeGenerator -import com.nasdroid.core.markdown.generator.MarkdownParagraph -import com.nasdroid.core.markdown.generator.MarkdownRule -import com.nasdroid.core.markdown.generator.MarkdownSpanNode -import com.nasdroid.core.markdown.generator.MarkdownTable -import com.nasdroid.core.markdown.generator.MarkdownWhitespace -import org.intellij.markdown.ast.ASTNode -import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor -import org.intellij.markdown.parser.MarkdownParser -import kotlin.test.Test -import kotlin.test.assertEquals - -class MarkdownNodeGeneratorTest { - - companion object { - private val ITALICS_PATTERNS = mapOf( - "*asterisks*" to markdownText(text = "asterisks", isItalics = true), - "_underscores_" to markdownText(text = "underscores", isItalics = true), - "*multi word asterisks*" to markdownText(text = "multi word asterisks", isItalics = true), - "_multi word underscores_" to markdownText(text = "multi word underscores", isItalics = true), - ) - - private val BOLD_PATTERNS = mapOf( - "**asterisks**" to markdownText(text = "asterisks", isBold = true), - "__underscores__" to markdownText(text = "underscores", isBold = true), - "**multi word asterisks**" to markdownText(text = "multi word asterisks", isBold = true), - "__multi word underscores__" to markdownText(text = "multi word underscores", isBold = true), - ) - - private val STRIKETHROUGH_PATTERNS = mapOf( - "~~strikethrough~~" to markdownText(text = "strikethrough", isStrikethrough = true), - "~~multi word strikethrough~~" to - markdownText(text = "multi word strikethrough", isStrikethrough = true) - ) - - private val MONOSPACE_PATTERNS = mapOf( - "`monospace`" to markdownCodeSpan("monospace"), - "` `" to markdownCodeSpan(" "), - "`multi word monospace`" to markdownCodeSpan("multi word monospace") - ) - - private val RULE_PATTERNS = mapOf( - "---" to MarkdownRule - ) - - private val CODEBLOCK_PATTERNS = mapOf( - """ - ```kotlin - val codeBlockTest = true - ``` - """.trimIndent() to markdownCodeBlock(text = "val codeBlockTest = true", language = "kotlin"), - """ - ```kotlin - val codeBlockTest = true - val secondLine = true - ``` - """.trimIndent() to markdownCodeBlock( - text = "val codeBlockTest = true\nval secondLine = true", - language = "kotlin" - ), - """ - ```kotlin - val codeBlockTest = true - - val secondLine = true - ``` - """.trimIndent() to markdownCodeBlock( - text = "val codeBlockTest = true\n\nval secondLine = true", - language = "kotlin" - ), - ) - - private val BLOCKQUOTE_PATTERNS = mapOf( - "> this is a block quote" to markdownBlockQuote( - markdownParagraph( - markdownText("this is a block quote") - ) - ), - """ - > > What on earth - > - > > Is this - > - > # Heading - """.trimIndent() to markdownBlockQuote( - markdownBlockQuote( - markdownParagraph(markdownText("What on earth")) - ), - markdownBlockQuote( - markdownParagraph(markdownText("Is this")) - ), - markdownHeader(MarkdownHeading.Size.Headline1, markdownText("Heading")), - ) - ) - - private val PARAGRAPH_PATTERNS = mapOf( - "**bold** _italics_ ~~strikethrough~~ [Google](https://google.com)" to markdownParagraph( - markdownText("bold", isBold = true), - MarkdownWhitespace, - markdownText("italics", isItalics = true), - MarkdownWhitespace, - markdownText("strikethrough", isStrikethrough = true), - MarkdownWhitespace, - markdownLink("https://google.com", listOf(markdownText("Google"))) - ), - """ - **bold** _italics_ - [Google](https://google.com) - This is a single newline test - """.trimIndent() to markdownParagraph( - markdownText("bold", isBold = true), - MarkdownWhitespace, - markdownText("italics", isItalics = true), - MarkdownEol, - markdownLink("https://google.com", listOf(markdownText("Google"))), - MarkdownEol, - markdownText("This is a single newline test") - ), - "un*frigging*believable" to markdownParagraph( - markdownText("un"), - markdownText("frigging", isItalics = true), - markdownText("believable") - ) - ) - - private val LINK_PATTERNS = mapOf( - "https://google.com" to markdownLink("https://google.com"), - "" to markdownLink("https://google.com"), - "[Google](https://google.com)" to markdownLink( - link = "https://google.com", - text = listOf(markdownText("Google")) - ), - "[*Google*](https://google.com)" to markdownLink( - link = "https://google.com", - text = listOf(markdownText("Google", isItalics = true)) - ), - "[**Google**](https://google.com)" to markdownLink( - link = "https://google.com", - text = listOf(markdownText("Google", isBold = true)) - ), - "[Google](https://google.com \"Google\")" to markdownLink( - link = "https://google.com", - text = listOf(markdownText("Google")), - altText = "Google" - ), - ) - - private val PLAINTEXT_PATTERNS = mapOf( - "text" to markdownText(text = "text"), - "one two three" to markdownText("one two three") - ) - - private val HEADER_PATTERNS = mapOf( - """ - H1 - === - """.trimIndent() to markdownHeader(MarkdownHeading.Size.Headline1, markdownText("H1")), - "# H1" to markdownHeader(MarkdownHeading.Size.Headline1, markdownText("H1")), - """ - H2 - --- - """.trimIndent() to markdownHeader(MarkdownHeading.Size.Headline2, markdownText("H2")), - "## H2" to markdownHeader(MarkdownHeading.Size.Headline2, markdownText("H2")), - "### H3" to markdownHeader(MarkdownHeading.Size.Headline3, markdownText("H3")), - "#### H4" to markdownHeader(MarkdownHeading.Size.Headline4, markdownText("H4")), - "##### H5" to markdownHeader(MarkdownHeading.Size.Headline5, markdownText("H5")), - "###### H6" to markdownHeader(MarkdownHeading.Size.Headline6, markdownText("H6")), - ) - - private val IMAGE_PATTERNS = mapOf( - "![alt text](https://test.image)" to markdownImage("alt text", "https://test.image"), - "![alt text](https://test.image \"Test image\")" to markdownImage("alt text", "https://test.image", "Test image") - ) - - private val TABLE_PATTERNS = mapOf( - """ - | foo | bar | - | --- | --- | - | baz | bim | - """.trimIndent() to markdownTable( - markdownTableColumn( - markdownParagraph(markdownText("foo")), - MarkdownTable.Alignment.LEFT, - markdownParagraph(markdownText("baz")) - ), - markdownTableColumn( - markdownParagraph(markdownText("bar")), - MarkdownTable.Alignment.LEFT, - markdownParagraph(markdownText("bim")) - ) - ), - """ - | foo | bar | baz | - | :--- | ---: | :---: | - """.trimIndent() to markdownTable( - markdownTableColumn( - markdownParagraph(markdownText("foo")), - MarkdownTable.Alignment.LEFT, - ), - markdownTableColumn( - markdownParagraph(markdownText("bar")), - MarkdownTable.Alignment.RIGHT, - ), - markdownTableColumn( - markdownParagraph(markdownText("baz")), - MarkdownTable.Alignment.CENTER, - ) - ) - ) - - private val UNORDERED_LIST_PATTERNS = mapOf( - """ - * Apples - * Oranges - * Pears - """.trimIndent() to markdownUnorderedList( - markdownListItem(markdownParagraph(markdownText("Apples"))), - markdownListItem(markdownParagraph(markdownText("Oranges"))), - markdownListItem(markdownParagraph(markdownText("Pears"))), - ), - """ - - Apples - - Oranges - - Pears - """.trimIndent() to markdownUnorderedList( - markdownListItem(markdownParagraph(markdownText("Apples"))), - markdownListItem(markdownParagraph(markdownText("Oranges"))), - markdownListItem(markdownParagraph(markdownText("Pears"))), - ), - """ - + Apples - + Oranges - + Pears - """.trimIndent() to markdownUnorderedList( - markdownListItem(markdownParagraph(markdownText("Apples"))), - markdownListItem(markdownParagraph(markdownText("Oranges"))), - markdownListItem(markdownParagraph(markdownText("Pears"))), - ), - ) - - private val ORDERED_LIST_PATTERNS = mapOf( - """ - 1. Apples - 2. Oranges - 3. Pears - """.trimIndent() to markdownOrderedList( - markdownListItem(markdownParagraph(markdownText("Apples"))), - markdownListItem(markdownParagraph(markdownText("Oranges"))), - markdownListItem(markdownParagraph(markdownText("Pears"))), - ), - """ - 1) Apples - 2) Oranges - 3) Pears - """.trimIndent() to markdownOrderedList( - markdownListItem(markdownParagraph(markdownText("Apples"))), - markdownListItem(markdownParagraph(markdownText("Oranges"))), - markdownListItem(markdownParagraph(markdownText("Pears"))), - ), - ) - - private val MIXED_LIST_PATTERNS = mapOf( - """ - * Mixed - 1. List - + Containing - 2. Different - * Types - """.trimIndent() to markdownUnorderedList( - markdownListItem( - markdownParagraph(markdownText("Mixed")), - markdownOrderedList( - markdownListItem( - markdownParagraph(markdownText("List")), - markdownUnorderedList( - markdownListItem(markdownParagraph(markdownText("Containing"))) - ) - ), - markdownListItem(markdownParagraph(markdownText("Different"))) - ) - ), - markdownListItem(markdownParagraph(markdownText("Types"))) - ) - ) - - private fun produceMarkdownAstNode(markdown: String): ASTNode { - val flavor = GFMFlavourDescriptor() - val tree = MarkdownParser(flavor).buildMarkdownTreeFromString(markdown) - return tree - } - } - - private fun testSpanParsing(markdown: String, expectedText: MarkdownSpanNode) { - testNodeParsing(markdown, MarkdownParagraph(listOf(expectedText))) - } - - private fun testNodeParsing(markdown: String, expectedNode: MarkdownNode) { - val generator = MarkdownNodeGenerator(markdown, produceMarkdownAstNode(markdown)) - val actual = generator.generateNodes() - assertEquals( - listOf(expectedNode), actual, - "Matching failed for input $markdown" - ) - } - - @Test - fun `plaintext parsing`() { - PLAINTEXT_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - @Test - fun `strikethrough parsing`() { - STRIKETHROUGH_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - - @Test - fun `bold parsing`() { - BOLD_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - - @Test - fun `italics parsing`() { - ITALICS_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - - @Test - fun `header parsing`() { - HEADER_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `link parsing`() { - LINK_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - - @Test - fun `paragraph parsing`() { - PARAGRAPH_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `image parsing`() { - IMAGE_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - - @Test - fun `rule parsing`() { - RULE_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `blockquote parsing`() { - BLOCKQUOTE_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `code span parsing`() { - MONOSPACE_PATTERNS.forEach { (markdown, expected) -> - testSpanParsing(markdown, expected) - } - } - - @Test - fun `code block parsing`() { - CODEBLOCK_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `table parsing`() { - TABLE_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `unordered list parsing`() { - UNORDERED_LIST_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `mixed list parsing`() { - MIXED_LIST_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } - - @Test - fun `ordered list parsing`() { - ORDERED_LIST_PATTERNS.forEach { (markdown, expected) -> - testNodeParsing(markdown, expected) - } - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2184203b..0cb086e3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -79,8 +79,6 @@ junit = "4.13.2" # https://github.com/detekt/detekt/releases. detekt = "1.23.4" -intellijMarkdown = "0.6.1" - [libraries] @@ -106,9 +104,6 @@ apollo-runtime = { group = "com.apollographql.apollo3", name = "apollo-runtime" apollo-cache-memory = { group = "com.apollographql.apollo3", name = "apollo-normalized-cache", version.ref = "apollo" } apollo-cache-sqlite = { group = "com.apollographql.apollo3", name = "apollo-normalized-cache-sqlite", version.ref = "apollo" } coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } -coil-gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" } -coil-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil" } -intellij-markdown = { module = "org.jetbrains:markdown", version.ref = "intellijMarkdown" } kotlin-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutines" } kotlin-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" } datastore = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" } diff --git a/profile/build.gradle.kts b/profile/build.gradle.kts index e43a352c..df9b9a33 100644 --- a/profile/build.gradle.kts +++ b/profile/build.gradle.kts @@ -37,7 +37,6 @@ dependencies { implementation(projects.core) implementation(projects.api.anilist) implementation(projects.api.preferences) - implementation(projects.composeMarkdown) // AndroidX implementation(libs.androidx.activityCompose) diff --git a/settings.gradle.kts b/settings.gradle.kts index f80a0578..340ccfd1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -27,7 +27,6 @@ rootProject.name = "Animite" include( ":api:anilist", ":api:preferences", - ":compose-markdown", ":material-color-utilities", ":core", ":profile",