10a016d04SGreg Roach<?php 23976b470SGreg Roach 30a016d04SGreg Roach/** 40a016d04SGreg Roach * webtrees: online genealogy 589f7189bSGreg Roach * Copyright (C) 2021 webtrees development team 60a016d04SGreg Roach * This program is free software: you can redistribute it and/or modify 70a016d04SGreg Roach * it under the terms of the GNU General Public License as published by 80a016d04SGreg Roach * the Free Software Foundation, either version 3 of the License, or 90a016d04SGreg Roach * (at your option) any later version. 100a016d04SGreg Roach * This program is distributed in the hope that it will be useful, 110a016d04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 120a016d04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 130a016d04SGreg Roach * GNU General Public License for more details. 140a016d04SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 160a016d04SGreg Roach */ 17fcfa147eSGreg Roach 18e7f56f2aSGreg Roachdeclare(strict_types=1); 19e7f56f2aSGreg Roach 200a016d04SGreg Roachnamespace Fisharebest\Webtrees\CommonMark; 210a016d04SGreg Roach 228d0ebef0SGreg Roachuse Fisharebest\Webtrees\Gedcom; 230a016d04SGreg Roachuse Fisharebest\Webtrees\GedcomRecord; 246b9cb339SGreg Roachuse Fisharebest\Webtrees\Registry; 250a016d04SGreg Roachuse Fisharebest\Webtrees\Tree; 264a1f1d43SGreg Roachuse League\CommonMark\Inline\Parser\InlineParserInterface; 270a016d04SGreg Roachuse League\CommonMark\InlineParserContext; 280a016d04SGreg Roach 29eec99f1aSGreg Roachuse function is_string; 30eec99f1aSGreg Roachuse function trim; 31eec99f1aSGreg Roach 320a016d04SGreg Roach/** 330a016d04SGreg Roach * Convert XREFs within markdown text to links 340a016d04SGreg Roach */ 354a1f1d43SGreg Roachclass XrefParser implements InlineParserInterface 36c1010edaSGreg Roach{ 370a016d04SGreg Roach /** @var Tree - match XREFs in this tree */ 380a016d04SGreg Roach private $tree; 390a016d04SGreg Roach 400a016d04SGreg Roach /** 410a016d04SGreg Roach * MarkdownXrefParser constructor. 420a016d04SGreg Roach * 430a016d04SGreg Roach * @param Tree $tree 440a016d04SGreg Roach */ 45c1010edaSGreg Roach public function __construct(Tree $tree) 46c1010edaSGreg Roach { 470a016d04SGreg Roach $this->tree = $tree; 480a016d04SGreg Roach } 490a016d04SGreg Roach 500a016d04SGreg Roach /** 510a016d04SGreg Roach * We are only interested in text that begins with '@'. 520a016d04SGreg Roach * 5324f2a3afSGreg Roach * @return array<string> 540a016d04SGreg Roach */ 558f53f488SRico Sonntag public function getCharacters(): array 56c1010edaSGreg Roach { 570a016d04SGreg Roach return ['@']; 580a016d04SGreg Roach } 590a016d04SGreg Roach 600a016d04SGreg Roach /** 61*56d47542SGreg Roach * @param InlineParserContext $inlineContext 620a016d04SGreg Roach * 630a016d04SGreg Roach * @return bool 640a016d04SGreg Roach */ 65*56d47542SGreg Roach public function parse(InlineParserContext $inlineContext): bool 66c1010edaSGreg Roach { 670a016d04SGreg Roach // The cursor should be positioned on the opening '@'. 68*56d47542SGreg Roach $cursor = $inlineContext->getCursor(); 690a016d04SGreg Roach 70eec99f1aSGreg Roach // If this isn't the start of an XREF, we'll need to rewind to here. 710a016d04SGreg Roach $previous_state = $cursor->saveState(); 720a016d04SGreg Roach 73eec99f1aSGreg Roach $xref = $cursor->match('/@' . Gedcom::REGEX_XREF . '@/'); 740a016d04SGreg Roach 75eec99f1aSGreg Roach if (is_string($xref)) { 76eec99f1aSGreg Roach $xref = trim($xref, '@'); 776b9cb339SGreg Roach $record = Registry::gedcomRecordFactory()->make($xref, $this->tree); 780a016d04SGreg Roach 79eec99f1aSGreg Roach if ($record instanceof GedcomRecord) { 80*56d47542SGreg Roach $inlineContext->getContainer()->appendChild(new XrefNode($record)); 81eec99f1aSGreg Roach 82eec99f1aSGreg Roach return true; 83eec99f1aSGreg Roach } 84eec99f1aSGreg Roach } 85eec99f1aSGreg Roach 86eec99f1aSGreg Roach // Not an XREF? Linked record does not exist? 870a016d04SGreg Roach $cursor->restoreState($previous_state); 880a016d04SGreg Roach 890a016d04SGreg Roach return false; 900a016d04SGreg Roach } 910a016d04SGreg Roach} 92