Replace marked namespaces with Marked instance

Based on a new addition to marked, this commits replaces the imported
marked namespaces with a Marked class, that doesn't change when
`marked.use` introduces new options or extensions.

Also changes the naming slighty to use `markdown` as module, so it
sounds more generic.

Reference: https://github.com/markedjs/marked/pull/2831

Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
This commit is contained in:
Sebastian Martinez
2023-07-17 14:47:53 +02:00
parent 50088a5c8a
commit 69946f5d8c
5 changed files with 39 additions and 46 deletions
+4 -4
View File
@@ -35,7 +35,7 @@
"@types/dompurify": "^3.0.2",
"@types/katex": "^0.16.0",
"@types/lodash": "^4.14.195",
"@types/marked": "^5.0.0",
"@types/marked": "^5.0.1",
"@types/md5": "^2.3.2",
"@types/node": "^18.16.12",
"@types/sinon": "^10.0.15",
@@ -836,9 +836,9 @@
"dev": true
},
"node_modules/@types/marked": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.0.tgz",
"integrity": "sha512-YcZe50jhltsCq7rc9MNZC/4QB/OnA2Pd6hrOSTOFajtabN+38slqgDDCeE/0F83SjkKBQcsZUj7VLWR0H5cKRA==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.1.tgz",
"integrity": "sha512-Y3pAUzHKh605fN6fvASsz5FDSWbZcs/65Q6xYRmnIP9ZIYz27T4IOmXfH9gWJV1dpi7f1e7z7nBGUTx/a0ptpA==",
"dev": true
},
"node_modules/@types/md5": {
+1 -1
View File
@@ -26,7 +26,7 @@
"@types/dompurify": "^3.0.2",
"@types/katex": "^0.16.0",
"@types/lodash": "^4.14.195",
"@types/marked": "^5.0.0",
"@types/marked": "^5.0.1",
"@types/md5": "^2.3.2",
"@types/node": "^18.16.12",
"@types/sinon": "^10.0.15",
+2 -2
View File
@@ -1,14 +1,14 @@
<script lang="ts">
import dompurify from "dompurify";
import { marked } from "marked";
import markdown from "@app/lib/markdown";
import { twemoji } from "@app/lib/utils";
export let content: string;
export let fontSize: "tiny" | "small" | "medium" = "small";
const render = (content: string): string =>
dompurify.sanitize(marked.parseInline(content));
dompurify.sanitize(markdown.parseInline(content));
</script>
<style>
+3 -8
View File
@@ -2,13 +2,13 @@
import dompurify from "dompurify";
import matter from "@radicle/gray-matter";
import { afterUpdate } from "svelte";
import { marked } from "marked";
import { toDom } from "hast-util-to-dom";
import * as router from "@app/lib/router";
import markdown from "@app/lib/markdown";
import { Renderer } from "@app/lib/markdown";
import { highlight } from "@app/lib/syntax";
import { isUrl, twemoji, scrollIntoView, canonicalize } from "@app/lib/utils";
import { Renderer } from "@app/lib/markdown";
export let content: string;
// If present, resolve all relative links with respect to this URL
@@ -53,12 +53,7 @@
function render(content: string): string {
return dompurify.sanitize(
marked.parse(content, {
renderer: new Renderer(linkBaseUrl),
// TODO: Disables deprecated options, remove once removed from marked
mangle: false,
headerIds: false,
}),
markdown.parse(content, { renderer: new Renderer(linkBaseUrl) }),
);
}
+29 -31
View File
@@ -1,7 +1,9 @@
import type { marked } from "marked";
import dompurify from "dompurify";
import emojis from "@app/lib/emojis";
import katex from "katex";
import { marked, Renderer as BaseRenderer } from "marked";
import { Marked, Renderer as BaseRenderer } from "marked";
dompurify.setConfig({
// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -24,11 +26,8 @@ const emojisMarkedExtension = {
};
}
},
renderer: (token: marked.Tokens.Generic) => {
return `<span>${
token.text in emojis ? emojis[token.text] : token.text
}</span>`;
},
renderer: (token: marked.Tokens.Generic): string =>
`<span>${token.text in emojis ? emojis[token.text] : token.text}</span>`,
};
const katexMarkedExtension = {
@@ -45,7 +44,7 @@ const katexMarkedExtension = {
};
}
},
renderer: (token: marked.Tokens.Generic) =>
renderer: (token: marked.Tokens.Generic): string =>
katex.renderToString(token.text, {
throwOnError: false,
}),
@@ -68,9 +67,8 @@ const footnoteReferenceMarkedExtension = {
};
}
},
renderer: (token: marked.Tokens.Generic) => {
return `<sup class="footnote-ref" id="${referencePrefix}:${token.text}"><a href="#${footnotePrefix}:${token.text}">[${token.text}]</a></sup>`;
},
renderer: (token: marked.Tokens.Generic): string =>
`<sup class="footnote-ref" id="${referencePrefix}:${token.text}"><a href="#${footnotePrefix}:${token.text}">[${token.text}]</a></sup>`,
};
const footnoteMatch = /^\[\^([^\]]+)\]:\s([\S]*)/;
const footnoteMarkedExtension = {
@@ -88,17 +86,16 @@ const footnoteMarkedExtension = {
};
}
},
renderer: (token: marked.Tokens.Generic) => {
return `${
renderer: (token: marked.Tokens.Generic): string =>
`${
token.reference === "0" ? "<hr />" : ""
}<p class="txt-small" id="${footnotePrefix}:${token.reference}">${
token.reference
}. ${marked.parseInline(
}. ${markedInstance.parseInline(
token.text,
)} <a class="txt-tiny ref-arrow" href="#${referencePrefix}:${
token.reference
}">↩</a></p>`;
},
}">↩</a></p>`,
};
// Converts self closing anchor tags into empty anchor tags, to avoid erratic wrapping behaviour
@@ -117,24 +114,10 @@ const anchorMarkedExtension = {
};
}
},
renderer: (token: marked.Tokens.Generic) => {
return `<a name="${token.text}"></a>`;
},
renderer: (token: marked.Tokens.Generic): string =>
`<a name="${token.text}"></a>`,
};
// TODO: Disables deprecated options, remove once removed from marked
marked.use({
extensions: [
anchorMarkedExtension,
emojisMarkedExtension,
footnoteMarkedExtension,
footnoteReferenceMarkedExtension,
katexMarkedExtension,
],
mangle: false,
headerIds: false,
});
export class Renderer extends BaseRenderer {
#baseUrl: string | undefined;
@@ -174,3 +157,18 @@ export class Renderer extends BaseRenderer {
}
}
}
const markedInstance = new Marked({
extensions: [
emojisMarkedExtension,
katexMarkedExtension,
footnoteMarkedExtension,
footnoteReferenceMarkedExtension,
anchorMarkedExtension,
],
// TODO: Disables deprecated options, remove once removed from marked
mangle: false,
headerIds: false,
});
export default markedInstance;