1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2022 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Factories; 21 22use Fisharebest\Webtrees\CommonMark\CensusTableExtension; 23use Fisharebest\Webtrees\CommonMark\XrefExtension; 24use Fisharebest\Webtrees\Contracts\MarkdownFactoryInterface; 25use Fisharebest\Webtrees\Tree; 26use League\CommonMark\Environment\Environment; 27use League\CommonMark\Extension\Autolink\AutolinkExtension; 28use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; 29use League\CommonMark\Extension\CommonMark\Node\Inline\Link; 30use League\CommonMark\Extension\CommonMark\Renderer\Inline\LinkRenderer; 31use League\CommonMark\Extension\Table\TableExtension; 32use League\CommonMark\MarkdownConverter; 33use League\CommonMark\Node\Block\Document; 34use League\CommonMark\Node\Block\Paragraph; 35use League\CommonMark\Node\Inline\Newline; 36use League\CommonMark\Node\Inline\Text; 37use League\CommonMark\Parser\Inline\NewlineParser; 38use League\CommonMark\Renderer\Block\DocumentRenderer; 39use League\CommonMark\Renderer\Block\ParagraphRenderer; 40use League\CommonMark\Renderer\Inline\NewlineRenderer; 41use League\CommonMark\Renderer\Inline\TextRenderer; 42use League\CommonMark\Util\HtmlFilter; 43 44use function strip_tags; 45use function strtr; 46use function trim; 47 48/** 49 * Create a markdown converter. 50 */ 51class MarkdownFactory implements MarkdownFactoryInterface 52{ 53 protected const CONFIG_AUTOLINK = [ 54 'allow_unsafe_links' => false, 55 'html_input' => HtmlFilter::ESCAPE, 56 'renderer' => [ 57 'soft_break' => '<br>', 58 ], 59 ]; 60 61 protected const CONFIG_MARKDOWN = [ 62 'allow_unsafe_links' => false, 63 'html_input' => HtmlFilter::ESCAPE, 64 'renderer' => [ 65 'soft_break' => '<br>', 66 ], 67 'table' => [ 68 'wrap' => [ 69 'enabled' => true, 70 'tag' => 'div', 71 'attributes' => [ 72 'class' => 'table-responsive', 73 ], 74 ], 75 ], 76 ]; 77 78 /** 79 * @param string $markdown 80 * @param Tree|null $tree 81 * 82 * @return string 83 */ 84 public function autolink(string $markdown, Tree $tree = null): string 85 { 86 // Create a minimal commonmark processor - just add support for auto-links. 87 $environment = new Environment(static::CONFIG_AUTOLINK); 88 $environment->addInlineParser(new NewlineParser()); 89 $environment->addRenderer(Document::class, new DocumentRenderer()); 90 $environment->addRenderer(Paragraph::class, new ParagraphRenderer()); 91 $environment->addRenderer(Text::class, new TextRenderer()); 92 $environment->addRenderer(Link::class, new LinkRenderer()); 93 $environment->addRenderer(Newline::class, new NewlineRenderer()); 94 $environment->addExtension(new AutolinkExtension()); 95 96 // Optionally create links to other records. 97 if ($tree instanceof Tree) { 98 $environment->addExtension(new XrefExtension($tree)); 99 } 100 101 $converter = new MarkDownConverter($environment); 102 103 $html = $converter->convert($markdown)->getContent(); 104 $html = strtr($html, ["</p>\n<p>" => '<br><br>' ]); 105 106 return trim(strip_tags($html, ['a', 'br'])); 107 } 108 109 /** 110 * @param string $markdown 111 * @param Tree|null $tree 112 * 113 * @return string 114 */ 115 public function markdown(string $markdown, Tree $tree = null): string 116 { 117 $environment = new Environment(static::CONFIG_MARKDOWN); 118 $environment->addExtension(new CommonMarkCoreExtension()); 119 $environment->addExtension(new TableExtension()); 120 121 // Convert webtrees 1.x style census tables to commonmark format. 122 $environment->addExtension(new CensusTableExtension()); 123 124 // Optionally create links to other records. 125 if ($tree instanceof Tree) { 126 $environment->addExtension(new XrefExtension($tree)); 127 } 128 129 $converter = new MarkDownConverter($environment); 130 131 return $converter->convert($markdown)->getContent(); 132 } 133} 134