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

dg / texy / 21501721037

30 Jan 2026 02:00AM UTC coverage: 91.159% (-1.3%) from 92.426%
21501721037

push

github

dg
wip

2681 of 2941 relevant lines covered (91.16%)

0.91 hits per line

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

95.45
/src/Texy/Modules/EmoticonModule.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\Nodes\EmoticonNode;
14
use Texy\ParseContext;
15
use Texy\Position;
16
use Texy\Syntax;
17
use function strlen;
18

19

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

39

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

46

47
        public function beforeParse(string &$text): void
1✔
48
        {
49
                if (str_contains(implode('', $this->icons), '.')) {
1✔
50
                        trigger_error('EmoticonModule: using image files is deprecated, use Unicode characters instead.', E_USER_DEPRECATED);
1✔
51
                }
52

53
                $icons = $this->icons;
1✔
54
                krsort($icons);
1✔
55
                $pattern = [];
1✔
56
                foreach ($icons as $key => $foo) {
1✔
57
                        $pattern[] = Texy\Regexp::quote($key) . '+'; // last char can be repeated
1✔
58
                }
59

60
                $this->texy->registerLinePattern(
1✔
61
                        $this->parse(...),
1✔
62
                        '~
63
                                (?<= ^ | [\x00-\x20] )
64
                                (' . implode('|', $pattern) . ')
1✔
65
                        ~',
66
                        Syntax::Emoticon,
1✔
67
                );
68
        }
1✔
69

70

71
        /**
72
         * Parses :-).
73
         * @param  array<?string>  $matches
74
         * @param  array<?int>  $offsets
75
         */
76
        public function parse(ParseContext $context, array $matches, array $offsets): ?EmoticonNode
1✔
77
        {
78
                $match = $matches[0];
1✔
79

80
                // Find the closest match
81
                foreach ($this->icons as $emoticon => $_) {
1✔
82
                        if (str_starts_with($match, $emoticon)) {
1✔
83
                                return new EmoticonNode($emoticon, new Position($offsets[0], strlen($matches[0])));
1✔
84
                        }
85
                }
86

87
                return null;
×
88
        }
89
}
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