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

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

Issue 12733003: Adds facilities for extracting Intl.message calls and generating code from translations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
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.
4
5 /**
6 * This provides utilities for generating localized versions of
7 * messages. It does not stand alone, but expects to be given
8 * TranslatedMessage objects and generate code for a particular locale
9 * based on them.
10 *
11 * An example of usage can be found
12 * in test/message_extract/generate_from_json.dart
13 */
14 library generate_localized;
15
16 import 'extract_messages.dart';
17 import 'src/intl_message.dart';
18 import 'dart:io';
19 import 'package:pathos/path.dart' as path;
20
21 /**
22 * A list of all the locales for which we have translations. Code that does
23 * the reading of translations should add to this.
24 */
25 List<String> allLocales = [];
26
27 /**
28 * This represents a message and its translation. We assume that the translation
29 * has some identifier that allows us to figure out the original message it
30 * corresponds to, and that it may want to transform the translated text in
31 * some way, e.g. to turn whatever format the translation uses for variables
32 * into a Dart string interpolation. Specific translation
33 * mechanisms are expected to subclass this.
34 */
35 abstract class TranslatedMessage {
36 /** The identifier for this message. In the simplest case, this is the name.*/
37 var id;
38
39 String translatedString;
40 IntlMessage originalMessage;
41 TranslatedMessage(this.id, this.translatedString);
42
43 get message => translatedString;
Emily Fortuna 2013/03/13 18:54:43 please list the return type for getters/functions.
Alan Knight 2013/03/14 17:49:05 Done.
44 }
45
46 /**
47 * We can't use a hyphen in a Dart library name, so convert the locale
48 * separator to an underscore.
49 */
50 asLibraryName(String x) => x.replaceAll('-', '_');
51
52 /**
53 * Generate a file messages_<locale>.dart for the [translations] in
54 * [locale].
55 */
56 generateIndividualMessageFile(String locale,
57 Iterable<TranslatedMessage> translations) {
58 var result = new StringBuffer();
59 locale = new IntlMessage().escapeAndValidate(locale, locale);
60 result.write(prologue(locale));
61 for (var each in translations) {
62 var message = each.originalMessage;
63 if (each.message != null) {
64 message.addTranslation(locale, each.message);
65 }
66 }
67 var sorted = translations.where((each) => each.message != null).toList();
68 sorted.sort((a, b) =>
69 a.originalMessage.name.compareTo(b.originalMessage.name));
70 for (var each in sorted) {
71 result.write(" ");
72 result.write(each.originalMessage.toCode(locale));
73 result.write("\n\n");
74 }
75 result.write("\n final messages = const {\n");
76 var entries = sorted
77 .map((translation) => translation.originalMessage.name)
78 .map((name) => " \"$name\" : $name");
79 result.write(entries.join(",\n"));
80 result.write("\n };\n}");
81
82 ifNull(x, y) => (x == null) ? y : x;
83 var target = ifNull(Platform.environment["INTL_MESSAGE_OUTPUT"], '.');
84 var output = new File(path.join(target, "messages_$locale.dart"));
85 output.writeAsStringSync(result.toString());
86 }
87
88 /**
89 * This returns the mostly constant string used in [generated] for the
90 * beginning of the file, parameterized by [locale].
91 */
92 prologue(String locale) => """
93 /**
94 * DO NOT EDIT. This is code generated via pkg/intl/generate_localized.dart
95 * This is a library that provides messages for a $locale locale. All the
96 * messages from the main program should be duplicated here with the same
97 * function name.
98 */
99
100 library messages_${locale.replaceAll('-','_')};
101 import 'package:intl/intl.dart';
102 import 'package:intl/message_lookup_by_library.dart';
103
104 final messages = new MessageLookup();
105
106 class MessageLookup extends MessageLookupByLibrary {
107
108 get localeName => '$locale';
109 """;
110
111 /**
112 * This section generates the messages_all.dart file based on the list of
113 * [allLocales].
114 */
115 generateMainImportFile() {
116 var output = new StringBuffer();
117 output.write(mainPrologue);
118 for (var each in allLocales) {
119 output.write("import 'messages_$each.dart' as ${asLibraryName(each)};\n");
120 }
121 output.write(
122 "\nMessageLookupByLibrary _findExact(localeName) {\n"
123 " switch (localeName) {\n");
124 for (var each in allLocales) {
125 output.write(
126 " case '$each' : return ${asLibraryName(each)}.messages;\n");
127 }
128 output.write(closing);
129 return output.toString();
130 }
131
132 /**
133 * Constant string used in [generateMainImportFile] for the beginning of the
134 * file.
135 */
136 const mainPrologue = """
137 /**
138 * DO NOT EDIT. This is code generated via pkg/intl/generate_localized.dart
139 * This is a library that looks up messages for specific locales by
140 * delegating to the appropriate library.
141 */
142
143 library messages_all;
144
145 import 'dart:async';
146 import 'package:intl/message_lookup_by_library.dart';
147 import 'package:intl/src/intl_helpers.dart';
148 import 'package:intl/intl.dart';
149
150 """;
151
152 /**
153 * Constant string used in [generateMainImportfile] as the end of the file.
154 */
155 const closing = """
156 default: return null;
157 }
158 }
159
160 /** User programs should call this before using [localeName] for messages.*/
161 initializeMessages(localeName) {
162 initializeInternalMessageLookup(() => new CompositeMessageLookup());
163 messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
164 return new Future.immediate(null);
165 }
166
167 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
168 var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
169 if (actualLocale == null) return null;
170 return _findExact(actualLocale);
171 }
172 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698