Fix depluralize.

This commit is contained in:
Valentin Lorentz 2011-01-22 10:28:27 +01:00
parent e122102e5a
commit e4cced8364

View File

@ -1,6 +1,7 @@
### ###
# Copyright (c) 2002-2005, Jeremiah Fincher # Copyright (c) 2002-2005, Jeremiah Fincher
# Copyright (c) 2008-2009, James Vega # Copyright (c) 2008-2009, James Vega
# Copyright (c) 2010, Valentin Lorentz
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -41,6 +42,9 @@ import textwrap
from iter import all, any from iter import all, any
from structures import TwoWayDictionary from structures import TwoWayDictionary
from supybot.i18n import PluginInternationalization
internationalizeFunction=PluginInternationalization().internationalizeFunction
curry = new.instancemethod curry = new.instancemethod
chars = string.maketrans('', '') chars = string.maketrans('', '')
@ -55,9 +59,14 @@ def rsplit(s, sep=None, maxsplit=-1):
else: else:
return s.rsplit(sep, maxsplit) return s.rsplit(sep, maxsplit)
def normalizeWhitespace(s): def normalizeWhitespace(s, removeNewline=True):
"""Normalizes the whitespace in a string; \s+ becomes one space.""" """Normalizes the whitespace in a string; \s+ becomes one space."""
return ' '.join(s.split()) s = str(s)
if removeNewline:
s = str.replace(s, '\n', '')
while ' ' in s:
s = str.replace(s, ' ', ' ')
return s
def distance(s, t): def distance(s, t):
"""Returns the levenshtein edit distance between two strings.""" """Returns the levenshtein edit distance between two strings."""
@ -252,12 +261,13 @@ def matchCase(s1, s2):
L[i] = L[i].upper() L[i] = L[i].upper()
return ''.join(L) return ''.join(L)
consonants = 'bcdfghjklmnpqrstvwxz' @internationalizeFunction('pluralize')
_pluralizeRegex = re.compile('[%s]y$' % consonants)
def pluralize(s): def pluralize(s):
"""Returns the plural of s. Put any exceptions to the general English """Returns the plural of s. Put any exceptions to the general English
rule of appending 's' in the plurals dictionary. rule of appending 's' in the plurals dictionary.
""" """
consonants = 'bcdfghjklmnpqrstvwxz'
_pluralizeRegex = re.compile('[%s]y$' % consonants)
lowered = s.lower() lowered = s.lower()
# Exception dictionary # Exception dictionary
if lowered in plurals: if lowered in plurals:
@ -274,9 +284,11 @@ def pluralize(s):
else: else:
return matchCase(s, s+'s') return matchCase(s, s+'s')
_depluralizeRegex = re.compile('[%s]ies' % consonants) @internationalizeFunction('depluralize')
def depluralize(s): def depluralize(s):
"""Returns the singular of s.""" """Returns the singular of s."""
consonants = 'bcdfghjklmnpqrstvwxz'
_depluralizeRegex = re.compile('[%s]ies' % consonants)
lowered = s.lower() lowered = s.lower()
if lowered in plurals: if lowered in plurals:
return matchCase(s, plurals[lowered]) return matchCase(s, plurals[lowered])
@ -293,17 +305,28 @@ def depluralize(s):
def nItems(n, item, between=None): def nItems(n, item, between=None):
"""Works like this: """Works like this:
>>> nItems(4, '<empty>')
'4'
>>> nItems(1, 'clock') >>> nItems(1, 'clock')
'1 clock' '1 clock'
>>> nItems(10, 'clock') >>> nItems(10, 'clock')
'10 clocks' '10 clocks'
>>> nItems(4, '<empty>', between='grandfather')
'4 grandfather'
>>> nItems(10, 'clock', between='grandfather') >>> nItems(10, 'clock', between='grandfather')
'10 grandfather clocks' '10 grandfather clocks'
""" """
assert isinstance(n, int) or isinstance(n, long), \ assert isinstance(n, int) or isinstance(n, long), \
'The order of the arguments to nItems changed again, sorry.' 'The order of the arguments to nItems changed again, sorry.'
if item == '<empty>':
if between is None:
return format('%s', n)
else:
return format('%s %s', n, item)
if between is None: if between is None:
if n != 1: if n != 1:
return format('%s %p', n, item) return format('%s %p', n, item)
@ -315,6 +338,7 @@ def nItems(n, item, between=None):
else: else:
return format('%s %s %s', n, between, item) return format('%s %s %s', n, between, item)
@internationalizeFunction('ordinal')
def ordinal(i): def ordinal(i):
"""Returns i + the ordinal indicator for the number. """Returns i + the ordinal indicator for the number.
@ -333,6 +357,7 @@ def ordinal(i):
ord = 'rd' ord = 'rd'
return '%s%s' % (i, ord) return '%s%s' % (i, ord)
@internationalizeFunction('be')
def be(i): def be(i):
"""Returns the form of the verb 'to be' based on the number i.""" """Returns the form of the verb 'to be' based on the number i."""
if i == 1: if i == 1:
@ -340,6 +365,7 @@ def be(i):
else: else:
return 'are' return 'are'
@internationalizeFunction('has')
def has(i): def has(i):
"""Returns the form of the verb 'to have' based on the number i.""" """Returns the form of the verb 'to have' based on the number i."""
if i == 1: if i == 1:
@ -362,7 +388,7 @@ def timestamp(t):
t = time.time() t = time.time()
return time.ctime(t) return time.ctime(t)
_formatRe = re.compile('%((?:\d+)?\.\d+f|[bfhiLnpqrstu%])') _formatRe = re.compile('%((?:\d+)?\.\d+f|[bfhiLnpqrsStuv%])')
def format(s, *args, **kwargs): def format(s, *args, **kwargs):
"""w00t. """w00t.
@ -377,8 +403,11 @@ def format(s, *args, **kwargs):
p: pluralize (takes a string) p: pluralize (takes a string)
q: quoted (takes a string) q: quoted (takes a string)
n: nItems (takes a 2-tuple of (n, item) or a 3-tuple of (n, between, item)) n: nItems (takes a 2-tuple of (n, item) or a 3-tuple of (n, between, item))
S: returns a human-readable size (takes an int)
t: time, formatted (takes an int) t: time, formatted (takes an int)
u: url, wrapped in braces (this should be configurable at some point) u: url, wrapped in braces (this should be configurable at some point)
v: void : takes one or many arguments, but doesn't display it
(useful for translation)
""" """
args = list(args) args = list(args)
args.reverse() # For more efficient popping. args.reverse() # For more efficient popping.
@ -425,10 +454,22 @@ def format(s, *args, **kwargs):
return nItems(t[0], t[2], between=t[1]) return nItems(t[0], t[2], between=t[1])
else: else:
raise ValueError, 'Invalid value for %%n in format: %s' % t raise ValueError, 'Invalid value for %%n in format: %s' % t
elif char == 'S':
t = args.pop()
if not isinstance(t, (int, long)):
raise ValueError, 'Invalid value for %%S in format: %s' % t
for suffix in ['B','KB','MB','GB','TB']:
if t < 1024:
return "%i%s" % (t, suffix)
t /= 1024
elif char == 't': elif char == 't':
return timestamp(args.pop()) return timestamp(args.pop())
elif char == 'u': elif char == 'u':
return '<%s>' % args.pop() return '<%s>' % args.pop()
elif char == 'v':
args.pop()
return ''
elif char == '%': elif char == '%':
return '%' return '%'
else: else: