*/ public static function extractToc(string $content): array { $items = []; $lines = explode("\n", $content); // Use CommonMark's own SlugNormalizer so TOC links match the rendered heading IDs exactly. $normalizer = new \League\CommonMark\Normalizer\SlugNormalizer(); foreach ($lines as $line) { if (preg_match('/^(#{1,3})\s+(.+)$/', $line, $m)) { $level = strlen($m[1]); $label = trim($m[2]); $id = $normalizer->normalize($label); $items[] = ['label' => $label, 'href' => '#' . $id, 'level' => $level]; } } return $items; } }