首页 前端知识 Markdown文件转换为html(包括markdown-it、生成菜单、自定义id锚点)

Markdown文件转换为html(包括markdown-it、生成菜单、自定义id锚点)

2024-02-03 12:02:43 前端知识 前端哥 426 894 我要收藏

前提:此需求在全网未找到实现的案例,故自己记录一下。
使用到的插件:markdown-it、markdown-it-anchor、markdown-it-toc-done-right、uslug
例子使用vue实现,nodejs可以参考,用法一样
最终成品直接看3、4

template和样式部分:

<template>
	<div class="md-content">
		<div class="sidebar">
			<div v-html="tocContent"></div>
		</div>
		<div class="content" v-html="htmlMD"></div>
	</div>
</template>
<style scoped>
.md-content {display: flex;}
.sidebar {position: sticky;top: 0;width: 300px;padding: 20px;background-color: #f0f0f0;overflow-y: auto;}
.content {flex-grow: 1;padding: 20px;}
.sidebar ul {list-style: none;padding: 0;}
.sidebar li {margin-left: 10px;}
.sidebar a {display: inline-block;margin-bottom: 5px;}
</style>

1、只使用makdown-it时,设置为html:true可以实现将md转换为html页面展示:

<script>
import axios from "axios";
export default {
  data(){
    return {
      htmlMD:'',
      tocContent:''
    }
  },
  mounted() {
    this.ok()
  },
  methods:{
    ok(){
      axios.get("/测试平台使用手册.md").then((response) => {
        const md = require("markdown-it")({
          html: true,
          typographer: true
        })
        var result = md.render(response.data);
        this.htmlMD = result;
      });
    },
  }
}
</script>

此时的界面:
在这里插入图片描述
此时标题的html标签:
在这里插入图片描述

2、markdown-it-anchor可以为 Markdown 文本生成唯一 ID 的标题,并自动在内容中创建链接:

<script>
import axios from "axios";
import markdownItAnchor from "markdown-it-anchor"; //增加
export default {
  data(){
    return {
      htmlMD:'',
      tocContent:''
    }
  },
  mounted() {
    this.ok()
  },
  methods:{
    ok(){
      axios.get("/测试平台使用手册.md").then((response) => {
        const md = require("markdown-it")({
          html: true,
          typographer: true
        })
        //增加
        .use(markdownItAnchor, {
          permalink: true,
          permalinkSymbol: "",
        })
        var result = md.render(response.data);
        this.htmlMD = result;
      });
    },
  }
}
</script>

此时标题的html标签:
在这里插入图片描述

3、解析md,可以获取标题节点,并结合markdown-it-toc-done-right生成锚点菜单:

<script>
import axios from "axios";
import markdownItAnchor from "markdown-it-anchor";
import markdownItTocDoneRight from "markdown-it-toc-done-right"; //新增
export default {
  data(){
    return {
      htmlMD:'',
      tocContent:''
    }
  },
  mounted() {
    this.ok()
  },
  methods:{
    ok(){
      axios.get("/测试平台使用手册.md").then((response) => {
        const md = require("markdown-it")({
          html: true,
          typographer: true
        })
        .use(markdownItAnchor, {
          permalink: true,
          permalinkSymbol: "",
        })
        //新增
        .use(markdownItTocDoneRight, {
          includeLevel: [1, 2],
        })
        var result = md.render(response.data);
        this.htmlMD = result;
        //新增
        this.generateToc(response.data,md);
      });
    },
    generateToc(markdownText,md) {
      let tocHtml = '';
      const tokens = md.parse(markdownText, {}); //解析为token数组
      console.log("tokens",tokens) 
      tokens.forEach((token, index) => {
        if (token.type === 'heading_open') {  //标题的开始标签节点
          const anchor = token.attrGet('id'); //获取标题的id
          let title = '';
          const nextToken = tokens[index + 1];
          if (nextToken.type === 'inline') {
            // 如果下一个标记是文本标记,则将其内容作为标题内容
            title = md.renderer.render(nextToken.children, md.options, {});
          } else {
            // 否则使用默认的标题内容
            title = md.renderer.renderToken(tokens[index + 1], md.options, {});
          }
          tocHtml += `<a href="#${anchor}">${title}</a><br>`; //渲染为锚点链接
        }
      });
      this.tocContent = tocHtml;
    },
  }
}
</script>

此时,菜单可以正常跳转使用。

注:不能用markdown-it-toc替换markdown-it-toc-done-rightmarkdown-it-toc生成的html中标题id跟#${anchor}获取到的不一致,不可控

4、利用uslug自定义标题id。
如果有自定义id的需求就安装使用uslug
比如,会有网页的地址url是hash多级路径的,比如:http://127.0.0.1:8080/#/helpdocument点击菜单的锚点链接后地址栏会变成http://127.0.0.1:8080/#/helpdocument/#11-物理机管理,这时页面404,因为此时识别的锚点为#/helpdocument/#11-物理机管理,而页面里的标题id是11-物理机管理,匹配错误。

uslug(string, options)
参数说明:
string是待传入的字符串;options有三个值可以设置:
①allowedChars: 可以指定字符串保持原样,不转换,缺省值:‘-_~’.
②lower: 布尔值,是否强制转换为小写?缺省为true
③spaces: 布尔值,是否允许空格?缺省为false。

<script>
import axios from "axios";
import markdownItAnchor from "markdown-it-anchor";
import markdownItTocDoneRight from "markdown-it-toc-done-right";
export default {
  data(){
    return {
      htmlMD:'',
      tocContent:''
    }
  },
  mounted() {
    this.ok()
  },
  methods:{
    ok(){
      axios.get("/测试平台使用手册.md").then((response) => {
      //新增
      const uslug = require('uslug')
      //括号里为自定义标题格式,第二个参数是允许保留/和#符号
      const uslugify = s => uslug('/helpDocument/#'+s,{ allowedChars: ['/','#'] })
        const md = require("markdown-it")({
          html: true,
          typographer: true
        })
        .use(markdownItAnchor, {
          permalink: true,
          permalinkSymbol: "",
          slugify: uslugify  //新增
        })
        .use(markdownItTocDoneRight, {
          includeLevel: [1, 2],
        })
        var result = md.render(response.data);
        this.htmlMD = result;
        this.generateToc(response.data,md);
      });
    },
    generateToc(markdownText,md) {
      let tocHtml = '';
      const tokens = md.parse(markdownText, {}); //解析为token数组
      console.log("tokens",tokens) 
      tokens.forEach((token, index) => {
        if (token.type === 'heading_open') {  //标题的开始标签节点
          const anchor = token.attrGet('id'); //获取标题的id
          let title = '';
          const nextToken = tokens[index + 1];
          if (nextToken.type === 'inline') {
            // 如果下一个标记是文本标记,则将其内容作为标题内容
            title = md.renderer.render(nextToken.children, md.options, {});
          } else {
            // 否则使用默认的标题内容
            title = md.renderer.renderToken(tokens[index + 1], md.options, {});
          }
          tocHtml += `<a href="#${anchor}">${title}</a><br>`; //渲染为锚点链接
        }
      });
      this.tocContent = tocHtml;
    },
  }
}
</script>

此时的菜单链接:
在这里插入图片描述

正文标题标签:
在这里插入图片描述

示例界面:
在这里插入图片描述

参考:将Markdown字符串转成HTML

转载请注明出处或者链接地址:https://www.qianduange.cn//article/1184.html
标签
评论
发布的文章

jQuery ---- 插件

2024-02-15 14:02:06

CSS-JavaScript-Jquery-Servlet

2024-02-15 14:02:00

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!