JavaScript构建一个Markdown解析器

发布时间:2025-03-27

Markdown是一种轻量级标记语言,以简单易读的语法和可生成丰富多彩的内容,受到开发者们的青睐。无论是文档编写,还是博客传记都广泛使用到Markdown。本文介绍试用JavaScript来构建一个Markdown解析器,解锁Markdown的强大之处。

什么是Markdown解析器

Markdown解析器的就是讲Markdown文本解析之后转换成HTML格式,供给浏览器渲染页面。例如文本中 # 标题 会被转换成 <h1>标题</h1> 形式的代码。

解析器基本实现

要想解析Markdown文本,首先要先提取出Markdown文本中各类标记,可以使用正则来获取,例如 /^# (.*$)/gim 可以获取到所有的 # 标题 标记,再将其替换成对应的HTML代码。

function parseMarkdown(markdown) {
    // 转换标题
    markdown = markdown.replace(/^# (.*$)/gim, '<h1>$1</h1>');
    markdown = markdown.replace(/^## (.*$)/gim, '<h2>$1</h2>');
    markdown = markdown.replace(/^### (.*$)/gim, '<h3>$1</h3>');

    // 转换加粗
    markdown = markdown.replace(/\*\*(.*?)\*\*/gim, '<strong>$1</strong>');

    // 转换斜体
    markdown = markdown.replace(/\*(.*?)\*/gim, '<em>$1</em>');

    // 转换链接
    markdown = markdown.replace(/\[(.*?)\]\((.*?)\)/gim, '<a href="$2">$1</a>');

    // 换行处理
    markdown = markdown.replace(/\n/gim, '<br />');

    return markdown.trim();
}

// 测试 Markdown 文本
const markdownText = `
# 欢迎使用 Markdown 解析器
## 副标题
这是 **加粗** 和 *斜体* 的示例。
[点击访问](https://scung.cn)
`;

console.log(parseMarkdown(markdownText));

上面的代码中 parseMarkdown 就是我们定义的Markdown解析器,内部通过使用 replace 方法进行内容的替换,替换的依据使用正则表达式来判断,完成了Markdown的基本解析

<h1>欢迎使用 Markdown 解析器</h1>
<br />
<h2>副标题</h2>
<br />
这是 <strong>加粗</strong><em>斜体</em> 的示例。
<br />
<a href="https://scung.cn">点击访问</a>
<br />

实现代码高亮

首先我们定义一个自定义解析代码的解析器,然后我们可以引入外部库,使用 highlight.js 实现代码高亮。

function parseCodeBlocks(markdown) {
    return markdown.replace(/```([\s\S]*?)```/gim, '<pre><code>$1</code></pre>');
}

结合上 highlight.js

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<script>
    let code = '``` let code = 1;```';

    let codeBlock = parseCodeBlocks(code);

    //将codeBlock插入到页面后调用代码高亮
    hljs.highlightAll();
</script>

构建一个 Markdown 解析器从简单正则到功能全面的扩展,可以灵活适配不同场景。对于小型项目,手动实现基础解析已足够;而大型项目中,结合库和工具则更高效。

其他阅读

Angular中制作一个按钮组件

本文将会介绍如何在Angular中制作一个自定义按钮组件,直接在原生按钮上添加特性即可使用,还提供多种颜色方便切换。

查看原文

HTTP方法

HTTP报文中包含了方法,指的是客户端希望服务器对资源执行的动作,是一个单独的词,比如GET,POST,OPTIONS等,本文将会介绍主流的几种方法。

查看原文

Linux中查看,添加,修改,删除用户和用户组

将用户分组是Linux系统中对用户进行管理及控制访问权限的一种手段。某个用户都属于某个用户组;一个组中可以有多个用户,一个用户也可以属于不同的组。当一个用户同时是多个组中的成员时,登录时所属的为默认组,而其他组称为附加组。本文将会介绍在 Linux 中查看,添加,修改,删除用户和用户组,注意:权限管理非常重要,可能一不小心就导致系统无法登录,请谨慎操作。

查看原文

网页小技巧

分享一些网页开发中实用的UI小技巧,快速完成页面搭建工作。

查看原文

解决sqlite依赖无法打包单文件的问题

在一次WPF开发中,选用了sqlite作为内嵌数据库,使用 ystem.Data.SQLite 库来调用,在使用 Fody 进行单文件打包时,发现打包文成后会出现 x86 和 x64 两个特定的文件夹,分别对应着32位和64位的 SQLite.Interop.dll,本文介绍修改项目文件来实现将 sqlite 通信库一起打包成单文件的方法。

查看原文