. * * @author Daniil Gentili * @copyright 2016-2023 Daniil Gentili * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3 * @link https://docs.madelineproto.xyz MadelineProto documentation */ namespace danog\MadelineProto; use danog\MadelineProto\TL\Conversion\DOMEntities; use danog\MadelineProto\TL\Conversion\Extension; use Parsedown; use Webmozart\Assert\Assert; /** * Some tools. */ abstract class StrTools extends Extension { /** * Get Telegram UTF-8 length of string. * * @param string $text Text */ public static function mbStrlen(string $text): int { $length = 0; $textlength = \strlen($text); for ($x = 0; $x < $textlength; $x++) { $char = \ord($text[$x]); if (($char & 0xc0) != 0x80) { $length += 1 + ($char >= 0xf0 ? 1 : 0); } } return $length; } /** * Telegram UTF-8 multibyte substring. * * @param string $text Text to substring * @param integer $offset Offset * @param null|int $length Length */ public static function mbSubstr(string $text, int $offset, ?int $length = null): string { return \mb_convert_encoding( \substr( \mb_convert_encoding($text, 'UTF-16'), $offset<<1, $length === null ? null : ($length<<1), ), 'UTF-8', 'UTF-16', ); } /** * Telegram UTF-8 multibyte split. * * @param string $text Text * @param integer $length Length * @return array */ public static function mbStrSplit(string $text, int $length): array { $result = []; foreach (\str_split(\mb_convert_encoding($text, 'UTF-16'), $length<<1) as $chunk) { $chunk = \mb_convert_encoding($chunk, 'UTF-8', 'UTF-16'); Assert::string($chunk); $result []= $chunk; } return $result; } /** * Convert to camelCase. * * @param string $input String */ public static function toCamelCase(string $input): string { return \lcfirst(\str_replace('_', '', \ucwords($input, '_'))); } /** * Convert to snake_case. * * @param string $input String */ public static function toSnakeCase(string $input): string { \preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches); $ret = $matches[0]; foreach ($ret as &$match) { $match = $match == \strtoupper($match) ? \strtolower($match) : \lcfirst($match); } return \implode('_', $ret); } /** * Escape string for markdown. * * @param string $hwat String to escape */ public static function markdownEscape(string $hwat): string { return \str_replace('_', '\\_', $hwat); } /** * Escape type name. * * @param string $type String to escape */ public static function typeEscape(string $type): string { $type = \str_replace(['<', '>'], ['_of_', ''], $type); return \preg_replace('/.*_of_/', '', $type); } /** * Escape method name. * * @param string $method Method name */ public static function methodEscape(string $method): string { return \str_replace('.', '->', $method); } /** * Strip markdown tags. * * @internal */ public static function toString(string $markdown): string { if ($markdown === '') { return $markdown; } return (new DOMEntities(Parsedown::instance()->text($markdown)))->message; } }