From f711cd33c5685d9ab7e8b5de1421cc43d43f51a3 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Sun, 13 May 2018 21:34:19 +0200 Subject: [PATCH] New wordwrap method --- src/Util/StringUtil.php | 38 ++++++++++++++++--------- test/MenuItem/MenuMenuItemTest.php | 5 ++-- test/MenuItem/SelectableItemTest.php | 5 ++-- test/MenuItem/StaticItemTest.php | 2 +- test/Util/StringUtilTest.php | 42 ++++++++++++++-------------- 5 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/Util/StringUtil.php b/src/Util/StringUtil.php index 4ce39878..ebd32b7f 100644 --- a/src/Util/StringUtil.php +++ b/src/Util/StringUtil.php @@ -11,20 +11,32 @@ class StringUtil * Minimal multi-byte wordwrap implementation * which also takes break length into consideration */ - public static function wordwrap(string $str, int $width, string $break = "\n") : string + public static function wordwrap(string $string, int $width, string $break = "\n") : string { - $length = 0; - return implode(' ', array_map(function ($word) use (&$length, $width, $break) { - $length += (mb_strlen($word) + 1); - - if ($length > $width) { - $word = sprintf('%s%s', $break, $word); - $length = mb_strlen($word); - return $word; - } - - return $word; - }, explode(' ', $str))); + return implode( + $break, + array_map(function (string $line) use ($width, $break) { + $line = rtrim($line); + if (mb_strlen($line) <= $width) { + return $line; + } + + $words = explode(' ', $line); + $line = ''; + $actual = ''; + foreach ($words as $word) { + if (mb_strlen($actual . $word) <= $width) { + $actual .= $word . ' '; + } else { + if ($actual !== '') { + $line .= rtrim($actual) . $break; + } + $actual = $word . ' '; + } + } + return $line . trim($actual); + }, explode($break, $string)) + ); } public static function stripAnsiEscapeSequence(string $str) : string diff --git a/test/MenuItem/MenuMenuItemTest.php b/test/MenuItem/MenuMenuItemTest.php index ec336b57..e08b17f9 100644 --- a/test/MenuItem/MenuMenuItemTest.php +++ b/test/MenuItem/MenuMenuItemTest.php @@ -124,9 +124,8 @@ public function testGetRowsWithMultipleLines() : void $item = new MenuMenuItem('LONG ITEM LINE', $subMenu); $this->assertEquals( [ - " LONG ", - " ITEM ", - " LINE" + " LONG ITEM", + " LINE", ], $item->getRows($menuStyle) ); diff --git a/test/MenuItem/SelectableItemTest.php b/test/MenuItem/SelectableItemTest.php index 459a05bb..9c35a078 100644 --- a/test/MenuItem/SelectableItemTest.php +++ b/test/MenuItem/SelectableItemTest.php @@ -138,9 +138,8 @@ public function testGetRowsWithMultipleLinesWithItemExtra() : void }, true); $this->assertEquals( [ - " LONG [EXTRA]", - " ITEM ", - " LINE" + " LONG ITEM [EXTRA]", + " LINE", ], $item->getRows($menuStyle) ); diff --git a/test/MenuItem/StaticItemTest.php b/test/MenuItem/StaticItemTest.php index aa199424..c1ffca46 100644 --- a/test/MenuItem/StaticItemTest.php +++ b/test/MenuItem/StaticItemTest.php @@ -64,7 +64,7 @@ public function testGetRowsWithContentWhichDoesNotFitOnOneLineIsWrapped() : void $item = new StaticItem('CONTENT 1 LINE'); $this->assertEquals( - ['CONTENT 1 ', 'LINE'], + ['CONTENT 1', 'LINE'], $item->getRows($menuStyle) ); } diff --git a/test/Util/StringUtilTest.php b/test/Util/StringUtilTest.php index 19971a8d..7760a2aa 100644 --- a/test/Util/StringUtilTest.php +++ b/test/Util/StringUtilTest.php @@ -28,11 +28,11 @@ public function testItWrapsAsExpectedTo80Length() : void { $result = StringUtil::wordwrap($this->dummyText, 80); - $expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \n" . - "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis \n" . - "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \n" . - "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \n" . - "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \n" . + $expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\n" . + "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n" . + "nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n" . + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n" . + "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\n" . "culpa qui officia deserunt mollit anim id est laborum"; self::assertEquals($expected, $result); @@ -42,13 +42,13 @@ public function testItWrapsAsExpectedTo60Length() : void { $result = StringUtil::wordwrap($this->dummyText, 60); - $expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, \n" . - "sed do eiusmod tempor incididunt ut labore et dolore magna \n" . - "aliqua. Ut enim ad minim veniam, quis nostrud exercitation \n" . - "ullamco laboris nisi ut aliquip ex ea commodo consequat. \n" . - "Duis aute irure dolor in reprehenderit in voluptate velit \n" . - "esse cillum dolore eu fugiat nulla pariatur. Excepteur sint \n" . - "occaecat cupidatat non proident, sunt in culpa qui officia \n" . + $expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed\n" . + "do eiusmod tempor incididunt ut labore et dolore magna\n" . + "aliqua. Ut enim ad minim veniam, quis nostrud exercitation\n" . + "ullamco laboris nisi ut aliquip ex ea commodo consequat.\n" . + "Duis aute irure dolor in reprehenderit in voluptate velit\n" . + "esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n" . + "occaecat cupidatat non proident, sunt in culpa qui officia\n" . "deserunt mollit anim id est laborum"; self::assertEquals($expected, $result); @@ -58,13 +58,13 @@ public function testItCanUseACustomBreakCharacter() : void { $result = StringUtil::wordwrap($this->dummyText, 60, 'H'); - $expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, H" . - "sed do eiusmod tempor incididunt ut labore et dolore magna H" . - "aliqua. Ut enim ad minim veniam, quis nostrud exercitation H" . - "ullamco laboris nisi ut aliquip ex ea commodo consequat. H" . - "Duis aute irure dolor in reprehenderit in voluptate velit H" . - "esse cillum dolore eu fugiat nulla pariatur. Excepteur sint H" . - "occaecat cupidatat non proident, sunt in culpa qui officia H" . + $expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sedH" . + "do eiusmod tempor incididunt ut labore et dolore magnaH" . + "aliqua. Ut enim ad minim veniam, quis nostrud exercitationH" . + "ullamco laboris nisi ut aliquip ex ea commodo consequat.H" . + "Duis aute irure dolor in reprehenderit in voluptate velitH" . + "esse cillum dolore eu fugiat nulla pariatur. Excepteur sintH" . + "occaecat cupidatat non proident, sunt in culpa qui officiaH" . "deserunt mollit anim id est laborum"; self::assertEquals($expected, $result); @@ -84,10 +84,10 @@ public function testItCanStripAnsiEscapeSequence() : void public function testSplitItemBug() : void { - $test = 'item three I guess it isn\'t that bad, is it ?'; + $test = 'Item three I guess it isn\'t that bad, is it ?'; self::assertEquals( - "item three \nI guess it \nisn't that \nbad, is it \n?", + "Item three\nI guess it\nisn't that\nbad, is it\n?", StringUtil::wordwrap($test, 11) ); }