@@ -72,6 +72,9 @@ import androidx.compose.ui.text.font.FontFamily
72import androidx.compose.ui.unit.dp
72import androidx.compose.ui.unit.dp
73import kotlinx.coroutines.flow.conflate
73import kotlinx.coroutines.flow.conflate
74import kotlinx.coroutines.delay
74import kotlinx.coroutines.delay
75+import com.mikepenz.markdown.annotator.AnnotatorSettings
76+import com.mikepenz.markdown.annotator.DefaultAnnotatorSettings
77+import com.mikepenz.markdown.annotator.buildMarkdownAnnotatedString
75import com.mikepenz.markdown.compose.LocalMarkdownAnnotator
78import com.mikepenz.markdown.compose.LocalMarkdownAnnotator
76import com.mikepenz.markdown.compose.LocalMarkdownColors
79import com.mikepenz.markdown.compose.LocalMarkdownColors
77import com.mikepenz.markdown.compose.LocalMarkdownTypography
80import com.mikepenz.markdown.compose.LocalMarkdownTypography
@@ -80,7 +83,7 @@ import com.mikepenz.markdown.compose.components.markdownComponents
80import com.mikepenz.markdown.compose.elements.MarkdownText as LibraryMarkdownText
83import com.mikepenz.markdown.compose.elements.MarkdownText as LibraryMarkdownText
81import com.mikepenz.markdown.m3.Markdown
84import com.mikepenz.markdown.m3.Markdown
82import com.mikepenz.markdown.model.DefaultMarkdownAnnotator
85import com.mikepenz.markdown.model.DefaultMarkdownAnnotator
83−import com.mikepenz.markdown.utils.buildMarkdownAnnotatedString
86+import com.mikepenz.markdown.model.DefaultMarkdownAnnotatorConfig
84import org.intellij.markdown.MarkdownElementTypes
87import org.intellij.markdown.MarkdownElementTypes
85import org.intellij.markdown.ast.ASTNode
88import org.intellij.markdown.ast.ASTNode
86import org.intellij.markdown.ast.getTextInNode
89import org.intellij.markdown.ast.getTextInNode
@@ -217,7 +220,7 @@ private fun MarkdownBody(
217 // rather than extracted to a helper to keep this file under detekt's TooManyFunctions threshold.
220 // rather than extracted to a helper to keep this file under detekt's TooManyFunctions threshold.
218 val inlineCodeAnnotator = remember(baseAnnotator, inlineCodeTypography, inlineCodeColors) {
221 val inlineCodeAnnotator = remember(baseAnnotator, inlineCodeTypography, inlineCodeColors) {
219 val codeStyle = inlineCodeTypography.inlineCode.copy(
222 val codeStyle = inlineCodeTypography.inlineCode.copy(
220− color = inlineCodeColors.inlineCodeText,
223+ color = inlineCodeTypography.inlineCode.color,
221 background = inlineCodeColors.inlineCodeBackground,
224 background = inlineCodeColors.inlineCodeBackground,
222 ).toSpanStyle()
225 ).toSpanStyle()
223 DefaultMarkdownAnnotator(
226 DefaultMarkdownAnnotator(
@@ -247,6 +250,7 @@ private fun MarkdownBody(
247 baseAnnotator.annotate?.invoke(this, content, node) ?: false
250 baseAnnotator.annotate?.invoke(this, content, node) ?: false
253+ config = DefaultMarkdownAnnotatorConfig(),
252 // Compose the inline-code tagger with the search-highlight wrapper when a query is active.
256 // Compose the inline-code tagger with the search-highlight wrapper when a query is active.
@@ -271,6 +275,7 @@ private fun MarkdownBody(
278+ config = DefaultMarkdownAnnotatorConfig(),
@@ -317,12 +322,12 @@ private fun MarkdownBody(
317 // interrupting on every token; the reader hears the reply grow in measured chunks.
322 // interrupting on every token; the reader hears the reply grow in measured chunks.
318 CompositionLocalProvider(
323 CompositionLocalProvider(
319 LocalUriHandler provides safeUriHandler,
324 LocalUriHandler provides safeUriHandler,
320− LocalMarkdownAnnotator provides effectiveAnnotator,
322 Markdown(
326 Markdown(
323 content = renderedContent,
327 content = renderedContent,
324 modifier = modifier.semantics { liveRegion = LiveRegionMode.Polite },
328 modifier = modifier.semantics { liveRegion = LiveRegionMode.Polite },
325 components = components,
329 components = components,
330+ annotator = effectiveAnnotator,
328 // A blinking caret at the end of a streaming reply gives a "live" typewriter feel.
333 // A blinking caret at the end of a streaming reply gives a "live" typewriter feel.
@@ -336,12 +341,12 @@ private fun MarkdownBody(
336 content = markdown,
341 content = markdown,
337 modifier = modifier.semantics { liveRegion = LiveRegionMode.Polite },
342 modifier = modifier.semantics { liveRegion = LiveRegionMode.Polite },
338 components = components,
343 components = components,
344+ annotator = effectiveAnnotator,
342 CompositionLocalProvider(
348 CompositionLocalProvider(
343 LocalUriHandler provides safeUriHandler,
349 LocalUriHandler provides safeUriHandler,
344− LocalMarkdownAnnotator provides effectiveAnnotator,
346 content()
351 content()
@@ -465,12 +470,20 @@ private fun ParagraphWithInlineCodeCopy(model: MarkdownComponentModel) {
465 val context = LocalContext.current
470 val context = LocalContext.current
466 val haptics = LocalHapticFeedback.current
471 val haptics = LocalHapticFeedback.current
467 val style = model.typography.paragraph
472 val style = model.typography.paragraph
468− // buildMarkdownAnnotatedString is @Composable (it reads LocalMarkdownAnnotator to run the
473+ val typography = LocalMarkdownTypography.current
474+ val annotator = LocalMarkdownAnnotator.current
475+ // buildMarkdownAnnotatedString needs an explicit AnnotatorSettings in 0.43+ (the old
476+ // overload that read LocalMarkdownAnnotator internally was removed). Build one from the
469− // inline-code tagger installed in MarkdownBody), so the annotated string can't be built in
477+ // current composition locals so the inline-code tagger installed in MarkdownBody still
470− // a `remember` block. The library's own MarkdownParagraph does the same.
478+ // runs. The library's own MarkdownParagraph does the same.
479+ val settings = DefaultAnnotatorSettings(
480+ linkTextSpanStyle = typography.textLink,
481+ codeSpanStyle = typography.inlineCode.toSpanStyle(),
482+ annotator = annotator,
471 val styledText = buildAnnotatedString {
484 val styledText = buildAnnotatedString {
472 pushStyle(style.toSpanStyle())
485 pushStyle(style.toSpanStyle())
473− buildMarkdownAnnotatedString(model.content, model.node)
486+ buildMarkdownAnnotatedString(model.content, model.node, settings)
476 // Capture the layout result so a long-press position can be mapped to a character offset,
489 // Capture the layout result so a long-press position can be mapped to a character offset,
@@ -478,7 +491,7 @@ private fun ParagraphWithInlineCodeCopy(model: MarkdownComponentModel) {
478 var layoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }
491 var layoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }
479 LibraryMarkdownText(
492 LibraryMarkdownText(
480 content = styledText,
493 content = styledText,
481− style = style,
494+ node = model.node,
482 modifier = Modifier.pointerInput(styledText) {
495 modifier = Modifier.pointerInput(styledText) {
483 detectTapGestures(
496 detectTapGestures(
484 onLongPress = { pos ->
497 onLongPress = { pos ->
@@ -493,7 +506,8 @@ private fun ParagraphWithInlineCodeCopy(model: MarkdownComponentModel) {
496− onTextLayout = { layoutResult = it },
510+ onTextLayout = { result, _ -> layoutResult = result },