Numbers_Words
[ class tree: Numbers_Words ] [ index: Numbers_Words ] [ all elements ]

Source for file lang.bg.php

Documentation is available at lang.bg.php

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

Documentation generated on Mon, 11 Mar 2019 13:56:07 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.