{"id":18266049,"url":"https://github.com/dokar3/ktspans","last_synced_at":"2025-04-12T00:24:02.619Z","repository":{"id":57733033,"uuid":"332007162","full_name":"dokar3/KtSpans","owner":"dokar3","description":"KtSpans is a library provides html \u0026 css like DSL to write spans on Android.","archived":false,"fork":false,"pushed_at":"2021-11-20T00:58:42.000Z","size":380,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T20:11:49.973Z","etag":null,"topics":["android","dsl","html","kotlin","span"],"latest_commit_sha":null,"homepage":"","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/dokar3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-22T16:51:25.000Z","updated_at":"2023-09-14T08:09:46.000Z","dependencies_parsed_at":"2022-09-26T22:30:39.866Z","dependency_job_id":null,"html_url":"https://github.com/dokar3/KtSpans","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dokar3%2FKtSpans","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dokar3%2FKtSpans/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dokar3%2FKtSpans/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dokar3%2FKtSpans/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dokar3","download_url":"https://codeload.github.com/dokar3/KtSpans/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248498623,"owners_count":21114161,"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","dsl","html","kotlin","span"],"created_at":"2024-11-05T11:21:23.751Z","updated_at":"2025-04-12T00:24:02.595Z","avatar_url":"https://github.com/dokar3.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](./arts/ktspans.png)\n\n[README - 中文](./README_zh.md)\n\n# KtSpans\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.dokar3/ktspans/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.dokar3/ktspans)\n\nInspired by [kotlinx.html](https://github.com/Kotlin/kotlinx.html), KtSpans is a library provides **html** \u0026 **css** like DSL to write spans on Android.\n\n# How?\n\nAdd dependency to project:\n\n```groovy\nimplementation 'io.github.dokar3:ktspans:latest_version'\n```\n\nCreate spanned:\n\n```kotlin\ntextView.text = createSpanned {\n    style {\n        h3 {\n            color = 0xFF8D07F6.toInt()\n        }\n        quote {\n            stripeColor = 0x72AAAAAA\n            stripeWidth = 2.dp\n            gapWidth = 8.dp\n        }\n        \"serif-font\" {\n            fontFamily = Typeface.SERIF\n        }\n    }\n\n    h3 { +\"::before\" }\n    p {\n        b { +\"KtSpans\" }\n        +\" is inspired by \"\n        a(\"https://github.com/Kotlin/kotlinx.html\") {\n            +\"kotlinx.html\"\n        }\n    }\n    br {}\n    h3 { +\"#now\" }\n    p {\n        +\"Make more fun with Android spans\"\n    }\n    br {}\n    h3 { +\"::after\" }\n    quote {\n        className = \"serif-font\"\n        +\"\\\"I never think of the future, it comes soon enough.\\\"—Albert Einstein\"\n    }\n}\n```\n\nThe result:\n\n![](./arts/screenshot_01_clipped.png)\n\n# More usages\n\n### Attributes inside tags:\n\n```kotlin\np {\n    attrs {\n        fontStyle = Typeface.BOLD \n    }\n    +\"Some text\"\n}\n```\n\n### Full attributes for some special tags:\n\n```kotlin\nquote {\n    fullAttrs {\n        stripeColor = accent\n        stripeWidth = 4.dp\n        gapWidth = 8.dp\n    }\n    +\"A quote here\"\n}\n```\n\n### Use style from outside:\n\n```kotlin\nval appTextStyle = createStyle {\n    h1 { ... }\n    p { ... }\n    quote { ... }\n    bullet { ... }\n    hr { ... }\n}\n```\n\nInside `createSpanned`:\n\n```kotlin\ncreateSpanned {\n    style(appTextStyle)\n    ...\n}\n```\n\n### Include/reuse spans:\n\n```kotlin\nfun header(): Spanned {\n    val banner = ContextCompat.getDrawable(this, R.mipmap.ic_banner)!!\n    return createSpanned{\n        img(banner) {}\n        h1 { +\"Title\" }\n        p { ... }\n    }\n}\n```\n\nInside  `createSpanned`:\n\n```kotlin\ncreateSpanned{\n    +header()\n    \n    p { ... }\n    ...\n}\n```\n\n# Tags and attributes\n\n### Built-in tags:\n\n**`h1` - `h6`,  `p`, `b`, `i`, `u`, `s`, `hr`, `sup`, `sub`, `img`, `clickable`**\n\n### Common attributes:\n\n**fontSize: Size? = null**\n\nCreate some sizes like this: `16.sp`, `12.px`, `10.dp`, `2.em`, `Px(18)`, `Em(2.0f)`\n\n**fontFamily: Typeface? = null**\n\nUse system typefaces or load from assets/file: `Typeface.DEFAULT`, `Typeface.DEFAULT_BOLD`, `Typeface.SANS_SERIF`, `Typeface.SERIF`, `Typeface.MONOSPACE`\n\n**fontStyle: Int = Typeface.NORMAL**\n\nValues: `Typeface.NORMAL`, `Typeface.BOLD`, `Typeface.ITALIC`, `Typeface.BOLD_ITALIC`\n\n**lineHeight: Size? = null**\n\nSame as `fontSize`\n\n**align: Layout.Alignment? = null**\n\nValues: `Layout.Alignment.ALIGN_NORMAL`, `Layout.Alignment.ALIGN_CENTER`, `Layout.Alignment.ALIGN_OPPOSITE`\n\n**color: Int = 0**\n\nSame as Android's color ints\n\n**backgroundColor: Int = 0**\n\nSame as Android's color ints\n\n**decoration: Decoration? = null**\n\nValues: `Decoration.Underline`, `Decoration.Strikethrough`\n\n# Custom tags\n\n### Simple dashedHr example:\n\n1. Write an extension function:\n\n```kotlin\n@SpanTagMarker\ninline fun Tag.dashedHr(crossinline body: SelfClosingTag.() -\u003e Unit) {\n    val tag = SelfClosingTag(\"dashed-hr\", root)\n    // This line is redundant in this case, a self closing tag should not\n    // contain any content.\n    // tag.body()\n    val spans = spans = arrayOf(DashedHrSpan())\n    insertTag(tag, spans, isBlockElement = true)\n}\n```\n\n2. Use it:\n\n```kotlin\ncreateSpanned{\n    ...\n    dashedHr {}\n    ...\n}\n```\n\nResult:\n\n![](./arts/screenshot_02_clipped.png)\n\n### With custom attributes:\n\n1. Custom attributes class:\n\n```kotlin\nclass DashedHrAttributes(var height: Size = 1.dp) : Attributes()\n```\n\n2. Custom tag class:\n\n```kotlin\nclass DashedHr(root: IRoot?) : SelfClosingTag(NAME, root) {\n    companion object {\n        const val NAME = \"dashed-hr\"\n    }\n}\n```\n\n3. Extension function for `fullAttrs` dsl:\n\n```kotlin\n@StyleTagMarker\ninline fun DashedHr.fullAttrs(body: DashedHrAttributes.() -\u003e Unit) {\n    this.attrs = DashedHrAttributes().also(body)\n}\n```\n\n4. Extension function for span dsl:\n\n```kotlin\n@SpanTagMarker\ninline fun Tag.dashedHr(crossinline body: DashedHr.() -\u003e Unit) {\n    val tag = DashedHr(root).also(body)\n    root!!.defaultStyle.dashedHr {}\n    val attrs = (tag.attrs ?: root!!.attrs(tag.name)) as DashedHrAttributes\n    val height = attrs.height.value\n    val color = attrs.color\n    insertTag(tag, arrayOf(DashedHrSpan(height, color)), isBlockElement = true)\n}\n```\n\n5. Extension function for style dsl:\n\n```kotlin\ninline fun StyleSheet.dashedHr(body: DashedHrAttributes.() -\u003e Unit) {\n    val attrs = tagAttrs[DashedHr.NAME] as? DashedHrAttributes\n        ?: DashedHrAttributes().also {\n            tagAttrs[DashedHr.NAME] = it\n        }\n    attrs.body()\n}\n```\n\n6. Use it:\n\n```kotlin\ncreatSpan {\n    style {\n        dashedHr {\n            height = 1.5.dp\n        }\n    }\n    ...\n    dashedHr {}\n    dashedHr {\n        fullAttrs {\n            height = 2.dp\n        }\n    }\n    ...\n}\n```\n\nResult:\n\n![](./arts/screenshot_03_clipped.png)\n\n# License\n\n[Apache License 2.0](./LICENSE)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdokar3%2Fktspans","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdokar3%2Fktspans","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdokar3%2Fktspans/lists"}