1: <?php declare(strict_types=1);
2:
3: namespace Salient\Console\Support;
4:
5: use Salient\Console\Support\ConsoleTagAttributes as TagAttributes;
6: use Salient\Contract\Console\ConsoleFormatInterface as Format;
7: use Salient\Contract\Console\ConsoleTag as Tag;
8: use Salient\Contract\Core\Immutable;
9: use Salient\Core\Concern\HasMutator;
10: use Salient\Utility\Arr;
11:
12: /**
13: * Maps inline formatting tags to formats
14: */
15: final class ConsoleTagFormats implements Immutable
16: {
17: use HasMutator;
18:
19: /** @var array<Tag::*,Format> */
20: private array $Formats = [];
21: private bool $Unescape;
22: private bool $WrapAfterApply;
23: private Format $FallbackFormat;
24:
25: public function __construct(
26: bool $unescape = true,
27: bool $wrapAfterApply = false,
28: ?Format $fallbackFormat = null
29: ) {
30: $this->Unescape = $unescape;
31: $this->WrapAfterApply = $wrapAfterApply;
32: $this->FallbackFormat = $fallbackFormat
33: ?: ConsoleFormat::getDefaultFormat();
34: }
35:
36: /**
37: * @return static
38: */
39: public function withUnescape(bool $value = true)
40: {
41: return $this->with('Unescape', $value);
42: }
43:
44: /**
45: * @return static
46: */
47: public function withWrapAfterApply(bool $value = true)
48: {
49: return $this->with('WrapAfterApply', $value);
50: }
51:
52: /**
53: * True if text should be unescaped for the target
54: */
55: public function getUnescape(): bool
56: {
57: return $this->Unescape;
58: }
59:
60: /**
61: * True if text should be wrapped after formatting
62: */
63: public function getWrapAfterApply(): bool
64: {
65: return $this->WrapAfterApply;
66: }
67:
68: /**
69: * Get an instance with a format assigned to a tag
70: *
71: * @param Tag::* $tag
72: * @return static
73: */
74: public function withFormat($tag, Format $format)
75: {
76: // @phpstan-ignore salient.property.type
77: return $this->with('Formats', Arr::set($this->Formats, $tag, $format));
78: }
79:
80: /**
81: * Get the format assigned to a tag
82: *
83: * @param Tag::* $tag
84: */
85: public function getFormat($tag): Format
86: {
87: return $this->Formats[$tag] ?? $this->FallbackFormat;
88: }
89:
90: /**
91: * Format tagged text before it is written to the target
92: */
93: public function apply(?string $text, TagAttributes $attributes): string
94: {
95: $format = $this->Formats[$attributes->Tag] ?? $this->FallbackFormat;
96: return $format->apply($text, $attributes);
97: }
98: }
99: