博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自己动手开发更好用的markdown编辑器-07(扩展语法)
阅读量:4564 次
发布时间:2019-06-08

本文共 4586 字,大约阅读时间需要 15 分钟。

这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 
 
文章目录

我们实现了自动更新的功能.

在前面的6篇中,我们基本没做什么创造,都只是像玩乐高那样把零件拼接成我们想要的东西.

今天这篇将对marked进行简单扩展, 增加我们的markdown编辑器支持的语法,实现目录,emojis表情两种新语法.
以及改造codemirror,实现我们自定义语法的编辑器高亮显示(这个本来是要放到下一篇,但是刚刚做完后发现内容很短,所以就又合并到这篇里来了).

对于不想看如何实现的朋友,直接下载,然后点击右上角的更新按钮更新到最新版即可.

准备工作

首先打开,Fork一份到自己仓库. 对marked的改造都将基于我们的这个fork版本.

目录语法

功能描述: 自动提取所有H标签,形成目录树,在解析markdown文本时,如果遇到[TOC]标签则自动将其替换为目录.

将我们fork的版本clone到本地,打开.所有代码都在这个文件里.

修改inline.gfm,增加目录语法匹配正则

1 2 3 4 5 6 7 8 9 10 11 12 13 14
/**  * GFM Inline Grammar  */ inline.gfm = merge({}, inline.normal, {
escape: replace(inline.escape)('])', '~|])')(), url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, del: /^~~(?=\S)([\s\S]*?\S)~~/, toc: /\s*\[TOC\]/, text: replace(inline.text) (']|', '~]|') ('|', '|https?://|') () });

 

修改Renderer,增加toctocItem两个方法,用于生成目录标签:

1 2 3 4 5 6 7 8 9 10
Renderer.prototype.toc = function (items) {
var html = '
    '; html += items; html += '
'; return html; } Renderer.prototype.tocItem = function (id, level, text) {
return '
  • ' + text + '
  • '; };

     

    修改Rendererheading方法,为其赋予id作为点击目录项的锚点

    1 2 3 4 5 6 7 8 9
    Renderer.prototype.heading = function(text, level, raw) {
    var escapedText = text.toLowerCase(); return '
    ' + text + '
    '; };

     

    修改 Parser.prototype.parse,在解析时预生成好目录标签备用:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
    /**  * Parse Loop  */ Parser.prototype.parse = function (src) {
    var me = this, tocItems = ''; //预生成好目录标签 src.forEach(function (token) {
    if (token.type == 'heading') {
    id = token.text.toLowerCase(); tocItems += me.renderer.tocItem(id, token.depth, token.text); } }); this.inline = new InlineLexer(src.links, this.options, this.renderer); this.inline.tocHTML = me.renderer.toc(tocItems); this.tokens = src.reverse(); var out = ''; while (this.next()) {
    out += this.tok(); } return out; };

     

    最后是修改InlineLexer,在匹配到[TOC]时将其替换为完整的目录标签

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    /**  * Lexing/Compiling  */ InlineLexer.prototype.output = function(src) {
    var out = '' , link , text , href , cap; while (src) {
    //toc语法 if (cap = this.rules.toc.exec(src)) {
    src = src.substring(cap[0].length); out += this.tocHTML; continue; } ... }

     

    这样目录语法就完成了,没几行代码,效果如图(预览的样式比较丑,这系列的某一篇会专门优化预览样式):

    emojis表情语法

    准备表情素材

    我将要实现的emoji表情库基于这个项目,大家可以通过这个页面查看所有表情的命名.

    我将这里所有表情上传一份到我的七牛空间里,这样访问会快一些.

    实现功能

    emojis语法的实现跟目录类似.

    修改inline.gfm,增加emojis语法匹配正则

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    /**  * GFM Inline Grammar  */ inline.gfm = merge({}, inline.normal, {
    escape: replace(inline.escape)('])', '~|])')(), url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, del: /^~~(?=\S)([\s\S]*?\S)~~/, emoji: /^:([A-Za-z0-9_\-\+]+?):/, toc: /\s*\[TOC\]/, text: replace(inline.text) (']|', ':~]|') ('|', '|https?://|') () });

     

    Renderer增加emoji方法:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14
    Renderer.prototype.emoji = function (emoji) {
    //图片使用自己的七牛空间 return ':'   + escape(emoji)   + ':'; };

     

    最后,在InlineLexer里:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    /**  * Lexing/Compiling  */ InlineLexer.prototype.output = function(src) {
    var out = '' , link , text , href , cap; while (src) {
    ... // emoji (gfm) if (cap = this.rules.emoji.exec(src)) {
    src = src.substring(cap[0].length); out += this.renderer.emoji(cap[1]); continue; } ... }

     

    完成!这个功能比目录功能更加简单

    编辑器语法高亮

    这里就不再去fork 这个项目了,有兴趣的可以去fork,修改完后提交给官方.

    我们直接简单粗暴的修改.

    增加toc和emoji的正则:

    1 2 3 4 5 6 7 8 9 10 11 12 13
    ... ,    toc = 'toc' ,    emoji = 'emoji' .. .. var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/ ,   ulRE = /^[*\-+]\s+/ ,   olRE = /^[0-9]+\.\s+/ ,   taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE ,   atxHeaderRE = /^#+/ ,   tocRE = /\[TOC\]/ ,   emojiRE = /^:([A-Za-z0-9_\-\+]+?):/ ..

     

    blockNormal方法里为匹配到的标签返回独立的class:

    1 2 3 4 5 6 7
    ... } else if(match = stream.match(tocRE)){
    return toc; } else if(match = stream.match(emojiRE)){
    return emoji; } ...

     

    这样就搞定了,编辑器会为匹配到的代码加上相应的class

    有了,class,就可以在样式修改自定义语法的高亮显示了,比如我现在用的样式文件
    打开这个样式文件,加上样式:

    1 2 3 4 5 6
    .cm-toc{
    background:#ccc; } .cm-emoji{
    color:#F7A21B; }

     

    现在这些语法在编辑器里有独特的高亮效果了:

    总结

    通过两个自定义语法的实现,我们可以总结出自定义语法的一般步骤:

    1. 增加语法关键词的匹配正则.
    2. Renderer里增加相应的标签生成方法.
    3. InlineLexer里处理匹配到的语法.

    接下来的计划:

    1. 导出pdf,html文件.
    2. 美化预览样式.

    附件

    转载于:https://www.cnblogs.com/honghongming/p/4516962.html

    你可能感兴趣的文章
    Android仿腾讯应用宝 应用市场,下载界面, 有了进展button
    查看>>
    安卓|五大逆向软件下载
    查看>>
    5 OK6410裸机调试(不用Jlink)
    查看>>
    “模板”学习笔记(5)-----编译器在处理函数模板的时候都干了啥
    查看>>
    教你用shell写CGI程序
    查看>>
    窗口 对话框 Pop Dialog 示例
    查看>>
    ubuntu(centos) server安装vmware tools
    查看>>
    数据结构之最大不重复串
    查看>>
    为什么要配置sdk-tools/platform-toools?
    查看>>
    自己动手开发更好用的markdown编辑器-07(扩展语法)
    查看>>
    maven dependency:tree中反斜杠的含义
    查看>>
    队列的循环队列
    查看>>
    程序中的日期格式
    查看>>
    大众点评CAT错误总结以及解决思路
    查看>>
    MyEclipse 检出新项目后,如果项目名称签名有个红色感叹号
    查看>>
    Java开发环境系列:一篇能解决你99%问题的排雷日记
    查看>>
    从0开始学爬虫3之xpath的介绍和使用
    查看>>
    Shell成长之路
    查看>>
    vim下正则表达式的非贪婪匹配
    查看>>
    一个python的计算熵(entropy)的函数
    查看>>