%]}{O('; public const NOSES = '*!&-#=>oO$<'; public const MOUTHS = ')(D|OoXxpP/\\*!{}#[$'; public const DEFAULT_COLOR = 10; /** The pictures of smiley.gif: 20 a row, 3 rows. */ public const IMAGES = 60; public const BIG_COUNT = 15; /** * Cuts a text into pieces: strings, and smileys as arrays. * * @return list */ public static function parse(string $text, int $images = self::IMAGES): array { $out = []; $plain = ''; $len = strlen($text); $i = 0; while ($i < $len) { $smiley = self::at($text, $i, $len, $images); if ($smiley === null) { $plain .= $text[$i]; $i++; continue; } if ($plain !== '') { $out[] = $plain; $plain = ''; } $out[] = $smiley; $i += strlen($smiley['source']); } if ($plain !== '') { $out[] = $plain; } return $out; } /** @return array{kind: string, eyes?: int, nose?: int, mouth?: int, hands?: int, color?: int, n?: int, source: string}|null */ private static function at(string $s, int $i, int $len, int $images): ?array { if ($len - $i < 3) { return null; } $e = strpos(self::EYES, $s[$i]); if ($e !== false) { $n = strpos(self::NOSES, $s[$i + 1]); $m = strpos(self::MOUTHS, $s[$i + 2]); if ($n === false || $m === false) { return null; } $extra = 0; $color = self::DEFAULT_COLOR; if ($len - $i >= 4 && ctype_digit($s[$i + 3])) { $color = (int)$s[$i + 3]; $extra = 1; } $hands = 0; if ($len - $i >= 5 + $extra && $s[$i + 3 + $extra] === '#' && in_array($s[$i + 4 + $extra], ['c', 'd'], true)) { $hands |= $s[$i + 4 + $extra] === 'd' ? 1 : 2; $extra += 2; if ($len - $i >= 4 + $extra && in_array($s[$i + 3 + $extra], ['c', 'd'], true)) { $hands |= $s[$i + 3 + $extra] === 'd' ? 4 : 8; $extra += 1; } } return ['kind' => 'face', 'eyes' => $e, 'nose' => $n, 'mouth' => $m, 'color' => $color, 'hands' => $hands, 'source' => substr($s, $i, 3 + $extra)]; } $c = $s[$i]; if (($c !== '#' && $c !== '@') || !ctype_digit(substr($s, $i + 1, 2))) { return null; } $nn = (int)substr($s, $i + 1, 2); if ($c === '#' && $nn < self::BIG_COUNT) { $color = in_array($nn, [13, 14], true) ? 1 : self::DEFAULT_COLOR; $length = 3; if (in_array($nn, [2, 4, 13, 14], true) && $len - $i >= 4 && ctype_digit($s[$i + 3])) { $color = (int)$s[$i + 3]; $length = 4; } return ['kind' => 'big', 'n' => $nn, 'color' => $color, 'source' => substr($s, $i, $length)]; } if ($c === '@' && $nn < $images) { return ['kind' => 'image', 'n' => $nn, 'source' => substr($s, $i, 3)]; } return null; } }