58 lines
1.8 KiB
TypeScript
Raw Normal View History

"use strict";
import TurndownService from "turndown";
import turndownPluginGfm from "@joplin/turndown-plugin-gfm";
2024-02-19 21:59:40 +02:00
let instance: TurndownService | null = null;
2024-12-17 23:45:37 +02:00
const fencedCodeBlockFilter: TurndownService.Rule = {
2025-01-09 18:07:02 +02:00
filter: function (node, options) {
return options.codeBlockStyle === "fenced" && node.nodeName === "PRE" && node.firstChild !== null && node.firstChild.nodeName === "CODE";
},
replacement: function (content, node, options) {
if (!node.firstChild || !("getAttribute" in node.firstChild) || typeof node.firstChild.getAttribute !== "function") {
return content;
}
2024-12-17 23:45:37 +02:00
2025-01-09 18:07:02 +02:00
const className = node.firstChild.getAttribute("class") || "";
const language = rewriteLanguageTag((className.match(/language-(\S+)/) || [null, ""])[1]);
2024-12-17 23:45:37 +02:00
2025-01-09 18:07:02 +02:00
return "\n\n" + options.fence + language + "\n" + node.firstChild.textContent + "\n" + options.fence + "\n\n";
}
2024-12-17 23:45:37 +02:00
};
2024-02-19 21:59:40 +02:00
function toMarkdown(content: string) {
if (instance === null) {
instance = new TurndownService({
headingStyle: "atx",
codeBlockStyle: "fenced"
});
// Filter is heavily based on: https://github.com/mixmark-io/turndown/issues/274#issuecomment-458730974
2025-01-09 18:07:02 +02:00
instance.addRule("fencedCodeBlock", fencedCodeBlockFilter);
instance.use(turndownPluginGfm.gfm);
}
return instance.turndown(content);
}
function rewriteLanguageTag(source: string) {
2024-12-17 23:45:37 +02:00
if (!source) {
2025-01-09 18:07:02 +02:00
return source;
2024-12-17 23:45:37 +02:00
}
switch (source) {
case "text-x-trilium-auto":
return "";
case "application-javascript-env-frontend":
case "application-javascript-env-backend":
return "javascript";
default:
return source.split("-").at(-1);
}
}
export default {
toMarkdown
2021-02-20 20:10:45 +01:00
};