{"id":13610832,"url":"https://github.com/mikepenz/multiplatform-markdown-renderer","last_synced_at":"2025-05-15T10:03:41.771Z","repository":{"id":37841388,"uuid":"412759104","full_name":"mikepenz/multiplatform-markdown-renderer","owner":"mikepenz","description":"Markdown renderer for Kotlin Multiplatform Projects (Android, iOS, Desktop), using Compose.","archived":false,"fork":false,"pushed_at":"2025-05-09T13:50:40.000Z","size":9993,"stargazers_count":587,"open_issues_count":11,"forks_count":44,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2025-05-09T14:58:35.387Z","etag":null,"topics":["android","compose","hacktoberfest","jvm","kotlin","kotlin-multiplatform","markdown"],"latest_commit_sha":null,"homepage":"https://mikepenz.github.io/multiplatform-markdown-renderer/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikepenz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["mikepenz"]}},"created_at":"2021-10-02T10:09:41.000Z","updated_at":"2025-05-09T13:50:43.000Z","dependencies_parsed_at":"2023-02-08T17:46:11.633Z","dependency_job_id":"ad900c87-e5ba-4597-9245-557bc58187c7","html_url":"https://github.com/mikepenz/multiplatform-markdown-renderer","commit_stats":null,"previous_names":[],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikepenz%2Fmultiplatform-markdown-renderer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikepenz%2Fmultiplatform-markdown-renderer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikepenz%2Fmultiplatform-markdown-renderer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikepenz%2Fmultiplatform-markdown-renderer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikepenz","download_url":"https://codeload.github.com/mikepenz/multiplatform-markdown-renderer/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319716,"owners_count":22051072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose","hacktoberfest","jvm","kotlin","kotlin-multiplatform","markdown"],"created_at":"2024-08-01T19:01:48.413Z","updated_at":"2025-05-15T10:03:36.677Z","avatar_url":"https://github.com/mikepenz.png","language":"Kotlin","funding_links":["https://github.com/sponsors/mikepenz","http://paypal.me/mikepenz"],"categories":["Kotlin","Multiplatform"],"sub_categories":["Android samples"],"readme":"\u003ch1 align=\"center\"\u003e\n  Kotlin Multiplatform Markdown Renderer\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n    ... a Kotlin Multiplatform Markdown Renderer. (Android, Desktop, ...) powered by Compose Multiplatform\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://github.com/mikepenz/multiplatform-markdown-renderer/actions\"\u003e\n\t\t\u003cimg src=\"https://github.com/mikepenz/multiplatform-markdown-renderer/workflows/CI/badge.svg\"/\u003e\n\t\u003c/a\u003e\n    \u003ca href=\"https://central.sonatype.com/artifact/com.mikepenz/multiplatform-markdown-renderer\"\u003e\n        \u003cimg src=\"https://img.shields.io/maven-central/v/com.mikepenz/multiplatform-markdown-renderer?style=flat-square\u0026color=%231B4897\"/\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\u003cbr /\u003e\n\n-------\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"#whats-included-\"\u003eWhat's included 🚀\u003c/a\u003e \u0026bull;\n    \u003ca href=\"#setup\"\u003eSetup 🛠️\u003c/a\u003e \u0026bull;\n    \u003ca href=\"#usage\"\u003eUsage 🛠️\u003c/a\u003e \u0026bull;\n    \u003ca href=\"#license\"\u003eLicense 📓\u003c/a\u003e\n\u003c/p\u003e\n\n-------\n\n### What's included 🚀\n\n- Super simple setup\n- Cross-platform ready\n- Lightweight\n\n-------\n\n## Setup\n\n### Using Gradle\n\n\u003cdetails open\u003e\u003csummary\u003e\u003cb\u003eMultiplatform\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\nFor multiplatform projects specify this single dependency:\n\n```kotlin\ndependencies {\n    implementation(\"com.mikepenz:multiplatform-markdown-renderer:${version}\")\n\n    // Offers Material 2 defaults for Material 2 themed apps (com.mikepenz.markdown.m2.Markdown)\n    implementation(\"com.mikepenz:multiplatform-markdown-renderer-m2:${version}\")\n\n    // Offers Material 3 defaults for Material 3 themed apps (com.mikepenz.markdown.m3.Markdown)\n    implementation(\"com.mikepenz:multiplatform-markdown-renderer-m3:${version}\")\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eJVM\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\nTo use the library on JVM, you have to include:\n\n```kotlin\ndependencies {\n    implementation(\"com.mikepenz:multiplatform-markdown-renderer-jvm:${version}\")\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eAndroid\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\nFor Android a special dependency is available:\n\n```kotlin\ndependencies {\n    implementation(\"com.mikepenz:multiplatform-markdown-renderer-android:${version}\")\n}\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003e [!TIP]\n\u003e Since 0.13.0 the core library does not depend on a Material theme anymore. Include the `-m2`\n\u003e or `-m3` module to get\n\u003e access to the defaults.\n\n\n-------\n\n## Usage\n\n```Kotlin\nval markdown = \"\"\"\n### What's included 🚀\n\n- Super simple setup\n- Cross-platform ready\n- Lightweight\n\"\"\".trimIndent()\n\n//\nMarkdown(markdown)\n```\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eAdvanced Usage\u003c/b\u003e\u003c/summary\u003e\n\u003cp\u003e\n\nThe library offers the ability to modify different behaviour when rendering the markdown.\n\n### Provided custom style\n\n```kotlin\nMarkdown(\n    content,\n    colors = markdownColors(text = Color.Red),\n    typography = markdownTypography(h1 = MaterialTheme.typography.body1)\n)\n```\n\n### Disable Animation\n\nBy default, the `MarkdownText` animates size changes (if images are loaded).\n\n```kotlin\nMarkdown(\n    content,\n    animations = markdownAnimations(\n        animateTextSize = {\n            this\n            /** No animation */\n        }\n    ),\n)\n```\n\n### Extended spans\n\nStarting with 0.16.0 the library includes support\nfor [extended-spans](https://github.com/saket/extended-spans).\n\u003e The library was integrated to make it multiplatform-compatible.\n\u003e All credits for its functionality go to [Saket Narayan](https://github.com/saket).\n\nIt is not enabled by default, however you can enable it quickly by configuring the `extendedSpans`\nfor your `Markdown` composeable.\nDefine the `ExtendedSpans` you want to apply (including optionally your own custom ones) and return\nit.\n\n```kotlin\nMarkdown(\n    content,\n    extendedSpans = markdownExtendedSpans {\n        val animator = rememberSquigglyUnderlineAnimator()\n        remember {\n            ExtendedSpans(\n                RoundedCornerSpanPainter(),\n                SquigglyUnderlineSpanPainter(animator = animator)\n            )\n        }\n    }\n)\n```\n\n### Extend Annotated string handling\n\nThe library already handles a significant amount of different tokens, however not all. To allow\nspecial integrations expand this, you can pass in a custom `annotator` to the `Markdown`\ncomposeable. This `annotator` allows you to customize existing handled tokens, but also add new\nones.\n\n```kotlin\nMarkdown(\n    content,\n    annotator = markdownAnnotator { content, child -\u003e\n        if (child.type == GFMElementTypes.STRIKETHROUGH) {\n            append(\"Replaced you :)\")\n            true // return true to consume this ASTNode child\n        } else false\n    }\n)\n```\n\n### Adjust List Ordering\n\n```kotlin\n// Use the bullet list symbol from the original markdown\nCompositionLocalProvider(LocalBulletListHandler provides { \"$it \" }) {\n    Markdown(content)\n}\n\n// Replace the ordered list symbol with `A.)` instead.\nCompositionLocalProvider(LocalOrderedListHandler provides { \"A.) \" }) {\n    Markdown(content, Modifier.fillMaxSize().padding(16.dp).verticalScroll(scrollState))\n}\n```\n\n### Custom Components\n\nSince v0.9.0 it is possible to provide custom components, instead of the default ones.\nThis can be done by providing the components `MarkdownComponents` to the `Markdown` composable.\n\nUse the `markdownComponents()` to keep defaults for non overwritten components.\n\nThe `MarkdownComponent` will expose access to\nthe `content: String`, `node: ASTNode`, `typography: MarkdownTypography`,\noffering full flexibility.\n\n```kotlin\n// Simple adjusted paragraph with different Modifier.\nval customParagraphComponent: MarkdownComponent = {\n    MarkdownParagraph(it.content, it.node, Modifier.align(Alignment.End))\n}\n\n// Full custom paragraph example\nval customParagraphComponent: MarkdownComponent = {\n    // build a styled paragraph. (util function provided by the library)\n    val styledText = buildAnnotatedString {\n        pushStyle(LocalMarkdownTypography.current.paragraph.toSpanStyle())\n        buildMarkdownAnnotatedString(content, it.node)\n        pop()\n    }\n\n    // define the `Text` composable\n    Text(\n        styledText,\n        modifier = Modifier.align(Alignment.End),\n        textAlign = TextAlign.End\n    )\n}\n\n// Define the `Markdown` composable and pass in the custom paragraph component\nMarkdown(\n    content,\n    components = markdownComponents(\n        paragraph = customParagraphComponent\n    )\n)\n```\n\nAnother example to of a custom component is changing the rendering of an unordered list.\n\n```kotlin\n// Define a custom component for rendering unordered list items in Markdown\nval customUnorderedListComponent: MarkdownComponent = {\n    // Use the MarkdownListItems composable to render the list items\n    MarkdownListItems(it.content, it.node, level = 0) { index, child -\u003e\n        // Render an icon for the bullet point with a green tint\n        Icon(\n            imageVector = icon,\n            tint = Color.Green,\n            contentDescription = null,\n            modifier = Modifier.size(20.dp),\n        )\n    }\n}\n\n// Define the `Markdown` composable and pass in the custom unorderedList component\nMarkdown(\n    content,\n    components = markdownComponents(\n        unorderedList = customUnorderedListComponent\n    )\n)\n```\n\n### Table Support\n\nStarting with 0.30.0, the library includes support for rendering tables in markdown. The `Markdown`\ncomposable will automatically handle table elements in your markdown content.\n\n```kotlin\nval markdown = \"\"\"\n| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1   | Cell 2   |\n| Cell 3   | Cell 4   |\n\"\"\".trimIndent()\n\nMarkdown(markdown)\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n### Image Loading\n\nTo configure image loading, the library offers different implementations, to offer great flexibility\nfor the respective integration.\nAfter adding the dependency, the chosen image transformer implementation has to be passed to the\n`Markdown` API.\n\n\u003e [!NOTE]  \n\u003e Please refer to the official documentation for the specific image loading integration you are using (e.g., coil3) on how to adjust its\n\u003e behavior.\n\n#### coil3\n\n```groovy\n// Offers coil3 (Coil3ImageTransformerImpl)\nimplementation(\"com.mikepenz:multiplatform-markdown-renderer-coil3:${version}\")\n```\n\n```kotlin\nMarkdown(\n    MARKDOWN,\n    imageTransformer = Coil3ImageTransformerImpl,\n)\n```\n\n#### coil2\n\n```groovy\n// Offers coil2 (Coil2ImageTransformerImpl)\nimplementation(\"com.mikepenz:multiplatform-markdown-renderer-coil2:${version}\")\n```\n\n```kotlin\nMarkdown(\n    MARKDOWN,\n    imageTransformer = Coil2ImageTransformerImpl,\n)\n```\n\n### Syntax Highlighting\n\nThe library (introduced with 0.27.0) offers optional support for syntax highlighting via\nthe [Highlights](https://github.com/SnipMeDev/Highlights) project.\nThis support is not included in the core, and can be enabled by adding the\n`multiplatform-markdown-renderer-code`\ndependency.\n\n```groovy\nimplementation(\"com.mikepenz:multiplatform-markdown-renderer-code:${version}\")\n```\n\nOnce added, the `Markdown` has to be configured to use the alternative code highlighter.\n\n```kotlin\n// Use default color scheme\nMarkdown(\n    MARKDOWN,\n    components = markdownComponents(\n        codeBlock = highlightedCodeBlock,\n        codeFence = highlightedCodeFence,\n    )\n)\n\n// ADVANCED: Customize Highlights library by defining different theme\nval isDarkTheme = isSystemInDarkTheme()\nval highlightsBuilder = remember(isDarkTheme) {\n    Highlights.Builder().theme(SyntaxThemes.atom(darkMode = isDarkTheme))\n}\nMarkdown(\n    MARKDOWN,\n    components = markdownComponents(\n        codeBlock = {\n            MarkdownHighlightedCodeBlock(\n                content = it.content,\n                node = it.node,\n                highlights = highlightsBuilder\n            )\n        },\n        codeFence = {\n            MarkdownHighlightedCodeFence(\n                content = it.content,\n                node = it.node,\n                highlights = highlightsBuilder\n            )\n        },\n    )\n)\n```\n\n## Dependency\n\nThis project uses JetBrains [markdown](https://github.com/JetBrains/markdown/) Multiplatform\nMarkdown processor as\ndependency to parse the markdown content.\n\n## Developed By\n\n* Mike Penz\n* [mikepenz.com](http://mikepenz.com) - \u003cmikepenz@gmail.com\u003e\n* [paypal.me/mikepenz](http://paypal.me/mikepenz)\n\n## Contributors\n\nThis free, open source software was also made possible by a group of volunteers that put many hours\nof hard work into\nit. See the [CONTRIBUTORS.md](CONTRIBUTORS.md) file for details.\n\n## Credits\n\nBig thanks to [Erik Hellman](https://twitter.com/ErikHellman) and his awesome article\non [Rendering Markdown with Jetpack Compose](https://www.hellsoft.se/rendering-markdown-with-jetpack-compose/),\nand the related source [MarkdownComposer](https://github.com/ErikHellman/MarkdownComposer).\n\nAlso huge thanks to [Saket Narayan](https://github.com/saket/) for his great work on\nthe [extended-spans](https://github.com/saket/extended-spans) project. Ported into this project to\nmake it multiplatform.\n\n## Fork License\n\nCopyright for portions of the code are held by [Erik Hellman, 2020] as part of\nproject [MarkdownComposer](https://github.com/ErikHellman/MarkdownComposer) under the MIT license.\nAll other copyright\nfor project multiplatform-markdown-renderer are held by [Mike Penz, 2023] under the Apache License,\nVersion 2.0.\n\n## License\n\n    Copyright 2025 Mike Penz\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikepenz%2Fmultiplatform-markdown-renderer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikepenz%2Fmultiplatform-markdown-renderer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikepenz%2Fmultiplatform-markdown-renderer/lists"}