/** * `@toc.sub@` collects Markdown headers that are **below** the placeholder and on the same or deeper level. * If there's a header above the placeholder, its depth will be used as a minimum depth. * If there's no header above the placeholder, the first header after the placeholder will be used for the minimum depth. * There is currently no maximum depth for `@toc.sub@`. * * e.g. * ```markdown * # ignore me * * @toc.sub@ * ## sub 1 * # ignore me again * ``` * is converted into * * ```markdown * # ignore me * - [sub 1](#sub-1) * ## sub 1 * # ignore me again * ``` * * @param \nochso\WriteMe\Placeholder\Call $call * @param int $maxDepth How many levels of headers you'd like to keep. * Defaults to zero, meaning all sub-headers are kept. */ public function tocSub(Call $call, $maxDepth = 0) { $parser = new Markdown\HeaderParser(); $headerList = $parser->extractHeaders($call->getDocument()); $lines = Multiline::create($call->getDocument()->getContent()); $lineIndex = $lines->getLineIndexByCharacterPosition($call->getStartPositionOfRawCall()); $headers = $headerList->getHeadersBelowLine($lineIndex); if ($maxDepth > 0) { $minDepth = $this->getMinimumDepth($headers); // Filter headers that are relatively too deep $headers = array_filter($headers, function (Markdown\Header $header) use($minDepth, $maxDepth) { return $header->getLevel() - $minDepth < $maxDepth; }); } $toc = $this->formatTOC($headers); $call->replace($toc); }
/** * @param string $input * @param array $expectedText * @param array $expectedLevel * @param array $expectedLineIndex * @param array $expectedUniqueCounter * * @dataProvider extractHeadersProvider */ public function testExtractHeaders($input, array $expectedText = null, array $expectedLevel = null, array $expectedLineIndex = null, array $expectedUniqueCounter = null) { $parser = new HeaderParser(); $document = new Document($input); $headerList = $parser->extractHeaders($document); $headers = $headerList->getHeaders(); $expectedCount = count($expectedText); $this->assertCount($expectedCount, $headers); for ($i = 0; $i < $expectedCount; $i++) { if ($expectedText !== null) { $this->assertSame($expectedText[$i], $headers[$i]->getText()); } if ($expectedLevel !== null) { $this->assertSame($expectedLevel[$i], $headers[$i]->getLevel()); } if ($expectedLineIndex !== null) { $this->assertSame($expectedLineIndex[$i], $headers[$i]->getLineIndex()); } if ($expectedUniqueCounter !== null) { $this->assertSame($expectedUniqueCounter[$i], $headers[$i]->getUniqueCounter()); } } }