fix(export): rendered inline markdown in list items
- Parsed nested marked text tokens through the inline parser. - Added browser-template regression coverage for ordered, unordered, and nested lists. Fixes #5567
This commit is contained in:
@@ -114,6 +114,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
"marked": "catalog:",
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@huggingface/transformers": "catalog:",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- Fixed Bash internal URLs remaining unresolved when used as unquoted arguments inside command substitutions ([#5535](https://github.com/can1357/oh-my-pi/issues/5535)).
|
||||
- Fixed the built-in `fd` printing `fd: Broken pipe (os error 32)` when a downstream pipeline reader exited early (e.g. `fd … | head`); it now exits silently with 141 (128+SIGPIPE), matching real fd.
|
||||
- Fixed prewalk repeatedly continuing after a bash-only task such as `commit` had already completed ([#5551](https://github.com/can1357/oh-my-pi/issues/5551)).
|
||||
- Fixed `/share` and `/export` web views rendering inline Markdown inside list items as literal text ([#5567](https://github.com/can1357/oh-my-pi/issues/5567)).
|
||||
|
||||
## [16.5.2] - 2026-07-14
|
||||
|
||||
|
||||
@@ -92,7 +92,8 @@
|
||||
"sherpa-onnx-node": "1.13.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:"
|
||||
"@types/bun": "catalog:",
|
||||
"marked": "catalog:"
|
||||
},
|
||||
"engines": {
|
||||
"bun": ">=1.3.14"
|
||||
|
||||
@@ -1386,7 +1386,7 @@
|
||||
},
|
||||
// Text content: escape HTML tags
|
||||
text(token) {
|
||||
return escapeHtmlTags(escapeHtml(token.text));
|
||||
return token.tokens ? this.parser.parseInline(token.tokens) : escapeHtmlTags(escapeHtml(token.text));
|
||||
},
|
||||
// Inline code: escape HTML
|
||||
codespan(token) {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import * as vm from "node:vm";
|
||||
import { parseHTML } from "linkedom";
|
||||
import { Marked } from "marked";
|
||||
|
||||
const [templateHtml, templateJs] = await Promise.all([
|
||||
Bun.file(new URL("../src/export/html/template.html", import.meta.url)).text(),
|
||||
Bun.file(new URL("../src/export/html/template.js", import.meta.url)).text(),
|
||||
]);
|
||||
|
||||
function renderMarkdown(source: string): Element {
|
||||
const { document, window } = parseHTML(templateHtml);
|
||||
const session = {
|
||||
header: {
|
||||
type: "session",
|
||||
version: 3,
|
||||
id: "markdown-test",
|
||||
timestamp: "2026-01-01T00:00:00.000Z",
|
||||
cwd: "/tmp",
|
||||
},
|
||||
entries: [
|
||||
{
|
||||
type: "message",
|
||||
id: "message-1",
|
||||
parentId: null,
|
||||
timestamp: "2026-01-01T00:00:00.000Z",
|
||||
message: {
|
||||
role: "user",
|
||||
content: source,
|
||||
timestamp: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
leafId: "message-1",
|
||||
};
|
||||
|
||||
const sessionData = document.getElementById("session-data");
|
||||
if (!sessionData) throw new Error("Export template is missing session data");
|
||||
sessionData.textContent = Buffer.from(JSON.stringify(session)).toBase64();
|
||||
Object.defineProperty(window, "location", {
|
||||
value: new URL("https://example.test/export.html"),
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(window, "matchMedia", {
|
||||
value: () => ({ matches: false, addEventListener() {}, removeEventListener() {} }),
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
const context = vm.createContext({
|
||||
window,
|
||||
document,
|
||||
marked: new Marked(),
|
||||
hljs: {
|
||||
getLanguage: () => false,
|
||||
highlight: () => ({ value: "" }),
|
||||
highlightAuto: () => ({ value: "" }),
|
||||
},
|
||||
URL,
|
||||
URLSearchParams,
|
||||
TextDecoder,
|
||||
Uint8Array,
|
||||
atob,
|
||||
navigator: { clipboard: null },
|
||||
localStorage: { getItem: () => null, setItem() {} },
|
||||
setTimeout: () => 0,
|
||||
clearTimeout() {},
|
||||
});
|
||||
vm.runInContext(templateJs, context);
|
||||
|
||||
const rendered = document.querySelector(".markdown-content");
|
||||
if (!rendered) throw new Error("Export viewer did not render Markdown content");
|
||||
return rendered;
|
||||
}
|
||||
|
||||
describe("HTML export Markdown", () => {
|
||||
test("renders inline Markdown in ordered, unordered, and nested list items", () => {
|
||||
const rendered = renderMarkdown("**outside**\n\n- **bold** and *italic* and `code`\n 1. **nested**");
|
||||
|
||||
expect(rendered.querySelector("p strong")?.textContent).toBe("outside");
|
||||
expect(rendered.querySelector("ul > li > strong")?.textContent).toBe("bold");
|
||||
expect(rendered.querySelector("ul > li > em")?.textContent).toBe("italic");
|
||||
expect(rendered.querySelector("ul > li > code")?.textContent).toBe("code");
|
||||
expect(rendered.querySelector("ol > li > strong")?.textContent).toBe("nested");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user