1 /* <lambda>null2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.example.text.styling.renderer 17 18 import android.graphics.Typeface 19 import android.support.annotation.ColorInt 20 import android.text.SpannableStringBuilder 21 import android.text.SpannedString 22 import android.text.style.LeadingMarginSpan 23 import android.text.style.RelativeSizeSpan 24 import android.text.style.StyleSpan 25 import androidx.text.buildSpannedString 26 import androidx.text.inSpans 27 import com.android.example.text.styling.parser.Element 28 import com.android.example.text.styling.parser.Parser 29 import com.android.example.text.styling.renderer.spans.BulletPointSpan 30 import com.android.example.text.styling.renderer.spans.CodeBlockSpan 31 32 /** 33 * Renders the text as simple markdown, using spans. 34 */ 35 class MarkdownBuilder( 36 @ColorInt private val bulletPointColor: Int, 37 @ColorInt private val codeBackgroundColor: Int, 38 private val codeBlockTypeface: Typeface?, 39 private val parser: Parser 40 ) { 41 42 fun markdownToSpans(string: String): SpannedString { 43 val markdown = parser.parse(string) 44 45 return buildSpannedString { 46 markdown.elements.forEach { it -> buildElement(it, this) } 47 } 48 } 49 50 private fun buildElement(element: Element, builder: SpannableStringBuilder): CharSequence { 51 return builder.apply { 52 // apply different spans depending on the type of the element 53 when (element.type) { 54 Element.Type.CODE_BLOCK -> { 55 inSpans(CodeBlockSpan(codeBlockTypeface, codeBackgroundColor)) { 56 append(element.text) 57 } 58 } 59 Element.Type.QUOTE -> { 60 // You can set multiple spans for the same text 61 inSpans(StyleSpan(Typeface.ITALIC), 62 LeadingMarginSpan.Standard(40), 63 RelativeSizeSpan(1.1f)) { 64 append(element.text) 65 } 66 } 67 Element.Type.BULLET_POINT -> { 68 inSpans(BulletPointSpan(20, bulletPointColor)) { 69 for (child in element.elements) { 70 buildElement(child, builder) 71 } 72 } 73 } 74 Element.Type.TEXT -> append(element.text) 75 } 76 } 77 } 78 79 } 80