package mods.eln.i18n; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.registry.LanguageRegistry; /** * Internationalization and localization helper class. */ public class I18N { private final static LanguageRegistry languageRegistry = LanguageRegistry.instance(); public static String getCurrentLanguage() { return FMLCommonHandler.instance().getCurrentLanguage(); } static String encodeLangKey(final String key) { return encodeLangKey(key, true); } static String encodeLangKey(String key, boolean replaceWhitspaces) { if (key != null) { if (replaceWhitspaces) { key = key.replace(' ', '_'); } return key.replace("=", "\\=") .replace(":", "\\:") .replace("\n", "\\n") .replace("/", "_"); } else { return null; } } /** * Translates the given string. You can pass arguments to the method and reference them in the string using * the placeholders %N$ whereas N is the index of the actual parameter <b>starting at 1</b>. * <p> * Example: tr("You have %1$ lives left", 4); * <p> * IT IS IMPORTANT THAT YOU PASS THE <b>STRING LITERALS</b> AT LEAST ONCE AS THE FIRST PARAMETER TO THIS METHOD or * you call the method TR() with the actual string literal in order to register the translation text automatically! * Otherwise the translation will not be added to the language files. There is no problem to use the tr() method * afterwards using an already registered string in the code using a string variable as the first parameter. * <p/> * * @param text Text to translate * @param objects Arguments to integrate into the text. * @return Translated text or original text (Argument placeholders are replaced by the actual arguments * anyway) if no translation is present. */ public static String tr(final String text, Object... objects) { // Try to find the translation for the string using forge API. String translation = languageRegistry.getStringLocalization(encodeLangKey(text)); // If no translation was found, just use the original text. if (translation == null || "".equals(translation)) { translation = text; } else { // Replace placeholders . translation = translation.replace("\\n", "\n").replace("\\:", ":"); } // Replace placeholders in string by actual string values of the passed objects. for (int i = 0; i < objects.length; ++i) { translation = translation.replace("%" + (i + 1) + "$", String.valueOf(objects[i])); } return translation; } /** * This method can be used to mark an unlocalized text in order to add it to the generated language files. * The method does not actually translate the text - it marks the text literal only to be translated afterwards. * A common use case is to add text to the language file which is translated using a text variable with the * method tr(). * * @param text String LITERAL to add to the language files. * @return Exactly the same text as given to the method. */ public static String TR(final String text) { return encodeLangKey(text); } /** * Defines the different translatable types. */ public enum Type { /** * The text to translate is not related to a particular translatable type, so basically only the ".name" suffix * is added to the translation key. */ NONE("", false, true), /** * The text to translate is related to an item. The "item." runtimePrefix will be added to the translation key. */ ITEM("item.", false, false), /** * The text to translate is related to a tile. The "tile." runtimePrefix will be added to the translation key. */ TILE("tile.", false, false), /** * The text to translate is related to an achievement. The "achievement." runtimePrefix will be added to the * translation key. */ ACHIEVEMENT("achievement.", true, true), /** * The text to translate is related to an entity. The "entity." runtimePrefix will be added to the translation key. */ ENTITY("entity.", false, false), /** * The text to translate is related to a death attack. The "death.attack" runtimePrefix will be added to the * translation key. */ DEATH_ATTACK("death.attack.", false, false), /** * The text to translate is related to an item group. The "itemGroup." runtimePrefix will be added to the translation * key. */ ITEM_GROUP("itemGroup.", false, false), /** * The text to translate is related to a container. The "container." runtimePrefix will be added to the translation * key. */ CONTAINER("container.", false, false), /** * The text to translate is related to an block. The "block." runtimePrefix will be added to the translation key. */ BLOCK("block.", false, false), SIX_NODE("eln.sixnode.", false, true), NODE("eln.node.", false, true); private final String prefix; private final boolean encodeAtRuntime; private final boolean replaceWhitespacesInFile; Type(final String prefix, boolean encodeAtRuntime, boolean replaceWhitespacesInFile) { this.prefix = prefix; this.encodeAtRuntime = encodeAtRuntime; this.replaceWhitespacesInFile = replaceWhitespacesInFile; } /** * Returns the prefix. * * @return Prefix for the type of translatable text. */ public String getPrefix() { return prefix; } public boolean isEncodedAtRuntime() { return encodeAtRuntime; } public boolean isWhitespacesInFileReplaced() { return replaceWhitespacesInFile; } } /** * Used to register a name to translate. The forge mechanisms are used in order to translate the name. * * @param type Type the translatable name is related to. * @param text String LITERAL to register for translation. * @return Returns the same text literal, forge will translate the name magically. */ public static String TR_NAME(final Type type, final String text) { if (type.isEncodedAtRuntime()) { return (new StringBuilder(type.getPrefix())).append(encodeLangKey(text)).append(".name").toString(); } else { return text; } } /** * Used to register a description to translate. The forge mechanisms are used in order to translate the description. * * @param type Type the translatable description is related to. * @param text String LITERAL to register for translation. * @return Returns the same text literal, forge will translate the description magically. */ public static String TR_DESC(final Type type, final String text) { if (type.isEncodedAtRuntime()) { return (new StringBuilder(type.getPrefix())).append(encodeLangKey(text)).append(".desc").toString(); } else { return text; } } }