Skip to content

Commit

Permalink
Merge pull request #45 from halilozercan/halilozercan/dematerialize
Browse files Browse the repository at this point in the history
Remove Material dependency from richtext-ui

Bump versions;
- Compose 1.0.1
- Kotlin 1.5.21
  • Loading branch information
halilozercan authored Aug 6, 2021
2 parents 4d16e56 + 0c44dc0 commit 99ab621
Show file tree
Hide file tree
Showing 34 changed files with 569 additions and 226 deletions.
9 changes: 7 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
buildscript {
ext.versions = [
targetSdk: 30,
compose: '1.0.0',
kotlin: '1.5.10',
compose: '1.0.1',
kotlin: '1.5.21',
commonmark: '0.18.0'
]

Expand All @@ -29,6 +29,10 @@ buildscript {
composeOptions {
kotlinCompilerExtensionVersion versions.compose
}

lintOptions {
disable "ComposableModifierFactory", "ModifierFactoryExtensionFunction", "ModifierFactoryReturnType", "ModifierFactoryUnreferencedReceiver"
}
}

ext.deps = [
Expand Down Expand Up @@ -58,6 +62,7 @@ buildscript {
icons: "androidx.compose.material:material-icons-extended:${versions.compose}",
test: "androidx.ui:ui-test:${versions.compose}",
tooling: "androidx.compose.ui:ui-tooling:${versions.compose}",
tooling_preview: "androidx.compose.ui:ui-tooling-preview:${versions.compose}",
tooling_data: "androidx.compose.ui:ui-tooling-data:${versions.compose}",
],
kotlin: [
Expand Down
76 changes: 40 additions & 36 deletions docs/richtext-commonmark.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Markdown

Library for rendering Markdown in Compose using Atlassian's [CommonMark](https://github.com/atlassian/commonmark-java)
Library for rendering Markdown in Compose using [CommonMark](https://github.com/commonmark/commonmark-java)
library to parse, and `richtext-ui` to render.

## Gradle
Expand All @@ -16,44 +16,48 @@ dependencies {
The simplest way to render markdown is just pass a string to the [`Markdown`](../api/richtext-commonmark/com.zachklipp.richtext.markdown/-markdown.html)
composable:

!!! warning
Markdown composable has recently changed to be an extension on [RichTextScope](../api/richtext-ui/com.zachklipp.richtext.ui/-rich-text-scope/index.html) instead
of being a separate entry composable.

~~~kotlin
Markdown(
"""
# Demo
Emphasis, aka italics, with *asterisks* or _underscores_. Strong emphasis, aka bold, with **asterisks** or __underscores__. Combined emphasis with **asterisks and _underscores_**. [Links with two blocks, text in square-brackets, destination is in parentheses.](https://www.example.com). Inline `code` has `back-ticks around` it.
1. First ordered list item
2. Another item
* Unordered sub-list.
3. And another item.
You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown).
* Unordered list can use asterisks
- Or minuses
+ Or pluses
---
```javascript
var s = "code blocks use monospace font";
alert(s);
```
Markdown | Table | Extension
--- | --- | ---
*renders* | `beautiful images` | ![random image](https://picsum.photos/seed/picsum/400/400 "Text 1")
1 | 2 | 3
> Blockquotes are very handy in email to emulate reply text.
> This line is part of the same quote.
""".trimIndent(),
Modifier.padding(16.dp)
)
RichText(
modifier = Modifier.padding(16.dp)
) {
Markdown(
"""
# Demo
Emphasis, aka italics, with *asterisks* or _underscores_. Strong emphasis, aka bold, with **asterisks** or __underscores__. Combined emphasis with **asterisks and _underscores_**. [Links with two blocks, text in square-brackets, destination is in parentheses.](https://www.example.com). Inline `code` has `back-ticks around` it.
1. First ordered list item
2. Another item
* Unordered sub-list.
3. And another item.
You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown).
* Unordered list can use asterisks
- Or minuses
+ Or pluses
---
```javascript
var s = "code blocks use monospace font";
alert(s);
```
Markdown | Table | Extension
--- | --- | ---
*renders* | `beautiful images` | ![random image](https://picsum.photos/seed/picsum/400/400 "Text 1")
1 | 2 | 3
> Blockquotes are very handy in email to emulate reply text.
> This line is part of the same quote.
""".trimIndent()
)
}
~~~

Which produces something like this:

![markdown demo](img/markdown-demo.png)

The `Markdown` composable also takes an optional `RichTextStyle` which can be used to customize how
it's rendered.
75 changes: 75 additions & 0 deletions docs/richtext-ui-material.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Richtext UI Material

Library that makes RichText compatible with Material design in Compose.

## Gradle

```groovy
dependencies {
implementation "com.halilibo.compose-richtext:richtext-ui-material:${richtext_version}"
}
```

## Usage

`RichText` composable already wraps around `BasicRichText` by using appropriate Material
attributes. You can quickly start by calling `RichText` without any further setup.

```kotlin
RichText(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, "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 this is a really long line that is going to wrap hopefully") }
}
}
}
```
30 changes: 28 additions & 2 deletions docs/richtext-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
A library of composables for formatting text using higher-level concepts than are supported by
compose foundation, such as "bullet lists" and "headings".

RichText UI is a base library that is non-opinionated about higher level design requirements.
If you are already using `MaterialTheme` in your compose app, you can jump to [RichText UI Material](../richtext-ui-material/index.html)
for quick start.

## Gradle

```groovy
Expand All @@ -11,12 +15,34 @@ dependencies {
}
```

## [`BasicRichText`](../api/richtext-ui/com.zachklipp.richtext.ui/-basic-rich-text.html)

Richtext UI does not depend on Material artifact of Compose. Design agnostic API allows anyone
to adopt RichText UI and its extensions like Markdown to their own design and typography systems.

If you are planning to adopt RichText within your design system, please go ahead and check out [`RichText Material`](../richtext-ui-material/index.html)
for inspiration.

## [`RichTextScope`](../api/richtext-ui/com.zachklipp.richtext.ui/-rich-text-scope/index.html)

`RichTextScope` is a context wrapper around composables that integrate and play well within RichText
content. Scope carries information about the current `TextStyle` and `ContentColor` which enables anyone
to adopt `BasicRichText` by passing their own typography in the composition tree. `ProvideTextStyle` and
`ProvideContentColor` functions also serve to pass updated text styles from RichText context to outer
design system.

RichTextScope also offers a `Default` implementation that sets up an internal design system to
easily test the library.

## Example

Open the `Demo.kt` file in the `richtext-ui` module to play with this.
Open the `Demo.kt` file in the `sample` module to play with this. Although the mentioned demo
uses Material integrated version of `BasicRichText`, they share 99% of their API.

```kotlin
RichText(modifier = Modifier.background(color = Color.White)) {
RichTextScope.Default.BasicRichText(
modifier = Modifier.background(color = Color.White)
) {
Heading(0, "Paragraphs")
Text("Simple paragraph.")
Text("Paragraph with\nmultiple lines.")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ kotlin.code.style=official
systemProp.org.gradle.internal.publish.checksums.insecure=true

GROUP=com.halilibo.compose-richtext
VERSION_NAME=0.5.0
VERSION_NAME=0.6.0

POM_DESCRIPTION=A collection of Compose libraries for advanced text formatting and alternative display types.

Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ markdown_extensions:

nav:
- index.md
- richtext-ui-material.md
- richtext-ui.md
- richtext-commonmark.md
- printing.md
Expand Down
2 changes: 1 addition & 1 deletion richtext-commonmark/api/richtext-commonmark.api
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public final class com/zachklipp/richtext/markdown/ComposableSingletons$Markdown
}

public final class com/zachklipp/richtext/markdown/MarkdownKt {
public static final fun Markdown (Ljava/lang/String;Landroidx/compose/ui/Modifier;Lcom/zachklipp/richtext/ui/RichTextStyle;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V
public static final fun Markdown (Lcom/zachklipp/richtext/ui/RichTextScope;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.zachklipp.richtext.markdown

import android.annotation.SuppressLint
import android.os.Build
import android.text.Html
import android.widget.TextView
Expand All @@ -10,7 +11,6 @@ import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.viewinterop.AndroidView
import com.zachklipp.richtext.markdown.extensions.AstTableRoot
Expand All @@ -20,9 +20,7 @@ import com.zachklipp.richtext.ui.FormattedList
import com.zachklipp.richtext.ui.Heading
import com.zachklipp.richtext.ui.HorizontalRule
import com.zachklipp.richtext.ui.ListType
import com.zachklipp.richtext.ui.RichText
import com.zachklipp.richtext.ui.RichTextScope
import com.zachklipp.richtext.ui.RichTextStyle
import com.zachklipp.richtext.ui.string.InlineContent
import com.zachklipp.richtext.ui.string.Text
import com.zachklipp.richtext.ui.string.richTextString
Expand All @@ -31,35 +29,27 @@ import org.commonmark.ext.gfm.tables.TablesExtension
import org.commonmark.parser.Parser

/**
* A composable that renders Markdown content using [RichText].
* A composable that renders Markdown content using RichText.
*
* @param content Markdown text. No restriction on length.
* @param style [RichTextStyle] that will be used to style markdown rendering.
* @param onLinkClicked A function to invoke when a link is clicked from rendered content.
*/
@Composable
public fun Markdown(
public fun RichTextScope.Markdown(
content: String,
modifier: Modifier = Modifier,
style: RichTextStyle? = null,
onLinkClicked: ((String) -> Unit)? = null
) {
RichText(
modifier = modifier,
style = style
) {
// Can't use UriHandlerAmbient.current::openUri here,
// see https://issuetracker.google.com/issues/172366483
val realLinkClickedHandler = onLinkClicked ?: LocalUriHandler.current.let {
remember {
{ url -> it.openUri(url) }
}
// Can't use UriHandlerAmbient.current::openUri here,
// see https://issuetracker.google.com/issues/172366483
val realLinkClickedHandler = onLinkClicked ?: LocalUriHandler.current.let {
remember {
{ url -> it.openUri(url) }
}
}

CompositionLocalProvider(LocalOnLinkClicked provides realLinkClickedHandler) {
val markdownAst = parsedMarkdownAst(text = content)
RecursiveRenderMarkdownAst(astNode = markdownAst)
}
CompositionLocalProvider(LocalOnLinkClicked provides realLinkClickedHandler) {
val markdownAst = parsedMarkdownAst(text = content)
RecursiveRenderMarkdownAst(astNode = markdownAst)
}
}

Expand All @@ -71,7 +61,7 @@ public fun Markdown(
*
* This function basically receives a node from the tree, root or any node, and then
* recursively travels along the nodes while spitting out or wrapping composables around
* the content. [RichText] API is highly compatible with this methodology.
* the content. RichText API is highly compatible with this method.
*
* However, there are multiple assumptions to increase predictability. Despite the fact
* that every [AstNode] can have another [AstNode] as a child, it should not be that
Expand Down Expand Up @@ -195,6 +185,7 @@ internal fun parsedMarkdownAst(text: String): AstNode? {
*
* @param node Root ASTNode whose children will be visited.
*/
@SuppressLint("ComposableNaming")
@Composable
internal fun RichTextScope.visitChildren(node: AstNode?) {
node?.childrenSequence()?.forEach {
Expand Down
20 changes: 20 additions & 0 deletions richtext-ui-material/api/richtext-ui-material.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
public final class com/zachklipp/richtext/ui/material/BuildConfig {
public static final field BUILD_TYPE Ljava/lang/String;
public static final field DEBUG Z
public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String;
public fun <init> ()V
}

public final class com/zachklipp/richtext/ui/material/ComposableSingletons$RichTextKt {
public static final field INSTANCE Lcom/zachklipp/richtext/ui/material/ComposableSingletons$RichTextKt;
public static field lambda-1 Lkotlin/jvm/functions/Function4;
public static field lambda-2 Lkotlin/jvm/functions/Function4;
public fun <init> ()V
public final fun getLambda-1$richtext_ui_material_release ()Lkotlin/jvm/functions/Function4;
public final fun getLambda-2$richtext_ui_material_release ()Lkotlin/jvm/functions/Function4;
}

public final class com/zachklipp/richtext/ui/material/RichTextKt {
public static final fun RichText (Landroidx/compose/ui/Modifier;Lcom/zachklipp/richtext/ui/RichTextStyle;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
}

16 changes: 16 additions & 0 deletions richtext-ui-material/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
plugins {
id('org.jetbrains.dokka')
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply from: rootProject.file('gradle/maven-publish.gradle')

android rootProject.ext.defaultAndroidConfig

dependencies {
compileOnly deps.compose.tooling

api project(":richtext-ui")
implementation deps.compose.material
}
Empty file.
Loading

0 comments on commit 99ab621

Please sign in to comment.