uni-app 关于解析Markdown文件的格式和兼容性

发布于 1周前 作者 eggper 来自 Uni-App

uni-app 关于解析Markdown文件的格式和兼容性

以下显示基于PC端最流行的Markdown软件Typora进行编写,如显示不正常请参考附件(用Typora打开md文件,或参考PDF),以下内容与md文件一致粘贴过来

另有一个开源项目可以参考,希望能提供帮助,https://github.com/sbfkcel/towxml

需求1,复杂表格可以正常显示,且只有table的情况下,不需要添加tbody标签

表格:

Html表格含tbody

<table>
<tr>
<td colspan="2">合并表头</td>
</tr>
<tr>
<td>内容1</td>
<td>内容2</td>
</tr>
</table>  

html表格不含tbody

<table>
<tr>
<td>背景</td>
<td colspan="2">第二次世界大战中,世界反法西斯国家提出了建立战后国际安全组织的主张</td>
</tr>
<tr>
<td>成立</td>
<td colspan="2">1945年10月</td>
</tr>
<tr>
<td>地位</td>
<td colspan="2">联合国是人类构建世界和平的成果,也是影响最大的国际组织</td>
</tr>
<tr>
<td>总部</td>
<td colspan="2">设在美国纽约</td>
</tr>
<tr>
<td rowspan="3">主要机构</td>
<td rowspan="3">联合国大会、联合国安全理事会、联合国秘书处等</td>
<td>联合国大会简称“联大”,由全体会员国组成,每年举行一届大会</td>
</tr>
<tr>
<td>联合国安全理事会,简称“安理会”,担负着维护国际和平与安全的主要责任。安理会由中国、法国、俄罗斯、英国、美国5个常任理事国和10个非常任理事国组成,常任理事国拥有否决权</td>
</tr>
<tr>
<td>联合国秘书处是联合国的行政秘书事务机构</td>
</tr>
<tr>
<td>职能</td>
<td colspan="2">根据安理会或联大的决议,联合国可以向冲突地区派出军事人员,以恢复或维持和平。以联合国名义派出的武装力量,被人们称为“联合国维持和平部队”</td>
</tr>
<tr>
<td>作用</td>
<td colspan="2">联合国在维护国际和平与安全方面发挥了积极作用,使许多国家和地区避免了一些可能发生的战争</td>
</tr>
</table>  

Markdown表格

次数 物体所受的重力/N 物体在水中时测力计的读数/N 浮力/N 小桶和排开的水所受的总重力/N 小桶所受的重力/N 排开水所受的重力/N
1
2
3

## 需求2,公式正常显示

### 公式1,包含了$$中间的LaTax公式正常显示
```latex
\[ F_{\text {浮}}'=\rho_{\text {水}} V_{\text {排}}' g=1.0 \times 10^{3} \mathrm{~kg} / \mathrm{m}^{3} \times 1 \times 10^{-4} \mathrm{~m}^{3} \times 10 \mathrm{~N} / \mathrm{kg}=1 \mathrm{~N} \]

公式2,一行里面如果有两套$$内容,前后多个公式都要独立显示

\[ F_{\text {浮 }}=G_{\text {排 }}=m_{\text {排 }} g=\rho_{\text {液 }} g V_{\text {排 }} \]、这里前后有两个公式 \( 0.8 \times 10^3 \text{kg/m}^3 \)

公式3,$$套起来的公式块正常显示

\[ 
F_{\text {浮}}'=\rho_{\text {水}} V_{\text {排}}' g=1.0 \times 10^{3} \mathrm{~kg} / \mathrm{m}^{3} \times 1 \times 10^{-4} \mathrm{~m}^{3} \times 10 \mathrm{~N} / \mathrm{kg}=1 \mathrm{~N}
\]

公式4,相关符号没有显示,且手机上被换行

\[ \Delta \quad \underline{\quad\quad\quad\quad} \quad \rho \quad \eta \]

公式5,需要在手机上正常显示

\[
\begin{align}
& 原式= - \frac { 5 } { 2 } \div ( - 15 ) \times ( - \frac { 1 } { 15 } ) \\
&=- \frac { 5 } { 2 } \times \frac { 1 } { 15 } \times \frac { 1 } { 15 } \\
&=- \frac { 1 } { 90 }
\end{align}
\]

公式6,$包括的乘号times在手机上不显示,被识别成了纯文本

0.32N,0.4 \times 10^3 \text{kg/m}^3

公式7,Markdown的上标下标正常显示

1~0~ 1~1~ 1~2~ 1~3~ 1^3^


### 公式8,table标签表格内的上标下标无法正常显示,只显示了上标下标,没有显示数字本身
```html
<table>
<tr>
<td>1<sub>234</sub></td>
<td>2<sup>345</sup></td>
<td>3</td>
</tr>
</table>

公式9,容错,第二个等号后面的内容没有显示,需要在同一行内识别单美元和双$

\[ \eta=\frac{W_{\text {有用 }}}{W_{\text {总 }}} \] =\frac{W_{\text {有用 }}}{W_{有用}+W_{额外}}

需求3,带有HTML标签的样式显示问题

样式1,普通无标签无语法内容

如图甲所示,将一金属圆柱体挂在弹簧测力计下缓慢浸入水中(水足够深),在圆柱体接触容器底之前,分别记下圆柱体下表面所处深度h和弹簧测力计相应的示数F,图乙是根据记录数据作出的F和h关系的图象(g取10N/kg)。由图象可知(  )

样式2,html样式尾部没封口正常显示

<p style="text-indent:2em"><font font-family="楷体">如图甲所示,将一金属圆柱体挂在弹簧测力计下缓慢浸入水中(水足够深),在圆柱体接触容器底之前,分别记下圆柱体下表面所处深度h和弹簧测力计相应的示数F,图乙是根据记录数据作出的F和h关系的图象(g取10N/kg)。由图象可知(  )

样式3,html样式尾部封口正常显示

<p style="text-indent:2em"><font font-family="楷体">如图甲所示,将一金属圆柱体挂在弹簧测力计下缓慢浸入水中(水足够深),在圆柱体接触容器底之前,分别记下圆柱体下表面所处深度h和弹簧测力计相应的示数F,图乙是根据记录数据作出的F和h关系的图象(g取10N/kg)。由图象可知(  )</font></p>

样式4,html语法居中

<center>这里是居中的内容</center>

样式5,html语法居中且加粗

<p style="text-align:center"><strong>如图甲所示,将一金属圆柱体挂在弹簧测力计下缓慢浸入水中(水足够深),在圆柱体接触容器底之前,分别记下圆柱体下表面所处深度h和弹簧测力计相应的示数F,图乙是根据记录数据作出的F和h关系的图象(g取10N/kg)。由图象可知(  )</strong></p>

样式6,html字体样式楷体,加粗,下划线(目前插件插画线有但是被换行)

<p style="text-indent:2em"><font face="楷体">如图甲所示,<strong>将一金属圆柱</strong>体挂在弹簧测力计下缓慢浸入水中(水足够深),在圆柱体接触容器底之前,<u>1234567890</u>分别记下圆柱体下表面所处深度h和弹簧测力计相应的示数F,图乙是根据记录数据作出的F和h关系的图象(g取10N/kg)。由图象可知(  )</font></p>

Markdown显示层级,这里是control1

Markdown显示层级,这里是control2

Markdown显示层级,这里是control3

Markdown显示层级,这里是control4

Markdown显示层级,这里是control5
Markdown显示层级,这里是control6(注意control6是灰色的字体)

这里符号前后不换行

(1)物体受平衡力(或不受力)$\leftrightarrow$物体的运动状态不变(保持静止或匀速直线运动状态)。

(2)物体受非平衡力作用运$\leftrightarrow$动状态改变(运动快慢或方向改变)。


13 回复

你的需求是全端吗? app和h5下,用renderjs,可以引入web端的方案进来。 在app上,还可以引入原生插件,在nvue页面里使用。(原生生态里应该有合适的markdown解析控件,具体我没调研) 小程序下简单表格好办,官方有uni-table,但合并单元格等复杂表格在小程序上可不好解决。
我知道另一个公司,就是csdn,他们的做法是把这些复杂的内容,包括公式和复杂表格,转成了图片。你下载一个csdn app就知道了,它的博客详情其实是原生页面,但也还是用了图片方案。可能这是一种更落地的方案。


不是全端,就只是在UniApp上面。转图片这个没法逆向了,因为我们整理内容的时候是专门把图片提出来做成的LeTax公式,目的就是在多端可以显示。而且很多公式是嵌套在了文章里面,所以不太适用于图片方案。

回复 QuizCat: 说的就是uni-app的全端。在uni-app的小程序端应该是搞不定这事。csdn的做法是web端做编辑,数据库同时保留原始公式和图片。

回复 DCloud_heavensoft: 我们不发布小程序版本,只做安卓和iOS。数据库里确实也保留了原始公式(基于Markdown)以及图片。

回复 DCloud_heavensoft: 主要是需要同时兼顾复杂表格和公式,这两个是核心问题。

如果官方能够给出一个只兼容复杂表格以及直接识别公式的方案的话,后面的问题就好解决很多。

回复 QuizCat: 只做app端,那就好说了啊。图片是一种方案,web端的库也可以通过renderjs引入到app里,https://uniapp.dcloud.io/frame?id=renderjs

回复 DCloud_heavensoft: 我们因为公式全部走的是LeTax格式,所以没法用图片方案。你的意思是通过web渲染以后再通过App加载出来?

回复 DCloud_heavensoft: 这个方案只是可以用正常的html代码,但是对于公式以及Markdown的兼容性还是不够。

回复 QuizCat: web库生态里,应该有可以解析markdown公式的库啊,不然typora怎么做的

回复 DCloud_heavensoft: 感谢答复,我们开发已经摸到了一些方案和线索,但是寻找下来发现没有特别合适的web库。不知道有没有合适的可以推荐几个,我们着手尝试一下。多谢。

回复 DCloud_heavensoft: 能否推荐几个合适的web库,我们找下来发现没有特别合适的。

在uni-app中解析Markdown文件并实现良好的兼容性,你可以使用诸如markdown-it这样的JavaScript库来解析Markdown内容,并将其渲染为HTML。以下是一个简单的示例,展示如何在uni-app项目中集成和使用markdown-it来解析Markdown文件。

步骤 1:安装markdown-it

首先,你需要安装markdown-it库。你可以通过npm或yarn来安装它:

npm install markdown-it --save
# 或者
yarn add markdown-it

步骤 2:创建Markdown解析组件

接下来,你可以创建一个Vue组件来封装Markdown解析的逻辑。

<template>
  <view class="markdown-container">
    <rich-text :nodes="htmlNodes"></rich-text>
  </view>
</template>

<script>
import MarkdownIt from 'markdown-it';

export default {
  data() {
    return {
      markdownContent: '',
      htmlNodes: []
    };
  },
  created() {
    this.markdownToHtml();
  },
  methods: {
    markdownToHtml() {
      const md = new MarkdownIt();
      this.htmlNodes = md.renderToHtml(this.markdownContent);
    },
    setMarkdownContent(content) {
      this.markdownContent = content;
      this.markdownToHtml();
    }
  },
  props: {
    initialContent: {
      type: String,
      default: ''
    }
  },
  watch: {
    initialContent(newVal) {
      this.setMarkdownContent(newVal);
    }
  }
};
</script>

<style scoped>
.markdown-container {
  padding: 16px;
  background-color: #f5f5f5;
}
</style>

步骤 3:使用Markdown解析组件

现在,你可以在你的页面中使用这个组件,并传入Markdown内容:

<template>
  <view>
    <MarkdownViewer :initialContent="markdownText" />
  </view>
</template>

<script>
import MarkdownViewer from '@/components/MarkdownViewer.vue';

export default {
  components: {
    MarkdownViewer
  },
  data() {
    return {
      markdownText: '# Hello, Markdown!\n\nThis is a **bold** text.'
    };
  }
};
</script>

兼容性

markdown-it库支持大多数Markdown语法,并且在uni-app中使用时,通过<rich-text>组件渲染HTML内容,可以确保在大多数平台上具有良好的兼容性。不过,由于<rich-text>组件本身的一些限制,可能并不支持所有HTML标签和样式,因此在使用时需要注意Markdown内容的复杂度和样式需求。

这个示例展示了如何在uni-app中解析和显示Markdown内容,并且保持了一定的兼容性。如果你需要更多的Markdown特性或样式支持,可以考虑自定义<rich-text>的渲染逻辑或使用其他更适合的库。

回到顶部