Fixes #149
[akelos.git] / lib / AkInflexor.php
blobf4f588975c2ce354e3c92a70596ef2d2fa9d8f22
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
11 /**
12 * @package ActiveSupport
13 * @subpackage Inflector
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 require_once(AK_LIB_DIR.DS.'AkInflector.php');
21 /**
22 * Spanish Inflector
24 class AkInflexor extends AkInflector
27 function pluralize($word)
29 $plural = array(
30 '/([aeiou])x$/i'=> '\\1x', // This could fail if the word is oxytone.
31 '/([áéíóú])([ns])$/i'=> '|1\\2es',
32 '/(^[bcdfghjklmnñpqrstvwxyz]*)an$/i'=>'\\1anes', //clan->clanes
33 '/([áéíóú])s$/i'=> '|1ses',
34 '/(^[bcdfghjklmnñpqrstvwxyz]*)([aeiou])([ns])$/i'=>'\\1\\2\\3es', //tren->trenes
35 '/([aeiouáéó])$/i'=> '\\1s', // casa->casas, padre->padres, papá->papás
36 '/([aeiou])s$/i'=> '\\1s', // atlas->atlas, virus->virus, etc.
37 '/([éí])(s)$/i'=> '|1\\2es', // inglés->ingleses
38 '/z$/i'=> 'ces', // luz->luces
39 '/([íú])$/i' => '\\1es', // ceutí->ceutíes, tabú->tabúes
40 '/(ng|[wckgtp])$/'=>'\\1s', // Anglicismos como puenting, frac, crack, show (En que casos podría fallar esto?)
41 '/$/i'=> 'es', // ELSE +es (v.g. árbol->árboles)
42 ); // We should manage _orden_ -> _órdenes_, _joven_->_jóvenes_ and so.
44 $uncountable = array('tijeras','gafas', 'vacaciones','víveres','déficit');
45 /* In fact these words have no singular form: you cannot say neither
46 "una gafa" nor "un vívere". So we should change the variable name to
47 $onlyplural or something alike.*/
48 $irregular = array(
49 'país'=>'países',
50 'champú'=>'champús',
51 'jersey'=>'jerséis',
52 'carácter'=>'caracteres',
53 'espécimen'=>'especímenes',
54 'menú'=>'menús',
55 'régimen'=>'regímenes',
56 'curriculum' => 'currículos',
57 'ultimátum' => 'ultimatos',
58 'memorándum' => 'memorandos',
59 'referéndum' => 'referendos'
61 $lowercased_word = strtolower($word);
64 foreach ($uncountable as $_uncountable){
65 if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){
66 return $word;
70 foreach ($irregular as $_plural=> $_singular){
71 if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
72 return preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word);
76 foreach ($plural as $rule => $replacement) {
77 if (preg_match($rule, $word, $match)) {
78 if(strstr($replacement,'|')){
79 foreach ($match as $k=>$v){
80 $replacement = str_replace("|$k",strtr($v,'ÁÉÍÓÚáéíóú','AEIOUaeiou'), $replacement);
83 $result = preg_replace($rule, $replacement, $word);
84 // Esto acentua los sustantivos que al pluralizarse se convierten en esdrújulos como esmóquines, jóvenes...
85 if(preg_match('/([aeiou]).{1,3}[aeiou]nes$/i',$result,$match) && !preg_match('/[áéíóú]/i',$word)){
86 $result = str_replace($match[0], strtr($match[1],'AEIOUaeiou','ÁÉÍÓÚáéíóú').substr($match[0],1), $result);
88 return $result;
91 return false;
95 function singularize($word)
97 $singular = array (
98 '/^([bcdfghjklmnñpqrstvwxyz]*)([aeiou])([ns])es$/i'=> '\\1\\2\\3',
99 '/([aeiou])([ns])es$/i'=> '~1\\2',
100 '/oides$/i'=> 'oide', //androides->androide
101 '/(ces)$/i' => 'z',
102 '/(sis|tis|xis)+$/i'=> '\\1', //crisis, apendicitis, praxis
103 '/(é)s$/i'=> '\\1', // bebés->bebé
104 '/([^e])s$/i'=> '\\1', // casas->casa
105 '/([bcdfghjklmnñprstvwxyz]{2,}e)s$/i'=>'\\1', // cofres->cofre
106 '/([ghñpv]e)s$/i'=>'\\1', // 24-01 llaves->llave
107 '/es$/i'=>'', // ELSE remove _es_ monitores->monitor
111 $uncountable = array('paraguas','tijeras','gafas', 'vacaciones','víveres','lunes','martes','miércoles','jueves','viernes','cumpleaños','virus','atlas','sms');
112 $irregular = array(
113 'jersey'=>'jerséis',
114 'espécimen'=>'especímenes',
115 'carácter'=>'caracteres',
116 'régimen'=>'regímenes',
117 'menú'=>'menús',
118 'régimen'=>'regímenes',
119 'curriculum' => 'currículos',
120 'ultimátum' => 'ultimatos',
121 'memorándum' => 'memorandos',
122 'referéndum' => 'referendos',
123 'sándwich' => 'sándwiches'
126 $lowercased_word = strtolower($word);
127 foreach ($uncountable as $_uncountable){
128 if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){
129 return $word;
133 foreach ($irregular as $_plural=> $_singular){
134 if (preg_match('/('.$_singular.')$/i', $word, $arr)) {
135 return preg_replace('/('.$_singular.')$/i', substr($arr[0],0,1).substr($_plural,1), $word);
139 foreach ($singular as $rule => $replacement) {
140 if (preg_match($rule, $word, $match)) {
141 if(strstr($replacement,'~')){
142 foreach ($match as $k=>$v){
143 $replacement = str_replace("~$k",strtr($v,'AEIOUaeiou','ÁÉÍÓÚáéíóú'), $replacement);
147 $result = preg_replace($rule, $replacement, $word);
148 // Esta es una posible solución para el problema de dobles acentos. Un poco sucio pero funciona
149 $result = preg_match('/([áéíóú]).*([áéíóú])/',$result) ? strtr($result,'ÁÉÍÓÚáéíóú','AEIOUaeiou') : $result;
151 return $result;
155 return $word;