feat: add some highlighting to markdown renderer
This commit is contained in:
@ -1,12 +1,13 @@
|
||||
import { unified } from "https://esm.sh/unified@10.1.2";
|
||||
import { render } from "https://deno.land/x/gfm@0.2.5/mod.ts";
|
||||
import "https://esm.sh/prismjs@1.29.0/components/prism-typescript?no-check";
|
||||
import "https://esm.sh/prismjs@1.29.0/components/prism-bash?no-check";
|
||||
import "https://esm.sh/prismjs@1.29.0/components/prism-rust?no-check";
|
||||
import remarkParse from "https://esm.sh/remark-parse@10.0.2";
|
||||
import remarkStringify from "https://esm.sh/remark-stringify@10.0.3";
|
||||
import remarkFrontmatter, {
|
||||
Root,
|
||||
} from "https://esm.sh/remark-frontmatter@4.0.1";
|
||||
import remarkRehype from "https://esm.sh/remark-rehype@10.1.0";
|
||||
import rehypeSanitize from "https://esm.sh/rehype-sanitize@5.0.1";
|
||||
import rehypeStringify from "https://esm.sh/rehype-stringify@9.0.3";
|
||||
import * as cache from "@lib/cache/documents.ts";
|
||||
import { SILVERBULLET_SERVER } from "@lib/env.ts";
|
||||
import { fixRenderedMarkdown } from "@lib/helpers.ts";
|
||||
@ -90,14 +91,9 @@ export function parseDocument(doc: string) {
|
||||
}
|
||||
|
||||
export function renderMarkdown(doc: string) {
|
||||
const out = unified()
|
||||
.use(remarkParse)
|
||||
.use(remarkRehype)
|
||||
.use(rehypeSanitize)
|
||||
.use(rehypeStringify)
|
||||
.processSync(doc);
|
||||
|
||||
return String(out);
|
||||
return render(doc, {
|
||||
allowMath: true,
|
||||
});
|
||||
}
|
||||
|
||||
export type ParsedDocument = ReturnType<typeof parseDocument>;
|
||||
|
79
lib/highlight.ts
Normal file
79
lib/highlight.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { refractor } from "https://esm.sh/refractor@4.8.1";
|
||||
import { visit } from "https://esm.sh/unist-util-visit@5.0.0";
|
||||
import { toString } from "https://esm.sh/hast-util-to-string@2.0.0";
|
||||
|
||||
import jsx from "https://esm.sh/refractor/lang/jsx";
|
||||
import javascript from "https://esm.sh/refractor/lang/javascript";
|
||||
import css from "https://esm.sh/refractor/lang/css";
|
||||
import cssExtras from "https://esm.sh/refractor/lang/css-extras";
|
||||
import jsExtras from "https://esm.sh/refractor/lang/js-extras";
|
||||
import sql from "https://esm.sh/refractor/lang/sql";
|
||||
import typescript from "https://esm.sh/refractor/lang/typescript";
|
||||
import swift from "https://esm.sh/refractor/lang/swift";
|
||||
import objectivec from "https://esm.sh/refractor/lang/objectivec";
|
||||
import markdown from "https://esm.sh/refractor/lang/markdown";
|
||||
import json from "https://esm.sh/refractor/lang/json";
|
||||
|
||||
refractor.register(jsx);
|
||||
refractor.register(json);
|
||||
refractor.register(typescript);
|
||||
refractor.register(javascript);
|
||||
refractor.register(css);
|
||||
refractor.register(cssExtras);
|
||||
refractor.register(jsExtras);
|
||||
refractor.register(sql);
|
||||
refractor.register(swift);
|
||||
refractor.register(objectivec);
|
||||
refractor.register(markdown);
|
||||
|
||||
refractor.alias({ jsx: ["js"] });
|
||||
refractor.alias({typescript:["ts"]})
|
||||
|
||||
const getLanguage = (node) => {
|
||||
const className = node.properties.className || [];
|
||||
|
||||
for (const classListItem of className) {
|
||||
if (classListItem.slice(0, 9) === "language-") {
|
||||
return classListItem.slice(9).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const rehypePrism = (options) => {
|
||||
options = options || {};
|
||||
|
||||
return (tree) => {
|
||||
visit(tree, "element", visitor);
|
||||
};
|
||||
|
||||
function visitor(node, index, parent) {
|
||||
if (!parent || parent.tagName !== "pre" || node.tagName !== "code") {
|
||||
return;
|
||||
}
|
||||
|
||||
const lang = getLanguage(node);
|
||||
|
||||
if (lang === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
parent.properties.className = (parent.properties.className || []).concat(
|
||||
"language-" + lang,
|
||||
);
|
||||
result = refractor.highlight(toString(node), lang);
|
||||
} catch (err) {
|
||||
if (options.ignoreMissing && /Unknown language/.test(err.message)) {
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
node.children = result;
|
||||
}
|
||||
};
|
||||
|
||||
export default rehypePrism;
|
@ -35,8 +35,7 @@ export const isYoutubeLink = (link: string) => {
|
||||
try {
|
||||
const url = new URL(link);
|
||||
return ["youtu.be", "youtube.com","www.youtube.com" ].includes(url.hostname);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
} catch (_err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user