Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: pkg/intl/lib/intl.dart

Issue 18543009: Plurals and Genders (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * This library provides internationalization and localization. This includes 6 * This library provides internationalization and localization. This includes
7 * message formatting and replacement, date and number formatting and parsing, 7 * message formatting and replacement, date and number formatting and parsing,
8 * and utilities for working with Bidirectional text. 8 * and utilities for working with Bidirectional text.
9 * 9 *
10 * ## Installing ## 10 * ## Installing ##
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 * name: 'today', 64 * name: 'today',
65 * args: [date], 65 * args: [date],
66 * desc: 'Indicate the current date', 66 * desc: 'Indicate the current date',
67 * examples: {'date' : 'June 8, 2012'}); 67 * examples: {'date' : 'June 8, 2012'});
68 * print(today(new DateTime.now()); 68 * print(today(new DateTime.now());
69 * 69 *
70 * msg(num_people, place) => Intl.message( 70 * msg(num_people, place) => Intl.message(
71 * '''I see ${Intl.plural(num_people, 71 * '''I see ${Intl.plural(num_people,
72 * {'0': 'no one at all', 72 * {'0': 'no one at all',
73 * '1': 'one other person', 73 * '1': 'one other person',
74 * 'other': '$num_people other people'})} in $place.'''', 74 * 'other': '$num_people other people'})} in $place.''',
75 * name: 'msg', 75 * name: 'msg',
76 * args: [num_people, place], 76 * args: [num_people, place],
77 * desc: 'Description of how many people are seen as program start.', 77 * desc: 'Description of how many people are seen as program start.',
78 * examples: {'num_people': 3, 'place': 'London'}); 78 * examples: {'num_people': 3, 'place': 'London'});
79 * 79 *
80 * Calling `msg(2, 'Athens');` would 80 * Calling `msg(2, 'Athens');` would
81 * produce "I see 2 other people in Athens." as output in the default locale. 81 * produce "I see 2 other people in Athens." as output in the default locale.
82 * 82 *
83 * To use a locale other than the default, use the `withLocale` function. 83 * To use a locale other than the default, use the `withLocale` function.
84 * var todayString = new DateFormat("pt_BR").format(new DateTime.now()); 84 * var todayString = new DateFormat("pt_BR").format(new DateTime.now());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 if (aLocale == null) return systemLocale; 231 if (aLocale == null) return systemLocale;
232 if (aLocale == "C") return "en_ISO"; 232 if (aLocale == "C") return "en_ISO";
233 if ((aLocale.length < 5) || (aLocale.length > 6)) return aLocale; 233 if ((aLocale.length < 5) || (aLocale.length > 6)) return aLocale;
234 if (aLocale[2] != '-' && (aLocale[2] != '_')) return aLocale; 234 if (aLocale[2] != '-' && (aLocale[2] != '_')) return aLocale;
235 var lastRegionLetter = aLocale.length == 5 ? "" : aLocale[5].toUpperCase(); 235 var lastRegionLetter = aLocale.length == 5 ? "" : aLocale[5].toUpperCase();
236 return '${aLocale[0]}${aLocale[1]}_${aLocale[3].toUpperCase()}' 236 return '${aLocale[0]}${aLocale[1]}_${aLocale[3].toUpperCase()}'
237 '${aLocale[4].toUpperCase()}$lastRegionLetter'; 237 '${aLocale[4].toUpperCase()}$lastRegionLetter';
238 } 238 }
239 239
240 /** 240 /**
241 * Support method for message formatting. Select the correct plural form from 241 * Format a message differently depending on [howMany]. Normally used
242 * [cases] given [howMany]. 242 * as part of an Intl.message message that is to be translated.
Emily Fortuna 2013/07/03 17:52:33 `Intl.message` also you probably can do without t
Alan Knight 2013/07/03 18:41:07 Done. Changed second "message" to "text"
243 * Selects the correct plural form from
244 * the provided alternatives. The [other] named argument is mandatory.
243 */ 245 */
244 static String plural(var howMany, Map cases, [num offset=0]) { 246 static String plural(int howMany, {zero, one, two, few, many, other}) {
245 // TODO(efortuna): Deal with "few" and "many" cases, offset, and others! 247 if (other == null) {
246 return select(howMany.toString(), cases); 248 throw new ArgumentError("The 'other' named argument must be provided");
Emily Fortuna 2013/07/03 17:52:33 in which case should we make it a positional requi
Alan Knight 2013/07/03 18:41:07 That would mean you'd have to write it first, whic
249 }
250 // TODO(alanknight): This algorithm needs to be locale-dependent.
Emily Fortuna 2013/07/03 17:52:33 how will we be able to change this behavior based
Alan Knight 2013/07/03 18:41:07 I was thinking that there would be a generated imp
251 switch (howMany) {
252 case 0 : return (zero == null) ? other : zero;
253 case 1 : return (one == null) ? other : one;
254 case 2: return (two == null) ? ((few == null) ? other : few) : two;
255 default:
256 if (howMany == 3 || howMany == 4 && few != null) return few;
257 if (howMany > 10 && howMany < 100 && many != null) return many;
258 return other;
259 }
260 throw new ArgumentError("Invalid plural usage for $howMany");
247 } 261 }
248 262
249 /** 263 /**
264 * Format a message differently depending on [gender]. Normally used as part
265 * of an Intl.message message that is to be translated.
266 */
267 static String gender(String gender,
268 {String male, String female, String other}) {
269 if (other == null) {
270 throw new ArgumentError("The 'other' named argument must be specified");
271 }
272 switch(gender) {
273 case "female" : return female == null ? other : female;
274 case "male" : return male == null ? other : male;
275 default: return other;
276 }
277 }
278
279 /**
250 * Format the given function with a specific [locale], given a 280 * Format the given function with a specific [locale], given a
251 * [message_function] that takes no parameters. The [message_function] can be 281 * [message_function] that takes no parameters. The [message_function] can be
252 * a simple message function that just returns the result of `Intl.message()` 282 * a simple message function that just returns the result of `Intl.message()`
253 * it can be a wrapper around a message function that takes arguments, or it 283 * it can be a wrapper around a message function that takes arguments, or it
254 * can be something more complex that manipulates multiple message 284 * can be something more complex that manipulates multiple message
255 * functions. 285 * functions.
256 * 286 *
257 * In either case, the purpose of this is to delay calling [message_function] 287 * In either case, the purpose of this is to delay calling [message_function]
258 * until the proper locale has been set. This returns the result of calling 288 * until the proper locale has been set. This returns the result of calling
259 * [message_function], which could be of an arbitrary type. 289 * [message_function], which could be of an arbitrary type.
260 */ 290 */
261 static withLocale(String locale, Function message_function) { 291 static withLocale(String locale, Function message_function) {
262 // We have to do this silliness because Locale is not known at compile time, 292 // We have to do this silliness because Locale is not known at compile time,
263 // but must be a static variable in order to be visible to the Intl.message 293 // but must be a static variable in order to be visible to the Intl.message
264 // invocation. 294 // invocation.
265 var oldLocale = getCurrentLocale(); 295 var oldLocale = getCurrentLocale();
266 _defaultLocale = locale; 296 _defaultLocale = locale;
267 var result = message_function(); 297 var result = message_function();
268 _defaultLocale = oldLocale; 298 _defaultLocale = oldLocale;
269 return result; 299 return result;
270 } 300 }
271 301
272 /** 302 /**
273 * Support method for message formatting. Select the correct exact (gender, 303 * Support method for message formatting. Select the correct exact (gender,
274 * usually) form from [cases] given the user [choice]. 304 * usually) form from [cases] given the user [choice].
275 */ 305 */
276 static String select(String choice, Map cases) { 306 static String select(String choice, Map cases) {
277 if (cases.containsKey(choice)) { 307 var exact = cases[choice];
278 return cases[choice]; 308 if (exact != null) return exact;
279 } else if (cases.containsKey('other')){ 309 var other = cases["other"];
280 return cases['other']; 310 return (other == null) ? '' : other;
281 } else {
282 return '';
283 }
284 } 311 }
285 312
286 /** 313 /**
287 * Accessor for the current locale. This should always == the default locale, 314 * Accessor for the current locale. This should always == the default locale,
288 * unless for some reason this gets called inside a message that resets the 315 * unless for some reason this gets called inside a message that resets the
289 * locale. 316 * locale.
290 */ 317 */
291 static String getCurrentLocale() { 318 static String getCurrentLocale() {
292 if (_defaultLocale == null) _defaultLocale = systemLocale; 319 if (_defaultLocale == null) _defaultLocale = systemLocale;
293 return _defaultLocale; 320 return _defaultLocale;
294 } 321 }
295 322
296 toString() => "Intl($locale)"; 323 toString() => "Intl($locale)";
297 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698