1717use function time ;
1818
1919/**
20- * Formatter consists of text formatting helpers to support the use of Slack's Mrkdwn format in messages, modals, etc.
20+ * Md consists of text formatting helpers to support the use of Slack's Mrkdwn format in messages, modals, etc.
2121 *
2222 * Some characters ("<", ">", "&") should be escaped when they are not a part of formatting that requires those
2323 * characters. The formatting helpers in this class automatically escape input in situations where the text is place
2424 * within angle brackets, such as with dates and links.
2525 */
26- final class Formatter
26+ final class Md
2727{
28+ private static ?self $ instance = null ;
29+
2830 public const DATE = '{date} ' ;
2931 public const DATE_LONG = '{date_long} ' ;
3032 public const DATE_LONG_PRETTY = '{date_long_pretty} ' ;
@@ -37,7 +39,7 @@ final class Formatter
3739
3840 public static function new (): self
3941 {
40- return new self ();
42+ return ( self :: $ instance ??= new self () );
4143 }
4244
4345 /**
@@ -72,7 +74,7 @@ public function sub(string $text, array $values): string
7274 return strtr ($ text , $ replacements );
7375 }
7476
75- // region Helpers for @here, @channel, and @everyone mentions.
77+ # region Helpers for @here, @channel, and @everyone mentions.
7678 public function atChannel (): string
7779 {
7880 return '<!channel> ' ;
@@ -87,9 +89,9 @@ public function atHere(): string
8789 {
8890 return '<!here> ' ;
8991 }
90- // endregion
92+ # endregion
9193
92- // region Helpers for mentioning/linking specific channels, users, or user groups.
94+ # region Helpers for mentioning/linking specific channels, users, or user groups.
9395 public function channel (string $ id ): string
9496 {
9597 return "<# {$ id }> " ;
@@ -104,9 +106,9 @@ public function userGroup(string $id): string
104106 {
105107 return "<!subteam^ {$ id }> " ;
106108 }
107- // endregion
109+ # endregion
108110
109- // region Helpers for basic text formatting (B/I/S) and links.
111+ # region Helpers for basic text formatting (B/I/S) and links.
110112 public function bold (string $ text ): string
111113 {
112114 return "* {$ text }* " ;
@@ -129,43 +131,39 @@ public function strike(string $text): string
129131
130132 public function link (string $ url , ?string $ text = null ): string
131133 {
132- return isset ($ text ) ? "< {$ this -> escape ( $ url) }| {$ this ->escape ($ text )}> " : "< {$ this -> escape ( $ url) }> " ;
134+ return isset ($ text ) ? "< {$ url }| {$ this ->escape ($ text )}> " : "< {$ url }> " ;
133135 }
134136
135137 public function emailLink (string $ email , ?string $ text = null ): string
136138 {
137139 return $ this ->link ("mailto: {$ email }" , $ text );
138140 }
139- // endregion
141+ # endregion
140142
141- // region Helpers for multi-line content blocks like lists and quotes.
143+ # region Helpers for multi-line content blocks like lists and quotes.
142144 /**
143145 * @param array<string>|string $lines
144- * @return string
145146 */
146147 public function blockQuote (array |string $ lines ): string
147148 {
148149 return $ this ->lines ($ this ->explode ($ lines ), '> ' , false );
149150 }
150151
152+ public function codeBlock (string $ text ): string
153+ {
154+ return "``` \n{$ this ->escape ($ text )}\n``` " ;
155+ }
156+
151157 /**
152158 * @param array<string>|string $items
153- * @param string $bullet
154- * @return string
155159 */
156160 public function bulletedList (array |string $ items , string $ bullet = '• ' ): string
157161 {
158162 return $ this ->lines ($ this ->explode ($ items ), "{$ bullet } " );
159163 }
160164
161- public function codeBlock (string $ text ): string
162- {
163- return "``` \n{$ this ->escape ($ text )}\n``` " ;
164- }
165-
166165 /**
167166 * @param array<string>|string $items
168- * @return string
169167 */
170168 public function numberedList (array |string $ items ): string
171169 {
@@ -182,9 +180,6 @@ public function numberedList(array|string $items): string
182180 * Optionally applies a prefix to each line. You can use a closure if the prefix varies per line.
183181 *
184182 * @param array<string> $lines
185- * @param string|callable|null $prefix
186- * @param bool $filter
187- * @return string
188183 */
189184 public function lines (array $ lines , string |callable |null $ prefix = null , bool $ filter = true ): string
190185 {
@@ -194,10 +189,8 @@ public function lines(array $lines, string|callable|null $prefix = null, bool $f
194189 };
195190 }
196191
197- if (is_callable ($ prefix )) {
192+ if (! is_null ($ prefix )) {
198193 $ lines = array_map ($ prefix , $ lines );
199- } elseif (!is_null ($ prefix )) {
200- throw new Exception ('Formatter::lines given invalid prefix argument ' );
201194 }
202195
203196 if ($ filter ) {
@@ -208,17 +201,16 @@ public function lines(array $lines, string|callable|null $prefix = null, bool $f
208201
209202 return implode ("\n" , $ lines ) . "\n" ;
210203 }
211- // endregion
204+ # endregion
212205
213- // region Helpers for formatting dates and times.
206+ # region Helpers for formatting dates and times.
214207 /**
215208 * Formats a timestamp as a date in mrkdwn.
216209 *
217210 * @param int|null $timestamp Timestamp to format. Defaults to now.
218211 * @param string $format Format name supported by Slack. Defaults to "{date}".
219212 * @param string|null $fallback Fallback text for old Slack clients. Defaults to an ISO-formatted timestamp.
220213 * @param string|null $link URL, if the date is to act as a link.
221- * @return string
222214 * @see https://api.slack.com/reference/surfaces/formatting#date-formatting
223215 */
224216 public function date (
@@ -243,7 +235,6 @@ public function date(
243235 * @param string $format Format name supported by Slack. Defaults to "{time}".
244236 * @param string|null $fallback Fallback text for old Slack clients. Defaults to an ISO-formatted timestamp.
245237 * @param string|null $link URL, if the time is to act as a link.
246- * @return string
247238 */
248239 public function time (
249240 ?int $ timestamp = null ,
@@ -253,7 +244,7 @@ public function time(
253244 ): string {
254245 return $ this ->date ($ timestamp , $ format , $ fallback , $ link );
255246 }
256- // endregion
247+ # endregion
257248
258249 /**
259250 * Ensures the provided items are an array.
@@ -265,12 +256,10 @@ public function time(
265256 */
266257 private function explode (array |string $ items ): array
267258 {
268- if (is_string ($ items )) {
269- return explode ("\n" , $ items );
270- } elseif (is_array ($ items )) {
259+ if (is_array ($ items )) {
271260 return $ items ;
272261 }
273262
274- throw new Exception ( ' Formatter:: explode given invalid items argument ' );
263+ return explode ( "\n" , $ items );
275264 }
276265}
0 commit comments