如何用Node.js实现给Markdown文件标题加数字序号?

简介: 本文介绍如何使用Node.js为Markdown文件的标题自动添加序号。通过读取文件、解析标题层级、维护计数器并重构标题行,实现清晰的多级编号体系,提升文档可读性,适合技术写作场景。

目录

前言

你好,我是喵喵侠。作为一名技术创作者,Markdown我每次写文章都会用到,它可以很方便的帮助我书写文章,让我专注于内容,不需要刻意注重排版。

当一篇文章的目录过多时,往往分不清最终显示的标题,到底是几级标题,以及这些标题是怎么样的层级和排序。

今天我将为你带来一个Markdown加序号的实现方法,看完你立马就能用上。

需求分析

我们这里用Node.js做演示,首先肯定是要读取到md文件内容,找出里面所有的标题,然后在每个标题的后面,添加合适的序号。

这里还需要追加限定条件:

如果最高层级的标题是一级标题#,那么得到的结果是# 1.

如果最高层级的标题是二级标题##,那么得到的结果是## 1.

依次类推……

那么怎么实现这样的操作呢,来看下面的实现步骤吧。

实现步骤

读取Markdown文件

从文件系统读取Markdown文件的内容。

解析并确定最高标题级别

遍历文件内容,确定最高标题级别。

解析并处理每一行

根据最高标题级别,逐行检查是否为标题行,更新计数器。

维护标题级别的计数器

使用一个数组记录每个级别标题的当前计数,并根据标题级别进行更新。

构造新的标题行

根据计数器的值构造新的标题行,添加相应的序号。

写回文件

将处理后的内容重新写回文件。

实现代码

废话不多数,直接上代码!

const fs = require('fs');
const path = require('path');
// 读取Markdown文件
const filePath = path.join(__dirname, 'your-file.md');
let fileContent = fs.readFileSync(filePath, 'utf8');
// 分割文件内容为行
let lines = fileContent.split('\n');
// 确定最高标题级别
let highestHeadingLevel = 6; // 初始化为最大标题级别
lines.forEach(line => {
  if (line.startsWith('#')) {
    const headingLevel = line.split(' ')[0].length;
    if (headingLevel < highestHeadingLevel) {
      highestHeadingLevel = headingLevel;
    }
  }
});
// 初始化计数器数组,根据最高标题级别决定长度
let headingCounters = Array(6 - highestHeadingLevel + 1).fill(0);
// 处理每一行
lines = lines.map(line => {
  if (line.startsWith('#')) {
    const headingLevel = line.split(' ')[0].length;
    if (headingLevel >= highestHeadingLevel) {
      const index = headingLevel - highestHeadingLevel;
      headingCounters[index] += 1; // 当前级别计数加1
      // 将当前级别以下的计数器归零
      for (let i = index + 1; i < headingCounters.length; i++) {
        headingCounters[i] = 0;
      }
      // 生成序号前缀
      const headingNumber = headingCounters.slice(0, index + 1).join('.');
      // 重构标题行
      line = line.replace(/^#+/, match => `${match} ${headingNumber}.`);
    }
  }
  return line;
});
// 写回Markdown文件
fileContent = lines.join('\n');
fs.writeFileSync(filePath, fileContent, 'utf8');
console.log('标题已添加序号');

代码解析

乍一看上面代码,可能读不太明白,这里做一个解析。

读取Markdown文件

读取Markdown文件的内容。

const filePath = path.join(__dirname, 'your-file.md');
let fileContent = fs.readFileSync(filePath, 'utf8');

分割文件内容为行

将文件内容按行分割成一个数组。

let lines = fileContent.split('\n');

确定最高标题级别

遍历每一行,确定文件中最高的标题级别(例如,最高标题级别是#还是##)。

let highestHeadingLevel = 6;
lines.forEach(line => {
  if (line.startsWith('#')) {
    const headingLevel = line.split(' ')[0].length;
    if (headingLevel < highestHeadingLevel) {
      highestHeadingLevel = headingLevel;
    }
  }
});

初始化计数器数组

根据最高标题级别,初始化计数器数组。

let headingCounters = Array(6 - highestHeadingLevel + 1).fill(0);

处理每一行

根据标题级别更新计数器,重构标题行。

lines = lines.map(line => {
  if (line.startsWith('#')) {
    const headingLevel = line.split(' ')[0].length;
    if (headingLevel >= highestHeadingLevel) {
      const index = headingLevel - highestHeadingLevel;
      headingCounters[index] += 1;
      for (let i = index + 1; i < headingCounters.length; i++) {
        headingCounters[i] = 0;
      }
      const headingNumber = headingCounters.slice(0, index + 1).join('.');
      line = line.replace(/^#+/, match => `${match} ${headingNumber}.`);
    }
  }
  return line;
});

写回文件

将处理后的内容写回Markdown文件。

fileContent = lines.join('\n');
fs.writeFileSync(filePath, fileContent, 'utf8');

结语

本文的代码脚本,会读取Markdown文件,解析并处理每一行标题,根据最高标题级别生成序号,并将处理后的内容写回文件,从而实现标题序号的自动添加。这个代码可以满足基本的使用,还有一些可以优化的点,比方说执行脚本可以输入文件路径、排除部分大标题(比如目录)的序号等等,也可以根据个人需要,改写成网页版本。如果你也喜欢用Markdown写作,不妨试一试吧。

目录
相关文章
|
5月前
|
边缘计算 人工智能 算法
基于 YOLOv8+DeepSORT 的高精准 AI 客流统计技术实现与优化
基于AI视觉技术的客流统计系统,融合YOLOv8、DeepSORT与高斯核密度算法,实现精准计数、动态热力图与智能预警,误差率低于3%。边缘+云端协同架构保障实时性与 scalability,人脸模糊化处理确保隐私合规,为运营决策提供全链路数据支撑。
505 0
|
小程序
uniapp如何分包 & 分包配置后无法读取static文件夹
uniapp如何分包 & 分包配置后无法读取static文件夹
1017 0
uniapp如何分包 & 分包配置后无法读取static文件夹
|
4月前
|
域名解析 人工智能 API
不用懂代码?DeepSeek 个人网站搭建,新手0基础一看就会!
通过阿里云计算巢“DeepSeek个人站点-快速部署”服务,用户可以轻松搭建专属DeepSeek网站。学生用户可领取300元代金券实现0成本部署,普通用户则可用99元/年的服务器。整个过程简单快捷,无需代码,最快5分钟完成部署,支持多种AI模型如DeepSeek、Qwen-max、Llama等。详细教程涵盖从购买到设置的每一步,确保用户顺利搭建并访问自己的AI网站。
564 9
|
5月前
|
JavaScript 前端开发 定位技术
Vue项目中的虚拟滚动:提升页面渲染性能的最佳实践
本文介绍虚拟滚动技术及其在Vue项目中的应用,通过vue-virtual-scroller实现大数据量下长列表的高性能渲染,提升页面流畅度与用户体验,适用于地图轨迹等业务场景。
1664 0
|
9月前
|
机器学习/深度学习 缓存 人工智能
MoE模型加速秘籍:vLLM混合KV缓存管理解析​
vLLM是高效分布式大模型推理引擎,采用分页注意力、连续批处理等技术实现高吞吐与低延迟。本文详解其架构设计与关键技术,包括KV缓存管理、调度机制、推测解码与分布式扩展等,助你深入理解性能优化原理。
1597 1
|
5月前
|
机器学习/深度学习 人工智能 算法
2026年Geo优化的底层逻辑:从语义占位到数字信任的范式重构
“两大核心+四轮驱动”体系,不仅是获客提效的工具,更是企业在AI语义空间中构建数字信任资产的底层协议。
305 1
|
6月前
|
移动开发 小程序 前端开发
告别高额开发费!优质婚恋交友系统/高颜值婚恋交友小程序源码快速入局
高颜值、全功能婚恋交友系统源码,支持微信小程序/H5/App三端。基于PHP+UniApp,含完整部署文档与二次开发指南,模块解耦易扩展,助力创业者快速落地校园恋爱、银发婚恋等多元场景,附赠技术群支持与定制服务。
263 0
|
5月前
|
前端开发 程序员 API
作为前端开发,分享下我在编程中的好习惯
前端开发喵喵侠分享多年实战总结的8个编程好习惯:写前先思考、注释重“为什么”、规范命名、代码自检、写文档、Git提交规范化、表单提示友好化、果断删除无用代码。习惯决定代码质量,写出半年后自己仍能读懂的代码,才是成熟的开始。
159 0
|
5月前
|
存储 弹性计算 人工智能
2026年阿里云服务器价格解析:轻量服务器与 ECS 云服务器配置成本及选型参考
阿里云服务器通过 “轻量应用服务器” 与 “云服务器 ECS” 两大品类,覆盖从个人开发到企业级业务的多元化需求,不同配置的价格差异显著,核心围绕 “算力 - 内存 - 带宽” 三大维度定价。本文基于官方定价与实测数据,梳理主流配置的价格体系、性能特点及适配场景,为用户提供客观的成本与选型参考,帮助避开 “过度配置” 或 “性能不足” 的误区。