Move comment preview text into lib

The regex-heavy markdown stripping was untested in the component.
This commit is contained in:
Rūdolfs Ošiņš
2026-10-01 18:20:24 +02:00
parent a15a20393c
commit f6a23e0b0f
3 changed files with 49 additions and 22 deletions
+2 -22
View File
@@ -5,6 +5,7 @@
import type { Thread } from "@bindings/cob/thread/Thread";
import type { Resolution } from "@app/lib/commentResolutions";
import { plainText } from "@app/lib/markdownPlain";
import type { CommentAnchor } from "@app/lib/pierreComments";
import { anchorOf, formatAnchorLines } from "@app/lib/pierreComments";
import {
@@ -51,30 +52,9 @@
return author.alias ?? truncateId(authorKey(author));
}
/// Inline markdown, dropped down to the words it decorates. A row is a couple
/// of truncated lines, and on a narrow column the punctuation crowds out the
/// text that says what the comment is about. Deliberately shallow — this is a
/// preview, not a parser; the comment itself is one click away in the diff.
function plain(body: string): string {
return (
body
.replace(/!?\[([^\]]*)\]\([^)]*\)/gu, "$1")
.replace(/`/gu, "")
.replace(/~~(.+?)~~/gu, "$1")
// Emphasis only where a marker sits on a word boundary, so `snake_case`,
// `MAX_SIZE` and `_private` survive being read as italics.
.replace(/(^|[^\w])[*_]{1,2}([^*_]+?)[*_]{1,2}(?=[^\w]|$)/gu, "$1$2")
.replace(/^\s{0,3}#{1,6}\s+/gmu, "")
.replace(/^\s{0,3}>\s?/gmu, "")
.replace(/^\s{0,3}(?:[-+*]|\d+\.)\s+/gmu, "")
.replace(/\s+/gu, " ")
.trim()
);
}
/// The last edit is the current text.
function preview(comment: Comment<CodeLocation>): string {
return plain(comment.edits.at(-1)?.body ?? "");
return plainText(comment.edits.at(-1)?.body ?? "");
}
</script>
+20
View File
@@ -0,0 +1,20 @@
/// Inline markdown, dropped down to the words it decorates. A row is a couple
/// of truncated lines, and on a narrow column the punctuation crowds out the
/// text that says what the comment is about. Deliberately shallow — this is a
/// preview, not a parser; the comment itself is one click away in the diff.
export function plainText(body: string): string {
return (
body
.replace(/!?\[([^\]]*)\]\([^)]*\)/gu, "$1")
.replace(/`/gu, "")
.replace(/~~(.+?)~~/gu, "$1")
// Emphasis only where a marker sits on a word boundary, so `snake_case`,
// `MAX_SIZE` and `_private` survive being read as italics.
.replace(/(^|[^\w])[*_]{1,2}([^*_]+?)[*_]{1,2}(?=[^\w]|$)/gu, "$1$2")
.replace(/^\s{0,3}#{1,6}\s+/gmu, "")
.replace(/^\s{0,3}>\s?/gmu, "")
.replace(/^\s{0,3}(?:[-+*]|\d+\.)\s+/gmu, "")
.replace(/\s+/gu, " ")
.trim()
);
}
+27
View File
@@ -0,0 +1,27 @@
import { expect, test } from "vitest";
import { plainText } from "@app/lib/markdownPlain";
test.each([
["[the docs](https://example.com)", "the docs"],
["![diagram](a.png) here", "diagram here"],
["run `npm test` now", "run npm test now"],
["~~old~~ new", "old new"],
["**bold** and _italic_", "bold and italic"],
["__strong__ and *em*", "strong and em"],
["# Heading", "Heading"],
["### Deep heading", "Deep heading"],
["> quoted\n> text", "quoted text"],
["- one\n* two\n+ three\n1. four", "one two three four"],
["line one\n\n line two", "line one line two"],
[" padded ", "padded"],
])("%j reads as %j", (markdown, expected) => {
expect(plainText(markdown)).toBe(expected);
});
test.each(["snake_case_name", "MAX_SIZE", "_private", "a*b*c"])(
"leaves %j alone",
text => {
expect(plainText(text)).toBe(text);
},
);