perf(chat): memoize inline LaTeX and match bare URLs once (#1316) (#1342)

This commit is contained in:
m57 authored and GitHub committed 2026-09-28 00:49:17 +03:00
1 parent 4fc4d097cc
commit 18953e368b
2 files changed
+53 -33

No files matched your search

@@ -68,6 +68,9 @@ object MarkdownInlineStyler {
val src = text val src = text
while (i < src.length) { while (i < src.length) {
// Cheap prefix gate: URL_PATTERN only matches at "http(s)://", so skip the regex elsewhere.
val urlMatch =
if (src.startsWith("http", i, ignoreCase = true)) URL_PATTERN.matchAt(src, i) else null
when { when {
// Inline code is opaque to emphasis parsing, and delimiters must match by run length. // Inline code is opaque to emphasis parsing, and delimiters must match by run length.
src[i] == '`' -> { src[i] == '`' -> {
@@ -312,9 +315,8 @@ object MarkdownInlineStyler {
} }
// bare URL // bare URL
URL_PATTERN.matchAt(src, i) != null -> { urlMatch != null -> {
val match = URL_PATTERN.matchAt(src, i)!! val url = urlMatch.value
val url = match.value
val urlToAppend = if (isRtl) BidiUtils.wrapLtrIsolate(url) else url val urlToAppend = if (isRtl) BidiUtils.wrapLtrIsolate(url) else url
pushLink(LinkAnnotation.Url(url)) pushLink(LinkAnnotation.Url(url))
withStyle( withStyle(
@@ -326,7 +328,7 @@ object MarkdownInlineStyler {
append(urlToAppend) append(urlToAppend)
} }
pop() pop()
i = match.range.last + 1 i = urlMatch.range.last + 1
} }
// Plain text / words in RTL // Plain text / words in RTL
@@ -66,38 +66,56 @@ fun MarkdownInlineText(
} }
val config = val config =
LatexConfig( remember(style.fontSize, textColor) {
fontSize = style.fontSize, LatexConfig(
theme = LatexTheme.light(color = textColor, backgroundColor = Color.Transparent), fontSize = style.fontSize,
accessibilityEnabled = true, theme = LatexTheme.light(color = textColor, backgroundColor = Color.Transparent),
) accessibilityEnabled = true,
val inlineContent = mutableMapOf<String, InlineTextContent>() )
segments.forEachIndexed { index, segment ->
if (segment is InlineMathSegment.Math) {
latexMeasurer.inlineContent(segment.latex, config)?.let { inlineContent["latex-$index"] = it }
} }
} val inlineContent =
val annotated = remember(segments, latexMeasurer, config) {
buildAnnotatedString { val map = mutableMapOf<String, InlineTextContent>()
segments.forEachIndexed { index, segment -> segments.forEachIndexed { index, segment ->
when (segment) { if (segment is InlineMathSegment.Math) {
is InlineMathSegment.Math -> { latexMeasurer.inlineContent(segment.latex, config)?.let { map["latex-$index"] = it }
val id = "latex-$index" }
if (id in inlineContent) appendInlineContent(id, segment.latex) else append(segment.latex) }
} map
}
val annotated =
remember(
segments,
inlineContent,
textColor,
searchQuery,
isCurrentMatch,
linkColor,
highlights,
isRtl,
) {
buildAnnotatedString {
segments.forEachIndexed { index, segment ->
when (segment) {
is InlineMathSegment.Math -> {
val id = "latex-$index"
val measured = id in inlineContent
if (measured) appendInlineContent(id, segment.latex) else append(segment.latex)
}
is InlineMathSegment.Text -> { is InlineMathSegment.Text -> {
append( append(
MarkdownInlineStyler.parseInlineSource( MarkdownInlineStyler.parseInlineSource(
text = segment.value, text = segment.value,
textColor = textColor, textColor = textColor,
searchQuery = searchQuery, searchQuery = searchQuery,
isCurrentMatch = isCurrentMatch, isCurrentMatch = isCurrentMatch,
linkColor = linkColor, linkColor = linkColor,
highlights = highlights, highlights = highlights,
isRtl = isRtl, isRtl = isRtl,
), ),
) )
}
} }
} }
} }