• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dg / texy / 22262589061

21 Feb 2026 07:04PM UTC coverage: 92.991% (+1.8%) from 91.178%
22262589061

push

github

dg
LinkModule: deprecated label and modifiers in link definitions

3 of 3 new or added lines in 1 file covered. (100.0%)

126 existing lines in 22 files now uncovered.

2083 of 2240 relevant lines covered (92.99%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.0
/src/Texy/Modules/ParagraphModule.php
1
<?php declare(strict_types=1);
2

3
/**
4
 * This file is part of the Texy! (https://texy.nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
namespace Texy\Modules;
9

10
use Texy;
11
use Texy\Regexp;
12
use function str_contains, str_replace, strlen, strtr, substr_replace, trim;
13

14

15
/**
16
 * Processes paragraphs and handles line breaks.
17
 */
18
final class ParagraphModule extends Texy\Module
19
{
20
        public function __construct(
1✔
21
                private Texy\Texy $texy,
22
        ) {
23
                $texy->addHandler('paragraph', $this->solve(...));
1✔
24
        }
1✔
25

26

27
        /** @return list<Texy\HtmlElement> */
28
        public function process(Texy\BlockParser $parser, string $content): array
1✔
29
        {
30
                $res = [];
1✔
31
                $parts = $parser->isIndented()
1✔
32
                        ? Regexp::split($content, '~(\n (?! \ ) | \n{2,})~', skipEmpty: true)
1✔
33
                        : Regexp::split($content, '~(\n{2,})~', skipEmpty: true);
1✔
34

35
                foreach ($parts ?: [] as $s) {
1✔
36
                        $s = trim($s);
1✔
37
                        if ($s === '') {
1✔
38
                                continue;
1✔
39
                        }
40

41
                        // try to find modifier
42
                        $mod = null;
1✔
43
                        if ($mx = Regexp::match($s, '~' . Texy\Patterns::MODIFIER_H . '(?= \n | \z)~sUm', captureOffset: true)) {
1✔
44
                                [$mMod] = $mx[1];
1✔
45
                                $s = trim(substr_replace($s, '', $mx[0][1], strlen($mx[0][0])));
1✔
46
                                if ($s === '') {
1✔
47
                                        continue;
1✔
48
                                }
49

50
                                $mod = Texy\Modifier::parse($mMod);
1✔
51
                        }
52

53
                        $el = $this->texy->invokeAroundHandlers('paragraph', $parser, [$s, $mod]);
1✔
54
                        if ($el) {
1✔
55
                                $res[] = $el;
1✔
56
                        }
57
                }
58

59
                return $res;
1✔
60
        }
61

62

63
        /**
64
         * Finish invocation.
65
         */
66
        private function solve(
1✔
67
                Texy\HandlerInvocation $invocation,
68
                string $content,
69
                ?Texy\Modifier $mod = null,
70
        ): Texy\HtmlElement
71
        {
72
                $texy = $this->texy;
1✔
73

74
                // find hard linebreaks
75
                $content = $texy->mergeLines
1✔
76
                        // ....
77
                        // ... => \r means break line
78
                        ? Regexp::replace($content, '~\n\ +(?= \S)~', "\r")
1✔
79
                        : Regexp::replace($content, '~\n~', "\r");
1✔
80

81
                $el = new Texy\HtmlElement('p');
1✔
82
                $el->parseLine($texy, $content);
1✔
83
                $content = $el->getText();
1✔
84
                assert($content !== null);
85

86
                // check content type
87
                // block contains block tag
88
                if (str_contains($content, $texy::CONTENT_BLOCK)) {
1✔
89
                        $el->setName(null); // ignores modifier!
1✔
90

91
                // block contains text (protected)
92
                } elseif (str_contains($content, $texy::CONTENT_TEXTUAL)) {
1✔
93
                        // leave element p
94

95
                // block contains text
96
                } elseif (Regexp::match($content, '~[^\s' . Texy\Patterns::MARK . ']~')) {
1✔
97
                        // leave element p
98

99
                // block contains only replaced element
100
                } elseif (str_contains($content, $texy::CONTENT_REPLACED)) {
1✔
101
                        if ($texy->nontextParagraph instanceof Texy\HtmlElement) {
1✔
UNCOV
102
                                $el = (clone $texy->nontextParagraph)->setText($content);
×
103
                        } else {
104
                                $el->setName($texy->nontextParagraph);
1✔
105
                        }
106

107
                // block contains only markup tags or spaces or nothing
108
                } else {
109
                        // if {ignoreEmptyStuff} return null;
110
                        if (!$mod) {
1✔
111
                                $el->setName(null);
1✔
112
                        }
113
                }
114

115
                if ($el->getName()) {
1✔
116
                        // apply modifier
117
                        if ($mod) {
1✔
118
                                $mod->decorate($texy, $el);
1✔
119
                        }
120

121
                        // add <br>
122
                        if (str_contains($content, "\r")) {
1✔
123
                                $key = $texy->protect('<br>', $texy::CONTENT_REPLACED);
1✔
124
                                $content = str_replace("\r", $key, $content);
1✔
125
                        }
126
                }
127

128
                $content = strtr($content, "\r\n", '  ');
1✔
129
                $el->setText($content);
1✔
130

131
                return $el;
1✔
132
        }
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc