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 // Commonmark uses <br /> for hard-breaks, so we use the same for soft-breaks. 54 protected const CONFIG_AUTOLINK = [ 55 'allow_unsafe_links' => false, 56 'html_input' => HtmlFilter::ESCAPE, 57 'renderer' => [ 58 'soft_break' => '<br />', 59 ], 60 ]; 61 62 protected const CONFIG_MARKDOWN = [ 63 'allow_unsafe_links' => false, 64 'html_input' => HtmlFilter::ESCAPE, 65 'renderer' => [ 66 'soft_break' => '<br />', 67 ], 68 'table' => [ 69 'wrap' => [ 70 'enabled' => true, 71 'tag' => 'div', 72 'attributes' => [ 73 'class' => 'table-responsive', 74 ], 75 ], 76 ], 77 ]; 78 79 /** 80 * @param string $markdown 81 * @param Tree|null $tree 82 * 83 * @return string 84 */ 85 public function autolink(string $markdown, Tree $tree = null): string 86 { 87 // Create a minimal commonmark processor - just add support for auto-links. 88 $environment = new Environment(static::CONFIG_AUTOLINK); 89 $environment->addInlineParser(new NewlineParser()); 90 $environment->addRenderer(Document::class, new DocumentRenderer()); 91 $environment->addRenderer(Paragraph::class, new ParagraphRenderer()); 92 $environment->addRenderer(Text::class, new TextRenderer()); 93 $environment->addRenderer(Link::class, new LinkRenderer()); 94 $environment->addRenderer(Newline::class, new NewlineRenderer()); 95 $environment->addExtension(new AutolinkExtension()); 96 97 // Optionally create links to other records. 98 if ($tree instanceof Tree) { 99 $environment->addExtension(new XrefExtension($tree)); 100 } 101 102 $converter = new MarkDownConverter($environment); 103 104 $html = $converter->convert($markdown)->getContent(); 105 $html = strtr($html, ["</p>\n<p>" => '<br><br>' ]); 106 107 return trim(strip_tags($html, ['a', 'br'])); 108 } 109 110 /** 111 * @param string $markdown 112 * @param Tree|null $tree 113 * 114 * @return string 115 */ 116 public function markdown(string $markdown, Tree $tree = null): string 117 { 118 $environment = new Environment(static::CONFIG_MARKDOWN); 119 $environment->addExtension(new CommonMarkCoreExtension()); 120 $environment->addExtension(new TableExtension()); 121 122 // Convert webtrees 1.x style census tables to commonmark format. 123 $environment->addExtension(new CensusTableExtension()); 124 125 // Optionally create links to other records. 126 if ($tree instanceof Tree) { 127 $environment->addExtension(new XrefExtension($tree)); 128 } 129 130 $converter = new MarkDownConverter($environment); 131 132 return $converter->convert($markdown)->getContent(); 133 } 134} 135