小程序 Towxml 3.0 解析Markdown 及HTML

900 阅读2分钟

Towxml 是一个让小程序(微信/QQ)可以解析MarkdownHTML的解析库。

Towxml拥有以下特性:

  • 支持echarts图表(3.0+)
  • 支持LaTex数学公式(3.0+)
  • 支持yuml流程图(3.0+)
  • 支持按需构建(3.0+)
  • 支持代码语法高亮、代码块行号显示
  • 支持emoji表情
  • 支持上标、下标、下划线、删除线、表格、视频、图片(几乎所有html元素)……
  • 支持typographer字符替换
  • 支持多主题切换
  • 支持Markdown TodoList
  • 支持事件绑定(这样允许自行扩展功能哟,例如:点击页面中的某个元素,更新当前页面内容等...)
  • 极致的中文排版优化
  • 支持前后解析数据

使用方法

首先,需要构建Towxml

  • 克隆项目到本地
  • git clone https://github.com/sbfkcel/towxml.git
  • 安装构建依赖
  • npm install 或 yarn
  • 编辑配置文件towxml/config.js
  • 根据自行需要,仅保留你需要的功能即可(配置中有详细注释)
  • 运行 npm run build 或 yarn run build即可

新构建出来的文件会保存在你桌面上的towxml目录,需要将此目录复制到你的小程序项目中去

开始使用

将构建出来的towxml并解压至小程序项目根目录下,即(小程序/towxml

引入库/app.js

//app.js
App({
    // 引入`towxml3.0`解析方法
    towxml:require('/towxml/index')
})

// 在页面配置文件中引入towxml组件 `/pages/index/index.json`
{
  "usingComponents": {
    "towxml":"/towxml/towxml"
  }
}

// 在页面中插入组件`/pages/index/index.wxml`

<!--index.wxml-->
<view>
  <towxml nodes="{{nodes}}"/>
</view>

// 解析内容并使用`/pages/index/index.js`


onLoad: function () {
    // 解析Markdown 
    let result = app.towxml(`# Markdown`,'markdown',{
        base:'https://xxx.com',             // 相对资源的base路径
        theme:'dark',                   // 主题,默认`light`
        events:{                    // 为元素绑定的事件方法
            tap:(e)=>{
                console.log('tap',e);
            }
        }
    });
}


API

app.towxml(str,type,options)有三个参数

  • str <必选> string,html或markdown字符串
  • type <必选> string,需要解析的内容类型htmlmarkdown
  • options <可选> object,可选参数,可以该选项设置主题绑定事件设置base

FAQ

1、echarts所有图表都支持吗?

考虑到库体积的问题,Towxml3.0 默认集成的echarts仅支持柱状图折线图饼图,如需其它图表可 自行定制

2、为什么需要构建,不能直接使用吗?  

也可以直接使用,不过可能会存在一些问题,或有一些无用的文件。所以建议还是自行构建出自己想要的版本库。

3、解析HTML时如果有pre 内置代码需要再单独解析后端返回的字符串(会有编码)不然会导致pre内代码块展示不完整

// 方法中截取的字符串是根据 编辑器编译后返回固定的字符串 可以根据需求改动
const getTowxmlText = (str: string) => {
  const list: any = []
  const arr = str.split('</span></code></pre>')
  arr.forEach((item: any, index: number) => {
    if (item.includes('style="height:undefinedpx"><span>')) {
      const itemList = item.split('style="height:undefinedpx"><span>')
      itemList.forEach((v: any, i: number) => {
        if (i === itemList.length - 1) {
          list.push('style="height:undefinedpx"><span>' + replaceChar(v))
        } else {
          list.push(v)
        }
      })
      list.push('</span></code></pre>')
    } else {
      list.push(item)
      if (arr.length - 1 > index) list.push('</span></code></pre>')
    }
  })

  return list.join(' ')
}

//替换文本中特殊字符
export function replaceSpecialChar(str: string) {
  str = str.replace(/&quot;/g, '"');
  str = str.replace(/&amp;/g, '&');
  str = str.replace(/&lt;/g, '<');
  str = str.replace(/&gt;/g, '>');
  str = str.replace(/&nbsp;/g, ' ');
  const content = getTowxmlText(str)
  return content ? content : str
}

const text = replaceSpecialChar('<div><pre> dingText = app.towxml(text, 'html', {}) /n </pre></div>')
const dingText = app.towxml(text, 'html', {
    events: {
      tap: this.tabClick
    }
})