JustYeh的前端博客

Markdown编辑器simplemde-markdown-editor

2019-07-09

插件markdown

cnode中文社区里面使用了一款不错的Markdown编辑器,名字叫做editor,网友NextStepWebs基于这个版本做了一些改进。我尽我最大可能做一些翻译工作,希望能帮助的大家;当然,如果你熟悉英文,可以直接参考官方文档

在线demo

特性

  • SimpleMDE 是一个嵌入式 JavaScript 编辑器,用于书写好看且易懂的 markdown格式文本。
  • 如果你对Markdown语法不够熟悉,SimpleMDE提供了更为简单的快捷键和工具栏。
  • SimpleMDE 不支持WYSIWYG(所见即所得),因为在编辑时呈现语法可以清楚地显示预期的结果。
  • 美观的样式:标题更大,强调的词语为斜体,链接带有下划线等。
  • 内置自动保存和拼写检查功能

安装

使用npm

npm install simplemde --save

使用bower

bower install simplemde --save

在浏览器中使用

注意:有些cdn服务可能会晚几天才能更新到最新版本。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>

快速开始

基本使用

安装之后,SimpleMDE会绑定在页面的第一个textarea元素上。

<script>
var simplemde = new SimpleMDE();
</script>

使用在特定的textarea上

源生js写法

<script>
var simplemde = new SimpleMDE({ element: document.getElementById("MyID") });
</script>

jQuery写法

<script>
var simplemde = new SimpleMDE({ element: $("#MyID")[0] });
</script>

get/set内容

//get
simplemde.value();
//set
simplemde.value("This text will appear in the editor");

配置项

autoDownloadFontAwesome

为true时会强制下载FontAwesome字体图标,为false时会阻止下载,默认值undefined时,会自动判断页面里面有没有FontAwesome,默认值undefined。

autofocus

是否使editor自动获取焦点,默认值false。

autosave

设置自动保存内容选项:

  • enabled:为true时时自动保存,默认值false。
  • delay:每次保存的时间间隔,默认值10000(10s)。
  • uniqueId:必须设置一个ID,便于可其他实例区分开来。

blockStyles

定义markdown标签的表现形式:

  • bold:** 或者 __ ; 默认为 **
  • code: ``` 或者 ~ ; 默认为 ```
  • italic:* 或者 _ ; 默认为 *

element

设置绑定的DOM元素,默认为页面中的第一个textarea。

forceSync

当内容改变时,是否进行强制存储,默认值false。

hideIcons

要隐藏的图标名称数组。 可以用于隐藏默认显示的图标,而不完全自定义工具栏。

indentWithTabs

为false时,缩进使用空格而不是制表符,默认值true。

initialValue

如果设置了该项,则为editor设置了默认值。

insertTexts

设置插入的内容,值为一个包含两个元素的数组,第一个元素将是在光标或高亮之前插入的文本,第二个元素将插入到后面

这是默认链接值:["[", "](http://)"]

lineWrapping

为false时禁用换行,默认值true。

parsingConfig

定义编辑期间解析Markdown的设置:

  • allowAtxHeaderWithoutSpace:是否在header的后面添加 #,默认false
  • strikethrough: 是否处理GFM删除线语法,,默认true
  • underscoresBreakWords: 是否让下划线是用于分隔单词的分隔符,默认false

placeholder

设置editor的占位内容。

previewRender

定义解析纯文本Markdown和返回HTML时的自定义函数,在用户预览时使用。

promptURLs

为true时点击链接或图像将显示一个prompt窗口,要求提供链接或图像URL,默认值true。

renderingConfig

定义预览Markdown时的设置:

  • singleLineBreaks:为false时禁用GFM的单行中断,默认true。
  • strikethrough: 是否使用highlight.js高亮插件,默认false;注意,为true你需要引入相关文件:
    <script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/github.min.css">

shortcuts

设置快捷键,参考下文快捷键。

showIcons

要隐藏的图标名称数组, 可以用于显示默认隐藏的图标,而不完全自定义工具栏。

spellChecker

是否启用拼写检查,默认值true。

status

为flase时影藏status bar。

styleSelectedText

如果为false,将移除用于选中项上的CodeMirror-selectedtext样式,值为一个数组,内容为内置状态栏项目。

tabSize 设置tab的大小,默认值2。

toolbar 为false时,影藏toolbar,值为一个数组,参考下文toolbar图标。

toolbar 是否启用工具栏按钮tips提示效果,默认值true。

Toolbar图标

下面是内置的工具栏图标(默认部分启用)列表,在表格中,Name是图标的名称,Action是要打开的函数或URL,Tooltip是图标提示文字,class是作用于图标上的样式。

Name Action Tooltip Class
bold toggleBold Bold fa fa-bold
italic toggleItalic Italic fa fa-italic
strikethrough toggleStrikethrough Strikethrough fa fa-strikethrough
heading toggleHeadingSmaller Heading fa fa-header
heading-smaller toggleHeadingSmaller Smaller Heading fa fa-header
heading-bigger toggleHeadingBigger Bigger Heading fa fa-lg fa-header
heading-1 toggleHeading1 Big Heading fa fa-header fa-header-x fa-header-1
heading-2 toggleHeading2 Medium Heading fa fa-header fa-header-x fa-header-2
heading-3 toggleHeading3 Small Heading fa fa-header fa-header-x fa-header-3
code toggleCodeBlock Code fa fa-code
quote toggleBlockquote Quote fa fa-quote-left
unordered-list toggleUnorderedList Generic List fa fa-list-ul
ordered-list toggleOrderedList Numbered List fa fa-list-ol
clean-block cleanBlock Clean block fa fa-eraser fa-clean-block
link drawLink Create Link fa fa-link
image drawImage Insert Image fa fa-picture-o
table drawTable Insert Table fa fa-table
horizontal-rule drawHorizontalRule Insert Horizontal Line fa fa-minus
preview togglePreview Toggle Preview fa fa-eye no-disable
side-by-side toggleSideBySide Toggle Side by Side fa fa-columns no-disable no-mobile
fullscreen toggleFullScreen Toggle Fullscreen fa fa-arrows-alt no-disable no-mobile
guide This link Markdown Guide fa fa-question-circle

自定义toolbar的用法:

// Customize only the order of existing buttons
var simplemde = new SimpleMDE({
    toolbar: ["bold", "italic", "heading", "|", "quote"],
});

// Customize all information and/or add your own icons
var simplemde = new SimpleMDE({
    toolbar: [{
            name: "bold",
            action: SimpleMDE.toggleBold,
            className: "fa fa-bold",
            title: "Bold",
        },
        {
            name: "custom",
            action: function customFunction(editor){
                // Add your own code
            },
            className: "fa fa-star",
            title: "Custom Button",
        },
        "|", // Separator
        ...
    ],
});

样式

为SimpleMDE设置最小高度

.CodeMirror, .CodeMirror-scroll {
    min-height: 200px;
}

也可以设置为固定高度:

.CodeMirror {
    height: 300px;
}

快捷键

SimpleMDE附带了一组预定义的键盘快捷键,但可以使用配置选项进行更改。

修改快捷键的方法:

var simplemde = new SimpleMDE({
    shortcuts: {
        "toggleOrderedList": "Ctrl-Alt-K", // alter the shortcut for toggleOrderedList
        "toggleCodeBlock": null, // unbind Ctrl-Alt-C
        "drawTable": "Cmd-Alt-T" // bind Cmd-Alt-T to drawTable action, which doesn't come with a default shortcut
    }
});

SimpleMDE可以智能识别你的操作系统,如果你在Windows上设置了一个快捷键Ctrl-B,在Mac上,他会被自动转化为Cmd-B

事件处理

SimpleMDE允许你捕获一些事件,事件列表可以参考这个网址:https://codemirror.net/doc/manual.html#events

var simplemde = new SimpleMDE();
simplemde.codemirror.on("change", function(){
    console.log(simplemde.value());
});
var simplemde = new SimpleMDE();
...
simplemde.toTextArea();
simplemde = null;

移除绑定

你可以通过调用'toTextArea()'方法来使textare恢复到最初始的状态,这时,自动保存功能将被解除, textarea会保留原来的的文本内容。

var simplemde = new SimpleMDE();
...
simplemde.toTextArea();
simplemde = null;

常见方法

var simplemde = new SimpleMDE();
simplemde.isPreviewActive(); // returns boolean
simplemde.isSideBySideActive(); // returns boolean
simplemde.isFullscreenActive(); // returns boolean
simplemde.clearAutosavedValue(); // no returned value

DEMO

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title>SimpleMDE Dome</title>
<link rel="stylesheet" href="simplemde.min.css">
<script src="simplemde.min.js"></script>
<style type="text/css">
body{
background: #eaebec;
}
h1{
font-size: 50px;
text-align: center;
}
.container{
background: #fff;
width: 800px;
padding: 20px;
margin: 50px auto;
}
</style>
</head>

<body>

<h1>SimpleMDE Dome</h1>

<div class="container">
<textarea name="" rows="" cols="" id="editor"></textarea>
</div>

<script type="text/javascript">
// Most options demonstrate the non-default behavior
var simplemde = new SimpleMDE({
    autofocus: true,
    autosave: {
        enabled: true,
        uniqueId: "editor01",
        delay: 1000,
    },
    blockStyles: {
        bold: "__",
        italic: "_"
    },
    element: document.getElementById("editor"),
    forceSync: true,
    hideIcons: ["guide", "heading"],
    indentWithTabs: false,
    initialValue: "SimpleMDE Dome",
    insertTexts: {
        horizontalRule: ["", "\n\n-----\n\n"],
        image: ["![](http://", ")"],
        link: ["[", "](http://)"],
        table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text     | Text      | Text     |\n\n"],
    },
    lineWrapping: false,
    parsingConfig: {
        allowAtxHeaderWithoutSpace: true,
        strikethrough: false,
        underscoresBreakWords: true,
    },
    placeholder: "placeholder",
   /* previewRender: function(plainText) {
    console.log(plainText)
        return customMarkdownParser(plainText); // Returns HTML from a custom parser
    },
    previewRender: function(plainText, preview) { // Async method
        setTimeout(function(){
            preview.innerHTML = customMarkdownParser(plainText);
        }, 250);

        return "Loading...";
    },*/
    promptURLs: true,
    renderingConfig: {
        singleLineBreaks: false,
        codeSyntaxHighlighting: true,
    },
    shortcuts: {
        drawTable: "Cmd-Alt-T"
    },
    showIcons: ["code", "table"],
    spellChecker: false,
    status: false,
    status: ["autosave", "lines", "words", "cursor"], // Optional usage
    status: ["autosave", "lines", "words", "cursor", {
        className: "keystrokes",
        defaultValue: function(el) {
            this.keystrokes = 0;
            el.innerHTML = "0 Keystrokes";
        },
        onUpdate: function(el) {
            el.innerHTML = ++this.keystrokes + " Keystrokes";
        }
    }], // Another optional usage, with a custom status bar item that counts keystrokes
    styleSelectedText: false,
    tabSize: 4,
    //toolbar: flase,
    //toolbarTips: false,
});
</script>

</body>
</html>