comparison planemo/lib/python3.7/site-packages/galaxy/util/inflection.py @ 1:56ad4e20f292 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:32:28 -0400
parents
children
comparison
equal deleted inserted replaced
0:d30785e31577 1:56ad4e20f292
1 #!/usr/bin/env python
2
3 # Copyright (c) 2006 Bermi Ferrer Martinez
4 #
5 # bermi a-t bermilabs - com
6 # See the end of this file for the free software, open source license (BSD-style).
7
8 import re
9
10
11 class Base(object):
12 '''Locale inflectors must inherit from this base class inorder to provide
13 the basic Inflector functionality'''
14
15 def cond_plural(self, number_of_records, word):
16 '''Returns the plural form of a word if first parameter is greater than 1'''
17
18 if number_of_records != 1:
19 return self.pluralize(word)
20 else:
21 return word
22
23 def titleize(self, word, uppercase=''):
24 '''Converts an underscored or CamelCase word into a English sentence.
25 The titleize function converts text like "WelcomePage",
26 "welcome_page" or "welcome page" to this "Welcome Page".
27 If second parameter is set to 'first' it will only
28 capitalize the first character of the title.'''
29
30 if(uppercase == 'first'):
31 return self.humanize(self.underscore(word)).capitalize()
32 else:
33 return self.humanize(self.underscore(word)).title()
34
35 def camelize(self, word):
36 ''' Returns given word as CamelCased
37 Converts a word like "send_email" to "SendEmail". It
38 will remove non alphanumeric character from the word, so
39 "who's online" will be converted to "WhoSOnline"'''
40 return ''.join(w[0].upper() + w[1:] for w in re.sub('[^A-Z^a-z^0-9^:]+', ' ', word).split(' '))
41
42 def underscore(self, word):
43 ''' Converts a word "into_it_s_underscored_version"
44 Convert any "CamelCased" or "ordinary Word" into an
45 "underscored_word".
46 This can be really useful for creating friendly URLs.'''
47
48 return re.sub(r'[^A-Z^a-z^0-9^\/]+', r'_',
49 re.sub(r'([a-z\d])([A-Z])', r'\1_\2',
50 re.sub(r'([A-Z]+)([A-Z][a-z])', r'\1_\2', re.sub(r'::', r'/', word)))).lower()
51
52 def humanize(self, word, uppercase=''):
53 '''Returns a human-readable string from word
54 Returns a human-readable string from word, by replacing
55 underscores with a space, and by upper-casing the initial
56 character by default.
57 If you need to uppercase all the words you just have to
58 pass 'all' as a second parameter.'''
59
60 if(uppercase == 'first'):
61 return re.sub('_id$', '', word).replace('_', ' ').capitalize()
62 else:
63 return re.sub('_id$', '', word).replace('_', ' ').title()
64
65 def variablize(self, word):
66 '''Same as camelize but first char is lowercased
67 Converts a word like "send_email" to "sendEmail". It
68 will remove non alphanumeric character from the word, so
69 "who's online" will be converted to "whoSOnline"'''
70 word = self.camelize(word)
71 return word[0].lower() + word[1:]
72
73 def tableize(self, class_name):
74 ''' Converts a class name to its table name according to rails
75 naming conventions. Example. Converts "Person" to "people" '''
76 return self.pluralize(self.underscore(class_name))
77
78 def classify(self, table_name):
79 '''Converts a table name to its class name according to rails
80 naming conventions. Example: Converts "people" to "Person" '''
81 return self.camelize(self.singularize(table_name))
82
83 def ordinalize(self, number):
84 '''Converts number to its ordinal English form.
85 This method converts 13 to 13th, 2 to 2nd ...'''
86 tail = 'th'
87 if number % 100 == 11 or number % 100 == 12 or number % 100 == 13:
88 tail = 'th'
89 elif number % 10 == 1:
90 tail = 'st'
91 elif number % 10 == 2:
92 tail = 'nd'
93 elif number % 10 == 3:
94 tail = 'rd'
95
96 return str(number) + tail
97
98 def unaccent(self, text):
99 '''Transforms a string to its unaccented version.
100 This might be useful for generating "friendly" URLs'''
101 find = u'\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5\u00C6\u00C7\u00C8\u00C9\u00CA\u00CB\u00CC\u00CD\u00CE\u00CF\u00D0\u00D1\u00D2\u00D3\u00D4\u00D5\u00D6\u00D8\u00D9\u00DA\u00DB\u00DC\u00DD\u00DE\u00DF\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EC\u00ED\u00EE\u00EF\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6\u00F8\u00F9\u00FA\u00FB\u00FC\u00FD\u00FE\u00FF'
102 replace = u'AAAAAAACEEEEIIIIDNOOOOOOUUUUYTsaaaaaaaceeeeiiiienoooooouuuuyty'
103 return self.string_replace(text, find, replace)
104
105 def string_replace(self, word, find, replace):
106 '''This function returns a copy of word, translating
107 all occurrences of each character in find to the
108 corresponding character in replace'''
109 for k in range(0, len(find)):
110 word = re.sub(find[k], replace[k], word)
111
112 return word
113
114 def urlize(self, text):
115 '''Transform a string its unaccented and underscored
116 version ready to be inserted in friendly URLs'''
117 return re.sub('^_|_$', '', self.underscore(self.unaccent(text)))
118
119 def demodulize(self, module_name):
120 return self.humanize(self.underscore(re.sub('^.*::', '', module_name)))
121
122 def modulize(self, module_description):
123 return self.camelize(self.singularize(module_description))
124
125 def foreignKey(self, class_name, separate_class_name_and_id_with_underscore=1):
126 ''' Returns class_name in underscored form, with "_id" tacked on at the end.
127 This is for use in dealing with the database.'''
128 if separate_class_name_and_id_with_underscore:
129 tail = '_id'
130 else:
131 tail = 'id'
132 return self.underscore(self.demodulize(class_name)) + tail
133
134
135 class English(Base):
136 """
137 Inflector for pluralize and singularize English nouns.
138
139 This is the default Inflector for the Inflector obj
140 """
141
142 def pluralize(self, word):
143 '''Pluralizes English nouns.'''
144
145 rules = [
146 ['(?i)(quiz)$', '\\1zes'],
147 ['^(?i)(ox)$', '\\1en'],
148 ['(?i)([m|l])ouse$', '\\1ice'],
149 ['(?i)(matr|vert|ind)ix|ex$', '\\1ices'],
150 ['(?i)(x|ch|ss|sh)$', '\\1es'],
151 ['(?i)([^aeiouy]|qu)ies$', '\\1y'],
152 ['(?i)([^aeiouy]|qu)y$', '\\1ies'],
153 ['(?i)(hive)$', '\\1s'],
154 ['(?i)(?:([^f])fe|([lr])f)$', '\\1\\2ves'],
155 ['(?i)sis$', 'ses'],
156 ['(?i)([ti])um$', '\\1a'],
157 ['(?i)(buffal|tomat)o$', '\\1oes'],
158 ['(?i)(bu)s$', '\\1ses'],
159 ['(?i)(alias|status)', '\\1es'],
160 ['(?i)(octop|vir)us$', '\\1i'],
161 ['(?i)(ax|test)is$', '\\1es'],
162 ['(?i)s$', 's'],
163 ['(?i)$', 's']
164 ]
165
166 uncountable_words = ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep']
167
168 irregular_words = {
169 'person': 'people',
170 'man': 'men',
171 'child': 'children',
172 'sex': 'sexes',
173 'move': 'moves'
174 }
175
176 lower_cased_word = word.lower()
177
178 for uncountable_word in uncountable_words:
179 if lower_cased_word[-1 * len(uncountable_word):] == uncountable_word:
180 return word
181
182 for irregular in irregular_words.keys():
183 match = re.search('(' + irregular + ')$', word, re.IGNORECASE)
184 if match:
185 return re.sub('(?i)' + irregular + '$', match.expand('\\1')[0] + irregular_words[irregular][1:], word)
186
187 for rule in range(len(rules)):
188 match = re.search(rules[rule][0], word, re.IGNORECASE)
189 if match:
190 groups = match.groups()
191 for k in range(0, len(groups)):
192 if groups[k] is None:
193 rules[rule][1] = rules[rule][1].replace('\\' + str(k + 1), '')
194
195 return re.sub(rules[rule][0], rules[rule][1], word)
196
197 return word
198
199 def singularize(self, word):
200 '''Singularizes English nouns.'''
201
202 rules = [
203 ['(?i)(quiz)zes$', '\\1'],
204 ['(?i)(matr)ices$', '\\1ix'],
205 ['(?i)(vert|ind)ices$', '\\1ex'],
206 ['(?i)^(ox)en', '\\1'],
207 ['(?i)(alias|status)es$', '\\1'],
208 ['(?i)([octop|vir])i$', '\\1us'],
209 ['(?i)(cris|ax|test)es$', '\\1is'],
210 ['(?i)(shoe)s$', '\\1'],
211 ['(?i)(o)es$', '\\1'],
212 ['(?i)(bus)es$', '\\1'],
213 ['(?i)([m|l])ice$', '\\1ouse'],
214 ['(?i)(x|ch|ss|sh)es$', '\\1'],
215 ['(?i)(m)ovies$', '\\1ovie'],
216 ['(?i)(s)eries$', '\\1eries'],
217 ['(?i)([^aeiouy]|qu)ies$', '\\1y'],
218 ['(?i)([lr])ves$', '\\1f'],
219 ['(?i)(tive)s$', '\\1'],
220 ['(?i)(hive)s$', '\\1'],
221 ['(?i)([^f])ves$', '\\1fe'],
222 ['(?i)(^analy)ses$', '\\1sis'],
223 ['(?i)((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$', '\\1\\2sis'],
224 ['(?i)([ti])a$', '\\1um'],
225 ['(?i)(n)ews$', '\\1ews'],
226 ['(?i)s$', ''],
227 ]
228
229 uncountable_words = ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep', 'sms']
230
231 irregular_words = {
232 'people': 'person',
233 'men': 'man',
234 'children': 'child',
235 'sexes': 'sex',
236 'moves': 'move'
237 }
238
239 lower_cased_word = word.lower()
240 for uncountable_word in uncountable_words:
241 if lower_cased_word[-1 * len(uncountable_word):] == uncountable_word:
242 return word
243
244 for irregular in irregular_words.keys():
245 match = re.search('(' + irregular + ')$', word, re.IGNORECASE)
246 if match:
247 return re.sub('(?i)' + irregular + '$', match.expand('\\1')[0] + irregular_words[irregular][1:], word)
248
249 for rule in range(len(rules)):
250 match = re.search(rules[rule][0], word, re.IGNORECASE)
251 if match:
252 groups = match.groups()
253 for k in range(0, len(groups)):
254 if groups[k] is None:
255 rules[rule][1] = rules[rule][1].replace('\\' + str(k + 1), '')
256
257 return re.sub(rules[rule][0], rules[rule][1], word)
258
259 return word
260
261
262 class Inflector(object):
263 """
264 Inflector for pluralizing and singularizing nouns.
265
266 It provides methods for helping on creating programs
267 based on naming conventions like on Ruby on Rails.
268 """
269
270 def __init__(self, Inflector=English):
271 assert callable(Inflector), "Inflector should be a callable obj"
272 self.Inflector = Inflector()
273
274 def pluralize(self, word):
275 '''Pluralizes nouns.'''
276 return self.Inflector.pluralize(word)
277
278 def singularize(self, word):
279 '''Singularizes nouns.'''
280 return self.Inflector.singularize(word)
281
282 def cond_plural(self, number_of_records, word):
283 '''Returns the plural form of a word if first parameter is greater than 1'''
284 return self.Inflector.cond_plural(number_of_records, word)
285
286 def titleize(self, word, uppercase=''):
287 '''Converts an underscored or CamelCase word into a sentence.
288 The titleize function converts text like "WelcomePage",
289 "welcome_page" or "welcome page" to this "Welcome Page".
290 If the "uppercase" parameter is set to 'first' it will only
291 capitalize the first character of the title.'''
292 return self.Inflector.titleize(word, uppercase)
293
294 def camelize(self, word):
295 ''' Returns given word as CamelCased
296 Converts a word like "send_email" to "SendEmail". It
297 will remove non alphanumeric character from the word, so
298 "who's online" will be converted to "WhoSOnline"'''
299 return self.Inflector.camelize(word)
300
301 def underscore(self, word):
302 ''' Converts a word "into_it_s_underscored_version"
303 Convert any "CamelCased" or "ordinary Word" into an
304 "underscored_word".
305 This can be really useful for creating friendly URLs.'''
306 return self.Inflector.underscore(word)
307
308 def humanize(self, word, uppercase=''):
309 '''Returns a human-readable string from word
310 Returns a human-readable string from word, by replacing
311 underscores with a space, and by upper-casing the initial
312 character by default.
313 If you need to uppercase all the words you just have to
314 pass 'all' as a second parameter.'''
315 return self.Inflector.humanize(word, uppercase)
316
317 def variablize(self, word):
318 '''Same as camelize but first char is lowercased
319 Converts a word like "send_email" to "sendEmail". It
320 will remove non alphanumeric character from the word, so
321 "who's online" will be converted to "whoSOnline"'''
322 return self.Inflector.variablize(word)
323
324 def tableize(self, class_name):
325 ''' Converts a class name to its table name according to rails
326 naming conventions. Example. Converts "Person" to "people" '''
327 return self.Inflector.tableize(class_name)
328
329 def classify(self, table_name):
330 '''Converts a table name to its class name according to rails
331 naming conventions. Example: Converts "people" to "Person" '''
332 return self.Inflector.classify(table_name)
333
334 def ordinalize(self, number):
335 '''Converts number to its ordinal form.
336 This method converts 13 to 13th, 2 to 2nd ...'''
337 return self.Inflector.ordinalize(number)
338
339 def unaccent(self, text):
340 '''Transforms a string to its unaccented version.
341 This might be useful for generating "friendly" URLs'''
342 return self.Inflector.unaccent(text)
343
344 def urlize(self, text):
345 '''Transform a string to its unaccented and underscored
346 version ready to be inserted in friendly URLs'''
347 return self.Inflector.urlize(text)
348
349 def demodulize(self, module_name):
350 return self.Inflector.demodulize(module_name)
351
352 def modulize(self, module_description):
353 return self.Inflector.modulize(module_description)
354
355 def foreignKey(self, class_name, separate_class_name_and_id_with_underscore=1):
356 ''' Returns class_name in underscored form, with "_id" tacked on at the end.
357 This is for use in dealing with the database.'''
358 return self.Inflector.foreignKey(class_name, separate_class_name_and_id_with_underscore)
359
360
361 # Copyright (c) 2006 Bermi Ferrer Martinez
362 # Permission is hereby granted, free of charge, to any person obtaining a copy
363 # of this software to deal in this software without restriction, including
364 # without limitation the rights to use, copy, modify, merge, publish,
365 # distribute, sublicense, and/or sell copies of this software, and to permit
366 # persons to whom this software is furnished to do so, subject to the following
367 # condition:
368 #
369 # THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
370 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
371 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
372 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
373 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
374 # OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN
375 # THIS SOFTWARE.