OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |