1<?php 2 3/* 4 * This file is part of the league/commonmark package. 5 * 6 * (c) Colin O'Dell <colinodell@gmail.com> 7 * (c) Rezo Zero / Ambroise Maupate 8 * 9 * For the full copyright and license information, please view the LICENSE 10 * file that was distributed with this source code. 11 */ 12 13declare(strict_types=1); 14 15namespace League\CommonMark\Extension\Footnote\Parser; 16 17use League\CommonMark\Extension\Footnote\Node\FootnoteRef; 18use League\CommonMark\Inline\Parser\InlineParserInterface; 19use League\CommonMark\InlineParserContext; 20use League\CommonMark\Normalizer\SlugNormalizer; 21use League\CommonMark\Normalizer\TextNormalizerInterface; 22use League\CommonMark\Reference\Reference; 23use League\CommonMark\Util\ConfigurationAwareInterface; 24use League\CommonMark\Util\ConfigurationInterface; 25 26final class AnonymousFootnoteRefParser implements InlineParserInterface, ConfigurationAwareInterface 27{ 28 /** @var ConfigurationInterface */ 29 private $config; 30 31 /** @var TextNormalizerInterface */ 32 private $slugNormalizer; 33 34 public function __construct() 35 { 36 $this->slugNormalizer = new SlugNormalizer(); 37 } 38 39 public function getCharacters(): array 40 { 41 return ['^']; 42 } 43 44 public function parse(InlineParserContext $inlineContext): bool 45 { 46 $container = $inlineContext->getContainer(); 47 $cursor = $inlineContext->getCursor(); 48 $nextChar = $cursor->peek(); 49 if ($nextChar !== '[') { 50 return false; 51 } 52 $state = $cursor->saveState(); 53 54 $m = $cursor->match('/\^\[[^\n^\]]+\]/'); 55 if ($m !== null) { 56 if (\preg_match('#\^\[([^\]]+)\]#', $m, $matches) > 0) { 57 $reference = $this->createReference($matches[1]); 58 $container->appendChild(new FootnoteRef($reference, $matches[1])); 59 60 return true; 61 } 62 } 63 64 $cursor->restoreState($state); 65 66 return false; 67 } 68 69 private function createReference(string $label): Reference 70 { 71 $refLabel = $this->slugNormalizer->normalize($label); 72 $refLabel = \mb_substr($refLabel, 0, 20); 73 74 return new Reference( 75 $refLabel, 76 '#' . $this->config->get('footnote/footnote_id_prefix', 'fn:') . $refLabel, 77 $label 78 ); 79 } 80 81 public function setConfiguration(ConfigurationInterface $config): void 82 { 83 $this->config = $config; 84 } 85} 86