diff options
Diffstat (limited to 'engine/strings.php')
-rw-r--r-- | engine/strings.php | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/engine/strings.php b/engine/strings.php new file mode 100644 index 0000000..2d9b1d3 --- /dev/null +++ b/engine/strings.php @@ -0,0 +1,138 @@ +<?php + +enum DeclensionCase: string { + case GEN = 'Gen'; + case DAT = 'Dat'; + case ACC = 'Acc'; + case INS = 'Ins'; + case ABL = 'Abl'; +} + +enum NameSex: int { + case MALE = 0; + case FEMALE = 1; +} + +enum NameType: int { + case FIRST_NAME = 0; + case LAST_NAME = 1; +} + +class StringsBase implements ArrayAccess { + protected array $data = []; + + function offsetSet(mixed $offset, mixed $value): void { + throw new RuntimeException('Not implemented'); + } + + function offsetExists(mixed $offset): bool { + return isset($this->data[$offset]); + } + + function offsetUnset(mixed $offset): void { + throw new RuntimeException('Not implemented'); + } + + function offsetGet(mixed $offset): mixed { + if (!isset($this->data[$offset])) { + logError(__METHOD__.': '.$offset.' not found'); + return '{'.$offset.'}'; + } + return $this->data[$offset]; + } + + function get(string $key, mixed ...$sprintf_args): string|array { + $val = $this[$key]; + if (!empty($sprintf_args)) { + array_unshift($sprintf_args, $val); + return call_user_func_array('sprintf', $sprintf_args); + } else { + return $val; + } + } + + function num(string $key, int $num, array$opts = []) { + $s = $this[$key]; + + $default_opts = [ + 'format' => true, + 'format_delim' => ' ', + 'lang' => 'ru', + ]; + $opts = array_merge($default_opts, $opts); + + switch ($opts['lang']) { + case 'ru': + $n = $num % 100; + if ($n > 19) + $n %= 10; + + if ($n == 1) { + $word = 0; + } elseif ($n >= 2 && $n <= 4) { + $word = 1; + } elseif ($num == 0 && count($s) == 4) { + $word = 3; + } else { + $word = 2; + } + break; + + default: + if ($num == 0 && count($s) == 4) { + $word = 3; + } else { + $word = $num == 1 ? 0 : 1; + } + break; + } + + // if zero + if ($word == 3) { + return $s[3]; + } + + if (is_callable($opts['format'])) { + $num = $opts['format']($num); + } else if ($opts['format'] === true) { + $num = formatNumber($num, $opts['format_delim']); + } + + return sprintf($s[$word], $num); + } +} + +class Strings extends StringsBase { + private static ?Strings $instance = null; + protected array $loadedPackages = []; + + private function __construct() {} + protected function __clone() {} + + public static function getInstance(): self { + if (is_null(self::$instance)) + self::$instance = new self(); + return self::$instance; + } + + function load(string ...$pkgs): array { + $keys = []; + foreach ($pkgs as $name) { + $raw = yaml_parse_file(APP_ROOT.'/strings/'.$name.'.yaml'); + $this->data = array_merge($this->data, $raw); + $keys = array_merge($keys, array_keys($raw)); + $this->loadedPackages[$name] = true; + } + return $keys; + } + + function flex(string $s, DeclensionCase $case, NameSex $sex, NameType $type): string { + $s = iconv('utf-8', 'cp1251', $s); + $s = vkflex($s, $case->value, $sex->value, 0, $type->value); + return iconv('cp1251', 'utf-8', $s); + } + + function search(string $regexp): array { + return preg_grep($regexp, array_keys($this->data)); + } +}
\ No newline at end of file |