Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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\Helper;
13
 
14
/**
15
 * Simple output wrapper for "tagged outputs" instead of wordwrap(). This solution is based on a StackOverflow
16
 * answer: https://stackoverflow.com/a/20434776/1476819 from user557597 (alias SLN).
17
 *
18
 *  (?:
19
 *       # -- Words/Characters
20
 *       (                       # (1 start)
21
 *            (?>                     # Atomic Group - Match words with valid breaks
22
 *                 .{1,16}                 #  1-N characters
23
 *                                         #  Followed by one of 4 prioritized, non-linebreak whitespace
24
 *                 (?:                     #  break types:
25
 *                      (?<= [^\S\r\n] )        # 1. - Behind a non-linebreak whitespace
26
 *                      [^\S\r\n]?              #      ( optionally accept an extra non-linebreak whitespace )
27
 *                   |  (?= \r? \n )            # 2. - Ahead a linebreak
28
 *                   |  $                       # 3. - EOS
29
 *                   |  [^\S\r\n]               # 4. - Accept an extra non-linebreak whitespace
30
 *                 )
31
 *            )                       # End atomic group
32
 *         |
33
 *            .{1,16}                 # No valid word breaks, just break on the N'th character
34
 *       )                       # (1 end)
35
 *       (?: \r? \n )?           # Optional linebreak after Words/Characters
36
 *    |
37
 *       # -- Or, Linebreak
38
 *       (?: \r? \n | $ )        # Stand alone linebreak or at EOS
39
 *  )
40
 *
41
 * @author Krisztián Ferenczi <ferenczi.krisztian@gmail.com>
42
 *
43
 * @see https://stackoverflow.com/a/20434776/1476819
44
 */
45
final class OutputWrapper
46
{
47
    private const TAG_OPEN_REGEX_SEGMENT = '[a-z](?:[^\\\\<>]*+ | \\\\.)*';
48
    private const TAG_CLOSE_REGEX_SEGMENT = '[a-z][^<>]*+';
49
    private const URL_PATTERN = 'https?://\S+';
50
 
51
    public function __construct(
52
        private bool $allowCutUrls = false
53
    ) {
54
    }
55
 
56
    public function wrap(string $text, int $width, string $break = "\n"): string
57
    {
58
        if (!$width) {
59
            return $text;
60
        }
61
 
62
        $tagPattern = sprintf('<(?:(?:%s)|/(?:%s)?)>', self::TAG_OPEN_REGEX_SEGMENT, self::TAG_CLOSE_REGEX_SEGMENT);
63
        $limitPattern = "{1,$width}";
64
        $patternBlocks = [$tagPattern];
65
        if (!$this->allowCutUrls) {
66
            $patternBlocks[] = self::URL_PATTERN;
67
        }
68
        $patternBlocks[] = '.';
69
        $blocks = implode('|', $patternBlocks);
70
        $rowPattern = "(?:$blocks)$limitPattern";
71
        $pattern = sprintf('#(?:((?>(%1$s)((?<=[^\S\r\n])[^\S\r\n]?|(?=\r?\n)|$|[^\S\r\n]))|(%1$s))(?:\r?\n)?|(?:\r?\n|$))#imux', $rowPattern);
72
        $output = rtrim(preg_replace($pattern, '\\1'.$break, $text), $break);
73
 
74
        return str_replace(' '.$break, $break, $output);
75
    }
76
}