From 7169e50007e55225b4cbe90a71efb3383c71967c Mon Sep 17 00:00:00 2001 From: gaaming <15626185054@163.com> Date: Thu, 13 Oct 2022 13:35:03 +0800 Subject: [PATCH] feat: line numbers plugin (#84) * feat: add rehypePluginLineNumbers * feat: rehypePluginLineNumbers options control * docs: use-mdx add line numbers usage * fix: docs about line-numbers --- docs/en/api/config-extension.md | 17 +++++++ docs/en/guide/use-mdx.mdx | 14 ++++++ docs/zh/api/config-extension.md | 17 +++++++ docs/zh/guide/use-mdx.mdx | 14 ++++++ src/node/plugin-mdx/pluginMdxRollup.ts | 2 + .../plugin-mdx/rehypePlugins/lineNumbers.ts | 44 +++++++++++++++++++ src/shared/types/index.ts | 1 + src/theme-default/styles/doc.css | 4 +- 8 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/node/plugin-mdx/rehypePlugins/lineNumbers.ts diff --git a/docs/en/api/config-extension.md b/docs/en/api/config-extension.md index 1caa8983..8bbdb4f5 100644 --- a/docs/en/api/config-extension.md +++ b/docs/en/api/config-extension.md @@ -173,3 +173,20 @@ export default defineConfig({ } }); ``` + +### markdown.lineNumbers + +- Type: `Boolean`, +- Default: false + +You can enable line numbers for each code blocks via config: + +```js +import { defineConfig } from 'islandjs'; + +export default defineConfig({ + markdown: { + lineNumbers: true + } +}); +``` \ No newline at end of file diff --git a/docs/en/guide/use-mdx.mdx b/docs/en/guide/use-mdx.mdx index 5d2c4e6f..c881a694 100644 --- a/docs/en/guide/use-mdx.mdx +++ b/docs/en/guide/use-mdx.mdx @@ -186,3 +186,17 @@ export default defineConfig({ } }); ``` + +## Codeblock Line Numbers + +If you hold that codeblock show the line numbers, you can open it through this config. + +```js{5} +import { defineConfig } from 'islandjs'; + +export default defineConfig({ + markdown: { + lineNumbers: true + } +}); +``` diff --git a/docs/zh/api/config-extension.md b/docs/zh/api/config-extension.md index 7ed939cc..022ad0dc 100644 --- a/docs/zh/api/config-extension.md +++ b/docs/zh/api/config-extension.md @@ -173,3 +173,20 @@ export default defineConfig({ } }); ``` + +### markdown.lineNumbers + +- Type: `Boolean`, +- Default: false + +是否给代码块加上行号,默认是不展示。 + +```js +import { defineConfig } from 'islandjs'; + +export default defineConfig({ + markdown: { + lineNumbers: true + } +}); +``` \ No newline at end of file diff --git a/docs/zh/guide/use-mdx.mdx b/docs/zh/guide/use-mdx.mdx index 914f0387..e23a0933 100644 --- a/docs/zh/guide/use-mdx.mdx +++ b/docs/zh/guide/use-mdx.mdx @@ -190,3 +190,17 @@ export default defineConfig({ } }); ``` + +## 代码块行号 + +如果你希望给代码块添加行号,可以通过以下配置开启功能。 + +```js{5} +import { defineConfig } from 'islandjs'; + +export default defineConfig({ + markdown: { + lineNumbers: true + } +}); +``` diff --git a/src/node/plugin-mdx/pluginMdxRollup.ts b/src/node/plugin-mdx/pluginMdxRollup.ts index a268d105..2bf575cf 100644 --- a/src/node/plugin-mdx/pluginMdxRollup.ts +++ b/src/node/plugin-mdx/pluginMdxRollup.ts @@ -13,6 +13,7 @@ import { remarkPluginToc } from './remarkPlugins/toc'; import { remarkPluginTip } from './remarkPlugins/tip'; import shiki from 'shiki'; import { rehypePluginShiki } from './rehypePlugins/shiki'; +import { rehypePluginLineNumbers } from './rehypePlugins/lineNumbers'; import { SiteConfig } from 'shared/types/index'; import { Plugin } from 'vite'; @@ -67,6 +68,7 @@ export async function pluginMdxRollup( } ], rehypePluginPreWrapper, + ...(config.markdown?.lineNumbers ? rehypePluginLineNumbers : []), ...(config.markdown?.rehypePlugins || []) ] }) as Plugin; diff --git a/src/node/plugin-mdx/rehypePlugins/lineNumbers.ts b/src/node/plugin-mdx/rehypePlugins/lineNumbers.ts new file mode 100644 index 00000000..22c82c08 --- /dev/null +++ b/src/node/plugin-mdx/rehypePlugins/lineNumbers.ts @@ -0,0 +1,44 @@ +import { visit } from 'unist-util-visit'; + +export const rehypePluginLineNumbers = () => { + return (tree) => { + visit(tree, 'element', (node, index, parent) => { + // after preWrapperPlugin,
+ if ( + node.tagName === 'pre' && + node.children?.[0]?.type === 'element' && + node.children[0].tagName === 'code' + ) { + const parentClassName = parent.properties?.className?.toString() || ''; + parent.properties = parent.properties || {}; + parent.properties.className = `${parentClassName} line-numbers-mode`; + + const codeContent = node.children[0].children.filter( + (item) => item.type === 'text' + ); + const lineNumbersCode: Element = { + type: 'element', + tagName: 'div', + properties: { + className: 'line-numbers-wrapper' + }, + children: [...Array(codeContent.length)].map((line, index) => ({ + type: 'element', + tagName: 'span', + properties: { + className: 'line-number' + }, + children: [ + { + type: 'text', + value: index + 1 + } + ] + })) + }; + const children = parent.children; + parent.children = [...children, lineNumbersCode]; + } + }); + }; +}; diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index 85faa27a..eff78fe9 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -197,4 +197,5 @@ export interface RouteOptions { export interface MarkdownOptions { remarkPlugins?: PluggableList; rehypePlugins?: PluggableList; + lineNumbers?: boolean; } diff --git a/src/theme-default/styles/doc.css b/src/theme-default/styles/doc.css index ded16105..c35ffc96 100644 --- a/src/theme-default/styles/doc.css +++ b/src/theme-default/styles/doc.css @@ -359,13 +359,15 @@ z-index: 3; border-right: 1px solid var(--island-c-divider-dark-2); padding-top: 16px; - width: 32px; + width: 36px; text-align: center; font-family: var(--island-font-family-mono); line-height: var(--island-code-line-height); font-size: var(--island-code-font-size); color: var(--island-code-line-number-color); transition: border-color 0.5s, color 0.5s; + display: flex; + flex-direction: column; } .island-doc [class*='language-'] > button.copy {