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

dg / texy / 21345922688

26 Jan 2026 04:05AM UTC coverage: 92.426% (+0.04%) from 92.382%
21345922688

push

github

dg
HtmlElement: removed toHtml() & toText()

18 of 19 new or added lines in 5 files covered. (94.74%)

28 existing lines in 7 files now uncovered.

2404 of 2601 relevant lines covered (92.43%)

0.92 hits per line

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

98.08
/src/Texy/Modules/ParagraphModule.php
1
<?php
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
declare(strict_types=1);
9

10
namespace Texy\Modules;
11

12
use Texy;
13
use Texy\Regexp;
14
use function preg_match, preg_split, str_contains, str_replace, strlen, strtr, substr_replace, trim;
15
use const PREG_SPLIT_NO_EMPTY;
16

17

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

29

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

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

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

53
                                $mod = new Texy\Modifier;
1✔
54
                                $mod->setProperties($mMod);
1✔
55
                        }
56

57
                        $res = $this->texy->invokeAroundHandlers('paragraph', $parser, [$s, $mod]);
1✔
58
                        if ($res) {
1✔
59
                                $children[] = $res;
1✔
60
                        }
61
                }
62

63
                return $children;
1✔
64
        }
65

66

67
        public function toElement(
1✔
68
                Texy\HandlerInvocation $invocation,
69
                string $content,
70
                ?Texy\Modifier $mod = null,
71
        ): Texy\HtmlElement
72
        {
73
                $texy = $this->texy;
1✔
74

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

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

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

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

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

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

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

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

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

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

132
                return $el;
1✔
133
        }
134
}
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