compose-richtext

repository·main·Indexed 21 days ago

https://github.com/halilozercan/compose-richtext

A collection of experimental Compose Multiplatform libraries for Markdown rendering and rich text formatting. It provides modules for Android and Desktop (excluding iOS), including richtext-ui, richtext-markdown, richtext-commonmark, and Material/Material 3 integrations. Key components include the RichText and Markdown composables, as well as manual formatting elements like Heading, BlockQuote, and CodeBlock.

Tokens
3.9K
Snippets
15
Records
19
Agent score
76%

What's inside compose-richtext

  1. Overview of Compose Richtext libraries

    main

    Compose Richtext is a collection of Compose libraries designed for rich text formatting and Markdown rendering. The project consists of several modules that can be used in Android and Desktop Compose applications.

    Available modules include:

    • richtext-ui
    • richtext-markdown
    • richtext-commonmark
    • richtext-ui-material
    • richtext-ui-material3

    Note: This project is pre-v1.0.0. The API is subject to change without deprecation cycles, and performance or stability issues may exist as the project is still maturing.

  2. Overview of compose-richtext

    main

    compose-richtext is a collection of Compose libraries designed for rendering Markdown and handling rich text formatting.

    Key details:

    • Compatibility: All modules are compatible with Compose Multiplatform, though iOS support is currently lacking.
    • Status: The library is considered very experimental, and the development roadmap is currently unclear.
    • Documentation: Detailed documentation can be found at halilibo.com/compose-richtext.
  3. What is richtext-markdown and when to use it?

    main

    The richtext-markdown module is a specialized library for rendering a Markdown tree defined as an AstNode.

    When to use it: Use this module if you already have an AstNode tree (perhaps generated by a custom parser or a 3rd party tool) and you want to render it using Compose.

    When NOT to use it: If your goal is simply to take a raw Markdown string and render it directly, this module alone is insufficient. In that case, you should use richtext-commonmark, which provides the necessary parsing logic to bridge the gap between strings and the AstNode tree.

  4. Integrate custom typography with RichTextThemeProvider

    main

    Use RichTextThemeProvider to connect your application's existing typography and theme system to BasicRichText. The library is designed to work with CompositionLocals that provide TextStyle objects.

    Best Practice: Following Compose Material patterns, your TextStyle should generally not include text color; instead, rely on content color to determine the appropriate text color for the current context (e.g., light vs. dark mode).

  5. Install Compose Richtext via Gradle

    main

    Compose Richtext libraries are published to Maven Central. You can add them to your project using standard Gradle dependency notation. The libraries are Kotlin Multiplatform (KMP) compatible and work in Android and Desktop Compose apps (except for iOS support, which is currently not available).

    To add a library to an Android or Desktop project:

    dependencies {
      implementation("com.halilibo.compose-richtext:<LIBRARY-ARTIFACT>:${richtext_version}")
    }

    To add a library to a Kotlin Multiplatform (KMP) module (e.g., in commonMain):

    val commonMain by getting {
      dependencies {
        implementation("com.halilibo.compose-richtext:richtext-ui:${richtext_version}")
      }
    }
    dependencies {
      implementation("com.halilibo.compose-richtext:<LIBRARY-ARTIFACT>:${richtext_version}")
    }
  6. Render an AstNode using BasicMarkdown

    main

    The primary way to render Markdown content is to pass an AstNode to the BasicMarkdown composable. BasicMarkdown must be called within a RichText scope. Since richtext-markdown only handles rendering the tree, you typically need a parser (such as CommonmarkAstNodeParser from the richtext-commonmark module) to convert a Markdown string into the required AstNode structure.

    RichText(
      modifier = Modifier.padding(16.dp)
    ) {
      // requires richtext-commonmark module.
      val parser = remember(options) { CommonmarkAstNodeParser(options) }
      val astNode = remember(parser) {
        parser.parse(
          """
            # Demo
            
            Emphasis, aka italics, with *asterisks* or _underscores_.
          """.trimIndent()
        )
      }
      BasicMarkdown(astNode)
    }
  7. Add Richtext UI Material to your Gradle dependencies

    main

    To use Material design compatibility with Compose RichText, add the richtext-ui-material dependency to your build.gradle(.kts) file. Ensure you use the appropriate version variable (e.g., ${richtext_version}).

    dependencies {
      implementation("com.halilibo.compose-richtext:richtext-ui-material:${richtext_version}")
    }
  8. Install Richtext UI via Gradle

    main

    To use the base Richtext UI library in your Android or JVM Compose project, add the following dependency to your build.gradle(.kts) file. Replace ${richtext_version} with the desired version of the library.

    dependencies {
      implementation("com.halilibo.compose-richtext:richtext-ui:${richtext_version}")
    }
  9. Add richtext-commonmark to your Gradle dependencies

    main

    To use the Commonmark Markdown parsing and rendering capabilities in your Compose project, add the following dependency to your build.gradle(.kts) file. Replace ${richtext_version} with the appropriate version of the library.

    dependencies {
      implementation("com.halilibo.compose-richtext:richtext-commonmark:${richtext_version}")
    }
  10. Install richtext-markdown via Gradle

    main

    To use the Markdown rendering capabilities, add the richtext-markdown dependency to your Gradle configuration. Note that this module is a building block for rendering an AstNode tree and does not include a Markdown string parser by default. For parsing Markdown strings into AstNode trees, you should use a companion module like richtext-commonmark.

    dependencies {
      implementation("com.halilibo.compose-richtext:richtext-markdown:${richtext_version}")
    }
  11. Add Richtext UI Material 3 to your Gradle dependencies

    main

    To use Material 3 themed RichText in your Compose project, add the following dependency to your build.gradle(.kts) file. Ensure you have defined the richtext_version variable (e.g., 0.20.0).

    dependencies {
      implementation("com.halilibo.compose-richtext:richtext-ui-material3:${richtext_version}")
    }
  12. Example: Comprehensive usage of Richtext UI elements

    main

    The following example demonstrates how to use various high-level formatting components within a BasicRichText block, including headings, lists, horizontal rules, code blocks, block quotes, info panels, and tables.

    BasicRichText(
      modifier = Modifier.background(color = Color.White)
    ) {
      Heading(0, "Paragraphs")
      Text("Simple paragraph.")
      Text("Paragraph with\nmultiple lines.")
      Text("Paragraph with really long line that should be getting wrapped.")
    
      Heading(0, "Lists")
      Heading(1, "Unordered")
      ListDemo(listType = Unordered)
      Heading(1, "Ordered")
      ListDemo(listType = Ordered)
    
      Heading(0, "Horizontal Line")
      Text("Above line")
      HorizontalRule()
      Text("Below line")
    
      Heading(0, "Code Block")
      CodeBlock(
        """
          {
            "Hello": "world!"
          }
        """.trimIndent()
      )
    
      Heading(0, "Block Quote")
      BlockQuote {
        Text("These paragraphs are quoted.")
        Text("More text.")
        BlockQuote {
          Text("Nested block quote.")
        }
      }
    
      Heading(0, "Info Panel")
      InfoPanel(InfoPanelType.Primary, "Only text primary info panel")
      InfoPanel(InfoPanelType.Success) {
        Column {
          Text("Successfully sent some data")
          HorizontalRule()
          BlockQuote {
            Text("This is a quote")
          }
        }
      }
    
      Heading(0, "Table")
      Table(headerRow = {
        cell { Text("Column 1") }
        cell { Text("Column 2") }
      }) {
        row {
          cell { Text("Hello") }
          cell {
            CodeBlock("Foo bar")
          }
        }
        row {
          cell {
            BlockQuote {
              Text("Stuff")
            }
          }
          cell { Text("Hello world that is a really long line that is going to wrap hopefully") }
        }
      }
    }