react-native-enriched-markdown 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +479 -0
- package/ReactNativeEnrichedMarkdown.podspec +27 -0
- package/android/build.gradle +101 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +39 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +21 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +24 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +25 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +57 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1164 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.h +32 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.cpp +16 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.h +20 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/baseline-prof.txt +65 -0
- package/android/src/main/cpp/jni-adapter.cpp +203 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +153 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +119 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextPackage.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +165 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkPressEvent.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +166 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +89 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +105 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeRenderer.kt +35 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/DocumentRenderer.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/EmphasisRenderer.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LineBreakRenderer.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +28 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +105 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +58 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +99 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ParagraphRenderer.kt +66 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/Renderer.kt +95 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +85 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrongRenderer.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/TextRenderer.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ThematicBreakRenderer.kt +44 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +136 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +135 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +180 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +34 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/HeadingSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +320 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LineHeightSpan.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/MarginBottomSpan.kt +76 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +87 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TextSpan.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ThematicBreakSpan.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BaseBlockStyle.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +51 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeStyle.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/EmphasisStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/HeadingStyle.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineImageStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ParagraphStyle.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrongStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +180 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleParser.kt +75 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ThematicBreakStyle.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/AsyncDrawable.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/HTMLGenerator.kt +809 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownExtractor.kt +365 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/SelectionActionMode.kt +139 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/Utils.kt +181 -0
- package/android/src/main/jni/CMakeLists.txt +82 -0
- package/android/src/main/jni/EnrichedMarkdownTextSpec.cpp +21 -0
- package/android/src/main/jni/EnrichedMarkdownTextSpec.h +25 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextComponentDescriptor.h +29 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.cpp +45 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.h +21 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +33 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +49 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +25 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +19 -0
- package/cpp/md4c/md4c.c +6492 -0
- package/cpp/md4c/md4c.h +402 -0
- package/cpp/parser/MD4CParser.cpp +314 -0
- package/cpp/parser/MD4CParser.hpp +23 -0
- package/cpp/parser/MarkdownASTNode.hpp +49 -0
- package/ios/EnrichedMarkdownText.h +18 -0
- package/ios/EnrichedMarkdownText.mm +1074 -0
- package/ios/attachments/ImageAttachment.h +23 -0
- package/ios/attachments/ImageAttachment.m +185 -0
- package/ios/attachments/ThematicBreakAttachment.h +15 -0
- package/ios/attachments/ThematicBreakAttachment.m +33 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.cpp +24 -0
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.h +25 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.cpp +57 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.h +1164 -0
- package/ios/generated/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +20 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.h +32 -0
- package/ios/generated/EnrichedMarkdownTextSpec/States.cpp +16 -0
- package/ios/generated/EnrichedMarkdownTextSpec/States.h +20 -0
- package/ios/internals/EnrichedMarkdownTextComponentDescriptor.h +19 -0
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +43 -0
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +85 -0
- package/ios/internals/EnrichedMarkdownTextState.h +24 -0
- package/ios/parser/MarkdownASTNode.h +33 -0
- package/ios/parser/MarkdownASTNode.m +32 -0
- package/ios/parser/MarkdownParser.h +8 -0
- package/ios/parser/MarkdownParser.mm +13 -0
- package/ios/parser/MarkdownParserBridge.mm +110 -0
- package/ios/renderer/AttributedRenderer.h +9 -0
- package/ios/renderer/AttributedRenderer.m +119 -0
- package/ios/renderer/BlockquoteRenderer.h +7 -0
- package/ios/renderer/BlockquoteRenderer.m +159 -0
- package/ios/renderer/CodeBlockRenderer.h +10 -0
- package/ios/renderer/CodeBlockRenderer.m +89 -0
- package/ios/renderer/CodeRenderer.h +10 -0
- package/ios/renderer/CodeRenderer.m +60 -0
- package/ios/renderer/EmphasisRenderer.h +6 -0
- package/ios/renderer/EmphasisRenderer.m +96 -0
- package/ios/renderer/HeadingRenderer.h +7 -0
- package/ios/renderer/HeadingRenderer.m +98 -0
- package/ios/renderer/ImageRenderer.h +12 -0
- package/ios/renderer/ImageRenderer.m +62 -0
- package/ios/renderer/LinkRenderer.h +7 -0
- package/ios/renderer/LinkRenderer.m +69 -0
- package/ios/renderer/ListItemRenderer.h +16 -0
- package/ios/renderer/ListItemRenderer.m +91 -0
- package/ios/renderer/ListRenderer.h +13 -0
- package/ios/renderer/ListRenderer.m +67 -0
- package/ios/renderer/NodeRenderer.h +8 -0
- package/ios/renderer/ParagraphRenderer.h +7 -0
- package/ios/renderer/ParagraphRenderer.m +69 -0
- package/ios/renderer/RenderContext.h +88 -0
- package/ios/renderer/RenderContext.m +248 -0
- package/ios/renderer/RendererFactory.h +12 -0
- package/ios/renderer/RendererFactory.m +110 -0
- package/ios/renderer/StrongRenderer.h +6 -0
- package/ios/renderer/StrongRenderer.m +83 -0
- package/ios/renderer/TextRenderer.h +6 -0
- package/ios/renderer/TextRenderer.m +16 -0
- package/ios/renderer/ThematicBreakRenderer.h +5 -0
- package/ios/renderer/ThematicBreakRenderer.m +53 -0
- package/ios/styles/StyleConfig.h +228 -0
- package/ios/styles/StyleConfig.mm +1467 -0
- package/ios/utils/BlockquoteBorder.h +20 -0
- package/ios/utils/BlockquoteBorder.m +92 -0
- package/ios/utils/CodeBackground.h +19 -0
- package/ios/utils/CodeBackground.m +191 -0
- package/ios/utils/CodeBlockBackground.h +17 -0
- package/ios/utils/CodeBlockBackground.m +87 -0
- package/ios/utils/EditMenuUtils.h +22 -0
- package/ios/utils/EditMenuUtils.m +118 -0
- package/ios/utils/FontUtils.h +20 -0
- package/ios/utils/FontUtils.m +13 -0
- package/ios/utils/HTMLGenerator.h +20 -0
- package/ios/utils/HTMLGenerator.m +779 -0
- package/ios/utils/LastElementUtils.h +53 -0
- package/ios/utils/ListMarkerDrawer.h +15 -0
- package/ios/utils/ListMarkerDrawer.m +127 -0
- package/ios/utils/MarkdownExtractor.h +17 -0
- package/ios/utils/MarkdownExtractor.m +295 -0
- package/ios/utils/ParagraphStyleUtils.h +13 -0
- package/ios/utils/ParagraphStyleUtils.m +56 -0
- package/ios/utils/PasteboardUtils.h +36 -0
- package/ios/utils/PasteboardUtils.m +134 -0
- package/ios/utils/RTFExportUtils.h +24 -0
- package/ios/utils/RTFExportUtils.m +297 -0
- package/ios/utils/RuntimeKeys.h +38 -0
- package/ios/utils/RuntimeKeys.m +11 -0
- package/ios/utils/TextViewLayoutManager.h +14 -0
- package/ios/utils/TextViewLayoutManager.mm +113 -0
- package/lib/module/EnrichedMarkdownText.js +34 -0
- package/lib/module/EnrichedMarkdownText.js.map +1 -0
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +130 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/normalizeMarkdownStyle.js +340 -0
- package/lib/module/normalizeMarkdownStyle.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/EnrichedMarkdownText.d.ts +101 -0
- package/lib/typescript/src/EnrichedMarkdownText.d.ts.map +1 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +111 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts +6 -0
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -0
- package/package.json +186 -1
- package/react-native.config.js +13 -0
- package/src/EnrichedMarkdownText.tsx +152 -0
- package/src/EnrichedMarkdownTextNativeComponent.ts +130 -0
- package/src/index.tsx +7 -0
- package/src/normalizeMarkdownStyle.ts +377 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Paint
|
|
4
|
+
import android.text.style.LineHeightSpan
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds bottom margin to a block element (paragraphs/headings) using LineHeightSpan.
|
|
8
|
+
*
|
|
9
|
+
* For spacer lines (single newline), sets the line height to exactly marginBottom.
|
|
10
|
+
* For regular lines, adds marginBottom only at paragraph boundaries to preserve lineHeight.
|
|
11
|
+
*
|
|
12
|
+
* @param marginBottom The margin in pixels to add below the block (must be > 0)
|
|
13
|
+
*/
|
|
14
|
+
class MarginBottomSpan(
|
|
15
|
+
val marginBottom: Float,
|
|
16
|
+
) : LineHeightSpan {
|
|
17
|
+
override fun chooseHeight(
|
|
18
|
+
text: CharSequence,
|
|
19
|
+
start: Int,
|
|
20
|
+
end: Int,
|
|
21
|
+
spanstartv: Int,
|
|
22
|
+
lineHeight: Int,
|
|
23
|
+
fm: Paint.FontMetricsInt,
|
|
24
|
+
) {
|
|
25
|
+
// Only process lines that end with a newline
|
|
26
|
+
if (end <= start || text[end - 1] != '\n') {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
val marginPixels = marginBottom.toInt()
|
|
31
|
+
|
|
32
|
+
// Handle spacer lines (single newline character)
|
|
33
|
+
if (end - start == 1 && text[start] == '\n') {
|
|
34
|
+
if (hasContentAfter(text, end)) {
|
|
35
|
+
// Set line height to exactly marginBottom for spacer lines
|
|
36
|
+
fm.top = 0
|
|
37
|
+
fm.ascent = 0
|
|
38
|
+
fm.descent = marginPixels
|
|
39
|
+
fm.bottom = marginPixels
|
|
40
|
+
} else {
|
|
41
|
+
// No content after - collapse the spacer line to zero height
|
|
42
|
+
fm.top = 0
|
|
43
|
+
fm.ascent = 0
|
|
44
|
+
fm.descent = 0
|
|
45
|
+
fm.bottom = 0
|
|
46
|
+
}
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// For regular lines, add spacing only if there's content after
|
|
51
|
+
if (hasContentAfter(text, end)) {
|
|
52
|
+
fm.descent += marginPixels
|
|
53
|
+
fm.bottom += marginPixels
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Checks if there's non-newline content after the given position.
|
|
59
|
+
* Used to determine if spacing should be applied (between items) or skipped (after last item).
|
|
60
|
+
*/
|
|
61
|
+
private fun hasContentAfter(
|
|
62
|
+
text: CharSequence,
|
|
63
|
+
pos: Int,
|
|
64
|
+
): Boolean {
|
|
65
|
+
if (pos >= text.length) return false
|
|
66
|
+
|
|
67
|
+
// If the next character is a newline, check the character after that
|
|
68
|
+
if (text[pos] == '\n') {
|
|
69
|
+
val nextPos = pos + 1
|
|
70
|
+
if (nextPos >= text.length) return false
|
|
71
|
+
return text[nextPos] != '\n' // Non-newline = content exists
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return true // Non-newline content immediately after
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.graphics.Typeface
|
|
7
|
+
import android.text.Layout
|
|
8
|
+
import android.text.TextPaint
|
|
9
|
+
import com.facebook.react.common.ReactConstants
|
|
10
|
+
import com.facebook.react.views.text.ReactTypefaceUtils.applyStyles
|
|
11
|
+
import com.facebook.react.views.text.ReactTypefaceUtils.parseFontWeight
|
|
12
|
+
import com.swmansion.enriched.markdown.renderer.BlockStyle
|
|
13
|
+
import com.swmansion.enriched.markdown.renderer.SpanStyleCache
|
|
14
|
+
import com.swmansion.enriched.markdown.styles.ListStyle
|
|
15
|
+
|
|
16
|
+
class OrderedListSpan(
|
|
17
|
+
private val listStyle: ListStyle,
|
|
18
|
+
depth: Int,
|
|
19
|
+
context: Context,
|
|
20
|
+
styleCache: SpanStyleCache,
|
|
21
|
+
) : BaseListSpan(
|
|
22
|
+
depth = depth,
|
|
23
|
+
context = context,
|
|
24
|
+
styleCache = styleCache,
|
|
25
|
+
blockStyle =
|
|
26
|
+
BlockStyle(
|
|
27
|
+
fontSize = listStyle.fontSize,
|
|
28
|
+
fontFamily = listStyle.fontFamily,
|
|
29
|
+
fontWeight = listStyle.fontWeight,
|
|
30
|
+
color = listStyle.color,
|
|
31
|
+
),
|
|
32
|
+
marginLeft = listStyle.marginLeft,
|
|
33
|
+
gapWidth = listStyle.gapWidth,
|
|
34
|
+
) {
|
|
35
|
+
companion object {
|
|
36
|
+
private val sharedMarkerPaint = TextPaint().apply { isAntiAlias = true }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private val markerTypeface: Typeface =
|
|
40
|
+
run {
|
|
41
|
+
val fontFamily = listStyle.fontFamily.takeIf { it.isNotEmpty() }
|
|
42
|
+
val fontWeight = parseFontWeight(listStyle.markerFontWeight)
|
|
43
|
+
applyStyles(null, ReactConstants.UNSET, fontWeight, fontFamily, context.assets)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private fun configureMarkerPaint(): TextPaint =
|
|
47
|
+
sharedMarkerPaint.apply {
|
|
48
|
+
textSize = listStyle.fontSize
|
|
49
|
+
color = listStyle.markerColor
|
|
50
|
+
typeface = markerTypeface
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override fun getMarkerWidth(): Float {
|
|
54
|
+
val paint = configureMarkerPaint()
|
|
55
|
+
return paint.measureText("99.")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var itemNumber: Int = 1
|
|
59
|
+
private set
|
|
60
|
+
|
|
61
|
+
override fun drawMarker(
|
|
62
|
+
c: Canvas,
|
|
63
|
+
p: Paint,
|
|
64
|
+
x: Int,
|
|
65
|
+
dir: Int,
|
|
66
|
+
top: Int,
|
|
67
|
+
baseline: Int,
|
|
68
|
+
bottom: Int,
|
|
69
|
+
layout: Layout?,
|
|
70
|
+
start: Int,
|
|
71
|
+
) {
|
|
72
|
+
val markerPaint = configureMarkerPaint()
|
|
73
|
+
val text = "$itemNumber."
|
|
74
|
+
val textWidth = markerPaint.measureText(text)
|
|
75
|
+
|
|
76
|
+
// Calculate marker position based on depth
|
|
77
|
+
// depth 0: markerWidth, depth 1: marginLeft + markerWidth, etc.
|
|
78
|
+
val markerRightEdge = (depth * marginLeft + getMarkerWidth()) * dir
|
|
79
|
+
val markerX = markerRightEdge - textWidth * dir
|
|
80
|
+
|
|
81
|
+
c.drawText(text, markerX, baseline.toFloat(), markerPaint)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fun setItemNumber(number: Int) {
|
|
85
|
+
itemNumber = number
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Typeface
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.MetricAffectingSpan
|
|
6
|
+
import com.swmansion.enriched.markdown.renderer.BlockStyle
|
|
7
|
+
import com.swmansion.enriched.markdown.renderer.SpanStyleCache
|
|
8
|
+
import com.swmansion.enriched.markdown.utils.applyColorPreserving
|
|
9
|
+
|
|
10
|
+
class StrongSpan(
|
|
11
|
+
private val styleCache: SpanStyleCache,
|
|
12
|
+
private val blockStyle: BlockStyle,
|
|
13
|
+
) : MetricAffectingSpan() {
|
|
14
|
+
private val strongColor = styleCache.getStrongColorFor(blockStyle.color)
|
|
15
|
+
|
|
16
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
17
|
+
applyStrongStyle(tp)
|
|
18
|
+
tp.applyColorPreserving(strongColor, *styleCache.colorsToPreserve)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override fun updateMeasureState(tp: TextPaint) {
|
|
22
|
+
applyStrongStyle(tp)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private fun applyStrongStyle(tp: TextPaint) {
|
|
26
|
+
// Preserve code fontSize if code is nested inside strong text
|
|
27
|
+
val codeFontSize = blockStyle.fontSize * 0.85f
|
|
28
|
+
if (kotlin.math.abs(tp.textSize - codeFontSize) > 0.1f) {
|
|
29
|
+
tp.textSize = blockStyle.fontSize
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
val currentTypeface = tp.typeface ?: Typeface.DEFAULT
|
|
33
|
+
val isItalic = (currentTypeface.style) and Typeface.ITALIC != 0
|
|
34
|
+
val style = if (isItalic) Typeface.BOLD_ITALIC else Typeface.BOLD
|
|
35
|
+
tp.typeface = Typeface.create(currentTypeface, style)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.text.TextPaint
|
|
5
|
+
import android.text.style.MetricAffectingSpan
|
|
6
|
+
import com.swmansion.enriched.markdown.renderer.BlockStyle
|
|
7
|
+
import com.swmansion.enriched.markdown.utils.applyBlockStyleFont
|
|
8
|
+
|
|
9
|
+
class TextSpan(
|
|
10
|
+
private val blockStyle: BlockStyle,
|
|
11
|
+
private val context: Context,
|
|
12
|
+
) : MetricAffectingSpan() {
|
|
13
|
+
override fun updateDrawState(tp: TextPaint) {
|
|
14
|
+
applyBlockStyle(tp)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override fun updateMeasureState(tp: TextPaint) {
|
|
18
|
+
applyBlockStyle(tp)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private fun applyBlockStyle(tp: TextPaint) {
|
|
22
|
+
tp.textSize = blockStyle.fontSize
|
|
23
|
+
tp.color = blockStyle.color
|
|
24
|
+
tp.applyBlockStyleFont(blockStyle, context)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.text.style.ReplacementSpan
|
|
6
|
+
|
|
7
|
+
class ThematicBreakSpan(
|
|
8
|
+
private val lineColor: Int,
|
|
9
|
+
private val lineHeight: Float,
|
|
10
|
+
private val marginTop: Float,
|
|
11
|
+
private val marginBottom: Float,
|
|
12
|
+
) : ReplacementSpan() {
|
|
13
|
+
override fun getSize(
|
|
14
|
+
paint: Paint,
|
|
15
|
+
text: CharSequence?,
|
|
16
|
+
start: Int,
|
|
17
|
+
end: Int,
|
|
18
|
+
fm: Paint.FontMetricsInt?,
|
|
19
|
+
): Int {
|
|
20
|
+
val totalHeight = (marginTop + lineHeight + marginBottom).toInt()
|
|
21
|
+
|
|
22
|
+
fm?.apply {
|
|
23
|
+
ascent = -totalHeight
|
|
24
|
+
top = -totalHeight
|
|
25
|
+
descent = 0
|
|
26
|
+
bottom = 0
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override fun draw(
|
|
33
|
+
canvas: Canvas,
|
|
34
|
+
text: CharSequence?,
|
|
35
|
+
start: Int,
|
|
36
|
+
end: Int,
|
|
37
|
+
x: Float,
|
|
38
|
+
top: Int,
|
|
39
|
+
y: Int,
|
|
40
|
+
bottom: Int,
|
|
41
|
+
paint: Paint,
|
|
42
|
+
) {
|
|
43
|
+
paint.withStyle(lineColor, lineHeight) {
|
|
44
|
+
val lineY = top + marginTop + (lineHeight / 2f)
|
|
45
|
+
|
|
46
|
+
canvas.drawLine(0f, lineY, canvas.width.toFloat(), lineY, paint)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private inline fun Paint.withStyle(
|
|
51
|
+
color: Int,
|
|
52
|
+
width: Float,
|
|
53
|
+
action: () -> Unit,
|
|
54
|
+
) {
|
|
55
|
+
val oldColor = this.color
|
|
56
|
+
val oldWidth = this.strokeWidth
|
|
57
|
+
val oldStyle = this.style
|
|
58
|
+
|
|
59
|
+
this.color = color
|
|
60
|
+
this.strokeWidth = width
|
|
61
|
+
this.style = Paint.Style.STROKE
|
|
62
|
+
|
|
63
|
+
action()
|
|
64
|
+
|
|
65
|
+
this.color = oldColor
|
|
66
|
+
this.strokeWidth = oldWidth
|
|
67
|
+
this.style = oldStyle
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.text.Layout
|
|
7
|
+
import com.swmansion.enriched.markdown.renderer.BlockStyle
|
|
8
|
+
import com.swmansion.enriched.markdown.renderer.SpanStyleCache
|
|
9
|
+
import com.swmansion.enriched.markdown.styles.ListStyle
|
|
10
|
+
|
|
11
|
+
class UnorderedListSpan(
|
|
12
|
+
private val listStyle: ListStyle,
|
|
13
|
+
depth: Int,
|
|
14
|
+
context: Context,
|
|
15
|
+
styleCache: SpanStyleCache,
|
|
16
|
+
) : BaseListSpan(
|
|
17
|
+
depth = depth,
|
|
18
|
+
context = context,
|
|
19
|
+
styleCache = styleCache,
|
|
20
|
+
blockStyle =
|
|
21
|
+
BlockStyle(
|
|
22
|
+
fontSize = listStyle.fontSize,
|
|
23
|
+
fontFamily = listStyle.fontFamily,
|
|
24
|
+
fontWeight = listStyle.fontWeight,
|
|
25
|
+
color = listStyle.color,
|
|
26
|
+
),
|
|
27
|
+
marginLeft = listStyle.marginLeft,
|
|
28
|
+
gapWidth = listStyle.gapWidth,
|
|
29
|
+
) {
|
|
30
|
+
companion object {
|
|
31
|
+
private val sharedBulletPaint =
|
|
32
|
+
Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
33
|
+
style = Paint.Style.FILL
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private val radius: Float = listStyle.bulletSize / 2f
|
|
38
|
+
|
|
39
|
+
private fun configureBulletPaint(): Paint =
|
|
40
|
+
sharedBulletPaint.apply {
|
|
41
|
+
color = listStyle.bulletColor
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
override fun getMarkerWidth(): Float = radius
|
|
45
|
+
|
|
46
|
+
override fun drawMarker(
|
|
47
|
+
c: Canvas,
|
|
48
|
+
p: Paint,
|
|
49
|
+
x: Int,
|
|
50
|
+
dir: Int,
|
|
51
|
+
top: Int,
|
|
52
|
+
baseline: Int,
|
|
53
|
+
bottom: Int,
|
|
54
|
+
layout: Layout?,
|
|
55
|
+
start: Int,
|
|
56
|
+
) {
|
|
57
|
+
val bulletPaint = configureBulletPaint()
|
|
58
|
+
|
|
59
|
+
// Calculate bullet position based on depth
|
|
60
|
+
// depth 0: radius, depth 1: marginLeft + radius, etc.
|
|
61
|
+
val bulletX = (depth * marginLeft + radius) * dir
|
|
62
|
+
|
|
63
|
+
// Vertical centering based on font metrics
|
|
64
|
+
val fm = p.fontMetrics
|
|
65
|
+
val bulletY = baseline + (fm.ascent + fm.descent) / 2f
|
|
66
|
+
|
|
67
|
+
c.drawCircle(bulletX, bulletY, radius, bulletPaint)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class BlockquoteStyle(
|
|
6
|
+
override val fontSize: Float,
|
|
7
|
+
override val fontFamily: String,
|
|
8
|
+
override val fontWeight: String,
|
|
9
|
+
override val color: Int,
|
|
10
|
+
override val marginBottom: Float,
|
|
11
|
+
override val lineHeight: Float,
|
|
12
|
+
val borderColor: Int,
|
|
13
|
+
val borderWidth: Float,
|
|
14
|
+
val gapWidth: Float,
|
|
15
|
+
val backgroundColor: Int?,
|
|
16
|
+
) : BaseBlockStyle {
|
|
17
|
+
companion object {
|
|
18
|
+
fun fromReadableMap(
|
|
19
|
+
map: ReadableMap,
|
|
20
|
+
parser: StyleParser,
|
|
21
|
+
): BlockquoteStyle {
|
|
22
|
+
val fontSize = parser.toPixelFromSP(map.getDouble("fontSize").toFloat())
|
|
23
|
+
val fontFamily = parser.parseString(map, "fontFamily")
|
|
24
|
+
val fontWeight = parser.parseString(map, "fontWeight", "normal")
|
|
25
|
+
val color = parser.parseColor(map, "color")
|
|
26
|
+
val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
|
|
27
|
+
val lineHeightRaw = map.getDouble("lineHeight").toFloat()
|
|
28
|
+
val lineHeight = parser.toPixelFromSP(lineHeightRaw)
|
|
29
|
+
val borderColor = parser.parseColor(map, "borderColor")
|
|
30
|
+
val borderWidth = parser.toPixelFromDIP(map.getDouble("borderWidth").toFloat())
|
|
31
|
+
val gapWidth = parser.toPixelFromDIP(map.getDouble("gapWidth").toFloat())
|
|
32
|
+
val backgroundColor = parser.parseOptionalColor(map, "backgroundColor")
|
|
33
|
+
|
|
34
|
+
return BlockquoteStyle(
|
|
35
|
+
fontSize,
|
|
36
|
+
fontFamily,
|
|
37
|
+
fontWeight,
|
|
38
|
+
color,
|
|
39
|
+
marginBottom,
|
|
40
|
+
lineHeight,
|
|
41
|
+
borderColor,
|
|
42
|
+
borderWidth,
|
|
43
|
+
gapWidth,
|
|
44
|
+
backgroundColor,
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class CodeBlockStyle(
|
|
6
|
+
override val fontSize: Float,
|
|
7
|
+
override val fontFamily: String,
|
|
8
|
+
override val fontWeight: String,
|
|
9
|
+
override val color: Int,
|
|
10
|
+
override val marginBottom: Float,
|
|
11
|
+
override val lineHeight: Float,
|
|
12
|
+
val backgroundColor: Int,
|
|
13
|
+
val borderColor: Int,
|
|
14
|
+
val borderRadius: Float,
|
|
15
|
+
val borderWidth: Float,
|
|
16
|
+
val padding: Float,
|
|
17
|
+
) : BaseBlockStyle {
|
|
18
|
+
companion object {
|
|
19
|
+
fun fromReadableMap(
|
|
20
|
+
map: ReadableMap,
|
|
21
|
+
parser: StyleParser,
|
|
22
|
+
): CodeBlockStyle {
|
|
23
|
+
val fontSize = parser.toPixelFromSP(map.getDouble("fontSize").toFloat())
|
|
24
|
+
val fontFamily = parser.parseString(map, "fontFamily")
|
|
25
|
+
val fontWeight = parser.parseString(map, "fontWeight", "normal")
|
|
26
|
+
val color = parser.parseColor(map, "color")
|
|
27
|
+
val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
|
|
28
|
+
val lineHeightRaw = map.getDouble("lineHeight").toFloat()
|
|
29
|
+
val lineHeight = parser.toPixelFromSP(lineHeightRaw)
|
|
30
|
+
val backgroundColor = parser.parseColor(map, "backgroundColor")
|
|
31
|
+
val borderColor = parser.parseColor(map, "borderColor")
|
|
32
|
+
val borderRadius = parser.toPixelFromDIP(map.getDouble("borderRadius").toFloat())
|
|
33
|
+
val borderWidth = parser.toPixelFromDIP(map.getDouble("borderWidth").toFloat())
|
|
34
|
+
val padding = parser.toPixelFromDIP(map.getDouble("padding").toFloat())
|
|
35
|
+
|
|
36
|
+
return CodeBlockStyle(
|
|
37
|
+
fontSize,
|
|
38
|
+
fontFamily,
|
|
39
|
+
fontWeight,
|
|
40
|
+
color,
|
|
41
|
+
marginBottom,
|
|
42
|
+
lineHeight,
|
|
43
|
+
backgroundColor,
|
|
44
|
+
borderColor,
|
|
45
|
+
borderRadius,
|
|
46
|
+
borderWidth,
|
|
47
|
+
padding,
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class CodeStyle(
|
|
6
|
+
val color: Int,
|
|
7
|
+
val backgroundColor: Int,
|
|
8
|
+
val borderColor: Int,
|
|
9
|
+
) {
|
|
10
|
+
companion object {
|
|
11
|
+
fun fromReadableMap(
|
|
12
|
+
map: ReadableMap,
|
|
13
|
+
parser: StyleParser,
|
|
14
|
+
): CodeStyle {
|
|
15
|
+
val color = parser.parseColor(map, "color")
|
|
16
|
+
val backgroundColor = parser.parseColor(map, "backgroundColor")
|
|
17
|
+
val borderColor = parser.parseColor(map, "borderColor")
|
|
18
|
+
return CodeStyle(color, backgroundColor, borderColor)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class EmphasisStyle(
|
|
6
|
+
val color: Int?,
|
|
7
|
+
) {
|
|
8
|
+
companion object {
|
|
9
|
+
fun fromReadableMap(
|
|
10
|
+
map: ReadableMap,
|
|
11
|
+
parser: StyleParser,
|
|
12
|
+
): EmphasisStyle {
|
|
13
|
+
val color = parser.parseOptionalColor(map, "color")
|
|
14
|
+
return EmphasisStyle(color)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class HeadingStyle(
|
|
6
|
+
override val fontSize: Float,
|
|
7
|
+
override val fontFamily: String,
|
|
8
|
+
override val fontWeight: String,
|
|
9
|
+
override val color: Int,
|
|
10
|
+
override val marginBottom: Float,
|
|
11
|
+
override val lineHeight: Float,
|
|
12
|
+
) : BaseBlockStyle {
|
|
13
|
+
companion object {
|
|
14
|
+
fun fromReadableMap(
|
|
15
|
+
map: ReadableMap,
|
|
16
|
+
parser: StyleParser,
|
|
17
|
+
): HeadingStyle {
|
|
18
|
+
val fontSize = parser.toPixelFromSP(map.getDouble("fontSize").toFloat())
|
|
19
|
+
val fontFamily = parser.parseString(map, "fontFamily")
|
|
20
|
+
val fontWeight = parser.parseString(map, "fontWeight", "normal")
|
|
21
|
+
val color = parser.parseColor(map, "color")
|
|
22
|
+
val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
|
|
23
|
+
val lineHeightRaw = map.getDouble("lineHeight").toFloat()
|
|
24
|
+
val lineHeight = parser.toPixelFromSP(lineHeightRaw)
|
|
25
|
+
|
|
26
|
+
return HeadingStyle(fontSize, fontFamily, fontWeight, color, marginBottom, lineHeight)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class ImageStyle(
|
|
6
|
+
val height: Float,
|
|
7
|
+
val borderRadius: Float,
|
|
8
|
+
val marginBottom: Float,
|
|
9
|
+
) {
|
|
10
|
+
companion object {
|
|
11
|
+
fun fromReadableMap(
|
|
12
|
+
map: ReadableMap,
|
|
13
|
+
parser: StyleParser,
|
|
14
|
+
): ImageStyle {
|
|
15
|
+
val height = parser.toPixelFromDIP(map.getDouble("height").toFloat())
|
|
16
|
+
val borderRadius = parser.toPixelFromDIP(map.getDouble("borderRadius").toFloat())
|
|
17
|
+
val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
|
|
18
|
+
return ImageStyle(height, borderRadius, marginBottom)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class InlineImageStyle(
|
|
6
|
+
val size: Float,
|
|
7
|
+
) {
|
|
8
|
+
companion object {
|
|
9
|
+
fun fromReadableMap(
|
|
10
|
+
map: ReadableMap,
|
|
11
|
+
parser: StyleParser,
|
|
12
|
+
): InlineImageStyle {
|
|
13
|
+
val size = parser.toPixelFromDIP(map.getDouble("size").toFloat())
|
|
14
|
+
return InlineImageStyle(size)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class LinkStyle(
|
|
6
|
+
val color: Int,
|
|
7
|
+
val underline: Boolean,
|
|
8
|
+
) {
|
|
9
|
+
companion object {
|
|
10
|
+
fun fromReadableMap(
|
|
11
|
+
map: ReadableMap,
|
|
12
|
+
parser: StyleParser,
|
|
13
|
+
): LinkStyle {
|
|
14
|
+
val color = parser.parseColor(map, "color")
|
|
15
|
+
val underline = map.getBoolean("underline")
|
|
16
|
+
return LinkStyle(color, underline)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.styles
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
|
+
|
|
5
|
+
data class ListStyle(
|
|
6
|
+
override val fontSize: Float,
|
|
7
|
+
override val fontFamily: String,
|
|
8
|
+
override val fontWeight: String,
|
|
9
|
+
override val color: Int,
|
|
10
|
+
override val marginBottom: Float,
|
|
11
|
+
override val lineHeight: Float,
|
|
12
|
+
val bulletColor: Int,
|
|
13
|
+
val bulletSize: Float,
|
|
14
|
+
val markerColor: Int,
|
|
15
|
+
val markerFontWeight: String,
|
|
16
|
+
val gapWidth: Float,
|
|
17
|
+
val marginLeft: Float,
|
|
18
|
+
) : BaseBlockStyle {
|
|
19
|
+
companion object {
|
|
20
|
+
fun fromReadableMap(
|
|
21
|
+
map: ReadableMap,
|
|
22
|
+
parser: StyleParser,
|
|
23
|
+
): ListStyle {
|
|
24
|
+
val fontSize = parser.toPixelFromSP(map.getDouble("fontSize").toFloat())
|
|
25
|
+
val fontFamily = parser.parseString(map, "fontFamily")
|
|
26
|
+
val fontWeight = parser.parseString(map, "fontWeight", "normal")
|
|
27
|
+
val color = parser.parseColor(map, "color")
|
|
28
|
+
val marginBottom = parser.toPixelFromDIP(map.getDouble("marginBottom").toFloat())
|
|
29
|
+
val lineHeightRaw = map.getDouble("lineHeight").toFloat()
|
|
30
|
+
val lineHeight = parser.toPixelFromSP(lineHeightRaw)
|
|
31
|
+
val bulletColor = parser.parseColor(map, "bulletColor")
|
|
32
|
+
val bulletSize = parser.toPixelFromDIP(map.getDouble("bulletSize").toFloat())
|
|
33
|
+
val markerColor = parser.parseColor(map, "markerColor")
|
|
34
|
+
val markerFontWeight = parser.parseString(map, "markerFontWeight", "normal")
|
|
35
|
+
val gapWidth = parser.toPixelFromDIP(map.getDouble("gapWidth").toFloat())
|
|
36
|
+
val marginLeft = parser.toPixelFromDIP(map.getDouble("marginLeft").toFloat())
|
|
37
|
+
|
|
38
|
+
return ListStyle(
|
|
39
|
+
fontSize,
|
|
40
|
+
fontFamily,
|
|
41
|
+
fontWeight,
|
|
42
|
+
color,
|
|
43
|
+
marginBottom,
|
|
44
|
+
lineHeight,
|
|
45
|
+
bulletColor,
|
|
46
|
+
bulletSize,
|
|
47
|
+
markerColor,
|
|
48
|
+
markerFontWeight,
|
|
49
|
+
gapWidth,
|
|
50
|
+
marginLeft,
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|