8000 feature #22225 [Console] Support formatted text cutting (ro0NL) · symfony/symfony@c3fd60d · GitHub
[go: up one dir, main page]

Skip to content

Commit c3fd60d

Browse files
author
Robin Chalas
committed
feature #22225 [Console] Support formatted text cutting (ro0NL)
This PR was squashed before being merged into the 4.2-dev branch (closes #22225). Discussion ---------- [Console] Support formatted text cutting | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes/no | Fixed tickets | #... <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | symfony/symfony-docs#... <!--highly recommended for new features--> allows cutting a formatted text to a certain width. Actually needed if we want to support max. column widths in tables (see #22156) ```php $text = 'pre <error>foo bar baz</error> post'; dump('BEFORE'); $output->writeln(wordwrap($output->getFormatter()->format($text), 3, "\n", true), OutputInterface::OUTPUT_RAW); dump('AFTER'); $output->writeln($output->getFormatter()->format($text, 3), OutputInterface::OUTPUT_RAW); ``` ![image](https://cloud.githubusercontent.com/assets/1047696/24519346/19c9b0ca-1585-11e7-8437-0bcfb6fab63e.png) Commits ------- 09f8ad9 [Console] Support formatted text cutting
2 parents 25ca59d + 09f8ad9 commit c3fd60d

File tree

4 files changed

+67
-6
lines changed

4 files changed

+67
-6
lines changed

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* deprecated passing a command as a string to `ProcessHelper::run()`,
1010
pass it the command as an array of its arguments instead
1111
* made the `ProcessHelper` class final
12+
* added `WrappableOutputFormatterInterface::formatAndWrap()` (implemented in `OutputFormatter`)
1213

1314
4.1.0
1415
-----

src/Symfony/Component/Console/Formatter/OutputFormatter.php

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
* Formatter class for console output.
1818
*
1919
* @author Konstantin Kudryashov <ever.zet@gmail.com>
20+
* @author Roland Franssen <franssen.roland@gmail.com>
2021
*/
21-
class OutputFormatter implements OutputFormatterInterface
22+
class OutputFormatter implements WrappableOutputFormatterInterface
2223
{
2324
private $decorated;
2425
private $styles = array();
@@ -130,7 +131,14 @@ public function getStyle($name)
130131
*/
131132
public function format($message)
132133
{
133-
$message = (string) $message;
134+
return $this->formatAndWrap((string) $message, 0);
135+
}
136+
137+
/**
138+
* {@inheritdoc}
139+
*/
140+
public function formatAndWrap(string $message, int $width)
141+
{
134142
$offset = 0;
135143
$output = '';
136144
$tagRegex = '[a-z][a-z0-9,_=;-]*+';
@@ -144,7 +152,7 @@ public function format($message)
144152
}
145153

146154
// add the text up to the next tag
147-
$output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
155+
$output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset), $output, $width);
148156
$offset = $pos + \strlen($text);
149157

150158
// opening tag?
@@ -158,15 +166,15 @@ public function format($message)
158166
// </>
159167
$this->styleStack->pop();
160168
} elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
161-
$output .= $this->applyCurrentStyle($text);
169+
$output .= $this->applyCurrentStyle($text, $output, $width);
162170
} elseif ($open) {
163171
$this->styleStack->push($style);
164172
} else {
165173
$this->styleStack->pop($style);
166174
}
167175
}
168176

169-
$output .= $this->applyCurrentStyle(substr($message, $offset));
177+
$output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width);
170178

171179
if (false !== strpos($output, "\0")) {
172180
return strtr($output, array("\0" => '\\', '\\<' => '<'));
@@ -223,8 +231,24 @@ private function createStyleFromString(string $string)
223231
/**
224232
* Applies current style from stack to text, if must be applied.
225233
*/
226-
private function applyCurrentStyle(string $text): string
234+
private function applyCurrentStyle(string $text, string $current, int $width): string
227235
{
236+
if ('' === $text) {
237+
return '';
238+
}
239+
240+
if ($width) {
241+
if ('' !== $current) {
242+
$text = ltrim($text);
243+
}
244+
245+
$text = wordwrap($text, $width, "\n", true);
246+
247+
if ('' !== $current && "\n" !== substr($current, -1)) {
248+
$text = "\n".$text;
249+
}
250+
}
251+
228252
return $this->isDecorated() && \strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
229253
}
230254
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Console\Formatter;
13+
14+
/**
15+
* Formatter interface for console output that supports word wrapping.
16+
*
17+
* @author Roland Franssen <franssen.roland@gmail.com>
18+
*/
19+
interface WrappableOutputFormatterInterface extends OutputFormatterInterface
20+
{
21+
/**
22+
* Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping).
23+
*/
24+
public function formatAndWrap(string $message, int $width);
25+
}

src/Symfony/Component/Console/Tests/Formatter/OutputFormatterTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,17 @@ public function testContentWithLineBreaks()
322322
EOF
323323
));
324324
}
325+
326+
public function testFormatAndWrap()
327+
{
328+
$formatter = new OutputFormatter(true);
329+
330+
$this->assertSame("pre\n\033[37;41mfoo\nbar\nbaz\033[39;49m\npos\nt", $formatter->formatAndWrap('pre <error>foo bar baz</error> post', 3));
331+
332+
$formatter = new OutputFormatter();
333+
334+
$this->assertSame("pre\nfoo\nbar\nbaz\npos\nt", $formatter->formatAndWrap('pre <error>foo bar baz</error> post', 3));
335+
}
325336
}
326337

327338
class TableCell

0 commit comments

Comments
 (0)
0