mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 02:52:27 +08:00
195 lines
7.7 KiB
TypeScript
195 lines
7.7 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { trimIndentation } from "../../../spec/support/utils.js";
|
|
import markdownService from "./markdown.js";
|
|
|
|
describe("markdown", () => {
|
|
it("rewrites language of known language tags", () => {
|
|
const conversionTable = {
|
|
"nginx": "language-text-x-nginx-conf",
|
|
"diff": "language-text-x-diff",
|
|
"javascript": "language-application-javascript-env-backend",
|
|
"css": "language-text-css",
|
|
"mips": "language-text-x-asm-mips"
|
|
};
|
|
|
|
for (const [ input, output ] of Object.entries(conversionTable)) {
|
|
const result = markdownService.renderToHtml(trimIndentation`\
|
|
\`\`\`${input}
|
|
Hi
|
|
\`\`\`
|
|
`, "title");
|
|
expect(result).toBe(trimIndentation`\
|
|
<pre><code class="${output}">Hi</code></pre>`);
|
|
}
|
|
});
|
|
|
|
it("rewrites language of unknown language tags", () => {
|
|
const result = markdownService.renderToHtml(trimIndentation`\
|
|
\`\`\`unknownlanguage
|
|
Hi
|
|
\`\`\`
|
|
`, "title");
|
|
expect(result).toBe(trimIndentation`\
|
|
<pre><code class="language-text-x-trilium-auto">Hi</code></pre>`);
|
|
});
|
|
|
|
it("converts h1 heading", () => {
|
|
const result = markdownService.renderToHtml(trimIndentation`\
|
|
# Hello
|
|
## world
|
|
# another one
|
|
Hello, world
|
|
`, "title");
|
|
expect(result).toBe(`<h2>Hello</h2><h2>world</h2><h2>another one</h2><p>Hello, world</p>`);
|
|
});
|
|
|
|
it("parses duplicate title with escape correctly", () => {
|
|
const result = markdownService.renderToHtml(trimIndentation`\
|
|
# What's new
|
|
Hi there
|
|
`, "What's new")
|
|
expect(result).toBe(`<p>Hi there</p>`);
|
|
});
|
|
|
|
it("trims unnecessary whitespace", () => {
|
|
const input = `\
|
|
## Heading 1
|
|
|
|
Title
|
|
|
|
\`\`\`
|
|
code block 1
|
|
second line 2
|
|
\`\`\`
|
|
|
|
* Hello
|
|
* world
|
|
|
|
1. Hello
|
|
2. World
|
|
`;
|
|
const expected = `\
|
|
<h2>Heading 1</h2><p>Title</p><pre><code class="language-text-x-trilium-auto">code block 1
|
|
second line 2</code></pre><ul><li>Hello</li><li>world</li></ul><ol><li>Hello</li><li>World</li></ol>`;
|
|
expect(markdownService.renderToHtml(input, "Troubleshooting")).toBe(expected);
|
|
});
|
|
|
|
it("imports admonitions properly", () => {
|
|
const space = " "; // editor config trimming space.
|
|
const input = trimIndentation`\
|
|
Before
|
|
|
|
> [!NOTE]
|
|
> This is a note.
|
|
|
|
> [!TIP]
|
|
> This is a tip.
|
|
|
|
> [!IMPORTANT]
|
|
> This is a very important information.
|
|
|
|
> [!CAUTION]
|
|
> This is a caution.
|
|
|
|
> [!WARNING]
|
|
> ## Title goes here
|
|
>${space}
|
|
> This is a warning.
|
|
|
|
After`;
|
|
const expected = `<p>Before</p><aside class="admonition note"><p>This is a note.</p></aside><aside class="admonition tip"><p>This is a tip.</p></aside><aside class="admonition important"><p>This is a very important information.</p></aside><aside class="admonition caution"><p>This is a caution.</p></aside><aside class="admonition warning"><h2>Title goes here</h2><p>This is a warning.</p></aside><p>After</p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("imports images with same outcome as if inserted from CKEditor", () => {
|
|
const input = "";
|
|
const expected = `<p><img src="api/attachments/YbkR3wt2zMcA/image/image"></p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("maintains code blocks with XML/HTML", () => {
|
|
const input = trimIndentation`\
|
|
Before
|
|
\`\`\`
|
|
<application
|
|
...
|
|
android:testOnly="false">
|
|
...
|
|
</application>
|
|
\`\`\`
|
|
After`;
|
|
const expected = trimIndentation`\
|
|
<p>Before</p><pre><code class="language-text-x-trilium-auto"><application
|
|
...
|
|
android:testOnly="false">
|
|
...
|
|
</application></code></pre><p>After</p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("does not escape unneeded characters", () => {
|
|
const input = `It's important to note that these examples are not natively supported by Trilium out of the box; instead, they demonstrate what you can build within Trilium.`;
|
|
const expected = `<p>It's important to note that these examples are not natively supported by Trilium out of the box; instead, they demonstrate what you can build within Trilium.</p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("preserves ", () => {
|
|
const input = `Hello world.`;
|
|
const expected = /*html*/`<p>Hello world.</p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("converts non-breaking space character to ", () => {
|
|
const input = `Hello\u00a0world.`;
|
|
const expected = /*html*/`<p>Hello world.</p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("supports normal links", () => {
|
|
const input = `[Google](https://www.google.com)`;
|
|
const expected = /*html*/`<p><a href="https://www.google.com">Google</a></p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("does not touch relative links", () => {
|
|
const input = `[Canvas](../../Canvas.html)`;
|
|
const expected = /*html*/`<p><a href="../../Canvas.html">Canvas</a></p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("imports back to reference links", () => {
|
|
const input = `<a class="reference-link" href="../../Canvas.html">Canvas</a>`;
|
|
const expected = /*html*/`<p><a class="reference-link" href="../../Canvas.html">Canvas</a></p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("preserves figures", () => {
|
|
const input = `<figure class="image image-style-align-center image_resized" style="width:50%;"><img style="aspect-ratio:991/403;" src="Jump to Note_image.png" width="991" height="403"></figure>`;
|
|
const expected = /*html*/`<figure class="image image-style-align-center image_resized" style="width:50%;"><img style="aspect-ratio:991/403;" src="Jump to Note_image.png" width="991" height="403"></figure>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("converts inline math expressions into Mathtex format", () => {
|
|
const input = `The equation is\u00a0$e=mc^{2}$.`;
|
|
const expected = /*html*/`<p>The equation is <span class="math-tex">\\(e=mc^{2}\\)</span>.</p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("converts display math expressions into Mathtex format", () => {
|
|
const input = `$$\sqrt{x^{2}+1}$$`;
|
|
const expected = /*html*/`<p><span class="math-tex">\\[\sqrt{x^{2}+1}\\]</span></p>`;
|
|
expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected);
|
|
});
|
|
|
|
it("preserves escaped math expressions", () => {
|
|
const scenarios = [
|
|
"\\$\\$\sqrt{x^{2}+1}\\$\\$",
|
|
"The equation is \\$e=mc^{2}\\$."
|
|
];
|
|
for (const scenario of scenarios) {
|
|
expect(markdownService.renderToHtml(scenario, "Title")).toStrictEqual(`<p>${scenario}</p>`);
|
|
}
|
|
});
|
|
|
|
});
|