• 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

97.67
/src/Texy/Modules/FigureModule.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\Modifier;
14
use Texy\Nodes\ContentNode;
15
use Texy\Nodes\FigureNode;
16
use Texy\Nodes\ImageNode;
17
use Texy\Nodes\LinkNode;
18
use Texy\ParseContext;
19
use Texy\Patterns;
20
use Texy\Position;
21
use Texy\Syntax;
22
use function strlen;
23

24

25
/**
26
 * Processes images with captions.
27
 */
28
final class FigureModule extends Texy\Module
29
{
30
        public function __construct(
1✔
31
                private Texy\Texy $texy,
32
        ) {
33
        }
1✔
34

35

36
        public function beforeParse(string &$text): void
1✔
37
        {
38
                $this->texy->registerBlockPattern(
1✔
39
                        $this->parse(...),
1✔
40
                        '~^
41
                                (?>
42
                                        \[\*\ *+                      # opening bracket with asterisk
43
                                        ([^\n' . Patterns::MARK . ']{1,1000}) # URLs (1)
1✔
44
                                        ' . Patterns::MODIFIER . '?   # modifier (2)
1✔
45
                                        \ *+
46
                                        ( \* | (?<! < ) > | < )       # alignment (3)
47
                                ]
48
                                )
49
                                (?:
50
                                        :(' . Patterns::LINK_URL . ' | : ) # link or colon (4)
1✔
51
                                )??
52
                                (?:
53
                                        \ ++ \*\*\* \ ++              # separator
54
                                        (.{0,2000})                   # caption (5)
55
                                )?
56
                                ' . Patterns::MODIFIER_H . '?     # modifier (6)
1✔
57
                        $~mU',
58
                        Syntax::Figure,
1✔
59
                );
60
        }
1✔
61

62

63
        /**
64
         * Parses [*image*]:link *** caption .(title)[class]{style}>.
65
         * @param  array<?string>  $matches
66
         * @param  array<?int>  $offsets
67
         */
68
        public function parse(ParseContext $context, array $matches, array $offsets): ?FigureNode
1✔
69
        {
70
                [, $mURLs, $mImgMod, $mAlign, $mLink, $mContent, $mMod] = $matches;
1✔
71

72
                $texy = $this->texy;
1✔
73

74
                // Parse image content
75
                $parsed = $texy->imageModule->parseImageContent($mURLs);
1✔
76
                $modifier = Modifier::parse($mImgMod . $mAlign);
1✔
77

78
                if ($parsed['url'] === null) {
1✔
79
                        return null;
×
80
                }
81

82
                // Create ImageNode
83
                $imageNode = new ImageNode(
1✔
84
                        $parsed['url'],
1✔
85
                        $parsed['width'],
1✔
86
                        $parsed['height'],
1✔
87
                        $modifier,
88
                );
89

90
                // If figure has link, wrap image in LinkNode
91
                $image = $imageNode;
1✔
92
                if ($mLink) {
1✔
93
                        if ($mLink === ':') {
1✔
94
                                // Link to image itself - use imageModule.root
95
                                $linkUrl = $parsed['linkedUrl'] ?? $parsed['url'];
1✔
96
                                $isImageLink = true;
1✔
97
                        } else {
98
                                // Direct URL or reference like [ref] or [*img*]
99
                                $linkUrl = $mLink;
1✔
100
                                // Check if it's an image reference [*...*] → use imageModule.root
101
                                $len = strlen($mLink);
1✔
102
                                $isImageLink = $len > 4 && $mLink[0] === '[' && $mLink[1] === '*'
1✔
103
                                        && $mLink[$len - 1] === ']' && $mLink[$len - 2] === '*';
1✔
104
                        }
105

106
                        $image = new LinkNode(
1✔
107
                                url: $linkUrl,
1✔
108
                                content: new ContentNode([$imageNode]),
1✔
109
                                isImageLink: $isImageLink,
110
                        );
111
                }
112

113
                // Parse caption as inline content
114
                $caption = null;
1✔
115
                $mContent = trim($mContent ?? '');
1✔
116
                if ($mContent !== '') {
1✔
117
                        $captionOffset = $offsets[5] ?? $offsets[0];
1✔
118
                        $caption = $context->parseInline($mContent, $captionOffset);
1✔
119
                }
120

121
                return new FigureNode(
1✔
122
                        $image,
1✔
123
                        $caption,
124
                        Modifier::parse($mMod),
1✔
125
                        new Position($offsets[0], strlen($matches[0])),
1✔
126
                );
127
        }
128
}
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