
HTML and Markdown rendering component enabling rich text display with customizable CSS and tag processing. Supports HTML tags like headings, links, lists, and images.
RtText是Kotlin Multiplatform 库,支持多平台IOS、Android、Desktop。
RtText目前支持的HTML标签有:h1,h2,h3,h4,h5,h6,a,b,strong,ol,ul,p,img,table
implementation("cn.changjiahong:RtText:<version>") val license = "勾选即代表你同意本应用<a href=\"https://ex.license.com\"><b>使用协议</b></a>。"
RtHtml(
license,
modifier = Modifier.fillMaxSize(),
linkAction = { link ->
openLink(link)
}
) val regsiter =
"你还没有账号?点击跳转<a style=\" color:#ffdd0000\" href=\"register\"><b>注册</b></a>。"
RtHtml(
regsiter,
modifier = Modifier.fillMaxSize(),
linkAction = { tag ->
when(tag){
"register" -> goToRegister()
}
}
)
RtText默认提供了一组github风格CSS,你也可以自定义CSS。
val customCss = """
.post-md
{
width: 100%;
font-size: 16.8px;
letter-spacing: 0;
}
.post-md h1,
.post-md h2,
.post-md h3,
.post-md h4,
.post-md h5,
.post-md h6
{
color: #000;
margin: 12px 0;
}
.post-md h1
{
font-size: 2.5rem;
line-height: 1.2;
padding: 24px 0;
}
.post-md h2
{
font-size: 2rem;
line-height: 1.2;
padding: 20px 0;
}
.post-md h3
{
font-size: 1.75rem;
line-height: 1.2;
padding: 18px 0;
}
.post-md h4
{
font-size: 1.5rem;
line-height: 1.2;
padding: 16px 0;
}
.post-md h5
{
font-size: 1.25rem;
line-height: 1.2;
padding: 14px 0;
}
.post-md h6
{
font-size: 1.125rem;
line-height: 1.2;
padding: 12px 0;
}
.post-md a
{
color: #666;
box-shadow: 0 2px 0 #ccc;
/* transition: color ease-in-out .65s, box-shadow ease-in-out .65s; */
}
""".trimIndent()
RtHtml(
html,
css = customCss,
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
linkAction = {
println(it)
}
)
RtText默认支持的标签处理器defaultNodeHandlers,若要扩展新的处理器,则只需要实现NodeHandler并注册即可。
// 自定义blod标签,支持字体加粗显示
val blod = NodeHandler("blod") { node: Node ->
val (spanStyle, paragraphStyle) = node.parseStyle()
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold).merge(spanStyle)) {
appendChild(node)
}
}
// nodeHandlers里注册blod
RtHtml(
html,
nodeHandlers = mutableListOf(blod).apply { addAll(defaultNodeHandlers) },
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
linkAction = {
println(it)
}
)RtText中若要绘制特殊显示,如img,table等标签,则可实现InlineNodeProcessor处理器。
// 代码块标签处理器
val code =
InlineNodeProcessor("code") {
val param: Param = Json.decodeFromString(it)
val codeNode = Ksoup.parse(param.contentText).body().firstChild()!!
Box(modifier = Modifier.fillMaxWidth().wrapContentHeight().background(Color.Yellow)) {
Text(codeNode.outHtml())
}
}如果需要改变内嵌控件的高度,则可调用handlerContext.updateInlineContent()更新
val density = LocalDensity.current.density
val fontScale = LocalDensity.current.fontScale
val handlerContext = LocalHandlerContext.current
Box(modifier = Modifier
.onSizeChanged { size ->
handlerContext.updateInlineContent(
param, (size.width / density * fontScale).sp,
(size.height / density * fontScale).sp,
)
}){
Text("")
}RtText依赖以下lib,如果你使用了RtText,则不需要再重复添加该库
有关使用和一般查询的问题,请参考GitHub Discussions。
如果您希望贡献,请阅读贡献指南。
要报告任何问题,请访问我们的GitHub Issues,请确保在提交新问题之前检查重复项。
通过加入此存储库的 stargazers 来支持它。⭐
也可以 Follow Me 一起创作吧!🤩
Copyright 2025 ChangJiahong
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
RtText是Kotlin Multiplatform 库,支持多平台IOS、Android、Desktop。
RtText目前支持的HTML标签有:h1,h2,h3,h4,h5,h6,a,b,strong,ol,ul,p,img,table
implementation("cn.changjiahong:RtText:<version>") val license = "勾选即代表你同意本应用<a href=\"https://ex.license.com\"><b>使用协议</b></a>。"
RtHtml(
license,
modifier = Modifier.fillMaxSize(),
linkAction = { link ->
openLink(link)
}
) val regsiter =
"你还没有账号?点击跳转<a style=\" color:#ffdd0000\" href=\"register\"><b>注册</b></a>。"
RtHtml(
regsiter,
modifier = Modifier.fillMaxSize(),
linkAction = { tag ->
when(tag){
"register" -> goToRegister()
}
}
)
RtText默认提供了一组github风格CSS,你也可以自定义CSS。
val customCss = """
.post-md
{
width: 100%;
font-size: 16.8px;
letter-spacing: 0;
}
.post-md h1,
.post-md h2,
.post-md h3,
.post-md h4,
.post-md h5,
.post-md h6
{
color: #000;
margin: 12px 0;
}
.post-md h1
{
font-size: 2.5rem;
line-height: 1.2;
padding: 24px 0;
}
.post-md h2
{
font-size: 2rem;
line-height: 1.2;
padding: 20px 0;
}
.post-md h3
{
font-size: 1.75rem;
line-height: 1.2;
padding: 18px 0;
}
.post-md h4
{
font-size: 1.5rem;
line-height: 1.2;
padding: 16px 0;
}
.post-md h5
{
font-size: 1.25rem;
line-height: 1.2;
padding: 14px 0;
}
.post-md h6
{
font-size: 1.125rem;
line-height: 1.2;
padding: 12px 0;
}
.post-md a
{
color: #666;
box-shadow: 0 2px 0 #ccc;
/* transition: color ease-in-out .65s, box-shadow ease-in-out .65s; */
}
""".trimIndent()
RtHtml(
html,
css = customCss,
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
linkAction = {
println(it)
}
)
RtText默认支持的标签处理器defaultNodeHandlers,若要扩展新的处理器,则只需要实现NodeHandler并注册即可。
// 自定义blod标签,支持字体加粗显示
val blod = NodeHandler("blod") { node: Node ->
val (spanStyle, paragraphStyle) = node.parseStyle()
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold).merge(spanStyle)) {
appendChild(node)
}
}
// nodeHandlers里注册blod
RtHtml(
html,
nodeHandlers = mutableListOf(blod).apply { addAll(defaultNodeHandlers) },
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
linkAction = {
println(it)
}
)RtText中若要绘制特殊显示,如img,table等标签,则可实现InlineNodeProcessor处理器。
// 代码块标签处理器
val code =
InlineNodeProcessor("code") {
val param: Param = Json.decodeFromString(it)
val codeNode = Ksoup.parse(param.contentText).body().firstChild()!!
Box(modifier = Modifier.fillMaxWidth().wrapContentHeight().background(Color.Yellow)) {
Text(codeNode.outHtml())
}
}如果需要改变内嵌控件的高度,则可调用handlerContext.updateInlineContent()更新
val density = LocalDensity.current.density
val fontScale = LocalDensity.current.fontScale
val handlerContext = LocalHandlerContext.current
Box(modifier = Modifier
.onSizeChanged { size ->
handlerContext.updateInlineContent(
param, (size.width / density * fontScale).sp,
(size.height / density * fontScale).sp,
)
}){
Text("")
}RtText依赖以下lib,如果你使用了RtText,则不需要再重复添加该库
有关使用和一般查询的问题,请参考GitHub Discussions。
如果您希望贡献,请阅读贡献指南。
要报告任何问题,请访问我们的GitHub Issues,请确保在提交新问题之前检查重复项。
通过加入此存储库的 stargazers 来支持它。⭐
也可以 Follow Me 一起创作吧!🤩
Copyright 2025 ChangJiahong
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.