showdown.js

showdown.js 是一个 javascript 环境下 markdown 语法解释工具

我们需要先下载解释器 showdown.js,传送门:https://github.com/showdownjs/showdown

然后将 showdown.js 引入到内容编辑页面的模板文件中。

还要引入下面的JS代码:

function compile(){
    var text = document.getElementById("content").value;
    var converter = new showdown.Converter();
    var html = converter.makeHtml(text);
    document.getElementById("result").innerHTML = html;
}

上面代码中,text 是获取你输入的 markdown 语法的文章内容,然后实例化解释器对象,然后使用解释器将你输入的文章内容翻译成目标样式的界面内容,即 html,然后输出即可。

SimpleMDE Markdown Editor

一个可替代 javascript textarea 替代品,用于编写美观且易于理解的 markdown

官网地址:https://simplemde.com/

下载解压后,主要将 simplemde.min.jssimplemde.min.css 拿出来放到 static 目录

<link rel="stylesheet" href="/static/plugins/simplemde/simplemde.min.css">
<div id="markdown-editor">
     <textarea id="editorarea"style="display:none;"><#if post??>${post.postContent?if_exists}</#if></textarea>
</div>
<script src="/static/plugins/jquery/jquery.min.js"></script>
<script src="/static/plugins/simplemde/simplemde.min.js"></script>
<script>
    /**
     * 加载编辑器
     */
    // 创建一个 SimpleMDE 的实例
    var simplemde = new SimpleMDE({
         // 要绑定的 textarea 元素
        element: document.getElementById("editorarea"),
        // 占位符
        placeholder: '请使用 Markdown 格式书写 ;-),代码片段黏贴时请注意使用高亮语法。',
        // 禁用拼写检查
        spellChecker: false,
        autoDownloadFontAwesome: false,
        autofocus: true,
        // 启用自动保存,uniqueId 是一个用于区别于其他站点的标识
        autosave: {
            enabled: true,
            uniqueId: "editor-temp-page-<#if post??>${post.postId}<#else>1</#if>",
            delay: 10000
        },
        // 启用代码高亮,需要引入 highlight.js
        renderingConfig: {
            codeSyntaxHighlighting: true
        },
        //显示图标
        showIcons: ["code", "table"],
        status: true,
        status: ["autosave", "lines", "words"],
        tabSize: 4
    });
</script>
simplemde.value() // 获得编辑器的文本内容
simplemde.markdown(simplemde.value()) // 包含 `html` 标签的内容

相关参数(具体实际请去官网上查阅):

  • autoDownloadFontAwesome: 如果设置为true,会强制下载字体(用于图标)。如果设置为false,则阻止下载。默认undefined,这将智能地检查是否已经包括字体,然后相应地下载
  • autofocus: 如果设置为true,自动对焦编辑器。默认为false
  • autosave: 保存正在编写的文本,并将在将来加载它回来。提交包含的表单时,它会忘记文本

    • enabled: 如果设置为true,自动保存文本。默认为 false.
    • delay: 节省之间的延迟,在毫秒内。默认到 10000(10s).
    • uniqueId: 你必须设置一个独特的字符串标识符,以便简单MDE可以自动保存。将此内容与网站上其他简单MDE的其他实例分开的东西。
  • blockStyles:自定义某些按钮,样式文本块的行为方式

    • bold 可以设置为 或 __。默认为
    • code 可以设置为` 或 ~~。默认为 `
    • italic 可以设置为 或 _。默认为
  • element: 要使用的文本区域的DOM元素。默认到页面上的第一个文本区域.
  • forceSync: 如果设置为true, 强制在 Simplemde 中更改的文本立即存储在原始文本区域中。默认为 false.
  • hideIcons: 要隐藏的图标名称。可用于隐藏默认情况下显示的特定图标,而无需完全自定义工具栏.
  • indentWithTabs: 如果设置为false,凹痕使用空间而不是选项卡。默认为true.
  • initialValue: 如果设置,将自定义编辑器的初始值.
  • insertTexts: 自定义插入文本的某些按钮的行为方式。采用包含两个元素的阵列。第一个元素将是在光标或高光亮显示之前插入的文本,第二个元素将在光标或高光亮显示之前插入。例如,这是默认链接值:。["[", "](http://)"]

    • 水平规则
    • 图像
    • 链接
    • 表格
  • lineWrapping: 如果设置为false ,禁用线包装。默认为true .
  • parsingConfig: 调整设置,在编辑过程中解析记分(不预览).

    • allowAtxHeaderWithoutSpace: 如果设置为true,将呈现标题后没有空间。默认为false .
    • strikethrough: 如果设置为 false, 将不会处理 Gfm 语法. 默认为 true.
    • underscoresBreakWords: 如果设置为true,让下划线成为分离单词的划界器。默认为flase
  • placeholder: 应显示的自定义占位符
  • previewRender:用于解析纯文本标记和返回 HTML 的自定义功能。用户预览时使用。
  • promptURLs: 如果设置为true JS 警报窗口,则会显示请求链接或图像 URL。默认为false
  • renderingConfig: 调整编辑期间解析 Markdown 的设置(非预览)。

    • singleLineBreaks: 如果设置为 true,将在 # 后呈现没有空格的标题。默认为false 。
    • codeSyntaxHighlighting: 如果设置为 true,将使用 highlight.js 突出显示。默认为假。要使用此功能,您必须在页面上包含 highlight.js。例如,包括脚本和 CSS 文件,如:

      <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:如果设置为 false,则禁用拼写检查器。默认为true
  • status: 如果设置为 false,则隐藏状态栏。默认为内置状态栏项的数组

    • 或者,您可以设置要包含的状态栏项目数组以及顺序。您甚至可以定义自己的自定义状态栏项目
  • styleSelectedText: 如果设置为 false,则从所选行中删除 CodeMirror-selectedtext 类。默认为true
  • tabSize: 如果设置,自定义选项卡大小。默认为2.
  • toolbar: 如果设置为false,则隐藏工具栏。默认是全部图标.
  • toolbarTips: 如果设置为false,禁用工具栏按钮提示。默认为true

不推荐的原因:拓展较少,使用不太灵活。

editor.md(推荐)

Editor.md 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。

主要特性:

项目地址:https://gitee.com/pandao/editor.md

<link rel="stylesheet" href="editor.md/css/editormd.min.css" />
<div id="markdown-editor">
    <textarea class="editormd-markdown-textarea" name="test-editormd-markdown-doc" id="editormd"></textarea>
    <!-- 第二个隐藏文本域,用来构造生成的HTML代码,方便表单POST提交,这里的name可以任意取,后台接受时以这个name键为准 -->
    <!-- html textarea 需要开启配置项 saveHTMLToTextarea == true -->
    <textarea class="editormd-html-textarea" name="editorhtml" id="editorhtml"></textarea>
</div>
<script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="editormd/lib/marked.min.js"></script>
<script src="editormd/lib/prettify.min.js"></script>
<script src="editormd/lib/raphael.min.js"></script>
<script src="editormd/lib/underscore.min.js"></script>
<script src="editormd/lib/sequence-diagram.min.js"></script>
<script src="editormd/lib/flowchart.min.js"></script>
<script src="editormd/lib/jquery.flowchart.min.js"></script>
<script src="editormd/js/editormd.min.js"></script>
<script type="text/javascript">
    var llEditor = null;
    $(function () {
        llEditor = editormd("test-editor", {
            placeholder: '本编辑器支持Markdown编辑,左边编写,右边预览',  //默认显示的文字,这里就不解释了
            width: "90%",
            htmlDecode      : "style,script,iframe",
            height: 640,
            syncScrolling: "single",
            path: "editormd/lib/",   //你的path路径(原资源文件中lib包在我们项目中所放的位置)
            theme: "dark",//工具栏主题
            previewTheme: "dark",//预览主题
            editorTheme: "pastel-on-dark",//编辑主题
            saveHTMLToTextarea: true,
            emoji: false,
            taskList: true,
            tocm: true,         // Using [TOCM]
            tex: true,                   // 开启科学公式TeX语言支持,默认关闭
            flowChart: true,             // 开启流程图支持,默认关闭
            sequenceDiagram: true,       // 开启时序/序列图支持,默认关闭,
            toolbarIcons: function () {  //自定义工具栏,后面有详细介绍
                return editormd.toolbarModes['simple']; // full, simple, mini
            },
        });
        //上面的挑有用的写上去就行
    })

    testEditor.gotoLine(90);//转到第90行
    testEditor.show();//显示编辑器
    testEditor.hide();//隐藏编辑器
    //通过上面将MarkDown分成文本和html这里可以直接取值
    $("#editorhtml").val();//获取编辑器内容(不含html)
    $("#editormd").val();//获取编辑器html内容
    //未分开的话使用
    testEditor.getMarkdown();//获取编辑器内容(不含html)
    testEditor.getHTML();//获取编辑器html内容
    testEditor.watch();//开启双窗口对比
    testEditor.unwatch();//取消双窗口对比
    testEditor.previewing();//预览效果
    testEditor.fullscreen();//全屏(按ESC取消)
    testEditor.showToolbar();//显示工具栏
    testEditor.hideToolbar();//隐藏工具栏
    testEditor.config({
        tocDropdown: true,
        tocTitle: "目录 Table of Contents",
    });//TOC下拉菜单
    testEditor.config("tocDropdown", false);//TOC默认
</script>

注意: 一定要加上 htmlDecode,不然你再编辑的时候 写了个 <script> 会被解析,很难受,而且还有 xss 注入的漏洞,因此 后台还要再转义一下。

完整示例: http://editor.md.ipandao.com/examples/html-preview-markdown-to-html.html

mode                 : "gfm",          // gfm or markdown
name                 : "",             // 帖子的表单元素名称
value                : "",             // CodeMirror 的值,如果模式不是 gfm/markdown
theme                : "",             // Editor.md自带主题,v1.5.0之前是CodeMirror主题,默认empty
editorTheme          : "default",      // 编辑区主题,这是 v1.5.0 的 CodeMirror 主题
previewTheme         : "",             // 预览区主题,默认empty
markdown             : "",             // Markdown源码
appendMarkdown       : "",             // 如果在 init textarea 中的值不为空,则将 markdown 附加到 textarea
width                : "100%",
height               : "100%",
path                 : "./lib/",       // 依赖模块文件目录
pluginPath           : "",             // 如果此项为空,则默认使用 settings.path + "../plugins/"
delay                : 300,            // 延迟解析 markdown 到 html, Uint : ms
autoLoadModules      : true,           // 自动加载依赖模块文件
watch                : true,           // 双面预览开启or关闭
placeholder          : "Enjoy Markdown! coding now...",
gotoLine             : true,           // 启用/禁用转到一行
codeFold             : false,           // 代码折叠
autoHeight           : false,
autoFocus            : true,           // 启用/禁用自动焦点编辑器左侧输入区域
autoCloseTags        : true,           // 自动关闭标签
searchReplace        : true,           // 启用/禁用(CodeMirror)搜索和替换功能
syncScrolling        : true,           // 选项:true|false|single,默认为true
readOnly             : false,          // 启用/禁用只读模式
tabSize              : 4,
indentUnit           : 4,
lineNumbers          : true,           // 显示编辑器行号
lineWrapping         : true,           // 换行
autoCloseBrackets    : true,            // 自动关闭括号
showTrailingSpace    : true,            // 显示尾随空间
matchBrackets        : true,            //匹配括号
indentWithTabs       : true,            //带制表符的缩进
styleSelectedText    : true,            //样式选择文本
matchWordHighlight   : true,           // 选项:true、false、“onselected”
styleActiveLine      : true,           // 突出显示当前行
dialogLockScreen     : true,            //对话框锁屏
dialogShowMask       : true,            //对话框显示蒙版
dialogDraggable      : true,            //对话框可拖动
dialogMaskBgColor    : "#fff",
dialogMaskOpacity    : 0.1,                //对话框遮罩不透明度
fontSize             : "13px",
saveHTMLToTextarea   : false,          // 如果启用,编辑器将创建一个 <textarea name="{editor-id}-html-code"> 标记保存表单发布到服务器端的 HTML 代码。
disabledKeyMaps      : [],
    
onload               : function() {},
onresize             : function() {},
onchange             : function() {},
onwatch              : null,
onunwatch            : null,
onpreviewing         : function() {},
onpreviewed          : function() {},
onfullscreen         : function() {},
onfullscreenExit     : function() {},
onscroll             : function() {},
onpreviewscroll      : function() {},
    
imageUpload          : false,          // 启用/禁用上传
imageFormats         : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL       : "",             // Upload url
crossDomainUpload    : false,          // 启用/禁用跨域上传
uploadCallbackURL    : "",             // 跨域上传回调url

toc                  : true,           // 目录
tocm                 : false,          // 使用 [TOCM],自动创建 ToC 下拉菜单
tocTitle             : "",             // 用于 ToC 下拉菜单按钮
tocDropdown          : false,          // 启用/禁用目录下拉菜单
tocContainer         : "",             // 自定义目录容器选择器
tocStartLevel        : 1,              // 从H1创建ToC
htmlDecode           : false,          // 打开 HTML 标签识别
pageBreak            : true,           // 启用解析分页符 [========]
atLink               : true,           // for @link
emailLink            : true,           // 对于电子邮件地址自动链接
taskList             : false,          // 启用 Github Flavored Markdown 任务列表
emoji                : false,          // :emoji: , 支持 Github 表情符号、推特表情符号(Twemoji);
tex                  : false,          // TeX(LaTeX),基于KaTeX
flowChart            : false,          // flowChart.js 仅支持 IE9+
sequenceDiagram      : false,          // sequenceDiagram.js 仅支持 IE9+
previewCodeHighlight : true,           // 启用/禁用编辑器预览区域的代码高亮

toolbar              : true,           // 显示或隐藏工具栏
toolbarAutoFixed     : true,           // 在窗口滚动自动固定位置
toolbarIcons         : "full",         // 工具栏图标模式,选项:完整、简单、迷你,参见 `editormd.toolbarModes` 属性。
toolbarTitles        : {},
toolbarHandlers      : {
    ucwords : function() {
        return editormd.toolbarHandlers.ucwords;
    },
    lowercase : function() {
        return editormd.toolbarHandlers.lowercase;
    }
},
toolbarCustomIcons   : {               // 使用 html 标签创建工具栏图标,未使用的默认 <a> 标签。
        lowercase        : "<a href=\"javascript:;\" title=\"Lowercase\" unselectable=\"on\"><i class=\"fa\" name=\"lowercase\" style=\"font-size:24px;margin-top: -10px;\">a</i></a>",
        "ucwords"        : "<a href=\"javascript:;\" title=\"ucwords\" unselectable=\"on\"><i class=\"fa\" name=\"ucwords\" style=\"font-size:20px;margin-top: -3px;\">Aa</i></a>"
    },
    toolbarIconTexts     : {},
    
    lang : {  // Language data, you can custom your language.
        name        : "zh-cn",
        description : "开源在线Markdown编辑器<br/>Open source online Markdown editor.",
        tocTitle    : "目录",
        toolbar     : {
            //...
        },
        button: {
            //...
        },
        dialog : {
            //...
        }
        //...
    }

推荐的原因:界面简洁功能较多,拓展很多,比较灵活。

Mditor

Mditor是一款轻量级的 markdown 编辑器。取名自 markdown + editor,用于实现页面 markdown 输入框的便利操作。

支持浏览器: chrome/safari/firefox/ie9+

Git Repo: https://github.com/Houfeng/mditor

<link rel="stylesheet" href="../build/css/mditor.min.css" />
<script src="../build/js/mditor.min.js"></script>
<textarea name="editor" id="editor">
var mditor =  Mditor.fromTextarea(document.getElementById('editor'));
// 获取或设置编辑器的值
console.log(mditor.value);
mditor.value = '** hello **';    
// 是否打开分屏            
mditor.split = true;     // 打开
mditor.split = false;    // 关闭

// 是否打开预览            
mditor.preivew = true;    // 打开
mditor.preivew = false;   // 关闭

// 是否全屏            
mditor.fullscreen = true;    // 打开    
mditor.fullscreen = false;   // 关闭            

// 配置工具条按钮
// mditor.toolbar.items 是一个数组,包括所有按钮的信息
// 可以直接操作 items 以控制工具条

// 只保留第一个按钮
mditor.toolbar.items = mditor.toolbar.items.slice(0,1);

// 更改指定按钮配置
let btn = mditor.toolbar.items[0];
btn.icon = '...';   // 设置按钮图标
btn.title = '...';  // 投置按钮标题
btn.control = true; // 作为控制按钮显示在右侧
btn.key = 'ctrl+d'; // 设置按钮快捷建

// 替换按钮动作
btn.handler = function(){
  // 自定义处理逻辑
  // this 指向当前 mditor 实例
}; 

// 编辑器常用 API
// 编辑器相关 AIP 在 mditor.editor 对象上

//  在光标前插入文本
mditor.editor.insertBeforeText('文本');
// 在光标后插入文本
mditor.editor.insertAfterText('文本');