From 5daead538437b243d38f21d71a62e5b0b0e66829 Mon Sep 17 00:00:00 2001 From: taga3s Date: Sun, 22 Dec 2024 23:04:07 +0900 Subject: [PATCH 1/2] refactor: remark / rehype momiji --- app/packages/rehype-momiji/README.md | 6 ++---- app/packages/rehype-momiji/buildCodeBlock.ts | 10 +++++++--- .../docs/assets/rehype-momiji-sample.png | Bin 8685 -> 0 bytes app/packages/rehype-momiji/index.ts | 9 +++++---- .../index.ts | 13 ++++++------- vite.config.ts | 6 +++--- 6 files changed, 23 insertions(+), 21 deletions(-) delete mode 100644 app/packages/rehype-momiji/docs/assets/rehype-momiji-sample.png rename app/packages/{remark-momiji-filename => remark-momiji-title}/index.ts (65%) diff --git a/app/packages/rehype-momiji/README.md b/app/packages/rehype-momiji/README.md index 8ccf8da..e151c89 100644 --- a/app/packages/rehype-momiji/README.md +++ b/app/packages/rehype-momiji/README.md @@ -1,4 +1,4 @@ -# rehype-momiji (in development) +# rehype-momiji [rehype](https://github.com/rehypejs/rehype) plugin powered by [shiki](https://shiki.matsu.io/). @@ -9,6 +9,4 @@ ## How to use? -When you want only highlighting code block, just use this package. If you want to display a filename, you also need to use `remark-momiji`. - -example usage of rehype-momiji +When you want only highlighting code block, just use this package. If you want to display a filename, you also need to use `remark-momiji-title`. diff --git a/app/packages/rehype-momiji/buildCodeBlock.ts b/app/packages/rehype-momiji/buildCodeBlock.ts index 933dc27..99adf5b 100644 --- a/app/packages/rehype-momiji/buildCodeBlock.ts +++ b/app/packages/rehype-momiji/buildCodeBlock.ts @@ -1,6 +1,6 @@ import type { BundledLanguage, HighlighterGeneric, BundledTheme } from "shiki"; import { COLOR_SHIRONERI, COLOR_HAI } from "./colors"; -import type { Root } from "hast"; +import type { Element } from "hast"; const buildCodeBlock = ( highlighter: HighlighterGeneric, @@ -10,7 +10,7 @@ const buildCodeBlock = ( filename: string, filenameBGColor?: string, filenameTextColor?: string, -): Root => { +): Element | undefined => { const hast = highlighter.codeToHast(rawCode, { lang: lang, theme: theme, @@ -50,7 +50,11 @@ const buildCodeBlock = ( ], }); - return hast; + if (hast.children[0].type !== "element") { + return; + } + + return hast.children[0]; }; export { buildCodeBlock }; diff --git a/app/packages/rehype-momiji/docs/assets/rehype-momiji-sample.png b/app/packages/rehype-momiji/docs/assets/rehype-momiji-sample.png deleted file mode 100644 index 7ca4ef682f7c320a20eff5888e7bcf57fc1431bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8685 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 diff --git a/app/packages/rehype-momiji/index.ts b/app/packages/rehype-momiji/index.ts index 1464377..997a739 100644 --- a/app/packages/rehype-momiji/index.ts +++ b/app/packages/rehype-momiji/index.ts @@ -93,23 +93,24 @@ const rehypeMomiji: Plugin = (options) => { const supportedLang = checkSupportedLanguage(lang); - const filename = (codeElem.properties["data-remark-code-filename"] as string) ?? ""; + const filename = codeElem.properties["data-remark-code-title"] ?? ""; const codeBlock = buildCodeBlock( defaultHighlighter, rawCode, supportedLang, theme, - filename, + String(filename), filenameBGColor, filenameTextColor, ); + if (!codeBlock) return; node.tagName = "div"; - node.children = codeBlock.children as ElementContent[]; + node.children = [codeBlock]; node.properties.style = "position: relative;"; }); }; }; -export default rehypeMomiji; +export { rehypeMomiji }; diff --git a/app/packages/remark-momiji-filename/index.ts b/app/packages/remark-momiji-title/index.ts similarity index 65% rename from app/packages/remark-momiji-filename/index.ts rename to app/packages/remark-momiji-title/index.ts index 76108b0..e496cd3 100644 --- a/app/packages/remark-momiji-filename/index.ts +++ b/app/packages/remark-momiji-title/index.ts @@ -2,7 +2,7 @@ import { visit } from "unist-util-visit"; import type { Root } from "mdast"; import type { Plugin } from "unified"; -const remarkMomijiFilename: Plugin<[], Root> = () => { +const remarkMomijiTitle: Plugin<[], Root> = () => { return (tree) => { visit(tree, "code", (node) => { const metaString = `${node.lang ?? ""} ${node.meta ?? ""}`.trim(); @@ -11,14 +11,13 @@ const remarkMomijiFilename: Plugin<[], Root> = () => { const [title] = metaString.match(/(?<=title=("|'))(.*?)(?=("|'))/) ?? [""]; if (!title) return; - if (!node.data) { - node.data = {}; - } - node.data.hProperties = { - "data-remark-code-filename": title, + node.data = { + hProperties: { + "data-remark-code-title": title, + }, }; }); }; }; -export default remarkMomijiFilename; +export { remarkMomijiTitle }; diff --git a/vite.config.ts b/vite.config.ts index 0e83709..5eec036 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,8 +8,8 @@ import remarkBreaks from 'remark-breaks'; import remarkFrontmatter from 'remark-frontmatter'; import remarkMdxFrontmatter from 'remark-mdx-frontmatter'; import remarkGfm from 'remark-gfm' -import rehypeMomiji from './app/packages/rehype-momiji' -import remarkMomijiCodeFilename from './app/packages/remark-momiji-filename' +import { rehypeMomiji } from './app/packages/rehype-momiji' +import { remarkMomijiTitle } from './app/packages/remark-momiji-title' import rehypeMermaid from './app/packages/rehype-mermaid/rehypeMermaid' import { remarkAttentionBlock } from './app/packages/remark-attention-block' import { rehypeAttentionBlock } from './app/packages/rehype-attention-block' @@ -25,7 +25,7 @@ export default defineConfig(() => { ssg({ entry: "./app/server.ts" }), mdx({ jsxImportSource: 'hono/jsx', - remarkPlugins: [remarkGfm, remarkBreaks, remarkFrontmatter, remarkMdxFrontmatter, remarkMomijiCodeFilename, remarkAttentionBlock], + remarkPlugins: [remarkGfm, remarkBreaks, remarkFrontmatter, remarkMdxFrontmatter, remarkMomijiTitle, remarkAttentionBlock], rehypePlugins: [[rehypeMomiji, { excludeLangs: ['mermaid'] }], rehypeMermaid, rehypeAttentionBlock], }) ], From 6894a69f92484e76d9b6f37fad131d6c0b19d3d2 Mon Sep 17 00:00:00 2001 From: taga3s Date: Mon, 23 Dec 2024 00:34:14 +0900 Subject: [PATCH 2/2] refactor: rehype-mermaid --- app/packages/rehype-mermaid/README.md | 4 ---- .../docs/assets/rehype-mermaid-sample.png | Bin 25498 -> 0 bytes app/packages/rehype-mermaid/rehypeMermaid.ts | 14 ++++++++------ 3 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 app/packages/rehype-mermaid/docs/assets/rehype-mermaid-sample.png diff --git a/app/packages/rehype-mermaid/README.md b/app/packages/rehype-mermaid/README.md index f06f4d6..9ee180d 100644 --- a/app/packages/rehype-mermaid/README.md +++ b/app/packages/rehype-mermaid/README.md @@ -5,7 +5,3 @@ ## features - Generating Mermaid Diagrams - -## How to use? - -example usage of rehype-mermaid diff --git a/app/packages/rehype-mermaid/docs/assets/rehype-mermaid-sample.png b/app/packages/rehype-mermaid/docs/assets/rehype-mermaid-sample.png deleted file mode 100644 index e5e95a28e3399dca13e45a890282474a9ab532ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25498 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 E0XVFTaR2}S diff --git a/app/packages/rehype-mermaid/rehypeMermaid.ts b/app/packages/rehype-mermaid/rehypeMermaid.ts index b445c7f..c1b7107 100644 --- a/app/packages/rehype-mermaid/rehypeMermaid.ts +++ b/app/packages/rehype-mermaid/rehypeMermaid.ts @@ -1,4 +1,4 @@ -import type { Plugin } from "unified"; +import type { Plugin, Transformer } from "unified"; import type { Text, Parent, Root } from "hast"; import { visit } from "unist-util-visit"; import { renderMermaid } from "@mermaid-js/mermaid-cli"; @@ -23,8 +23,8 @@ const rehypeMermaid: Plugin<[], Root> = () => { const checkIsMermaid = (lang: string): boolean => lang === "mermaid"; - return async (tree) => { - const mermaidCodeBlocks: MermaidCodeBlock[] = []; + const transformer: Transformer = async (tree) => { + const mermaidCodeBlockPromises: MermaidCodeBlock[] = []; visit(tree, "element", (node, index, parent) => { // Check if the node is a pre tag with a single child @@ -61,11 +61,11 @@ const rehypeMermaid: Plugin<[], Root> = () => { const isMermaid = checkIsMermaid(lang); if (isMermaid && index && parent) { - mermaidCodeBlocks.push({ textNode, index, parent }); + mermaidCodeBlockPromises.push({ textNode, index, parent }); } }); - if (mermaidCodeBlocks.length === 0) { + if (mermaidCodeBlockPromises.length === 0) { return; } @@ -76,7 +76,7 @@ const rehypeMermaid: Plugin<[], Root> = () => { const decoder = new TextDecoder(); await Promise.all( - mermaidCodeBlocks.map(async ({ textNode, index, parent }, blockIndex) => { + mermaidCodeBlockPromises.map(async ({ textNode, index, parent }, blockIndex) => { const { data: svgBuffer } = await renderMermaid(browser, textNode.value, "svg"); const svgElem = decoder.decode(svgBuffer).replaceAll("my-svg", `my-svg-${blockIndex}`); @@ -95,6 +95,8 @@ const rehypeMermaid: Plugin<[], Root> = () => { await browser.close(); }; + + return transformer; }; export default rehypeMermaid;