Of anchors and ToCs

Hello everyone,

I’ve got some issues with the “Of anchors and ToCs, part 1” in CookBook. The first step works (Replace headlines with anchors) with the code :

<?php

Kirby::plugin('k-cookbook/toc', [
  'hooks' => [
    'kirbytext:after' => [

      function($text) {

        // get the headline levels to convert from a config option, we use h2 as the default
        $headlines = option('k-cookbook.toc.headlines', 'h2|h3');

        // create the regex pattern to be used as first argument in `preg_replace_callback()`
        $headlinesPattern = is_array($headlines) ? implode('|', $headlines) : $headlines;

        // use `preg_replace_callback()` to replace matches with anchors
        $text = preg_replace_callback('!<(' . $headlinesPattern . ')>(.*?)</\\1>!s', function ($match) {

            // create the id from the headline text
            $id = Str::slug(Str::unhtml($match[2]));

            // return the modified headline:
            // $match[1] contains the match for the first subpattern, i.e. `h2`, `h3` etc.
            // $match[2] contains the match for the second subpattern, i.e. the actual headline text
            return '<' . $match[1] . ' id="' . $id . '"><a href="#' . $id . '">' . $match[2] . '</a></' . $match[1] . '>';

        }, $text);

        return $text;
      },
    ]
  ]
]);

But then, I’m not sure how to add this first part to the second part for Generate the ToC

<?php

use Kirby\Toolkit\Collection;
use Kirby\Toolkit\Str;
use Kirby\Toolkit\Obj;

Kirby::plugin('k-cookbook/toc', [
  'hooks' => [

    'kirbytext:after' => [

      // (…) add the callback function from above here (without the wrapper)

      function($text) {

        // the pattern allows passing an optional headline level `(toc: h3)`
        $pattern  = '!\(toc(?::\s?(h[1-6]))?\)!';

        $text = preg_replace_callback($pattern, function($match) use($text) {

          // get the headline level from the match
          $headline = $match[1] ?? 'h2';

          // find all headline matches
          preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $text, $matches);

          // create a new collection for the headlines…
          $headlines = new Collection();

          // …and add all matches
          foreach ($matches[1] as $text) {
              $headline = new Obj([
                  'id'   => $id = '#' . Str::slug(Str::unhtml($text)),
                  'url'  => $id,
                  'text' => trim(strip_tags($text)),
              ]);

              $headlines->append($headline->url(), $headline);
          }

          // return the html for the ToC
          return snippet('toc', ['headlines' => $headlines], false);

        }, $text);

        return $text;

      },
    ],
  ],
  'snippets' => [
    'toc' => __DIR__ . '/snippets/toc.php'
  ],
]);

I’m working on the starterkit on /content/notes page, has anyone done this before ?

Thanks !

Closed because duplicate.