diff options
22 files changed, 679 insertions, 414 deletions
diff --git a/app/CommonMark/CensusTableContinueParser.php b/app/CommonMark/CensusTableContinueParser.php new file mode 100644 index 0000000000..ff7c98df50 --- /dev/null +++ b/app/CommonMark/CensusTableContinueParser.php @@ -0,0 +1,124 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\CommonMark; + +use League\CommonMark\Extension\Table\Table; +use League\CommonMark\Extension\Table\TableCell; +use League\CommonMark\Extension\Table\TableRow; +use League\CommonMark\Extension\Table\TableSection; +use League\CommonMark\Node\Block\AbstractBlock; +use League\CommonMark\Node\Inline\Text; +use League\CommonMark\Parser\Block\AbstractBlockContinueParser; +use League\CommonMark\Parser\Block\BlockContinue; +use League\CommonMark\Parser\Block\BlockContinueParserInterface; +use League\CommonMark\Parser\Cursor; + +use function array_map; +use function explode; +use function str_starts_with; +use function strlen; +use function substr; + +/** + * Convert webtrees 1.x census-assistant markup into tables. + * Note that webtrees 2.0 generates markdown tables directly. + */ +class CensusTableContinueParser extends AbstractBlockContinueParser +{ + private Table $table; + + private TableSection $thead; + + private TableSection $tbody; + + /** + * Constructor + */ + public function __construct() + { + $this->table = new Table(); + $this->thead = new TableSection(TableSection::TYPE_HEAD); + $this->tbody = new TableSection(TableSection::TYPE_BODY); + $this->table->appendChild($this->thead); + $this->table->appendChild($this->tbody); + } + + /** + * @param Cursor $cursor + * @param BlockContinueParserInterface $activeBlockParser + * + * @return BlockContinue|null + */ + public function tryContinue(Cursor $cursor, BlockContinueParserInterface $activeBlockParser): ?BlockContinue + { + $line = $cursor->getLine(); + + if ($line === CensusTableExtension::CA_SUFFIX) { + return BlockContinue::finished(); + } + + // Blank line before the suffix is an error. + if ($line === '') { + return BlockContinue::none(); + } + + $cells = explode('|', $line); + + $callback = static function (string $text): string { + if (str_starts_with($text, CensusTableExtension::TH_PREFIX)) { + return substr($text, strlen(CensusTableExtension::TH_PREFIX)); + } + + return $text; + }; + + $tr = new TableRow(); + + if (empty($this->thead->children())) { + $cells = array_map($callback, $cells); + + foreach ($cells as $cell) { + $table_cell = new TableCell(TableCell::TYPE_HEADER); + $table_cell->appendChild(new Text($cell)); + $tr->appendChild($table_cell); + } + + $this->thead->appendChild($tr); + } else { + foreach ($cells as $cell) { + $table_cell = new TableCell(TableCell::TYPE_DATA); + $table_cell->appendChild(new Text($cell)); + $tr->appendChild($table_cell); + } + + $this->tbody->appendChild($tr); + } + + return BlockContinue::at($cursor); + } + + /** + * @return Table + */ + public function getBlock(): AbstractBlock + { + return $this->table; + } +} diff --git a/app/CommonMark/CensusTableExtension.php b/app/CommonMark/CensusTableExtension.php index 43add29d0c..b00b24c6bf 100644 --- a/app/CommonMark/CensusTableExtension.php +++ b/app/CommonMark/CensusTableExtension.php @@ -19,32 +19,44 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\CommonMark; -use League\CommonMark\ConfigurableEnvironmentInterface; -use League\CommonMark\Extension\ExtensionInterface; -use League\CommonMark\Extension\Table\Table; -use League\CommonMark\Extension\Table\TableCell; -use League\CommonMark\Extension\Table\TableCellRenderer; -use League\CommonMark\Extension\Table\TableRenderer; -use League\CommonMark\Extension\Table\TableRow; -use League\CommonMark\Extension\Table\TableRowRenderer; -use League\CommonMark\Extension\Table\TableSection; -use League\CommonMark\Extension\Table\TableSectionRenderer; +use League\CommonMark\Environment\EnvironmentBuilderInterface; +use League\CommonMark\Extension\ConfigurableExtensionInterface; +use League\CommonMark\Extension\Table\TableExtension; +use League\Config\ConfigurationBuilderInterface; /** * Convert webtrees 1.x census-assistant markup into tables. * Note that webtrees 2.0 generates markdown tables directly. * - * Based on the table parser from league/commonmark-ext-table. + * .start_formatted_area. + * .b.HEADING1|.b.HEADING2|.b.HEADING3 + * COL1|COL2|COL3 + * COL1|COL2|COL3 + * .end_formatted_area. */ -class CensusTableExtension implements ExtensionInterface +class CensusTableExtension implements ConfigurableExtensionInterface { - public function register(ConfigurableEnvironmentInterface $environment): void + // Keywords used to create the webtrees 1.x census-assistant notes. + public const CA_PREFIX = '.start_formatted_area.'; + public const CA_SUFFIX = '.end_formatted_area.'; + public const TH_PREFIX = '.b.'; + + /** + * The core TableExtension will already have configured tables. + * + * @param ConfigurationBuilderInterface $builder + */ + public function configureSchema(ConfigurationBuilderInterface $builder): void + { + } + + /** + * Assumes we have also registered the core TableExtension. + * + * @param EnvironmentBuilderInterface $environment + */ + public function register(EnvironmentBuilderInterface $environment): void { - $environment - ->addBlockParser(new CensusTableParser()) - ->addBlockRenderer(Table::class, new TableRenderer()) - ->addBlockRenderer(TableSection::class, new TableSectionRenderer()) - ->addBlockRenderer(TableRow::class, new TableRowRenderer()) - ->addBlockRenderer(TableCell::class, new TableCellRenderer()); + $environment->addBlockStartParser(new CensusTableStartParser()); } } diff --git a/app/CommonMark/CensusTableParser.php b/app/CommonMark/CensusTableParser.php deleted file mode 100644 index b5162edb59..0000000000 --- a/app/CommonMark/CensusTableParser.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php - -/** - * webtrees: online genealogy - * Copyright (C) 2021 webtrees development team - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -declare(strict_types=1); - -namespace Fisharebest\Webtrees\CommonMark; - -use League\CommonMark\Block\Element\Paragraph; -use League\CommonMark\Block\Parser\BlockParserInterface; -use League\CommonMark\ContextInterface; -use League\CommonMark\Cursor; -use League\CommonMark\Extension\Table\Table; -use League\CommonMark\Extension\Table\TableCell; -use League\CommonMark\Extension\Table\TableRow; - -use function array_shift; -use function explode; -use function str_starts_with; -use function substr; - -/** - * Convert webtrees 1.x census-assistant markup into tables. - * Note that webtrees 2.0 generates markdown tables directly. - * - * Based on the table parser from webuni/commonmark-table-extension. - */ -class CensusTableParser implements BlockParserInterface -{ - // Keywords used to create the webtrees 1.x census-assistant notes. - private const CA_PREFIX = '.start_formatted_area.'; - private const CA_SUFFIX = '.end_formatted_area.'; - private const TH_PREFIX = '.b.'; - - /** - * Parse a paragraph of text with the following structure: - * - * .start_formatted_area. - * .b.HEADING1|.b.HEADING2|.b.HEADING3 - * COL1|COL2|COL3 - * COL1|COL2|COL3 - * .end_formatted_area. - * - * @param ContextInterface $context - * @param Cursor $cursor - * - * @return bool - */ - public function parse(ContextInterface $context, Cursor $cursor): bool - { - $container = $context->getContainer(); - - if (!$container instanceof Paragraph) { - return false; - } - - $lines = $container->getStrings(); - $first = array_shift($lines); - - if ($first !== self::CA_PREFIX) { - return false; - } - - if ($cursor->getLine() !== self::CA_SUFFIX) { - return false; - } - - // We don't need to parse/markup any of the table's contents. - $table = new Table(static function (): bool { - return false; - }); - - // First line is the table header. - $line = array_shift($lines); - $row = $this->parseRow($line, TableCell::TYPE_HEAD); - $table->getHead()->appendChild($row); - - // Subsequent lines are the table body. - while ($lines !== []) { - $line = array_shift($lines); - $row = $this->parseRow($line, TableCell::TYPE_BODY); - $table->getBody()->appendChild($row); - } - - $context->replaceContainerBlock($table); - - return true; - } - - /** - * @param string $line - * @param string $type - * - * @return TableRow - */ - private function parseRow(string $line, string $type): TableRow - { - $cells = explode('|', $line); - $row = new TableRow(); - - foreach ($cells as $cell) { - if (str_starts_with($cell, self::TH_PREFIX)) { - $cell = substr($cell, strlen(self::TH_PREFIX)); - $type = TableCell::TYPE_HEAD; - } - - $row->appendChild(new TableCell($cell, $type, null)); - } - - return $row; - } -} diff --git a/app/CommonMark/CensusTableStartParser.php b/app/CommonMark/CensusTableStartParser.php new file mode 100644 index 0000000000..5b5c3a3467 --- /dev/null +++ b/app/CommonMark/CensusTableStartParser.php @@ -0,0 +1,48 @@ +<?php + +/** + * webtrees: online genealogy + * Copyright (C) 2021 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +declare(strict_types=1); + +namespace Fisharebest\Webtrees\CommonMark; + +use League\CommonMark\Parser\Block\BlockStart; +use League\CommonMark\Parser\Block\BlockStartParserInterface; +use League\CommonMark\Parser\Cursor; +use League\CommonMark\Parser\MarkdownParserStateInterface; + +/** + * Convert webtrees 1.x census-assistant markup into tables. + * Note that webtrees 2.0 generates markdown tables directly. + */ +class CensusTableStartParser implements BlockStartParserInterface +{ + /** + * @param Cursor $cursor + * @param MarkdownParserStateInterface $parserState + * + * @return BlockStart|null + */ + public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart + { + if ($cursor->getLine() === CensusTableExtension::CA_PREFIX) { + return BlockStart::of(new CensusTableContinueParser()) + ->at($cursor); + } + + return BlockStart::none(); + } +} diff --git a/app/CommonMark/ResponsiveTableExtension.php b/app/CommonMark/ResponsiveTableExtension.php deleted file mode 100644 index 88ce3301ec..0000000000 --- a/app/CommonMark/ResponsiveTableExtension.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -/** - * webtrees: online genealogy - * Copyright (C) 2021 webtrees development team - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -declare(strict_types=1); - -namespace Fisharebest\Webtrees\CommonMark; - -use League\CommonMark\ConfigurableEnvironmentInterface; -use League\CommonMark\Extension\ExtensionInterface; -use League\CommonMark\Extension\Table\Table; -use League\CommonMark\Extension\Table\TableCell; -use League\CommonMark\Extension\Table\TableCellRenderer; -use League\CommonMark\Extension\Table\TableParser; -use League\CommonMark\Extension\Table\TableRow; -use League\CommonMark\Extension\Table\TableRowRenderer; -use League\CommonMark\Extension\Table\TableSection; -use League\CommonMark\Extension\Table\TableSectionRenderer; - -/** - * Class ResponsiveTableExtension - wrap markdown tables in a responsive DIV element. - */ -class ResponsiveTableExtension implements ExtensionInterface -{ - /** - * @param ConfigurableEnvironmentInterface $environment - */ - public function register(ConfigurableEnvironmentInterface $environment): void - { - $environment - ->addBlockParser(new TableParser()) - ->addBlockRenderer(Table::class, new ResponsiveTableRenderer()) - ->addBlockRenderer(TableSection::class, new TableSectionRenderer()) - ->addBlockRenderer(TableRow::class, new TableRowRenderer()) - ->addBlockRenderer(TableCell::class, new TableCellRenderer()); - } -} diff --git a/app/CommonMark/ResponsiveTableRenderer.php b/app/CommonMark/ResponsiveTableRenderer.php deleted file mode 100644 index d69c6326d2..0000000000 --- a/app/CommonMark/ResponsiveTableRenderer.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php - -/** - * webtrees: online genealogy - * Copyright (C) 2021 webtrees development team - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -declare(strict_types=1); - -namespace Fisharebest\Webtrees\CommonMark; - -use League\CommonMark\Block\Element\AbstractBlock; -use League\CommonMark\Block\Renderer\BlockRendererInterface; -use League\CommonMark\ElementRendererInterface; -use League\CommonMark\Extension\Table\TableRenderer; -use League\CommonMark\HtmlElement; - -/** - * Class ResponsiveTableRenderer - wrap markdown tables in a responsive DIV element. - */ -class ResponsiveTableRenderer implements BlockRendererInterface -{ - // A table is made responsive by wrapping it in a DIV element. - private const WRAP_ELEMENT = 'div'; - private const WRAP_ATTRIBUTES = ['class' => 'table-responsive']; - - private TableRenderer $table_renderer; - - /** - * ResponsiveTableRenderer constructor. - */ - public function __construct() - { - $this->table_renderer = new TableRenderer(); - } - - /** - * @param AbstractBlock $block - * @param ElementRendererInterface $htmlRenderer - * @param bool $inTightList - * - * @return HtmlElement - */ - public function render( - AbstractBlock $block, - ElementRendererInterface $htmlRenderer, - bool $inTightList = false - ): HtmlElement { - $table_element = $this->table_renderer->render($block, $htmlRenderer, $inTightList); - - return new HtmlElement(self::WRAP_ELEMENT, self::WRAP_ATTRIBUTES, $table_element); - } -} diff --git a/app/CommonMark/XrefExtension.php b/app/CommonMark/XrefExtension.php index 0d0ecfc574..1826f00fdf 100644 --- a/app/CommonMark/XrefExtension.php +++ b/app/CommonMark/XrefExtension.php @@ -20,7 +20,7 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\CommonMark; use Fisharebest\Webtrees\Tree; -use League\CommonMark\ConfigurableEnvironmentInterface; +use League\CommonMark\Environment\EnvironmentBuilderInterface; use League\CommonMark\Extension\ExtensionInterface; /** @@ -40,10 +40,13 @@ class XrefExtension implements ExtensionInterface $this->tree = $tree; } - public function register(ConfigurableEnvironmentInterface $environment): void + /** + * @param EnvironmentBuilderInterface $environment + */ + public function register(EnvironmentBuilderInterface $environment): void { $environment ->addInlineParser(new XrefParser($this->tree)) - ->addInlineRenderer(XrefNode::class, new XrefRenderer()); + ->addRenderer(XrefNode::class, new XrefRenderer); } } diff --git a/app/CommonMark/XrefNode.php b/app/CommonMark/XrefNode.php index b154c62053..76b3d20742 100644 --- a/app/CommonMark/XrefNode.php +++ b/app/CommonMark/XrefNode.php @@ -20,12 +20,13 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\CommonMark; use Fisharebest\Webtrees\GedcomRecord; -use League\CommonMark\Inline\Element\AbstractStringContainer; +use League\CommonMark\Node\Node; +use League\CommonMark\Renderer\NodeRendererInterface; /** * Convert XREFs within markdown text to links */ -class XrefNode extends AbstractStringContainer +class XrefNode extends Node { private GedcomRecord $record; @@ -41,6 +42,9 @@ class XrefNode extends AbstractStringContainer $this->record = $record; } + /** + * @return GedcomRecord + */ public function record(): GedcomRecord { return $this->record; diff --git a/app/CommonMark/XrefParser.php b/app/CommonMark/XrefParser.php index ec1b25aa4a..e0be315bc5 100644 --- a/app/CommonMark/XrefParser.php +++ b/app/CommonMark/XrefParser.php @@ -23,11 +23,9 @@ 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; +use League\CommonMark\Parser\Inline\InlineParserInterface; +use League\CommonMark\Parser\Inline\InlineParserMatch; +use League\CommonMark\Parser\InlineParserContext; /** * Convert XREFs within markdown text to links @@ -49,11 +47,11 @@ class XrefParser implements InlineParserInterface /** * We are only interested in text that begins with '@'. * - * @return array<string> + * @return InlineParserMatch */ - public function getCharacters(): array + public function getMatchDefinition(): InlineParserMatch { - return ['@']; + return InlineParserMatch::regex('@(' . Gedcom::REGEX_XREF . ')@'); } /** @@ -63,28 +61,18 @@ class XrefParser implements InlineParserInterface */ public function parse(InlineParserContext $inlineContext): bool { - // The cursor should be positioned on the opening '@'. $cursor = $inlineContext->getCursor(); + [$xref] = $inlineContext->getSubMatches(); + $record = Registry::gedcomRecordFactory()->make($xref, $this->tree); - // 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 ($record instanceof GedcomRecord) { + $cursor->advanceBy($inlineContext->getFullMatchLength()); - if (is_string($xref)) { - $xref = trim($xref, '@'); - $record = Registry::gedcomRecordFactory()->make($xref, $this->tree); + $inlineContext->getContainer()->appendChild(new XrefNode($record)); - if ($record instanceof GedcomRecord) { - $inlineContext->getContainer()->appendChild(new XrefNode($record)); - - return true; - } + return true; } - // Not an XREF? Linked record does not exist? - $cursor->restoreState($previous_state); - return false; } } diff --git a/app/CommonMark/XrefRenderer.php b/app/CommonMark/XrefRenderer.php index f57db0f482..bdead6e4b3 100644 --- a/app/CommonMark/XrefRenderer.php +++ b/app/CommonMark/XrefRenderer.php @@ -19,27 +19,31 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\CommonMark; -use League\CommonMark\ElementRendererInterface; -use League\CommonMark\Inline\Element\AbstractInline; -use League\CommonMark\Inline\Renderer\InlineRendererInterface; - -use function e; +use League\CommonMark\Node\Node; +use League\CommonMark\Renderer\ChildNodeRendererInterface; +use League\CommonMark\Renderer\NodeRendererInterface; +use League\CommonMark\Util\HtmlElement; +use Stringable; /** * Convert XREFs within markdown text to links */ -class XrefRenderer implements InlineRendererInterface +class XrefRenderer implements NodeRendererInterface { /** - * @param AbstractInline $inline - * @param ElementRendererInterface $htmlRenderer + * @param Node $node + * @param ChildNodeRendererInterface $childRenderer * - * @return string + * @return Stringable */ - public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer): string + public function render(Node $node, ChildNodeRendererInterface $childRenderer): Stringable { - assert($inline instanceof XrefNode); + XrefNode::assertInstanceOf($node); + + /** @var XrefNode $node */ + $href = $node->record()->url(); + $html = $node->record()->fullName(); - return '<a href="' . e($inline->record()->url()) . '">' . $inline->record()->fullName() . '</a>'; + return new HtmlElement('a', ['href' => $href], $html); } } diff --git a/app/Contracts/MarkdownFactoryInterface.php b/app/Contracts/MarkdownFactoryInterface.php index 9b8c3152fd..e239ae8df6 100644 --- a/app/Contracts/MarkdownFactoryInterface.php +++ b/app/Contracts/MarkdownFactoryInterface.php @@ -20,7 +20,6 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\Contracts; use Fisharebest\Webtrees\Tree; -use League\CommonMark\CommonMarkConverter; /** * Create a markdown converter. @@ -28,16 +27,18 @@ use League\CommonMark\CommonMarkConverter; interface MarkdownFactoryInterface { /** + * @param string $markdown * @param Tree|null $tree * - * @return CommonMarkConverter + * @return string */ - public function autolink(Tree $tree = null): CommonMarkConverter; + public function autolink(string $markdown, Tree $tree = null): string; /** + * @param string $markdown * @param Tree|null $tree * - * @return CommonMarkConverter + * @return string */ - public function markdown(Tree $tree = null): CommonMarkConverter; + public function markdown(string $markdown, Tree $tree = null): string; } diff --git a/app/Elements/AbstractElement.php b/app/Elements/AbstractElement.php index 099bb7bc46..9753353fe9 100644 --- a/app/Elements/AbstractElement.php +++ b/app/Elements/AbstractElement.php @@ -323,7 +323,7 @@ abstract class AbstractElement implements ElementInterface $canonical = $this->canonical($value); if (str_contains($canonical, 'http://') || str_contains($canonical, 'https://')) { - $html = Registry::markdownFactory()->autolink()->convertToHtml($canonical); + $html = Registry::markdownFactory()->autolink($canonical); return strip_tags($html, ['a']); } @@ -347,12 +347,12 @@ abstract class AbstractElement implements ElementInterface switch ($format) { case 'markdown': - $html = Registry::markdownFactory()->markdown($tree)->convertToHtml($canonical); + $html = Registry::markdownFactory()->markdown($canonical, $tree); return '<div class="markdown" dir="auto">' . $html . '</div>'; default: - $html = Registry::markdownFactory()->autolink($tree)->convertToHtml($canonical); + $html = Registry::markdownFactory()->autolink($canonical, $tree); if (str_contains($html, "\n")) { return '<div class="markdown" dir="auto">' . $html . '</div>'; diff --git a/app/Factories/MarkdownFactory.php b/app/Factories/MarkdownFactory.php index 96c6a05691..cfad2e0d1f 100644 --- a/app/Factories/MarkdownFactory.php +++ b/app/Factories/MarkdownFactory.php @@ -20,46 +20,62 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\Factories; use Fisharebest\Webtrees\CommonMark\CensusTableExtension; -use Fisharebest\Webtrees\CommonMark\ResponsiveTableExtension; use Fisharebest\Webtrees\CommonMark\XrefExtension; use Fisharebest\Webtrees\Contracts\MarkdownFactoryInterface; use Fisharebest\Webtrees\Tree; -use League\CommonMark\Block\Element\Document; -use League\CommonMark\Block\Element\Paragraph; -use League\CommonMark\Block\Renderer\DocumentRenderer; -use League\CommonMark\Block\Renderer\ParagraphRenderer; -use League\CommonMark\CommonMarkConverter; -use League\CommonMark\Environment; -use League\CommonMark\EnvironmentInterface; +use League\CommonMark\Environment\Environment; use League\CommonMark\Extension\Autolink\AutolinkExtension; -use League\CommonMark\Inline\Element\Link; -use League\CommonMark\Inline\Element\Text; -use League\CommonMark\Inline\Renderer\LinkRenderer; -use League\CommonMark\Inline\Renderer\TextRenderer; +use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; +use League\CommonMark\Extension\CommonMark\Node\Inline\Link; +use League\CommonMark\Extension\CommonMark\Renderer\Inline\LinkRenderer; +use League\CommonMark\Extension\Table\TableExtension; +use League\CommonMark\MarkdownConverter; +use League\CommonMark\Node\Block\Document; +use League\CommonMark\Node\Block\Paragraph; +use League\CommonMark\Node\Inline\Text; +use League\CommonMark\Renderer\Block\DocumentRenderer; +use League\CommonMark\Renderer\Block\ParagraphRenderer; +use League\CommonMark\Renderer\Inline\TextRenderer; +use League\CommonMark\Util\HtmlFilter; /** * Create a markdown converter. */ class MarkdownFactory implements MarkdownFactoryInterface { - protected const CONFIG = [ + protected const CONFIG_AUTOLINK = [ 'allow_unsafe_links' => false, - 'html_input' => EnvironmentInterface::HTML_INPUT_ESCAPE, + 'html_input' => HtmlFilter::ESCAPE, + ]; + + protected const CONFIG_MARKDOWN = [ + 'allow_unsafe_links' => false, + 'html_input' => HtmlFilter::ESCAPE, + 'table' => [ + 'wrap' => [ + 'enabled' => true, + 'tag' => 'div', + 'attributes' => [ + 'class' => 'table-responsive', + ], + ], + ], ]; /** + * @param string $markdown * @param Tree|null $tree * - * @return CommonMarkConverter + * @return string */ - public function autolink(Tree $tree = null): CommonMarkConverter + public function autolink(string $markdown, Tree $tree = null): string { // Create a minimal commonmark processor - just add support for auto-links. - $environment = new Environment(); - $environment->addBlockRenderer(Document::class, new DocumentRenderer()); - $environment->addBlockRenderer(Paragraph::class, new ParagraphRenderer()); - $environment->addInlineRenderer(Text::class, new TextRenderer()); - $environment->addInlineRenderer(Link::class, new LinkRenderer()); + $environment = new Environment(static::CONFIG_AUTOLINK); + $environment->addRenderer(Document::class, new DocumentRenderer()); + $environment->addRenderer(Paragraph::class, new ParagraphRenderer()); + $environment->addRenderer(Text::class, new TextRenderer()); + $environment->addRenderer(Link::class, new LinkRenderer()); $environment->addExtension(new AutolinkExtension()); // Optionally create links to other records. @@ -67,29 +83,33 @@ class MarkdownFactory implements MarkdownFactoryInterface $environment->addExtension(new XrefExtension($tree)); } - return new CommonMarkConverter(static::CONFIG, $environment); + $converter = new MarkDownConverter($environment); + + return $converter->convert($markdown)->getContent(); } /** + * @param string $markdown * @param Tree|null $tree * - * @return CommonMarkConverter + * @return string */ - public function markdown(Tree $tree = null): CommonMarkConverter + public function markdown(string $markdown, Tree $tree = null): string { - $environment = Environment::createCommonMarkEnvironment(); - - // Wrap tables so support horizontal scrolling with bootstrap. - $environment->addExtension(new ResponsiveTableExtension()); + $environment = new Environment(static::CONFIG_MARKDOWN); + $environment->addExtension(new CommonMarkCoreExtension()); + $environment->addExtension(new TableExtension()); // Convert webtrees 1.x style census tables to commonmark format. - $environment->addExtension(new CensusTableExtension()); + $environment->addExtension(new CensusTableExtension(new TableExtension())); // Optionally create links to other records. if ($tree instanceof Tree) { $environment->addExtension(new XrefExtension($tree)); } - return new CommonMarkConverter(static::CONFIG, $environment); + $converter = new MarkDownConverter($environment); + + return $converter->convert($markdown)->getContent(); } } diff --git a/app/Functions/FunctionsPrint.php b/app/Functions/FunctionsPrint.php index b87ebb186e..be56b857b3 100644 --- a/app/Functions/FunctionsPrint.php +++ b/app/Functions/FunctionsPrint.php @@ -107,7 +107,7 @@ class FunctionsPrint I18N::translate( '<span class="label">%1$s:</span> <span class="field" dir="auto">%2$s</span>', $label, - $first_line + $html ) . '</div>'; } diff --git a/app/Functions/FunctionsPrintFacts.php b/app/Functions/FunctionsPrintFacts.php index fd24835fbf..ca985978ea 100644 --- a/app/Functions/FunctionsPrintFacts.php +++ b/app/Functions/FunctionsPrintFacts.php @@ -438,11 +438,11 @@ class FunctionsPrintFacts if ($tree->getPreference('FORMAT_TEXT') === 'markdown') { $data .= '<div class="markdown" dir="auto">'; - $data .= Registry::markdownFactory()->markdown($tree)->convertToHtml($source); + $data .= Registry::markdownFactory()->markdown($source, $tree); $data .= '</div>'; } else { $data .= '<div class="markdown" dir="auto" style="white-space: pre-wrap;">'; - $data .= Registry::markdownFactory()->autolink($tree)->convertToHtml($source); + $data .= Registry::markdownFactory()->autolink($source, $tree); $data .= '</div>'; } diff --git a/app/Note.php b/app/Note.php index 8016dee960..d09b9c2164 100644 --- a/app/Note.php +++ b/app/Note.php @@ -90,9 +90,9 @@ class Note extends GedcomRecord public function extractNames(): void { if ($this->tree->getPreference('FORMAT_TEXT') === 'markdown') { - $text = Registry::markdownFactory()->markdown()->convertToHtml($this->getNote()); + $text = Registry::markdownFactory()->markdown($this->getNote()); } else { - $text = Registry::markdownFactory()->autolink()->convertToHtml($this->getNote()); + $text = Registry::markdownFactory()->autolink($this->getNote()); } diff --git a/app/Report/ReportParserGenerate.php b/app/Report/ReportParserGenerate.php index b8c13d6490..e7a5a23864 100644 --- a/app/Report/ReportParserGenerate.php +++ b/app/Report/ReportParserGenerate.php @@ -1005,9 +1005,9 @@ class ReportParserGenerate extends ReportParserBase $tmp = explode(':', $tag); if (in_array(end($tmp), ['NOTE', 'TEXT'], true)) { if ($this->tree->getPreference('FORMAT_TEXT') === 'markdown') { - $value = strip_tags(Registry::markdownFactory()->markdown($this->tree)->convertToHtml($value)); + $value = strip_tags(Registry::markdownFactory()->markdown($value, $this->tree)); } else { - $value = strip_tags(Registry::markdownFactory()->autolink($this->tree)->convertToHtml($value)); + $value = strip_tags(Registry::markdownFactory()->autolink($value, $this->tree)); } } diff --git a/app/Webtrees.php b/app/Webtrees.php index 34bd1aaa93..5338f795d2 100644 --- a/app/Webtrees.php +++ b/app/Webtrees.php @@ -199,7 +199,7 @@ class Webtrees Registry::xrefFactory(new XrefFactory()); // Workaround for https://github.com/fisharebest/webtrees/issues/4179 - class_alias(TranslatorInterface::class, 'Symfony\\Component\\Translation\\TranslatorInterface'); + //class_alias(TranslatorInterface::class, 'Symfony\\Component\\Translation\\TranslatorInterface'); } /** diff --git a/composer.json b/composer.json index 225602b3ef..a570a848d1 100644 --- a/composer.json +++ b/composer.json @@ -53,12 +53,12 @@ "fisharebest/flysystem-chroot-adapter": "2.0.0", "fisharebest/localization": "1.15.1", "guzzlehttp/guzzle": "7.4.1", - "illuminate/container": "8.80.0", - "illuminate/database": "8.80.0", - "illuminate/support": "8.80.0", + "illuminate/container": "8.81.0", + "illuminate/database": "8.81.0", + "illuminate/support": "8.81.0", "intervention/image": "2.7.1", "io-developer/php-whois": "4.1.6", - "league/commonmark": "1.6.0", + "league/commonmark": "2.2.1", "league/flysystem": "2.4.0", "league/flysystem-ziparchive": "2.3.1", "middlewares/client-ip": "2.0.1", diff --git a/composer.lock b/composer.lock index e01bfc95e5..5d94e2a04e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f91781982f058cca4bc5b190b15d6616", + "content-hash": "592da0e453806dcce41450fdd619d3ca", "packages": [ { "name": "aura/router", @@ -121,6 +121,81 @@ "time": "2021-08-15T20:50:18+00:00" }, { + "name": "dflydev/dot-access-data", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" + }, + "time": "2021-08-13T13:06:58+00:00" + }, + { "name": "doctrine/cache", "version": "2.1.1", "source": { @@ -1418,7 +1493,7 @@ }, { "name": "illuminate/container", - "version": "v8.80.0", + "version": "v8.81.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", @@ -1517,16 +1592,16 @@ }, { "name": "illuminate/database", - "version": "v8.80.0", + "version": "v8.81.0", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", - "reference": "0e6e98b163cf3bf53750f0fb0faa1b22c46d1343" + "reference": "2dab88ccaf750e3e79d51ddd0b2c94f5f11c8d77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/0e6e98b163cf3bf53750f0fb0faa1b22c46d1343", - "reference": "0e6e98b163cf3bf53750f0fb0faa1b22c46d1343", + "url": "https://api.github.com/repos/illuminate/database/zipball/2dab88ccaf750e3e79d51ddd0b2c94f5f11c8d77", + "reference": "2dab88ccaf750e3e79d51ddd0b2c94f5f11c8d77", "shasum": "" }, "require": { @@ -1581,7 +1656,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-17T19:06:15+00:00" + "time": "2022-01-22T18:51:18+00:00" }, { "name": "illuminate/macroable", @@ -1631,16 +1706,16 @@ }, { "name": "illuminate/support", - "version": "v8.80.0", + "version": "v8.81.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "69afbd89e6b6bf847e3df59e0f72cd820b18e8da" + "reference": "fb33fd4bbcc075f641d5576b700a1c3d962acef0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/69afbd89e6b6bf847e3df59e0f72cd820b18e8da", - "reference": "69afbd89e6b6bf847e3df59e0f72cd820b18e8da", + "url": "https://api.github.com/repos/illuminate/support/zipball/fb33fd4bbcc075f641d5576b700a1c3d962acef0", + "reference": "fb33fd4bbcc075f641d5576b700a1c3d962acef0", "shasum": "" }, "require": { @@ -1652,7 +1727,7 @@ "illuminate/macroable": "^8.0", "nesbot/carbon": "^2.53.1", "php": "^7.3|^8.0", - "voku/portable-ascii": "^1.4.8" + "voku/portable-ascii": "^1.6.1" }, "conflict": { "tightenco/collect": "<5.5.33" @@ -1695,7 +1770,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-17T15:24:30+00:00" + "time": "2022-01-25T16:10:28+00:00" }, { "name": "intervention/image", @@ -1845,42 +1920,52 @@ }, { "name": "league/commonmark", - "version": "1.6.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "19a9673b833cc37770439097b381d86cd125bfe8" + "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/19a9673b833cc37770439097b381d86cd125bfe8", - "reference": "19a9673b833cc37770439097b381d86cd125bfe8", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a", + "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1 || ^8.0" - }, - "conflict": { - "scrutinizer/ocular": "1.7.*" + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { - "cebe/markdown": "~1.0", - "commonmark/commonmark.js": "0.29.2", - "erusev/parsedown": "~1.0", + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "erusev/parsedown": "^1.0", "ext-json": "*", "github/gfm": "0.29.0", - "michelf/php-markdown": "~1.4", - "mikehaertl/php-shellcommand": "^1.4", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2", - "scrutinizer/ocular": "^1.5", - "symfony/finder": "^4.2" + "michelf/php-markdown": "^1.4", + "phpstan/phpstan": "^0.12.88 || ^1.0.0", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" }, - "bin": [ - "bin/commonmark" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.3-dev" + } + }, "autoload": { "psr-4": { "League\\CommonMark\\": "src" @@ -1898,7 +1983,7 @@ "role": "Lead Developer" } ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", "homepage": "https://commonmark.thephpleague.com", "keywords": [ "commonmark", @@ -1912,16 +1997,13 @@ ], "support": { "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", "issues": "https://github.com/thephpleague/commonmark/issues", "rss": "https://github.com/thephpleague/commonmark/releases.atom", "source": "https://github.com/thephpleague/commonmark" }, "funding": [ { - "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", - "type": "custom" - }, - { "url": "https://www.colinodell.com/sponsor", "type": "custom" }, @@ -1934,15 +2016,93 @@ "type": "github" }, { - "url": "https://www.patreon.com/colinodell", - "type": "patreon" - }, - { "url": "https://tidelift.com/funding/github/packagist/league/commonmark", "type": "tidelift" } ], - "time": "2021-05-01T19:00:49+00:00" + "time": "2022-01-25T14:37:33+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" }, { "name": "league/flysystem", @@ -2356,6 +2516,153 @@ "time": "2022-01-21T17:08:38+00:00" }, { + "name": "nette/schema", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.2" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.2" + }, + "time": "2021-10-15T11:40:02+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.7", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/0af4e3de4df9f1543534beab255ccf459e7a2c99", + "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.2" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.7" + }, + "time": "2022-01-24T11:29:14+00:00" + }, + { "name": "nyholm/psr7", "version": "1.4.1", "source": { diff --git a/resources/views/modules/user-messages/user-messages.phtml b/resources/views/modules/user-messages/user-messages.phtml index 2c222083ec..0084fb7cff 100644 --- a/resources/views/modules/user-messages/user-messages.phtml +++ b/resources/views/modules/user-messages/user-messages.phtml @@ -106,7 +106,7 @@ use Illuminate\Support\Collection; <td class="wt-page-options-value" colspan="4"> <div id="message<?= $message->message_id ?>" class="collapse"> <div dir="auto" style="white-space: pre-wrap;"> - <?= Registry::markdownFactory()->autolink()->convertToHtml($message->body) ?> + <?= Registry::markdownFactory()->autolink($message->body) ?> </div> <br> diff --git a/tests/app/Factories/MarkdownFactoryTest.php b/tests/app/Factories/MarkdownFactoryTest.php index 2f9af0a203..76cd4055b4 100644 --- a/tests/app/Factories/MarkdownFactoryTest.php +++ b/tests/app/Factories/MarkdownFactoryTest.php @@ -35,11 +35,10 @@ class MarkdownFactoryTest extends TestCase public function testAutoLinkWithoutTree(): void { $factory = new MarkdownFactory(); - $autolink = $factory->autolink(); $this->assertSame( "<p>FOO <a href=\"https://example.com\">https://example.com</a> BAR</p>\n", - $autolink->convertToHtml('FOO https://example.com BAR') + $factory->autolink('FOO https://example.com BAR') ); } @@ -49,14 +48,12 @@ class MarkdownFactoryTest extends TestCase */ public function testAutoLinkWithTree(): void { - $tree = $this->createStub(Tree::class); - - $factory = new MarkdownFactory(); - $autolink = $factory->autolink($tree); + $factory = new MarkdownFactory(); + $tree = $this->createStub(Tree::class); $this->assertSame( "<p>FOO <a href=\"https://example.com\">https://example.com</a> BAR</p>\n", - $autolink->convertToHtml('FOO https://example.com BAR') + $factory->autolink('FOO https://example.com BAR', $tree) ); } @@ -67,11 +64,10 @@ class MarkdownFactoryTest extends TestCase public function testAutoLinkWithHtml(): void { $factory = new MarkdownFactory(); - $autolink = $factory->autolink(); $this->assertSame( "<p><b> <a href=\"https://example.com\">https://example.com</a> </b></p>\n", - $autolink->convertToHtml('<b> https://example.com </b>') + $factory->autolink('<b> https://example.com </b>') ); } @@ -80,17 +76,16 @@ class MarkdownFactoryTest extends TestCase */ public function testMarkdownWithoutTree(): void { - $factory = new MarkdownFactory(); - $Markdown = $factory->Markdown(); + $factory = new MarkdownFactory(); $this->assertSame( "<p>FOO https://example.com BAR</p>\n", - $Markdown->convertToHtml('FOO https://example.com BAR') + $factory->markdown('FOO https://example.com BAR') ); $this->assertSame( "<p>FOO <a href=\"https://example.com\">https://example.com</a> BAR</p>\n", - $Markdown->convertToHtml('FOO <https://example.com> BAR') + $factory->markdown('FOO <https://example.com> BAR') ); } @@ -100,19 +95,17 @@ class MarkdownFactoryTest extends TestCase */ public function testMarkdownWithTree(): void { - $tree = $this->createStub(Tree::class); - - $factory = new MarkdownFactory(); - $Markdown = $factory->Markdown($tree); + $tree = $this->createStub(Tree::class); + $factory = new MarkdownFactory(); $this->assertSame( "<p>FOO https://example.com BAR</p>\n", - $Markdown->convertToHtml('FOO https://example.com BAR') + $factory->markdown('FOO https://example.com BAR', $tree) ); $this->assertSame( "<p>FOO <a href=\"https://example.com\">https://example.com</a> BAR</p>\n", - $Markdown->convertToHtml('FOO <https://example.com> BAR') + $factory->markdown('FOO <https://example.com> BAR', $tree) ); } @@ -122,12 +115,11 @@ class MarkdownFactoryTest extends TestCase */ public function testMarkdownWithHtml(): void { - $factory = new MarkdownFactory(); - $markdown = $factory->Markdown(); + $factory = new MarkdownFactory(); $this->assertSame( "<p><b> <a href=\"https://example.com\">https://example.com</a> </b></p>\n", - $markdown->convertToHtml('<b> <https://example.com> </b>') + $factory->markdown('<b> <https://example.com> </b>') ); } } |
