feat: HTML code preview is supported in markdown.

This commit is contained in:
jaywcjlove
2022-10-23 22:27:07 +08:00
parent fdcfcb287b
commit a478fbb888
6 changed files with 44 additions and 5 deletions

View File

@ -31,9 +31,11 @@ $ chmod -R 755 my_directory
### Chmod 生成器 ### Chmod 生成器
<div style="display: flex; justify-content: space-evenly; align-items: center;padding: 1rem 1rem;"> ```html preview
<div>
权限:<input type="text" id="num" placeholder="777" maxlength="3" style="padding: 0.3rem 0.3rem;" /> <input type="text" id="let" placeholder="rwxrwxrwx" maxlength="9" style="padding: 0.3rem 0.3rem;" /> 权限:<input type="text" id="num" placeholder="777" maxlength="3" style="padding: 0.3rem 0.3rem;" /> <input type="text" id="let" placeholder="rwxrwxrwx" maxlength="9" style="padding: 0.3rem 0.3rem;" />
</div> </div>
```
--- ---
@ -275,8 +277,10 @@ $ find /path -type f -exec chmod 644 {} \;
* [使用 chmod 修改文件权限](https://www.linode.com/docs/guides/modify-file-permissions-with-chmod/) _(linode.com)_ * [使用 chmod 修改文件权限](https://www.linode.com/docs/guides/modify-file-permissions-with-chmod/) _(linode.com)_
<!--rehype:ignore:start--> <!--rehype:ignore:start-->
### 以下是 Chmod 生成器 JS 代码(用于网站请忽略) ### 以下是 Chmod 生成器 JS 代码(代码用于网站请忽略不要删除
<!--rehype:ignore:end--> <!--rehype:ignore:end-->
```html preview
<!-- Chmod 生成器 JS 代码 --> <!-- Chmod 生成器 JS 代码 -->
<script type="text/javascript"> <script type="text/javascript">
const reg_num = /^[0-7]{3}$/; // 一些正则表达式来检查 num 输入 const reg_num = /^[0-7]{3}$/; // 一些正则表达式来检查 num 输入
@ -499,3 +503,4 @@ $ find /path -type f -exec chmod 644 {} \;
return perm_num; return perm_num;
} }
</script> </script>
```

View File

@ -228,6 +228,16 @@ const school = <div>学校</div>;
``` ```
<!--rehype:className=wrap-text --> <!--rehype:className=wrap-text -->
### HTML 代码预览
```
```html preview
这里是你的 HTML 代码
\```
```
上面的 `markdown` 代码在 `meta` 位置添加 `preview` 标识HTML 代码将被执行预览
布局 布局
--- ---

View File

@ -19,7 +19,7 @@
}, },
"keywords": [], "keywords": [],
"devDependencies": { "devDependencies": {
"@wcj/markdown-to-html": "^2.1.0", "@wcj/markdown-to-html": "^2.1.1",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"fs-extra": "^10.1.0", "fs-extra": "^10.1.0",
"recursive-readdir-files": "^2.3.0", "recursive-readdir-files": "^2.3.0",

View File

@ -12,6 +12,7 @@ import { homeCardIcons } from './utils/homeCardIcons.mjs';
import { getTocsTree } from './utils/getTocsTree.mjs'; import { getTocsTree } from './utils/getTocsTree.mjs';
import { rehypeTitle } from './utils/rehypeTitle.mjs'; import { rehypeTitle } from './utils/rehypeTitle.mjs';
import { anchorPoint } from './utils/anchorPoint.mjs'; import { anchorPoint } from './utils/anchorPoint.mjs';
import { rehypePreviewHTML } from './utils/rehypePreviewHTML.mjs';
const favicon = `data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%221em%22%20width%3D%221em%22%3E%20%3Cpath%20d%3D%22m21.66%2010.44-.98%204.18c-.84%203.61-2.5%205.07-5.62%204.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2%201.17-2.42%203.16-3.07%206.5-2.28l1.67.39c4.19.98%205.47%203.05%204.49%207.23Z%22%20fill%3D%22%23c9d1d9%22%2F%3E%20%3Cpath%20d%3D%22M15.06%2019.39c-.62.42-1.4.77-2.35%201.08l-1.58.52c-3.97%201.28-6.06.21-7.35-3.76L2.5%2013.28c-1.28-3.97-.22-6.07%203.75-7.35l1.58-.52c.41-.13.8-.24%201.17-.31-.3.61-.54%201.35-.74%202.2l-.98%204.19c-.98%204.18.31%206.24%204.48%207.23l1.68.4c.58.14%201.12.23%201.62.27Zm2.43-8.88c-.06%200-.12-.01-.19-.02l-4.85-1.23a.75.75%200%200%201%20.37-1.45l4.85%201.23a.748.748%200%200%201-.18%201.47Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3Cpath%20d%3D%22M14.56%2013.89c-.06%200-.12-.01-.19-.02l-2.91-.74a.75.75%200%200%201%20.37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3C%2Fsvg%3E`; const favicon = `data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%221em%22%20width%3D%221em%22%3E%20%3Cpath%20d%3D%22m21.66%2010.44-.98%204.18c-.84%203.61-2.5%205.07-5.62%204.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2%201.17-2.42%203.16-3.07%206.5-2.28l1.67.39c4.19.98%205.47%203.05%204.49%207.23Z%22%20fill%3D%22%23c9d1d9%22%2F%3E%20%3Cpath%20d%3D%22M15.06%2019.39c-.62.42-1.4.77-2.35%201.08l-1.58.52c-3.97%201.28-6.06.21-7.35-3.76L2.5%2013.28c-1.28-3.97-.22-6.07%203.75-7.35l1.58-.52c.41-.13.8-.24%201.17-.31-.3.61-.54%201.35-.74%202.2l-.98%204.19c-.98%204.18.31%206.24%204.48%207.23l1.68.4c.58.14%201.12.23%201.62.27Zm2.43-8.88c-.06%200-.12-.01-.19-.02l-4.85-1.23a.75.75%200%200%201%20.37-1.45l4.85%201.23a.748.748%200%200%201-.18%201.47Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3Cpath%20d%3D%22M14.56%2013.89c-.06%200-.12-.01-.19-.02l-2.91-.74a.75.75%200%200%201%20.37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3C%2Fsvg%3E`;
@ -41,6 +42,7 @@ export function create(str = '', options = {}) {
}], }],
], ],
rewrite: (node, index, parent) => { rewrite: (node, index, parent) => {
rehypePreviewHTML(node, parent);
rehypeTitle(node, options.filename); rehypeTitle(node, options.filename);
homeCardIcons(node, parent, options.isHome); homeCardIcons(node, parent, options.isHome);
tooltips(node, index, parent); tooltips(node, index, parent);

View File

@ -3,11 +3,19 @@ import rehypeParse from 'rehype-parse';
import {unified} from 'unified'; import {unified} from 'unified';
import { VFile } from 'vfile'; import { VFile } from 'vfile';
export function getSVGNode(iconPath) { export function getSVGNode(iconPath, space = 'svg') {
const svgStr = fs.readFileSync(iconPath); const svgStr = fs.readFileSync(iconPath);
const processor = unified().use(rehypeParse,{ fragment: true, space: "svg" }) const processor = unified().use(rehypeParse,{ fragment: true, space })
const file = new VFile(); const file = new VFile();
file.value = svgStr.toString(); file.value = svgStr.toString();
const hastNode = processor.runSync(processor.parse(file), file); const hastNode = processor.runSync(processor.parse(file), file);
return hastNode.children || [] return hastNode.children || []
} }
export function getVNode(str = '', space = 'html') {
const processor = unified().use(rehypeParse,{ fragment: true, space })
const file = new VFile();
file.value = str.toString();
const hastNode = processor.runSync(processor.parse(file), file);
return hastNode.children || []
}

View File

@ -0,0 +1,14 @@
import { getCodeString } from 'rehype-rewrite';
import { getVNode } from './getSVGNode.mjs';
export function rehypePreviewHTML(node, parent) {
if (node.type === 'element' && node.tagName === 'pre' && node.properties?.className?.includes('language-html')) {
const child = node.children[0];
if (child?.tagName === 'code' && child.data?.meta === 'preview') {
const code = getCodeString(node.children)
const vnode = getVNode(code || '')
node.children = vnode
}
}
}