Created
February 28, 2024 17:50
-
-
Save tayiorbeii/25db563d549722b14f6342bbcd648e52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let MarkdownIt = await npm("markdown-it"); | |
let hljs = await npm("highlight.js"); | |
let TurndownService = await npm("turndown"); | |
// import 'highlight.js/styles/night-owl.css'; | |
import "@johnlindquist/kit"; | |
// Name: html-to-markdown | |
// Description: Paste Markdown to generate HTML with syntax highlighting | |
let html = await editor(`Paste HTML (result will be copied to clipboard)`); | |
let turnDownService = new TurndownService({ | |
codeBlockStyle: "fenced", | |
headingStyle: "atx", | |
preformattedCode: true, | |
}); | |
// custom rule for inline code | |
turnDownService.addRule("inlineCode", { | |
filter: function (node) { | |
return ( | |
node.nodeName == "SPAN" && node.style.fontFamily.includes("monospace") | |
); | |
}, | |
replacement: function (content, node, options) { | |
// Wrap the content in backticks for inline code format | |
return "`" + content + "`"; | |
}, | |
}); | |
// custom rule for removing "Run as cell" button | |
turnDownService.addRule("removeButton", { | |
filter: function (node) { | |
return node.nodeName == "BUTTON" && node.textContent == "Run as cell"; | |
}, | |
replacement: function (content, node, options) { | |
return ""; | |
}, | |
}); | |
// custom rule for code blocks | |
turnDownService.addRule("codeBlock", { | |
filter: function (node) { | |
return ( | |
node.nodeName == "DIV" && | |
node.className.includes("monaco-editor") && | |
node.getAttribute("role") === "code" | |
); | |
}, | |
replacement: function (content, node, options) { | |
let language = node.parentNode.attributes["data-mode-id"] | |
? node.parentNode.attributes["data-mode-id"].data | |
: ""; | |
let findCodeblockNode = function (node) { | |
let result = []; | |
if ( | |
node.className && | |
node.className === "view-lines monaco-mouse-cursor-text" | |
) { | |
result.push(node); | |
} | |
for (let i = 0; i < node.childNodes.length; i++) { | |
result = result.concat(findCodeblockNode(node.childNodes[i])); | |
} | |
return result; | |
}; | |
let nestedNodes = findCodeblockNode(node); | |
let codeLines = nestedNodes | |
.map((nestedNode) => | |
[...nestedNode.childNodes] | |
.filter( | |
(n) => | |
n.nodeName === "DIV" && | |
n.className && | |
n.className.includes("view-line") | |
) | |
.map((x) => x.textContent) | |
.join("\n") | |
) | |
.join("\n"); | |
return "```" + language + "\n" + codeLines + "\n```"; | |
}, | |
}); | |
let markdown = turnDownService.turndown(html); | |
// replace all non-standard empty characters with a space | |
markdown = markdown.replace(" ", " "); | |
// test this later: | |
// // replace (\n\s*){2,} with \n\n but only if it is not inside of a code block | |
// let codeBlocks = markdown.match(/```[\s\S]*?```/g); | |
// let codeBlockPlaceholders = []; | |
// if (codeBlocks) { | |
// codeBlocks.forEach((codeBlock) => { | |
// codeBlockPlaceholders.push(`{{${codeBlockPlaceholders.length}}}`); | |
// markdown = markdown.replace(codeBlock, codeBlockPlaceholders.slice(-1)[0]); | |
// }); | |
// } | |
// markdown = markdown.replace(/(\n\s*){2,}/g, "\n\n"); | |
// codeBlockPlaceholders.forEach((codeBlock, index) => { | |
// markdown = markdown.replace(codeBlock, codeBlocks[index]); | |
// }); | |
await copy(`${markdown}`.replaceAll(""", `"`)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment