diff --git a/.changeset/fix-single-tilde-strikethrough.md b/.changeset/fix-single-tilde-strikethrough.md new file mode 100644 index 0000000..e9a0a5d --- /dev/null +++ b/.changeset/fix-single-tilde-strikethrough.md @@ -0,0 +1,6 @@ +--- +"@silicajs/core": patch +"@silicajs/assistant": patch +--- + +Disable GFM single-tilde strikethrough so `~text~` is not crossed out, matching Obsidian syntax. diff --git a/packages/assistant/src/ui/message.tsx b/packages/assistant/src/ui/message.tsx index 23be91e..28a4b76 100644 --- a/packages/assistant/src/ui/message.tsx +++ b/packages/assistant/src/ui/message.tsx @@ -43,7 +43,7 @@ export function AssistantMessage({ message, onRetry }: AssistantMessageProps) { {message.content ? (
{
+ const result = await renderMarkdown(
+ "~~crossed out~~ and ~not crossed~",
+ testContext("index", ["index"]),
+ );
+
+ const html = renderToStaticMarkup(<>{result.content}>);
+
+ expect(html).toContain("crossed out");
+ expect(html).toContain("~not crossed~");
+ expect(html).not.toContain("not crossed");
+ }, 15_000);
+
it("sanitizes raw HTML and escapes OFM-injected labels", async () => {
const result = await renderMarkdown(
'[[
]]\n\n\n\n
\n\nRaw heading
\n\nUser heading
',
diff --git a/packages/core/src/pipeline/index.ts b/packages/core/src/pipeline/index.ts
index 2f5368d..80adb5f 100644
--- a/packages/core/src/pipeline/index.ts
+++ b/packages/core/src/pipeline/index.ts
@@ -37,6 +37,9 @@ import {
rehypeUnwrapSilicaEmbeds,
} from "./plugins.js";
+/** Obsidian strikethrough uses `~~text~~`; single tildes are subscript, not delete. */
+const remarkGfmOptions = { singleTilde: false } as const;
+
type MdastNode = {
type: string;
value?: string;
@@ -367,7 +370,7 @@ function baseProcessor(context: RenderContext) {
return unified()
.use(remarkParse)
.use(remarkFrontmatter, ["yaml"])
- .use(remarkGfm)
+ .use(remarkGfm, remarkGfmOptions)
.use(remarkMath)
.use(remarkObsidian, { inlineTags: context.tags?.inline ?? true })
.use(remarkSilicaObsidian, context)
@@ -381,7 +384,7 @@ async function runRemarkObsidian(markdown: string, context: RenderContext) {
const processor = unified()
.use(remarkParse)
.use(remarkFrontmatter, ["yaml"])
- .use(remarkGfm)
+ .use(remarkGfm, remarkGfmOptions)
.use(remarkMath)
.use(remarkObsidian, { inlineTags: context.tags?.inline ?? true })
.use(remarkSilicaObsidian, context);
@@ -413,7 +416,7 @@ function parsePlainTextMarkdown(markdown: string): MdastNode {
return unified()
.use(remarkParse)
.use(remarkFrontmatter, ["yaml"])
- .use(remarkGfm)
+ .use(remarkGfm, remarkGfmOptions)
.use(remarkMath)
.use(remarkObsidian)
.parse(markdown) as MdastNode;