Element 的文档站是讲Markdown解析成vue组件在页面中渲染出来,转换过程如下图所示:

红框部分势必要对 Markdown 进行特殊的订制,订制过的 Markdown 像下面这样。


:::demo 要使用 Radio 组件,只需要设置`v-model`绑定变量,选中意味着变量的值为相应 Radio `label`属性的值,`label`可以是`String`、`Number`或`Boolean`。
```html
<template>
  <el-radio v-model="radio" label="1">备选项</el-radio>
  <el-radio v-model="radio" label="2">备选项</el-radio>
</template>
<script>
  export default {
    data () {
      return {
        radio: '1'
      };
    }
  }
</script>
\`\`\`
:::

需要解析成对应的页面如下图:

通过 :::demo 作为页面中组件实例的标识,这个转换过程在md-loader中处理。具体element文档站如何实现解析功能的,看看源码build文件下的webpack.demo.js配置md的解析器。

webpack配置

把Markdown解析成vue组件就在webpack配置md的解析loader:

    {
        test: /\.md$/,
        use: [
          {
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                preserveWhitespace: false
              }
            }
          },
          {
            loader: path.resolve(__dirname, './md-loader/index.js')
          }
        ]
      },

从配置文件中可以看出,Markdown 先经由 md-loader 处理,然后再交由 vue-loader 处理。经过这两个 loader 的处理后输出JavaScript在页面中渲染出来。

md-loader

源码中md-loader目录如下:

├─md-loader
| ├─config.js
| ├─containers.js
| ├─fence.js
| ├─index.js
| ├─util.js

index.js:

const {
  stripScript,
  stripTemplate,
  genInlineComponentText
} = require('./util');
const md = require('./config');
module.exports = function(source) {
  const content = md.render(source);
  const startTag = '<!--element-demo:';
  const startTagLen = startTag.length;
  const endTag = ':element-demo-->';
  const endTagLen = endTag.length;
...

md.render(source)这句代码是在markdown-it插件(将markdown转换为html插件)用法很相似,根据const md = require('./config');可以猜测markdown转换为html的代码在config中。

config.js:

const Config = require('markdown-it-chain');
const anchorPlugin = require('markdown-it-anchor');
const slugify = require('transliteration').slugify;
const containers = require('./containers');
const overWriteFenceRule = require('./fence');
const config = new Config();
config
  .options.html(true).end()
  .plugin('anchor').use(anchorPlugin, [
    {
      level: 2,
      slugify: slugify,
      permalink: true,
      permalinkBefore: true
    }
  ]).end()
  .plugin('containers').use(containers).end();
const md = config.toMd();
overWriteFenceRule(md);
module.exports = md;

代码中用到很多插件,我们先百度下这几个插件的作用。

markdown-it-chain:npm上markdown-it-chain包的描述是这样的:

In order to ensure the consistency of the chained API world, webpack-it-chain is developed directly on the basis of webpack-chain and ensures that the usage is completely consistent.Here are some things worth reading that come from webpack-chain:ChainedMapConfig plugins

因为英语不好,我用谷歌翻译:

为了确保链式API世界的一致性,直接在webpack-chain的基础上开发了webpack-it-chain,并确保用法是完全一致的。

确保链式API世界的一致性这句基本没看懂,可能作者老哥也和我一样英语不好,但我们可以知道这个插件是在webpack-it-chain的基础做的功能完善优化。通过给的markdown-it-chain的例子我们知道 config.js代码主要就是在声明使用markdown-it-chain的。markdown-it-chain的例子代码如下:

// Require the markdown-it-chain module. This module exports a single
// constructor function for creating a configuration API.
const Config = require('markdown-it-chain')
 
// Instantiate the configuration with a new API
const config = new Config()
 
// Make configuration changes using the chain API.
// Every API call tracks a change to the stored configuration.
config
  // Interact with 'options' in new MarkdownIt
  // Ref: https://markdown-it.github.io/markdown-it/#MarkdownIt.new
  .options
    .html(true) // equal to .set('html', true)
    .linkify(true)
    .end()
 
  // Interact with 'plugins'
  .plugin('toc')
    // The first parameter is the plugin module, which may be a function
    // while the second parameter is an array of parameters accepted by the plugin.
    .use(require('markdown-it-table-of-contents'), [{
      includeLevel: [2, 3]
    }])
    // Move up one level, like .end() in jQuery.
    .end()
 
  .plugin('anchor')
    .use(require('markdown-it-anchor'), [{
      permalink: true,
      permalinkBefore: true,
      permalinkSymbol: '$'
    }])
    // Apply this plugin before toc.
    .before('toc')
 
// Create a markdown-it instance using the above configuration
const md = config.toMd()
md.render('[[TOC]] \n # h1 \n ## h2 \n ## h3 ')

要知道markdown-it-chain的到底是做什么的,我去查了下webpack-chain插件

Use a chaining API to generate and simplify the modification of webpack version 2-4 configurations.

链式API用于创建和修改webpack配置

就是提供一些链式函数的调用方法来修改和创建webpack配置,例子如下:

const Config = require('webpack-chain');

const config = new Config();

config
.amd(amd)
.bail(bail)
.cache(cache)
.devtool(devtool)
.context(context)
.externals(externals)
.loader(loader)
.name(name)
.mode(mode)
.parallelism(parallelism)
.profile(profile)
.recordsPath(recordsPath)
.recordsInputPath(recordsInputPath)
.recordsOutputPath(recordsOutputPath)
.stats(stats)
.target(target)
.watch(watch)
.watchOptions(watchOptions)

至此第一个插件markdown-it-chain我们知道了他的用处:用链式调用的方法来创建和修改markdown-it配置,而其中plugin是给markdown-it配置一些插件。config.js代码中

 .plugin('anchor').use(anchorPlugin, [
    {
      level: 2,
      slugify: slugify,
      permalink: true,
      permalinkBefore: true
    }
  ]).end()
  .plugin('containers').use(containers).end();

就是给markdown-it添加markdown-it-anchorcontainers.js插件。

那么这里抛出一个问题,为什么使用markdown-it-chain,它带来的好处是什么呢?

npm上 webpack-chain的文档是这么说的:

webpack's core configuration is based on creating and modifying a potentially unwieldy JavaScript object. While this is OK for configurations on individual projects, trying to share these objects across projects and make subsequent modifications gets messy, as you need to have a deep understanding of the underlying object structure to make those changes.

webpack的核心配置基于创建和修改可能难以使用的JavaScript对象。 尽管这对于单个项目上的配置是可以的,但是尝试在项目之间共享这些对象并进行后续修改会很麻烦,因为您需要对基础对象结构有深刻的了解才能进行这些更改。

大概意思理解了,但因为没有经常操作webpack的配置所以对尝试在项目之间共享这些对象并进行后续修改会很麻烦这个点get不到。后续去找资料麻烦的点具体是指的什么,大家也可以一起讨论下。觉得写的可以点个赞。下篇继续!

参考资料

Element 文档中的 Markdown 解析的更多相关文章

  1. php解析word,获得文档中的图片

    背景 前段时间在写一个功能:用原生php将获得word中的内容并导入到网站系统中.因为文档中存在公式,图片,表格等,因此写的比较麻烦. 思路 大体思路是先将word中格式为doc的文档转化为docx, ...

  2. Java解析word,获取文档中图片位置

    前言(背景介绍): Apache POI是Apache基金会下一个开源的项目,用来处理office系列的文档,能够创建和解析word.excel.ppt格式的文档. 其中对word文档的处理有两个技术 ...

  3. 使用Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)(转)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  4. 如何在Markdown文档中插入空格?

    简单说 在 Markdown 文档中,可以直接采用 HTML 标记插入空格(blank space),而且无需任何其他前缀或分隔符.具体如下所示: 插入一个空格 (non-breaking space ...

  5. 【python】使用HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies

    一.从HTML文档中提取链接 模块HTMLParser,该模块使我们能够根据HTML文档中的标签来简洁.高效地解析HTML文档. 处理HTML文档的时候,我们常常需要从其中提取出所有的链接.使用HTM ...

  6. 01将图片嵌入到Markdown文档中

    将图片内嵌入Markdown文档中 将图片嵌入Markdown文档中一直是一个比较麻烦的事情.通常的做法是将图片存入本地某个路径或者网络存储空间,使用URL链接的形式插入图片: ![image][ur ...

  7. Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)

    对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...

  8. dom4j解析xml报"文档中根元素后面的标记格式必须正确"

    今天,在写个批量启动报盘机的自动化应用,为了简化起见,将配置信息存储在xml中,格式如下: <?xml version="1.0" encoding="UTF-8& ...

  9. 详解xml文件描述,读取方法以及将对象存放到xml文档中,并按照指定的特征寻找的方案

    主要的几个功能: 1.完成多条Emp信息的XML描述2.读取XML文档解析Emp信息3.将Emp(存放在List中)对象转换为XML文档4.在XML文档中查找指定特征的Emp信息 dom4j,jaxe ...

随机推荐

  1. UVA 796 - Critical Links 无向图字典序输出桥

    题目:传送门 题意:给你一个无向图,你需要找出里面的桥,并把所有桥按字典序输出 这一道题就是用无向图求桥的模板就可以了. 我一直错就是因为我在输入路径的时候少考虑一点 错误代码+原因: 1 #incl ...

  2. LINUX - 随机数

    #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h& ...

  3. leetcode 1 两数之和 hashmap

    主要是hashmap.还有边插入边查找,提高效率和降低空间复杂度. 之前一直用map,结果发现还有hashmap,效率更高. 注意名称空间为 using namespace __gnu_cxx; 问题 ...

  4. CodeForces - 13E(分块)

    Little Petya likes to play a lot. Most of all he likes to play a game «Holes». This is a game for on ...

  5. Linux 驱动框架---net驱动框架

    这一篇主要是学习网络设备驱动框架性的东西具体的实例分析可以参考Linux 驱动框架---dm9000分析 .Linux 对于网络设备的驱动的定义分了四层分别是网络接口层对上是IP,ARP等网络协议,因 ...

  6. 你所不知道的 JS: null , undefined, NaN, true==1=="1",false==0=="",null== undefined

    1 1 1 === 全相等(全部相等) ==  值相等(部分相等) demo: var x=0; undefined var y=false; undefined if(x===y){ console ...

  7. .NET & C# & ASP.NET

    .NET && C# && ASP.NET https://docs.microsoft.com/zh-cn/dotnet/ .NET Documentation We ...

  8. 微信小程序-导航 & 路由

    微信小程序-导航 & 路由 页面跳转 页面路由 页面栈, 框架以栈的形式维护了当前的所有页面. https://developers.weixin.qq.com/miniprogram/dev ...

  9. UML online tools

    UML online tools UML https://www.diagrams.net/assets/svg/home-dia1.svg refs https://www.diagrams.net ...

  10. WebAssembly in Action

    WebAssembly in Action 数据加密,反爬虫,防盗链,版权保护,数据追踪,埋点 blogs 加密,js 禁用检测,权限控制 WebAssembly 防盗链 wasm online id ...