Files
wordpress-kratos-yang/assets/css
laoyang 76c69b31e8 正文标题自动编号,与目录编号共用同一份计算 #30
需求:目录里有编号、正文标题没有,读长文时要回头去目录找对应关系。
本版给 h1/h2/h3 加编号,样式为灰色小号(标题字号的 0.62 倍),
不抢标题视觉重心,与目录 .yang-toc-num 同风格。

编号规则(编号范围跟着后台 toc_levels 设置走,默认 1/2/3):
- 按「实际出现的最外层」归一,没有 h1 时 h2 直接是一级(1/2/3),
  不会编成 2/2.1。天然满足用户"h1 没有就是 h2 一级"的要求。
- 作者已手写编号的标题跳过并占位(1./1、/1)/1.2/一、/(一)/第一章
  等写法),不叠加成"3.1 1. xxx",但编号序列不错位。

实现要点:
- 抽出 yang_toc_pick / yang_toc_depths / yang_toc_number_map 三个纯函数,
  目录与正文共用同一份编号计算,杜绝两边漂移(用户痛点正是"两边不一致")。
- 插入按 id 回填:条目清单只来自 scan() 那一份,id 是唯一键。
- 用 preg_match_all + PREG_OFFSET_CAPTURE 拿字节偏移、从后往前拼接插入。
  早期写成 preg_replace_callback('#<h([1-6])([^>]*)>(.{0,120})#is'),
  那个 .{0,120} 贪婪跨过块边界,导致 5 个标题只有第 1 个拿到编号且不报错。
- 幂等用 strncmp(substr($html,$end), $needle, strlen($needle)),不手数字节
  (写成固定 26 而实际 25 会让幂等静默失效、编号插两层)。

CSS 修一个自己造的问题:编号把标题撑高 3px。
line-height:inherit 无效——同行高下小字号半行距更大,盒底反而更往下探
(h2 46→49)。改为 display:inline-block + line-height:1 成为原子行内盒,
实测 46→46、37→37。八组隔离试验数据见 _tooling/_diag362b.js。

验证(全部本地/线上实跑,非推断):
- 正向判据 43/0;反证 22/0(10 组注入均红在预期条目)
- 线上 4 篇真实文章 20/0(含"只有 h3"、"h1+h2"、"h2+h3"三种形态)
- 新旧两版目录 HTML 逐字节比对 7/0(4/4 篇相同,证明重构没改坏老行为)
- 几何判据 68/0,含两条反证:回到 inline+inherit ⇒ 高度差 3.00px;
  编号 display:block 掉行 ⇒ G3 差 14.88px
- 打包自检 59/0 + 4 组注入反证全红
2026-10-28 08:27:53 +08:00
..