PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/php-pear-Numbers-Words-0.16.4/Numbers_Words-0.16.4/Numbers/Words/lang.bg.php

#
PHP | 520 lines | 266 code | 52 blank | 202 comment | 39 complexity | afc2b54ada583a5e403c29e1bfa5e460 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Numbers_Words
  4. *
  5. * PHP version 4
  6. *
  7. * Copyright (c) 1997-2006 The PHP Group
  8. *
  9. * This source file is subject to version 3.01 of the PHP license,
  10. * that is bundled with this package in the file LICENSE, and is
  11. * available at through the world-wide-web at
  12. * http://www.php.net/license/3_01.txt
  13. * If you did not receive a copy of the PHP license and are unable to
  14. * obtain it through the world-wide-web, please send a note to
  15. * license@php.net so we can mail you a copy immediately.
  16. *
  17. * @category Numbers
  18. * @package Numbers_Words
  19. * @author Kouber Saparev <kouber@php.net>
  20. * @license PHP 3.01 http://www.php.net/license/3_01.txt
  21. * @version SVN: $Id$
  22. * @link http://pear.php.net/package/Numbers_Words
  23. */
  24. /**
  25. * Include needed files
  26. */
  27. require_once "Numbers/Words.php";
  28. /**
  29. * Class for translating numbers into Bulgarian.
  30. *
  31. * @category Numbers
  32. * @package Numbers_Words
  33. * @author Kouber Saparev <kouber@php.net>
  34. * @license PHP 3.01 http://www.php.net/license/3_01.txt
  35. * @link http://pear.php.net/package/Numbers_Words
  36. */
  37. class Numbers_Words_bg extends Numbers_Words
  38. {
  39. // {{{ properties
  40. /**
  41. * Locale name.
  42. * @var string
  43. * @access public
  44. */
  45. var $locale = 'bg';
  46. /**
  47. * Language name in English.
  48. * @var string
  49. * @access public
  50. */
  51. var $lang = 'Bulgarian';
  52. /**
  53. * Native language name.
  54. * @var string
  55. * @access public
  56. */
  57. var $lang_native = '?????????';
  58. /**
  59. * Some miscellaneous words and language constructs.
  60. * @var string
  61. * @access private
  62. */
  63. var $_misc_strings = array(
  64. 'deset'=>'?????', // "ten"
  65. 'edinadeset'=>'??????????', // "eleven"
  66. 'na'=>'??', // liaison particle for 12 to 19
  67. 'sto'=>'???', // "hundred"
  68. 'sta'=>'???', // suffix for 2 and 3 hundred
  69. 'stotin'=>'??????', // suffix for 4 to 9 hundred
  70. 'hiliadi'=>'??????' // plural form of "thousand"
  71. );
  72. /**
  73. * The words for digits (except zero). Note that, there are three genders for them (neuter, masculine and feminine).
  74. * The words for 3 to 9 (masculine) and for 2 to 9 (feminine) are the same as neuter, so they're filled
  75. * in the _initDigits() method, which is invoked from the constructor.
  76. * @var string
  77. * @access private
  78. */
  79. var $_digits = array(
  80. 0=>array(1=>"????", "???", "???", "??????", "???", "????", "?????", "????", "?????"), // neuter
  81. 1=>array(1=>'????', '???'), // masculine
  82. -1=>array(1=>'????') // feminine
  83. );
  84. /**
  85. * A flag, that determines if the _digits array is filled for masculine and feminine genders.
  86. * @var string
  87. * @access private
  88. */
  89. var $_digits_initialized = false;
  90. /**
  91. * A flag, that determines if the "and" word is placed already before the last non-empty group of digits.
  92. * @var string
  93. * @access private
  94. */
  95. var $_last_and = false;
  96. /**
  97. * The word for zero.
  98. * @var string
  99. * @access private
  100. */
  101. var $_zero = '????';
  102. /**
  103. * The word for infinity.
  104. * @var string
  105. * @access private
  106. */
  107. var $_infinity = '???????????';
  108. /**
  109. * The word for the "and" language construct.
  110. * @var string
  111. * @access private
  112. */
  113. var $_and = '?';
  114. /**
  115. * The word separator.
  116. * @var string
  117. * @access private
  118. */
  119. var $_sep = ' ';
  120. /**
  121. * The word for the minus sign.
  122. * @var string
  123. * @access private
  124. */
  125. var $_minus = '?????'; // minus sign
  126. /**
  127. * The plural suffix (except for thousand).
  128. * @var string
  129. * @access private
  130. */
  131. var $_plural = '?'; // plural suffix
  132. /**
  133. * The suffixes for exponents (singular).
  134. * @var array
  135. * @access private
  136. */
  137. var $_exponent = array(
  138. 0 => '',
  139. 3 => '??????',
  140. 6 => '??????',
  141. 9 => '???????',
  142. 12 => '???????',
  143. 15 => '??????????',
  144. 18 => '??????????',
  145. 21 => '??????????',
  146. 24 => '?????????',
  147. 27 => '????????',
  148. 30 => '????????',
  149. 33 => '????????',
  150. 36 => '??????????',
  151. 39 => '???????????',
  152. 42 => '???????????',
  153. 45 => '??????????????',
  154. 48 => '?????????????',
  155. 51 => '????????????',
  156. 54 => '????????????',
  157. 57 => '????????????',
  158. 60 => '?????????????',
  159. 63 => '???????????',
  160. 66 => '?????????????',
  161. 69 => '??????????????',
  162. 72 => '??????????????',
  163. 75 => '?????????????????',
  164. 78 => '???????????????',
  165. 81 => '???????????????',
  166. 84 => '?????????????????',
  167. 87 => '???????????????',
  168. 90 => '????????????????',
  169. 93 => '????????????',
  170. 96 => '??????????????',
  171. 99 => '???????????????',
  172. 102 => '???????????????',
  173. 105 => '??????????????????',
  174. 108 => '????????????????',
  175. 111 => '????????????????',
  176. 114 => '??????????????????',
  177. 117 => '????????????????',
  178. 120 => '?????????????????',
  179. 123 => '???????????????',
  180. 126 => '?????????????????',
  181. 129 => '??????????????????',
  182. 132 => '??????????????????',
  183. 135 => '?????????????????????',
  184. 138 => '???????????????????',
  185. 141 => '???????????????????',
  186. 144 => '?????????????????????',
  187. 147 => '???????????????????',
  188. 150 => '????????????????????',
  189. 153 => '????????????????',
  190. 156 => '?????????????????',
  191. 159 => '??????????????????',
  192. 162 => '??????????????????',
  193. 165 => '?????????????????????',
  194. 168 => '???????????????????',
  195. 171 => '???????????????????',
  196. 174 => '?????????????????????',
  197. 177 => '???????????????????',
  198. 180 => '????????????????????',
  199. 183 => '??????????????',
  200. 186 => '????????????????',
  201. 189 => '?????????????????',
  202. 192 => '?????????????????',
  203. 195 => '????????????????????',
  204. 198 => '??????????????????',
  205. 201 => '??????????????????',
  206. 204 => '????????????????????',
  207. 207 => '??????????????????',
  208. 210 => '???????????????????',
  209. 213 => '??????????????',
  210. 216 => '????????????????',
  211. 219 => '?????????????????',
  212. 222 => '?????????????????',
  213. 225 => '????????????????????',
  214. 228 => '??????????????????',
  215. 231 => '??????????????????',
  216. 234 => '????????????????????',
  217. 237 => '??????????????????',
  218. 240 => '???????????????????',
  219. 243 => '?????????????',
  220. 246 => '???????????????',
  221. 249 => '????????????????',
  222. 252 => '????????????????',
  223. 255 => '???????????????????',
  224. 258 => '?????????????????',
  225. 261 => '?????????????????',
  226. 264 => '?????????????????',
  227. 267 => '?????????????????',
  228. 270 => '??????????????????',
  229. 273 => '?????????????',
  230. 276 => '???????????????',
  231. 279 => '????????????????',
  232. 282 => '????????????????',
  233. 285 => '???????????????????',
  234. 288 => '?????????????????',
  235. 291 => '?????????????????',
  236. 294 => '???????????????????',
  237. 297 => '?????????????????',
  238. 300 => '??????????????????',
  239. 303 => '?????????'
  240. );
  241. // }}}
  242. // {{{ Numbers_Words_bg()
  243. /**
  244. * The class constructor, used for calling the _initDigits method.
  245. *
  246. * @return void
  247. *
  248. * @access public
  249. * @author Kouber Saparev <kouber@php.net>
  250. * @see function _initDigits
  251. */
  252. function Numbers_Words_bg()
  253. {
  254. $this->_initDigits();
  255. }
  256. // }}}
  257. // {{{ _initDigits()
  258. /**
  259. * Fills the _digits array for masculine and feminine genders with
  260. * corresponding references to neuter words (when they're the same).
  261. *
  262. * @return void
  263. *
  264. * @access private
  265. * @author Kouber Saparev <kouber@php.net>
  266. */
  267. function _initDigits()
  268. {
  269. if (!$this->_digits_initialized) {
  270. for ($i=3; $i<=9; $i++) {
  271. $this->_digits[1][$i] =& $this->_digits[0][$i];
  272. }
  273. for ($i=2; $i<=9; $i++) {
  274. $this->_digits[-1][$i] =& $this->_digits[0][$i];
  275. }
  276. $this->_digits_initialized = true;
  277. }
  278. }
  279. // }}}
  280. // {{{ _splitNumber()
  281. /**
  282. * Split a number to groups of three-digit numbers.
  283. *
  284. * @param mixed $num An integer or its string representation
  285. * that need to be split
  286. *
  287. * @return array Groups of three-digit numbers.
  288. *
  289. * @access private
  290. * @author Kouber Saparev <kouber@php.net>
  291. * @since PHP 4.2.3
  292. */
  293. function _splitNumber($num)
  294. {
  295. if (is_string($num)) {
  296. $ret = array();
  297. $strlen = strlen($num);
  298. $first = substr($num, 0, $strlen%3);
  299. preg_match_all('/\d{3}/', substr($num, $strlen%3, $strlen), $m);
  300. $ret =& $m[0];
  301. if ($first) {
  302. array_unshift($ret, $first);
  303. }
  304. return $ret;
  305. }
  306. return explode(' ', number_format($num, 0, '', ' ')); // a faster version for integers
  307. }
  308. // }}}
  309. // {{{ _showDigitsGroup()
  310. /**
  311. * Converts a three-digit number to its word representation
  312. * in Bulgarian language.
  313. *
  314. * @param integer $num An integer between 1 and 999 inclusive.
  315. * @param integer $gender An integer which represents the gender of
  316. * the current digits group.
  317. * 0 - neuter
  318. * 1 - masculine
  319. * -1 - feminine
  320. * @param boolean $last A flag that determines if the current digits group
  321. * is the last one.
  322. *
  323. * @return string The words for the given number.
  324. *
  325. * @access private
  326. * @author Kouber Saparev <kouber@php.net>
  327. */
  328. function _showDigitsGroup($num, $gender = 0, $last = false)
  329. {
  330. /* A storage array for the return string.
  331. Positions 1, 3, 5 are intended for digit words
  332. and everything else (0, 2, 4) for "and" words.
  333. Both of the above types are optional, so the size of
  334. the array may vary.
  335. */
  336. $ret = array();
  337. // extract the value of each digit from the three-digit number
  338. $e = $num%10; // ones
  339. $d = ($num-$e)%100/10; // tens
  340. $s = ($num-$d*10-$e)%1000/100; // hundreds
  341. // process the "hundreds" digit.
  342. if ($s) {
  343. switch ($s) {
  344. case 1:
  345. $ret[1] = $this->_misc_strings['sto'];
  346. break;
  347. case 2:
  348. case 3:
  349. $ret[1] = $this->_digits[0][$s].$this->_misc_strings['sta'];
  350. break;
  351. default:
  352. $ret[1] = $this->_digits[0][$s].$this->_misc_strings['stotin'];
  353. }
  354. }
  355. // process the "tens" digit, and optionally the "ones" digit.
  356. if ($d) {
  357. // in the case of 1, the "ones" digit also must be processed
  358. if ($d==1) {
  359. if (!$e) {
  360. $ret[3] = $this->_misc_strings['deset']; // ten
  361. } else {
  362. if ($e==1) {
  363. $ret[3] = $this->_misc_strings['edinadeset']; // eleven
  364. } else {
  365. $ret[3] = $this->_digits[1][$e].$this->_misc_strings['na'].$this->_misc_strings['deset']; // twelve - nineteen
  366. }
  367. // the "ones" digit is alredy processed, so skip a second processment
  368. $e = 0;
  369. }
  370. } else {
  371. $ret[3] = $this->_digits[1][$d].$this->_misc_strings['deset']; // twenty - ninety
  372. }
  373. }
  374. // process the "ones" digit
  375. if ($e) {
  376. $ret[5] = $this->_digits[$gender][$e];
  377. }
  378. // put "and" where needed
  379. if (count($ret)>1) {
  380. if ($e) {
  381. $ret[4] = $this->_and;
  382. } else {
  383. $ret[2] = $this->_and;
  384. }
  385. }
  386. // put "and" optionally in the case this is the last non-empty group
  387. if ($last) {
  388. if (!$s||count($ret)==1) {
  389. $ret[0] = $this->_and;
  390. }
  391. $this->_last_and = true;
  392. }
  393. // sort the return array so that "and" constructs go to theirs appropriate places
  394. ksort($ret);
  395. return implode($this->_sep, $ret);
  396. }
  397. // }}}
  398. // {{{ _toWords()
  399. /**
  400. * Converts a number to its word representation
  401. * in Bulgarian language.
  402. *
  403. * @param integer $num An integer between 9.99*-10^302 and 9.99*10^302 (999 centillions)
  404. * that need to be converted to words
  405. *
  406. * @return string The corresponding word representation
  407. *
  408. * @access protected
  409. * @author Kouber Saparev <kouber@php.net>
  410. * @since Numbers_Words 0.16.3
  411. */
  412. function _toWords($num = 0)
  413. {
  414. $ret = array();
  415. $ret_minus = '';
  416. // check if $num is a valid non-zero number
  417. if (!$num || preg_match('/^-?0+$/', $num) || !preg_match('/^-?\d+$/', $num)) {
  418. return $this->_zero;
  419. }
  420. // add a minus sign
  421. if (substr($num, 0, 1) == '-') {
  422. $ret_minus = $this->_minus . $this->_sep;
  423. $num = substr($num, 1);
  424. }
  425. // if the absolute value is greater than 9.99*10^302, return infinity
  426. if (strlen($num) > 306) {
  427. return $ret_minus . $this->_infinity;
  428. }
  429. // strip excessive zero signs
  430. $num = ltrim($num, '0');
  431. // split $num to groups of three-digit numbers
  432. $num_groups = $this->_splitNumber($num);
  433. $sizeof_numgroups = count($num_groups);
  434. // go through the groups in reverse order, so that the last group could be determined
  435. for ($i=$sizeof_numgroups-1, $j=1; $i>=0; $i--, $j++) {
  436. if (!isset($ret[$j])) {
  437. $ret[$j] = '';
  438. }
  439. // what is the corresponding exponent for the current group
  440. $pow = $sizeof_numgroups-$i;
  441. // skip processment for empty groups
  442. if ($num_groups[$i]!='000') {
  443. if ($num_groups[$i]>1) {
  444. if ($pow==1) {
  445. $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], 0, !$this->_last_and && $i).$this->_sep;
  446. $ret[$j] .= $this->_exponent[($pow-1)*3];
  447. } elseif ($pow==2) {
  448. $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], -1, !$this->_last_and && $i).$this->_sep;
  449. $ret[$j] .= $this->_misc_strings['hiliadi'].$this->_sep;
  450. } else {
  451. $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], 1, !$this->_last_and && $i).$this->_sep;
  452. $ret[$j] .= $this->_exponent[($pow-1)*3].$this->_plural.$this->_sep;
  453. }
  454. } else {
  455. if ($pow==1) {
  456. $ret[$j] .= $this->_showDigitsGroup($num_groups[$i], 0, !$this->_last_and && $i).$this->_sep;
  457. } elseif ($pow==2) {
  458. $ret[$j] .= $this->_exponent[($pow-1)*3].$this->_sep;
  459. } else {
  460. $ret[$j] .= $this->_digits[1][1].$this->_sep.$this->_exponent[($pow-1)*3].$this->_sep;
  461. }
  462. }
  463. }
  464. }
  465. return $ret_minus . rtrim(implode('', array_reverse($ret)), $this->_sep);
  466. }
  467. // }}}
  468. }