1 前言

在用typecho写文章时,总是需要使用标题来组织文章结构,但是标题多了没有编号的话看起来总感觉不舒服。采用手动编号不方便调整文章内容位置而且容易出错,于是想着如果能够根据文章HTML的标题自动编号为:

  • 1 前言 (h1)
  • 1.1 文章背景 (h2)
  • 1.2 标题1.2
  • 2 介绍
  • 2.1 标题2.1
  • 2.2 标题2.2
  • ......

那就方便多了,于是使用GPT帮忙找到如下方法。

2 具体方法

首先找到主题的functions.php(如果是handsome主题,则为functions_mine.php)在其末尾添加如下函数:

// 新增函数
function add_heading_numbers($content) {
    $counters = []; // 用于记录每个标题级别的编号

    // 使用正则替换回调,匹配 <h1> 到 <h6>
    $content = preg_replace_callback(
        '/<(h[1-6])>(.*?)<\/\1>/i',
        function ($matches) use (&$counters) {
            $level = intval(substr($matches[1], 1)); // 获取标题等级(1 到 6)
                        $title = $matches[2]; // 获取标题内容

            // 判断标题是否以数字或 "第n章" 开头
            if (preg_match('/^(\d+(\.\d+)*|第\s*\d+\s*章)/u', trim($title))) {
                return $matches[0]; // 原样返回标题,不进行编号
            }

            // 截断计数器数组到当前级别
            $counters = array_slice($counters, 0, $level);

            // 当前级别的计数器加1
            $counters[$level - 1] = ($counters[$level - 1] ?? 0) + 1;

            // 生成编号,例如 "1.1.2"
            $number = implode('.', $counters);

            // 返回带编号的新标题
            return sprintf('<%1$s>%2$s %3$s</%1$s>', $matches[1], $number, $matches[2]);
        },
        $content
    );

    return $content;
}

然后找到主题下的post.php文件的输出文章内容的地方,添加如下代码即可:

$this->content = add_heading_numbers($this->content);

如果是handsome主题则如图所示:

2024-12-13T14:23:04.png

最后修改:2024 年 12 月 13 日
如果觉得我的文章对你有用,请随意赞赏