$template,
'html' => << Great!\s* Great!\s* Great!\s*]*>Hello
\n+
Paragraph 2\s*
"], ]; } #[DataProvider('getIndentationTests')] public function testStripsCommonIndentation(string $body, string $expected): void { $runtime = new MarkdownRuntime(new class implements MarkdownInterface { public function convert(string $body): string { return $body; } }); $this->assertSame($expected, $runtime->convert($body)); } public static function getIndentationTests() { return [ 'leading blank line keeps blank lines' => ["\nParagraph 1\n\nParagraph 2", "\nParagraph 1\n\nParagraph 2"], 'common indentation is removed' => ["\n Hello\n =====\n\n Great!\n", "\nHello\n=====\n\nGreat!\n"], 'minimal common indentation is removed' => [" a\n b\n", "a\n b\n"], 'indented code block before non-indented prose is preserved' => [" Code\n\nParagraph\n", " Code\n\nParagraph\n"], 'tab indentation is removed' => ["\tHello\n\tGreat!\n", "Hello\nGreat!\n"], 'mixed tabs and spaces are left untouched' => ["\ta\n b\n", "\ta\n b\n"], 'blank lines are ignored when computing indentation' => [" a\n\n b\n", "a\n\nb\n"], ]; } public function testMarkdownToHtmlIsNotSafeInJsContext(): void { $twig = new Environment(new ArrayLoader([ 'index' => "{% autoescape 'js' %}{{ '# Hello'|markdown_to_html }}{% endautoescape %}", ])); $twig->addExtension(new MarkdownExtension()); $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface { public function load(string $c): ?object { return MarkdownRuntime::class === $c ? new $c(new DefaultMarkdown()) : null; } }); $output = $twig->render('index'); $this->assertStringNotContainsString('