From f610f68c53bb74be3ebe268fea29a6abac7d243d Mon Sep 17 00:00:00 2001 From: Alex Fence Date: Tue, 26 Feb 2019 11:41:37 +0100 Subject: [PATCH 01/15] fix bold + color rendering --- Tests/Combined/Html/BoldColorTest.php | 29 +++++++++++++++++++++++++++ src/Delta/Html/Compound.php | 6 +++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 Tests/Combined/Html/BoldColorTest.php diff --git a/Tests/Combined/Html/BoldColorTest.php b/Tests/Combined/Html/BoldColorTest.php new file mode 100644 index 0000000..8b3e010 --- /dev/null +++ b/Tests/Combined/Html/BoldColorTest.php @@ -0,0 +1,29 @@ +My Text

'; + + public function testBoldColor() + { + $result = null; + + try { + $quill = new QuillRender($this->delta_bold_text); + $result = $quill->render(); + } catch (\Exception $e) { + $this->fail(__METHOD__ . 'failure, ' . $e->getMessage()); + } + + $this->assertEquals($this->expected_href, trim($result), __METHOD__ . ' BoldColorText'); + } +} + diff --git a/src/Delta/Html/Compound.php b/src/Delta/Html/Compound.php index fe368a6..3f91e1a 100644 --- a/src/Delta/Html/Compound.php +++ b/src/Delta/Html/Compound.php @@ -104,7 +104,11 @@ public function render(): string $element_attributes = ''; foreach ($this->element_attributes as $attribute => $value) { - $element_attributes .= "{$attribute}=\"{$value}\" "; + if ($attribute == "color") { + $element_attributes .= "style=\"{$attribute}: $value\""; + } else { + $element_attributes .= "{$attribute}=\"{$value}\" "; + } } foreach ($this->tags as $i => $tag) { From 4bf18d58159dd14b1a89c4136d89e6da6a2f602c Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 2 Mar 2019 23:45:01 +0000 Subject: [PATCH 02/15] CHANGELOG * Updated changelog, placeholder --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2df90..6618f86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Full changelog for PHP Quill Renderer +## v3.17.0 - 2019-03-xx + + + ## v3.16.0 - 2019-02-28 * Reworked the parser, split deltas much sooner to try and simplify some of the later logic. From a8bf8348be02f97053ff0f432f1077dd7a0e82f5 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 2 Mar 2019 23:46:58 +0000 Subject: [PATCH 03/15] Removed ParserSplitInterface * Removed ParserSplitInterface --- src/Interfaces/ParserSplitInterface.php | 32 ------------------------- src/Parser/Html.php | 3 +-- 2 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 src/Interfaces/ParserSplitInterface.php diff --git a/src/Interfaces/ParserSplitInterface.php b/src/Interfaces/ParserSplitInterface.php deleted file mode 100644 index 915e5c9..0000000 --- a/src/Interfaces/ParserSplitInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright Dean Blackborough - * @license https://github.com/deanblackborough/php-quill-renderer/blob/master/LICENSE - */ -interface ParserSplitInterface -{ - /** - * Split an insert on multiple new lines and handle accordingly - * - * @param string $insert An insert string - * - * @return array array of inserts, two indexes, insert and close - */ - public function splitInsertsOnNewLines($insert): array; - - /** - * Split an insert on a single new line and handle accordingly - * - * @param string $insert An insert string - * - * @return array array of inserts, three indexes, insert, close and new_line - */ - public function splitInsertsOnNewLine($insert): array; -} diff --git a/src/Parser/Html.php b/src/Parser/Html.php index 5e3892b..facfc4d 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -20,7 +20,6 @@ use DBlackborough\Quill\Delta\Html\Underline; use DBlackborough\Quill\Delta\Html\Video; use DBlackborough\Quill\Interfaces\ParserAttributeInterface; -use DBlackborough\Quill\Interfaces\ParserSplitInterface; use DBlackborough\Quill\Options; /** @@ -32,7 +31,7 @@ * @copyright Dean Blackborough * @license https://github.com/deanblackborough/php-quill-renderer/blob/master/LICENSE */ -class Html extends Parse implements ParserSplitInterface, ParserAttributeInterface +class Html extends Parse implements ParserAttributeInterface { /** * Deltas array after parsing, array of Delta objects From 032a44fc0b85706e5b9e5cdcd74bec86837deef9 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sat, 2 Mar 2019 23:54:50 +0000 Subject: [PATCH 04/15] Interface usage change * Parse now implements the attributes interface --- src/Parser/Html.php | 3 +-- src/Parser/Markdown.php | 3 +-- src/Parser/Parse.php | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Parser/Html.php b/src/Parser/Html.php index facfc4d..8ba41dc 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -19,7 +19,6 @@ use DBlackborough\Quill\Delta\Html\SuperScript; use DBlackborough\Quill\Delta\Html\Underline; use DBlackborough\Quill\Delta\Html\Video; -use DBlackborough\Quill\Interfaces\ParserAttributeInterface; use DBlackborough\Quill\Options; /** @@ -31,7 +30,7 @@ * @copyright Dean Blackborough * @license https://github.com/deanblackborough/php-quill-renderer/blob/master/LICENSE */ -class Html extends Parse implements ParserAttributeInterface +class Html extends Parse { /** * Deltas array after parsing, array of Delta objects diff --git a/src/Parser/Markdown.php b/src/Parser/Markdown.php index 483f14c..f88512a 100644 --- a/src/Parser/Markdown.php +++ b/src/Parser/Markdown.php @@ -13,7 +13,6 @@ use DBlackborough\Quill\Delta\Markdown\Link; use DBlackborough\Quill\Delta\Markdown\ListItem; use DBlackborough\Quill\Delta\Markdown\Video; -use DBlackborough\Quill\Interfaces\ParserAttributeInterface; use DBlackborough\Quill\Options; /** @@ -24,7 +23,7 @@ * @copyright Dean Blackborough * @license https://github.com/deanblackborough/php-quill-renderer/blob/master/LICENSE */ -class Markdown extends Parse implements ParserAttributeInterface +class Markdown extends Parse { /** * Deltas array after parsing, array of Delta objects diff --git a/src/Parser/Parse.php b/src/Parser/Parse.php index 15cb8dd..9eab6fc 100644 --- a/src/Parser/Parse.php +++ b/src/Parser/Parse.php @@ -4,6 +4,7 @@ namespace DBlackborough\Quill\Parser; use DBlackborough\Quill\Delta\Delta; +use DBlackborough\Quill\Interfaces\ParserAttributeInterface; use DBlackborough\Quill\Interfaces\ParserInterface; use DBlackborough\Quill\Options; @@ -14,7 +15,7 @@ * @copyright Dean Blackborough * @license https://github.com/deanblackborough/php-quill-renderer/blob/master/LICENSE */ -abstract class Parse implements ParserInterface +abstract class Parse implements ParserInterface, ParserAttributeInterface { /** * The initial quill json string after it has been json decoded From eb88bc8be03e2d1c37ab27456cbf45aaa738492b Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 00:02:53 +0000 Subject: [PATCH 05/15] Redundant methods * Removed split methods and extended insert methods --- CHANGELOG.md | 4 +- src/Interfaces/ParserAttributeInterface.php | 10 -- src/Parser/Html.php | 146 -------------------- 3 files changed, 3 insertions(+), 157 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6618f86..628b414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ Full changelog for PHP Quill Renderer ## v3.17.0 - 2019-03-xx - +* Removed the `ParserSplitInterface` interface, no use anymore. +* Changed which class implements `ParserAttributeInterface` interface. +* Removed redundant methods from parsers. ## v3.16.0 - 2019-02-28 diff --git a/src/Interfaces/ParserAttributeInterface.php b/src/Interfaces/ParserAttributeInterface.php index 6965dfc..a77b051 100644 --- a/src/Interfaces/ParserAttributeInterface.php +++ b/src/Interfaces/ParserAttributeInterface.php @@ -102,16 +102,6 @@ public function attributeUnderline(array $quill); */ public function insert(array $quill); - /** - * Extended Quill insert, insert will need to be split before creation - * of Deltas - * - * @param array $quill - * - * @return void - */ - public function extendedInsert(array $quill); - /** * Multiple attributes set, handle accordingly * diff --git a/src/Parser/Html.php b/src/Parser/Html.php index 8ba41dc..c220aa0 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -57,124 +57,6 @@ public function __construct() $this->class_delta_video = Video::class; } - /** - * Split insert by new lines and optionally set whether or not the close() - * method needs to called on the Delta - * - * @param string $insert An insert string - * - * @return array array of inserts, two indexes, insert and close - */ - public function splitInsertsOnNewLines($insert): array - { - $inserts = []; - - if (preg_match("/[\n]{2,}/", $insert) !== 0) { - $splits = (preg_split("/[\n]{2,}/", $insert)); - $i = 0; - foreach (preg_split("/[\n]{2,}/", $insert) as $match) { - - $close = false; - - $sub_inserts = $this->splitInsertsOnNewLine($match); - - if (count($sub_inserts) > 0) { - if (count($sub_inserts) === 1) { - if ($i === 0 || $i !== count($splits) - 1) { - $close = true; - } - - $inserts[] = [ - 'insert' => $sub_inserts[0]['insert'], - 'close' => $close, - 'new_line' => false, - 'pre_new_line' => false - ]; - } else { - $count = count($sub_inserts); - $i = 0; - foreach ($sub_inserts as $sub_insert) { - $inserts[] = [ - 'insert' => $sub_insert['insert'], - 'close' => (($count - 1) === $i ? true : $sub_insert['close']), - 'new_line' => $sub_insert['new_line'], - 'pre_new_line' => $sub_insert['pre_new_line'] - ]; - $i++; - } - } - } - - $i++; - } - } else { - $sub_inserts = $this->splitInsertsOnNewLine($insert); - foreach ($sub_inserts as $sub_insert) { - $inserts[] = [ - 'insert' => $sub_insert['insert'], - 'close' => $sub_insert['close'], - 'new_line' => $sub_insert['new_line'], - 'pre_new_line' => $sub_insert['pre_new_line'] - ]; - } - } - - return $inserts; - } - - /** - * Split insert by new line and optionally set whether or not the close() - * and newLine() methods needs to be called on the Delta - * - * @param string $insert An insert string - * - * @return array array of inserts, three indexes, insert, close and new_line - */ - public function splitInsertsOnNewLine($insert): array - { - $inserts = []; - - if (preg_match("/[\n]{1}/", rtrim($insert, "\n")) !== 0) { - $matches = preg_split("/[\n]{1}/", rtrim($insert, "\n")); - $i = 0; - - foreach ($matches as $match) { - if (strlen(trim($match)) > 0) { - $sub_insert = str_replace("\n", '', $match); - $new_line = true; - $pre_new_line = false; - if ($i === (count($matches) - 1)) { - $new_line = false; - } - if ($i === 1 && count($inserts) === 0) { - $pre_new_line = true; - } - $inserts[] = [ - 'insert' => $sub_insert, - 'close' => false, - 'new_line' => $new_line, - 'pre_new_line' => $pre_new_line - ]; - } - $i++; - } - } else { - $new_line = false; - if (strpos($insert, "\n") !== FALSE) { - $new_line = true; - } - - $inserts[] = [ - 'insert' => str_replace("\n", '', $insert), - 'close' => false, - 'new_line' => $new_line, - 'pre_new_line' => false - ]; - } - - return $inserts; - } - /** * Quill list assign the relevant Delta class and set up the data, needs to * modify/remove previous Deltas @@ -345,34 +227,6 @@ public function compoundInsert(array $quill) } } - /** - * Extended Quill insert, insert will need to be split before creation - * of Deltas - * - * @param array $quill - * - * @return void - */ - public function extendedInsert(array $quill) - { - $inserts = $this->splitInsertsOnNewLines($quill['insert']); - - foreach ($inserts as $insert) { - $delta = new Insert($insert['insert']); - if ($insert['close'] === true) { - $delta->setClose(); - } - if ($insert['new_line'] === true) { - $delta->setNewLine(); - } - if (array_key_exists('pre_new_line', $insert) === true && $insert['pre_new_line'] === true) { - $delta->setPreNewLine(); - } - - $this->deltas[] = $delta; - } - } - /** * Quill HTML insert, override DBlackborough\Quill\Delta\Delta::insert * From b74fe5cdf422da39fccf2b0fe2e839beb8fdaded Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 00:12:42 +0000 Subject: [PATCH 06/15] Clean up * Comment corrections and formatting --- src/Parser/Html.php | 15 ++++++++++----- src/Render.php | 3 ++- src/Renderer/GithubMarkdown.php | 2 +- src/Renderer/Html.php | 5 ++++- src/Renderer/Markdown.php | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Parser/Html.php b/src/Parser/Html.php index c220aa0..6c558e8 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -67,7 +67,12 @@ public function __construct() */ public function attributeList(array $quill) { - if (in_array($quill['attributes'][OPTIONS::ATTRIBUTE_LIST], array('ordered', 'bullet')) === true) { + if ( + in_array( + $quill['attributes'][OPTIONS::ATTRIBUTE_LIST], + array('ordered', 'bullet') + ) === true + ) { $insert = $this->deltas[count($this->deltas) - 1]->getInsert(); $attributes = $this->deltas[count($this->deltas) - 1]->getAttributes(); @@ -238,12 +243,12 @@ public function insert(array $quill) { $insert = $quill['insert']; - /** - * @var Delta - */ if (strlen(trim($insert)) > 0) { - $delta = new $this->class_delta_insert($insert, (array_key_exists('attributes', $quill) ? $quill['attributes'] : [])); + /** + * @var Delta + */ + $delta = new $this->class_delta_insert($insert, (array_key_exists('attributes', $quill) ? $quill['attributes'] : [])); if (preg_match("/[\n]{2,}/", $insert) !== 0) { $delta->setClose(); diff --git a/src/Render.php b/src/Render.php index 1a4da81..8ffe5ca 100644 --- a/src/Render.php +++ b/src/Render.php @@ -23,7 +23,8 @@ class Render private $format; /** - * Renderer constructor, pass in the $quill_json string and set the requested output format + * Renderer constructor, pass in the $quill_json string and set the requested + * output format * * @param string $quill_json * @param string $format Requested output format diff --git a/src/Renderer/GithubMarkdown.php b/src/Renderer/GithubMarkdown.php index 6b638f3..a5801b1 100644 --- a/src/Renderer/GithubMarkdown.php +++ b/src/Renderer/GithubMarkdown.php @@ -4,7 +4,7 @@ namespace DBlackborough\Quill\Renderer; /** - * Quill renderer, iterates over the Delta[] array to create the required HTML + * Quill renderer, iterates over the Delta[] array to create the required Markdown * * @author Dean Blackborough * @copyright Dean Blackborough diff --git a/src/Renderer/Html.php b/src/Renderer/Html.php index fa4cabb..43097aa 100644 --- a/src/Renderer/Html.php +++ b/src/Renderer/Html.php @@ -43,7 +43,10 @@ public function render(bool $trim = false): string $block_open = false; foreach ($this->deltas as $i => $delta) { - if ($delta->displayType() === Delta::DISPLAY_INLINE && $block_open === false) { + if ( + $delta->displayType() === Delta::DISPLAY_INLINE && + $block_open === false + ) { $block_open = true; $this->output .= '

'; } diff --git a/src/Renderer/Markdown.php b/src/Renderer/Markdown.php index 091a2b8..c747f29 100644 --- a/src/Renderer/Markdown.php +++ b/src/Renderer/Markdown.php @@ -6,7 +6,7 @@ use DBlackborough\Quill\Delta\Markdown\Delta; /** - * Quill renderer, iterates over the Delta[] array to create the required HTML + * Quill renderer, iterates over the Delta[] array to create the required Markdown * * @author Dean Blackborough * @copyright Dean Blackborough From ae887e66873c6c548419637b4de759709208c52a Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 00:19:26 +0000 Subject: [PATCH 07/15] Updated CHANGELOG and README * Updated README and CHANGELOG, added Alex pending changes. --- CHANGELOG.md | 2 ++ README.md | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 628b414..95ea405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,11 @@ Full changelog for PHP Quill Renderer ## v3.17.0 - 2019-03-xx +* Handle custom attributes in a better way, assign to style if sensible, thank you [Alex](https://github.com/AlexFence). * Removed the `ParserSplitInterface` interface, no use anymore. * Changed which class implements `ParserAttributeInterface` interface. * Removed redundant methods from parsers. +* Code formatting and comment corrections. ## v3.16.0 - 2019-02-28 diff --git a/README.md b/README.md index 6b5fb40..3a7afb5 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,7 @@ for use under the MIT License (MIT). * [raphaelsaunier](https://github.com/raphaelsaunier) [Issue #87] - Newlines proceeding inserts ignored, bug location. * [Basil](https://github.com/nadar) [Issue #101] - Newline only inserts being ignored by parser. * [Lee Hesselden](https://github.com/on2) [PR #104] - Color delta to allowing spans with a style:color="#xxx" definition. (Feature will be extended by [Issue #106]) +* [Alex](https://github.com/AlexFence) [PR112] - Custom attributes assigned to style attribute if sensible. ## Coding standard credit From a3801336b514d643935bbaffd7cdf29fbbd59775 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 12:58:47 +0000 Subject: [PATCH 08/15] Failing test * Added first failing test for #108 --- Tests/Api/BugTest.php | 53 +++++++++++++++++++++++++++++++++++++++++-- src/Parser/Parse.php | 12 ++++++++-- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Tests/Api/BugTest.php b/Tests/Api/BugTest.php index 8763396..cc65a03 100644 --- a/Tests/Api/BugTest.php +++ b/Tests/Api/BugTest.php @@ -12,15 +12,39 @@ final class BugTest extends \PHPUnit\Framework\TestCase { private $delta_bug_external_3 = '{"ops":[{"insert":"Lorem ipsum\nLorem ipsum\n\nLorem ipsum\n"}]}'; + private $delta_bug_108_link_within_header = ' + { + "ops":[ + { + "insert":"This is a " + }, + { + "attributes":{ + "link":"https://link.com" + }, + "insert":"head" + }, + { + "insert":", it has a link within it." + }, + { + "attributes":{ + "header":2 + }, + "insert":"\n" + } + ] + }'; - private $expected_bug_external_3 = "

Lorem ipsum + private $expected_bug_external_3 = '

Lorem ipsum
Lorem ipsum

Lorem ipsum
-

"; +

'; + private $expected_bug_108_link_within_header = ''; /** * Newlines still proving to be an issue @@ -46,4 +70,29 @@ public function testNewlinesNotGeneratingNewParagraph() __METHOD__ . ' newline issues, no new paragraph' ); } + + /** + * Newlines still proving to be an issue + * Bug report https://github.com/nadar/quill-delta-parser/issues/3 + * + * @return void + * @throws \Exception + */ + public function testLinkWithinAHeader() + { + $result = null; + + try { + $quill = new QuillRender($this->delta_bug_108_link_within_header); + $result = $quill->render(); + } catch (\Exception $e) { + $this->fail(__METHOD__ . 'failure, ' . $e->getMessage()); + } + + $this->assertEquals( + $this->expected_bug_108_link_within_header, + trim($result), + __METHOD__ . ' link with header' + ); + } } diff --git a/src/Parser/Parse.php b/src/Parser/Parse.php index 9eab6fc..e5543a7 100644 --- a/src/Parser/Parse.php +++ b/src/Parser/Parse.php @@ -395,10 +395,18 @@ public function attributeBold(array $quill) */ public function attributeHeader(array $quill) { - if (in_array($quill['attributes'][OPTIONS::ATTRIBUTE_HEADER], array(1, 2, 3, 4, 5, 6, 7)) === true) { + if ( + in_array( + $quill['attributes'][OPTIONS::ATTRIBUTE_HEADER], + array(1, 2, 3, 4, 5, 6, 7) + ) === true + ) { $insert = $this->deltas[count($this->deltas) - 1]->getInsert(); unset($this->deltas[count($this->deltas) - 1]); - $this->deltas[] = new $this->class_delta_header($insert, $quill['attributes']); + $this->deltas[] = new $this->class_delta_header( + $insert, + $quill['attributes'] + ); // Reorder the array $this->deltas = array_values($this->deltas); } From 8941de88e72417089c16fa3255fa7a2b761e0e5d Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 14:36:46 +0000 Subject: [PATCH 09/15] Added children to headers Links within headers displaying correctly, however, one failing test. --- Tests/Api/BugTest.php | 4 ++-- src/Delta/Delta.php | 24 +++++++++++++++++++ src/Delta/Html/Header.php | 11 ++++++++- src/Delta/Markdown/Header.php | 27 +++++++++++++++++++-- src/Parser/Html.php | 45 +++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 5 deletions(-) diff --git a/Tests/Api/BugTest.php b/Tests/Api/BugTest.php index cc65a03..eb86632 100644 --- a/Tests/Api/BugTest.php +++ b/Tests/Api/BugTest.php @@ -22,7 +22,7 @@ final class BugTest extends \PHPUnit\Framework\TestCase "attributes":{ "link":"https://link.com" }, - "insert":"head" + "insert":"header" }, { "insert":", it has a link within it." @@ -44,7 +44,7 @@ final class BugTest extends \PHPUnit\Framework\TestCase

Lorem ipsum

'; - private $expected_bug_108_link_within_header = ''; + private $expected_bug_108_link_within_header = '

This is a header, it has a link within it.

'; /** * Newlines still proving to be an issue diff --git a/src/Delta/Delta.php b/src/Delta/Delta.php index 55b1397..e3f8139 100644 --- a/src/Delta/Delta.php +++ b/src/Delta/Delta.php @@ -76,6 +76,20 @@ public function hasChildren(): bool } } + /** + * Does the delta have any attributes + * + * @return boolean + */ + public function hasAttributes(): bool + { + if (count($this->attributes) > 0) { + return true; + } else { + return false; + } + } + /** * Is the delta a child? * @@ -164,6 +178,16 @@ public function setLastChild(bool $value = true): Delta return $this; } + /** + * Set the insert string + * + * @param string $insert + */ + public function setInsert(string $insert) + { + $this->insert = $insert; + } + /** * Escape the given insert string * diff --git a/src/Delta/Html/Header.php b/src/Delta/Html/Header.php index e471133..63d3a9b 100644 --- a/src/Delta/Html/Header.php +++ b/src/Delta/Html/Header.php @@ -46,6 +46,15 @@ public function displayType(): string */ public function render(): string { - return $this->renderSimpleTag($this->tag, $this->escape($this->insert), true); + $html = "<{$this->tag}>"; + if ($this->hasChildren() === true) { + + foreach ($this->children() as $child) { + $html .= $child->render(); + } + } + $html .= "{$this->escape($this->insert)}tag}>\n"; + + return $html; } } diff --git a/src/Delta/Markdown/Header.php b/src/Delta/Markdown/Header.php index dd55f13..fca3798 100644 --- a/src/Delta/Markdown/Header.php +++ b/src/Delta/Markdown/Header.php @@ -29,6 +29,16 @@ public function __construct(string $insert, array $attributes = []) $this->token = Options::MARKDOWN_TOKEN_HEADER; } + /** + * Return the display type + * + * @return string + */ + public function displayType(): string + { + return parent::DISPLAY_BLOCK; + } + /** * Render the Markdown string * @@ -36,7 +46,20 @@ public function __construct(string $insert, array $attributes = []) */ public function render(): string { - return str_repeat('#', intval($this->attributes['header'])) . - " {$this->escape($this->insert)}"; + $string = str_repeat('#', intval($this->attributes['header'])) . ' '; + if ($this->hasChildren() === true) { + + foreach ($this->children() as $child) { + $string .= $child->render(); + } + } + $string .= "{$this->escape($this->insert)}"; + + return $string; + + + + /*return str_repeat('#', intval($this->attributes['header'])) . + " {$this->escape($this->insert)}";*/ } } diff --git a/src/Parser/Html.php b/src/Parser/Html.php index 6c558e8..606a5b9 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -162,6 +162,51 @@ public function attributeList(array $quill) } } + /** + * Header Quill attribute, assign the relevant Delta class and set up the data + * + * @param array $quill + * + * @return void + */ + public function attributeHeader(array $quill) + { + if ( + in_array( + $quill['attributes'][OPTIONS::ATTRIBUTE_HEADER], + array(1, 2, 3, 4, 5, 6, 7) + ) === true + ) { + $insert[] = $quill['insert']; + + $this->deltas = array_values($this->deltas); + $this->deltas[] = new $this->class_delta_header( + '', + $quill['attributes'] + ); + $current_index = count($this->deltas) - 1; + + for ($i = $current_index - 1; $i >= 0; $i--) { + $this_delta = $this->deltas[$i]; + if ($this_delta->displayType() === Delta::DISPLAY_BLOCK) { + break; + } else if ($this_delta->hasAttributes() === true) { + $this->deltas[$current_index]->addChild($this->deltas[$i]); + unset($this->deltas[$i]); + } else { + $this->deltas[$current_index]->addChild( + new $this->class_delta_insert( + $this->deltas[$i]->getInsert() + ) + ); + unset($this->deltas[$i]); + } + } + + $this->deltas = array_values($this->deltas); + } + } + /** * Color Quill attribute, assign the relevant Delta class and set up the data * From cbb910839f07aa19b4c43d133cdfee93083c1cda Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 15:30:47 +0000 Subject: [PATCH 10/15] Link within header * Link within a header now renders correctly. --- src/Parser/Html.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Parser/Html.php b/src/Parser/Html.php index 606a5b9..ad6ff90 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -188,7 +188,13 @@ public function attributeHeader(array $quill) for ($i = $current_index - 1; $i >= 0; $i--) { $this_delta = $this->deltas[$i]; - if ($this_delta->displayType() === Delta::DISPLAY_BLOCK) { + if ( + $this_delta->displayType() === Delta::DISPLAY_BLOCK + || + $this_delta->newLine() === true + || + $this_delta->close() === true + ) { break; } else if ($this_delta->hasAttributes() === true) { $this->deltas[$current_index]->addChild($this->deltas[$i]); From 666e109962471bbaa5f17a8fff2ef90c8f0e5694 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 15:44:17 +0000 Subject: [PATCH 11/15] Children with headers * Resolved #108 * Added davidraijmakers to credits for reporting bug --- CHANGELOG.md | 1 + README.md | 1 + Tests/Api/BugTest.php | 50 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95ea405..d7c23cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Full changelog for PHP Quill Renderer * Removed the `ParserSplitInterface` interface, no use anymore. * Changed which class implements `ParserAttributeInterface` interface. * Removed redundant methods from parsers. +* Fixed [#108](https://github.com/deanblackborough/php-quill-renderer/issues/108), links within headers not correctly rendering, headers now support children. * Code formatting and comment corrections. ## v3.16.0 - 2019-02-28 diff --git a/README.md b/README.md index 3a7afb5..60907da 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ for use under the MIT License (MIT). * [Basil](https://github.com/nadar) [Issue #101] - Newline only inserts being ignored by parser. * [Lee Hesselden](https://github.com/on2) [PR #104] - Color delta to allowing spans with a style:color="#xxx" definition. (Feature will be extended by [Issue #106]) * [Alex](https://github.com/AlexFence) [PR112] - Custom attributes assigned to style attribute if sensible. +* [davidraijmakers](https://github.com/davidraijmakers) [#Issue #108] - Children not supported with headers. ## Coding standard credit diff --git a/Tests/Api/BugTest.php b/Tests/Api/BugTest.php index eb86632..3663b8a 100644 --- a/Tests/Api/BugTest.php +++ b/Tests/Api/BugTest.php @@ -35,6 +35,26 @@ final class BugTest extends \PHPUnit\Framework\TestCase } ] }'; + private $delta_bug_108_link_end_of_header = ' + { + "ops":[ + { + "insert":"This is a header, with a link at the " + }, + { + "attributes":{ + "link":"https://link.com" + }, + "insert":"end" + }, + { + "attributes":{ + "header":2 + }, + "insert":"\n" + } + ] + }'; private $expected_bug_external_3 = '

Lorem ipsum
@@ -45,6 +65,7 @@ final class BugTest extends \PHPUnit\Framework\TestCase

'; private $expected_bug_108_link_within_header = '

This is a header, it has a link within it.

'; + private $expected_bug_108_link_end_of_header = '

This is a header, with a link at the end

'; /** * Newlines still proving to be an issue @@ -72,8 +93,8 @@ public function testNewlinesNotGeneratingNewParagraph() } /** - * Newlines still proving to be an issue - * Bug report https://github.com/nadar/quill-delta-parser/issues/3 + * Link within a header + * Bug report https://github.com/deanblackborough/php-quill-renderer/issues/108 * * @return void * @throws \Exception @@ -95,4 +116,29 @@ public function testLinkWithinAHeader() __METHOD__ . ' link with header' ); } + + /** + * Link at the end of a header + * Bug report https://github.com/deanblackborough/php-quill-renderer/issues/108 + * + * @return void + * @throws \Exception + */ + public function testLinkAtEndOfHeader() + { + $result = null; + + try { + $quill = new QuillRender($this->delta_bug_108_link_end_of_header); + $result = $quill->render(); + } catch (\Exception $e) { + $this->fail(__METHOD__ . 'failure, ' . $e->getMessage()); + } + + $this->assertEquals( + $this->expected_bug_108_link_end_of_header, + trim($result), + __METHOD__ . ' link at end of header' + ); + } } From 8ff1115c211bb9666c2d0f711c558e5926b27858 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 15:55:56 +0000 Subject: [PATCH 12/15] Added failing test * Added failing test for #109 --- Tests/Api/BugTest.php | 150 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/Tests/Api/BugTest.php b/Tests/Api/BugTest.php index 3663b8a..0c30014 100644 --- a/Tests/Api/BugTest.php +++ b/Tests/Api/BugTest.php @@ -55,6 +55,130 @@ final class BugTest extends \PHPUnit\Framework\TestCase } ] }'; + private $delta_bug_109_list_outout_incorrect = ' + { + "ops": [ + { + "insert": "Headline 1" + }, + { + "attributes": { + "header": 1 + }, + "insert": "\n" + }, + { + "insert": "Some text. " + }, + { + "attributes": { + "bold": true + }, + "insert": "Bold Text" + }, + { + "insert": ". " + }, + { + "attributes": { + "italic": true + }, + "insert": "Italic Text" + }, + { + "insert": ". " + }, + { + "attributes": { + "italic": true, + "bold": true + }, + "insert": "Bold and italic Text" + }, + { + "insert": ". Here is a " + }, + { + "attributes": { + "link": "https://scrumpy.io" + }, + "insert": "Link" + }, + { + "insert": ". \nHeadline 2" + }, + { + "attributes": { + "header": 2 + }, + "insert": "\n" + }, + { + "insert": "ordered list item" + }, + { + "attributes": { + "list": "ordered" + }, + "insert": "\n" + }, + { + "insert": "ordered list item" + }, + { + "attributes": { + "list": "ordered" + }, + "insert": "\n" + }, + { + "insert": "ordered list item" + }, + { + "attributes": { + "list": "ordered" + }, + "insert": "\n" + }, + { + "insert": "unordered list item" + }, + { + "attributes": { + "list": "bullet" + }, + "insert": "\n" + }, + { + "insert": "unordered list item with " + }, + { + "attributes": { + "bold": true, + "link": "https://scrumpy.io" + }, + "insert": "link" + }, + { + "attributes": { + "list": "bullet" + }, + "insert": "\n" + }, + { + "insert": "unordered list item" + }, + { + "attributes": { + "list": "bullet" + }, + "insert": "\n" + }, + { + "insert": "Some Text.\n" + } + ] + }'; private $expected_bug_external_3 = '

Lorem ipsum
@@ -66,6 +190,7 @@ final class BugTest extends \PHPUnit\Framework\TestCase

'; private $expected_bug_108_link_within_header = '

This is a header, it has a link within it.

'; private $expected_bug_108_link_end_of_header = '

This is a header, with a link at the end

'; + private $expected_bug_109_list_outout_incorrect = ''; /** * Newlines still proving to be an issue @@ -141,4 +266,29 @@ public function testLinkAtEndOfHeader() __METHOD__ . ' link at end of header' ); } + + /** + * Link at the end of a header + * Bug report https://github.com/deanblackborough/php-quill-renderer/issues/108 + * + * @return void + * @throws \Exception + */ + public function testIncorrectListOutput() + { + $result = null; + + try { + $quill = new QuillRender($this->delta_bug_109_list_outout_incorrect); + $result = $quill->render(); + } catch (\Exception $e) { + $this->fail(__METHOD__ . 'failure, ' . $e->getMessage()); + } + + $this->assertEquals( + $this->expected_bug_109_list_outout_incorrect, + trim($result), + __METHOD__ . ' list output incorrect' + ); + } } From 5048d47aab291d2dd5793cb15f263b4d6e1c4c91 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Sun, 3 Mar 2019 16:12:09 +0000 Subject: [PATCH 13/15] Failing to switch list types * Partial fix for #109 - Wasn't switching list types --- src/Parser/Html.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Parser/Html.php b/src/Parser/Html.php index ad6ff90..11bc4e3 100644 --- a/src/Parser/Html.php +++ b/src/Parser/Html.php @@ -151,12 +151,17 @@ public function attributeList(array $quill) $this->deltas[$current_index]->setFirstChild(); $this->deltas[$current_index]->setLastChild(); } else { - if ($this->deltas[$previous_index]->isChild() === true) { - $this->deltas[$current_index]->setLastChild(); - $this->deltas[$previous_index]->setLastChild(false); + if ($this->deltas[$current_index]->parentTag() === $this->deltas[$previous_index]->parentTag()) { + if ($this->deltas[$previous_index]->isChild() === true) { + $this->deltas[$current_index]->setLastChild(); + $this->deltas[$previous_index]->setLastChild(false); + } else { + $this->deltas[$current_index]->setFirstChild(); + $this->deltas[$current_index]->setLastChild(); + } } else { + $this->deltas[$previous_index]->setLastChild(); $this->deltas[$current_index]->setFirstChild(); - $this->deltas[$current_index]->setLastChild(); } } } From 33aa4bfde5a0da8f88499290daabd3a40b021044 Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Mon, 4 Mar 2019 23:38:59 +0000 Subject: [PATCH 14/15] Close paragraphs * Not correctly closing paragraphs when starting a list, few missing close calls in HTML renderer * Added expected output to test for bug #109 --- Tests/Api/BugTest.php | 19 ++++++++++++++++++- src/Renderer/Html.php | 14 +++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Tests/Api/BugTest.php b/Tests/Api/BugTest.php index 0c30014..f3cbb9f 100644 --- a/Tests/Api/BugTest.php +++ b/Tests/Api/BugTest.php @@ -190,7 +190,24 @@ final class BugTest extends \PHPUnit\Framework\TestCase

'; private $expected_bug_108_link_within_header = '

This is a header, it has a link within it.

'; private $expected_bug_108_link_end_of_header = '

This is a header, with a link at the end

'; - private $expected_bug_109_list_outout_incorrect = ''; + private $expected_bug_109_list_outout_incorrect = '

Headline 1

+

Some text. Bold Text. Italic Text. Bold and italic Text. Here is a Link. +
+

+

Headline 2

+
    +
  1. ordered list item
  2. +
  3. ordered list item
  4. +
  5. ordered list item
  6. +
+
    +
  • unordered list item
  • +
  • unordered list item with linklink
  • +
  • unordered list item
  • +
+

Some Text. +
+

'; /** * Newlines still proving to be an issue diff --git a/src/Renderer/Html.php b/src/Renderer/Html.php index 43097aa..bdd783a 100644 --- a/src/Renderer/Html.php +++ b/src/Renderer/Html.php @@ -58,16 +58,28 @@ public function render(bool $trim = false): string $this->deltas[$i - 1]->displayType() === Delta::DISPLAY_INLINE ) { $this->output .= "

\n"; + $block_open = false; } $this->output .= '<' . $delta->parentTag() . ">\n"; } + if ( + $delta->displayType() === Delta::DISPLAY_BLOCK && + $block_open === true + ) { + $block_open = false; + $this->output .= "

\n"; + } + $this->output .= $delta->render(); if ( $delta->displayType() === Delta::DISPLAY_INLINE && - $block_open === true && $delta->close() === true + ( + $block_open === true && + $delta->close() === true + ) ) { $this->output .= "

\n"; $block_open = false; From 77a8ad8b877b4c9fbba49124f5642c9f52a1fe3b Mon Sep 17 00:00:00 2001 From: Dean Blackborough Date: Mon, 4 Mar 2019 23:49:17 +0000 Subject: [PATCH 15/15] Release v3.17.0 * Added philippkuehn to credits --- CHANGELOG.md | 13 +++++++++---- README.md | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7c23cb..ab811de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,18 @@ Full changelog for PHP Quill Renderer -## v3.17.0 - 2019-03-xx - -* Handle custom attributes in a better way, assign to style if sensible, thank you [Alex](https://github.com/AlexFence). +## v3.17.0 - 2019-03-04 + +* Handle custom color attribute in a better way, assign to style attribute if sensible, +thank you [Alex](https://github.com/AlexFence). Accepted PR as is, only handles colour, +will extend feature in v3.18.0. +* Fixed [#108](https://github.com/deanblackborough/php-quill-renderer/issues/108), +links within headers not correctly rendering, headers now support child deltas. +* Fixed [#109](https://github.com/deanblackborough/php-quill-renderer/issues/109), +not correctly closing paragraphs or detecting list type change. * Removed the `ParserSplitInterface` interface, no use anymore. * Changed which class implements `ParserAttributeInterface` interface. * Removed redundant methods from parsers. -* Fixed [#108](https://github.com/deanblackborough/php-quill-renderer/issues/108), links within headers not correctly rendering, headers now support children. * Code formatting and comment corrections. ## v3.16.0 - 2019-02-28 diff --git a/README.md b/README.md index 60907da..320585c 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ for use under the MIT License (MIT). * [Lee Hesselden](https://github.com/on2) [PR #104] - Color delta to allowing spans with a style:color="#xxx" definition. (Feature will be extended by [Issue #106]) * [Alex](https://github.com/AlexFence) [PR112] - Custom attributes assigned to style attribute if sensible. * [davidraijmakers](https://github.com/davidraijmakers) [#Issue #108] - Children not supported with headers. +* [philippkuehn](https://github.com/philippkuehn) [#Issue #109] - Multiple list output incorrect and paragraphs not being closed. ## Coding standard credit