Skip to content

Commit

Permalink
chore(admin): refine custom-container plugin (#244)
Browse files Browse the repository at this point in the history
* chore(admin): refine custom-container plugin

* chore: tweaks

* chore: tweaks
  • Loading branch information
Mister-Hope committed Mar 11, 2023
1 parent ed2689f commit 982a41b
Showing 1 changed file with 96 additions and 85 deletions.
181 changes: 96 additions & 85 deletions packages/admin/src/components/Editor/customContainer.tsx
@@ -1,109 +1,120 @@
import { BytemdPlugin } from 'bytemd';
import { BytemdPlugin } from "bytemd";
import remarkDirective from "remark-directive";
import { visit } from "unist-util-visit";

import remarkDirective from 'remark-directive';
import { visit } from 'unist-util-visit';
import { icons } from './icons';
export function customContainer(): BytemdPlugin {
return {
remark: (processer) => processer.use(remarkDirective).use(customContainerPlugin),

viewerEffect: ({ markdownBody }) => {
const els = markdownBody.querySelectorAll('.custom-container');
els.forEach((el) => {
const type = el.className.replace('custom-container', '').trim();
const title = el.getAttribute('type');
const titleEl = document.createElement('p');
titleEl.className = `custom-container-title ${title}`;

const icon = icons[type];
const html = `${icon}<span>${title}</span>`;
import { icons } from "./icons";

titleEl.innerHTML = html;
const CUSTOM_CONTAINER_ICON =
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 1024 1024"><path d="M157.4 966.004a99.435 99.435 0 0 1-99.334-99.287V668.09a99.468 99.468 0 0 1 99.333-99.287h709.323a99.425 99.425 0 0 1 99.282 99.287v198.626a99.393 99.393 0 0 1-99.282 99.287zm-14.2-297.913v198.626a14.234 14.234 0 0 0 14.2 14.199h709.322a14.233 14.233 0 0 0 14.199-14.2V668.092a14.266 14.266 0 0 0-14.2-14.199H157.4a14.266 14.266 0 0 0-14.198 14.2zm14.2-212.824a99.436 99.436 0 0 1-99.334-99.288V157.353a99.468 99.468 0 0 1 99.333-99.287h709.323a99.424 99.424 0 0 1 99.282 99.287V355.98a99.393 99.393 0 0 1-99.282 99.287zM143.2 157.353V355.98a14.233 14.233 0 0 0 14.2 14.199h709.32a14.233 14.233 0 0 0 14.2-14.2V157.354a14.266 14.266 0 0 0-14.2-14.199H157.4a14.267 14.267 0 0 0-14.198 14.2z"/></svg>';

el.insertBefore(titleEl, el.firstChild);
});
},
actions: [
{
title: '自定义高亮块',
icon: '<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3441" width="16" height="16" fill="currentColor"><path d="M157.399245 966.003965a99.435203 99.435203 0 0 1-99.33321-99.287213V668.09133a99.4682 99.4682 0 0 1 99.33321-99.287213h709.322511a99.425203 99.425203 0 0 1 99.282213 99.287213v198.625422a99.393206 99.393206 0 0 1-99.282213 99.287213z m-14.199029-297.912635v198.625422a14.234027 14.234027 0 0 0 14.199029 14.199029h709.322511a14.233027 14.233027 0 0 0 14.19903-14.199029V668.09133a14.266025 14.266025 0 0 0-14.19903-14.19903H157.399245a14.266025 14.266025 0 0 0-14.198029 14.19903z m14.199029-212.824452a99.436203 99.436203 0 0 1-99.33321-99.288212V157.353243a99.4682 99.4682 0 0 1 99.33321-99.287212h709.322511a99.424203 99.424203 0 0 1 99.282213 99.287212v198.625423a99.393206 99.393206 0 0 1-99.282213 99.287212z m-14.198029-297.913635v198.625423a14.233027 14.233027 0 0 0 14.199029 14.199029h709.321511a14.233027 14.233027 0 0 0 14.19903-14.199029V157.353243a14.266025 14.266025 0 0 0-14.19903-14.199029H157.399245a14.267025 14.267025 0 0 0-14.198029 14.199029z" p-id="3442"></path></svg>',
cheatsheet: `:::info{title="标题"}`,
handler: {
type: 'dropdown',
actions: customContainerActionItems.map(({ title, code }) => {
return {
title,
handler: {
type: 'action',
click({ editor, appendBlock, codemirror }) {
const { line } = appendBlock(code);
editor.setSelection(codemirror.Pos(line + 1, 0), codemirror.Pos(line + 1));
editor.focus();
},
},
};
}),
},
},
],
};
}

const customContainerActionItems = [
const CUSTOM_CONTAINER_ACTIONS = [
{
title: 'info',
title: "info",
code: `:::info{title="相关信息"}\n相关信息\n:::`,
},
{
title: 'note',
title: "note",
code: `:::note{title="注"}\n注\n:::`,
},
{
title: 'warning',
title: "warning",
code: `:::warning{title="注意"}\n注意\n:::`,
},
{
title: 'danger',
title: "danger",
code: `:::danger{title="警告"}\n警告\n:::`,
},
{
title: 'tip',
title: "tip",
code: `:::tip{title="提示"}\n提示\n:::`,
},
];

const customContainerTitleMap: Record<string, string> = {
note: '注',
info: '相关信息',
warning: '注意',
danger: '警告',
tip: '提示',
const CUSTOM_CONTAINER_TITLE: Record<string, string> = {
note: "注",
info: "相关信息",
warning: "注意",
danger: "警告",
tip: "提示",
};
function customContainerPlugin() {
return (tree) => {
visit(tree, (node) => {
if (
node.type === 'textDirective' ||
node.type === 'leafDirective' ||
node.type === 'containerDirective'
) {
if (node.type == 'containerDirective') {
const data = node.data || (node.data = {});
const tagName = node.name;
data.hName = 'div';
const { attributes } = node || {};
const title = attributes?.title || customContainerTitleMap[tagName];
const cls = `custom-container ${tagName}`;
data.hProperties = {
class: cls,
['type']: title,
};
return {
...node,
data,
};
}

// FIXME: Addd Types
const customContainerPlugin = () => (tree) => {
visit(tree, (node) => {
if (
node.type === "textDirective" ||
node.type === "leafDirective" ||
node.type === "containerDirective"
) {
if (node.type == "containerDirective") {
const { attributes, data = {}, name: tagName } = node;

const title = attributes?.title || CUSTOM_CONTAINER_TITLE[tagName];
const cls = `custom-container ${tagName}`;

data.hName = "div";
data.hProperties = {
class: cls,
["type"]: title,
};

return {
...node,
data,
};
}
});
}
});
};

export function customContainer(): BytemdPlugin {
return {
remark: (processor) =>
processor.use(remarkDirective).use(customContainerPlugin),

viewerEffect: ({ markdownBody }) => {
const elements = markdownBody.querySelectorAll(".custom-container");

elements.forEach((element) => {
const type = element.className.replace("custom-container", "").trim();
const title = element.getAttribute("type");
const titleEl = document.createElement("p");

titleEl.className = `custom-container-title ${title}`;

const icon = icons[type];
const html = `${icon}<span>${title}</span>`;

titleEl.innerHTML = html;

element.insertBefore(titleEl, element.firstChild);
});
},

actions: [
{
title: "自定义高亮块",
icon: CUSTOM_CONTAINER_ICON,
cheatsheet: `:::info{title="标题"}`,
handler: {
type: "dropdown",
actions: CUSTOM_CONTAINER_ACTIONS.map(({ title, code }) => ({
title,
handler: {
type: "action",
click: ({ editor, appendBlock, codemirror }) => {
const { line } = appendBlock(code);

editor.setSelection(
codemirror.Pos(line + 1, 0),
codemirror.Pos(line + 1)
);
editor.focus();
},
},
})),
},
},
],
};
}

0 comments on commit 982a41b

Please sign in to comment.