From 1e13f626129f421986f9647e21ec83f65dff4da9 Mon Sep 17 00:00:00 2001 From: dengqing Date: Sun, 8 May 2022 23:24:36 +0800 Subject: [PATCH] feat: support header --- README.md | 13 +++++---- playground/src/Resume.tsx | 19 ++++++++++--- playground/src/jsx.d.ts | 4 +++ playground/src/plugins/_util.ts | 4 ++- playground/src/plugins/header.ts | 47 ++++++++++++++++++++++++++++++++ playground/src/plugins/index.ts | 1 + 6 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 playground/src/plugins/header.ts diff --git a/README.md b/README.md index 933a81ac..adc764ab 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,14 @@ d: "" # 邓清 -## 个人信息 - -- Github: [https://github.com/Dunqing](https://github.com/Dunqing) +- [https://github.com/Dunqing](https://github.com/Dunqing) +> +- dengqing0821@gmail.com +- 2.5年 +- 21岁 +> - Telegram: @luckingforme -- Email: dengqing0821@gmail.com -- 工作经验:2.5年 -- 年龄:21 + ## 个人总结 diff --git a/playground/src/Resume.tsx b/playground/src/Resume.tsx index d91a56ed..baa5b8da 100644 --- a/playground/src/Resume.tsx +++ b/playground/src/Resume.tsx @@ -5,7 +5,7 @@ import '@unocss/reset/tailwind.css' import remarkFrontmatter from 'remark-frontmatter' import remarkGfm from 'remark-gfm' import clsx from 'clsx' -import { description, meta, table } from './plugins' +import { description, header, meta, table } from './plugins' function Resume() { const [markdown] = useState(() => { @@ -57,9 +57,19 @@ function Resume() { return }, 'description': ({ ...props }) => { - return

- -

+ return

+ }, + 'header': ({ node: _, ...props }) => { + return

+ }, + 'header-h1': ({ node: _, ...props }) => { + return

+ }, + 'header-ul': ({ ...props }) => { + return
    + }, + 'header-li': ({ ...props }) => { + return
  • }, }} remarkPlugins={[ @@ -69,6 +79,7 @@ function Resume() { ]} rehypePlugins={[ table, + header, description, ]} > diff --git a/playground/src/jsx.d.ts b/playground/src/jsx.d.ts index 039bfd8f..a8a061a1 100644 --- a/playground/src/jsx.d.ts +++ b/playground/src/jsx.d.ts @@ -8,6 +8,10 @@ declare global { 'card-item-label': React.DetailedHTMLProps, HTMLElement> 'card-item-value': React.DetailedHTMLProps, HTMLElement> 'description': React.DetailedHTMLProps, HTMLElement> + 'header': React.DetailedHTMLProps, HTMLElement> + 'header-h1': React.DetailedHTMLProps, HTMLElement> + 'header-ul': React.DetailedHTMLProps, HTMLElement> + 'header-li': React.DetailedHTMLProps, HTMLElement> } } } diff --git a/playground/src/plugins/_util.ts b/playground/src/plugins/_util.ts index cc3696f4..282a406d 100644 --- a/playground/src/plugins/_util.ts +++ b/playground/src/plugins/_util.ts @@ -3,6 +3,8 @@ import { is } from 'unist-util-is' const HeadingTag = ['h1', 'h2', 'h3'] -export const isHeading = (t: any): t is Element => is(t, { type: 'element' }) && HeadingTag.includes((t as Element).tagName) +export const isHeading = (t: any, tagName?: string | string[]): t is Element => is(t, { type: 'element' }) && tagName ? [tagName].flat().includes((t as Element).tagName) : HeadingTag.includes((t as Element).tagName) export const isTable = (t: any): t is Element => is(t, { type: 'element', tagName: 'table' }) && HeadingTag.includes((t as Element).tagName) export const isText = (t: any): t is Text => is(t, { type: 'text' }) +export const isUl = (t: T): t is T => is(t, { type: 'element', tagName: 'ul' }) +export const isBlockquote = (t: any) => is(t, { type: 'element', tagName: 'blockquote' }) diff --git a/playground/src/plugins/header.ts b/playground/src/plugins/header.ts new file mode 100644 index 00000000..93ed23cc --- /dev/null +++ b/playground/src/plugins/header.ts @@ -0,0 +1,47 @@ +import type { Plugin } from 'unified' +import { visit } from 'unist-util-visit' +import type { Element } from 'hast' +import { isBlockquote, isUl } from './_util' + +export const header: Plugin<[], Element> = function () { + return (root) => { + visit(root, { + type: 'element', + tagName: 'h1', + }, (paragraph, index, parent) => { + const len = parent.children.length + const children = [] + const delIndex: number[] = [] + + for (let i = index + 2; i < len; i += 2) { + const element = parent.children[i] as Element + + if (isBlockquote(element)) + continue + + if (!isUl(element)) + break + + children.push(element) + + element.tagName = 'header-ul' + + visit(element, { tagName: 'li' }, (li) => { + li.tagName = 'header-li' + }) + + delIndex.unshift(i) + } + + if (children.length) { + paragraph.tagName = 'header-h1' + delIndex.forEach(i => parent.children.splice(i, 1)) + parent.children.splice(index, 1, { + type: 'element', + tagName: 'header', + children: [paragraph, ...children], + }) + } + }) + } +} diff --git a/playground/src/plugins/index.ts b/playground/src/plugins/index.ts index 097d9b2f..10db4782 100644 --- a/playground/src/plugins/index.ts +++ b/playground/src/plugins/index.ts @@ -1,3 +1,4 @@ export * from './meta' export * from './table' export * from './description' +export * from './header'