前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何用Node.js实现给Markdown文件标题加数字序号?

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

原创
作者头像
喵喵侠
发布2024-07-31 21:34:03
1360
发布2024-07-31 21:34:03
举报

目录

前言

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

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

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

需求分析

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

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

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

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

依次类推……

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

实现步骤

读取Markdown文件

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

解析并确定最高标题级别

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

解析并处理每一行

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

维护标题级别的计数器

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

构造新的标题行

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

写回文件

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

实现代码

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

代码语言:javascript
复制
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文件的内容。

代码语言:javascript
复制
const filePath = path.join(__dirname, 'your-file.md');
let fileContent = fs.readFileSync(filePath, 'utf8');

分割文件内容为行

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

代码语言:javascript
复制
let lines = fileContent.split('\n');

确定最高标题级别

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

代码语言:javascript
复制
let highestHeadingLevel = 6;
lines.forEach(line => {
  if (line.startsWith('#')) {
    const headingLevel = line.split(' ')[0].length;
    if (headingLevel < highestHeadingLevel) {
      highestHeadingLevel = headingLevel;
    }
  }
});

初始化计数器数组

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

代码语言:javascript
复制
let headingCounters = Array(6 - highestHeadingLevel + 1).fill(0);

处理每一行

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

代码语言:javascript
复制
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文件。

代码语言:javascript
复制
fileContent = lines.join('\n');
fs.writeFileSync(filePath, fileContent, 'utf8');

结语

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 前言
  • 需求分析
  • 实现步骤
    • 读取Markdown文件
      • 解析并确定最高标题级别
        • 解析并处理每一行
          • 维护标题级别的计数器
            • 构造新的标题行
              • 写回文件
              • 实现代码
              • 代码解析
                • 读取Markdown文件
                  • 分割文件内容为行
                    • 确定最高标题级别
                      • 初始化计数器数组
                        • 处理每一行
                          • 写回文件
                          • 结语
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档