废话
距离上一次写文章已经过了大半年了,期间经历过想润回老家,刚好七月底公司裁员,休息了一个月,然后找到了一家上海的公司,空闲时候又把之前的博客网站拿过来折腾了一下。
上效果
思路
思路很简单,通过点击menu向编辑区添加主题文字,然后在预览区将主题文字相关的dom设置display:none不显示,同时动态添加link标签引入样式
贴代码自取
//这个是我自己cdn存的主题列表
import { themeList as themeMap } from './utils';
/**
*
* @param {*} options
* @param {Array} options.themeList 主题列表 {title:'主题名称', href: '样式链接'}
* @param {Function} options.onThemeChange 主题回调 参数为当前选中的主题样式css链接
* @returns
*/
function themePlugin(options = {}) {
if (options.onThemeChange && typeof options.onThemeChange !== 'function') {
console.error('onThemeChange 必须为函数');
}
return {
viewerEffect({ markdownBody }) {
const themeHTag = markdownBody.getElementsByTagName('h2')[0];
if (themeHTag && /theme|highlight/.test(themeHTag.innerText)) {
for (let i = 0; i < markdownBody.childNodes.length; i++) {
markdownBody.childNodes[i] && markdownBody.childNodes[i].style && (markdownBody.childNodes[i].style.display = 'none');
if (markdownBody.childNodes[i] === themeHTag) {
break;
}
}
}
},
actions: [
{
title: 'Markdown 主题',
icon: `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 2H2.66667C2.29848 2 2 2.29848 2 2.66667V6C2 6.36819 2.29848 6.66667 2.66667 6.66667H6C6.36819 6.66667 6.66667 6.36819 6.66667 6V2.66667C6.66667 2.29848 6.36819 2 6 2Z" stroke="#1D2129" stroke-width="1.33" stroke-linejoin="round"></path>
<path d="M6 9.3335H2.66667C2.29848 9.3335 2 9.63197 2 10.0002V13.3335C2 13.7017 2.29848 14.0002 2.66667 14.0002H6C6.36819 14.0002 6.66667 13.7017 6.66667 13.3335V10.0002C6.66667 9.63197 6.36819 9.3335 6 9.3335Z" stroke="#1D2129" stroke-width="1.33" stroke-linejoin="round"></path>
<path d="M13.3334 2H10C9.63185 2 9.33337 2.29848 9.33337 2.66667V6C9.33337 6.36819 9.63185 6.66667 10 6.66667H13.3334C13.7016 6.66667 14 6.36819 14 6V2.66667C14 2.29848 13.7016 2 13.3334 2Z" stroke="#1D2129" stroke-width="1.33" stroke-linejoin="round"></path>
<path d="M13.3334 9.3335H10C9.63185 9.3335 9.33337 9.63197 9.33337 10.0002V13.3335C9.33337 13.7017 9.63185 14.0002 10 14.0002H13.3334C13.7016 14.0002 14 13.7017 14 13.3335V10.0002C14 9.63197 13.7016 9.3335 13.3334 9.3335Z" stroke="#1D2129" stroke-width="1.33" stroke-linejoin="round"></path>
</svg>`,
handler: {
type: 'dropdown',
actions: (options.themeList || themeMap).map((item) => ({
title: item.title,
cheatsheet: `---
theme: ${item.title}
---`,
handler: {
type: 'action',
click({ editor }) {
const headerPart = /^-{3}[A-Za-z0-9_:\s-]*-{3}\n*/.exec(editor.getValue());
if (headerPart) {
editor.setValue(editor.getValue().replace(headerPart[0], headerPart[0].replace(/theme:\s[\w]*\n/, `theme: ${item.title}\n`)));
} else {
editor.setValue(`---\ntheme: ${item.title}\n---\n\n${editor.getValue()}`);
}
loadCSS(item.href);
options.onThemeChange && options.onThemeChange(item.href);
}
}
}))
}
}
]
};
}
export default themePlugin;
function loadCSS(href) {
let link = document.getElementById('markdown-style');
if (!link) {
link = document.createElement('link');
link.setAttribute('id', 'markdown-style');
link.rel = 'stylesheet';
}
link.href = href;
document.head.appendChild(link);
}