| |
| |
| |
| |
| |
| |
| |
| import { describe, it, expect } from "vitest"; |
| import { renderArticleHTML, type PublishMeta } from "../src/publisher/html-renderer.js"; |
| import type { PublishCSS } from "../src/publisher/index.js"; |
| import { detectShikiLang } from "../src/shared/detect-lang.js"; |
|
|
| const EMPTY_CSS: PublishCSS = { |
| variables: "", |
| reset: "", |
| base: "", |
| layout: "", |
| print: "", |
| editorTokens: "", |
| article: "", |
| components: "", |
| publisher: "", |
| }; |
|
|
| const META: PublishMeta = { |
| title: "Code Article", |
| description: "code highlighting", |
| authors: [{ name: "Alice", affiliationIndices: [1], affiliationNames: ["MIT"] }], |
| affiliations: [{ name: "MIT" }], |
| date: "2025-01-01", |
| }; |
|
|
| const PY = `import torch |
| from transformers import AutoModelForCausalLM, AutoTokenizer |
| |
| def load(name): |
| return AutoModelForCausalLM.from_pretrained(name)`; |
|
|
| describe("detectShikiLang", () => { |
| it("detects python from a typical snippet", () => { |
| expect(detectShikiLang(PY)).toBe("python"); |
| }); |
|
|
| it("returns empty for trivially short input", () => { |
| expect(detectShikiLang("x")).toBe(""); |
| }); |
| }); |
|
|
| describe("publisher highlights language-less code blocks", () => { |
| it("colors a code block that has no language attribute", async () => { |
| const json = { |
| type: "doc", |
| content: [ |
| |
| { type: "codeBlock", content: [{ type: "text", text: PY }] }, |
| ], |
| }; |
| const html = await renderArticleHTML(json as any, META, EMPTY_CSS); |
|
|
| |
| expect(html).toContain('data-lang="python"'); |
| expect(html).toContain("--shiki-light:"); |
| }); |
| }); |
|
|