From 3bdd64110e2a1582cea72cdea81af83cd016fe68 Mon Sep 17 00:00:00 2001 From: JounQin Date: Fri, 10 Dec 2021 01:35:10 +0800 Subject: [PATCH 1/3] chore: add changeset --- .changeset/wet-boxes-talk.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wet-boxes-talk.md diff --git a/.changeset/wet-boxes-talk.md b/.changeset/wet-boxes-talk.md new file mode 100644 index 00000000..3d600948 --- /dev/null +++ b/.changeset/wet-boxes-talk.md @@ -0,0 +1,5 @@ +--- +'cf-cleaner': patch +--- + +feat: first blood, should just work From e7104d9ebb6b05f13b94f0a1c12419e84c012b58 Mon Sep 17 00:00:00 2001 From: JounQin Date: Fri, 10 Dec 2021 02:21:12 +0800 Subject: [PATCH 2/3] feat: extract rehypeConfluence --- package.json | 7 ++- src/index.ts | 100 +-------------------------------------- src/rehype-confluence.ts | 89 ++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 101 deletions(-) create mode 100644 src/rehype-confluence.ts diff --git a/package.json b/package.json index c7d3e2e2..24edb5ec 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,11 @@ "main": "./lib/index.cjs", "module": "./lib/index.js", "exports": { - "import": "./lib/index.js", - "require": "./lib/index.cjs" + ".": { + "import": "./lib/index.js", + "require": "./lib/index.cjs" + }, + "./lib/rehype-confluence": "./lib/rehype-confluence.js" }, "types": "lib", "files": [ diff --git a/src/index.ts b/src/index.ts index 873599b1..06f64259 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,3 @@ -import { URL } from 'url' - -import type { Element, Root } from 'hast' import rehypeFormat from 'rehype-format' import rehypeParse from 'rehype-parse' import rehypePresetMinify from 'rehype-preset-minify' @@ -8,103 +5,8 @@ import rehypeStringify from 'rehype-stringify' import { unified } from 'unified' import type { MinimalDuplex } from 'unified-stream' import { stream } from 'unified-stream' -import { remove } from 'unist-util-remove' -import { visit } from 'unist-util-visit' - -const CLASSNAME_MAPPER = { - 'toc-macro': 'toc', - 'hide-toolbar': 'expandable', - 'confluence-information-macro': 'alert', - code: 'code', - panel: 'panel', - panelHeader: 'panel-header', - panelContent: 'panel-content', - confluenceTd: 'border-td', - confluenceTh: 'border-th', -} - -// eslint-disable-next-line sonarjs/cognitive-complexity -export const rehypeConfluence = () => (root: Root) => { - remove( - root, - node => - node.type === 'element' && - (['style', 'script'].includes(node.tagName) || - (node.properties?.className as string[] | undefined)?.some(className => - ['aui-icon', 'hide-border-bottom', 'hidden'].includes(className), - )), - ) - remove(root, node => { - if (node.type === 'element' && node.tagName === 'p') { - return node.children.every(item => { - if (item.type === 'text') { - return !item.value.trim() - } - - return false - }) - } - }) - - visit( - root, - node => node.type === 'element' && !!(node as Element).properties, - _el => { - const properties = (_el as Element).properties! - for (const key of Object.keys(properties)) { - switch (key) { - case 'className': { - const className = properties.className as string[] - properties.className = className - // eslint-disable-next-line array-callback-return - .map(name => { - if (name in CLASSNAME_MAPPER) { - return CLASSNAME_MAPPER[name as keyof typeof CLASSNAME_MAPPER] - } - - if (name.startsWith('confluence-information-macro-')) { - return name.replace('confluence-information-macro-', 'alert-') - } - }) - .filter(Boolean) as string[] - if (properties.className.length === 0) { - delete properties.className - } - if (properties.style) { - delete properties.style - } - break - } - case 'dataSyntaxhighlighterParams': { - const params = properties[key] as string - const matched = /brush:\s*([^;]+);/.exec(params) - const lang = matched?.[1] - if (lang) { - properties.className = ['language-' + lang] - } - delete properties[key] - break - } - case 'href': { - const href = properties.href as string - const url = new URL(href) - const matched = /\?pageId=(\d+)/.exec(url.search) - if (matched) { - properties.href = '/knowledge/' + matched[1] + url.hash - } - break - } - default: { - if (key.startsWith('data')) { - delete properties[key] - } - } - } - } - }, - ) -} +import { rehypeConfluence } from './rehype-confluence' const getProcessor = (minify?: boolean | undefined) => { let processor = unified() diff --git a/src/rehype-confluence.ts b/src/rehype-confluence.ts new file mode 100644 index 00000000..80fbdfb7 --- /dev/null +++ b/src/rehype-confluence.ts @@ -0,0 +1,89 @@ +import type { Element, Root } from 'hast' +import { remove } from 'unist-util-remove' +import { visit } from 'unist-util-visit' + +const CLASSNAME_MAPPER = { + 'toc-macro': 'toc', + 'hide-toolbar': 'expandable', + 'confluence-information-macro': 'alert', + code: 'code', + panel: 'panel', + panelHeader: 'panel-header', + panelContent: 'panel-content', + confluenceTd: 'border-td', + confluenceTh: 'border-th', +} + +// eslint-disable-next-line sonarjs/cognitive-complexity +export const rehypeConfluence = () => (root: Root) => { + remove( + root, + node => + node.type === 'element' && + (['style', 'script'].includes(node.tagName) || + (node.properties?.className as string[] | undefined)?.some(className => + ['aui-icon', 'hide-border-bottom', 'hidden'].includes(className), + )), + ) + + remove(root, node => { + if (node.type === 'element' && node.tagName === 'p') { + return node.children.every(item => { + if (item.type === 'text') { + return !item.value.trim() + } + + return item.type === 'element' && item.tagName === 'br' + }) + } + }) + + visit( + root, + node => node.type === 'element' && !!(node as Element).properties, + _el => { + const properties = (_el as Element).properties! + for (const key of Object.keys(properties)) { + switch (key) { + case 'className': { + const className = properties.className as string[] + properties.className = className + // eslint-disable-next-line array-callback-return + .map(name => { + if (name in CLASSNAME_MAPPER) { + return CLASSNAME_MAPPER[name as keyof typeof CLASSNAME_MAPPER] + } + + if (name.startsWith('confluence-information-macro-')) { + return name.replace('confluence-information-macro-', 'alert-') + } + }) + .filter(Boolean) as string[] + if (properties.className.length === 0) { + delete properties.className + } + if (properties.style) { + delete properties.style + } + break + } + case 'dataSyntaxhighlighterParams': { + const params = properties[key] as string + const matched = /brush:\s*([^;]+);/.exec(params) + const lang = matched?.[1] + if (lang) { + properties.className = ['language-' + lang] + } + delete properties[key] + break + } + default: { + if (key.startsWith('data')) { + delete properties[key] + } + } + } + } + }, + ) +} From ec4e9dbbde4188a63b2720fdf272dc75f3e5024d Mon Sep 17 00:00:00 2001 From: JounQin Date: Fri, 10 Dec 2021 02:42:03 +0800 Subject: [PATCH 3/3] Create cold-spies-fold.md --- .changeset/cold-spies-fold.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cold-spies-fold.md diff --git a/.changeset/cold-spies-fold.md b/.changeset/cold-spies-fold.md new file mode 100644 index 00000000..bd6c7821 --- /dev/null +++ b/.changeset/cold-spies-fold.md @@ -0,0 +1,5 @@ +--- +"cf-cleaner": patch +--- + +feat: extract rehypeConfluence