From 8407374c4ea863f6c0985c3580f459f01728e936 Mon Sep 17 00:00:00 2001 From: Mike Olson Date: Thu, 15 Oct 2026 09:55:19 -0400 Subject: [PATCH 1/3] fix: size ordered list markers to their widest number --- .../ordered_list_wide_markers_test.yaml | 163 ++++++ ...red_list_wide_markers_hundreds_display.png | Bin 0 -> 30529 bytes ...dered_list_wide_markers_nested_display.png | Bin 0 -> 33515 bytes ...ist_wide_markers_short_control_display.png | Bin 0 -> 18555 bytes ...ed_list_wide_markers_thousands_display.png | Bin 0 -> 31267 bytes ...red_list_wide_markers_hundreds_display.png | Bin 0 -> 32647 bytes ...dered_list_wide_markers_nested_display.png | Bin 0 -> 33258 bytes ...ist_wide_markers_short_control_display.png | Bin 0 -> 19441 bytes ...ed_list_wide_markers_thousands_display.png | Bin 0 -> 32425 bytes .../ordered_list_wide_markers_test.yaml | 33 ++ .../ios/ordered_list_wide_markers_display.png | Bin 0 -> 46912 bytes .../ios/api-reference/style-properties.md | 2 +- .../markdown/renderer/BlockStyleContext.kt | 6 + .../markdown/renderer/ListItemRenderer.kt | 45 +- .../markdown/renderer/ListRenderer.kt | 30 + .../enriched/markdown/spans/BaseListSpan.kt | 1 + .../markdown/spans/OrderedListSpan.kt | 24 +- .../enriched/markdown/spans/TaskListSpan.kt | 4 +- .../markdown/spans/UnorderedListSpan.kt | 4 +- .../spans/OrderedListMarkerWidthTest.kt | 281 ++++++++++ .../test/MarkdownRenderTestSupport.kt | 7 +- .../Rendering/RenderContext.swift | 11 + .../Renderers/BlockquoteRenderer.swift | 11 + .../Renderers/ListItemRenderer.swift | 77 ++- .../Rendering/Renderers/ListRenderer.swift | 29 + .../Views/Layout/BlockDecorationConfig.swift | 4 +- .../OrderedListMarkerWidthTests.swift | 198 +++++++ .../ios/OrderedListMarkerWidthTests.mm | 178 ++++++ .../markdown/renderer/BlockStyleContext.kt | 6 + .../markdown/renderer/ListItemRenderer.kt | 23 +- .../markdown/renderer/ListRenderer.kt | 24 + .../enriched/markdown/spans/BaseListSpan.kt | 1 + .../markdown/spans/OrderedListSpan.kt | 24 +- .../enriched/markdown/spans/TaskListSpan.kt | 4 +- .../markdown/spans/UnorderedListSpan.kt | 4 +- .../text/interaction/TaskListTapUtils.kt | 29 +- .../spans/OrderedListMarkerWidthTest.kt | 530 ++++++++++++++++++ .../ios/renderer/ListItemRenderer.m | 7 +- .../ios/renderer/ListRenderer.m | 19 + .../ios/renderer/RenderContext.h | 4 + .../ios/renderer/RenderContext.m | 8 + .../ios/styles/StyleConfig.h | 2 +- .../ios/styles/StyleConfig.mm | 6 +- 43 files changed, 1737 insertions(+), 62 deletions(-) create mode 100644 .maestro/enrichedMarkdownText/flows/advanced/block_elements/ordered_list_wide_markers_test.yaml create mode 100644 .maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_hundreds_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_nested_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_short_control_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_thousands_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_hundreds_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_nested_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_short_control_display.png create mode 100644 .maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_thousands_display.png create mode 100644 .maestro/iosExample/enrichedMarkdownText/flows/basic/block_elements/ordered_list_wide_markers_test.yaml create mode 100644 .maestro/iosExample/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_display.png create mode 100644 packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt create mode 100644 packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift create mode 100644 packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm create mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt diff --git a/.maestro/enrichedMarkdownText/flows/advanced/block_elements/ordered_list_wide_markers_test.yaml b/.maestro/enrichedMarkdownText/flows/advanced/block_elements/ordered_list_wide_markers_test.yaml new file mode 100644 index 000000000..730e26b0e --- /dev/null +++ b/.maestro/enrichedMarkdownText/flows/advanced/block_elements/ordered_list_wide_markers_test.yaml @@ -0,0 +1,163 @@ +appId: swmansion.enriched.markdown.example +tags: + - block + - advanced + - list + - text +--- +- launchApp: + permissions: {} + +- waitForAnimationToEnd + +- runFlow: + file: '../../../../subflows/move_to_playground.yaml' + +- assertVisible: + id: playground-screen + +- runFlow: + file: '../../../subflows/set_enriched_text_value.yaml' + env: + VALUE: | + 1. First short item + 2. Second short item + 3. Third short item + +- runFlow: + when: + platform: Android + commands: + - scrollUntilVisible: + element: + id: blur-button + direction: UP + visibilityPercentage: 100 + - tapOn: + id: blur-button + +- scrollUntilVisible: + element: + id: preview-container + direction: DOWN + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/capture_or_assert_screenshot.yaml' + env: + SCREENSHOT_NAME: 'ordered_list_wide_markers_short_control_display' + +- scrollUntilVisible: + element: + id: set-markdown-button + direction: UP + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/set_enriched_text_value.yaml' + env: + VALUE: | + 98. Before the boundary + 99. Two-digit marker + 100. Three-digit marker + 101. After the boundary + +- runFlow: + when: + platform: Android + commands: + - scrollUntilVisible: + element: + id: blur-button + direction: UP + visibilityPercentage: 100 + - tapOn: + id: blur-button + +- scrollUntilVisible: + element: + id: preview-container + direction: DOWN + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/capture_or_assert_screenshot.yaml' + env: + SCREENSHOT_NAME: 'ordered_list_wide_markers_hundreds_display' + +- scrollUntilVisible: + element: + id: set-markdown-button + direction: UP + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/set_enriched_text_value.yaml' + env: + VALUE: | + 998. Before the boundary + 999. Three-digit marker + 1000. Four-digit marker + 1001. After the boundary + +- runFlow: + when: + platform: Android + commands: + - scrollUntilVisible: + element: + id: blur-button + direction: UP + visibilityPercentage: 100 + - tapOn: + id: blur-button + +- scrollUntilVisible: + element: + id: preview-container + direction: DOWN + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/capture_or_assert_screenshot.yaml' + env: + SCREENSHOT_NAME: 'ordered_list_wide_markers_thousands_display' + +- scrollUntilVisible: + element: + id: set-markdown-button + direction: UP + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/set_enriched_text_value.yaml' + env: + VALUE: | + 1000. Wide parent + 1. Nested first item + 1. Deeper nested item + 2. Nested second item + 1001. Next wide parent + +- runFlow: + when: + platform: Android + commands: + - scrollUntilVisible: + element: + id: blur-button + direction: UP + visibilityPercentage: 100 + - tapOn: + id: blur-button + +- scrollUntilVisible: + element: + id: preview-container + direction: DOWN + visibilityPercentage: 100 + +- runFlow: + file: '../../../subflows/capture_or_assert_screenshot.yaml' + env: + SCREENSHOT_NAME: 'ordered_list_wide_markers_nested_display' diff --git a/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_hundreds_display.png b/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_hundreds_display.png new file mode 100644 index 0000000000000000000000000000000000000000..229d97a520e291276283d9289bb87ef6b6c7fd07 GIT binary patch literal 30529 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

i0Vbr)ybSxQfjkf^lg-uF_FMWJPsH!r-LkL2p&> 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�+mlMXL6 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 literal 0 HcmV?d00001 diff --git a/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_short_control_display.png b/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_short_control_display.png new file mode 100644 index 0000000000000000000000000000000000000000..887005cc76cf9eca0f52b0dceb466abc95a629c2 GIT binary patch literal 18555 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 L&BrAVpTGSdKXeml literal 0 HcmV?d00001 diff --git a/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_thousands_display.png b/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_thousands_display.png new file mode 100644 index 0000000000000000000000000000000000000000..a3ca7e714d3b3c4a8dcab6443189fc71e4bc4f32 GIT binary patch literal 31267 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 literal 0 HcmV?d00001 diff --git a/.maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_nested_display.png b/.maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_nested_display.png new file mode 100644 index 0000000000000000000000000000000000000000..a52b7111b5586acf818ced3ed6002fb84cb8e392 GIT binary patch literal 33258 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 literal 0 HcmV?d00001 diff --git a/.maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_short_control_display.png b/.maestro/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_short_control_display.png new file mode 100644 index 0000000000000000000000000000000000000000..2b25b45bf4d052005c50aba4e09c9aba561d48d8 GIT binary patch literal 19441 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 literal 0 HcmV?d00001 diff --git a/.maestro/iosExample/enrichedMarkdownText/flows/basic/block_elements/ordered_list_wide_markers_test.yaml b/.maestro/iosExample/enrichedMarkdownText/flows/basic/block_elements/ordered_list_wide_markers_test.yaml new file mode 100644 index 000000000..3e1a0dd65 --- /dev/null +++ b/.maestro/iosExample/enrichedMarkdownText/flows/basic/block_elements/ordered_list_wide_markers_test.yaml @@ -0,0 +1,33 @@ +appId: swmansion.enriched.markdown.ios.example +tags: + - block + - list + - text +--- +- launchApp + +- runFlow: + file: '../../../../subflows/move_to_playground.yaml' + +- runFlow: + file: '../../../subflows/set_enriched_text_value.yaml' + env: + VALUE: | + 1. One + 2. Two + 3. Three + 4. Four + 5. Five + 6. Six + 7. Seven + 8. Eight + 9. Nine + 10. Ten + 11. Eleven + 12. Twelve + - Nested under a two-digit item + +- runFlow: + file: '../../../subflows/capture_or_assert_screenshot.yaml' + env: + SCREENSHOT_NAME: 'ordered_list_wide_markers_display' diff --git a/.maestro/iosExample/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_display.png b/.maestro/iosExample/enrichedMarkdownText/screenshots/ios/ordered_list_wide_markers_display.png new file mode 100644 index 0000000000000000000000000000000000000000..db03347477d0267da43898fc2434e16d3f1fcd15 GIT binary patch literal 46912 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 literal 0 HcmV?d00001 diff --git a/docs/docs/ios/api-reference/style-properties.md b/docs/docs/ios/api-reference/style-properties.md index d294ee7c3..239fd7c87 100644 --- a/docs/docs/ios/api-reference/style-properties.md +++ b/docs/docs/ios/api-reference/style-properties.md @@ -256,7 +256,7 @@ Ordered and unordered lists, and their markers. Takes the [shared modifiers](#sh | `.bulletColor(_:)` | `Color \| semantic` | `.secondary` | The dot drawn for an unordered item | | `.bulletSize(_:)` | `CGFloat` | `6` | Diameter of that dot, in points | | `.markerColor(_:)` | `Color \| semantic` | `.secondary` | The `1.` `2.` `3.` of an ordered item | -| `.markerMinWidth(_:)` | `CGFloat` | `0` | Minimum width reserved for the marker column, so numbers past `9.` do not shift the text. `0` sizes the column to each marker | +| `.markerMinWidth(_:)` | `CGFloat` | `0` | Minimum width reserved for the marker column. An ordered list's column also grows to fit its widest number, so its markers are never clipped | | `.gapWidth(_:)` | `CGFloat` | `12` | Space between the marker and the item text. Clamped to a minimum of `4` | | `.marginLeading(_:)` | `CGFloat` | `24` | Indent added per nesting level | diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt index 89c37ece7..74e4f0c41 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt @@ -41,6 +41,9 @@ class BlockStyleContext { var listDepth = 0 var listType: ListType? = null var listItemNumber = 0 + var listMarkerWidth = 0f + var ancestorMarkerOffset = 0f + var listItemMarkerExtra = 0f var taskItemCount = 0 private val orderedListItemNumbers = ArrayDeque() @@ -149,6 +152,9 @@ class BlockStyleContext { listDepth = 0 listType = null listItemNumber = 0 + listMarkerWidth = 0f + ancestorMarkerOffset = 0f + listItemMarkerExtra = 0f taskItemCount = 0 orderedListItemNumbers.clear() } diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt index 541d66f51..b9485d3f7 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt @@ -37,18 +37,8 @@ class ListItemRenderer( // indices, matching the top-down order of `- [ ]` markers in the source. val taskIndex = if (isTask) styleContext.taskItemCount++ else -1 - factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) - - if (builder.length == start || builder.substring(start).isBlank()) return - - while (builder.length > start && builder.last() == '\n') { - builder.delete(builder.length - 1, builder.length) - } - builder.append("\n") - val depth = styleContext.listDepth - 1 val listStyle = config.style.listStyle - val itemEnd = builder.length val span = if (isTask) { TaskListSpan( @@ -59,21 +49,52 @@ class ListItemRenderer( styleCache = factory.styleCache, taskIndex = taskIndex, isChecked = isChecked, + ancestorMarkerOffset = styleContext.ancestorMarkerOffset, ) } else { when (listType) { BlockStyleContext.ListType.UNORDERED -> { - UnorderedListSpan(listStyle, depth, factory.context, factory.styleCache) + UnorderedListSpan( + listStyle, + depth, + factory.context, + factory.styleCache, + styleContext.ancestorMarkerOffset, + ) } BlockStyleContext.ListType.ORDERED -> { - OrderedListSpan(listStyle, depth, factory.context, factory.styleCache).apply { + OrderedListSpan( + listStyle, + depth, + factory.context, + factory.styleCache, + styleContext.listMarkerWidth, + styleContext.ancestorMarkerOffset, + ).apply { setItemNumber(styleContext.listItemNumber) } } } } + // Nested lists inside this item shift by its extra marker width. + val previousMarkerExtra = styleContext.listItemMarkerExtra + styleContext.listItemMarkerExtra = (span as? OrderedListSpan)?.markerExtraWidth ?: 0f + try { + factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) + } finally { + styleContext.listItemMarkerExtra = previousMarkerExtra + } + + if (builder.length == start || builder.substring(start).isBlank()) return + + while (builder.length > start && builder.last() == '\n') { + builder.delete(builder.length - 1, builder.length) + } + builder.append("\n") + + val itemEnd = builder.length builder.setSpan(span, start, itemEnd, SPAN_FLAGS_LIST_ITEM) if (isChecked) { diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt index e3e5f4f03..4893a5587 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt @@ -3,6 +3,8 @@ package com.swmansion.enriched.markdown.renderer import android.text.SpannableStringBuilder import com.swmansion.enriched.markdown.parser.MarkdownASTNode import com.swmansion.enriched.markdown.spans.MarginBottomSpan +import com.swmansion.enriched.markdown.spans.OrderedListSpan +import com.swmansion.enriched.markdown.styles.ListStyle import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE import com.swmansion.enriched.markdown.utils.text.span.applyLineHeightSkippingImages import com.swmansion.enriched.markdown.utils.text.span.applyMarginTop @@ -24,6 +26,13 @@ class ListRenderer( val contextManager = ListContextManager(factory.blockStyleContext) val entryState = contextManager.enterList(listType, listStyle) + val styleContext = factory.blockStyleContext + val previousMarkerWidth = styleContext.listMarkerWidth + val previousMarkerOffset = styleContext.ancestorMarkerOffset + if (entryState.previousDepth > 0) { + styleContext.ancestorMarkerOffset += styleContext.listItemMarkerExtra + } + styleContext.listMarkerWidth = if (isOrdered) measureMarkerColumn(node, listStyle, factory) else 0f // For top-level lists, insert marginTop spacer before rendering content if (entryState.previousDepth == 0) { @@ -41,6 +50,8 @@ class ListRenderer( try { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) } finally { + styleContext.listMarkerWidth = previousMarkerWidth + styleContext.ancestorMarkerOffset = previousMarkerOffset contextManager.exitList(entryState) } @@ -49,6 +60,25 @@ class ListRenderer( } } + /** Widest marker this list draws; lists under 100 items keep the `99.` column. */ + private fun measureMarkerColumn( + node: MarkdownASTNode, + listStyle: ListStyle, + factory: RendererFactory, + ): Float { + val marker = OrderedListSpan(listStyle, 0, factory.context, factory.styleCache) + var number = 1 + var width = marker.measureMarkerWidth(99) + for (item in node.children) { + if (item.type != MarkdownASTNode.NodeType.ListItem) continue + if (number >= 100 && item.attributes["isTask"] != "true") { + width = maxOf(width, marker.measureMarkerWidth(number)) + } + number++ + } + return width + } + private fun applyListSpacing( builder: SpannableStringBuilder, start: Int, diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt index fea4aa03e..3ebbcabed 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt @@ -22,6 +22,7 @@ abstract class BaseListSpan( protected val blockStyle: BlockStyle, protected val marginLeft: Float, protected val gapWidth: Float, + internal val ancestorMarkerOffset: Float = 0f, ) : MetricAffectingSpan(), LeadingMarginSpan { private var cachedText: CharSequence? = null diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt index e134bb669..8f3368ad1 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt @@ -16,6 +16,8 @@ class OrderedListSpan( depth: Int, context: Context, styleCache: SpanStyleCache, + private val markerWidth: Float = 0f, + ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -29,6 +31,7 @@ class OrderedListSpan( ), marginLeft = listStyle.marginLeft, gapWidth = listStyle.gapWidth, + ancestorMarkerOffset = ancestorMarkerOffset, ) { companion object { private val sharedMarkerPaint = TextPaint().apply { isAntiAlias = true } @@ -48,10 +51,21 @@ class OrderedListSpan( typeface = markerTypeface } - override fun getMarkerWidth(): Float { - val paint = configureMarkerPaint() - return listStyle.effectiveMarkerWidth(paint.measureText("99.")) - } + private val defaultMarkerWidth = measureMarkerWidth(99) + private val resolvedMarkerWidth = maxOf(markerWidth, defaultMarkerWidth) + + internal val markerExtraWidth = resolvedMarkerWidth - defaultMarkerWidth + + override fun getMarkerWidth(): Float = resolvedMarkerWidth + + internal fun measureMarkerWidth(number: Int): Float = listStyle.effectiveMarkerWidth(configureMarkerPaint().measureText("$number.")) + + override fun getLeadingMargin(first: Boolean): Int = + if (depth > 0) { + (listStyle.marginLeft + markerExtraWidth).toInt() + } else { + super.getLeadingMargin(first) + } var itemNumber: Int = 1 private set @@ -71,7 +85,7 @@ class OrderedListSpan( val text = if (dir < 0) ".$itemNumber" else "$itemNumber." val textWidth = markerPaint.measureText(text) - val markerRightEdge = x + (depth * marginLeft + getMarkerWidth()) * dir + val markerRightEdge = x + (depth * marginLeft + ancestorMarkerOffset + getMarkerWidth()) * dir val markerX = if (dir > 0) markerRightEdge - textWidth else markerRightEdge canvas.drawText(text, markerX, baseline.toFloat(), markerPaint) diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt index 2784850b3..564a13f82 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt @@ -26,6 +26,7 @@ class TaskListSpan( * moves it to the end of that order and shifts where its marker lands. */ var isChecked: Boolean, + ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -39,6 +40,7 @@ class TaskListSpan( ), marginLeft = listStyle.marginLeft, gapWidth = listStyle.gapWidth, + ancestorMarkerOffset = ancestorMarkerOffset, ) { companion object { private val boxPaint = @@ -79,7 +81,7 @@ class TaskListSpan( ) { val capHeight = -markerFontMetrics.ascent * CAP_HEIGHT_RATIO val centerY = baseline - capHeight / HALF_DIVISOR - val centerX = x + (depth * marginLeft + markerColumnWidth - checkboxSize / HALF_DIVISOR) * dir + val centerX = x + (depth * marginLeft + ancestorMarkerOffset + markerColumnWidth - checkboxSize / HALF_DIVISOR) * dir val half = checkboxSize / HALF_DIVISOR rect.set(centerX - half, centerY - half, centerX + half, centerY + half) diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt index 2b3465aa5..a5df5b519 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt @@ -13,6 +13,7 @@ class UnorderedListSpan( depth: Int, context: Context, styleCache: SpanStyleCache, + ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -26,6 +27,7 @@ class UnorderedListSpan( ), marginLeft = listStyle.marginLeft, gapWidth = listStyle.gapWidth, + ancestorMarkerOffset = ancestorMarkerOffset, ) { companion object { private val sharedBulletPaint = @@ -63,7 +65,7 @@ class UnorderedListSpan( // it hugs the gap before the text — matches iOS behavior and stays // visually flush-left when the column width equals the bullet radius // (the default). - val bulletX = x + (depth * marginLeft + markerColumnWidth) * dir + val bulletX = x + (depth * marginLeft + ancestorMarkerOffset + markerColumnWidth) * dir val fontMetrics = paint.fontMetrics val bulletY = baseline + (fontMetrics.ascent + fontMetrics.descent) / 2f diff --git a/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt b/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt new file mode 100644 index 000000000..d471abe0d --- /dev/null +++ b/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt @@ -0,0 +1,281 @@ +package com.swmansion.enriched.markdown.spans + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Rect +import android.graphics.RectF +import android.graphics.Typeface +import android.text.SpannableString +import android.text.StaticLayout +import android.text.TextDirectionHeuristics +import android.text.TextPaint +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.swmansion.enriched.markdown.parser.MarkdownASTNode +import com.swmansion.enriched.markdown.styles.StyleConfig +import com.swmansion.enriched.markdown.test.MarkdownRenderTestSupport +import com.swmansion.enriched.markdown.test.MarkdownRenderTestSupport.render +import com.swmansion.enriched.markdown.test.TestAstFactory.document +import com.swmansion.enriched.markdown.test.TestAstFactory.listItem +import com.swmansion.enriched.markdown.test.TestAstFactory.orderedList +import com.swmansion.enriched.markdown.test.TestAstFactory.paragraph +import com.swmansion.enriched.markdown.test.TestAstFactory.taskListItem +import com.swmansion.enriched.markdown.test.TestAstFactory.text +import com.swmansion.enriched.markdown.test.TestAstFactory.unorderedList +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(AndroidJUnit4::class) +@Config(sdk = [28]) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class OrderedListMarkerWidthTest { + @Test + fun shortListsKeepTheirIndentAndLongListsShareTheirWidestGutter() { + val style = styleConfig() + val paint = + TextPaint().apply { + textSize = style.listStyle.fontSize + typeface = Typeface.create("monospace", Typeface.NORMAL) + } + val baseline = paint.measureText("99.") + val gap = style.listStyle.gapWidth + val short = orderedSpans(style, numbered(99)) + short.forEach { assertEquals((baseline + gap).toInt(), it.getLeadingMargin(false)) } + for (count in listOf(100, 101, 250, 1000)) { + val spans = orderedSpans(style, numbered(count)) + val widest = maxOf(baseline, spans.maxOf { paint.measureText("${it.itemNumber}.") }) + spans.forEach { assertEquals((widest + gap).toInt(), it.getLeadingMargin(false)) } + assertTrue(spans.first().getLeadingMargin(false) > short.first().getLeadingMargin(false)) + } + } + + @Test + fun nestedAndFollowingListsRestoreTheirOwnGutters() { + val style = styleConfig() + val outer = withChild(numbered(101), 0, numbered(1000)) + val spans = orderedSpans(style, outer, numbered(1)) + val parent = spans.filter { it.depth == 0 }.dropLast(1) + assertEquals(101, parent.size) + parent.forEach { assertEquals(parent.first().getLeadingMargin(false), it.getLeadingMargin(false)) } + spans.filter { it.depth == 1 }.forEach { assertTrue(it.getLeadingMargin(false) > style.listStyle.marginLeft) } + val following = spans.last() + assertEquals(0, following.depth) + assertTrue(following.getLeadingMargin(false) < parent.first().getLeadingMargin(false)) + } + + @Test + fun markerMinimumWidthRemainsAFloor() { + val style = styleConfig(minWidth = 200f) + orderedSpans(style, numbered(101)).forEach { + assertEquals((style.listStyle.markerMinWidth + style.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) + } + } + + @Test + fun drawnMarkersStayInsideTheGutterAndAttachedToTheirParagraphs() { + val style = styleConfig() + for (count in listOf(4, 101, 1000)) { + val threeLevels = withChild(numbered(1), 0, numbered(1)) + drawMarkers(style, withChild(numbered(count), 2, threeLevels)).forEach { geometry -> + assertEquals( + "marker right at depth ${geometry.depth} in a list of $count", + geometry.paragraphLeft - style.listStyle.gapWidth, + geometry.marker.right, + 0.01f, + ) + } + } + } + + @Test + fun nestedBulletColumnsKeepTheirGapUnderWideParents() { + val style = styleConfig() + + fun tree(count: Int) = withChild(numbered(count), 2, unorderedList(item(), item())) + for (count in listOf(101, 1000)) { + assertNestedMarkerGapsUnchanged(style, tree(4), tree(count)) + } + } + + @Test + fun tasksDoNotPassTheWideListsNumericExtraToTheirChildren() { + val style = styleConfig() + + fun tree(count: Int): MarkdownASTNode { + val items = numbered(count).children.toMutableList() + items[1] = taskListItem(checked = false, paragraph(text("task")), numbered(1)) + items[2] = listItem(paragraph(text("item")), numbered(1)) + return orderedList(*items.toTypedArray()) + } + assertNestedMarkerGapsUnchanged(style, tree(4), tree(1000)) + } + + @Test + fun nestedTasksKeepTheirGapUnderWideNumericParents() { + val style = styleConfig() + + fun tree(count: Int) = withChild(numbered(count), 2, orderedList(taskListItem(checked = false, paragraph(text("task"))))) + for (count in listOf(101, 1000)) { + assertNestedMarkerGapsUnchanged(style, tree(4), tree(count)) + } + } + + @Test + fun inheritedMarkerOffsetsFollowTheRtlDirection() { + val style = styleConfig() + val text = SpannableString(render(document(withChild(numbered(1000), 0, numbered(1))), style)) + val layout = + StaticLayout.Builder + .obtain(text, 0, text.length, TextPaint(), LAYOUT_WIDTH) + .setTextDirection(TextDirectionHeuristics.RTL) + .build() + val canvas = MarkerCanvas() + layout.draw(canvas) + assertEquals(1001, canvas.markers.size) + canvas.markers.forEach { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + assertEquals(-1, layout.getParagraphDirection(line)) + assertEquals(layout.getParagraphRight(line) + style.listStyle.gapWidth, marker.left, 0.01f) + assertTrue(marker.right <= layout.width) + } + } + + private fun assertNestedMarkerGapsUnchanged( + style: StyleConfig, + short: MarkdownASTNode, + wide: MarkdownASTNode, + ) { + val shortMarkers = drawMarkers(style, short).filter { it.depth > 0 } + val wideMarkers = drawMarkers(style, wide).filter { it.depth > 0 } + assertTrue(shortMarkers.isNotEmpty()) + assertEquals(shortMarkers.size, wideMarkers.size) + shortMarkers.zip(wideMarkers).forEach { (control, actual) -> + assertEquals(control.depth, actual.depth) + assertEquals( + "nested marker gap at depth ${actual.depth}", + control.paragraphLeft - control.marker.right, + actual.paragraphLeft - actual.marker.right, + 0.01f, + ) + } + } + + private fun drawMarkers( + style: StyleConfig, + vararg lists: MarkdownASTNode, + ): List { + // SpannableString reports spans in insertion order, as the text view does. + val text = SpannableString(render(document(*lists), style)) + val paint = TextPaint().apply { textSize = style.listStyle.fontSize } + val layout = StaticLayout.Builder.obtain(text, 0, text.length, paint, LAYOUT_WIDTH).build() + val canvas = MarkerCanvas() + layout.draw(canvas) + assertEquals(text.getSpans(0, text.length, BaseListSpan::class.java).size, canvas.markers.size) + return canvas.markers.map { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + assertTrue("marker left ${marker.left} on line $line", marker.left >= 0f) + val start = layout.getLineStart(line) + val depth = text.getSpans(start, start + 1, BaseListSpan::class.java).maxOf { it.depth } + MarkerGeometry(marker, layout.getParagraphLeft(line).toFloat(), depth) + } + } + + private fun orderedSpans( + style: StyleConfig, + vararg lists: MarkdownASTNode, + ): List { + val text = render(document(*lists), style) + return text + .getSpans(0, text.length, OrderedListSpan::class.java) + .sortedWith(compareBy({ text.getSpanStart(it) }, { it.depth })) + } + + private data class MarkerGeometry( + val marker: DrawnMarker, + val paragraphLeft: Float, + val depth: Int, + ) + + private data class DrawnMarker( + val left: Float, + val right: Float, + val baseline: Float, + ) + + private class MarkerCanvas : Canvas(Bitmap.createBitmap(LAYOUT_WIDTH, 1, Bitmap.Config.ARGB_8888)) { + val markers = mutableListOf() + + // Layout draws only the lines inside the clip; report a clip tall enough for every list here. + override fun getClipBounds(bounds: Rect): Boolean { + bounds.set(0, 0, LAYOUT_WIDTH, Int.MAX_VALUE / 2) + return true + } + + override fun drawCircle( + cx: Float, + cy: Float, + radius: Float, + paint: Paint, + ) { + // Bullets are centered on the reserved column edge, matching the iOS drawer. + val outerRadius = radius + paint.strokeWidth / 2f + markers += DrawnMarker(cx - outerRadius, cx, cy) + super.drawCircle(cx, cy, radius, paint) + } + + override fun drawRoundRect( + rect: RectF, + rx: Float, + ry: Float, + paint: Paint, + ) { + val halfStroke = if (paint.style == Paint.Style.STROKE) paint.strokeWidth / 2f else 0f + markers += DrawnMarker(rect.left - halfStroke, rect.right + halfStroke, rect.centerY()) + super.drawRoundRect(rect, rx, ry, paint) + } + + override fun drawText( + text: String, + x: Float, + y: Float, + paint: Paint, + ) { + if (text.matches(Regex("(?:[0-9]+\\.|\\.[0-9]+)"))) markers += DrawnMarker(x, x + paint.measureText(text), y) + super.drawText(text, x, y, paint) + } + } + + private fun item(): MarkdownASTNode = listItem(paragraph(text("item"))) + + private fun numbered(count: Int): MarkdownASTNode = orderedList(*Array(count) { item() }) + + private fun withChild( + list: MarkdownASTNode, + index: Int, + child: MarkdownASTNode, + ): MarkdownASTNode { + val items = list.children.toMutableList() + items[index] = items[index].copy(children = items[index].children + child) + return list.copy(children = items) + } + + private fun styleConfig(minWidth: Float = 0f): StyleConfig { + val base = MarkdownRenderTestSupport.defaultStyle + return MarkdownRenderTestSupport.styleWithList( + base.listStyle.copy( + fontFamily = "monospace", + markerMinWidth = minWidth, + gapWidth = 8f, + marginLeft = 24f, + ), + ) + } + + private companion object { + const val LAYOUT_WIDTH = 2000 + } +} diff --git a/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt b/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt index 9a03ee04b..06a22103f 100644 --- a/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt +++ b/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt @@ -16,6 +16,7 @@ import com.swmansion.enriched.markdown.styles.CodeStyle import com.swmansion.enriched.markdown.styles.HeadingStyle import com.swmansion.enriched.markdown.styles.HighlightStyle import com.swmansion.enriched.markdown.styles.LinkStyle +import com.swmansion.enriched.markdown.styles.ListStyle import com.swmansion.enriched.markdown.styles.ParagraphStyle import com.swmansion.enriched.markdown.styles.SpoilerStyle import com.swmansion.enriched.markdown.styles.StrikethroughStyle @@ -101,6 +102,9 @@ object MarkdownRenderTestSupport { ) } + /** [defaultStyle] with only its [ListStyle] replaced. */ + fun styleWithList(listStyle: ListStyle): StyleConfig = copyOfDefault(listStyle = listStyle) + /** [defaultStyle] with only its [TaskListStyle] replaced. */ fun styleWithTaskList(taskListStyle: TaskListStyle): StyleConfig = copyOfDefault(taskListStyle = taskListStyle) @@ -111,6 +115,7 @@ object MarkdownRenderTestSupport { strikethroughStyle: StrikethroughStyle? = null, underlineStyle: UnderlineStyle? = null, highlightStyle: HighlightStyle? = null, + listStyle: ListStyle? = null, taskListStyle: TaskListStyle? = null, blockquoteStyle: BlockquoteStyle? = null, codeStyle: CodeStyle? = null, @@ -137,7 +142,7 @@ object MarkdownRenderTestSupport { imageStyle = base.imageStyle, inlineImageStyle = base.inlineImageStyle, blockquoteStyle = blockquoteStyle ?: base.blockquoteStyle, - listStyle = base.listStyle, + listStyle = listStyle ?: base.listStyle, taskListStyle = taskListStyle ?: base.taskListStyle, codeBlockStyle = codeBlockStyle ?: base.codeBlockStyle, thematicBreakStyle = base.thematicBreakStyle, diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift index 52185914f..96189afa8 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift @@ -43,6 +43,9 @@ enum MarkdownAttribute { /// Leading inset of a quote's bars and fill, set on quote paragraphs /// that sit inside a list item (the item's text column). static let blockquoteBarOffset = NSAttributedString.Key("EnrichedMarkdownBlockquoteBarOffset") + /// Marker widening already applied to a quote paragraph by the list items + /// it sits in, so an enclosing item's bar offset keeps it. + static let blockquoteMarkerExtra = NSAttributedString.Key("EnrichedMarkdownBlockquoteMarkerExtra") /// Present on blockquote paragraphs inside a GitHub admonition: the bar /// color of each nesting level, outermost first. static let blockquoteBarColors = NSAttributedString.Key("EnrichedMarkdownBlockquoteBarColors") @@ -76,6 +79,14 @@ package final class RenderContext { var listDepth = 0 var listType: ListType = .unordered var listItemNumber = 0 + /// Marker column of the current ordered list, sized to its widest number. + var listMarkerWidth: CGFloat = 0 + /// How far the current list's marker column exceeds the default one. + var listMarkerExtra: CGFloat = 0 + /// Extra marker width of the enclosing list items, carried into nested lists. + var listMarkerOffset: CGFloat = 0 + /// Extra marker width of the list item whose children are rendering. + var listItemMarkerExtra: CGFloat = 0 var taskItemIndex = 0 var rendersBlockImage = false /// Set once a superscript or subscript run is rendered, so the post-pass diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift index 27966a2c9..c0116c95f 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift @@ -27,11 +27,22 @@ final class BlockquoteRenderer: NodeRenderer { if let admonition { appendHeader(for: admonition, font: font, to: output) } + // An enclosing list item shifts the whole quote by its own indent, which + // already includes any widened marker column, so lists inside start fresh. + let prevMarkerOffset = context.listMarkerOffset + let prevItemMarkerExtra = context.listItemMarkerExtra + context.listMarkerOffset = 0 + context.listItemMarkerExtra = 0 factory.renderChildren(of: node, into: output, context: context) + context.listMarkerOffset = prevMarkerOffset + context.listItemMarkerExtra = prevItemMarkerExtra context.clearBlockStyle() context.exitBlockquote() guard output.length > start else { return } + // Bars share one offset per paragraph, so widening from lists inside this + // quote must not move this quote's own bar when an outer item shifts it. + output.removeAttribute(MarkdownAttribute.blockquoteMarkerExtra, range: NSRange(location: start, length: output.length - start)) applyStylingAndSpacing(to: output, start: start, end: output.length, levels: levels) } diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift index c779225fc..ffe2852dc 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift @@ -22,20 +22,27 @@ final class ListItemRenderer: NodeRenderer { context.taskItemIndex += 1 } + let baseMarkerWidth = isTask + ? effectiveTaskMarkerWidth(in: context) + : effectiveMarkerWidth(in: context) + // How far a widened ordered list grew this item's own column; nested lists move by it. + let markerExtra = baseMarkerWidth - defaultColumnWidth(isTask: isTask, listType: context.listType) + let startLocation = output.length + let prevMarkerExtra = context.listItemMarkerExtra + context.listItemMarkerExtra = markerExtra factory.renderChildren(of: node, into: output, context: context) + context.listItemMarkerExtra = prevMarkerExtra ParagraphStyleHelpers.ensureTrailingNewline(in: output) let itemRange = NSRange(location: startLocation, length: output.length - startLocation) guard itemRange.length > 0 else { return } - let baseMarkerWidth = isTask - ? effectiveTaskMarkerWidth(for: context.listType) - : effectiveMarkerWidth(for: context.listType) let gapWidth = max(config.list.gapWidth ?? 12, 4) let marginLeading = config.list.marginLeading ?? 24 let blockquoteIndent = CGFloat(context.blockquoteDepth) * blockquoteLevelSpacing() let totalIndent = blockquoteIndent + baseMarkerWidth + gapWidth + (CGFloat(nestingLevel) * marginLeading) + + context.listMarkerOffset let lineHeight = config.list.lineHeight ?? 0 let metadata: [NSAttributedString.Key: Any] = [ @@ -49,7 +56,11 @@ final class ListItemRenderer: NodeRenderer { itemRange: itemRange, nestingLevel: nestingLevel, metadata: metadata, - totalIndent: totalIndent, + indents: ItemIndents( + text: totalIndent, + quote: totalIndent - context.listMarkerOffset, + markerExtra: markerExtra + ), lineHeight: lineHeight ) @@ -64,7 +75,21 @@ final class ListItemRenderer: NodeRenderer { } } - private func effectiveMarkerWidth(for listType: ListType) -> CGFloat { + /// An ordered list's column is sized to its widest number by `ListRenderer`. + private func effectiveMarkerWidth(in context: RenderContext) -> CGFloat { + context.listType == .ordered + ? context.listMarkerWidth + : Self.defaultMarkerWidth(for: .unordered, config: config) + } + + /// The item's column before an ordered list widens it for its numbers. + private func defaultColumnWidth(isTask: Bool, listType: ListType) -> CGFloat { + let markerWidth = Self.defaultMarkerWidth(for: listType, config: config) + return isTask ? max(markerWidth, config.taskList.checkboxSize ?? 14) : markerWidth + } + + /// The marker column before an ordered list widens it for its numbers. + static func defaultMarkerWidth(for listType: ListType, config: MarkdownStyleConfiguration) -> CGFloat { let minWidth = config.list.markerMinWidth ?? 0 switch listType { case .ordered: @@ -74,10 +99,10 @@ final class ListItemRenderer: NodeRenderer { } } - /// The checkbox column is at least as wide as the list type's normal - /// marker column, so task items align with their non-task siblings. - private func effectiveTaskMarkerWidth(for listType: ListType) -> CGFloat { - max(effectiveMarkerWidth(for: listType), config.taskList.checkboxSize ?? 14) + /// The checkbox column is at least as wide as the list's marker column, + /// so task items align with their non-task siblings. + private func effectiveTaskMarkerWidth(in context: RenderContext) -> CGFloat { + max(effectiveMarkerWidth(in: context), config.taskList.checkboxSize ?? 14) } private func blockquoteLevelSpacing() -> CGFloat { @@ -139,7 +164,7 @@ final class ListItemRenderer: NodeRenderer { itemRange: NSRange, nestingLevel: Int, metadata: [NSAttributedString.Key: Any], - totalIndent: CGFloat, + indents: ItemIndents, lineHeight: CGFloat ) { let string = output.string as NSString @@ -153,7 +178,7 @@ final class ListItemRenderer: NodeRenderer { location = NSMaxRange(applyRange) if output.attribute(MarkdownAttribute.blockquoteDepth, at: applyRange.location, effectiveRange: nil) != nil { - shiftQuoteParagraph(in: output, range: applyRange, by: totalIndent) + shiftQuoteParagraph(in: output, range: applyRange, indents: indents) continue } if shouldSkipListStyling(in: output, range: applyRange, nestingLevel: nestingLevel) { @@ -161,8 +186,8 @@ final class ListItemRenderer: NodeRenderer { } let style = NSMutableParagraphStyle() - style.firstLineHeadIndent = totalIndent - style.headIndent = totalIndent + style.firstLineHeadIndent = indents.text + style.headIndent = indents.text if lineHeight > 0 { style.minimumLineHeight = lineHeight @@ -180,13 +205,20 @@ final class ListItemRenderer: NodeRenderer { } /// A quote inside the item keeps its own attributes and indent, moved - /// into the item's text column together with its bars. - private func shiftQuoteParagraph(in output: NSMutableAttributedString, range: NSRange, by offset: CGFloat) { + /// into the item's text column together with its bars. The bars also keep + /// the marker widening of any list item between this one and the quote. + private func shiftQuoteParagraph(in output: NSMutableAttributedString, range: NSRange, indents: ItemIndents) { + let innerExtra = output.attribute(MarkdownAttribute.blockquoteMarkerExtra, at: range.location, effectiveRange: nil) + as? CGFloat ?? 0 let style = ParagraphStyleHelpers.getOrCreateParagraphStyle(in: output, at: range.location) - style.firstLineHeadIndent += offset - style.headIndent += offset + style.firstLineHeadIndent += indents.quote + style.headIndent += indents.quote output.addAttributes( - [.paragraphStyle: style, MarkdownAttribute.blockquoteBarOffset: offset], + [ + .paragraphStyle: style, + MarkdownAttribute.blockquoteBarOffset: indents.quote + innerExtra, + MarkdownAttribute.blockquoteMarkerExtra: innerExtra + indents.markerExtra + ], range: range ) } @@ -216,3 +248,12 @@ final class ListItemRenderer: NodeRenderer { ).location == NSNotFound } } + +/// Where a list item moves its own paragraphs and the quotes inside it. +private struct ItemIndents { + let text: CGFloat + /// Each enclosing item shifts a quote too, adding its own widened column then. + let quote: CGFloat + /// How far a widened ordered list grew this item's marker column. + let markerExtra: CGFloat +} diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift index d5c1149be..cdfbc01d5 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift @@ -15,6 +15,9 @@ final class ListRenderer: NodeRenderer { let prevDepth = context.listDepth let prevType = context.listType let prevNumber = context.listItemNumber + let prevMarkerWidth = context.listMarkerWidth + let prevMarkerExtra = context.listMarkerExtra + let prevMarkerOffset = context.listMarkerOffset let startLocation = output.length if prevDepth == 0 { @@ -31,6 +34,12 @@ final class ListRenderer: NodeRenderer { context.listDepth = prevDepth + 1 context.listType = isOrdered ? .ordered : .unordered context.listItemNumber = 0 + if prevDepth > 0 { + context.listMarkerOffset += context.listItemMarkerExtra + } + let defaultMarkerWidth = ListItemRenderer.defaultMarkerWidth(for: .ordered, config: config) + context.listMarkerWidth = isOrdered ? widestMarkerWidth(of: node, atLeast: defaultMarkerWidth) : 0 + context.listMarkerExtra = isOrdered ? context.listMarkerWidth - defaultMarkerWidth : 0 let font = config.list.font ?? UIFont.preferredFont(forTextStyle: .body) let color = config.list.foregroundColor ?? UIColor.label @@ -45,6 +54,9 @@ final class ListRenderer: NodeRenderer { context.listDepth = prevDepth context.listType = prevType context.listItemNumber = prevNumber + context.listMarkerWidth = prevMarkerWidth + context.listMarkerExtra = prevMarkerExtra + context.listMarkerOffset = prevMarkerOffset if prevDepth == 0 { context.clearBlockStyle() @@ -53,4 +65,21 @@ final class ListRenderer: NodeRenderer { } } } + + /// Widens the marker column to the list's widest number, so markers are + /// never drawn past the column's leading edge. Task items draw a checkbox + /// instead of a number and do not count. + private func widestMarkerWidth(of node: MarkdownASTNode, atLeast minimumWidth: CGFloat) -> CGFloat { + let attributes: [NSAttributedString.Key: Any] = [ + .font: config.list.font ?? BlockDecorationConfig.defaultListMarkerFont + ] + var width = minimumWidth + var number = 0 + for item in node.children where item.type == .listItem { + number += 1 + guard item.attribute("isTask") != "true" else { continue } + width = max(width, ("\(number)." as NSString).size(withAttributes: attributes).width) + } + return width + } } diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Views/Layout/BlockDecorationConfig.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Views/Layout/BlockDecorationConfig.swift index 7b587e8c8..34696c8e1 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Views/Layout/BlockDecorationConfig.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Views/Layout/BlockDecorationConfig.swift @@ -18,7 +18,9 @@ struct BlockDecorationConfig { var listBulletSize: CGFloat = 6 var listBulletColor: UIColor = UIColor(red: 0.42, green: 0.45, blue: 0.50, alpha: 1) var listMarkerColor: UIColor = UIColor(red: 0.42, green: 0.45, blue: 0.50, alpha: 1) - var listMarkerFont: UIFont = .systemFont(ofSize: 16, weight: .medium) + static let defaultListMarkerFont: UIFont = .systemFont(ofSize: 16, weight: .medium) + + var listMarkerFont: UIFont = defaultListMarkerFont var taskCheckboxSize: CGFloat = 14 var taskCheckboxBorderRadius: CGFloat = 3 diff --git a/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift b/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift new file mode 100644 index 000000000..5c89aa82e --- /dev/null +++ b/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift @@ -0,0 +1,198 @@ +import UIKit +import XCTest +@testable import EnrichedMarkdown + +final class OrderedListMarkerWidthTests: XCTestCase { + private var config: MarkdownStyleConfiguration! + + override func setUp() { + super.setUp() + config = MarkdownStyleConfiguration.baseline() + } + + func testShortListsKeepTheirMarkerColumn() { + let result = MarkdownRenderer.render(numbered(9), config: config) + + // Default theme: 20pt ordered marker column + 12pt gap. + XCTAssertEqual(headIndent(in: result, at: "i1x"), 32) + XCTAssertEqual(headIndent(in: result, at: "i9x"), 32) + } + + func testListsWidenTheirColumnToTheirWidestNumber() { + for count in [12, 99, 101, 1000] { + let result = MarkdownRenderer.render(numbered(count), config: config) + let widest = (1...count).map { markerWidth("\($0).") }.max() ?? 0 + XCTAssertGreaterThan(widest, 20, "list of \(count)") + + for item in ["i1x", "i\(count)x"] { + XCTAssertEqual(headIndent(in: result, at: item), widest + 12, accuracy: 0.001, "\(item) of \(count)") + } + } + } + + func testMarkerMinWidthRemainsAFloor() { + config.list.markerMinWidth = 200 + let result = MarkdownRenderer.render(numbered(1000), config: config) + + XCTAssertEqual(headIndent(in: result, at: "i1x"), 212) + XCTAssertEqual(headIndent(in: result, at: "i1000x"), 212) + } + + func testFollowingListsRestoreTheirOwnColumn() { + let result = MarkdownRenderer.render(numbered(101) + "\nbreak\n\n" + numbered(3, prefix: "f"), config: config) + + XCTAssertGreaterThan(headIndent(in: result, at: "i101x"), 32) + XCTAssertEqual(headIndent(in: result, at: "f1x"), 32) + } + + func testNestedListsKeepTheirPlaceUnderWideParents() { + for nested in ["- nestedx", "1. nestedx", "- [ ] nestedx"] { + let short = nestedOffset(in: numbered(4, nesting: nested, under: 3), parent: "i3x") + for count in [101, 1000] { + let wide = nestedOffset(in: numbered(count, nesting: nested, under: 3), parent: "i3x") + XCTAssertEqual(wide, short, accuracy: 0.001, "\(nested) under a list of \(count)") + } + } + } + + func testListsInsideAQuoteUnderAWideParentShiftOnce() { + func offset(_ count: Int) -> CGFloat { + let source = numbered(count, nesting: "> quotex\n>\n> - nestedx", under: 3) + let result = MarkdownRenderer.render(source, config: config) + return headIndent(in: result, at: "nestedx") - headIndent(in: result, at: "quotex") + } + + for count in [101, 1000] { + XCTAssertEqual(offset(count), offset(4), accuracy: 0.001, "list of \(count)") + } + } + + func testQuotesUnderSeveralListLevelsShiftOnce() { + func offsets(_ count: Int) -> (text: CGFloat, bar: CGFloat) { + let source = numbered(count, nesting: "- childx\n > quotex", under: 3) + let result = MarkdownRenderer.render(source, config: config) + let quote = (result.string as NSString).range(of: "quotex").location + let bar = result.attribute(MarkdownAttribute.blockquoteBarOffset, at: quote, effectiveRange: nil) + let barOffset = bar as? CGFloat ?? -1 + return (headIndent(in: result, at: "quotex") - headIndent(in: result, at: "childx"), + headIndent(in: result, at: "quotex") - barOffset) + } + + let short = offsets(4) + for count in [101, 1000] { + let wide = offsets(count) + XCTAssertEqual(wide.text, short.text, accuracy: 0.001, "quote under a list of \(count)") + XCTAssertEqual(wide.bar, short.bar, accuracy: 0.001, "quote bar under a list of \(count)") + } + } + + func testQuoteBarsKeepTheWideningOfAnInnerList() { + func offsets(_ count: Int) -> (text: CGFloat, bar: CGFloat) { + let inner = numbered(count, prefix: "n", nesting: "> quotex", under: 3) + let result = MarkdownRenderer.render(numbered(4, nesting: inner, under: 2), config: config) + let quote = (result.string as NSString).range(of: "quotex").location + let bar = result.attribute(MarkdownAttribute.blockquoteBarOffset, at: quote, effectiveRange: nil) + let barOffset = bar as? CGFloat ?? -1 + return (headIndent(in: result, at: "quotex") - headIndent(in: result, at: "n3x"), + headIndent(in: result, at: "quotex") - barOffset) + } + + let short = offsets(4) + for count in [101, 1000] { + let wide = offsets(count) + XCTAssertEqual(wide.text, short.text, accuracy: 0.001, "quote in a nested list of \(count)") + XCTAssertEqual(wide.bar, short.bar, accuracy: 0.001, "quote bar in a nested list of \(count)") + } + } + + func testWideListsInsideAQuoteKeepTheQuoteBarInPlace() { + func barOffset(_ result: NSAttributedString, at text: String) -> CGFloat { + let location = (result.string as NSString).range(of: text).location + return result.attribute(MarkdownAttribute.blockquoteBarOffset, at: location, effectiveRange: nil) as? CGFloat ?? -1 + } + + for count in [4, 101, 1000] { + let inner = numbered(count, prefix: "n", nesting: "> innerx", under: 3) + let quote = "> beforex\n>\n" + inner.split(separator: "\n").map { "> " + $0 }.joined(separator: "\n") + + "\n>\n> afterx" + let result = MarkdownRenderer.render(numbered(4, nesting: quote, under: 1), config: config) + XCTAssertEqual(barOffset(result, at: "innerx"), barOffset(result, at: "beforex"), "list of \(count)") + XCTAssertEqual(barOffset(result, at: "afterx"), barOffset(result, at: "beforex"), "list of \(count)") + } + } + + func testTaskChildrenMoveOnlyAsFarAsTheirCheckboxColumn() { + for checkboxSize: CGFloat in [22, 100] { + config.taskList.checkboxSize = checkboxSize + func offset(_ count: Int) -> CGFloat { + var lines = (1...count).map { "\($0). i\($0)x" } + lines[1] = "2. [ ] taskx\n - childx" + let result = MarkdownRenderer.render(lines.joined(separator: "\n"), config: config) + return headIndent(in: result, at: "childx") - headIndent(in: result, at: "taskx") + } + + for count in [101, 1000] { + XCTAssertEqual(offset(count), offset(4), accuracy: 0.001, "checkbox \(checkboxSize), list of \(count)") + } + } + } + + func testNestedWideListsWidenOnlyThemselves() { + let source = numbered(3, nesting: numbered(101, prefix: "n"), under: 2) + let result = MarkdownRenderer.render(source, config: config) + let nestedWidest = (1...101).map { markerWidth("\($0).") }.max() ?? 0 + + XCTAssertEqual(headIndent(in: result, at: "i1x"), 32) + XCTAssertEqual(headIndent(in: result, at: "n101x"), 32 + 24 - 20 + nestedWidest, accuracy: 0.001) + } + + func testTaskItemsAlignWithWideNumberedSiblings() { + let source = (1...101).map { $0 == 2 ? "2. [ ] taskx" : "\($0). i\($0)x" }.joined(separator: "\n") + let result = MarkdownRenderer.render(source, config: config) + + XCTAssertEqual(headIndent(in: result, at: "taskx"), headIndent(in: result, at: "i1x")) + } + + func testTaskItemChildrenFollowTheirWideNumberedSiblings() { + var lines = (1...101).map { "\($0). i\($0)x" } + lines[1] = "2. [ ] taskx\n - undertaskx" + lines[2] = "3. i3x\n - undernumberx" + let result = MarkdownRenderer.render(lines.joined(separator: "\n"), config: config) + + XCTAssertEqual( + headIndent(in: result, at: "undertaskx") - headIndent(in: result, at: "taskx"), + headIndent(in: result, at: "undernumberx") - headIndent(in: result, at: "i3x"), + accuracy: 0.001 + ) + } + + private func nestedOffset(in source: String, parent: String) -> CGFloat { + let result = MarkdownRenderer.render(source, config: config) + return headIndent(in: result, at: "nestedx") - headIndent(in: result, at: parent) + } + + /// An ordered list of `count` items `x`, with `nesting` under item `under`. + private func numbered(_ count: Int, prefix: String = "i", nesting: String? = nil, under: Int = 0) -> String { + (1...count).map { number in + var item = "\(number). \(prefix)\(number)x" + if let nesting, number == under { + let indent = String(repeating: " ", count: "\(number). ".count) + item += "\n" + nesting.split(separator: "\n").map { indent + $0 }.joined(separator: "\n") + } + return item + }.joined(separator: "\n") + "\n" + } + + private func markerWidth(_ marker: String) -> CGFloat { + let font = config.list.font ?? BlockDecorationConfig.defaultListMarkerFont + return (marker as NSString).size(withAttributes: [.font: font]).width + } + + private func headIndent(in result: NSAttributedString, at substring: String) -> CGFloat { + let range = (result.string as NSString).range(of: substring) + XCTAssertNotEqual(range.location, NSNotFound, substring) + guard range.location != NSNotFound else { return -1 } + let style = result.attribute(.paragraphStyle, at: range.location, effectiveRange: nil) as? NSParagraphStyle + return style?.headIndent ?? -1 + } +} diff --git a/packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm b/packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm new file mode 100644 index 000000000..03e42822c --- /dev/null +++ b/packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm @@ -0,0 +1,178 @@ +#import "../../ios/parser/ENRMMarkdownParser.h" +#import "../../ios/parser/MarkdownASTNode.h" +#import "../../ios/renderer/AttributedRenderer.h" +#import "../../ios/renderer/ListItemRenderer.h" +#import "../../ios/renderer/RenderContext.h" +#import "../../ios/styles/StyleConfig.h" +#import + +static MarkdownASTNode *ENRMWidthList(NSInteger start, NSUInteger count) +{ + MarkdownASTNode *list = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeOrderedList]; + list.attributes[@"start"] = [@(start) stringValue]; + for (NSUInteger i = 0; i < count; i++) { + MarkdownASTNode *item = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeListItem]; + MarkdownASTNode *paragraph = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeParagraph]; + MarkdownASTNode *text = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeText]; + text.content = @"item"; + [paragraph addChild:text]; + [item addChild:paragraph]; + [list addChild:item]; + } + return list; +} + +@interface ENRMOrderedListMarkerWidthTests : XCTestCase +@end + +@implementation ENRMOrderedListMarkerWidthTests + +- (NSArray *)markersForLists:(NSArray *)lists + config:(StyleConfig *)config +{ + AttributedRenderer *renderer = [[AttributedRenderer alloc] initWithConfig:config]; + NSAttributedString *text = [renderer renderNodes:lists context:[[RenderContext alloc] init] block:nil]; + NSMutableArray *markers = [NSMutableArray array]; + [text enumerateAttribute:ListItemMarkerStartAttribute + inRange:NSMakeRange(0, text.length) + options:0 + usingBlock:^(NSArray *value, NSRange range, BOOL *stop) { + if (value) + [markers addObjectsFromArray:value]; + }]; + return markers; +} + +- (void)testShortListKeepsItsIndentAndLongListsShareTheWidestGutter +{ + StyleConfig *config = [[StyleConfig alloc] init]; + [config setListStyleFontSize:16]; + [config setListStyleMarginLeft:24]; + [config setListStyleGapWidth:11]; + CGFloat baseline = [@"99." sizeWithAttributes:@{NSFontAttributeName : config.listMarkerFont}].width; + CGFloat shortIndent = MAX(config.listStyleMarkerMinWidth, baseline) + config.effectiveListGapWidth; + NSArray *shortMarkers = [self markersForLists:@[ ENRMWidthList(1, 99) ] config:config]; + for (ENRMListMarkerDescriptor *marker in shortMarkers) { + XCTAssertEqualWithAccuracy(marker.indent, shortIndent, 0.01); + } + for (NSNumber *start in @[ @98, @998, @12345 ]) { + NSArray *markers = [self markersForLists:@[ ENRMWidthList(start.integerValue, 4) ] config:config]; + CGFloat width = baseline; + for (ENRMListMarkerDescriptor *marker in markers) { + NSString *label = [NSString stringWithFormat:@"%ld.", (long)marker.number]; + width = MAX(width, [label sizeWithAttributes:@{NSFontAttributeName : config.listMarkerFont}].width); + } + for (ENRMListMarkerDescriptor *marker in markers) { + XCTAssertEqualWithAccuracy(marker.indent, width + config.effectiveListGapWidth, 0.01); + } + } +} + +- (void)testNestedAndFollowingListsRestoreTheirOwnGutters +{ + StyleConfig *config = [[StyleConfig alloc] init]; + [config setListStyleFontSize:16]; + [config setListStyleMarginLeft:24]; + [config setListStyleGapWidth:11]; + MarkdownASTNode *outer = ENRMWidthList(98, 4); + [outer.children[0] addChild:ENRMWidthList(9998, 4)]; + NSArray *markers = [self markersForLists:@[ outer, ENRMWidthList(1, 1) ] config:config]; + CGFloat outerIndent = 0; + CGFloat nestedIndent = 0; + for (ENRMListMarkerDescriptor *marker in markers) { + if (marker.depth == 1) { + nestedIndent = marker.indent; + } else if (marker.number != 1) { + if (outerIndent == 0) + outerIndent = marker.indent; + XCTAssertEqualWithAccuracy(marker.indent, outerIndent, 0.01); + } + } + XCTAssertGreaterThan(nestedIndent, outerIndent + config.listStyleMarginLeft); + ENRMListMarkerDescriptor *last = markers.lastObject; + XCTAssertLessThan(last.indent, outerIndent); +} + +- (void)testNestedListsKeepTheSpaceReservedForWideParentMarkers +{ + StyleConfig *config = [[StyleConfig alloc] init]; + [config setListStyleFontSize:16]; + [config setListStyleMarginLeft:24]; + [config setListStyleGapWidth:11]; + MarkdownASTNode *outer = ENRMWidthList(123456789, 1); + MarkdownASTNode *middle = ENRMWidthList(1, 1); + [middle.children[0] addChild:ENRMWidthList(1, 1)]; + [outer.children[0] addChild:middle]; + NSArray *markers = [self markersForLists:@[ outer ] config:config]; + ENRMListMarkerDescriptor *parent = markers[0]; + ENRMListMarkerDescriptor *child = markers[1]; + ENRMListMarkerDescriptor *leaf = markers[2]; + XCTAssertEqual(parent.depth, 0); + XCTAssertEqual(child.depth, 1); + XCTAssertEqual(leaf.depth, 2); + XCTAssertEqualWithAccuracy(child.indent, parent.indent + config.listStyleMarginLeft, 0.01); + XCTAssertEqualWithAccuracy(leaf.indent, parent.indent + 2 * config.listStyleMarginLeft, 0.01); +} + +- (void)testTaskItemsDoNotPassTheOrderedListsExtraWidthToTheirChildren +{ + StyleConfig *config = [[StyleConfig alloc] init]; + [config setListStyleFontSize:16]; + [config setListStyleMarginLeft:24]; + [config setListStyleGapWidth:11]; + NSMutableArray *> *results = [NSMutableArray array]; + for (NSNumber *start in @[ @1, @12345 ]) { + MarkdownASTNode *outer = ENRMWidthList(start.integerValue, 3); + MarkdownASTNode *task = outer.children[1]; + task.attributes[@"isTask"] = @"true"; + MarkdownASTNode *child = ENRMWidthList(1, 1); + child.type = MarkdownNodeTypeUnorderedList; + [task addChild:child]; + [outer.children[2] addChild:ENRMWidthList(1, 1)]; + [results addObject:[self markersForLists:@[ outer ] config:config]]; + } + NSArray *shortMarkers = results[0]; + NSArray *wideMarkers = results[1]; + XCTAssertEqual(shortMarkers.count, 5u); + XCTAssertEqual(wideMarkers.count, 5u); + ENRMListMarkerDescriptor *task = wideMarkers[1]; + ENRMListMarkerDescriptor *child = wideMarkers[2]; + XCTAssertTrue(task.isTask); + XCTAssertEqual(child.depth, 1); + XCTAssertEqual(child.listType, ListTypeUnordered); + XCTAssertEqualWithAccuracy(task.indent, [shortMarkers[1] indent], 0.01); + CGFloat bulletIndent = + [config effectiveListMarginLeftForBullet] + config.effectiveListGapWidth + config.listStyleMarginLeft; + XCTAssertEqualWithAccuracy(child.indent, bulletIndent, 0.01); + XCTAssertEqualWithAccuracy(child.indent, [shortMarkers[2] indent], 0.01); + ENRMListMarkerDescriptor *numericChild = wideMarkers[4]; + ENRMListMarkerDescriptor *numericParent = wideMarkers[3]; + XCTAssertEqualWithAccuracy(numericChild.indent, numericParent.indent + config.listStyleMarginLeft, 0.01); +} + +- (void)testSourceNumbersAfterTheStartDoNotOverrideRenderedNumbers +{ + ENRMMarkdownParser *parser = [[ENRMMarkdownParser alloc] init]; + MarkdownASTNode *document = [parser parseMarkdown:@"98. a\n400. b\n1. c\n2. d"]; + StyleConfig *config = [[StyleConfig alloc] init]; + [config setListStyleFontSize:16]; + [config setListStyleMarginLeft:24]; + [config setListStyleGapWidth:11]; + NSArray *markers = [self markersForLists:document.children config:config]; + XCTAssertEqual(markers.count, 4u); + for (NSUInteger i = 0; i < markers.count; i++) { + ENRMListMarkerDescriptor *marker = markers[i]; + XCTAssertEqual(marker.number, 98 + (NSInteger)i); + } +} + +- (void)testMarkerMinimumWidthRemainsAFloor +{ + StyleConfig *config = [[StyleConfig alloc] init]; + [config setListStyleMarkerMinWidth:200]; + NSArray *markers = [self markersForLists:@[ ENRMWidthList(998, 4) ] config:config]; + for (ENRMListMarkerDescriptor *marker in markers) { + XCTAssertEqualWithAccuracy(marker.indent, 200 + config.effectiveListGapWidth, 0.01); + } +} +@end diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt index 0286a8558..c54919d41 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt @@ -41,6 +41,9 @@ class BlockStyleContext { var listDepth = 0 var listType: ListType? = null var listItemNumber = 0 + var listMarkerWidth = 0f + var ancestorMarkerOffset = 0f + var listItemMarkerExtra = 0f var taskItemCount = 0 var accumulatedIndent = 0 @@ -151,6 +154,9 @@ class BlockStyleContext { listDepth = 0 listType = null listItemNumber = 0 + listMarkerWidth = 0f + ancestorMarkerOffset = 0f + listItemMarkerExtra = 0f taskItemCount = 0 accumulatedIndent = 0 listItemStarts.clear() diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt index b849f7863..c0f6a1802 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt @@ -50,15 +50,31 @@ class ListItemRenderer( taskIndex = taskIndex, isChecked = isChecked, drawsMarker = drawsMarker, + ancestorMarkerOffset = styleContext.ancestorMarkerOffset, ) } else { when (listType) { BlockStyleContext.ListType.UNORDERED -> { - UnorderedListSpan(listStyle, depth, factory.context, factory.styleCache, drawsMarker) + UnorderedListSpan( + listStyle, + depth, + factory.context, + factory.styleCache, + drawsMarker, + styleContext.ancestorMarkerOffset, + ) } BlockStyleContext.ListType.ORDERED -> { - OrderedListSpan(listStyle, depth, factory.context, factory.styleCache, drawsMarker).apply { + OrderedListSpan( + listStyle, + depth, + factory.context, + factory.styleCache, + drawsMarker, + styleContext.listMarkerWidth, + styleContext.ancestorMarkerOffset, + ).apply { setItemNumber(styleContext.listItemNumber) } } @@ -67,12 +83,15 @@ class ListItemRenderer( val markerSpan = makeSpan(drawsMarker = true) + val previousMarkerExtra = styleContext.listItemMarkerExtra + styleContext.listItemMarkerExtra = (markerSpan as? OrderedListSpan)?.markerExtraWidth ?: 0f val prevIndent = styleContext.accumulatedIndent styleContext.accumulatedIndent = prevIndent + markerSpan.getLeadingMargin(false) try { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) } finally { styleContext.accumulatedIndent = prevIndent + styleContext.listItemMarkerExtra = previousMarkerExtra } if (builder.length == start || builder.substring(start).isBlank()) return diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt index 2bac5b11d..430011a7c 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt @@ -4,6 +4,7 @@ import android.text.SpannableStringBuilder import com.swmansion.enriched.markdown.parser.MarkdownASTNode import com.swmansion.enriched.markdown.spans.ListItemSpacingSpan import com.swmansion.enriched.markdown.spans.MarginBottomSpan +import com.swmansion.enriched.markdown.spans.OrderedListSpan import com.swmansion.enriched.markdown.styles.ListStyle import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE import com.swmansion.enriched.markdown.utils.text.span.applyLineHeightSkippingImages @@ -33,6 +34,27 @@ class ListRenderer( val contextManager = ListContextManager(factory.blockStyleContext) val entryState = contextManager.enterList(listType, listStyle, startNumber) + val previousMarkerWidth = factory.blockStyleContext.listMarkerWidth + val previousMarkerOffset = factory.blockStyleContext.ancestorMarkerOffset + if (entryState.previousDepth > 0) { + factory.blockStyleContext.ancestorMarkerOffset += factory.blockStyleContext.listItemMarkerExtra + } + factory.blockStyleContext.listMarkerWidth = + if (isOrdered) { + val marker = OrderedListSpan(listStyle, 0, factory.context, factory.styleCache) + var number = startNumber + var width = marker.measureMarkerWidth(99) + for (item in node.children) { + if (item.type != MarkdownASTNode.NodeType.ListItem) continue + if (number >= 100 && item.attributes["isTask"] != "true") { + width = maxOf(width, marker.measureMarkerWidth(number)) + } + number++ + } + width + } else { + 0f + } // For top-level lists, insert marginTop spacer before rendering content if (entryState.previousDepth == 0) { @@ -50,6 +72,8 @@ class ListRenderer( try { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) } finally { + factory.blockStyleContext.listMarkerWidth = previousMarkerWidth + factory.blockStyleContext.ancestorMarkerOffset = previousMarkerOffset contextManager.exitList(entryState) } diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt index 2ab00430c..9048a7e12 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt @@ -23,6 +23,7 @@ abstract class BaseListSpan( protected val marginLeft: Float, protected val gapWidth: Float, internal val drawsMarker: Boolean = true, + internal val ancestorMarkerOffset: Float = 0f, ) : MetricAffectingSpan(), LeadingMarginSpan { private var cachedText: CharSequence? = null diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt index 566f52800..f1bfbe9d2 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt @@ -19,6 +19,8 @@ class OrderedListSpan( context: Context, styleCache: SpanStyleCache, drawsMarker: Boolean = true, + private val markerWidth: Float = 0f, + ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -33,6 +35,7 @@ class OrderedListSpan( marginLeft = listStyle.marginLeft, gapWidth = listStyle.gapWidth, drawsMarker = drawsMarker, + ancestorMarkerOffset = ancestorMarkerOffset, ) { companion object { private val sharedMarkerPaint = TextPaint().apply { isAntiAlias = true } @@ -52,10 +55,21 @@ class OrderedListSpan( typeface = markerTypeface } - override fun getMarkerWidth(): Float { - val paint = configureMarkerPaint() - return listStyle.effectiveMarkerWidth(paint.measureText("99.")) - } + private val defaultMarkerWidth = measureMarkerWidth(99) + private val resolvedMarkerWidth = maxOf(markerWidth, defaultMarkerWidth) + + internal val markerExtraWidth = resolvedMarkerWidth - defaultMarkerWidth + + override fun getMarkerWidth(): Float = resolvedMarkerWidth + + internal fun measureMarkerWidth(number: Int): Float = listStyle.effectiveMarkerWidth(configureMarkerPaint().measureText("$number.")) + + override fun getLeadingMargin(first: Boolean): Int = + if (depth > 0) { + (listStyle.marginLeft + markerExtraWidth).toInt() + } else { + super.getLeadingMargin(first) + } var itemNumber: Int = 1 private set @@ -75,7 +89,7 @@ class OrderedListSpan( val text = if (dir < 0) ".$itemNumber" else "$itemNumber." val textWidth = markerPaint.measureText(text) - val markerRightEdge = x + (depth * marginLeft + getMarkerWidth()) * dir + val markerRightEdge = x + (depth * marginLeft + ancestorMarkerOffset + getMarkerWidth()) * dir val markerX = if (dir > 0) markerRightEdge - textWidth else markerRightEdge canvas.drawText(text, markerX, baseline.toFloat(), markerPaint) diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt index 3b5a5c60b..07629e0ba 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt @@ -20,6 +20,7 @@ class TaskListSpan( val taskIndex: Int, val isChecked: Boolean, drawsMarker: Boolean = true, + ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -34,6 +35,7 @@ class TaskListSpan( marginLeft = listStyle.marginLeft, gapWidth = listStyle.gapWidth, drawsMarker = drawsMarker, + ancestorMarkerOffset = ancestorMarkerOffset, ) { private val checkboxSize = taskStyle.checkboxSize private val markerColumnWidth = listStyle.effectiveMarkerWidth(checkboxSize) @@ -76,7 +78,7 @@ class TaskListSpan( // Right-align the checkbox inside the reserved marker column so it hugs // the gap before the text. At the default (markerColumnWidth == // checkboxSize) this is identical to the previous flush-left layout. - val centerX = x + (depth * marginLeft + markerColumnWidth - checkboxSize / HALF_DIVISOR) * dir + val centerX = x + (depth * marginLeft + ancestorMarkerOffset + markerColumnWidth - checkboxSize / HALF_DIVISOR) * dir val half = checkboxSize / HALF_DIVISOR rect.set(centerX - half, centerY - half, centerX + half, centerY + half) diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt index cc3e70401..2f50f46a0 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt @@ -14,6 +14,7 @@ class UnorderedListSpan( context: Context, styleCache: SpanStyleCache, drawsMarker: Boolean = true, + ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -28,6 +29,7 @@ class UnorderedListSpan( marginLeft = listStyle.marginLeft, gapWidth = listStyle.gapWidth, drawsMarker = drawsMarker, + ancestorMarkerOffset = ancestorMarkerOffset, ) { companion object { private val sharedBulletPaint = @@ -65,7 +67,7 @@ class UnorderedListSpan( // it hugs the gap before the text — matches iOS behavior and stays // visually flush-left when the column width equals the bullet radius // (the default). - val bulletX = x + (depth * marginLeft + markerColumnWidth) * dir + val bulletX = x + (depth * marginLeft + ancestorMarkerOffset + markerColumnWidth) * dir val bulletY = baseline + (markerFontMetrics.ascent + markerFontMetrics.descent) / 2f when (depth) { diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt index 1bb4b5313..ff5b0db95 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt @@ -131,16 +131,29 @@ object TaskListTapUtils { taskIndex = targetIndex, isChecked = newChecked, drawsMarker = old.drawsMarker, + ancestorMarkerOffset = old.ancestorMarkerOffset, ) - // Replace every segment of the item — spans are split around code blocks - for (old in targetSpans) { - val start = spannable.getSpanStart(old) - val end = spannable.getSpanEnd(old) - // Keep the original flags so the list item priority survives the toggle - val flags = spannable.getSpanFlags(old) - spannable.removeSpan(old) - spannable.setSpan(toggledCopy(old), start, end, flags) + // Layout draws leading margins in insertion order, and a re-added span moves to the end of it. + // Re-add the task's spans and everything attached after them (its ancestors) in their original + // order; the task's own nested items were attached first and stay where they are. + data class ListSpanState( + val span: BaseListSpan, + val start: Int, + val end: Int, + val flags: Int, + ) + + val coveringSpans = spannable.getSpans(spanStart, spanEnd, BaseListSpan::class.java) + val firstTarget = coveringSpans.indexOfFirst { it is TaskListSpan && it.taskIndex == targetIndex } + val listSpans = + coveringSpans.drop(firstTarget).map { + ListSpanState(it, spannable.getSpanStart(it), spannable.getSpanEnd(it), spannable.getSpanFlags(it)) + } + listSpans.forEach { spannable.removeSpan(it.span) } + for ((old, start, end, flags) in listSpans) { + val replacement = if (old is TaskListSpan && old.taskIndex == targetIndex) toggledCopy(old) else old + spannable.setSpan(replacement, start, end, flags) } // The marker may be drawn by an anchor span wrapping an unattached copy diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt new file mode 100644 index 000000000..4e3f62ef6 --- /dev/null +++ b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt @@ -0,0 +1,530 @@ +package com.swmansion.enriched.markdown.spans + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Typeface +import android.text.SpannableString +import android.text.Spanned +import android.text.StaticLayout +import android.text.TextPaint +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.facebook.react.bridge.JavaOnlyArray +import com.facebook.react.bridge.JavaOnlyMap +import com.facebook.react.uimanager.DisplayMetricsHolder +import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView +import com.swmansion.enriched.markdown.parser.MarkdownASTNode +import com.swmansion.enriched.markdown.parser.MarkdownASTNode.NodeType +import com.swmansion.enriched.markdown.renderer.Renderer +import com.swmansion.enriched.markdown.styles.StyleConfig +import com.swmansion.enriched.markdown.utils.text.interaction.TaskListTapUtils +import com.swmansion.enriched.markdown.utils.text.view.setupAsMarkdownTextView +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [30]) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class OrderedListMarkerWidthTest { + private val context = RuntimeEnvironment.getApplication() + + @Test + fun shortListsKeepTheirIndentAndLongListsShareTheirWidestGutter() { + val config = styleConfig() + val paint = + TextPaint().apply { + textSize = config.listStyle.fontSize + typeface = Typeface.create("monospace", Typeface.NORMAL) + } + val baseline = paint.measureText("99.") + val short = render(config, list(1, 99)) + short.forEach { assertEquals((baseline + config.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) } + for ((start, count) in listOf(1 to 250, 98 to 4, 998 to 4, 12345 to 4, 0 to 101)) { + val spans = render(config, list(start, count)) + val widest = maxOf(baseline, spans.maxOf { paint.measureText("${it.itemNumber}.") }) + spans.forEach { assertEquals((widest + config.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) } + assertTrue(spans.first().getLeadingMargin(false) > short.first().getLeadingMargin(false)) + } + } + + @Test + fun nestedAndFollowingListsRestoreTheirOwnGutters() { + val config = styleConfig() + val outer = list(98, 4) + val first = outer.children.first() + val nested = outer.copy(children = listOf(first.copy(children = first.children + list(9998, 4))) + outer.children.drop(1)) + val spans = render(config, nested, list(1, 1)) + val parent = spans.filter { it.depth == 0 && it.itemNumber != 1 } + assertEquals(4, parent.size) + parent.forEach { assertEquals(parent.first().getLeadingMargin(false), it.getLeadingMargin(false)) } + spans.filter { it.depth == 1 }.forEach { assertTrue(it.getLeadingMargin(false) > config.listStyle.marginLeft) } + val following = spans.single { it.depth == 0 && it.itemNumber == 1 } + assertTrue(following.getLeadingMargin(false) < parent.first().getLeadingMargin(false)) + } + + @Test + fun markerMinimumWidthRemainsAFloor() { + val config = styleConfig(200.0) + render(config, list(998, 4)).forEach { + assertEquals((config.listStyle.markerMinWidth + config.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) + } + } + + @Test + fun drawnMarkersStayInsideTheGutterAndAttachedToTheirParagraphs() { + for (start in listOf(1, 98, 9998)) { + val config = styleConfig() + val outer = list(start, 4) + val parent = outer.children[2] + val middle = list(1, 1) + val child = middle.children[0] + val threeLevels = middle.copy(children = listOf(child.copy(children = child.children + list(1, 1)))) + val nested = + outer.copy( + children = + outer.children.take(2) + parent.copy(children = parent.children + threeLevels) + outer.children.drop(3), + ) + assertDrawnMarkerPositions(config, nested) + } + } + + @Test + fun nestedBulletColumnsKeepTheirGapUnderWideParents() { + val config = styleConfig() + + fun tree(start: Int): MarkdownASTNode { + val outer = list(start, 4) + val parent = outer.children[2] + val bullets = list(1, 2).copy(type = NodeType.UnorderedList) + return outer.copy( + children = outer.children.take(2) + parent.copy(children = parent.children + bullets) + outer.children.drop(3), + ) + } + for (start in listOf(98, 9998)) { + assertNestedMarkerGapsUnchanged(config, tree(1), tree(start)) + } + } + + @Test + fun tasksDoNotPassTheWideListsNumericExtraToTheirChildren() { + val config = styleConfig() + + fun tree(start: Int): MarkdownASTNode { + val outer = list(start, 3) + val task = outer.children[1] + val taskWithChild = task.copy(attributes = mapOf("isTask" to "true"), children = task.children + list(1, 1)) + val numeric = outer.children[2] + val numericWithChild = numeric.copy(children = numeric.children + list(1, 1)) + return outer.copy(children = listOf(outer.children[0], taskWithChild, numericWithChild)) + } + assertNestedMarkerGapsUnchanged(config, tree(1), tree(12345)) + } + + @Test + fun nestedTasksKeepTheirGapUnderWideNumericParents() { + val config = styleConfig() + + fun tree(start: Int): MarkdownASTNode { + val outer = list(start, 4) + val parent = outer.children[2] + val nested = list(1, 1) + val task = nested.children[0].copy(attributes = mapOf("isTask" to "true")) + val taskList = nested.copy(children = listOf(task)) + return outer.copy( + children = outer.children.take(2) + parent.copy(children = parent.children + taskList) + outer.children.drop(3), + ) + } + for (start in listOf(98, 9998)) { + assertNestedMarkerGapsUnchanged(config, tree(1), tree(start)) + } + } + + @Test + fun togglingATaskUnderAWideParentKeepsEveryMarginAndMarkerPosition() { + assertTaskToggleKeepsGeometry(opensWithSublist = false) + } + + @Test + fun togglingAnAnchoredTaskUnderAWideParentKeepsEveryMarginAndMarkerPosition() { + assertTaskToggleKeepsGeometry(opensWithSublist = true) + } + + @Test + fun sameTypeBulletAndTaskNestsKeepTheirMarkerGap() { + val config = styleConfig() + val ordered = list(1, 1) + val bullet = ordered.copy(type = NodeType.UnorderedList) + val task = ordered.copy(children = listOf(ordered.children[0].copy(attributes = mapOf("isTask" to "true")))) + for (parent in listOf(bullet, task)) { + val item = parent.children[0] + assertDrawnMarkerPositions(config, parent.copy(children = listOf(item.copy(children = item.children + parent)))) + } + } + + @Test + fun shortMixedNestsKeepTheirOriginalTextIndents() { + val config = styleConfig(fontFamily = "", gapWidth = 6.0, checkboxSize = 14.0) + val ordered = list(1, 1) + val bullet = ordered.copy(type = NodeType.UnorderedList) + val task = ordered.copy(children = listOf(ordered.children[0].copy(attributes = mapOf("isTask" to "true")))) + val shapes = listOf(ordered to bullet, bullet to ordered, bullet to task, ordered to task, task to bullet) + val baseIndents = listOf(52f, 33f, 33f, 52f, 44f) + for ((index, shape) in shapes.withIndex()) { + val (parent, child) = shape + val tree = parent.copy(children = listOf(parent.children[0].copy(children = parent.children[0].children + child))) + val nested = drawMarkers(config, tree).single { it.depth == 1 } + assertEquals("base mixed indent for shape $index", baseIndents[index], nested.paragraphLeft, 0.01f) + assertTrue(nested.marker.left >= 0f) + } + } + + @Test + fun markersAnchoredOnANestedListKeepTheirAncestorsOffset() { + val config = styleConfig() + val outer = list(12345, 1) + val middle = list(1, 1) + val openingSublist = middle.children[0].copy(children = listOf(list(1, 1))) + val renderer = Renderer() + renderer.configure(config, context) + val nested = + outer.copy( + children = + listOf( + outer.children[0].copy( + children = + outer.children[0].children + middle.copy(children = listOf(openingSublist)), + ), + ), + ) + val text = SpannableString(renderer.renderContent(listOf(nested))) + assertEquals(1, text.getSpans(0, text.length, ListMarkerAnchorSpan::class.java).size) + val layout = StaticLayout.Builder.obtain(text, 0, text.length, TextPaint(), 2000).build() + val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) + layout.draw(canvas) + assertEquals(3, canvas.markers.size) + val markersByColumn = canvas.markers.sortedBy { it.right } + val root = markersByColumn[0] + val anchored = markersByColumn[1] + val leaf = markersByColumn[2] + assertEquals(root.right + config.listStyle.marginLeft, anchored.right, 0.01f) + assertEquals(anchored.right + config.listStyle.marginLeft, leaf.right, 0.01f) + assertTrue(canvas.markers.all { it.left >= 0f }) + } + + @Test + fun inheritedMarkerOffsetsFollowTheRtlDirection() { + val config = styleConfig() + val outer = list(12345, 1) + val renderer = Renderer() + renderer.configure(config, context) + val nested = outer.copy(children = listOf(outer.children[0].copy(children = outer.children[0].children + list(1, 1)))) + val text = SpannableString(renderer.renderContent(listOf(nested))) + val layout = + StaticLayout.Builder + .obtain(text, 0, text.length, TextPaint(), 2000) + .setTextDirection(android.text.TextDirectionHeuristics.RTL) + .build() + val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) + layout.draw(canvas) + assertEquals(2, canvas.markers.size) + canvas.markers.forEach { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + assertEquals(-1, layout.getParagraphDirection(line)) + assertEquals(layout.getParagraphRight(line) + config.listStyle.gapWidth, marker.left, 0.01f) + assertTrue(marker.right <= layout.width) + } + } + + private fun assertTaskToggleKeepsGeometry(opensWithSublist: Boolean) { + val config = styleConfig() + val outer = list(100, 2) + val nested = list(1, 1).copy(type = NodeType.UnorderedList) + val taskItem = nested.children.single() + val taskChildren = if (opensWithSublist) listOf(list(1, 1)) else taskItem.children + list(1, 1) + val task = taskItem.copy(attributes = mapOf("isTask" to "true"), children = taskChildren) + val parent = outer.children.first() + val tree = + outer.copy( + children = + listOf(parent.copy(children = parent.children + nested.copy(children = listOf(task)))) + outer.children.drop(1), + ) + val renderer = Renderer() + renderer.configure(config, context) + val textView = + object : AccessibleMarkdownTextView(context) {}.apply { + layoutParams = ViewGroup.LayoutParams(2000, ViewGroup.LayoutParams.WRAP_CONTENT) + setupAsMarkdownTextView() + } + textView.setText(renderer.renderContent(listOf(tree)), TextView.BufferType.SPANNABLE) + val initialText = textView.text as Spanned + val taskIndex = initialText.getSpans(0, initialText.length, TaskListSpan::class.java).single().taskIndex + assertEquals(if (opensWithSublist) 1 else 0, initialText.getSpans(0, initialText.length, ListMarkerAnchorSpan::class.java).size) + val initialMargins = listMargins(initialText) + val initialMarkers = drawTextViewMarkers(textView) + assertEquals(4, initialMarkers.size) + + for (checked in listOf(true, false)) { + assertTrue(TaskListTapUtils.updateTaskListItemCheckedState(textView, taskIndex, checked, config)) + val text = textView.text as Spanned + val tasks = text.getSpans(0, text.length, TaskListSpan::class.java) + assertTrue(tasks.isNotEmpty()) + tasks.forEach { assertEquals(checked, it.isChecked) } + text.getSpans(0, text.length, ListMarkerAnchorSpan::class.java).forEach { + assertEquals(checked, (it.marker as TaskListSpan).isChecked) + } + assertEquals("list margins after checked=$checked", initialMargins, listMargins(text)) + assertEquals("drawn markers after checked=$checked", initialMarkers, drawTextViewMarkers(textView)) + } + } + + private fun listMargins(text: Spanned): List> = + text + .getSpans(0, text.length, BaseListSpan::class.java) + .sortedWith(compareBy({ text.getSpanStart(it) }, { it.depth }, { text.getSpanEnd(it) })) + .map { listOf(text.getSpanStart(it), text.getSpanEnd(it), it.depth, it.getLeadingMargin(true), it.getLeadingMargin(false)) } + + private fun drawTextViewMarkers(textView: TextView): List { + textView.forceLayout() + textView.measure( + View.MeasureSpec.makeMeasureSpec(2000, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + ) + textView.layout(0, 0, textView.measuredWidth, textView.measuredHeight) + val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) + textView.layout.draw(canvas) + return canvas.markers.sortedWith(compareBy({ it.baseline }, { it.left })) + } + + private fun assertDrawnMarkerPositions( + config: StyleConfig, + vararg lists: MarkdownASTNode, + ) { + drawMarkers(config, *lists).forEach { geometry -> + assertEquals( + "marker right at depth ${geometry.depth}", + geometry.paragraphLeft - config.listStyle.gapWidth, + geometry.marker.right, + 0.01f, + ) + } + } + + private fun assertNestedMarkerGapsUnchanged( + config: StyleConfig, + short: MarkdownASTNode, + wide: MarkdownASTNode, + ) { + val shortMarkers = drawMarkers(config, short).filter { it.depth > 0 } + val wideMarkers = drawMarkers(config, wide).filter { it.depth > 0 } + assertTrue(shortMarkers.isNotEmpty()) + assertEquals(shortMarkers.size, wideMarkers.size) + shortMarkers.zip(wideMarkers).forEach { (control, actual) -> + assertEquals(control.depth, actual.depth) + assertEquals( + "nested marker gap at depth ${actual.depth}", + control.paragraphLeft - control.marker.right, + actual.paragraphLeft - actual.marker.right, + 0.01f, + ) + } + } + + private fun drawMarkers( + config: StyleConfig, + vararg lists: MarkdownASTNode, + ): List { + val renderer = Renderer() + renderer.configure(config, context) + // The view exposes spans in insertion order, as SpannableString does. + val text = SpannableString(renderer.renderContent(lists.toList())) + val paint = TextPaint().apply { textSize = config.listStyle.fontSize } + val layout = StaticLayout.Builder.obtain(text, 0, text.length, paint, 2000).build() + val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) + layout.draw(canvas) + assertEquals(text.getSpans(0, text.length, BaseListSpan::class.java).count { it.drawsMarker }, canvas.markers.size) + return canvas.markers.map { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + assertTrue("marker left ${marker.left} on line $line", marker.left >= 0f) + val start = layout.getLineStart(line) + val depth = text.getSpans(start, start + 1, BaseListSpan::class.java).maxOf { it.depth } + MarkerGeometry(marker, layout.getParagraphLeft(line).toFloat(), depth) + } + } + + private data class MarkerGeometry( + val marker: DrawnMarker, + val paragraphLeft: Float, + val depth: Int, + ) + + private data class DrawnMarker( + val left: Float, + val right: Float, + val baseline: Float, + ) + + private class MarkerCanvas( + bitmap: Bitmap, + ) : Canvas(bitmap) { + val markers = mutableListOf() + + override fun drawCircle( + cx: Float, + cy: Float, + radius: Float, + paint: Paint, + ) { + // Bullets are centered on the reserved column edge, matching the iOS drawer. + val outerRadius = radius + paint.strokeWidth / 2f + markers += DrawnMarker(cx - outerRadius, cx, cy) + super.drawCircle(cx, cy, radius, paint) + } + + override fun drawRoundRect( + rect: android.graphics.RectF, + rx: Float, + ry: Float, + paint: Paint, + ) { + val halfStroke = if (paint.style == Paint.Style.STROKE) paint.strokeWidth / 2f else 0f + markers += DrawnMarker(rect.left - halfStroke, rect.right + halfStroke, rect.centerY()) + super.drawRoundRect(rect, rx, ry, paint) + } + + override fun drawText( + text: String, + x: Float, + y: Float, + paint: Paint, + ) { + if (text.matches(Regex("(?:[0-9]+\\.|\\.[0-9]+)"))) markers += DrawnMarker(x, x + paint.measureText(text), y) + super.drawText(text, x, y, paint) + } + } + + private fun render( + config: StyleConfig, + vararg lists: MarkdownASTNode, + ): List { + val renderer = Renderer() + renderer.configure(config, context) + val text = renderer.renderContent(lists.toList()) + return text.getSpans(0, text.length, OrderedListSpan::class.java).toList() + } + + private fun list( + start: Int, + count: Int, + ) = MarkdownASTNode( + NodeType.OrderedList, + attributes = mapOf("start" to start.toString()), + children = + List(count) { + MarkdownASTNode( + NodeType.ListItem, + children = listOf(MarkdownASTNode(NodeType.Paragraph, children = listOf(MarkdownASTNode(NodeType.Text, "item")))), + ) + }, + ) + + private fun styleConfig( + minWidth: Double = 0.0, + fontFamily: String = "monospace", + gapWidth: Double = 8.0, + checkboxSize: Double = 16.0, + ): StyleConfig { + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) + + fun element() = + JavaOnlyMap.of( + "fontFamily", + "", + "fontWeight", + "normal", + "fontSize", + 16.0, + "lineHeight", + 0.0, + "marginTop", + 0.0, + "marginBottom", + 0.0, + "color", + Color.BLACK, + "backgroundColor", + Color.TRANSPARENT, + "borderColor", + Color.TRANSPARENT, + "underline", + false, + "fontScale", + 0.8, + "baselineOffsetScale", + 0.5, + ) + + val style = JavaOnlyMap() + listOf("paragraph", "strong", "em", "strikethrough", "code", "superscript", "subscript", "highlight") + .forEach { style.putMap(it, element()) } + style.putMap("link", element().apply { putString("fontFamily", "serif") }) + style.putArray( + "linkVariants", + JavaOnlyArray.of( + element().apply { + putString("pattern", "^ref:") + putString("fontFamily", "monospace") + putInt("color", Color.BLUE) + }, + ), + ) + style.putMap( + "spoiler", + element().apply { + putMap("particles", JavaOnlyMap.of("density", 0.5, "speed", 1.0)) + putMap("solid", JavaOnlyMap.of("borderRadius", 0.0)) + }, + ) + style.putMap( + "taskList", + JavaOnlyMap.of( + "checkedColor", + Color.BLACK, + "borderColor", + Color.BLACK, + "checkmarkColor", + Color.BLACK, + "checkedTextColor", + Color.BLACK, + "checkboxSize", + checkboxSize, + "checkboxBorderRadius", + 0.0, + "checkedStrikethrough", + false, + ), + ) + style.putMap( + "list", + element().apply { + putString("fontFamily", fontFamily) + putInt("bulletColor", Color.BLACK) + putInt("markerColor", Color.BLACK) + putDouble("bulletSize", 6.0) + putDouble("markerMinWidth", minWidth) + putDouble("gapWidth", gapWidth) + putDouble("marginLeft", 24.0) + putDouble("itemSpacing", 0.0) + }, + ) + return StyleConfig(style, context, false, 0f) + } +} diff --git a/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m b/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m index ed80dfad7..c26b10764 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m +++ b/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m @@ -84,24 +84,27 @@ - (void)renderNodeContent:(MarkdownASTNode *)node // currentDepth - 1 handles the horizontal offset for nested lists const NSInteger nestingLevel = currentDepth - 1; const CGFloat baseMarkerWidth = isTask ? [_config effectiveListMarginLeftForTask] - : (context.listType == ListTypeOrdered) ? [_config effectiveListMarginLeftForNumber] + : (context.listType == ListTypeOrdered) ? context.listMarkerWidth : [_config effectiveListMarginLeftForBullet]; const CGFloat blockquoteIndent = blockquoteIndentForDepth(context.blockquoteDepth, [_config blockquoteBorderWidth] + [_config blockquoteGapWidth]); const CGFloat totalIndent = blockquoteIndent + baseMarkerWidth + [_config effectiveListGapWidth] + - (nestingLevel * [_config listStyleMarginLeft]); + (nestingLevel * [_config listStyleMarginLeft]) + context.listMarkerOffset; const NSUInteger startLocation = output.length; // Manual save/restore — a scope snapshot would also roll back the listItemNumber increment + const CGFloat prevMarkerExtra = context.listItemMarkerExtra; + context.listItemMarkerExtra = !isTask && context.listType == ListTypeOrdered ? context.listMarkerExtra : 0; const CGFloat prevIndent = context.accumulatedIndent; context.accumulatedIndent = totalIndent; @try { [_rendererFactory renderChildrenOfNode:node into:output context:context]; } @finally { context.accumulatedIndent = prevIndent; + context.listItemMarkerExtra = prevMarkerExtra; } // Ensure every list item ends with a newline to prevent paragraph merging diff --git a/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m b/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m index 47283dc99..3b0844a1e 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m +++ b/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m @@ -90,6 +90,25 @@ - (void)renderNodeContent:(MarkdownASTNode *)node // ListItemRenderer pre-increments, so the counter starts one below the // first rendered number. context.listItemNumber = startNumber - 1; + const CGFloat defaultMarkerWidth = [_config effectiveListMarginLeftForNumber:99]; + if (prevDepth > 0) { + context.listMarkerOffset += context.listItemMarkerExtra; + } + context.listMarkerWidth = defaultMarkerWidth; + if (_isOrdered) { + NSInteger number = startNumber; + for (MarkdownASTNode *item in node.children) { + if (item.type != MarkdownNodeTypeListItem) + continue; + // Keep the existing gutter for one- and two-digit markers. + if (number >= 100 && ![item.attributes[@"isTask"] isEqualToString:@"true"]) { + context.listMarkerWidth = MAX(context.listMarkerWidth, [_config effectiveListMarginLeftForNumber:number]); + } + number++; + } + } + + context.listMarkerExtra = context.listMarkerWidth - defaultMarkerWidth; [context setBlockStyle:_isOrdered ? BlockTypeOrderedList : BlockTypeUnorderedList font:_config.listStyleFont diff --git a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h index ad4a6431a..5bafb9ac3 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h +++ b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h @@ -52,6 +52,10 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered }; @property (nonatomic, assign) NSInteger listDepth; @property (nonatomic, assign) ListType listType; @property (nonatomic, assign) NSInteger listItemNumber; +@property (nonatomic, assign) CGFloat listMarkerWidth; +@property (nonatomic, assign) CGFloat listMarkerExtra; +@property (nonatomic, assign) CGFloat listMarkerOffset; +@property (nonatomic, assign) CGFloat listItemMarkerExtra; @property (nonatomic, assign) CGFloat accumulatedIndent; @property (nonatomic, assign) BOOL allowFontScaling; @property (nonatomic, assign) CGFloat maxFontSizeMultiplier; diff --git a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m index b22686708..40776aaf7 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m +++ b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m @@ -24,6 +24,10 @@ @implementation BlockStyle @"listDepth", @"listType", @"listItemNumber", + @"listMarkerWidth", + @"listMarkerExtra", + @"listMarkerOffset", + @"listItemMarkerExtra", @"accumulatedIndent", ]; }); @@ -313,6 +317,10 @@ - (void)reset _listDepth = 0; _listType = ListTypeUnordered; _listItemNumber = 0; + _listMarkerWidth = 0; + _listMarkerExtra = 0; + _listMarkerOffset = 0; + _listItemMarkerExtra = 0; _accumulatedIndent = 0; _taskItemCount = 0; diff --git a/packages/react-native-enriched-markdown/ios/styles/StyleConfig.h b/packages/react-native-enriched-markdown/ios/styles/StyleConfig.h index 628d069ed..815a86a57 100644 --- a/packages/react-native-enriched-markdown/ios/styles/StyleConfig.h +++ b/packages/react-native-enriched-markdown/ios/styles/StyleConfig.h @@ -336,7 +336,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)listStyleFont; - (CGFloat)effectiveListGapWidth; - (CGFloat)effectiveListMarginLeftForBullet; -- (CGFloat)effectiveListMarginLeftForNumber; +- (CGFloat)effectiveListMarginLeftForNumber:(NSInteger)number; - (CGFloat)effectiveListMarginLeftForTask; // Code block properties - (CGFloat)codeBlockFontSize; diff --git a/packages/react-native-enriched-markdown/ios/styles/StyleConfig.mm b/packages/react-native-enriched-markdown/ios/styles/StyleConfig.mm index 33876bd21..82ae4be95 100644 --- a/packages/react-native-enriched-markdown/ios/styles/StyleConfig.mm +++ b/packages/react-native-enriched-markdown/ios/styles/StyleConfig.mm @@ -2079,11 +2079,13 @@ - (CGFloat)effectiveListMarginLeftForBullet return MAX(_listStyleMarkerMinWidth, _listStyleBulletSize / 2.0); } -- (CGFloat)effectiveListMarginLeftForNumber +- (CGFloat)effectiveListMarginLeftForNumber:(NSInteger)number { UIFont *font = [self listMarkerFont]; CGFloat natural = - [@"99." sizeWithAttributes:@{NSFontAttributeName : font ?: [UIFont systemFontOfSize:_listStyleFontSize]}].width; + [[NSString stringWithFormat:@"%ld.", (long)number] + sizeWithAttributes:@{NSFontAttributeName : font ?: [UIFont systemFontOfSize:_listStyleFontSize]}] + .width; return MAX(_listStyleMarkerMinWidth, natural); } From 312dcbf89c590f62bc08b96aab28c8bf6d434ce2 Mon Sep 17 00:00:00 2001 From: Gregory Moskaliuk Date: Fri, 16 Oct 2026 13:37:29 +0200 Subject: [PATCH 2/3] fix: carry the marker widening through the list context and move tasks with it The nested-item margin lives in BaseListSpan, driven by a markerExtraWidth that OrderedListSpan and TaskListSpan override, so a later change to nested margins has one formula to extend. ListContextManager saves and restores the widening like the rest of the list state, and the column is measured by a companion function instead of a throwaway span. The extra is rounded to whole pixels so the Int leading margins and the float marker positions agree at every depth. A task item inside a widened ordered list now moves with its numbered siblings on every platform, as the Swift package already did; before, the checkbox column stayed put and left a notch in long lists. iOS names the nesting offset ancestorMarkerOffset like Android, keeps the per-list extra cached on the context, and derives the default column width from ListStyle instead of a static on a sibling renderer. Co-Authored-By: Claude Fable 5.1 --- .../android/api-reference/style-properties.md | 2 +- .../api-reference/style-properties.md | 2 +- .../markdown/renderer/BlockStyleContext.kt | 4 +- .../markdown/renderer/ListContextManager.kt | 19 ++++++ .../markdown/renderer/ListItemRenderer.kt | 9 +-- .../markdown/renderer/ListRenderer.kt | 25 ++----- .../enriched/markdown/spans/BaseListSpan.kt | 5 +- .../markdown/spans/OrderedListSpan.kt | 65 ++++++++++-------- .../enriched/markdown/spans/TaskListSpan.kt | 3 +- .../Rendering/RenderContext.swift | 4 +- .../Renderers/BlockquoteRenderer.swift | 6 +- .../Renderers/ListItemRenderer.swift | 32 ++++----- .../Rendering/Renderers/ListRenderer.swift | 14 ++-- .../markdown/renderer/BlockStyleContext.kt | 4 +- .../markdown/renderer/ListContextManager.kt | 19 ++++++ .../markdown/renderer/ListItemRenderer.kt | 9 +-- .../markdown/renderer/ListRenderer.kt | 43 ++++++------ .../enriched/markdown/spans/BaseListSpan.kt | 5 +- .../markdown/spans/OrderedListSpan.kt | 67 +++++++++++-------- .../enriched/markdown/spans/TaskListSpan.kt | 3 +- .../text/interaction/TaskListTapUtils.kt | 1 + .../ios/renderer/ListItemRenderer.m | 7 +- .../ios/renderer/ListRenderer.m | 3 +- .../ios/renderer/RenderContext.h | 2 +- .../ios/renderer/RenderContext.m | 4 +- 25 files changed, 206 insertions(+), 151 deletions(-) diff --git a/docs/docs/android/api-reference/style-properties.md b/docs/docs/android/api-reference/style-properties.md index f734dbaa2..7dfc02153 100644 --- a/docs/docs/android/api-reference/style-properties.md +++ b/docs/docs/android/api-reference/style-properties.md @@ -236,7 +236,7 @@ Requires [`MarkdownOptions(admonitions = true)`](/android/api-reference/enriched | `bulletSize` | `Dp` | `6.dp` | Unordered list bullet size | | `markerColor` | `Color` | `#6B7280` | Ordered list number color | | `markerFontWeight` | `FontWeight` | `FontWeight.Medium` (500) | Ordered list number weight | -| `markerMinWidth` | `Dp` | `0.dp` | Minimum width reserved for the marker column | +| `markerMinWidth` | `Dp` | `0.dp` | Minimum width reserved for the marker column. An ordered list's column also grows to fit its widest number | | `gapWidth` | `Dp` | `12.dp` | Gap between the marker and the text | | `marginLeft` | `Dp` | `24.dp` | Indent applied per nesting level | diff --git a/docs/docs/react-native/api-reference/style-properties.md b/docs/docs/react-native/api-reference/style-properties.md index 55e477e5c..a83eae0d1 100644 --- a/docs/docs/react-native/api-reference/style-properties.md +++ b/docs/docs/react-native/api-reference/style-properties.md @@ -254,7 +254,7 @@ Requires [`flavor="github"`](/react-native/api-reference/enriched-markdown-text# | ------------------ | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `bulletColor` | `string` | `#6B7280` | Bullet point color | | `bulletSize` | `number` | `6` | Bullet point size | -| `markerMinWidth` | `number` | `0` | Minimum reserved marker column width (floors the natural width of every list type) | +| `markerMinWidth` | `number` | `0` | Minimum reserved marker column width (floors the natural width of every list type). An ordered list's column also grows to fit its widest number | | `markerColor` | `string` | `#6B7280` | Number marker color | | `markerFontWeight` | `string` | `'500'` | Number marker font weight | | `gapWidth` | `number` | `12` | Gap between marker and text | diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt index 74e4f0c41..7cab2df14 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt @@ -41,7 +41,7 @@ class BlockStyleContext { var listDepth = 0 var listType: ListType? = null var listItemNumber = 0 - var listMarkerWidth = 0f + var listMarkerExtra = 0f var ancestorMarkerOffset = 0f var listItemMarkerExtra = 0f var taskItemCount = 0 @@ -152,7 +152,7 @@ class BlockStyleContext { listDepth = 0 listType = null listItemNumber = 0 - listMarkerWidth = 0f + listMarkerExtra = 0f ancestorMarkerOffset = 0f listItemMarkerExtra = 0f taskItemCount = 0 diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt index 567cc79dc..f8b81399e 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt @@ -12,6 +12,8 @@ import com.swmansion.enriched.markdown.styles.ListStyle * allowing each level to maintain its own counter while preserving parent's position. * - **Parent context restoration**: Restores parent list's style when exiting nested lists * so subsequent parent items render correctly. + * - **Marker column**: An ordered list widens its `99.` column to fit its widest marker, and a + * nested list inherits the widening of the item it sits in. */ class ListContextManager( private val context: BlockStyleContext, @@ -24,6 +26,8 @@ class ListContextManager( val previousDepth: Int, val parentListType: BlockStyleContext.ListType?, val wasNestedInOrderedList: Boolean, + val previousMarkerExtra: Float, + val previousMarkerOffset: Float, ) /** @@ -32,10 +36,12 @@ class ListContextManager( * - Incrementing list depth * - Setting the appropriate list style * - Resetting item number for the new list + * - Widening the marker column by [markerExtraWidth] and shifting a nested list by its parent item's widening */ fun enterList( listType: BlockStyleContext.ListType, style: ListStyle, + markerExtraWidth: Float = 0f, ): ListEntryState { val previousDepth = context.listDepth val isNested = previousDepth > 0 @@ -60,10 +66,19 @@ class ListContextManager( } context.resetListItemNumber() + val previousMarkerExtra = context.listMarkerExtra + val previousMarkerOffset = context.ancestorMarkerOffset + if (isNested) { + context.ancestorMarkerOffset += context.listItemMarkerExtra + } + context.listMarkerExtra = markerExtraWidth + return ListEntryState( previousDepth = previousDepth, parentListType = parentListType, wasNestedInOrderedList = isNested && parentIsOrdered, + previousMarkerExtra = previousMarkerExtra, + previousMarkerOffset = previousMarkerOffset, ) } @@ -73,6 +88,7 @@ class ListContextManager( * - Decrementing list depth back to previousDepth * - Restoring parent list item numbers from stack (if applicable) * - Restoring parent list metadata (if nested) so subsequent parent items render correctly + * - Restoring the parent list's marker column and offset */ fun exitList(entryState: ListEntryState) { context.listDepth = entryState.previousDepth @@ -85,5 +101,8 @@ class ListContextManager( if (entryState.previousDepth > 0) { context.listType = entryState.parentListType } + + context.listMarkerExtra = entryState.previousMarkerExtra + context.ancestorMarkerOffset = entryState.previousMarkerOffset } } diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt index b9485d3f7..5878fe6c0 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt @@ -50,6 +50,7 @@ class ListItemRenderer( taskIndex = taskIndex, isChecked = isChecked, ancestorMarkerOffset = styleContext.ancestorMarkerOffset, + markerExtraWidth = styleContext.listMarkerExtra, ) } else { when (listType) { @@ -59,7 +60,7 @@ class ListItemRenderer( depth, factory.context, factory.styleCache, - styleContext.ancestorMarkerOffset, + ancestorMarkerOffset = styleContext.ancestorMarkerOffset, ) } @@ -69,8 +70,8 @@ class ListItemRenderer( depth, factory.context, factory.styleCache, - styleContext.listMarkerWidth, - styleContext.ancestorMarkerOffset, + markerExtraWidth = styleContext.listMarkerExtra, + ancestorMarkerOffset = styleContext.ancestorMarkerOffset, ).apply { setItemNumber(styleContext.listItemNumber) } @@ -80,7 +81,7 @@ class ListItemRenderer( // Nested lists inside this item shift by its extra marker width. val previousMarkerExtra = styleContext.listItemMarkerExtra - styleContext.listItemMarkerExtra = (span as? OrderedListSpan)?.markerExtraWidth ?: 0f + styleContext.listItemMarkerExtra = span.markerExtraWidth try { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) } finally { diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt index 4893a5587..077824b16 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt @@ -24,15 +24,9 @@ class ListRenderer( val listStyle = config.style.listStyle val listType = if (isOrdered) BlockStyleContext.ListType.ORDERED else BlockStyleContext.ListType.UNORDERED + val markerExtraWidth = if (isOrdered) markerExtraWidth(node, listStyle, factory) else 0f val contextManager = ListContextManager(factory.blockStyleContext) - val entryState = contextManager.enterList(listType, listStyle) - val styleContext = factory.blockStyleContext - val previousMarkerWidth = styleContext.listMarkerWidth - val previousMarkerOffset = styleContext.ancestorMarkerOffset - if (entryState.previousDepth > 0) { - styleContext.ancestorMarkerOffset += styleContext.listItemMarkerExtra - } - styleContext.listMarkerWidth = if (isOrdered) measureMarkerColumn(node, listStyle, factory) else 0f + val entryState = contextManager.enterList(listType, listStyle, markerExtraWidth) // For top-level lists, insert marginTop spacer before rendering content if (entryState.previousDepth == 0) { @@ -50,8 +44,6 @@ class ListRenderer( try { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) } finally { - styleContext.listMarkerWidth = previousMarkerWidth - styleContext.ancestorMarkerOffset = previousMarkerOffset contextManager.exitList(entryState) } @@ -60,23 +52,20 @@ class ListRenderer( } } - /** Widest marker this list draws; lists under 100 items keep the `99.` column. */ - private fun measureMarkerColumn( + /** Lists under 100 keep the `99.` column, so only numbers from 100 on widen it. Task items draw a checkbox. */ + private fun markerExtraWidth( node: MarkdownASTNode, listStyle: ListStyle, factory: RendererFactory, ): Float { - val marker = OrderedListSpan(listStyle, 0, factory.context, factory.styleCache) + val wideNumbers = mutableListOf() var number = 1 - var width = marker.measureMarkerWidth(99) for (item in node.children) { if (item.type != MarkdownASTNode.NodeType.ListItem) continue - if (number >= 100 && item.attributes["isTask"] != "true") { - width = maxOf(width, marker.measureMarkerWidth(number)) - } + if (number >= 100 && item.attributes["isTask"] != "true") wideNumbers += number number++ } - return width + return OrderedListSpan.measureExtraWidth(listStyle, factory.context, wideNumbers) } private fun applyListSpacing( diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt index 3ebbcabed..cffeb499a 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt @@ -38,6 +38,9 @@ abstract class BaseListSpan( protected abstract fun getMarkerWidth(): Float + /** How far an ordered list widened this item's column past the one short lists reserve. */ + internal open val markerExtraWidth: Float = 0f + override fun updateMeasureState(textPaint: TextPaint) = applyTextStyle(textPaint) override fun updateDrawState(textPaint: TextPaint) = applyTextStyle(textPaint) @@ -47,7 +50,7 @@ abstract class BaseListSpan( val effectiveGap = gapWidth.coerceAtLeast(DEFAULT_MIN_GAP) (getMarkerWidth() + effectiveGap).toInt() } else { - marginLeft.toInt() + (marginLeft + markerExtraWidth).toInt() } override fun drawLeadingMargin( diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt index 8f3368ad1..2d1130e5d 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt @@ -10,13 +10,14 @@ import com.swmansion.enriched.markdown.renderer.BlockStyle import com.swmansion.enriched.markdown.renderer.SpanStyleCache import com.swmansion.enriched.markdown.styles.ListStyle import com.swmansion.enriched.markdown.utils.text.TypefaceUtils +import kotlin.math.ceil class OrderedListSpan( private val listStyle: ListStyle, depth: Int, context: Context, styleCache: SpanStyleCache, - private val markerWidth: Float = 0f, + override val markerExtraWidth: Float = 0f, ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, @@ -35,37 +36,47 @@ class OrderedListSpan( ) { companion object { private val sharedMarkerPaint = TextPaint().apply { isAntiAlias = true } - } - - private val markerTypeface: Typeface = - TypefaceUtils.applyStyles( - context = context, - fontFamily = listStyle.fontFamily.takeIf { it.isNotEmpty() }, - fontWeight = listStyle.markerFontWeight, - ) - private fun configureMarkerPaint(): TextPaint = - sharedMarkerPaint.apply { - textSize = listStyle.fontSize - color = listStyle.markerColor - typeface = markerTypeface + /** + * How far the `99.` column every ordered list reserves must grow to fit each of [numbers]. + * Whole pixels, so the Int leading margins and the float marker positions agree at every depth. + */ + fun measureExtraWidth( + listStyle: ListStyle, + context: Context, + numbers: Iterable, + ): Float { + val paint = markerPaint(listStyle, markerTypeface(listStyle, context)) + val default = paint.measureText("99.") + val widest = numbers.fold(default) { width, number -> maxOf(width, paint.measureText("$number.")) } + return ceil(listStyle.effectiveMarkerWidth(widest) - listStyle.effectiveMarkerWidth(default)) } - private val defaultMarkerWidth = measureMarkerWidth(99) - private val resolvedMarkerWidth = maxOf(markerWidth, defaultMarkerWidth) - - internal val markerExtraWidth = resolvedMarkerWidth - defaultMarkerWidth + private fun markerTypeface( + listStyle: ListStyle, + context: Context, + ): Typeface = + TypefaceUtils.applyStyles( + context = context, + fontFamily = listStyle.fontFamily.takeIf { it.isNotEmpty() }, + fontWeight = listStyle.markerFontWeight, + ) - override fun getMarkerWidth(): Float = resolvedMarkerWidth + private fun markerPaint( + listStyle: ListStyle, + typeface: Typeface, + ): TextPaint = + sharedMarkerPaint.apply { + textSize = listStyle.fontSize + color = listStyle.markerColor + this.typeface = typeface + } + } - internal fun measureMarkerWidth(number: Int): Float = listStyle.effectiveMarkerWidth(configureMarkerPaint().measureText("$number.")) + private val markerTypeface = markerTypeface(listStyle, context) + private val defaultMarkerWidth = listStyle.effectiveMarkerWidth(markerPaint(listStyle, markerTypeface).measureText("99.")) - override fun getLeadingMargin(first: Boolean): Int = - if (depth > 0) { - (listStyle.marginLeft + markerExtraWidth).toInt() - } else { - super.getLeadingMargin(first) - } + override fun getMarkerWidth(): Float = defaultMarkerWidth + markerExtraWidth var itemNumber: Int = 1 private set @@ -81,7 +92,7 @@ class OrderedListSpan( layout: Layout?, start: Int, ) { - val markerPaint = configureMarkerPaint() + val markerPaint = markerPaint(listStyle, markerTypeface) val text = if (dir < 0) ".$itemNumber" else "$itemNumber." val textWidth = markerPaint.measureText(text) diff --git a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt index 564a13f82..0c269f96f 100644 --- a/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +++ b/packages/enriched-markdown-android/ui/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt @@ -27,6 +27,7 @@ class TaskListSpan( */ var isChecked: Boolean, ancestorMarkerOffset: Float = 0f, + override val markerExtraWidth: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -60,7 +61,7 @@ class TaskListSpan( } private val checkboxSize = taskStyle.checkboxSize - private val markerColumnWidth = listStyle.effectiveMarkerWidth(checkboxSize) + private val markerColumnWidth = listStyle.effectiveMarkerWidth(checkboxSize) + markerExtraWidth private val cornerRadius = taskStyle.checkboxBorderRadius private val rect = RectF() private val insetRect = RectF() diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift index 96189afa8..623bacd8f 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/RenderContext.swift @@ -81,10 +81,8 @@ package final class RenderContext { var listItemNumber = 0 /// Marker column of the current ordered list, sized to its widest number. var listMarkerWidth: CGFloat = 0 - /// How far the current list's marker column exceeds the default one. - var listMarkerExtra: CGFloat = 0 /// Extra marker width of the enclosing list items, carried into nested lists. - var listMarkerOffset: CGFloat = 0 + var ancestorMarkerOffset: CGFloat = 0 /// Extra marker width of the list item whose children are rendering. var listItemMarkerExtra: CGFloat = 0 var taskItemIndex = 0 diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift index c0116c95f..ce9fbc986 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/BlockquoteRenderer.swift @@ -29,12 +29,12 @@ final class BlockquoteRenderer: NodeRenderer { } // An enclosing list item shifts the whole quote by its own indent, which // already includes any widened marker column, so lists inside start fresh. - let prevMarkerOffset = context.listMarkerOffset + let prevMarkerOffset = context.ancestorMarkerOffset let prevItemMarkerExtra = context.listItemMarkerExtra - context.listMarkerOffset = 0 + context.ancestorMarkerOffset = 0 context.listItemMarkerExtra = 0 factory.renderChildren(of: node, into: output, context: context) - context.listMarkerOffset = prevMarkerOffset + context.ancestorMarkerOffset = prevMarkerOffset context.listItemMarkerExtra = prevItemMarkerExtra context.clearBlockStyle() context.exitBlockquote() diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift index ffe2852dc..cf1590cf5 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListItemRenderer.swift @@ -42,7 +42,7 @@ final class ListItemRenderer: NodeRenderer { let marginLeading = config.list.marginLeading ?? 24 let blockquoteIndent = CGFloat(context.blockquoteDepth) * blockquoteLevelSpacing() let totalIndent = blockquoteIndent + baseMarkerWidth + gapWidth + (CGFloat(nestingLevel) * marginLeading) - + context.listMarkerOffset + + context.ancestorMarkerOffset let lineHeight = config.list.lineHeight ?? 0 let metadata: [NSAttributedString.Key: Any] = [ @@ -58,7 +58,7 @@ final class ListItemRenderer: NodeRenderer { metadata: metadata, indents: ItemIndents( text: totalIndent, - quote: totalIndent - context.listMarkerOffset, + quote: totalIndent - context.ancestorMarkerOffset, markerExtra: markerExtra ), lineHeight: lineHeight @@ -79,26 +79,15 @@ final class ListItemRenderer: NodeRenderer { private func effectiveMarkerWidth(in context: RenderContext) -> CGFloat { context.listType == .ordered ? context.listMarkerWidth - : Self.defaultMarkerWidth(for: .unordered, config: config) + : config.list.defaultMarkerColumnWidth(for: .unordered) } /// The item's column before an ordered list widens it for its numbers. private func defaultColumnWidth(isTask: Bool, listType: ListType) -> CGFloat { - let markerWidth = Self.defaultMarkerWidth(for: listType, config: config) + let markerWidth = config.list.defaultMarkerColumnWidth(for: listType) return isTask ? max(markerWidth, config.taskList.checkboxSize ?? 14) : markerWidth } - /// The marker column before an ordered list widens it for its numbers. - static func defaultMarkerWidth(for listType: ListType, config: MarkdownStyleConfiguration) -> CGFloat { - let minWidth = config.list.markerMinWidth ?? 0 - switch listType { - case .ordered: - return max(minWidth, 20) - case .unordered: - return max(minWidth, config.list.bulletSize ?? 6) - } - } - /// The checkbox column is at least as wide as the list's marker column, /// so task items align with their non-task siblings. private func effectiveTaskMarkerWidth(in context: RenderContext) -> CGFloat { @@ -257,3 +246,16 @@ private struct ItemIndents { /// How far a widened ordered list grew this item's marker column. let markerExtra: CGFloat } + +extension ListStyle { + /// The marker column before an ordered list widens it for its numbers. + func defaultMarkerColumnWidth(for listType: ListType) -> CGFloat { + let minWidth = markerMinWidth ?? 0 + switch listType { + case .ordered: + return max(minWidth, 20) + case .unordered: + return max(minWidth, bulletSize ?? 6) + } + } +} diff --git a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift index cdfbc01d5..1263cc193 100644 --- a/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift +++ b/packages/enriched-markdown-ios/Sources/EnrichedMarkdown/Rendering/Renderers/ListRenderer.swift @@ -16,8 +16,7 @@ final class ListRenderer: NodeRenderer { let prevType = context.listType let prevNumber = context.listItemNumber let prevMarkerWidth = context.listMarkerWidth - let prevMarkerExtra = context.listMarkerExtra - let prevMarkerOffset = context.listMarkerOffset + let prevMarkerOffset = context.ancestorMarkerOffset let startLocation = output.length if prevDepth == 0 { @@ -35,11 +34,11 @@ final class ListRenderer: NodeRenderer { context.listType = isOrdered ? .ordered : .unordered context.listItemNumber = 0 if prevDepth > 0 { - context.listMarkerOffset += context.listItemMarkerExtra + context.ancestorMarkerOffset += context.listItemMarkerExtra } - let defaultMarkerWidth = ListItemRenderer.defaultMarkerWidth(for: .ordered, config: config) - context.listMarkerWidth = isOrdered ? widestMarkerWidth(of: node, atLeast: defaultMarkerWidth) : 0 - context.listMarkerExtra = isOrdered ? context.listMarkerWidth - defaultMarkerWidth : 0 + context.listMarkerWidth = isOrdered + ? widestMarkerWidth(of: node, atLeast: config.list.defaultMarkerColumnWidth(for: .ordered)) + : 0 let font = config.list.font ?? UIFont.preferredFont(forTextStyle: .body) let color = config.list.foregroundColor ?? UIColor.label @@ -55,8 +54,7 @@ final class ListRenderer: NodeRenderer { context.listType = prevType context.listItemNumber = prevNumber context.listMarkerWidth = prevMarkerWidth - context.listMarkerExtra = prevMarkerExtra - context.listMarkerOffset = prevMarkerOffset + context.ancestorMarkerOffset = prevMarkerOffset if prevDepth == 0 { context.clearBlockStyle() diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt index c54919d41..1ca6f3dd4 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt @@ -41,7 +41,7 @@ class BlockStyleContext { var listDepth = 0 var listType: ListType? = null var listItemNumber = 0 - var listMarkerWidth = 0f + var listMarkerExtra = 0f var ancestorMarkerOffset = 0f var listItemMarkerExtra = 0f var taskItemCount = 0 @@ -154,7 +154,7 @@ class BlockStyleContext { listDepth = 0 listType = null listItemNumber = 0 - listMarkerWidth = 0f + listMarkerExtra = 0f ancestorMarkerOffset = 0f listItemMarkerExtra = 0f taskItemCount = 0 diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt index cb3d2aa54..548dbda85 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt @@ -12,6 +12,8 @@ import com.swmansion.enriched.markdown.styles.ListStyle * allowing each level to maintain its own counter while preserving parent's position. * - **Parent context restoration**: Restores parent list's style when exiting nested lists * so subsequent parent items render correctly. + * - **Marker column**: An ordered list widens its `99.` column to fit its widest marker, and a + * nested list inherits the widening of the item it sits in. */ class ListContextManager( private val context: BlockStyleContext, @@ -24,6 +26,8 @@ class ListContextManager( val previousDepth: Int, val parentListType: BlockStyleContext.ListType?, val wasNestedInOrderedList: Boolean, + val previousMarkerExtra: Float, + val previousMarkerOffset: Float, ) /** @@ -32,11 +36,13 @@ class ListContextManager( * - Incrementing list depth * - Setting the appropriate list style * - Resetting item number for the new list + * - Widening the marker column by [markerExtraWidth] and shifting a nested list by its parent item's widening */ fun enterList( listType: BlockStyleContext.ListType, style: ListStyle, startNumber: Int = 1, + markerExtraWidth: Float = 0f, ): ListEntryState { val previousDepth = context.listDepth val isNested = previousDepth > 0 @@ -61,10 +67,19 @@ class ListContextManager( } context.resetListItemNumber(startNumber) + val previousMarkerExtra = context.listMarkerExtra + val previousMarkerOffset = context.ancestorMarkerOffset + if (isNested) { + context.ancestorMarkerOffset += context.listItemMarkerExtra + } + context.listMarkerExtra = markerExtraWidth + return ListEntryState( previousDepth = previousDepth, parentListType = parentListType, wasNestedInOrderedList = isNested && parentIsOrdered, + previousMarkerExtra = previousMarkerExtra, + previousMarkerOffset = previousMarkerOffset, ) } @@ -74,6 +89,7 @@ class ListContextManager( * - Decrementing list depth back to previousDepth * - Restoring parent list item numbers from stack (if applicable) * - Restoring parent list metadata (if nested) so subsequent parent items render correctly + * - Restoring the parent list's marker column and offset */ fun exitList(entryState: ListEntryState) { context.listDepth = entryState.previousDepth @@ -86,5 +102,8 @@ class ListContextManager( if (entryState.previousDepth > 0) { context.listType = entryState.parentListType } + + context.listMarkerExtra = entryState.previousMarkerExtra + context.ancestorMarkerOffset = entryState.previousMarkerOffset } } diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt index c0f6a1802..f79309fad 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt @@ -51,6 +51,7 @@ class ListItemRenderer( isChecked = isChecked, drawsMarker = drawsMarker, ancestorMarkerOffset = styleContext.ancestorMarkerOffset, + markerExtraWidth = styleContext.listMarkerExtra, ) } else { when (listType) { @@ -61,7 +62,7 @@ class ListItemRenderer( factory.context, factory.styleCache, drawsMarker, - styleContext.ancestorMarkerOffset, + ancestorMarkerOffset = styleContext.ancestorMarkerOffset, ) } @@ -72,8 +73,8 @@ class ListItemRenderer( factory.context, factory.styleCache, drawsMarker, - styleContext.listMarkerWidth, - styleContext.ancestorMarkerOffset, + markerExtraWidth = styleContext.listMarkerExtra, + ancestorMarkerOffset = styleContext.ancestorMarkerOffset, ).apply { setItemNumber(styleContext.listItemNumber) } @@ -84,7 +85,7 @@ class ListItemRenderer( val markerSpan = makeSpan(drawsMarker = true) val previousMarkerExtra = styleContext.listItemMarkerExtra - styleContext.listItemMarkerExtra = (markerSpan as? OrderedListSpan)?.markerExtraWidth ?: 0f + styleContext.listItemMarkerExtra = markerSpan.markerExtraWidth val prevIndent = styleContext.accumulatedIndent styleContext.accumulatedIndent = prevIndent + markerSpan.getLeadingMargin(false) try { diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt index 430011a7c..d88422262 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt @@ -32,29 +32,9 @@ class ListRenderer( 1 } + val markerExtraWidth = if (isOrdered) markerExtraWidth(node, listStyle, startNumber, factory) else 0f val contextManager = ListContextManager(factory.blockStyleContext) - val entryState = contextManager.enterList(listType, listStyle, startNumber) - val previousMarkerWidth = factory.blockStyleContext.listMarkerWidth - val previousMarkerOffset = factory.blockStyleContext.ancestorMarkerOffset - if (entryState.previousDepth > 0) { - factory.blockStyleContext.ancestorMarkerOffset += factory.blockStyleContext.listItemMarkerExtra - } - factory.blockStyleContext.listMarkerWidth = - if (isOrdered) { - val marker = OrderedListSpan(listStyle, 0, factory.context, factory.styleCache) - var number = startNumber - var width = marker.measureMarkerWidth(99) - for (item in node.children) { - if (item.type != MarkdownASTNode.NodeType.ListItem) continue - if (number >= 100 && item.attributes["isTask"] != "true") { - width = maxOf(width, marker.measureMarkerWidth(number)) - } - number++ - } - width - } else { - 0f - } + val entryState = contextManager.enterList(listType, listStyle, startNumber, markerExtraWidth) // For top-level lists, insert marginTop spacer before rendering content if (entryState.previousDepth == 0) { @@ -72,8 +52,6 @@ class ListRenderer( try { factory.renderChildren(node, builder, onLinkPress, onLinkLongPress) } finally { - factory.blockStyleContext.listMarkerWidth = previousMarkerWidth - factory.blockStyleContext.ancestorMarkerOffset = previousMarkerOffset contextManager.exitList(entryState) } @@ -82,6 +60,23 @@ class ListRenderer( } } + /** Lists under 100 keep the `99.` column, so only numbers from 100 on widen it. Task items draw a checkbox. */ + private fun markerExtraWidth( + node: MarkdownASTNode, + listStyle: ListStyle, + startNumber: Int, + factory: RendererFactory, + ): Float { + val wideNumbers = mutableListOf() + var number = startNumber + for (item in node.children) { + if (item.type != MarkdownASTNode.NodeType.ListItem) continue + if (number >= 100 && item.attributes["isTask"] != "true") wideNumbers += number + number++ + } + return OrderedListSpan.measureExtraWidth(listStyle, factory.context, wideNumbers) + } + private fun applyListSpacing( builder: SpannableStringBuilder, start: Int, diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt index 9048a7e12..054931d8d 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt @@ -39,6 +39,9 @@ abstract class BaseListSpan( protected abstract fun getMarkerWidth(): Float + /** How far an ordered list widened this item's column past the one short lists reserve. */ + internal open val markerExtraWidth: Float = 0f + override fun updateMeasureState(textPaint: TextPaint) = applyTextStyle(textPaint) override fun updateDrawState(textPaint: TextPaint) = applyTextStyle(textPaint) @@ -48,7 +51,7 @@ abstract class BaseListSpan( val effectiveGap = gapWidth.coerceAtLeast(DEFAULT_MIN_GAP) (getMarkerWidth() + effectiveGap).toInt() } else { - marginLeft.toInt() + (marginLeft + markerExtraWidth).toInt() } override fun drawLeadingMargin( diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt index f1bfbe9d2..9a2b19930 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt @@ -12,6 +12,7 @@ import com.facebook.react.views.text.ReactTypefaceUtils.parseFontWeight import com.swmansion.enriched.markdown.renderer.BlockStyle import com.swmansion.enriched.markdown.renderer.SpanStyleCache import com.swmansion.enriched.markdown.styles.ListStyle +import kotlin.math.ceil class OrderedListSpan( private val listStyle: ListStyle, @@ -19,7 +20,7 @@ class OrderedListSpan( context: Context, styleCache: SpanStyleCache, drawsMarker: Boolean = true, - private val markerWidth: Float = 0f, + override val markerExtraWidth: Float = 0f, ancestorMarkerOffset: Float = 0f, ) : BaseListSpan( depth = depth, @@ -39,37 +40,49 @@ class OrderedListSpan( ) { companion object { private val sharedMarkerPaint = TextPaint().apply { isAntiAlias = true } - } - - private val markerTypeface: Typeface = - run { - val fontFamily = listStyle.fontFamily.takeIf { it.isNotEmpty() } - val fontWeight = parseFontWeight(listStyle.markerFontWeight) - applyStyles(null, ReactConstants.UNSET, fontWeight, fontFamily, context.assets) - } - private fun configureMarkerPaint(): TextPaint = - sharedMarkerPaint.apply { - textSize = listStyle.fontSize - color = listStyle.markerColor - typeface = markerTypeface + /** + * How far the `99.` column every ordered list reserves must grow to fit each of [numbers]. + * Whole pixels, so the Int leading margins and the float marker positions agree at every depth. + */ + fun measureExtraWidth( + listStyle: ListStyle, + context: Context, + numbers: Iterable, + ): Float { + val paint = markerPaint(listStyle, markerTypeface(listStyle, context)) + val default = paint.measureText("99.") + val widest = numbers.fold(default) { width, number -> maxOf(width, paint.measureText("$number.")) } + return ceil(listStyle.effectiveMarkerWidth(widest) - listStyle.effectiveMarkerWidth(default)) } - private val defaultMarkerWidth = measureMarkerWidth(99) - private val resolvedMarkerWidth = maxOf(markerWidth, defaultMarkerWidth) + private fun markerTypeface( + listStyle: ListStyle, + context: Context, + ): Typeface = + applyStyles( + null, + ReactConstants.UNSET, + parseFontWeight(listStyle.markerFontWeight), + listStyle.fontFamily.takeIf { it.isNotEmpty() }, + context.assets, + ) - internal val markerExtraWidth = resolvedMarkerWidth - defaultMarkerWidth - - override fun getMarkerWidth(): Float = resolvedMarkerWidth + private fun markerPaint( + listStyle: ListStyle, + typeface: Typeface, + ): TextPaint = + sharedMarkerPaint.apply { + textSize = listStyle.fontSize + color = listStyle.markerColor + this.typeface = typeface + } + } - internal fun measureMarkerWidth(number: Int): Float = listStyle.effectiveMarkerWidth(configureMarkerPaint().measureText("$number.")) + private val markerTypeface = markerTypeface(listStyle, context) + private val defaultMarkerWidth = listStyle.effectiveMarkerWidth(markerPaint(listStyle, markerTypeface).measureText("99.")) - override fun getLeadingMargin(first: Boolean): Int = - if (depth > 0) { - (listStyle.marginLeft + markerExtraWidth).toInt() - } else { - super.getLeadingMargin(first) - } + override fun getMarkerWidth(): Float = defaultMarkerWidth + markerExtraWidth var itemNumber: Int = 1 private set @@ -85,7 +98,7 @@ class OrderedListSpan( layout: Layout?, start: Int, ) { - val markerPaint = configureMarkerPaint() + val markerPaint = markerPaint(listStyle, markerTypeface) val text = if (dir < 0) ".$itemNumber" else "$itemNumber." val textWidth = markerPaint.measureText(text) diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt index 07629e0ba..fb0088718 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt @@ -21,6 +21,7 @@ class TaskListSpan( val isChecked: Boolean, drawsMarker: Boolean = true, ancestorMarkerOffset: Float = 0f, + override val markerExtraWidth: Float = 0f, ) : BaseListSpan( depth = depth, context = context, @@ -38,7 +39,7 @@ class TaskListSpan( ancestorMarkerOffset = ancestorMarkerOffset, ) { private val checkboxSize = taskStyle.checkboxSize - private val markerColumnWidth = listStyle.effectiveMarkerWidth(checkboxSize) + private val markerColumnWidth = listStyle.effectiveMarkerWidth(checkboxSize) + markerExtraWidth private val cornerRadius = taskStyle.checkboxBorderRadius private val rect = RectF() private val checkPath = Path() diff --git a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt index ff5b0db95..a9e6e00d0 100644 --- a/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +++ b/packages/react-native-enriched-markdown/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt @@ -132,6 +132,7 @@ object TaskListTapUtils { isChecked = newChecked, drawsMarker = old.drawsMarker, ancestorMarkerOffset = old.ancestorMarkerOffset, + markerExtraWidth = old.markerExtraWidth, ) // Layout draws leading margins in insertion order, and a re-added span moves to the end of it. diff --git a/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m b/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m index c26b10764..dd6aa2478 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m +++ b/packages/react-native-enriched-markdown/ios/renderer/ListItemRenderer.m @@ -83,7 +83,8 @@ - (void)renderNodeContent:(MarkdownASTNode *)node // currentDepth - 1 handles the horizontal offset for nested lists const NSInteger nestingLevel = currentDepth - 1; - const CGFloat baseMarkerWidth = isTask ? [_config effectiveListMarginLeftForTask] + // A task in a widened ordered list moves with its numbered siblings. + const CGFloat baseMarkerWidth = isTask ? [_config effectiveListMarginLeftForTask] + context.listMarkerExtra : (context.listType == ListTypeOrdered) ? context.listMarkerWidth : [_config effectiveListMarginLeftForBullet]; @@ -91,13 +92,13 @@ - (void)renderNodeContent:(MarkdownASTNode *)node blockquoteIndentForDepth(context.blockquoteDepth, [_config blockquoteBorderWidth] + [_config blockquoteGapWidth]); const CGFloat totalIndent = blockquoteIndent + baseMarkerWidth + [_config effectiveListGapWidth] + - (nestingLevel * [_config listStyleMarginLeft]) + context.listMarkerOffset; + (nestingLevel * [_config listStyleMarginLeft]) + context.ancestorMarkerOffset; const NSUInteger startLocation = output.length; // Manual save/restore — a scope snapshot would also roll back the listItemNumber increment const CGFloat prevMarkerExtra = context.listItemMarkerExtra; - context.listItemMarkerExtra = !isTask && context.listType == ListTypeOrdered ? context.listMarkerExtra : 0; + context.listItemMarkerExtra = context.listMarkerExtra; const CGFloat prevIndent = context.accumulatedIndent; context.accumulatedIndent = totalIndent; @try { diff --git a/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m b/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m index 3b0844a1e..61812a7c0 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m +++ b/packages/react-native-enriched-markdown/ios/renderer/ListRenderer.m @@ -92,7 +92,7 @@ - (void)renderNodeContent:(MarkdownASTNode *)node context.listItemNumber = startNumber - 1; const CGFloat defaultMarkerWidth = [_config effectiveListMarginLeftForNumber:99]; if (prevDepth > 0) { - context.listMarkerOffset += context.listItemMarkerExtra; + context.ancestorMarkerOffset += context.listItemMarkerExtra; } context.listMarkerWidth = defaultMarkerWidth; if (_isOrdered) { @@ -107,7 +107,6 @@ - (void)renderNodeContent:(MarkdownASTNode *)node number++; } } - context.listMarkerExtra = context.listMarkerWidth - defaultMarkerWidth; [context setBlockStyle:_isOrdered ? BlockTypeOrderedList : BlockTypeUnorderedList diff --git a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h index 5bafb9ac3..376b5e99e 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h +++ b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.h @@ -54,7 +54,7 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered }; @property (nonatomic, assign) NSInteger listItemNumber; @property (nonatomic, assign) CGFloat listMarkerWidth; @property (nonatomic, assign) CGFloat listMarkerExtra; -@property (nonatomic, assign) CGFloat listMarkerOffset; +@property (nonatomic, assign) CGFloat ancestorMarkerOffset; @property (nonatomic, assign) CGFloat listItemMarkerExtra; @property (nonatomic, assign) CGFloat accumulatedIndent; @property (nonatomic, assign) BOOL allowFontScaling; diff --git a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m index 40776aaf7..fc5e6312c 100644 --- a/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m +++ b/packages/react-native-enriched-markdown/ios/renderer/RenderContext.m @@ -26,7 +26,7 @@ @implementation BlockStyle @"listItemNumber", @"listMarkerWidth", @"listMarkerExtra", - @"listMarkerOffset", + @"ancestorMarkerOffset", @"listItemMarkerExtra", @"accumulatedIndent", ]; @@ -319,7 +319,7 @@ - (void)reset _listItemNumber = 0; _listMarkerWidth = 0; _listMarkerExtra = 0; - _listMarkerOffset = 0; + _ancestorMarkerOffset = 0; _listItemMarkerExtra = 0; _accumulatedIndent = 0; _taskItemCount = 0; From 432ebb0775e2a5de22af09fe6a8bc4d99715339c Mon Sep 17 00:00:00 2001 From: Gregory Moskaliuk Date: Fri, 16 Oct 2026 13:37:37 +0200 Subject: [PATCH 3/3] test: name list tests by feature and share the Android render harness The marker width suites become ListRenderingTest(s) on every platform, growing with later list fixes instead of one file per bug. The checkbox toggle test moves to TaskListInteractionTest. The RN Android package gets a test/ support package like the standalone one: a render helper, an AST factory, and the canvas that records drawn markers, which both Android packages now share. Task alignment tests assert that every row of a widened list, tasks and their children included, shifts by the same amount. The Android baselines for ordered_list_wide_markers_test are recaptured on the repo's Pixel 9 API 36 AVD, where the committed ordered-list baselines pass exact-match; the iOS captures reproduce byte for byte and are unchanged. Co-Authored-By: Claude Fable 5.1 --- ...red_list_wide_markers_hundreds_display.png | Bin 30529 -> 26423 bytes ...dered_list_wide_markers_nested_display.png | Bin 33515 -> 27640 bytes ...ist_wide_markers_short_control_display.png | Bin 18555 -> 16260 bytes ...ed_list_wide_markers_thousands_display.png | Bin 31267 -> 26240 bytes ...arkerWidthTest.kt => ListRenderingTest.kt} | 133 ++--- .../markdown/test/ListMarkerCanvas.kt | 101 ++++ ...thTests.swift => ListRenderingTests.swift} | 2 +- ...kerWidthTests.mm => ListRenderingTests.mm} | 41 +- .../enriched/markdown/ListRenderingTest.kt | 270 +++++++++ .../markdown/TaskListInteractionTest.kt | 102 ++++ .../spans/OrderedListMarkerWidthTest.kt | 530 ------------------ .../markdown/test/ListMarkerCanvas.kt | 101 ++++ .../test/MarkdownRenderTestSupport.kt | 126 +++++ .../enriched/markdown/test/TestAstFactory.kt | 36 ++ 14 files changed, 798 insertions(+), 644 deletions(-) rename packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/{spans/OrderedListMarkerWidthTest.kt => ListRenderingTest.kt} (69%) create mode 100644 packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt rename packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/{OrderedListMarkerWidthTests.swift => ListRenderingTests.swift} (99%) rename packages/react-native-enriched-markdown/__tests__/ios/{OrderedListMarkerWidthTests.mm => ListRenderingTests.mm} (83%) create mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/ListRenderingTest.kt create mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/TaskListInteractionTest.kt delete mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt create mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt create mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt create mode 100644 packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/TestAstFactory.kt diff --git a/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_hundreds_display.png b/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_hundreds_display.png index 229d97a520e291276283d9289bb87ef6b6c7fd07..e2bf9313789f99f8a8464b6d285fafe1f61c5675 100644 GIT binary patch literal 26423 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

i0Vbr)ybSxQfjkf^lg-uF_FMWJPsH!r-LkL2p&> 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�+mlMXL6 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

TYWN%ZxLQ4#v~u2 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 diff --git a/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_short_control_display.png b/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_short_control_display.png index 887005cc76cf9eca0f52b0dceb466abc95a629c2..8316c5b2ce8984a79ceec79867a7ca9add4ea11c 100644 GIT binary patch literal 16260 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%0AY8z_3S>~{J zQuBeD1&Evd?*bIc zo6Lop!#+SwdQUB2ldG7ev|}^{t8Z0vcQN{WUe%6$P1qvPJ5flisO89HCZ(s_Xbq%M zq_&5aluC9Uv|nQn#mr|X6?&N!bu006g}-3jKIhqqOC9?)vUPE|g1(-HDqjJd5D#tz z@|HsNoS1Iw7+$7pcmU;0luG<>+P;5z+W!>yRRR6L_uahB{6mQAhQWbHx$a=);=MQ= zp)B#QU!qXEgF-;(D zW|%67@Dn<=WlIA#+7gc`GfBy;1&xQbPKE|xB*IMVKA>VOxj5Ucb*zCfR1JRAYVTUA z=ek>@qvo(|6ZL@y>i=*gI|oS5^!XKy!0u{6Of@l?(qtxxt@fdQ$2>+RM$n7LA+0(3 zxIl-o5NB>am#ZK!4zvOnJ%JuIT~%KfG_SQKOo64UAex)nv`fUwJnE_o7u;?OUHGY* zBEt0BXh9C|O_U1`oB)a!@52EPZI7^Uh-3XL)L_>=VQ!fO0c$ghnUMh1+jq9vWfI`v zz>5jKCJVX#FT55KY0IizkdIZuzT9IqB7dVVcE(sUIn;KnKZJ4~NYRWIDdR4%Kq^c7 zTBld&+s{zah|L<(5)evyg)MW46;qt)f(JEFj*CQc5ncAUztrl~k)I}lq+y|Cf`Q^% z;4bfcd-bc>g|ARGp>|ELFFz2-`5qtd-D^Ub-Z+I4JrkPLBl?^G@SOI0hsZgFh`Xpn zY5ubW3I+WK7yFLVtF#^}wGFL0Sot&Y1E6AySUDRPF2&h@2@r>O8TIGn&7dzgj0q$h z9rCSNW8A<4m-TBtA3s%+0KV0HUs%VX1&71k*k}h>cwTL)U|Ik?*V-l~RC;|8p8{IQ zX+Zsq3Znl({rYPoWWRq0aurSJ#J=3Y9U#a@#sISLrU2Azi#fk;*aHO=Uyu?D#G&II zkB!b@vHME8kz8V*6)CUl)fPhcyZKF1}UIt`ZnU+cwg9e|Hmf0YesW zjK57r@o#JvP68Si@_(uw!HGB^ku^S~`v4FaF!<=xM9|=IpLE{+DrFkHtq!zl_N||= za1KjeAlXf`ffyU!5)i144f7<*wfQOa7s!9VaU&}x*28_}JF4dJ-E`DevC!r{laqnL zMP?ETDA4F_9L459Tdv%Uc(2jRE(5Q1U0f1hnD2=u0ABVApe~+fiA9T7yOlxe({!~3 zOvh!bB2UEH)chrwOzBk)!0J0=7qcZfP!&=))nQrq28JQUkW4_ ztze;5j7H{nD9_lH^!sS%g0_K)tZdf5pW{^bG+B)75&DmFoPAs9!*@^qV<^dgFMg1& zT@hT1s$HJ5>Lf81oIR$G?ER0Sl&F~RjXZJDluspu$~aRm3P#67^Kxe~GchF+e~-TR zb)uX_P5nRw2aq*-O4@GxYq+!iABSF*DT9C3A4ik$O&B z(T52ilp6J8tkPce_uMW+g{~)LF@T)sL9tjxD_{c`tgdAKciRIhp!0 z8N0%rJ_0pCTjBRH=#afDly|5oXP}2SL)0_+81PCqvrgdrbmuA$uND5U`o@yev(TW;JpHDQBEWY)rzDg@FH7eV3cBIBjkOzVS zhliKIp*E^FV)Q9IPn5!99vCi78LAg%9Wx%~bG*2AlkD(B9r4WIiHRe^V!Htthb~M_ zP1k&d5qxRQB>d^^Z?MTPzGeX}^l?0*O0Q$iF0a{D!C9~1wZc38m(HkHUSu(hCeuk? X%i$8R;d%ouPo*HMB2)0>#k>Ct2>nc8 literal 18555 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 L&BrAVpTGSdKXeml diff --git a/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_thousands_display.png b/.maestro/enrichedMarkdownText/screenshots/android/ordered_list_wide_markers_thousands_display.png index a3ca7e714d3b3c4a8dcab6443189fc71e4bc4f32..d1f269bfd1cea39bbec2165ff2dc0466c3bb2c05 100644 GIT binary patch literal 26240 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 literal 31267 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 short.first().getLeadingMargin(false)) } } @@ -102,7 +100,7 @@ class OrderedListMarkerWidthTest { } @Test - fun tasksDoNotPassTheWideListsNumericExtraToTheirChildren() { + fun tasksMoveWithTheirWideNumberedSiblings() { val style = styleConfig() fun tree(count: Int): MarkdownASTNode { @@ -111,7 +109,7 @@ class OrderedListMarkerWidthTest { items[2] = listItem(paragraph(text("item")), numbered(1)) return orderedList(*items.toTypedArray()) } - assertNestedMarkerGapsUnchanged(style, tree(4), tree(1000)) + assertEveryRowShiftsTogether(style, tree(4), tree(1000)) } @Test @@ -128,15 +126,10 @@ class OrderedListMarkerWidthTest { fun inheritedMarkerOffsetsFollowTheRtlDirection() { val style = styleConfig() val text = SpannableString(render(document(withChild(numbered(1000), 0, numbered(1))), style)) - val layout = - StaticLayout.Builder - .obtain(text, 0, text.length, TextPaint(), LAYOUT_WIDTH) - .setTextDirection(TextDirectionHeuristics.RTL) - .build() - val canvas = MarkerCanvas() - layout.draw(canvas) - assertEquals(1001, canvas.markers.size) - canvas.markers.forEach { marker -> + val layout = MarkerCanvas.layout(text, style.listStyle.fontSize, rtl = true) + val markers = MarkerCanvas.drawMarkers(layout) + assertEquals(1001, markers.size) + markers.forEach { marker -> val line = layout.getLineForVertical(marker.baseline.toInt()) assertEquals(-1, layout.getParagraphDirection(line)) assertEquals(layout.getParagraphRight(line) + style.listStyle.gapWidth, marker.left, 0.01f) @@ -144,6 +137,29 @@ class OrderedListMarkerWidthTest { } } + /** The rows [wide] shares with [short], tasks and their children included, all sit [wide]'s widening further right. */ + private fun assertEveryRowShiftsTogether( + style: StyleConfig, + short: MarkdownASTNode, + wide: MarkdownASTNode, + ) { + val shortRows = drawMarkers(style, short) + val wideRows = drawMarkers(style, wide).take(shortRows.size) + assertEquals(shortRows.size, wideRows.size) + val shift = wideRows.first().paragraphLeft - shortRows.first().paragraphLeft + assertTrue(shift > 0f) + wideRows.zip(shortRows).forEach { (actual, control) -> + assertEquals(control.depth, actual.depth) + assertEquals("text shift at depth ${actual.depth}", shift, actual.paragraphLeft - control.paragraphLeft, 0.01f) + assertEquals( + "marker gap at depth ${actual.depth}", + control.paragraphLeft - control.marker.right, + actual.paragraphLeft - actual.marker.right, + 0.01f, + ) + } + } + private fun assertNestedMarkerGapsUnchanged( style: StyleConfig, short: MarkdownASTNode, @@ -170,18 +186,10 @@ class OrderedListMarkerWidthTest { ): List { // SpannableString reports spans in insertion order, as the text view does. val text = SpannableString(render(document(*lists), style)) - val paint = TextPaint().apply { textSize = style.listStyle.fontSize } - val layout = StaticLayout.Builder.obtain(text, 0, text.length, paint, LAYOUT_WIDTH).build() - val canvas = MarkerCanvas() - layout.draw(canvas) - assertEquals(text.getSpans(0, text.length, BaseListSpan::class.java).size, canvas.markers.size) - return canvas.markers.map { marker -> - val line = layout.getLineForVertical(marker.baseline.toInt()) - assertTrue("marker left ${marker.left} on line $line", marker.left >= 0f) - val start = layout.getLineStart(line) - val depth = text.getSpans(start, start + 1, BaseListSpan::class.java).maxOf { it.depth } - MarkerGeometry(marker, layout.getParagraphLeft(line).toFloat(), depth) - } + val geometry = MarkerCanvas.markerGeometry(text, MarkerCanvas.layout(text, style.listStyle.fontSize)) + assertEquals(text.getSpans(0, text.length, BaseListSpan::class.java).size, geometry.size) + geometry.forEach { assertTrue("marker left ${it.marker.left} at depth ${it.depth}", it.marker.left >= 0f) } + return geometry } private fun orderedSpans( @@ -194,61 +202,6 @@ class OrderedListMarkerWidthTest { .sortedWith(compareBy({ text.getSpanStart(it) }, { it.depth })) } - private data class MarkerGeometry( - val marker: DrawnMarker, - val paragraphLeft: Float, - val depth: Int, - ) - - private data class DrawnMarker( - val left: Float, - val right: Float, - val baseline: Float, - ) - - private class MarkerCanvas : Canvas(Bitmap.createBitmap(LAYOUT_WIDTH, 1, Bitmap.Config.ARGB_8888)) { - val markers = mutableListOf() - - // Layout draws only the lines inside the clip; report a clip tall enough for every list here. - override fun getClipBounds(bounds: Rect): Boolean { - bounds.set(0, 0, LAYOUT_WIDTH, Int.MAX_VALUE / 2) - return true - } - - override fun drawCircle( - cx: Float, - cy: Float, - radius: Float, - paint: Paint, - ) { - // Bullets are centered on the reserved column edge, matching the iOS drawer. - val outerRadius = radius + paint.strokeWidth / 2f - markers += DrawnMarker(cx - outerRadius, cx, cy) - super.drawCircle(cx, cy, radius, paint) - } - - override fun drawRoundRect( - rect: RectF, - rx: Float, - ry: Float, - paint: Paint, - ) { - val halfStroke = if (paint.style == Paint.Style.STROKE) paint.strokeWidth / 2f else 0f - markers += DrawnMarker(rect.left - halfStroke, rect.right + halfStroke, rect.centerY()) - super.drawRoundRect(rect, rx, ry, paint) - } - - override fun drawText( - text: String, - x: Float, - y: Float, - paint: Paint, - ) { - if (text.matches(Regex("(?:[0-9]+\\.|\\.[0-9]+)"))) markers += DrawnMarker(x, x + paint.measureText(text), y) - super.drawText(text, x, y, paint) - } - } - private fun item(): MarkdownASTNode = listItem(paragraph(text("item"))) private fun numbered(count: Int): MarkdownASTNode = orderedList(*Array(count) { item() }) @@ -274,8 +227,4 @@ class OrderedListMarkerWidthTest { ), ) } - - private companion object { - const val LAYOUT_WIDTH = 2000 - } } diff --git a/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt b/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt new file mode 100644 index 000000000..7383db048 --- /dev/null +++ b/packages/enriched-markdown-android/ui/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt @@ -0,0 +1,101 @@ +package com.swmansion.enriched.markdown.test + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Rect +import android.graphics.RectF +import android.text.Layout +import android.text.Spanned +import android.text.StaticLayout +import android.text.TextDirectionHeuristics +import android.text.TextPaint +import com.swmansion.enriched.markdown.spans.BaseListSpan + +/** A list marker as the layout drew it: a number, a bullet, or a checkbox. */ +data class DrawnMarker( + val left: Float, + val right: Float, + val baseline: Float, +) + +/** A drawn marker with the text edge and list depth of the paragraph it belongs to. */ +data class MarkerGeometry( + val marker: DrawnMarker, + val paragraphLeft: Float, + val depth: Int, +) + +/** Records the list markers a layout draws instead of painting them. */ +class MarkerCanvas : Canvas(Bitmap.createBitmap(LAYOUT_WIDTH, 1, Bitmap.Config.ARGB_8888)) { + val markers = mutableListOf() + + // Layout draws only the lines inside the clip; report one tall enough for every list. + override fun getClipBounds(bounds: Rect): Boolean { + bounds.set(0, 0, LAYOUT_WIDTH, Int.MAX_VALUE / 2) + return true + } + + override fun drawCircle( + cx: Float, + cy: Float, + radius: Float, + paint: Paint, + ) { + // Bullets are centered on the reserved column edge, matching the iOS drawer. + val outerRadius = radius + paint.strokeWidth / 2f + markers += DrawnMarker(cx - outerRadius, cx, cy) + super.drawCircle(cx, cy, radius, paint) + } + + override fun drawRoundRect( + rect: RectF, + rx: Float, + ry: Float, + paint: Paint, + ) { + val halfStroke = if (paint.style == Paint.Style.STROKE) paint.strokeWidth / 2f else 0f + markers += DrawnMarker(rect.left - halfStroke, rect.right + halfStroke, rect.centerY()) + super.drawRoundRect(rect, rx, ry, paint) + } + + override fun drawText( + text: String, + x: Float, + y: Float, + paint: Paint, + ) { + if (text.matches(Regex("(?:[0-9]+\\.|\\.[0-9]+)"))) markers += DrawnMarker(x, x + paint.measureText(text), y) + super.drawText(text, x, y, paint) + } + + companion object { + const val LAYOUT_WIDTH = 2000 + + fun layout( + text: CharSequence, + textSize: Float, + rtl: Boolean = false, + ): StaticLayout = + StaticLayout.Builder + .obtain(text, 0, text.length, TextPaint().apply { this.textSize = textSize }, LAYOUT_WIDTH) + .apply { if (rtl) setTextDirection(TextDirectionHeuristics.RTL) } + .build() + + /** The markers [layout] draws, top to bottom. */ + fun drawMarkers(layout: Layout): List = + MarkerCanvas().also(layout::draw).markers.sortedWith(compareBy({ it.baseline }, { it.left })) + + /** Every marker [layout] draws, with the text edge and depth of its paragraph. */ + fun markerGeometry( + text: Spanned, + layout: Layout, + ): List = + drawMarkers(layout).map { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + val start = layout.getLineStart(line) + val depth = text.getSpans(start, start + 1, BaseListSpan::class.java).maxOf { it.depth } + MarkerGeometry(marker, layout.getParagraphLeft(line).toFloat(), depth) + } + } +} diff --git a/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift b/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/ListRenderingTests.swift similarity index 99% rename from packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift rename to packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/ListRenderingTests.swift index 5c89aa82e..fdc7b11c2 100644 --- a/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/OrderedListMarkerWidthTests.swift +++ b/packages/enriched-markdown-ios/Tests/EnrichedMarkdownTests/ListRenderingTests.swift @@ -2,7 +2,7 @@ import UIKit import XCTest @testable import EnrichedMarkdown -final class OrderedListMarkerWidthTests: XCTestCase { +final class ListRenderingTests: XCTestCase { private var config: MarkdownStyleConfiguration! override func setUp() { diff --git a/packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm b/packages/react-native-enriched-markdown/__tests__/ios/ListRenderingTests.mm similarity index 83% rename from packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm rename to packages/react-native-enriched-markdown/__tests__/ios/ListRenderingTests.mm index 03e42822c..4209fdc80 100644 --- a/packages/react-native-enriched-markdown/__tests__/ios/OrderedListMarkerWidthTests.mm +++ b/packages/react-native-enriched-markdown/__tests__/ios/ListRenderingTests.mm @@ -6,7 +6,7 @@ #import "../../ios/styles/StyleConfig.h" #import -static MarkdownASTNode *ENRMWidthList(NSInteger start, NSUInteger count) +static MarkdownASTNode *ENRMOrderedList(NSInteger start, NSUInteger count) { MarkdownASTNode *list = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeOrderedList]; list.attributes[@"start"] = [@(start) stringValue]; @@ -22,10 +22,10 @@ return list; } -@interface ENRMOrderedListMarkerWidthTests : XCTestCase +@interface ENRMListRenderingTests : XCTestCase @end -@implementation ENRMOrderedListMarkerWidthTests +@implementation ENRMListRenderingTests - (NSArray *)markersForLists:(NSArray *)lists config:(StyleConfig *)config @@ -51,12 +51,12 @@ - (void)testShortListKeepsItsIndentAndLongListsShareTheWidestGutter [config setListStyleGapWidth:11]; CGFloat baseline = [@"99." sizeWithAttributes:@{NSFontAttributeName : config.listMarkerFont}].width; CGFloat shortIndent = MAX(config.listStyleMarkerMinWidth, baseline) + config.effectiveListGapWidth; - NSArray *shortMarkers = [self markersForLists:@[ ENRMWidthList(1, 99) ] config:config]; + NSArray *shortMarkers = [self markersForLists:@[ ENRMOrderedList(1, 99) ] config:config]; for (ENRMListMarkerDescriptor *marker in shortMarkers) { XCTAssertEqualWithAccuracy(marker.indent, shortIndent, 0.01); } for (NSNumber *start in @[ @98, @998, @12345 ]) { - NSArray *markers = [self markersForLists:@[ ENRMWidthList(start.integerValue, 4) ] config:config]; + NSArray *markers = [self markersForLists:@[ ENRMOrderedList(start.integerValue, 4) ] config:config]; CGFloat width = baseline; for (ENRMListMarkerDescriptor *marker in markers) { NSString *label = [NSString stringWithFormat:@"%ld.", (long)marker.number]; @@ -74,9 +74,9 @@ - (void)testNestedAndFollowingListsRestoreTheirOwnGutters [config setListStyleFontSize:16]; [config setListStyleMarginLeft:24]; [config setListStyleGapWidth:11]; - MarkdownASTNode *outer = ENRMWidthList(98, 4); - [outer.children[0] addChild:ENRMWidthList(9998, 4)]; - NSArray *markers = [self markersForLists:@[ outer, ENRMWidthList(1, 1) ] config:config]; + MarkdownASTNode *outer = ENRMOrderedList(98, 4); + [outer.children[0] addChild:ENRMOrderedList(9998, 4)]; + NSArray *markers = [self markersForLists:@[ outer, ENRMOrderedList(1, 1) ] config:config]; CGFloat outerIndent = 0; CGFloat nestedIndent = 0; for (ENRMListMarkerDescriptor *marker in markers) { @@ -99,9 +99,9 @@ - (void)testNestedListsKeepTheSpaceReservedForWideParentMarkers [config setListStyleFontSize:16]; [config setListStyleMarginLeft:24]; [config setListStyleGapWidth:11]; - MarkdownASTNode *outer = ENRMWidthList(123456789, 1); - MarkdownASTNode *middle = ENRMWidthList(1, 1); - [middle.children[0] addChild:ENRMWidthList(1, 1)]; + MarkdownASTNode *outer = ENRMOrderedList(123456789, 1); + MarkdownASTNode *middle = ENRMOrderedList(1, 1); + [middle.children[0] addChild:ENRMOrderedList(1, 1)]; [outer.children[0] addChild:middle]; NSArray *markers = [self markersForLists:@[ outer ] config:config]; ENRMListMarkerDescriptor *parent = markers[0]; @@ -114,7 +114,7 @@ - (void)testNestedListsKeepTheSpaceReservedForWideParentMarkers XCTAssertEqualWithAccuracy(leaf.indent, parent.indent + 2 * config.listStyleMarginLeft, 0.01); } -- (void)testTaskItemsDoNotPassTheOrderedListsExtraWidthToTheirChildren +- (void)testTaskItemsMoveWithTheirWideNumberedSiblings { StyleConfig *config = [[StyleConfig alloc] init]; [config setListStyleFontSize:16]; @@ -122,13 +122,13 @@ - (void)testTaskItemsDoNotPassTheOrderedListsExtraWidthToTheirChildren [config setListStyleGapWidth:11]; NSMutableArray *> *results = [NSMutableArray array]; for (NSNumber *start in @[ @1, @12345 ]) { - MarkdownASTNode *outer = ENRMWidthList(start.integerValue, 3); + MarkdownASTNode *outer = ENRMOrderedList(start.integerValue, 3); MarkdownASTNode *task = outer.children[1]; task.attributes[@"isTask"] = @"true"; - MarkdownASTNode *child = ENRMWidthList(1, 1); + MarkdownASTNode *child = ENRMOrderedList(1, 1); child.type = MarkdownNodeTypeUnorderedList; [task addChild:child]; - [outer.children[2] addChild:ENRMWidthList(1, 1)]; + [outer.children[2] addChild:ENRMOrderedList(1, 1)]; [results addObject:[self markersForLists:@[ outer ] config:config]]; } NSArray *shortMarkers = results[0]; @@ -140,11 +140,10 @@ - (void)testTaskItemsDoNotPassTheOrderedListsExtraWidthToTheirChildren XCTAssertTrue(task.isTask); XCTAssertEqual(child.depth, 1); XCTAssertEqual(child.listType, ListTypeUnordered); - XCTAssertEqualWithAccuracy(task.indent, [shortMarkers[1] indent], 0.01); - CGFloat bulletIndent = - [config effectiveListMarginLeftForBullet] + config.effectiveListGapWidth + config.listStyleMarginLeft; - XCTAssertEqualWithAccuracy(child.indent, bulletIndent, 0.01); - XCTAssertEqualWithAccuracy(child.indent, [shortMarkers[2] indent], 0.01); + CGFloat shift = [wideMarkers[0] indent] - [shortMarkers[0] indent]; + XCTAssertGreaterThan(shift, 0); + XCTAssertEqualWithAccuracy(task.indent, [shortMarkers[1] indent] + shift, 0.01); + XCTAssertEqualWithAccuracy(child.indent, [shortMarkers[2] indent] + shift, 0.01); ENRMListMarkerDescriptor *numericChild = wideMarkers[4]; ENRMListMarkerDescriptor *numericParent = wideMarkers[3]; XCTAssertEqualWithAccuracy(numericChild.indent, numericParent.indent + config.listStyleMarginLeft, 0.01); @@ -170,7 +169,7 @@ - (void)testMarkerMinimumWidthRemainsAFloor { StyleConfig *config = [[StyleConfig alloc] init]; [config setListStyleMarkerMinWidth:200]; - NSArray *markers = [self markersForLists:@[ ENRMWidthList(998, 4) ] config:config]; + NSArray *markers = [self markersForLists:@[ ENRMOrderedList(998, 4) ] config:config]; for (ENRMListMarkerDescriptor *marker in markers) { XCTAssertEqualWithAccuracy(marker.indent, 200 + config.effectiveListGapWidth, 0.01); } diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/ListRenderingTest.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/ListRenderingTest.kt new file mode 100644 index 000000000..c10a5a307 --- /dev/null +++ b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/ListRenderingTest.kt @@ -0,0 +1,270 @@ +package com.swmansion.enriched.markdown + +import android.graphics.Typeface +import android.text.SpannableString +import android.text.TextPaint +import com.swmansion.enriched.markdown.parser.MarkdownASTNode +import com.swmansion.enriched.markdown.spans.BaseListSpan +import com.swmansion.enriched.markdown.spans.ListMarkerAnchorSpan +import com.swmansion.enriched.markdown.spans.OrderedListSpan +import com.swmansion.enriched.markdown.styles.StyleConfig +import com.swmansion.enriched.markdown.test.MarkdownRenderTestSupport.render +import com.swmansion.enriched.markdown.test.MarkdownRenderTestSupport.styleConfig +import com.swmansion.enriched.markdown.test.MarkerCanvas +import com.swmansion.enriched.markdown.test.MarkerGeometry +import com.swmansion.enriched.markdown.test.TestAstFactory.listItem +import com.swmansion.enriched.markdown.test.TestAstFactory.orderedList +import com.swmansion.enriched.markdown.test.TestAstFactory.paragraph +import com.swmansion.enriched.markdown.test.TestAstFactory.taskListItem +import com.swmansion.enriched.markdown.test.TestAstFactory.text +import com.swmansion.enriched.markdown.test.TestAstFactory.unorderedList +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import kotlin.math.ceil + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [30]) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class ListRenderingTest { + @Test + fun shortListsKeepTheirIndentAndLongListsShareTheirWidestGutter() { + val style = listStyle() + val paint = + TextPaint().apply { + textSize = style.listStyle.fontSize + typeface = Typeface.create("monospace", Typeface.NORMAL) + } + val baseline = paint.measureText("99.") + val gap = style.listStyle.gapWidth + val short = orderedSpans(style, numbered(1, 99)) + short.forEach { assertEquals((baseline + gap).toInt(), it.getLeadingMargin(false)) } + for ((start, count) in listOf(1 to 250, 98 to 4, 998 to 4, 12345 to 4, 0 to 101)) { + val spans = orderedSpans(style, numbered(start, count)) + val widest = maxOf(baseline, spans.maxOf { paint.measureText("${it.itemNumber}.") }) + spans.forEach { assertEquals((baseline + ceil(widest - baseline) + gap).toInt(), it.getLeadingMargin(false)) } + assertTrue(spans.first().getLeadingMargin(false) > short.first().getLeadingMargin(false)) + } + } + + @Test + fun nestedAndFollowingListsRestoreTheirOwnGutters() { + val style = listStyle() + val spans = orderedSpans(style, withChild(numbered(98, 4), 0, numbered(9998, 4)), numbered(1, 1)) + val parent = spans.filter { it.depth == 0 && it.itemNumber != 1 } + assertEquals(4, parent.size) + parent.forEach { assertEquals(parent.first().getLeadingMargin(false), it.getLeadingMargin(false)) } + spans.filter { it.depth == 1 }.forEach { assertTrue(it.getLeadingMargin(false) > style.listStyle.marginLeft) } + val following = spans.single { it.depth == 0 && it.itemNumber == 1 } + assertTrue(following.getLeadingMargin(false) < parent.first().getLeadingMargin(false)) + } + + @Test + fun markerMinimumWidthRemainsAFloor() { + val style = listStyle(minWidth = 200.0) + orderedSpans(style, numbered(998, 4)).forEach { + assertEquals((style.listStyle.markerMinWidth + style.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) + } + } + + @Test + fun drawnMarkersStayInsideTheGutterAndAttachedToTheirParagraphs() { + val style = listStyle() + for (start in listOf(1, 98, 9998)) { + val threeLevels = withChild(numbered(1, 1), 0, numbered(1, 1)) + assertDrawnMarkerPositions(style, withChild(numbered(start, 4), 2, threeLevels)) + } + } + + @Test + fun nestedBulletColumnsKeepTheirGapUnderWideParents() { + val style = listStyle() + + fun tree(start: Int) = withChild(numbered(start, 4), 2, unorderedList(item(), item())) + for (start in listOf(98, 9998)) { + assertNestedMarkerGapsUnchanged(style, tree(1), tree(start)) + } + } + + @Test + fun tasksMoveWithTheirWideNumberedSiblings() { + val style = listStyle() + + fun tree(start: Int): MarkdownASTNode { + val items = numbered(start, 3).children.toMutableList() + items[1] = taskListItem(checked = false, paragraph(text("item")), numbered(1, 1)) + items[2] = listItem(paragraph(text("item")), numbered(1, 1)) + return orderedList(*items.toTypedArray(), start = start) + } + assertEveryRowShiftsTogether(style, tree(1), tree(12345)) + } + + @Test + fun nestedTasksKeepTheirGapUnderWideNumericParents() { + val style = listStyle() + + fun tree(start: Int) = withChild(numbered(start, 4), 2, orderedList(taskListItem(checked = false, paragraph(text("item"))))) + for (start in listOf(98, 9998)) { + assertNestedMarkerGapsUnchanged(style, tree(1), tree(start)) + } + } + + @Test + fun sameTypeBulletAndTaskNestsKeepTheirMarkerGap() { + val style = listStyle() + val bullet = unorderedList(item()) + val task = orderedList(taskListItem(checked = false, paragraph(text("item")))) + for (parent in listOf(bullet, task)) { + assertDrawnMarkerPositions(style, withChild(parent, 0, parent)) + } + } + + @Test + fun shortMixedNestsKeepTheirOriginalTextIndents() { + val style = styleConfig(list = mapOf("gapWidth" to 6.0), taskList = mapOf("checkboxSize" to 14.0)) + val ordered = numbered(1, 1) + val bullet = unorderedList(item()) + val task = orderedList(taskListItem(checked = false, paragraph(text("item")))) + val shapes = listOf(ordered to bullet, bullet to ordered, bullet to task, ordered to task, task to bullet) + val baseIndents = listOf(52f, 33f, 33f, 52f, 44f) + for ((index, shape) in shapes.withIndex()) { + val (parent, child) = shape + val nested = drawMarkers(style, withChild(parent, 0, child)).single { it.depth == 1 } + assertEquals("base mixed indent for shape $index", baseIndents[index], nested.paragraphLeft, 0.01f) + assertTrue(nested.marker.left >= 0f) + } + } + + @Test + fun markersAnchoredOnANestedListKeepTheirAncestorsOffset() { + val style = listStyle() + // The middle item opens with its sublist, so its marker is drawn by an anchor span. + val middle = orderedList(listItem(numbered(1, 1)), start = 1) + val text = SpannableString(render(style, withChild(numbered(12345, 1), 0, middle))) + assertEquals(1, text.getSpans(0, text.length, ListMarkerAnchorSpan::class.java).size) + val markers = MarkerCanvas.drawMarkers(MarkerCanvas.layout(text, style.listStyle.fontSize)) + assertEquals(3, markers.size) + val (root, anchored, leaf) = markers.sortedBy { it.right } + assertEquals(root.right + style.listStyle.marginLeft, anchored.right, 0.01f) + assertEquals(anchored.right + style.listStyle.marginLeft, leaf.right, 0.01f) + assertTrue(markers.all { it.left >= 0f }) + } + + @Test + fun inheritedMarkerOffsetsFollowTheRtlDirection() { + val style = listStyle() + val text = SpannableString(render(style, withChild(numbered(12345, 1), 0, numbered(1, 1)))) + val layout = MarkerCanvas.layout(text, style.listStyle.fontSize, rtl = true) + val markers = MarkerCanvas.drawMarkers(layout) + assertEquals(2, markers.size) + markers.forEach { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + assertEquals(-1, layout.getParagraphDirection(line)) + assertEquals(layout.getParagraphRight(line) + style.listStyle.gapWidth, marker.left, 0.01f) + assertTrue(marker.right <= layout.width) + } + } + + private fun assertDrawnMarkerPositions( + style: StyleConfig, + vararg lists: MarkdownASTNode, + ) { + drawMarkers(style, *lists).forEach { geometry -> + assertEquals( + "marker right at depth ${geometry.depth}", + geometry.paragraphLeft - style.listStyle.gapWidth, + geometry.marker.right, + 0.01f, + ) + } + } + + /** The rows [wide] shares with [short], tasks and their children included, all sit [wide]'s widening further right. */ + private fun assertEveryRowShiftsTogether( + style: StyleConfig, + short: MarkdownASTNode, + wide: MarkdownASTNode, + ) { + val shortRows = drawMarkers(style, short) + val wideRows = drawMarkers(style, wide).take(shortRows.size) + assertEquals(shortRows.size, wideRows.size) + val shift = wideRows.first().paragraphLeft - shortRows.first().paragraphLeft + assertTrue(shift > 0f) + wideRows.zip(shortRows).forEach { (actual, control) -> + assertEquals(control.depth, actual.depth) + assertEquals("text shift at depth ${actual.depth}", shift, actual.paragraphLeft - control.paragraphLeft, 0.01f) + assertEquals( + "marker gap at depth ${actual.depth}", + control.paragraphLeft - control.marker.right, + actual.paragraphLeft - actual.marker.right, + 0.01f, + ) + } + } + + private fun assertNestedMarkerGapsUnchanged( + style: StyleConfig, + short: MarkdownASTNode, + wide: MarkdownASTNode, + ) { + val shortMarkers = drawMarkers(style, short).filter { it.depth > 0 } + val wideMarkers = drawMarkers(style, wide).filter { it.depth > 0 } + assertTrue(shortMarkers.isNotEmpty()) + assertEquals(shortMarkers.size, wideMarkers.size) + shortMarkers.zip(wideMarkers).forEach { (control, actual) -> + assertEquals(control.depth, actual.depth) + assertEquals( + "nested marker gap at depth ${actual.depth}", + control.paragraphLeft - control.marker.right, + actual.paragraphLeft - actual.marker.right, + 0.01f, + ) + } + } + + private fun drawMarkers( + style: StyleConfig, + vararg lists: MarkdownASTNode, + ): List { + // SpannableString reports spans in insertion order, as the text view does. + val text = SpannableString(render(style, *lists)) + val geometry = MarkerCanvas.markerGeometry(text, MarkerCanvas.layout(text, style.listStyle.fontSize)) + assertEquals(text.getSpans(0, text.length, BaseListSpan::class.java).count { it.drawsMarker }, geometry.size) + geometry.forEach { assertTrue("marker left ${it.marker.left} at depth ${it.depth}", it.marker.left >= 0f) } + return geometry + } + + private fun orderedSpans( + style: StyleConfig, + vararg lists: MarkdownASTNode, + ): List { + val text = render(style, *lists) + return text + .getSpans(0, text.length, OrderedListSpan::class.java) + .sortedWith(compareBy({ text.getSpanStart(it) }, { it.depth })) + } + + private fun item(): MarkdownASTNode = listItem(paragraph(text("item"))) + + private fun numbered( + start: Int, + count: Int, + ): MarkdownASTNode = orderedList(*Array(count) { item() }, start = start) + + private fun withChild( + list: MarkdownASTNode, + index: Int, + child: MarkdownASTNode, + ): MarkdownASTNode { + val items = list.children.toMutableList() + items[index] = items[index].copy(children = items[index].children + child) + return list.copy(children = items) + } + + private fun listStyle(minWidth: Double = 0.0): StyleConfig = + styleConfig(list = mapOf("fontFamily" to "monospace", "markerMinWidth" to minWidth)) +} diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/TaskListInteractionTest.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/TaskListInteractionTest.kt new file mode 100644 index 000000000..64a70db33 --- /dev/null +++ b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/TaskListInteractionTest.kt @@ -0,0 +1,102 @@ +package com.swmansion.enriched.markdown + +import android.text.Spanned +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView +import com.swmansion.enriched.markdown.parser.MarkdownASTNode +import com.swmansion.enriched.markdown.spans.BaseListSpan +import com.swmansion.enriched.markdown.spans.ListMarkerAnchorSpan +import com.swmansion.enriched.markdown.spans.TaskListSpan +import com.swmansion.enriched.markdown.test.DrawnMarker +import com.swmansion.enriched.markdown.test.MarkdownRenderTestSupport.render +import com.swmansion.enriched.markdown.test.MarkdownRenderTestSupport.styleConfig +import com.swmansion.enriched.markdown.test.MarkerCanvas +import com.swmansion.enriched.markdown.test.TestAstFactory.listItem +import com.swmansion.enriched.markdown.test.TestAstFactory.orderedList +import com.swmansion.enriched.markdown.test.TestAstFactory.paragraph +import com.swmansion.enriched.markdown.test.TestAstFactory.taskListItem +import com.swmansion.enriched.markdown.test.TestAstFactory.text +import com.swmansion.enriched.markdown.test.TestAstFactory.unorderedList +import com.swmansion.enriched.markdown.utils.text.interaction.TaskListTapUtils +import com.swmansion.enriched.markdown.utils.text.view.setupAsMarkdownTextView +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [30]) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +class TaskListInteractionTest { + private val context = RuntimeEnvironment.getApplication() + + @Test + fun togglingATaskUnderAWideParentKeepsEveryMarginAndMarkerPosition() { + assertTaskToggleKeepsGeometry(opensWithSublist = false) + } + + @Test + fun togglingAnAnchoredTaskUnderAWideParentKeepsEveryMarginAndMarkerPosition() { + assertTaskToggleKeepsGeometry(opensWithSublist = true) + } + + // Layout draws leading margins in span insertion order, so a toggle that re-adds only the + // task's span would move its checkbox by its ancestors' margins. + private fun assertTaskToggleKeepsGeometry(opensWithSublist: Boolean) { + val style = styleConfig(list = mapOf("fontFamily" to "monospace")) + val taskChildren = if (opensWithSublist) arrayOf(numbered(1)) else arrayOf(paragraph(text("item")), numbered(1)) + val task = taskListItem(checked = false, *taskChildren) + val tree = orderedList(listItem(paragraph(text("item")), unorderedList(task)), item(), start = 100) + val textView = + object : AccessibleMarkdownTextView(context) {}.apply { + layoutParams = ViewGroup.LayoutParams(MarkerCanvas.LAYOUT_WIDTH, ViewGroup.LayoutParams.WRAP_CONTENT) + setupAsMarkdownTextView() + } + textView.setText(render(style, tree), TextView.BufferType.SPANNABLE) + val initialText = textView.text as Spanned + val taskIndex = initialText.getSpans(0, initialText.length, TaskListSpan::class.java).single().taskIndex + assertEquals(if (opensWithSublist) 1 else 0, initialText.getSpans(0, initialText.length, ListMarkerAnchorSpan::class.java).size) + val initialMargins = listMargins(initialText) + val initialMarkers = drawTextViewMarkers(textView) + assertEquals(4, initialMarkers.size) + + for (checked in listOf(true, false)) { + assertTrue(TaskListTapUtils.updateTaskListItemCheckedState(textView, taskIndex, checked, style)) + val text = textView.text as Spanned + val tasks = text.getSpans(0, text.length, TaskListSpan::class.java) + assertTrue(tasks.isNotEmpty()) + tasks.forEach { assertEquals(checked, it.isChecked) } + text.getSpans(0, text.length, ListMarkerAnchorSpan::class.java).forEach { + assertEquals(checked, (it.marker as TaskListSpan).isChecked) + } + assertEquals("list margins after checked=$checked", initialMargins, listMargins(text)) + assertEquals("drawn markers after checked=$checked", initialMarkers, drawTextViewMarkers(textView)) + } + } + + private fun listMargins(text: Spanned): List> = + text + .getSpans(0, text.length, BaseListSpan::class.java) + .sortedWith(compareBy({ text.getSpanStart(it) }, { it.depth }, { text.getSpanEnd(it) })) + .map { listOf(text.getSpanStart(it), text.getSpanEnd(it), it.depth, it.getLeadingMargin(true), it.getLeadingMargin(false)) } + + private fun drawTextViewMarkers(textView: TextView): List { + textView.forceLayout() + textView.measure( + View.MeasureSpec.makeMeasureSpec(MarkerCanvas.LAYOUT_WIDTH, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + ) + textView.layout(0, 0, textView.measuredWidth, textView.measuredHeight) + return MarkerCanvas.drawMarkers(textView.layout) + } + + private fun item(): MarkdownASTNode = listItem(paragraph(text("item"))) + + private fun numbered(count: Int): MarkdownASTNode = orderedList(*Array(count) { item() }, start = 1) +} diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt deleted file mode 100644 index 4e3f62ef6..000000000 --- a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/spans/OrderedListMarkerWidthTest.kt +++ /dev/null @@ -1,530 +0,0 @@ -package com.swmansion.enriched.markdown.spans - -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.Paint -import android.graphics.Typeface -import android.text.SpannableString -import android.text.Spanned -import android.text.StaticLayout -import android.text.TextPaint -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import com.facebook.react.bridge.JavaOnlyArray -import com.facebook.react.bridge.JavaOnlyMap -import com.facebook.react.uimanager.DisplayMetricsHolder -import com.swmansion.enriched.markdown.accessibility.AccessibleMarkdownTextView -import com.swmansion.enriched.markdown.parser.MarkdownASTNode -import com.swmansion.enriched.markdown.parser.MarkdownASTNode.NodeType -import com.swmansion.enriched.markdown.renderer.Renderer -import com.swmansion.enriched.markdown.styles.StyleConfig -import com.swmansion.enriched.markdown.utils.text.interaction.TaskListTapUtils -import com.swmansion.enriched.markdown.utils.text.view.setupAsMarkdownTextView -import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.RuntimeEnvironment -import org.robolectric.annotation.Config -import org.robolectric.annotation.GraphicsMode - -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [30]) -@GraphicsMode(GraphicsMode.Mode.NATIVE) -class OrderedListMarkerWidthTest { - private val context = RuntimeEnvironment.getApplication() - - @Test - fun shortListsKeepTheirIndentAndLongListsShareTheirWidestGutter() { - val config = styleConfig() - val paint = - TextPaint().apply { - textSize = config.listStyle.fontSize - typeface = Typeface.create("monospace", Typeface.NORMAL) - } - val baseline = paint.measureText("99.") - val short = render(config, list(1, 99)) - short.forEach { assertEquals((baseline + config.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) } - for ((start, count) in listOf(1 to 250, 98 to 4, 998 to 4, 12345 to 4, 0 to 101)) { - val spans = render(config, list(start, count)) - val widest = maxOf(baseline, spans.maxOf { paint.measureText("${it.itemNumber}.") }) - spans.forEach { assertEquals((widest + config.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) } - assertTrue(spans.first().getLeadingMargin(false) > short.first().getLeadingMargin(false)) - } - } - - @Test - fun nestedAndFollowingListsRestoreTheirOwnGutters() { - val config = styleConfig() - val outer = list(98, 4) - val first = outer.children.first() - val nested = outer.copy(children = listOf(first.copy(children = first.children + list(9998, 4))) + outer.children.drop(1)) - val spans = render(config, nested, list(1, 1)) - val parent = spans.filter { it.depth == 0 && it.itemNumber != 1 } - assertEquals(4, parent.size) - parent.forEach { assertEquals(parent.first().getLeadingMargin(false), it.getLeadingMargin(false)) } - spans.filter { it.depth == 1 }.forEach { assertTrue(it.getLeadingMargin(false) > config.listStyle.marginLeft) } - val following = spans.single { it.depth == 0 && it.itemNumber == 1 } - assertTrue(following.getLeadingMargin(false) < parent.first().getLeadingMargin(false)) - } - - @Test - fun markerMinimumWidthRemainsAFloor() { - val config = styleConfig(200.0) - render(config, list(998, 4)).forEach { - assertEquals((config.listStyle.markerMinWidth + config.listStyle.gapWidth).toInt(), it.getLeadingMargin(false)) - } - } - - @Test - fun drawnMarkersStayInsideTheGutterAndAttachedToTheirParagraphs() { - for (start in listOf(1, 98, 9998)) { - val config = styleConfig() - val outer = list(start, 4) - val parent = outer.children[2] - val middle = list(1, 1) - val child = middle.children[0] - val threeLevels = middle.copy(children = listOf(child.copy(children = child.children + list(1, 1)))) - val nested = - outer.copy( - children = - outer.children.take(2) + parent.copy(children = parent.children + threeLevels) + outer.children.drop(3), - ) - assertDrawnMarkerPositions(config, nested) - } - } - - @Test - fun nestedBulletColumnsKeepTheirGapUnderWideParents() { - val config = styleConfig() - - fun tree(start: Int): MarkdownASTNode { - val outer = list(start, 4) - val parent = outer.children[2] - val bullets = list(1, 2).copy(type = NodeType.UnorderedList) - return outer.copy( - children = outer.children.take(2) + parent.copy(children = parent.children + bullets) + outer.children.drop(3), - ) - } - for (start in listOf(98, 9998)) { - assertNestedMarkerGapsUnchanged(config, tree(1), tree(start)) - } - } - - @Test - fun tasksDoNotPassTheWideListsNumericExtraToTheirChildren() { - val config = styleConfig() - - fun tree(start: Int): MarkdownASTNode { - val outer = list(start, 3) - val task = outer.children[1] - val taskWithChild = task.copy(attributes = mapOf("isTask" to "true"), children = task.children + list(1, 1)) - val numeric = outer.children[2] - val numericWithChild = numeric.copy(children = numeric.children + list(1, 1)) - return outer.copy(children = listOf(outer.children[0], taskWithChild, numericWithChild)) - } - assertNestedMarkerGapsUnchanged(config, tree(1), tree(12345)) - } - - @Test - fun nestedTasksKeepTheirGapUnderWideNumericParents() { - val config = styleConfig() - - fun tree(start: Int): MarkdownASTNode { - val outer = list(start, 4) - val parent = outer.children[2] - val nested = list(1, 1) - val task = nested.children[0].copy(attributes = mapOf("isTask" to "true")) - val taskList = nested.copy(children = listOf(task)) - return outer.copy( - children = outer.children.take(2) + parent.copy(children = parent.children + taskList) + outer.children.drop(3), - ) - } - for (start in listOf(98, 9998)) { - assertNestedMarkerGapsUnchanged(config, tree(1), tree(start)) - } - } - - @Test - fun togglingATaskUnderAWideParentKeepsEveryMarginAndMarkerPosition() { - assertTaskToggleKeepsGeometry(opensWithSublist = false) - } - - @Test - fun togglingAnAnchoredTaskUnderAWideParentKeepsEveryMarginAndMarkerPosition() { - assertTaskToggleKeepsGeometry(opensWithSublist = true) - } - - @Test - fun sameTypeBulletAndTaskNestsKeepTheirMarkerGap() { - val config = styleConfig() - val ordered = list(1, 1) - val bullet = ordered.copy(type = NodeType.UnorderedList) - val task = ordered.copy(children = listOf(ordered.children[0].copy(attributes = mapOf("isTask" to "true")))) - for (parent in listOf(bullet, task)) { - val item = parent.children[0] - assertDrawnMarkerPositions(config, parent.copy(children = listOf(item.copy(children = item.children + parent)))) - } - } - - @Test - fun shortMixedNestsKeepTheirOriginalTextIndents() { - val config = styleConfig(fontFamily = "", gapWidth = 6.0, checkboxSize = 14.0) - val ordered = list(1, 1) - val bullet = ordered.copy(type = NodeType.UnorderedList) - val task = ordered.copy(children = listOf(ordered.children[0].copy(attributes = mapOf("isTask" to "true")))) - val shapes = listOf(ordered to bullet, bullet to ordered, bullet to task, ordered to task, task to bullet) - val baseIndents = listOf(52f, 33f, 33f, 52f, 44f) - for ((index, shape) in shapes.withIndex()) { - val (parent, child) = shape - val tree = parent.copy(children = listOf(parent.children[0].copy(children = parent.children[0].children + child))) - val nested = drawMarkers(config, tree).single { it.depth == 1 } - assertEquals("base mixed indent for shape $index", baseIndents[index], nested.paragraphLeft, 0.01f) - assertTrue(nested.marker.left >= 0f) - } - } - - @Test - fun markersAnchoredOnANestedListKeepTheirAncestorsOffset() { - val config = styleConfig() - val outer = list(12345, 1) - val middle = list(1, 1) - val openingSublist = middle.children[0].copy(children = listOf(list(1, 1))) - val renderer = Renderer() - renderer.configure(config, context) - val nested = - outer.copy( - children = - listOf( - outer.children[0].copy( - children = - outer.children[0].children + middle.copy(children = listOf(openingSublist)), - ), - ), - ) - val text = SpannableString(renderer.renderContent(listOf(nested))) - assertEquals(1, text.getSpans(0, text.length, ListMarkerAnchorSpan::class.java).size) - val layout = StaticLayout.Builder.obtain(text, 0, text.length, TextPaint(), 2000).build() - val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) - layout.draw(canvas) - assertEquals(3, canvas.markers.size) - val markersByColumn = canvas.markers.sortedBy { it.right } - val root = markersByColumn[0] - val anchored = markersByColumn[1] - val leaf = markersByColumn[2] - assertEquals(root.right + config.listStyle.marginLeft, anchored.right, 0.01f) - assertEquals(anchored.right + config.listStyle.marginLeft, leaf.right, 0.01f) - assertTrue(canvas.markers.all { it.left >= 0f }) - } - - @Test - fun inheritedMarkerOffsetsFollowTheRtlDirection() { - val config = styleConfig() - val outer = list(12345, 1) - val renderer = Renderer() - renderer.configure(config, context) - val nested = outer.copy(children = listOf(outer.children[0].copy(children = outer.children[0].children + list(1, 1)))) - val text = SpannableString(renderer.renderContent(listOf(nested))) - val layout = - StaticLayout.Builder - .obtain(text, 0, text.length, TextPaint(), 2000) - .setTextDirection(android.text.TextDirectionHeuristics.RTL) - .build() - val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) - layout.draw(canvas) - assertEquals(2, canvas.markers.size) - canvas.markers.forEach { marker -> - val line = layout.getLineForVertical(marker.baseline.toInt()) - assertEquals(-1, layout.getParagraphDirection(line)) - assertEquals(layout.getParagraphRight(line) + config.listStyle.gapWidth, marker.left, 0.01f) - assertTrue(marker.right <= layout.width) - } - } - - private fun assertTaskToggleKeepsGeometry(opensWithSublist: Boolean) { - val config = styleConfig() - val outer = list(100, 2) - val nested = list(1, 1).copy(type = NodeType.UnorderedList) - val taskItem = nested.children.single() - val taskChildren = if (opensWithSublist) listOf(list(1, 1)) else taskItem.children + list(1, 1) - val task = taskItem.copy(attributes = mapOf("isTask" to "true"), children = taskChildren) - val parent = outer.children.first() - val tree = - outer.copy( - children = - listOf(parent.copy(children = parent.children + nested.copy(children = listOf(task)))) + outer.children.drop(1), - ) - val renderer = Renderer() - renderer.configure(config, context) - val textView = - object : AccessibleMarkdownTextView(context) {}.apply { - layoutParams = ViewGroup.LayoutParams(2000, ViewGroup.LayoutParams.WRAP_CONTENT) - setupAsMarkdownTextView() - } - textView.setText(renderer.renderContent(listOf(tree)), TextView.BufferType.SPANNABLE) - val initialText = textView.text as Spanned - val taskIndex = initialText.getSpans(0, initialText.length, TaskListSpan::class.java).single().taskIndex - assertEquals(if (opensWithSublist) 1 else 0, initialText.getSpans(0, initialText.length, ListMarkerAnchorSpan::class.java).size) - val initialMargins = listMargins(initialText) - val initialMarkers = drawTextViewMarkers(textView) - assertEquals(4, initialMarkers.size) - - for (checked in listOf(true, false)) { - assertTrue(TaskListTapUtils.updateTaskListItemCheckedState(textView, taskIndex, checked, config)) - val text = textView.text as Spanned - val tasks = text.getSpans(0, text.length, TaskListSpan::class.java) - assertTrue(tasks.isNotEmpty()) - tasks.forEach { assertEquals(checked, it.isChecked) } - text.getSpans(0, text.length, ListMarkerAnchorSpan::class.java).forEach { - assertEquals(checked, (it.marker as TaskListSpan).isChecked) - } - assertEquals("list margins after checked=$checked", initialMargins, listMargins(text)) - assertEquals("drawn markers after checked=$checked", initialMarkers, drawTextViewMarkers(textView)) - } - } - - private fun listMargins(text: Spanned): List> = - text - .getSpans(0, text.length, BaseListSpan::class.java) - .sortedWith(compareBy({ text.getSpanStart(it) }, { it.depth }, { text.getSpanEnd(it) })) - .map { listOf(text.getSpanStart(it), text.getSpanEnd(it), it.depth, it.getLeadingMargin(true), it.getLeadingMargin(false)) } - - private fun drawTextViewMarkers(textView: TextView): List { - textView.forceLayout() - textView.measure( - View.MeasureSpec.makeMeasureSpec(2000, View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), - ) - textView.layout(0, 0, textView.measuredWidth, textView.measuredHeight) - val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) - textView.layout.draw(canvas) - return canvas.markers.sortedWith(compareBy({ it.baseline }, { it.left })) - } - - private fun assertDrawnMarkerPositions( - config: StyleConfig, - vararg lists: MarkdownASTNode, - ) { - drawMarkers(config, *lists).forEach { geometry -> - assertEquals( - "marker right at depth ${geometry.depth}", - geometry.paragraphLeft - config.listStyle.gapWidth, - geometry.marker.right, - 0.01f, - ) - } - } - - private fun assertNestedMarkerGapsUnchanged( - config: StyleConfig, - short: MarkdownASTNode, - wide: MarkdownASTNode, - ) { - val shortMarkers = drawMarkers(config, short).filter { it.depth > 0 } - val wideMarkers = drawMarkers(config, wide).filter { it.depth > 0 } - assertTrue(shortMarkers.isNotEmpty()) - assertEquals(shortMarkers.size, wideMarkers.size) - shortMarkers.zip(wideMarkers).forEach { (control, actual) -> - assertEquals(control.depth, actual.depth) - assertEquals( - "nested marker gap at depth ${actual.depth}", - control.paragraphLeft - control.marker.right, - actual.paragraphLeft - actual.marker.right, - 0.01f, - ) - } - } - - private fun drawMarkers( - config: StyleConfig, - vararg lists: MarkdownASTNode, - ): List { - val renderer = Renderer() - renderer.configure(config, context) - // The view exposes spans in insertion order, as SpannableString does. - val text = SpannableString(renderer.renderContent(lists.toList())) - val paint = TextPaint().apply { textSize = config.listStyle.fontSize } - val layout = StaticLayout.Builder.obtain(text, 0, text.length, paint, 2000).build() - val canvas = MarkerCanvas(Bitmap.createBitmap(2000, 2000, Bitmap.Config.ARGB_8888)) - layout.draw(canvas) - assertEquals(text.getSpans(0, text.length, BaseListSpan::class.java).count { it.drawsMarker }, canvas.markers.size) - return canvas.markers.map { marker -> - val line = layout.getLineForVertical(marker.baseline.toInt()) - assertTrue("marker left ${marker.left} on line $line", marker.left >= 0f) - val start = layout.getLineStart(line) - val depth = text.getSpans(start, start + 1, BaseListSpan::class.java).maxOf { it.depth } - MarkerGeometry(marker, layout.getParagraphLeft(line).toFloat(), depth) - } - } - - private data class MarkerGeometry( - val marker: DrawnMarker, - val paragraphLeft: Float, - val depth: Int, - ) - - private data class DrawnMarker( - val left: Float, - val right: Float, - val baseline: Float, - ) - - private class MarkerCanvas( - bitmap: Bitmap, - ) : Canvas(bitmap) { - val markers = mutableListOf() - - override fun drawCircle( - cx: Float, - cy: Float, - radius: Float, - paint: Paint, - ) { - // Bullets are centered on the reserved column edge, matching the iOS drawer. - val outerRadius = radius + paint.strokeWidth / 2f - markers += DrawnMarker(cx - outerRadius, cx, cy) - super.drawCircle(cx, cy, radius, paint) - } - - override fun drawRoundRect( - rect: android.graphics.RectF, - rx: Float, - ry: Float, - paint: Paint, - ) { - val halfStroke = if (paint.style == Paint.Style.STROKE) paint.strokeWidth / 2f else 0f - markers += DrawnMarker(rect.left - halfStroke, rect.right + halfStroke, rect.centerY()) - super.drawRoundRect(rect, rx, ry, paint) - } - - override fun drawText( - text: String, - x: Float, - y: Float, - paint: Paint, - ) { - if (text.matches(Regex("(?:[0-9]+\\.|\\.[0-9]+)"))) markers += DrawnMarker(x, x + paint.measureText(text), y) - super.drawText(text, x, y, paint) - } - } - - private fun render( - config: StyleConfig, - vararg lists: MarkdownASTNode, - ): List { - val renderer = Renderer() - renderer.configure(config, context) - val text = renderer.renderContent(lists.toList()) - return text.getSpans(0, text.length, OrderedListSpan::class.java).toList() - } - - private fun list( - start: Int, - count: Int, - ) = MarkdownASTNode( - NodeType.OrderedList, - attributes = mapOf("start" to start.toString()), - children = - List(count) { - MarkdownASTNode( - NodeType.ListItem, - children = listOf(MarkdownASTNode(NodeType.Paragraph, children = listOf(MarkdownASTNode(NodeType.Text, "item")))), - ) - }, - ) - - private fun styleConfig( - minWidth: Double = 0.0, - fontFamily: String = "monospace", - gapWidth: Double = 8.0, - checkboxSize: Double = 16.0, - ): StyleConfig { - DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) - - fun element() = - JavaOnlyMap.of( - "fontFamily", - "", - "fontWeight", - "normal", - "fontSize", - 16.0, - "lineHeight", - 0.0, - "marginTop", - 0.0, - "marginBottom", - 0.0, - "color", - Color.BLACK, - "backgroundColor", - Color.TRANSPARENT, - "borderColor", - Color.TRANSPARENT, - "underline", - false, - "fontScale", - 0.8, - "baselineOffsetScale", - 0.5, - ) - - val style = JavaOnlyMap() - listOf("paragraph", "strong", "em", "strikethrough", "code", "superscript", "subscript", "highlight") - .forEach { style.putMap(it, element()) } - style.putMap("link", element().apply { putString("fontFamily", "serif") }) - style.putArray( - "linkVariants", - JavaOnlyArray.of( - element().apply { - putString("pattern", "^ref:") - putString("fontFamily", "monospace") - putInt("color", Color.BLUE) - }, - ), - ) - style.putMap( - "spoiler", - element().apply { - putMap("particles", JavaOnlyMap.of("density", 0.5, "speed", 1.0)) - putMap("solid", JavaOnlyMap.of("borderRadius", 0.0)) - }, - ) - style.putMap( - "taskList", - JavaOnlyMap.of( - "checkedColor", - Color.BLACK, - "borderColor", - Color.BLACK, - "checkmarkColor", - Color.BLACK, - "checkedTextColor", - Color.BLACK, - "checkboxSize", - checkboxSize, - "checkboxBorderRadius", - 0.0, - "checkedStrikethrough", - false, - ), - ) - style.putMap( - "list", - element().apply { - putString("fontFamily", fontFamily) - putInt("bulletColor", Color.BLACK) - putInt("markerColor", Color.BLACK) - putDouble("bulletSize", 6.0) - putDouble("markerMinWidth", minWidth) - putDouble("gapWidth", gapWidth) - putDouble("marginLeft", 24.0) - putDouble("itemSpacing", 0.0) - }, - ) - return StyleConfig(style, context, false, 0f) - } -} diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt new file mode 100644 index 000000000..7383db048 --- /dev/null +++ b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/ListMarkerCanvas.kt @@ -0,0 +1,101 @@ +package com.swmansion.enriched.markdown.test + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Rect +import android.graphics.RectF +import android.text.Layout +import android.text.Spanned +import android.text.StaticLayout +import android.text.TextDirectionHeuristics +import android.text.TextPaint +import com.swmansion.enriched.markdown.spans.BaseListSpan + +/** A list marker as the layout drew it: a number, a bullet, or a checkbox. */ +data class DrawnMarker( + val left: Float, + val right: Float, + val baseline: Float, +) + +/** A drawn marker with the text edge and list depth of the paragraph it belongs to. */ +data class MarkerGeometry( + val marker: DrawnMarker, + val paragraphLeft: Float, + val depth: Int, +) + +/** Records the list markers a layout draws instead of painting them. */ +class MarkerCanvas : Canvas(Bitmap.createBitmap(LAYOUT_WIDTH, 1, Bitmap.Config.ARGB_8888)) { + val markers = mutableListOf() + + // Layout draws only the lines inside the clip; report one tall enough for every list. + override fun getClipBounds(bounds: Rect): Boolean { + bounds.set(0, 0, LAYOUT_WIDTH, Int.MAX_VALUE / 2) + return true + } + + override fun drawCircle( + cx: Float, + cy: Float, + radius: Float, + paint: Paint, + ) { + // Bullets are centered on the reserved column edge, matching the iOS drawer. + val outerRadius = radius + paint.strokeWidth / 2f + markers += DrawnMarker(cx - outerRadius, cx, cy) + super.drawCircle(cx, cy, radius, paint) + } + + override fun drawRoundRect( + rect: RectF, + rx: Float, + ry: Float, + paint: Paint, + ) { + val halfStroke = if (paint.style == Paint.Style.STROKE) paint.strokeWidth / 2f else 0f + markers += DrawnMarker(rect.left - halfStroke, rect.right + halfStroke, rect.centerY()) + super.drawRoundRect(rect, rx, ry, paint) + } + + override fun drawText( + text: String, + x: Float, + y: Float, + paint: Paint, + ) { + if (text.matches(Regex("(?:[0-9]+\\.|\\.[0-9]+)"))) markers += DrawnMarker(x, x + paint.measureText(text), y) + super.drawText(text, x, y, paint) + } + + companion object { + const val LAYOUT_WIDTH = 2000 + + fun layout( + text: CharSequence, + textSize: Float, + rtl: Boolean = false, + ): StaticLayout = + StaticLayout.Builder + .obtain(text, 0, text.length, TextPaint().apply { this.textSize = textSize }, LAYOUT_WIDTH) + .apply { if (rtl) setTextDirection(TextDirectionHeuristics.RTL) } + .build() + + /** The markers [layout] draws, top to bottom. */ + fun drawMarkers(layout: Layout): List = + MarkerCanvas().also(layout::draw).markers.sortedWith(compareBy({ it.baseline }, { it.left })) + + /** Every marker [layout] draws, with the text edge and depth of its paragraph. */ + fun markerGeometry( + text: Spanned, + layout: Layout, + ): List = + drawMarkers(layout).map { marker -> + val line = layout.getLineForVertical(marker.baseline.toInt()) + val start = layout.getLineStart(line) + val depth = text.getSpans(start, start + 1, BaseListSpan::class.java).maxOf { it.depth } + MarkerGeometry(marker, layout.getParagraphLeft(line).toFloat(), depth) + } + } +} diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt new file mode 100644 index 000000000..645ce339d --- /dev/null +++ b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/MarkdownRenderTestSupport.kt @@ -0,0 +1,126 @@ +package com.swmansion.enriched.markdown.test + +import android.content.Context +import android.graphics.Color +import android.text.Spannable +import com.facebook.react.bridge.JavaOnlyArray +import com.facebook.react.bridge.JavaOnlyMap +import com.facebook.react.uimanager.DisplayMetricsHolder +import com.swmansion.enriched.markdown.parser.MarkdownASTNode +import com.swmansion.enriched.markdown.renderer.Renderer +import com.swmansion.enriched.markdown.styles.StyleConfig +import org.robolectric.RuntimeEnvironment + +object MarkdownRenderTestSupport { + // Resolved per call, not cached: a @Config qualifier applies to the current test's context. + private val context: Context + get() = RuntimeEnvironment.getApplication() + + fun render( + style: StyleConfig, + vararg blocks: MarkdownASTNode, + ): Spannable { + val renderer = Renderer() + renderer.configure(style, context) + return renderer.renderContent(blocks.toList()) + } + + /** + * The style map the JS side sends, with [list] and [taskList] entries replacing the defaults. + * Sizes are Double, colors Int, as in a ReadableMap. + */ + fun styleConfig( + list: Map = emptyMap(), + taskList: Map = emptyMap(), + ): StyleConfig { + DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context) + val style = JavaOnlyMap() + listOf("paragraph", "strong", "em", "strikethrough", "code", "superscript", "subscript", "highlight") + .forEach { style.putMap(it, textElement()) } + style.putMap("link", textElement().apply { putString("fontFamily", "serif") }) + style.putArray( + "linkVariants", + JavaOnlyArray.of( + textElement().apply { + putString("pattern", "^ref:") + putString("fontFamily", "monospace") + putInt("color", Color.BLUE) + }, + ), + ) + style.putMap( + "spoiler", + textElement().apply { + putMap("particles", JavaOnlyMap.of("density", 0.5, "speed", 1.0)) + putMap("solid", JavaOnlyMap.of("borderRadius", 0.0)) + }, + ) + style.putMap("taskList", JavaOnlyMap().apply { putAll(defaultTaskList + taskList) }) + style.putMap("list", textElement().apply { putAll(defaultList + list) }) + return StyleConfig(style, context, false, 0f) + } + + private val defaultList: Map = + mapOf( + "fontFamily" to "", + "bulletColor" to Color.BLACK, + "markerColor" to Color.BLACK, + "bulletSize" to 6.0, + "markerMinWidth" to 0.0, + "gapWidth" to 8.0, + "marginLeft" to 24.0, + "itemSpacing" to 0.0, + ) + + private val defaultTaskList: Map = + mapOf( + "checkedColor" to Color.BLACK, + "borderColor" to Color.BLACK, + "checkmarkColor" to Color.BLACK, + "checkedTextColor" to Color.BLACK, + "checkboxSize" to 16.0, + "checkboxBorderRadius" to 0.0, + "checkedStrikethrough" to false, + ) + + private fun textElement(): JavaOnlyMap = + JavaOnlyMap.of( + "fontFamily", + "", + "fontWeight", + "normal", + "fontSize", + 16.0, + "lineHeight", + 0.0, + "marginTop", + 0.0, + "marginBottom", + 0.0, + "color", + Color.BLACK, + "backgroundColor", + Color.TRANSPARENT, + "borderColor", + Color.TRANSPARENT, + "underline", + false, + "fontScale", + 0.8, + "baselineOffsetScale", + 0.5, + ) + + private fun JavaOnlyMap.putAll(values: Map) { + for ((key, value) in values) { + when (value) { + is String -> putString(key, value) + is Boolean -> putBoolean(key, value) + is Int -> putInt(key, value) + is Double -> putDouble(key, value) + is Float -> putDouble(key, value.toDouble()) + else -> error("Unsupported style value for $key: $value") + } + } + } +} diff --git a/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/TestAstFactory.kt b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/TestAstFactory.kt new file mode 100644 index 000000000..1808c3414 --- /dev/null +++ b/packages/react-native-enriched-markdown/android/src/test/java/com/swmansion/enriched/markdown/test/TestAstFactory.kt @@ -0,0 +1,36 @@ +package com.swmansion.enriched.markdown.test + +import com.swmansion.enriched.markdown.parser.MarkdownASTNode +import com.swmansion.enriched.markdown.parser.MarkdownASTNode.NodeType + +object TestAstFactory { + fun paragraph(vararg children: MarkdownASTNode): MarkdownASTNode = MarkdownASTNode(NodeType.Paragraph, children = children.toList()) + + fun text(content: String): MarkdownASTNode = MarkdownASTNode(NodeType.Text, content = content) + + /** An ordered list; [start] is the first number, as md4c reports it. */ + fun orderedList( + vararg items: MarkdownASTNode, + start: Int? = null, + ): MarkdownASTNode = + MarkdownASTNode( + type = NodeType.OrderedList, + attributes = start?.let { mapOf("start" to it.toString()) }.orEmpty(), + children = items.toList(), + ) + + fun unorderedList(vararg items: MarkdownASTNode): MarkdownASTNode = MarkdownASTNode(NodeType.UnorderedList, children = items.toList()) + + fun listItem(vararg children: MarkdownASTNode): MarkdownASTNode = MarkdownASTNode(NodeType.ListItem, children = children.toList()) + + /** A GFM task-list item, what md4c produces for `- [ ]` / `- [x]`. */ + fun taskListItem( + checked: Boolean, + vararg children: MarkdownASTNode, + ): MarkdownASTNode = + MarkdownASTNode( + type = NodeType.ListItem, + attributes = mapOf("isTask" to "true", "taskChecked" to checked.toString()), + children = children.toList(), + ) +}