morphos 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/usr/bin/env php
  2. <?php
  3. use morphos\Russian\GeographicalNamesInflection;
  4. use morphos\Russian\NounDeclension;
  5. use morphos\Russian\NounPluralization;
  6. use morphos\S;
  7. $paths = [
  8. // as a root package or phar
  9. __DIR__ . '/../vendor/autoload.php',
  10. // as a dependency from bin
  11. __DIR__ . '/../autoload.php',
  12. // as a dependency from package folder
  13. __DIR__ . '/../../../autoload.php',
  14. ];
  15. function init_composer(array $paths)
  16. {
  17. foreach ($paths as $path) {
  18. if (file_exists($path)) {
  19. require_once $path;
  20. return true;
  21. }
  22. }
  23. return false;
  24. }
  25. if (!init_composer($paths)) {
  26. die('Run `composer install` firstly.' . PHP_EOL);
  27. }
  28. function dump()
  29. {
  30. $dumper = function ($value, $level = 0, $verbose = true) use (&$dumper) {
  31. $output = null;
  32. if (is_array($value)) {
  33. $output .= str_repeat(' ', $level) . ' array(' . count($value) . '):' . PHP_EOL;
  34. $i = 0;
  35. foreach ($value as $key => $element) {
  36. if ($key === $i++) {
  37. $output .= str_repeat(' ', $level + 1) . $dumper($element, $level, false) . PHP_EOL;
  38. } else {
  39. $output .= str_repeat(' ', $level + 1) . '[' . $dumper($key, $level,
  40. false) . '] => ' . $dumper($element, $level, false) . PHP_EOL;
  41. }
  42. }
  43. } else {
  44. if (is_string($value)) {
  45. $output .= $verbose ? 'string(' . strlen($value) . '): "' . $value . '"' . PHP_EOL : '\'' . $value . '\'';
  46. }
  47. }
  48. return $output;
  49. };
  50. $output = null;
  51. foreach (func_get_args() as $var) {
  52. $output .= $dumper($var);
  53. }
  54. return $output;
  55. }
  56. class ConsoleLine
  57. {
  58. protected $readlineSupport;
  59. public function __construct()
  60. {
  61. $this->readlineSupport = /*strncasecmp(PHP_OS, 'win', 3) !== 0 && */
  62. extension_loaded('readline');
  63. }
  64. public function addLineForEmulation($line)
  65. {
  66. $this->emulation[] = $line;
  67. }
  68. public function addToHistory($command)
  69. {
  70. if ($this->readlineSupport) {
  71. readline_add_history($command);
  72. }
  73. }
  74. public function readLine($prompt)
  75. {
  76. if (!empty($this->emulation)) {
  77. return array_shift($this->emulation);
  78. }
  79. if ($this->readlineSupport) {
  80. return trim(readline($prompt));
  81. } else {
  82. fwrite(STDOUT, $prompt);
  83. return fgets(STDIN);
  84. }
  85. }
  86. }
  87. $line = new ConsoleLine();
  88. $language = 'ru';
  89. for ($i = 1; $i < $argc; $i++) {
  90. if ($i == 1 && in_array($argv[$i], ['ru', 'en'])) {
  91. $language = $argv[$i];
  92. continue;
  93. }
  94. $line->addLineForEmulation(trim($argv[$i]));
  95. }
  96. fwrite(STDOUT,
  97. 'Напишите слово / комбинацию Фамилия Имя [Отчество] для проверки склонения или ? для полной справки' . PHP_EOL);
  98. while (true) {
  99. $word = $line->readLine('> ');
  100. if (empty($word)) {
  101. continue;
  102. }
  103. if ($word === '?') {
  104. fwrite(STDOUT, 'Возможные входные параметры:
  105. - слово
  106. Должно быть существительным. Склоняет слово во всех падежах в единственном и множественном числах.
  107. - Слово
  108. Склонение географического названия.
  109. - Фамилия Имя
  110. - Фамилия Имя Отчество
  111. Порядок следования (сначала всегда идёт Фамилия) соблюдать обязательно! Склоняет имя во всех падежах.
  112. - 123
  113. Любое число. Генерирует порядковое и количественное числительные во всех падежах.
  114. - 123 знак
  115. Любое число и существительное. Генерирует количественное числительное с существительным в правильной форме во всех падежах.
  116. ');
  117. continue;
  118. }
  119. $line->addToHistory($word);
  120. // генерация числительных
  121. if (is_numeric($word)) {
  122. if ($language == 'ru') {
  123. $cardinal_numerals = morphos\Russian\CardinalNumeralGenerator::getCases($word);
  124. $ordinal_numerals = morphos\Russian\OrdinalNumeralGenerator::getCases($word);
  125. } else {
  126. if ($language == 'en') {
  127. $cardinal_numerals = morphos\English\CardinalNumeralGenerator::generate($word);
  128. $ordinal_numerals = morphos\English\OrdinalNumeralGenerator::generate($word) . ' (' . morphos\English\OrdinalNumeralGenerator::generate($word,
  129. true) . ')';
  130. }
  131. }
  132. fwrite(STDOUT, 'Числительное количественное: ' . dump($cardinal_numerals));
  133. fwrite(STDOUT, 'Числительное порядковое: ' . dump($ordinal_numerals));
  134. } else {
  135. if (substr_count($word, ' ') === 1 && (list($number, $noun) = explode(' ', $word)) && is_numeric($number)) {
  136. fwrite(STDOUT, 'Число с существительным: ' . dump(morphos\Russian\pluralize($number, $noun)));
  137. } else {
  138. if (strpos($word, ' ') === false) {
  139. // только одно слово
  140. $first_char = S::slice($word, 0, 1);
  141. // географическое название
  142. if ($first_char == S::upper($first_char)) {
  143. $names = GeographicalNamesInflection::getCases($word);
  144. fwrite(STDOUT, 'Географическое название: ' . dump($names));
  145. } // существительное
  146. else {
  147. $cases = NounDeclension::getCases($word);
  148. $plural_cases = NounPluralization::getCases($word);
  149. fwrite(STDOUT, 'Существительное в единственном числе: ' . dump($cases));
  150. fwrite(STDOUT, 'Существительное во множественном числе: ' . dump($plural_cases));
  151. }
  152. } // Фамилия Имя
  153. else {
  154. $gender = morphos\Russian\detectGender($word);
  155. $cases = morphos\Russian\inflectName($word);
  156. fwrite(STDOUT, 'Предполагаемый пол: ' . $gender . PHP_EOL);
  157. fwrite(STDOUT, 'Склонение: ' . dump($cases));
  158. }
  159. }
  160. }
  161. }