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

dg / texy / 29746802114

20 Jul 2026 01:19PM UTC coverage: 94.677% (+0.04%) from 94.641%
29746802114

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%)

74 existing lines in 15 files now uncovered.

3344 of 3532 relevant lines covered (94.68%)

0.95 hits per line

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

97.3
/src/Texy/Engine.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;
9

10
use JetBrains\PhpStorm\Language;
11

12

13
/**
14
 * Minimal parser engine - handles pattern registration and parsing.
15
 *
16
 * This class is designed to be configured once and reused for multiple parse operations.
17
 * It contains NO security logic (UrlPolicy, allowedClasses, etc.) and NO lifecycle management.
18
 * Those responsibilities belong to the Texy class which contains this engine.
19
 *
20
 * Usage:
21
 *   $engine = new Engine();
22
 *   $engine->registerLinePattern($handler, $pattern, 'syntax/name');
23
 *   $engine->registerBlockPattern($handler, $pattern, 'syntax/name');
24
 *   $doc = $engine->parse($text, ['syntax/name' => true]);
25
 */
26
class Engine
27
{
28
        /**
29
         * Registered regexps and associated handlers for inline parsing.
30
         * @var array<string, array{handler: \Closure(ParseContext, array<?string>, array<?int>, string): ?Nodes\InlineNode, pattern: string}>
31
         */
32
        private array $linePatterns = [];
33

34
        /**
35
         * Registered regexps and associated handlers for block parsing.
36
         * @var array<string, array{handler: \Closure(ParseContext, array<?string>, array<?int>, string): ?Nodes\BlockNode, pattern: string}>
37
         */
38
        private array $blockPatterns = [];
39

40
        /**
41
         * Gap handler for content between block patterns.
42
         * @var \Closure(ParseContext, string, int): array<Nodes\BlockNode>
43
         */
44
        private \Closure $gapHandler;
45

46

47
        public function __construct()
48
        {
49
                // Default gap handler - creates empty array (no paragraphs by default)
50
                $this->gapHandler = fn(ParseContext $context, string $text, int $offset) => [];
1✔
51
        }
1✔
52

53

54
        /**
55
         * Register an inline pattern handler.
56
         *
57
         * @param  \Closure(ParseContext, array<?string>, array<?int>, string): ?Nodes\InlineNode  $handler
58
         */
59
        public function registerLinePattern(
1✔
60
                \Closure $handler,
61
                #[Language('RegExp')]
62
                string $pattern,
63
                string $name,
64
        ): void
65
        {
66
                $this->linePatterns[$name] = [
1✔
67
                        'handler' => $handler,
1✔
68
                        'pattern' => $pattern,
1✔
69
                ];
70
        }
1✔
71

72

73
        /**
74
         * Register a block pattern handler.
75
         *
76
         * @param  \Closure(ParseContext, array<?string>, array<?int>, string): ?Nodes\BlockNode  $handler
77
         */
78
        public function registerBlockPattern(
1✔
79
                \Closure $handler,
80
                #[Language('RegExp')]
81
                string $pattern,
82
                string $name,
83
        ): void
84
        {
85
                $this->blockPatterns[$name] = [
1✔
86
                        'handler' => $handler,
1✔
87
                        'pattern' => $pattern . 'm', // force multiline
1✔
88
                ];
89
        }
1✔
90

91

92
        /**
93
         * Set custom gap handler for content between block patterns.
94
         *
95
         * @param  \Closure(ParseContext, string, int): array<Nodes\BlockNode>  $handler
96
         */
97
        public function setGapHandler(\Closure $handler): void
1✔
98
        {
99
                $this->gapHandler = $handler;
1✔
100
        }
1✔
101

102

103
        /**
104
         * Parse text into AST.
105
         *
106
         * @param  array<string, bool>  $allowedSyntaxes  Map of syntax name => enabled
107
         * @param  bool  $singleLine  Parse as single line (inline only)
108
         */
109
        public function parse(string $text, array $allowedSyntaxes, bool $singleLine = false): Nodes\DocumentNode
1✔
110
        {
111
                $context = $this->createParseContext($allowedSyntaxes);
1✔
112
                $content = $singleLine
1✔
UNCOV
113
                        ? $context->parseInline($text)
×
114
                        : $context->parseBlock($text);
1✔
115

116
                return new Nodes\DocumentNode($content);
1✔
117
        }
118

119

120
        /**
121
         * Create parse context with filtered patterns.
122
         *
123
         * @param  array<string, bool>  $allowedSyntaxes
124
         */
125
        public function createParseContext(array $allowedSyntaxes): ParseContext
1✔
126
        {
127
                return new ParseContext(
1✔
128
                        $this->createInlineParser($allowedSyntaxes),
1✔
129
                        $this->createBlockParser($allowedSyntaxes),
1✔
130
                );
131
        }
132

133

134
        /**
135
         * Create block parser with filtered patterns.
136
         *
137
         * @param  array<string, bool>  $allowedSyntaxes
138
         */
139
        private function createBlockParser(array $allowedSyntaxes): BlockParser
1✔
140
        {
141
                $filteredPatterns = array_filter(
1✔
142
                        $this->blockPatterns,
1✔
143
                        fn($_, $name) => !empty($allowedSyntaxes[$name]),
1✔
144
                        ARRAY_FILTER_USE_BOTH,
1✔
145
                );
146

147
                return new BlockParser($filteredPatterns, $this->gapHandler);
1✔
148
        }
149

150

151
        /**
152
         * Create inline parser with filtered patterns.
153
         *
154
         * @param  array<string, bool>  $allowedSyntaxes
155
         */
156
        private function createInlineParser(array $allowedSyntaxes): InlineParser
1✔
157
        {
158
                $filteredPatterns = array_filter(
1✔
159
                        $this->linePatterns,
1✔
160
                        fn($_, $name) => !empty($allowedSyntaxes[$name]),
1✔
161
                        ARRAY_FILTER_USE_BOTH,
1✔
162
                );
163

164
                return new InlineParser($filteredPatterns);
1✔
165
        }
166
}
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