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

dg / texy / 29705051386

19 Jul 2026 09:41PM UTC coverage: 94.641% (+1.2%) from 93.477%
29705051386

push

github

dg
Dead code removed

- Engine::getPatternNames() and Texy::getEngine(): no callers in src or tests.
- LinkDefinitionModule::resolveUrl(): unreachable. Both bracket forms it
  handles ([*img*] and [ref]) are already consumed by earlier returns in
  resolveLinkNodeUrl(), so it could only ever return its argument unchanged.
- Text\Renderer: CodeBlockNode type 'comment' never exists; comments are a
  separate CommentNode. Leftover from before the node split.

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

35 existing lines in 7 files now uncovered.

3338 of 3527 relevant lines covered (94.64%)

0.95 hits per line

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

91.89
/src/Texy/Modules/EmoticonModule.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\Compat;
12
use Texy\Nodes\EmoticonNode;
13
use Texy\ParseContext;
14
use Texy\Range;
15
use Texy\Syntax;
16
use function strlen;
17

18

19
/**
20
 * Replaces emoticons with images or Unicode characters.
21
 */
22
final class EmoticonModule extends Texy\Module
23
{
24
        /** @var array<string, string> emoticon → emoji/image mapping */
25
        public array $icons = [
26
                ':-)' => '🙂',
27
                ':-(' => '☹',
28
                ';-)' => '😉',
29
                ':-D' => '😁',
30
                '8-O' => '😮',
31
                '8-)' => '😄',
32
                ':-?' => '😕',
33
                ':-x' => '😶',
34
                ':-P' => '😛',
35
                ':-|' => '😐',
36
        ];
37

38

39
        public function __construct(
1✔
40
                private Texy\Texy $texy,
41
        ) {
42
                $texy->allowed[Syntax::Emoticon] = false;
1✔
43
                $texy->addHandler('afterParse', $this->resolveEmoticons(...));
1✔
44
        }
1✔
45

46

47
        /**
48
         * Writes resolved emoji into EmoticonNode so the AST is semantically complete
49
         * and generators need not reach into this module.
50
         */
51
        public function resolveEmoticons(Texy\Nodes\DocumentNode $doc): void
1✔
52
        {
53
                if (empty($this->texy->allowed[Syntax::Emoticon])) { // disabled → no EmoticonNodes in AST
1✔
54
                        return;
1✔
55
                }
56

57
                (new Texy\NodeTraverser)->traverse($doc, function (Texy\Node $node): ?int {
1✔
58
                        if ($node instanceof EmoticonNode) {
1✔
59
                                $node->resolved = $this->icons[$node->emoticon] ?? $node->emoticon;
1✔
60
                        }
61
                        return null;
1✔
62
                });
1✔
63
        }
1✔
64

65

66
        public function beforeParse(string &$text): void
1✔
67
        {
68
                if (str_contains(implode('', $this->icons), '.')) {
1✔
69
                        trigger_error('EmoticonModule: using image files is deprecated, use Unicode characters instead.', E_USER_DEPRECATED);
1✔
70
                }
71

72
                $icons = $this->icons;
1✔
73
                krsort($icons);
1✔
74
                $pattern = [];
1✔
75
                foreach ($icons as $key => $foo) {
1✔
76
                        $pattern[] = Texy\Regexp::quote($key) . '+'; // last char can be repeated
1✔
77
                }
78

79
                $this->texy->registerLinePattern(
1✔
80
                        $this->parse(...),
1✔
81
                        '~
82
                                (?<= ^ | [\x00-\x20] )
83
                                (' . implode('|', $pattern) . ')
1✔
84
                        ~x',
85
                        Syntax::Emoticon,
1✔
86
                );
87
        }
1✔
88

89

90
        /**
91
         * Parses :-).
92
         * @param  array<?string>  $matches
93
         * @param  array<?int>  $offsets
94
         */
95
        public function parse(ParseContext $context, array $matches, array $offsets): ?EmoticonNode
1✔
96
        {
97
                /** @var array{string, string} $matches */
98
                $match = $matches[0];
1✔
99

100
                // Find the closest match
101
                foreach ($this->icons as $emoticon => $_) {
1✔
102
                        if (str_starts_with($match, $emoticon)) {
1✔
103
                                return new EmoticonNode($emoticon, new Range($offsets[0], strlen($matches[0])));
1✔
104
                        }
105
                }
106

UNCOV
107
                return null;
×
108
        }
109

110

111
        /**
112
         * @deprecated use $texy->htmlOutput->emoticonClass etc. instead
113
         */
114
        public function &__get(string $name): mixed
115
        {
UNCOV
116
                return Compat\Legacy::ref($this->texy, Compat\Legacy::OfModule['emoticonModule'], '$texy->emoticonModule', $name, 'read');
×
117
        }
118

119

120
        /**
121
         * @deprecated use $texy->htmlOutput->emoticonClass etc. instead
122
         */
123
        public function __set(string $name, mixed $value): void
1✔
124
        {
125
                Compat\Legacy::set($this->texy, Compat\Legacy::OfModule['emoticonModule'], '$texy->emoticonModule', $name, $value);
1✔
126
        }
1✔
127

128

129
        public function __isset(string $name): bool
130
        {
UNCOV
131
                return Compat\Legacy::isSet($this->texy, Compat\Legacy::OfModule['emoticonModule'], $name);
×
132
        }
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc