import marked from "marked";
import morphdom from "morphdom";
import DOMPurify from "dompurify";
import katex from "katex";
import monaco from "./live_editor/monaco";
// Reuse Monaco highlighter for Markdown code blocks
marked.setOptions({
highlight: (code, lang, callback) => {
monaco.editor
.colorize(code, lang)
.then((result) => {
// `colorize` always adds additional newline, so we remove it
result = result.replace(/
$/, "");
callback(null, result);
})
.catch((error) => {
callback(error, null);
});
},
});
// Modify external links, so that they open in a new tab.
// See https://github.com/cure53/DOMPurify/tree/main/demos#hook-to-open-all-links-in-a-new-window-link
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
if (
node.tagName.toLowerCase() === "a" &&
node.host !== window.location.host
) {
node.setAttribute("target", "_blank");
node.setAttribute("rel", "noreferrer noopener");
}
});
/**
* Renders markdown content in the given container.
*/
class Markdown {
constructor(container, content, baseUrl = null) {
this.container = container;
this.content = content;
this.baseUrl = baseUrl;
this.__render();
}
setContent(content) {
this.content = content;
this.__render();
}
__render() {
this.__getHtml().then((html) => {
// Wrap the HTML in another element, so that we
// can use morphdom's childrenOnly option.
const wrappedHtml = `