From 82c981657d3a43cd006a96450fd69909d1f5ee02 Mon Sep 17 00:00:00 2001 From: Aidan Woods Date: Tue, 22 Jan 2019 19:06:26 +0000 Subject: [PATCH] Require Inlines to provide a best plaintext rendering This allows markdown to be parsed "inside" the alt attribute of an image, and then the best plaintext can be used as the rest. This improves CommonMark compliance. --- src/Components/Inline.php | 6 ++++++ src/Components/Inlines/Code.php | 8 +++++++ src/Components/Inlines/Email.php | 8 +++++++ src/Components/Inlines/Emphasis.php | 8 +++++++ src/Components/Inlines/EscapeSequence.php | 9 ++++++++ src/Components/Inlines/Image.php | 23 ++++++++++++++++++++- src/Components/Inlines/Link.php | 8 +++++++ src/Components/Inlines/Markup.php | 8 +++++++ src/Components/Inlines/PlainText.php | 8 +++++++ src/Components/Inlines/SpecialCharacter.php | 8 +++++++ src/Components/Inlines/Strikethrough.php | 8 +++++++ src/Components/Inlines/Url.php | 8 +++++++ src/Components/Inlines/UrlTag.php | 8 +++++++ 13 files changed, 117 insertions(+), 1 deletion(-) diff --git a/src/Components/Inline.php b/src/Components/Inline.php index 337d3ed..3ee4d08 100644 --- a/src/Components/Inline.php +++ b/src/Components/Inline.php @@ -3,6 +3,7 @@ namespace Erusev\Parsedown\Components; use Erusev\Parsedown\Component; +use Erusev\Parsedown\Html\Renderables\Text; use Erusev\Parsedown\Parsing\Excerpt; use Erusev\Parsedown\State; @@ -28,4 +29,9 @@ interface Inline extends Component * @return int|null * */ public function modifyStartPositionTo(); + + /** + * @return Text + */ + public function bestPlaintext(); } diff --git a/src/Components/Inlines/Code.php b/src/Components/Inlines/Code.php index cde7f43..b559c4a 100644 --- a/src/Components/Inlines/Code.php +++ b/src/Components/Inlines/Code.php @@ -58,4 +58,12 @@ final class Code implements Inline { return new Element('code', [], [new Text($this->text)]); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->text); + } } diff --git a/src/Components/Inlines/Email.php b/src/Components/Inlines/Email.php index c012ab8..136e478 100644 --- a/src/Components/Inlines/Email.php +++ b/src/Components/Inlines/Email.php @@ -64,4 +64,12 @@ final class Email implements Inline { return new Element('a', ['href' => $this->url], [new Text($this->text)]); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->text); + } } diff --git a/src/Components/Inlines/Emphasis.php b/src/Components/Inlines/Emphasis.php index 156de1a..2b65321 100644 --- a/src/Components/Inlines/Emphasis.php +++ b/src/Components/Inlines/Emphasis.php @@ -85,4 +85,12 @@ final class Emphasis implements Inline } ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->text); + } } diff --git a/src/Components/Inlines/EscapeSequence.php b/src/Components/Inlines/EscapeSequence.php index dbf55f6..521680d 100644 --- a/src/Components/Inlines/EscapeSequence.php +++ b/src/Components/Inlines/EscapeSequence.php @@ -5,6 +5,7 @@ namespace Erusev\Parsedown\Components\Inlines; use Erusev\Parsedown\AST\StateRenderable; use Erusev\Parsedown\Components\Inline; use Erusev\Parsedown\Html\Renderables\RawHtml; +use Erusev\Parsedown\Html\Renderables\Text; use Erusev\Parsedown\Parsedown; use Erusev\Parsedown\Parsing\Excerpt; use Erusev\Parsedown\State; @@ -48,4 +49,12 @@ final class EscapeSequence implements Inline { return new RawHtml($this->html); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->html); + } } diff --git a/src/Components/Inlines/Image.php b/src/Components/Inlines/Image.php index e6198f1..f20f4d3 100644 --- a/src/Components/Inlines/Image.php +++ b/src/Components/Inlines/Image.php @@ -61,7 +61,20 @@ final class Image implements Inline function (State $State) use ($Parsedown) { $attributes = [ 'src' => $this->Link->url(), - 'alt' => $this->Link->label(), + 'alt' => \array_reduce( + $Parsedown->inlines($this->Link->label()), + /** + * @param string $text + * @return string + */ + function ($text, Inline $Inline) { + return ( + $text + . $Inline->bestPlaintext()->getStringBacking() + ); + }, + '' + ), ]; $title = $this->Link->title(); @@ -78,4 +91,12 @@ final class Image implements Inline } ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->Link->label()); + } } diff --git a/src/Components/Inlines/Link.php b/src/Components/Inlines/Link.php index fc756b9..0a948ca 100644 --- a/src/Components/Inlines/Link.php +++ b/src/Components/Inlines/Link.php @@ -134,4 +134,12 @@ final class Link implements Inline } ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->label); + } } diff --git a/src/Components/Inlines/Markup.php b/src/Components/Inlines/Markup.php index 6b82da3..e94c07e 100644 --- a/src/Components/Inlines/Markup.php +++ b/src/Components/Inlines/Markup.php @@ -74,4 +74,12 @@ final class Markup implements Inline } ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->html); + } } diff --git a/src/Components/Inlines/PlainText.php b/src/Components/Inlines/PlainText.php index 5bb592d..60a350a 100644 --- a/src/Components/Inlines/PlainText.php +++ b/src/Components/Inlines/PlainText.php @@ -72,4 +72,12 @@ final class PlainText implements Inline } ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->text); + } } diff --git a/src/Components/Inlines/SpecialCharacter.php b/src/Components/Inlines/SpecialCharacter.php index f53faab..714acae 100644 --- a/src/Components/Inlines/SpecialCharacter.php +++ b/src/Components/Inlines/SpecialCharacter.php @@ -51,4 +51,12 @@ final class SpecialCharacter implements Inline '&' . (new Text($this->charCodeHtml))->getHtml() . ';' ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text('&'.$this->charCodeHtml.';'); + } } diff --git a/src/Components/Inlines/Strikethrough.php b/src/Components/Inlines/Strikethrough.php index bcea2fd..8cf4f8a 100644 --- a/src/Components/Inlines/Strikethrough.php +++ b/src/Components/Inlines/Strikethrough.php @@ -64,4 +64,12 @@ final class Strikethrough implements Inline } ); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->text); + } } diff --git a/src/Components/Inlines/Url.php b/src/Components/Inlines/Url.php index bc02191..754401b 100644 --- a/src/Components/Inlines/Url.php +++ b/src/Components/Inlines/Url.php @@ -71,4 +71,12 @@ final class Url implements Inline { return new Element('a', ['href' => $this->url], [new Text($this->url)]); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->url); + } } diff --git a/src/Components/Inlines/UrlTag.php b/src/Components/Inlines/UrlTag.php index ac57d4c..d6dc05f 100644 --- a/src/Components/Inlines/UrlTag.php +++ b/src/Components/Inlines/UrlTag.php @@ -48,4 +48,12 @@ final class UrlTag implements Inline { return new Element('a', ['href' => $this->url], [new Text($this->url)]); } + + /** + * @return Text + */ + public function bestPlaintext() + { + return new Text($this->url); + } }