aboutsummaryrefslogtreecommitdiffstats
path: root/tools/make-keyboard-text/src
diff options
context:
space:
mode:
Diffstat (limited to 'tools/make-keyboard-text/src')
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java55
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java153
-rw-r--r--tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java14
3 files changed, 141 insertions, 81 deletions
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java
index 331003e67..48bf8010a 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/ArrayInitializerFormatter.java
@@ -22,17 +22,26 @@ public class ArrayInitializerFormatter {
private final PrintStream mOut;
private final int mMaxWidth;
private final String mIndent;
+ // String resource names array; indexed by {@link #CurrentIndex} and
+ // {@link #mStartIndexOfBuffer}.
+ private final String[] mResourceNames;
private int mCurrentIndex = 0;
- private String mFixedElement;
+ private String mLastElement;
private final StringBuilder mBuffer = new StringBuilder();
private int mBufferedLen;
- private int mBufferedIndex = Integer.MIN_VALUE;
+ private int mStartIndexOfBuffer = Integer.MIN_VALUE;
- public ArrayInitializerFormatter(PrintStream out, int width, String indent) {
+ public ArrayInitializerFormatter(final PrintStream out, final int width, final String indent,
+ final String[] resourceNames) {
mOut = out;
mMaxWidth = width - indent.length();
mIndent = indent;
+ mResourceNames = resourceNames;
+ }
+
+ public int getCurrentIndex() {
+ return mCurrentIndex;
}
public void flush() {
@@ -40,42 +49,48 @@ public class ArrayInitializerFormatter {
return;
}
final int lastIndex = mCurrentIndex - 1;
- if (mBufferedIndex == lastIndex) {
- mOut.format("%s/* %d */ %s\n", mIndent, mBufferedIndex, mBuffer);
- } else if (mBufferedIndex == lastIndex - 1) {
- final String[] elements = mBuffer.toString().split(" ");
- mOut.format("%s/* %d */ %s\n"
- + "%s/* %d */ %s\n",
- mIndent, mBufferedIndex, elements[0],
- mIndent, lastIndex, elements[1]);
+ if (mStartIndexOfBuffer == lastIndex) {
+ mOut.format("%s/* %s */ %s\n",
+ mIndent, mResourceNames[mStartIndexOfBuffer], mBuffer);
+ } else if (mStartIndexOfBuffer == lastIndex - 1) {
+ final String startElement = mBuffer.toString()
+ .substring(0, mBuffer.length() - mLastElement.length())
+ .trim();
+ mOut.format("%s/* %s */ %s\n"
+ + "%s/* %s */ %s\n",
+ mIndent, mResourceNames[mStartIndexOfBuffer], startElement,
+ mIndent, mResourceNames[lastIndex], mLastElement);
} else {
- mOut.format("%s/* %d~ */\n"
+ mOut.format("%s/* %s ~ */\n"
+ "%s%s\n"
- + "%s/* ~%d */\n", mIndent, mBufferedIndex,
+ + "%s/* ~ %s */\n",
+ mIndent, mResourceNames[mStartIndexOfBuffer],
mIndent, mBuffer,
- mIndent, lastIndex);
+ mIndent, mResourceNames[lastIndex]);
}
mBuffer.setLength(0);
mBufferedLen = 0;
}
- public void outCommentLines(String lines) {
+ public void outCommentLines(final String lines) {
flush();
mOut.print(lines);
- mFixedElement = null;
+ mLastElement = null;
}
- public void outElement(String element) {
- if (!element.equals(mFixedElement)) {
+ public void outElement(final String element) {
+ if (!element.equals(mLastElement)) {
flush();
- mBufferedIndex = mCurrentIndex;
+ mStartIndexOfBuffer = mCurrentIndex;
}
final int nextLen = mBufferedLen + " ".length() + element.length();
if (mBufferedLen != 0 && nextLen < mMaxWidth) {
+ // Element can fit in the current line.
mBuffer.append(' ');
mBuffer.append(element);
mBufferedLen = nextLen;
} else {
+ // Element should be on the next line.
if (mBufferedLen != 0) {
mBuffer.append('\n');
mBuffer.append(mIndent);
@@ -84,6 +99,6 @@ public class ArrayInitializerFormatter {
mBufferedLen = element.length();
}
mCurrentIndex++;
- mFixedElement = element;
+ mLastElement = element;
}
}
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
index dddb3d6c8..e9d6c864f 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/MoreKeysResources.java
@@ -25,9 +25,11 @@ import java.io.LineNumberReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.jar.JarFile;
+import java.util.regex.Pattern;
public class MoreKeysResources {
private static final String TEXT_RESOURCE_NAME = "donottranslate-more-keys.xml";
@@ -38,7 +40,6 @@ public class MoreKeysResources {
private static final String MARK_TEXTS = "@TEXTS@";
private static final String MARK_LANGUAGES_AND_TEXTS = "@LANGUAGES_AND_TEXTS@";
private static final String DEFAULT_LANGUAGE_NAME = "DEFAULT";
- private static final String ARRAY_NAME_FOR_LANGUAGE = "LANGUAGE_%s";
private static final String EMPTY_STRING_VAR = "EMPTY";
private static final String NO_LANGUAGE_CODE = "zz";
@@ -48,8 +49,19 @@ public class MoreKeysResources {
// Language to string resources map.
private final HashMap<String, StringResourceMap> mResourcesMap =
new HashMap<String, StringResourceMap>();
- // Name to id map.
- private final HashMap<String, Integer> mNameToIdMap = new HashMap<String,Integer>();
+ // Sorted languages list. The language is taken from string resource directories
+ // (values-<language>/) or {@link #DEFAULT_LANGUAGE_NAME} for the default string resource
+ // directory (values/).
+ private final ArrayList<String> mSortedLanguagesList = new ArrayList<String>();
+ // Default string resources map.
+ private final StringResourceMap mDefaultResourceMap;
+ // Histogram of string resource names. This is used to sort {@link #mSortedResourceNames}.
+ private final HashMap<String, Integer> mNameHistogram = new HashMap<String, Integer>();
+ // Sorted string resource names array; Descending order of histogram count.
+ // The string resource name is specified as an attribute "name" in string resource files.
+ // The string resource can be accessed by specifying name "!text/<name>"
+ // via {@link KeyboardTextsSet#getText(String)}.
+ private final String[] mSortedResourceNames;
public MoreKeysResources(final JarFile jar) {
mJar = jar;
@@ -66,6 +78,45 @@ public class MoreKeysResources {
close(stream);
}
}
+ mDefaultResourceMap = mResourcesMap.get(DEFAULT_LANGUAGE_NAME);
+ mSortedLanguagesList.addAll(mResourcesMap.keySet());
+ Collections.sort(mSortedLanguagesList);
+
+ // Initialize name histogram and names list.
+ final HashMap<String, Integer> nameHistogram = mNameHistogram;
+ final ArrayList<String> resourceNamesList = new ArrayList<String>();
+ for (final StringResource res : mDefaultResourceMap.getResources()) {
+ nameHistogram.put(res.mName, 0); // Initialize histogram value.
+ resourceNamesList.add(res.mName);
+ }
+ // Make name histogram.
+ for (final String language : mResourcesMap.keySet()) {
+ final StringResourceMap resMap = mResourcesMap.get(language);
+ if (resMap == mDefaultResourceMap) continue;
+ for (final StringResource res : resMap.getResources()) {
+ if (!mDefaultResourceMap.contains(res.mName)) {
+ throw new RuntimeException(res.mName + " in " + language
+ + " doesn't have default resource");
+ }
+ final int histogramValue = nameHistogram.get(res.mName);
+ nameHistogram.put(res.mName, histogramValue + 1);
+ }
+ }
+ // Sort names list.
+ Collections.sort(resourceNamesList, new Comparator<String>() {
+ @Override
+ public int compare(final String leftName, final String rightName) {
+ final int leftCount = nameHistogram.get(leftName);
+ final int rightCount = nameHistogram.get(rightName);
+ // Descending order of histogram count.
+ if (leftCount > rightCount) return -1;
+ if (leftCount < rightCount) return 1;
+ // TODO: Add further criteria to order the same histogram value names to be able to
+ // minimize footprints of string resources arrays.
+ return 0;
+ }
+ });
+ mSortedResourceNames = resourceNamesList.toArray(new String[resourceNamesList.size()]);
}
private static String getLanguageFromResDir(final String dirName) {
@@ -133,56 +184,47 @@ public class MoreKeysResources {
}
private void dumpNames(final PrintStream out) {
- final StringResourceMap defaultResMap = mResourcesMap.get(DEFAULT_LANGUAGE_NAME);
- int id = 0;
- for (final StringResource res : defaultResMap.getResources()) {
- out.format(" /* %2d */ \"%s\",\n", id, res.mName);
- mNameToIdMap.put(res.mName, id);
- id++;
+ final int namesCount = mSortedResourceNames.length;
+ for (int index = 0; index < namesCount; index++) {
+ final String name = mSortedResourceNames[index];
+ final int histogramValue = mNameHistogram.get(name);
+ out.format(" /* %3d:%2d */ \"%s\",\n", index, histogramValue, name);
}
}
private void dumpDefaultTexts(final PrintStream out) {
- final StringResourceMap defaultResMap = mResourcesMap.get(DEFAULT_LANGUAGE_NAME);
- dumpTextsInternal(out, defaultResMap, defaultResMap);
+ final int outputArraySize = dumpTextsInternal(out, mDefaultResourceMap);
+ mDefaultResourceMap.setOutputArraySize(outputArraySize);
+ }
+
+ private static String getArrayNameForLanguage(final String language) {
+ return "LANGUAGE_" + language;
}
private void dumpTexts(final PrintStream out) {
- final StringResourceMap defaultResMap = mResourcesMap.get(DEFAULT_LANGUAGE_NAME);
- final ArrayList<String> allLanguages = new ArrayList<String>();
- allLanguages.addAll(mResourcesMap.keySet());
- Collections.sort(allLanguages);
- for (final String language : allLanguages) {
- if (language.equals(DEFAULT_LANGUAGE_NAME)) {
- continue;
- }
- out.format(" /* Language %s: %s */\n", language, getLanguageDisplayName(language));
- out.format(" private static final String[] " + ARRAY_NAME_FOR_LANGUAGE + " = {\n",
- language);
+ for (final String language : mSortedLanguagesList) {
final StringResourceMap resMap = mResourcesMap.get(language);
- for (final StringResource res : resMap.getResources()) {
- if (!defaultResMap.contains(res.mName)) {
- throw new RuntimeException(res.mName + " in " + language
- + " doesn't have default resource");
- }
- }
- dumpTextsInternal(out, resMap, defaultResMap);
+ if (resMap == mDefaultResourceMap) continue;
+ out.format(" /* Language %s: %s */\n", language, getLanguageDisplayName(language));
+ out.format(" private static final String[] " + getArrayNameForLanguage(language)
+ + " = {\n");
+ final int outputArraySize = dumpTextsInternal(out, resMap);
+ resMap.setOutputArraySize(outputArraySize);
out.format(" };\n\n");
}
}
private void dumpLanguageMap(final PrintStream out) {
- final ArrayList<String> allLanguages = new ArrayList<String>();
- allLanguages.addAll(mResourcesMap.keySet());
- Collections.sort(allLanguages);
- for (final String language : allLanguages) {
+ for (final String language : mSortedLanguagesList) {
+ final StringResourceMap resMap = mResourcesMap.get(language);
final Locale locale = LocaleUtils.constructLocaleFromString(language);
- // If we use a different key, dump the original as comment for now.
final String languageKeyToDump = locale.getCountry().isEmpty()
? String.format("\"%s\"", language)
- : String.format("\"%s\" /* \"%s\" */", locale.getLanguage(), language);
- out.format(" %s, " + ARRAY_NAME_FOR_LANGUAGE + ", /* %s */\n",
- languageKeyToDump, language, getLanguageDisplayName(language));
+ : String.format("\"%s\"", locale.getLanguage());
+ out.format(" %s, %-15s /* %3d/%3d %s */\n",
+ languageKeyToDump, getArrayNameForLanguage(language) + ",",
+ resMap.getResources().size(), resMap.getOutputArraySize(),
+ getLanguageDisplayName(language));
}
}
@@ -194,14 +236,17 @@ public class MoreKeysResources {
return locale.getDisplayName(Locale.ENGLISH);
}
- private static void dumpTextsInternal(final PrintStream out, final StringResourceMap resMap,
- final StringResourceMap defaultResMap) {
+ private int dumpTextsInternal(final PrintStream out, final StringResourceMap resMap) {
final ArrayInitializerFormatter formatter =
- new ArrayInitializerFormatter(out, 100, " ");
+ new ArrayInitializerFormatter(out, 100, " ", mSortedResourceNames);
+ int outputArraySize = 0;
boolean successiveNull = false;
- for (final StringResource defaultRes : defaultResMap.getResources()) {
- if (resMap.contains(defaultRes.mName)) {
- final StringResource res = resMap.get(defaultRes.mName);
+ final int namesCount = mSortedResourceNames.length;
+ for (int index = 0; index < namesCount; index++) {
+ final String name = mSortedResourceNames[index];
+ final StringResource res = resMap.get(name);
+ if (res != null) {
+ // TODO: Check whether the resource value is equal to the default.
if (res.mComment != null) {
formatter.outCommentLines(addPrefix(" // ", res. mComment));
}
@@ -212,6 +257,7 @@ public class MoreKeysResources {
formatter.outElement(String.format("\"%s\",", escaped));
}
successiveNull = false;
+ outputArraySize = formatter.getCurrentIndex();
} else {
formatter.outElement("null,");
successiveNull = true;
@@ -220,6 +266,7 @@ public class MoreKeysResources {
if (!successiveNull) {
formatter.flush();
}
+ return outputArraySize;
}
private static String addPrefix(final String prefix, final String lines) {
@@ -241,26 +288,10 @@ public class MoreKeysResources {
sb.append(String.format("\\u%04X", (int)c));
}
}
- return replaceIncompatibleEscape(sb.toString());
- }
-
- private static String replaceIncompatibleEscape(final String text) {
- String t = text;
- t = replaceAll(t, "\\?", "?");
- t = replaceAll(t, "\\@", "@");
- t = replaceAll(t, "@string/", "!text/");
- return t;
- }
-
- private static String replaceAll(final String text, final String target, final String replace) {
- String t = text;
- while (t.indexOf(target) >= 0) {
- t = t.replace(target, replace);
- }
- return t;
+ return sb.toString();
}
- private static void close(Closeable stream) {
+ private static void close(final Closeable stream) {
try {
if (stream != null) {
stream.close();
diff --git a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
index cc7ff6a9c..4eff8a24b 100644
--- a/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
+++ b/tools/make-keyboard-text/src/com/android/inputmethod/keyboard/tools/StringResourceMap.java
@@ -39,6 +39,12 @@ public class StringResourceMap {
// Name to string resource map.
private final Map<String, StringResource> mResourcesMap;
+ // The length of String[] that is created from this {@link StringResourceMap}. The length is
+ // calculated in {@link MoreKeysResources#dumpTexts(OutputStream)} and recorded by
+ // {@link #setOutputArraySize(int)}. The recorded length is used as a part of comment by
+ // {@link MoreKeysResources#dumpLanguageMap(OutputStream)} via {@link #getOutputArraySize()}.
+ private int mOutputArraySize;
+
public StringResourceMap(final InputStream is) {
final StringResourceHandler handler = new StringResourceHandler();
final SAXParserFactory factory = SAXParserFactory.newInstance();
@@ -77,6 +83,14 @@ public class StringResourceMap {
return mResourcesMap.get(name);
}
+ public void setOutputArraySize(final int arraySize) {
+ mOutputArraySize = arraySize;
+ }
+
+ public int getOutputArraySize() {
+ return mOutputArraySize;
+ }
+
static class StringResourceHandler extends DefaultHandler2 {
private static final String TAG_RESOURCES = "resources";
private static final String TAG_STRING = "string";