A simple markdown editor base monaco-editor and markdown-it
- Code highlighting. by highlight.js or shiki
- Code Group support
- Custom Container support
- KateX support
- Mermaid support
- plantuml support
- flowchart support
- Swiper support
- Qrcode support
- github emoji support
- toc support
- include a remote markdown file
- Multi theme support, theme from juejin-markdown-themes
- export md, html, png files
- export Markmap support
- XLSX File view by x-spreadsheet and sheetjs
- support custom toolbar
- Prettier format support
- dark model support
npm i mdpress-editor
#or
yarn add mdpress-editor
<link rel="stylesheet" href="https://unpkg.com/mdpress-editor/index.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/mdpress-editor/dist/mdpress-editor.min.js"></script>
- highlight.js is external you need:
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
- It contains a large number of plugins
Considering the size of the packaging, so some plugin packages require you to dynamically register them
When using these plugins, you need to inject the necessary plugin packages
require(['vs/editor/editor.main'], function() {
registerMonaco(monaco);
});
prettier.prettierPlugins = prettierPlugins;
registerPrettier(prettier);
...
Built in highlight.js as a Code highlighting tool. If you like shiki, you can register shiki as a Code highlighting tool
It is a standalone folder that requires you to manually copy when used in the project
you can:
- copy from
node-moudules/mdress-editor/theme
- set theme url from cdn url when create
MDEditor
<script src="./lib/prettier/standalone.js"></script>
<script src="./lib/prettier/plugins/acorn.js"></script>
<!-- <script src="./lib/prettier/plugins/angular.js"></script> -->
<script src="./lib/prettier/plugins/babel.js"></script>
<script src="./lib/prettier/plugins/estree.js"></script>
<!-- <script src="./lib/prettier/plugins/flow.js"></script> -->
<!-- <script src="./lib/prettier/plugins/glimmer.js"></script> -->
<!-- <script src="./lib/prettier/plugins/graphql.js"></script> -->
<script src="./lib/prettier/plugins/html.js"></script>
<script src="./lib/prettier/plugins/markdown.js"></script>
<!-- <script src="./lib/prettier/plugins/meriyah.js"></script> -->
<script src="./lib/prettier/plugins/postcss.js"></script>
<script src="./lib/prettier/plugins/typescript.js"></script>
<!-- <script src="./lib/prettier/plugins/yaml.js"></script> -->
more info for prettier in browser
import 'mdpress-editor/index.css';
import {
showLoading,
hideLoading
} from 'mdpress-editor';
or
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/mdpress-editor/dist/mdpress-editor.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/mdpress-editor/index.css">
<script>
mdpress.registerMonaco(window.monaco);
mdpress.showLoading();
mdpress.hideLoading();
...
</script>
get markdown-it instance
import {
getMarkdownIt
} from 'mdpress-editor';
const md = getMarkdownIt();
md.use( /**you plugin**/ );
all theme list
import 'mdpress-editor/index.css';
import {
themes
} from 'mdpress-editor';
console.log(themes);
import {
showLoading,
hideLoading
} from 'mdpress-editor';
require(['vs/editor/editor.main'], function() {
registerMonaco(window.monaco);
});
shiki
.getHighlighter({
theme: 'material-theme-palenight',
langs: languages
})
.then(highlighter => {
registerShikiHighlighter(highlighter);
});
prettier.prettierPlugins = prettierPlugins;
registerPrettier(prettier);
registerSwiper(Swiper);
registerQRCode(QRCode);
registerMermaid(mermaid);
registerXLSX(XLSX);
registerX_spreadsheet(x_spreadsheet);
registerFlowChart(flowchart);
Editor Core Object
import {
showLoading,
hideLoading,
MDEditor
} from 'mdpress-editor';
const mdEditor = new MDEditor(dom, {
preview: true, //open preview model
theme: 'vitepress',
dark: false,
themeURL: './../theme/', //theme files path
themeCache: true, //open theme cache
tocOpen: false, //open toc
emojiURL: 'https://cdn.jsdelivr.net/npm/@emoji-mart/data',
//if you need offline,you can config your iconfont url
iconfontURL: '//at.alicdn.com/t/c/font_4227162_4oipkq7kqoo.css',
//monaco config
monacoOptions: {
language: 'markdown',
value: '',
automaticLayout: true
},
prettierOptions: {
tabWidth: 4
}
})
- setValue(value)
mdEditor.setValue('# hello \n ');
- getValue()
- getSelectText()
const [range, text] = mdEditor.getSelectText();
- getSelectRange()
const [starRange, endRange] = mdEditor.getSelectRange();
- getCurrentRange()
const [range] = mdEditor.getCurrentRange();
- getIcons()
const icons = mdEditor.getIcons();
- isPreview()
- isFullScreen()
- isToc()
- isDark()
- getContainer()
get eidtor container
- getEditor()
get monaco editor
const monacoEditor = mdEditor.getEditor();
monacoEditor.executeEdits('', [{
range,
text
}]);
- setTheme()
mdEditor.setTheme('vitepress');
- getTheme()
- openPreview()
- closePreview()
- openFullScreen()
- closeFullScreen()
- openToc()
- closeToc()
- openDark()
- closeDark()
- openfullscreen
- closefullscreen
- openpreview
- closepreview
- themechange
- opentoc
- closetoc
- opendark
- closedark
- paste
mdEditor.on('paste', e => {
console.log(e);
let files = e.clipboardData.files || [];
})
you can listen paste
for get files for upload images or other files
the icon for toolbar
const icon = new ToolIcon({
icon: 'icon-zitijiacu', //iconfont icon name
title: '加粗',
className: '', //custom className
position: 'left' //the postion,left or right
});
icon.on('click', e => {
console.log(e);
const mdEditor = e.target.getEditor();
});
icon.addTo(mdEditor);
- getDom()
- on(event, handler)
icon.on('click', e => {
console.log(e);
})
- getMDEditor()
- addTo(mdEditor)
- remove()
- show()
- hide()
- isVisible()
custom a toolicon for upload markdown file
function customIcons() {
const data = {
icon: 'icon-file-markdown1',
title: '我是自定义按钮-导入markdown',
className: 'red'
}
const icon = new ToolIcon(data);
icon.addTo(mEditor);
icon.on('click', () => {
const parseMd = (file) => {
const fileRender = new FileReader();
fileRender.onload = () => {
if (mEditor && fileRender.result) {
mEditor.setValue(fileRender.result);
}
};
fileRender.readAsText(file);
};
const inputFile = document.createElement('input');
inputFile.type = 'file';
inputFile.accept = '.md';
inputFile.addEventListener('change', () => {
if (inputFile.files.length) {
parseMd(inputFile.files[0]);
} else {
alert('没有发现上传文件');
}
});
inputFile.click();
})
}