. */ declare(strict_types=1); namespace Fisharebest\Webtrees\CommonMark; use Fisharebest\Webtrees\Factory; use Fisharebest\Webtrees\Gedcom; use Fisharebest\Webtrees\GedcomRecord; use Fisharebest\Webtrees\Tree; use League\CommonMark\Inline\Parser\InlineParserInterface; use League\CommonMark\InlineParserContext; use function is_string; use function trim; /** * Convert XREFs within markdown text to links */ class XrefParser implements InlineParserInterface { /** @var Tree - match XREFs in this tree */ private $tree; /** * MarkdownXrefParser constructor. * * @param Tree $tree */ public function __construct(Tree $tree) { $this->tree = $tree; } /** * We are only interested in text that begins with '@'. * * @return string[] */ public function getCharacters(): array { return ['@']; } /** * @param InlineParserContext $context * * @return bool */ public function parse(InlineParserContext $context): bool { // The cursor should be positioned on the opening '@'. $cursor = $context->getCursor(); // If this isn't the start of an XREF, we'll need to rewind to here. $previous_state = $cursor->saveState(); $xref = $cursor->match('/@' . Gedcom::REGEX_XREF . '@/'); if (is_string($xref)) { $xref = trim($xref, '@'); $record = Factory::gedcomRecord()->make($xref, $this->tree); if ($record instanceof GedcomRecord) { $context->getContainer()->appendChild(new XrefNode($record)); return true; } } // Not an XREF? Linked record does not exist? $cursor->restoreState($previous_state); return false; } }