. */ declare(strict_types=1); namespace Fisharebest\Webtrees\CommonMark; use Fisharebest\Webtrees\Gedcom; use Fisharebest\Webtrees\GedcomRecord; use Fisharebest\Webtrees\Registry; 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 { private Tree $tree; /** * MarkdownXrefParser constructor. * * @param Tree $tree Match XREFs in this tree */ public function __construct(Tree $tree) { $this->tree = $tree; } /** * We are only interested in text that begins with '@'. * * @return array */ public function getCharacters(): array { return ['@']; } /** * @param InlineParserContext $inlineContext * * @return bool */ public function parse(InlineParserContext $inlineContext): bool { // The cursor should be positioned on the opening '@'. $cursor = $inlineContext->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 = Registry::gedcomRecordFactory()->make($xref, $this->tree); if ($record instanceof GedcomRecord) { $inlineContext->getContainer()->appendChild(new XrefNode($record)); return true; } } // Not an XREF? Linked record does not exist? $cursor->restoreState($previous_state); return false; } }