Last active
October 24, 2020 00:50
-
-
Save bryangreen/6377733 to your computer and use it in GitHub Desktop.
Twig Inflector Extension - For plural and singular English words
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* ReadySetData 2009-2013 | |
* This program is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU General Public License | |
* as published by the Free Software Foundation; either version 2 | |
* of the License, or (at your option) any later version. | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
* User: Bryan Green | |
* Date: 2/14/13 | |
* Time: 2:10 AM | |
*/ | |
// Thanks to http://www.eval.ca/articles/php-pluralize (MIT license) | |
// http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/inflections.rb (MIT license) | |
// http://www.fortunecity.com/bally/durrus/153/gramch13.html | |
// http://www2.gsu.edu/~wwwesl/egw/crump.htm | |
// | |
// Changes (2013-02-14) - by: Bryan Green | |
// Formatted code | |
// Added "software" to uncountable list | |
// | |
// Changes (12/17/07) | |
// Major changes | |
// -- | |
// Fixed irregular noun algorithm to use regular expressions just like the original Ruby source. | |
// (this allows for things like fireman -> firemen | |
// Fixed the order of the singular array, which was backwards. | |
// | |
// Minor changes | |
// -- | |
// Removed incorrect pluralization rule for /([^aeiouy]|qu)ies$/ => $1y | |
// Expanded on the list of exceptions for *o -> *oes, and removed rule for buffalo -> buffaloes | |
// Removed dangerous singularization rule for /([^f])ves$/ => $1fe | |
// Added more specific rules for singularizing lives, wives, knives, sheaves, loaves, and leaves and thieves | |
// Added exception to /(us)es$/ => $1 rule for houses => house and blouses => blouse | |
// Added excpetions for feet, geese and teeth | |
// Added rule for deer -> deer | |
// Changes: | |
// Removed rule for virus -> viri | |
// Added rule for potato -> potatoes | |
// Added rule for *us -> *uses | |
class Inflect | |
{ | |
static $plural = array( | |
'/(quiz)$/i' => "$1zes", | |
'/^(ox)$/i' => "$1en", | |
'/([m|l])ouse$/i' => "$1ice", | |
'/(matr|vert|ind)ix|ex$/i' => "$1ices", | |
'/(x|ch|ss|sh)$/i' => "$1es", | |
'/([^aeiouy]|qu)y$/i' => "$1ies", | |
'/(hive)$/i' => "$1s", | |
'/(?:([^f])fe|([lr])f)$/i' => "$1$2ves", | |
'/(shea|lea|loa|thie)f$/i' => "$1ves", | |
'/sis$/i' => "ses", | |
'/([ti])um$/i' => "$1a", | |
'/(tomat|potat|ech|her|vet)o$/i' => "$1oes", | |
'/(bu)s$/i' => "$1ses", | |
'/(alias)$/i' => "$1es", | |
'/(octop)us$/i' => "$1i", | |
'/(ax|test)is$/i' => "$1es", | |
'/(us)$/i' => "$1es", | |
'/s$/i' => "s", | |
'/$/' => "s" | |
); | |
static $singular = array( | |
'/(quiz)zes$/i' => "$1", | |
'/(matr)ices$/i' => "$1ix", | |
'/(vert|ind)ices$/i' => "$1ex", | |
'/^(ox)en$/i' => "$1", | |
'/(alias)es$/i' => "$1", | |
'/(octop|vir)i$/i' => "$1us", | |
'/(cris|ax|test)es$/i' => "$1is", | |
'/(shoe)s$/i' => "$1", | |
'/(o)es$/i' => "$1", | |
'/(bus)es$/i' => "$1", | |
'/([m|l])ice$/i' => "$1ouse", | |
'/(x|ch|ss|sh)es$/i' => "$1", | |
'/(m)ovies$/i' => "$1ovie", | |
'/(s)eries$/i' => "$1eries", | |
'/([^aeiouy]|qu)ies$/i' => "$1y", | |
'/([lr])ves$/i' => "$1f", | |
'/(tive)s$/i' => "$1", | |
'/(hive)s$/i' => "$1", | |
'/(li|wi|kni)ves$/i' => "$1fe", | |
'/(shea|loa|lea|thie)ves$/i' => "$1f", | |
'/(^analy)ses$/i' => "$1sis", | |
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis", | |
'/([ti])a$/i' => "$1um", | |
'/(n)ews$/i' => "$1ews", | |
'/(h|bl)ouses$/i' => "$1ouse", | |
'/(corpse)s$/i' => "$1", | |
'/(us)es$/i' => "$1", | |
'/s$/i' => "" | |
); | |
static $irregular = array( | |
'move' => 'moves', | |
'foot' => 'feet', | |
'goose' => 'geese', | |
'sex' => 'sexes', | |
'child' => 'children', | |
'man' => 'men', | |
'tooth' => 'teeth', | |
'person' => 'people' | |
); | |
static $uncountable = array( | |
'sheep', | |
'fish', | |
'deer', | |
'series', | |
'species', | |
'money', | |
'rice', | |
'information', | |
'equipment', | |
'software', | |
'now' | |
); | |
public static function pluralize($string) | |
{ | |
// save some time in the case that singular and plural are the same | |
if (in_array(strtolower($string), self::$uncountable)) | |
return $string; | |
// check for irregular singular forms | |
foreach (self::$irregular as $pattern => $result) { | |
$pattern = '/' . $pattern . '$/i'; | |
if (preg_match($pattern, $string)) | |
return preg_replace($pattern, $result, $string); | |
} | |
// check for matches using regular expressions | |
foreach (self::$plural as $pattern => $result) { | |
if (preg_match($pattern, $string)) | |
return preg_replace($pattern, $result, $string); | |
} | |
return $string; | |
} | |
public static function singularize($string) | |
{ | |
// save some time in the case that singular and plural are the same | |
if (in_array(strtolower($string), self::$uncountable)) | |
return $string; | |
// check for irregular plural forms | |
foreach (self::$irregular as $result => $pattern) { | |
$pattern = '/' . $pattern . '$/i'; | |
if (preg_match($pattern, $string)) | |
return preg_replace($pattern, $result, $string); | |
} | |
// check for matches using regular expressions | |
foreach (self::$singular as $pattern => $result) { | |
if (preg_match($pattern, $string)) | |
return preg_replace($pattern, $result, $string); | |
} | |
return $string; | |
} | |
public static function pluralize_if($count, $string) | |
{ | |
if ($count == 1) | |
return "1 $string"; | |
else | |
return $count . " " . self::pluralize($string); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include_once('./utils/Inflector.php'); | |
/** | |
* Class Twig_Extension_Inflector | |
*/ | |
class Twig_Extension_Inflector extends Twig_Extension | |
{ | |
const PLURALIZE = 'pluralize'; | |
const SINGULARIZE = 'singularize'; | |
public function getName() | |
{ | |
return self::PLURALIZE; | |
} | |
public function getFilters() | |
{ | |
return array( | |
self::PLURALIZE => new \Twig_Filter_Method($this, self::PLURALIZE, array( | |
'pre_escape' => 'html', | |
'is_safe' => array('all') | |
)), | |
self::SINGULARIZE => new \Twig_Filter_Method($this, self::SINGULARIZE, array( | |
'pre_escape' => 'html', | |
'is_safe' => array('all') | |
)) | |
); | |
} | |
/** | |
* Converts a word into its plural form | |
* | |
* @param $text | |
* @param null $count | |
* | |
* @return string | |
*/ | |
public function pluralize($text, $count = null) | |
{ | |
$handback = $text; | |
if (!empty($text)) { | |
if (is_numeric($count)) { | |
$handback = Inflect::pluralize_if($count, $text); | |
} else { | |
$handback = Inflect::pluralize($text); | |
} | |
} | |
return $handback; | |
} | |
/** | |
* Converts a word into its singular form | |
* | |
* @param $text | |
* | |
* @return string | |
*/ | |
public function singularize($text) | |
{ | |
$handback = $text; | |
if (!empty($text)) { | |
$handback = Inflect::singularize($text); | |
} | |
return $handback; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is amazing, thanks a lot!