微信小程序基于 wxParse 实现代码高亮

小程序 About 4,235 words

页面展示

preview.png

前置条件

修改可参考前一篇文章。

  • 修改wxParse使代码块不换行
  • 修改wxParse使代码块中的注释不被替换

高亮插件

Prism官网下载prism.jsprism.css,默认只有css代码有渲染样式,注意选择需要渲染的语言。

小程序所用样式下载路径

https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+csharp+cpp+dart+erlang+git+go+graphql+http+hpkp+hsts+ini+java+javadoc+javadoclike+javastacktrace+json+kotlin+lua+makefile+markup-templating+nginx+objectivec+php+phpdoc+php-extras+properties+python+rust+sql+swift+yaml

特别感谢

sunriseydy大神采用的是替换<pre><code></code></pre><pre></pre>,基于pre标签进行渲染。

Jarry大神采用的直接渲染<pre><code></code></pre>

本人的小程序站在两位大佬的肩膀上完成了代码高亮的功能,特此感谢。

两位大佬文章链接再文末。

修改代码

  • 1.将prism.css重命名为prism.wxss
  • 2.复制prism.jsprism.wxssutils文件夹下
  • 3.替换prism.wxss中的code[class*="language-"].wxParse-code[class*="language-"]
  • 4.wxParse.wxss中引用prism.wxss
@import "../utils/prism.wxss";
  • 5.新增highlight.js高亮工具类(代码放置在wxParse文件夹下)
var Prism = require('../utils/prism.js')
function highlight(data, that) {
  // Prism 所支持的代码语言数组
  let langArr = new Array();
  langArr = listLanguages();
  // console.log('all-language:'+langArr)
  let html = data;
  //匹配到的所有标签<\/code>
  let tagArr = data.match(/<\/?code[^>]*>/g);
  if (tagArr == null) {
    return html;// 如果没有 pre 标签就直接返回原来的内容,不做代码高亮处理
  }
  //记录每一个 code 标签在data中的索引位置
  let indexArr = [];
  //计算索引位置
  for (let i = 0; i < tagArr.length; i++) {
    //添加索引值
    if (i == 0) {
      indexArr.push(data.indexOf(tagArr[i]));
    }
    else {
      indexArr.push(data.indexOf(tagArr[i], indexArr[i - 1]));
    }
  }

  //记录基本的class信息
  let cls;

  // 开始循环处理 code 标签
  let i = 0;
  while (i < tagArr.length - 1) {// 这里减一是因为不处理最后的 code 标签
    // 调用函数来获取 class 信息
    getStartInfo(tagArr[i])
    // 获取标签的值
    var label = tagArr[i].match(/<*([^> ]*)/)[1];
    // console.log('label:'+label)
    if (tagArr[i + 1] === '</' + label + '>') {//判断紧跟它的下一个标签是否为它的闭合标签
      if (label === 'code') {
        // 代码语言判断,根据类进行判断,自定义,比如 lang-语言,language-语言。
        let lang = cls.split(' ')[0];
        if (/lang-(.*)/i.test(lang)) {// 代码语言定义是 lang-XXX 的样式
          lang = lang.replace(/lang-(.*)/i, '$1');
        }
        else if (/languages?-(.*)/i.test(lang)) {
          lang = lang.replace(/languages?-(.*)/i, '$1');// 代码语言定义是 language(s)-XXX 的样式
        }
        // 如果代码语言不在 Prism 存在的语言,或者 class 值是 null,则不执行代码高亮函数
        if (langArr.indexOf(lang) == -1 || lang == null || lang == 'none' || lang == 'null') {
        }
        else {
          // 获取代码段内容为 code
          let code = data.substring(indexArr[i], indexArr[i + 1]).replace(/<code[^>]*>/, '');

          // 执行 Prism 的代码高亮函数
          let hcode = Prism.highlight(code, Prism.languages[lang], lang);
          html = html.replace(code, hcode);
        }

      }
      // 指向下一个标签(闭合标签)索引
      i++;
    } else {
      //onsole.log('不是闭包')
    }
    // 指向下一个标签(开始标签)的索引
    i++;
  }
  return html;

  function getStartInfo(str) {
    cls = matchRule(str, 'class');
  }

  //获取部分属性的值
  function matchRule(str, rule) {
    let value = '';
    let re = new RegExp(rule + '=[\'"]?([^\'"]*)');
    //console.log('regexp:'+re)
    if (str.match(re) !== null) {
      value = str.match(re)[1];
      //console.log('value:'+value)
    }
    return value;
  }


  // 列出当前 Prism.js 中已有的代码语言,可以自己在 Prism 的下载页面选择更多的语言。
  function listLanguages() {
    var langs = new Array();
    let i = 0;
    for (let language in Prism.languages) {
      if (Object.prototype.toString.call(Prism.languages[language]) !== '[object Function]') {
        langs[i] = language;
        i++;
      }
    }
    return langs;
  }
}

module.exports = {
  highlight: highlight
};
  • 6.在wxParse文件夹下的html2json.js中引用highlight.js工具类的highligh高亮函数
//引用`highlight.js`工具类
var highlight = require('./highlight.js');

function html2json(html, bindName, that) {
    html = removeDOCTYPE(html);
    html = trimHtml(html);
    html = wxDiscode.strDiscode(html);
    //引用高亮函数
    html = highlight.highlight(html, that);    

    //省略了后续代码
    ...

}

参考

https://blog.sunriseydy.top/technology/server-blog/wordpress/wordpress-miniapp-code-highlight

https://blog.csdn.net/qq_41107410/article/details/89042212

完整代码

https://github.com/fendoudebb/z-blog-wx

Views: 5,533 · Posted: 2020-02-07

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh