diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 9c8bd3cd4..bfe42327c 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -45,24 +45,6 @@ - - = \\ < - - ~ \\ { - - - Tab - - 123 - - - *# - - "AM" - - "PM" - 0 diff --git a/java/res/xml-sw600dp/key_shortcut.xml b/java/res/xml-sw600dp/key_shortcut.xml index d4c45ad22..2114c67bd 100644 --- a/java/res/xml-sw600dp/key_shortcut.xml +++ b/java/res/xml-sw600dp/key_shortcut.xml @@ -29,7 +29,7 @@ + latin:moreKeys="!label/more_keys_for_smiley" /> + latin:keyOutputText="!label/keylabel_for_popular_domain" + latin:moreKeys="!label/more_keys_for_popular_domain" /> diff --git a/java/res/xml-sw600dp/keys_apostrophe_dash.xml b/java/res/xml-sw600dp/keys_apostrophe_dash.xml index a53c1e4ab..faaae50c9 100644 --- a/java/res/xml-sw600dp/keys_apostrophe_dash.xml +++ b/java/res/xml-sw600dp/keys_apostrophe_dash.xml @@ -39,9 +39,9 @@ @@ -54,9 +54,9 @@ diff --git a/java/res/xml-sw600dp/keys_comma_period.xml b/java/res/xml-sw600dp/keys_comma_period.xml index f5f307be6..4a83cc817 100644 --- a/java/res/xml-sw600dp/keys_comma_period.xml +++ b/java/res/xml-sw600dp/keys_comma_period.xml @@ -32,14 +32,14 @@ diff --git a/java/res/xml-sw600dp/rowkeys_symbols2.xml b/java/res/xml-sw600dp/rowkeys_symbols2.xml index e0121a35c..fd774168f 100644 --- a/java/res/xml-sw600dp/rowkeys_symbols2.xml +++ b/java/res/xml-sw600dp/rowkeys_symbols2.xml @@ -26,13 +26,13 @@ + latin:keyLabel="!label/keylabel_for_symbols_percent" + latin:moreKeys="!label/more_keys_for_symbols_percent" /> + latin:moreKeys="!label/more_keys_for_star" /> + latin:moreKeys="!label/more_keys_for_plus" /> diff --git a/java/res/xml-sw600dp/rowkeys_symbols3.xml b/java/res/xml-sw600dp/rowkeys_symbols3.xml index 9293352cf..536ac05a2 100644 --- a/java/res/xml-sw600dp/rowkeys_symbols3.xml +++ b/java/res/xml-sw600dp/rowkeys_symbols3.xml @@ -41,11 +41,11 @@ + latin:keyLabel="!label/keylabel_for_symbols_semicolon" + latin:moreKeys="!label/more_keys_for_symbols_semicolon" /> + latin:keyLabel="!label/keylabel_for_comma" + latin:moreKeys="!label/more_keys_for_comma" /> @@ -53,6 +53,6 @@ latin:keyLabel="!" latin:moreKeys="¡" /> + latin:keyLabel="!label/keylabel_for_symbols_question" + latin:moreKeys="!label/more_keys_for_symbols_question" /> diff --git a/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml b/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml index 356ee2f0e..914a4499b 100644 --- a/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml +++ b/java/res/xml-sw600dp/rowkeys_symbols_shift1.xml @@ -30,7 +30,7 @@ + latin:moreKeys="!label/more_keys_for_bullet" /> diff --git a/java/res/xml-sw600dp/rows_number_normal.xml b/java/res/xml-sw600dp/rows_number_normal.xml index be5776b20..00fda2899 100644 --- a/java/res/xml-sw600dp/rows_number_normal.xml +++ b/java/res/xml-sw600dp/rows_number_normal.xml @@ -70,7 +70,7 @@ diff --git a/java/res/xml-sw600dp/rows_symbols4.xml b/java/res/xml-sw600dp/rows_symbols4.xml index bfc9b2cf6..afa2652ea 100644 --- a/java/res/xml-sw600dp/rows_symbols4.xml +++ b/java/res/xml-sw600dp/rows_symbols4.xml @@ -37,7 +37,7 @@ latin:keyWidth="39.750%p" /> + latin:moreKeys="!label/more_keys_for_tablet_double_quote" /> + latin:moreKeys="!label/more_keys_for_smiley" /> @@ -122,7 +122,7 @@ @@ -130,35 +130,35 @@ + latin:keyOutputText="!label/keylabel_for_popular_domain" + latin:moreKeys="!label/more_keys_for_popular_domain" /> diff --git a/java/res/xml-sw768dp/keys_apostrophe_dash.xml b/java/res/xml-sw768dp/keys_apostrophe_dash.xml index a53c1e4ab..faaae50c9 100644 --- a/java/res/xml-sw768dp/keys_apostrophe_dash.xml +++ b/java/res/xml-sw768dp/keys_apostrophe_dash.xml @@ -39,9 +39,9 @@ @@ -54,9 +54,9 @@ diff --git a/java/res/xml-sw768dp/rows_number_normal.xml b/java/res/xml-sw768dp/rows_number_normal.xml index 2eeb6c9d4..f868cbb8b 100644 --- a/java/res/xml-sw768dp/rows_number_normal.xml +++ b/java/res/xml-sw768dp/rows_number_normal.xml @@ -72,7 +72,7 @@ diff --git a/java/res/xml-sw768dp/rows_symbols4.xml b/java/res/xml-sw768dp/rows_symbols4.xml index 19b36d690..dd1647b95 100644 --- a/java/res/xml-sw768dp/rows_symbols4.xml +++ b/java/res/xml-sw768dp/rows_symbols4.xml @@ -37,7 +37,7 @@ latin:keyWidth="37.500%p" /> + latin:moreKeys="!label/more_keys_for_tablet_double_quote" /> diff --git a/java/res/xml/key_azerty_quote.xml b/java/res/xml/key_azerty_quote.xml index 966ae6f21..b8c51d30f 100644 --- a/java/res/xml/key_azerty_quote.xml +++ b/java/res/xml/key_azerty_quote.xml @@ -31,7 +31,7 @@ + latin:moreKeys="!label/more_keys_for_single_quote" /> diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml index b0b87a810..ec011d08b 100644 --- a/java/res/xml/key_styles_common.xml +++ b/java/res/xml/key_styles_common.xml @@ -35,7 +35,7 @@ @@ -98,7 +98,7 @@ latin:keyLabel=":-)" latin:keyOutputText=":-) " latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="@string/more_keys_for_smiley" + latin:moreKeys="!label/more_keys_for_smiley" latin:backgroundType="functional" /> @@ -158,7 +158,7 @@ latin:styleName="toSymbolKeyStyle" latin:code="!code/key_switch_alpha_symbol" latin:keyIcon="iconShortcutForLabel" - latin:keyLabel="@string/label_to_symbol_with_microphone_key" + latin:keyLabel="!label/label_to_symbol_with_microphone_key" latin:keyLabelFlags="withIconRight|preserveCase" latin:keyActionFlags="noKeyPreview" latin:backgroundType="functional" /> @@ -167,7 +167,7 @@ @@ -176,29 +176,29 @@ diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml index bd1d959e4..6057d5bd7 100644 --- a/java/res/xml/key_styles_currency.xml +++ b/java/res/xml/key_styles_currency.xml @@ -86,7 +86,7 @@ + latin:moreKeys="!label/more_keys_for_currency_general" /> @@ -112,7 +112,7 @@ + latin:moreKeys="!label/more_keys_for_currency_general" /> @@ -138,7 +138,7 @@ + latin:moreKeys="!label/more_keys_for_currency_pound" /> diff --git a/java/res/xml/key_styles_currency_dollar.xml b/java/res/xml/key_styles_currency_dollar.xml index 8dd849879..704970a56 100644 --- a/java/res/xml/key_styles_currency_dollar.xml +++ b/java/res/xml/key_styles_currency_dollar.xml @@ -26,7 +26,7 @@ + latin:moreKeys="!label/more_keys_for_currency_dollar" /> diff --git a/java/res/xml/key_styles_currency_euro.xml b/java/res/xml/key_styles_currency_euro.xml index 0573e0991..074d4c0c2 100644 --- a/java/res/xml/key_styles_currency_euro.xml +++ b/java/res/xml/key_styles_currency_euro.xml @@ -26,7 +26,7 @@ + latin:moreKeys="!abel/more_keys_for_currency_euro" /> diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml index 49759c470..04bd80d9e 100644 --- a/java/res/xml/key_styles_enter.xml +++ b/java/res/xml/key_styles_enter.xml @@ -30,7 +30,7 @@ + latin:moreKeys="!label/action_previous_as_more_key" /> + latin:moreKeys="!label/action_next_as_more_key" /> + latin:moreKeys="!fixedColumnOrder!2,!needsDividers!,!label/action_previous_as_more_key,!label/action_next_as_more_key" /> + latin:moreKeys="!label/action_next_as_more_key" /> + latin:moreKeys="!label/action_previous_as_more_key" /> @@ -119,7 +119,7 @@ > + latin:moreKeys="!label/more_keys_for_less_than" /> + latin:moreKeys="!label/more_keys_for_greater_than" /> diff --git a/java/res/xml/keys_parentheses.xml b/java/res/xml/keys_parentheses.xml index 502a84ede..17d72859c 100644 --- a/java/res/xml/keys_parentheses.xml +++ b/java/res/xml/keys_parentheses.xml @@ -24,9 +24,9 @@ + latin:moreKeys="!label/more_keys_for_left_parenthesis" /> + latin:moreKeys="!label/more_keys_for_right_parenthesis" /> diff --git a/java/res/xml/row_qwerty4.xml b/java/res/xml/row_qwerty4.xml index b2b47e9b5..c08518079 100644 --- a/java/res/xml/row_qwerty4.xml +++ b/java/res/xml/row_qwerty4.xml @@ -51,9 +51,9 @@ diff --git a/java/res/xml/rowkeys_azerty1.xml b/java/res/xml/rowkeys_azerty1.xml index 99834321f..50a0162de 100644 --- a/java/res/xml/rowkeys_azerty1.xml +++ b/java/res/xml/rowkeys_azerty1.xml @@ -25,47 +25,47 @@ latin:keyLabel="a" latin:keyHintLabel="1" latin:additionalMoreKeys="1" - latin:moreKeys="@string/more_keys_for_a" /> + latin:moreKeys="!label/more_keys_for_a" /> + latin:moreKeys="!label/more_keys_for_z" /> + latin:moreKeys="!label/more_keys_for_e" /> + latin:moreKeys="!label/more_keys_for_r" /> + latin:moreKeys="!label/more_keys_for_t" /> + latin:moreKeys="!label/more_keys_for_y" /> + latin:moreKeys="!label/more_keys_for_u" /> + latin:moreKeys="!label/more_keys_for_i" /> + latin:moreKeys="!label/more_keys_for_o" /> + latin:moreKeys="!label/more_keys_for_s" /> + latin:moreKeys="!label/more_keys_for_d" /> + latin:moreKeys="!label/more_keys_for_g" /> + latin:moreKeys="!label/more_keys_for_h" /> + latin:moreKeys="!label/more_keys_for_j" /> + latin:moreKeys="!label/more_keys_for_k" /> + latin:moreKeys="!label/more_keys_for_l" /> diff --git a/java/res/xml/rowkeys_azerty3.xml b/java/res/xml/rowkeys_azerty3.xml index b81c3c5a1..35e9b195f 100644 --- a/java/res/xml/rowkeys_azerty3.xml +++ b/java/res/xml/rowkeys_azerty3.xml @@ -23,20 +23,20 @@ > + latin:moreKeys="!label/more_keys_for_w" /> + latin:moreKeys="!label/more_keys_for_c" /> + latin:moreKeys="!label/more_keys_for_v" /> + latin:moreKeys="!label/more_keys_for_n" /> diff --git a/java/res/xml/rowkeys_east_slavic1.xml b/java/res/xml/rowkeys_east_slavic1.xml index 04c6ef6ab..dd83c0250 100644 --- a/java/res/xml/rowkeys_east_slavic1.xml +++ b/java/res/xml/rowkeys_east_slavic1.xml @@ -36,7 +36,7 @@ latin:keyLabel="у" latin:keyHintLabel="3" latin:additionalMoreKeys="3" - latin:moreKeys="@string/more_keys_for_cyrillic_u" /> + latin:moreKeys="!label/more_keys_for_cyrillic_u" /> + latin:moreKeys="!label/more_keys_for_cyrillic_ye" /> + latin:moreKeys="!label/more_keys_for_cyrillic_en" /> @@ -76,5 +76,5 @@ + latin:moreKeys="!label/more_keys_for_cyrillic_ha" /> diff --git a/java/res/xml/rowkeys_east_slavic2.xml b/java/res/xml/rowkeys_east_slavic2.xml index 57b037367..75d7d939d 100644 --- a/java/res/xml/rowkeys_east_slavic2.xml +++ b/java/res/xml/rowkeys_east_slavic2.xml @@ -25,8 +25,8 @@ + latin:keyLabel="!label/keylabel_for_east_slavic_row2_1" + latin:moreKeys="!label/more_keys_for_east_slavic_row2_1" /> @@ -42,7 +42,7 @@ + latin:moreKeys="!label/more_keys_for_cyrillic_o" /> diff --git a/java/res/xml/rowkeys_east_slavic3.xml b/java/res/xml/rowkeys_east_slavic3.xml index b0f7aed7b..a05e92d44 100644 --- a/java/res/xml/rowkeys_east_slavic3.xml +++ b/java/res/xml/rowkeys_east_slavic3.xml @@ -34,14 +34,14 @@ + latin:keyLabel="!label/keylabel_for_east_slavic_row3_5" /> + latin:moreKeys="!label/more_keys_for_cyrillic_soft_sign" /> diff --git a/java/res/xml/rowkeys_nordic1.xml b/java/res/xml/rowkeys_nordic1.xml index 056895f1f..ff29369d7 100644 --- a/java/res/xml/rowkeys_nordic1.xml +++ b/java/res/xml/rowkeys_nordic1.xml @@ -24,5 +24,5 @@ + latin:keyLabel="!label/keylabel_for_nordic_row1_11" /> diff --git a/java/res/xml/rowkeys_nordic2.xml b/java/res/xml/rowkeys_nordic2.xml index 0033ea1bb..52bb2f18f 100644 --- a/java/res/xml/rowkeys_nordic2.xml +++ b/java/res/xml/rowkeys_nordic2.xml @@ -24,9 +24,9 @@ + latin:keyLabel="!label/keylabel_for_nordic_row2_10" + latin:moreKeys="!label/more_keys_for_nordic_row2_10" /> + latin:keyLabel="!label/keylabel_for_nordic_row2_11" + latin:moreKeys="!label/more_keys_for_nordic_row2_11" /> diff --git a/java/res/xml/rowkeys_qwerty1.xml b/java/res/xml/rowkeys_qwerty1.xml index 19067a70c..8fb60db74 100644 --- a/java/res/xml/rowkeys_qwerty1.xml +++ b/java/res/xml/rowkeys_qwerty1.xml @@ -29,42 +29,42 @@ latin:keyLabel="w" latin:keyHintLabel="2" latin:additionalMoreKeys="2" - latin:moreKeys="@string/more_keys_for_w" /> + latin:moreKeys="!label/more_keys_for_w" /> + latin:moreKeys="!label/more_keys_for_e" /> + latin:moreKeys="!label/more_keys_for_r" /> + latin:moreKeys="!label/more_keys_for_t" /> + latin:moreKeys="!label/more_keys_for_y" /> + latin:moreKeys="!label/more_keys_for_u" /> + latin:moreKeys="!label/more_keys_for_i" /> + latin:moreKeys="!label/more_keys_for_o" /> + latin:moreKeys="!label/more_keys_for_a" /> + latin:moreKeys="!label/more_keys_for_s" /> + latin:moreKeys="!label/more_keys_for_d" /> + latin:moreKeys="!label/more_keys_for_g" /> + latin:moreKeys="!label/more_keys_for_h" /> + latin:moreKeys="!label/more_keys_for_j" /> + latin:moreKeys="!label/more_keys_for_k" /> + latin:moreKeys="!label/more_keys_for_l" /> diff --git a/java/res/xml/rowkeys_qwerty3.xml b/java/res/xml/rowkeys_qwerty3.xml index 932ea6f65..afe43f6e4 100644 --- a/java/res/xml/rowkeys_qwerty3.xml +++ b/java/res/xml/rowkeys_qwerty3.xml @@ -23,20 +23,20 @@ > + latin:moreKeys="!label/more_keys_for_z" /> + latin:moreKeys="!label/more_keys_for_c" /> + latin:moreKeys="!label/more_keys_for_v" /> + latin:moreKeys="!label/more_keys_for_n" /> diff --git a/java/res/xml/rowkeys_qwertz1.xml b/java/res/xml/rowkeys_qwertz1.xml index 3e11a7ab4..12788968a 100644 --- a/java/res/xml/rowkeys_qwertz1.xml +++ b/java/res/xml/rowkeys_qwertz1.xml @@ -29,42 +29,42 @@ latin:keyLabel="w" latin:keyHintLabel="2" latin:additionalMoreKeys="2" - latin:moreKeys="@string/more_keys_for_w" /> + latin:moreKeys="!label/more_keys_for_w" /> + latin:moreKeys="!label/more_keys_for_e" /> + latin:moreKeys="!label/more_keys_for_r" /> + latin:moreKeys="!label/more_keys_for_t" /> + latin:moreKeys="!label/more_keys_for_z" /> + latin:moreKeys="!label/more_keys_for_u" /> + latin:moreKeys="!label/more_keys_for_i" /> + latin:moreKeys="!label/more_keys_for_o" /> + latin:moreKeys="!label/more_keys_for_y" /> + latin:moreKeys="!label/more_keys_for_c" /> + latin:moreKeys="!label/more_keys_for_v" /> + latin:moreKeys="!label/more_keys_for_n" /> diff --git a/java/res/xml/rowkeys_south_slavic1.xml b/java/res/xml/rowkeys_south_slavic1.xml index e3cb89c67..7c9a3bc92 100644 --- a/java/res/xml/rowkeys_south_slavic1.xml +++ b/java/res/xml/rowkeys_south_slavic1.xml @@ -36,7 +36,7 @@ latin:keyLabel="е" latin:keyHintLabel="3" latin:additionalMoreKeys="3" - latin:moreKeys="@string/more_keys_for_cyrillic_ie" /> + latin:moreKeys="!label/more_keys_for_cyrillic_ie" /> @@ -61,7 +61,7 @@ latin:keyLabel="и" latin:keyHintLabel="8" latin:additionalMoreKeys="8" - latin:moreKeys="@string/more_keys_for_cyrillic_i" /> + latin:moreKeys="!label/more_keys_for_cyrillic_i" /> + latin:keyLabel="!label/keylabel_for_south_slavic_row2_11" /> diff --git a/java/res/xml/rowkeys_south_slavic3.xml b/java/res/xml/rowkeys_south_slavic3.xml index 97ff51ee1..d668ddf39 100644 --- a/java/res/xml/rowkeys_south_slavic3.xml +++ b/java/res/xml/rowkeys_south_slavic3.xml @@ -22,7 +22,7 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > + latin:keyLabel="!label/keylabel_for_south_slavic_row3_1" /> @@ -42,7 +42,7 @@ + latin:keyLabel="!label/keylabel_for_south_slavic_row3_8" /> diff --git a/java/res/xml/rowkeys_symbols1.xml b/java/res/xml/rowkeys_symbols1.xml index f6d6243d1..f9f8bb16c 100644 --- a/java/res/xml/rowkeys_symbols1.xml +++ b/java/res/xml/rowkeys_symbols1.xml @@ -22,43 +22,43 @@ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" > + latin:keyLabel="!label/keylabel_for_symbols_1" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_1" + latin:moreKeys="!label/more_keys_for_symbols_1" /> + latin:keyLabel="!label/keylabel_for_symbols_2" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_2" + latin:moreKeys="!label/more_keys_for_symbols_2" /> + latin:keyLabel="!label/keylabel_for_symbols_3" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_3" + latin:moreKeys="!label/more_keys_for_symbols_3" /> + latin:keyLabel="!label/keylabel_for_symbols_4" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_4" + latin:moreKeys="!label/more_keys_for_symbols_4" /> + latin:keyLabel="!label/keylabel_for_symbols_5" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_5" + latin:moreKeys="!label/more_keys_for_symbols_5" /> + latin:keyLabel="!label/keylabel_for_symbols_6" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_6" + latin:moreKeys="!label/more_keys_for_symbols_6" /> + latin:keyLabel="!label/keylabel_for_symbols_7" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_7" + latin:moreKeys="!label/more_keys_for_symbols_7" /> + latin:keyLabel="!label/keylabel_for_symbols_8" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_8" + latin:moreKeys="!label/more_keys_for_symbols_8" /> + latin:keyLabel="!label/keylabel_for_symbols_9" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_9" + latin:moreKeys="!label/more_keys_for_symbols_9" /> + latin:keyLabel="!label/keylabel_for_symbols_0" + latin:additionalMoreKeys="!label/additional_more_keys_for_symbols_0" + latin:moreKeys="!label/more_keys_for_symbols_0" /> diff --git a/java/res/xml/rowkeys_symbols2.xml b/java/res/xml/rowkeys_symbols2.xml index 1092421d8..47865a989 100644 --- a/java/res/xml/rowkeys_symbols2.xml +++ b/java/res/xml/rowkeys_symbols2.xml @@ -28,21 +28,21 @@ + latin:keyLabel="!label/keylabel_for_symbols_percent" + latin:moreKeys="!label/more_keys_for_symbols_percent" /> + latin:moreKeys="!label/more_keys_for_star" /> + U+2014: "—" EM DASH --> + latin:moreKeys="!label/more_keys_for_plus" /> diff --git a/java/res/xml/rowkeys_symbols3.xml b/java/res/xml/rowkeys_symbols3.xml index 1a484d416..4cef6b255 100644 --- a/java/res/xml/rowkeys_symbols3.xml +++ b/java/res/xml/rowkeys_symbols3.xml @@ -31,20 +31,20 @@ latin:moreKeys="¡" /> + latin:moreKeys="!label/more_keys_for_double_quote" /> + latin:moreKeys="!label/more_keys_for_single_quote" /> + latin:keyLabel="!label/keylabel_for_symbols_semicolon" + latin:moreKeys="!label/more_keys_for_symbols_semicolon" /> + latin:keyLabel="!label/keylabel_for_symbols_question" + latin:moreKeys="!label/more_keys_for_symbols_question" /> + latin:moreKeys="!label/more_keys_for_bullet" /> diff --git a/java/res/xml/rows_number_normal.xml b/java/res/xml/rows_number_normal.xml index 6f9429cd8..7015bb2d6 100644 --- a/java/res/xml/rows_number_normal.xml +++ b/java/res/xml/rows_number_normal.xml @@ -61,7 +61,7 @@ diff --git a/java/res/xml/rows_symbols4.xml b/java/res/xml/rows_symbols4.xml index 3e26650e8..de7e043e8 100644 --- a/java/res/xml/rows_symbols4.xml +++ b/java/res/xml/rows_symbols4.xml @@ -37,9 +37,9 @@ diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index fbb13c25f..254d2d618 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -189,11 +189,11 @@ public class Key { * @param row the row that this key belongs to. row's x-coordinate will be the right edge of * this key. * @param parser the XML parser containing the attributes for this key - * @param keyStyles active key styles set * @throws XmlPullParserException */ public Key(Resources res, Keyboard.Params params, Keyboard.Builder.Row row, - XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException { + XmlPullParser parser) throws XmlPullParserException { + final KeyStyles keyStyles = params.mKeyStyles; final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap; final int keyHeight = row.mRowHeight; mVerticalGap = params.mVerticalGap; @@ -210,7 +210,7 @@ public class Key { throw new XmlParseUtils.ParseException( "Unknown key style: " + styleName, parser); } else { - style = KeyStyles.getEmptyKeyStyle(); + style = keyStyles.getEmptyKeyStyle(); } final float keyXPos = row.getKeyX(keyAttr); @@ -709,8 +709,8 @@ public class Key { public static class Spacer extends Key { public Spacer(Resources res, Keyboard.Params params, Keyboard.Builder.Row row, - XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException { - super(res, params, row, parser, keyStyles); + XmlPullParser parser) throws XmlPullParserException { + super(res, params, row, parser); } /** diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 36a988bb6..4018d65d4 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -30,6 +30,7 @@ import android.view.InflateException; import com.android.inputmethod.keyboard.internal.KeyStyles; import com.android.inputmethod.keyboard.internal.KeyboardCodesSet; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.keyboard.internal.KeyboardLabelsSet; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.Utils; @@ -240,6 +241,8 @@ public class Keyboard { public final ArrayList mAltCodeKeysWhileTyping = new ArrayList(); public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet(); public final KeyboardCodesSet mCodesSet = new KeyboardCodesSet(); + public final KeyboardLabelsSet mLabelsSet = new KeyboardLabelsSet(); + public final KeyStyles mKeyStyles = new KeyStyles(mLabelsSet); public KeyboardLayoutSet.KeysCache mKeysCache; @@ -500,7 +503,6 @@ public class Keyboard { private boolean mLeftEdge; private boolean mTopEdge; private Key mRightEdgeKey = null; - private final KeyStyles mKeyStyles = new KeyStyles(); /** * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. @@ -777,7 +779,10 @@ public class Keyboard { params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0); params.mIconsSet.loadIcons(keyboardAttr); - params.mCodesSet.setLanguage(params.mId.mLocale.getLanguage()); + final String language = params.mId.mLocale.getLanguage(); + params.mCodesSet.setLanguage(language); + params.mLabelsSet.setLanguage(language); + params.mLabelsSet.loadStringResources(mContext); final int resourceId = keyboardAttr.getResourceId( R.styleable.Keyboard_touchPositionCorrectionData, 0); @@ -887,7 +892,7 @@ public class Keyboard { XmlParseUtils.checkEndTag(TAG_KEY, parser); if (DEBUG) startEndTag("<%s /> skipped", TAG_KEY); } else { - final Key key = new Key(mResources, mParams, row, parser, mKeyStyles); + final Key key = new Key(mResources, mParams, row, parser); if (DEBUG) { startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY, (key.isEnabled() ? "" : " disabled"), key, @@ -904,8 +909,7 @@ public class Keyboard { XmlParseUtils.checkEndTag(TAG_SPACER, parser); if (DEBUG) startEndTag("<%s /> skipped", TAG_SPACER); } else { - final Key.Spacer spacer = new Key.Spacer( - mResources, mParams, row, parser, mKeyStyles); + final Key.Spacer spacer = new Key.Spacer(mResources, mParams, row, parser); if (DEBUG) startEndTag("<%s />", TAG_SPACER); XmlParseUtils.checkEndTag(TAG_SPACER, parser); endKey(spacer); @@ -1210,7 +1214,7 @@ public class Keyboard { skip ? " skipped" : ""); } if (!skip) - mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser); + mParams.mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser); } finally { keyStyleAttr.recycle(); keyAttrs.recycle(); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index 51cd90549..c8ec3a4dd 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -65,9 +65,7 @@ public class KeyboardLayoutSet { private static final String DEFAULT_KEYBOARD_LAYOUT_SET = "qwerty"; private static final char KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER = ':'; - private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "xml/keyboard_layout_set_"; - private static final int DEFAULT_KEYBOARD_LAYOUT_SET_RESOURCE_ID = - R.xml.keyboard_layout_set_qwerty; + private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "keyboard_layout_set_"; private final Context mContext; private final Params mParams; @@ -319,9 +317,10 @@ public class KeyboardLayoutSet { throw new RuntimeException("Screen geometry is not specified"); if (mParams.mLocale == null) throw new RuntimeException("KeyboardLayoutSet subtype is not specified"); + final String packageName = mResources.getResourcePackageName( + R.xml.keyboard_layout_set_qwerty); final String keyboardLayoutSetName = mParams.mKeyboardLayoutSetName; - final int xmlId = KeySpecParser.getResourceId( - mResources, keyboardLayoutSetName, DEFAULT_KEYBOARD_LAYOUT_SET_RESOURCE_ID); + final int xmlId = mResources.getIdentifier(keyboardLayoutSetName, "xml", packageName); final RunInLocale job = new RunInLocale() { @Override protected Void job(Resources res) { diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java index 288fb4556..2981a8e5c 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java @@ -16,7 +16,6 @@ package com.android.inputmethod.keyboard.internal; -import android.content.res.Resources; import android.text.TextUtils; import com.android.inputmethod.keyboard.Keyboard; @@ -27,18 +26,20 @@ import java.util.ArrayList; import java.util.Arrays; /** - * String parser of moreKeys attribute of Key. - * The string is comma separated texts each of which represents one "more key". - * - String resource can be embedded into specification @string/name. This is done before parsing - * comma. + * The string parser of more keys specification. + * The specification is comma separated texts each of which represents one "more key". + * The specification might have label or string resource reference in it. These references are + * expanded before parsing comma. + * - Label reference should be a string representation of label (!label/label_name) + * - String resource reference should be a string representation of resource (!label/resource_name) * Each "more key" specification is one of the following: * - Label optionally followed by keyOutputText or code (keyLabel|keyOutputText). * - Icon followed by keyOutputText or code (!icon/icon_name|!code/code_name) * - Icon should be a string representation of icon (!icon/icon_name). - * - Code should be a code point presented by hexadecimal string prefixed with "0x". - * Or a string representation of code (!code/code_name). + * - Code should be a code point presented by hexadecimal string prefixed with "0x", or a string + * representation of code (!code/code_name). * Special character, comma ',' backslash '\', and bar '|' can be escaped by '\' character. - * Note that the character '@' and '\' are also parsed by XML parser and CSV parser as well. + * Note that the '\' is also parsed by XML parser and CSV parser as well. * See {@link KeyboardIconsSet} about icon_name. */ public class KeySpecParser { @@ -49,10 +50,8 @@ public class KeySpecParser { // Constants for parsing. private static int COMMA = ','; private static final char ESCAPE_CHAR = '\\'; - private static final char PREFIX_AT = '@'; - private static final char SUFFIX_SLASH = '/'; - private static final String PREFIX_STRING = PREFIX_AT + "string" + SUFFIX_SLASH; private static final char LABEL_END = '|'; + private static final String PREFIX_LABEL = "!label/"; private static final String PREFIX_ICON = "!icon/"; private static final String PREFIX_CODE = "!code/"; private static final String PREFIX_HEX = "0x"; @@ -341,17 +340,7 @@ public class KeySpecParser { } } - public static int getResourceId(Resources res, String name, int packageNameResId) { - String packageName = res.getResourcePackageName(packageNameResId); - int resId = res.getIdentifier(name, null, packageName); - if (resId == 0) { - throw new RuntimeException("Unknown resource: " + name); - } - return resId; - } - - private static String resolveStringResource(String rawText, Resources res, - int packageNameResId) { + public static String resolveLabelReference(String rawText, KeyboardLabelsSet labelsSet) { int level = 0; String text = rawText; StringBuilder sb; @@ -362,21 +351,20 @@ public class KeySpecParser { } final int size = text.length(); - if (size < PREFIX_STRING.length()) { + if (size < PREFIX_LABEL.length()) { return text; } sb = null; for (int pos = 0; pos < size; pos++) { final char c = text.charAt(pos); - if (c == PREFIX_AT && text.startsWith(PREFIX_STRING, pos)) { + if (text.startsWith(PREFIX_LABEL, pos) && labelsSet != null) { if (sb == null) { sb = new StringBuilder(text.substring(0, pos)); } - final int end = searchResourceNameEnd(text, pos + PREFIX_STRING.length()); - final String resName = text.substring(pos + 1, end); - final int resId = getResourceId(res, resName, packageNameResId); - sb.append(res.getString(resId)); + final int end = searchLabelNameEnd(text, pos + PREFIX_LABEL.length()); + final String name = text.substring(pos + PREFIX_LABEL.length(), end); + sb.append(labelsSet.getLabel(name)); pos = end - 1; } else if (c == ESCAPE_CHAR) { if (sb != null) { @@ -397,7 +385,7 @@ public class KeySpecParser { return text; } - private static int searchResourceNameEnd(String text, int start) { + private static int searchLabelNameEnd(String text, int start) { final int size = text.length(); for (int pos = start; pos < size; pos++) { final char c = text.charAt(pos); @@ -410,8 +398,8 @@ public class KeySpecParser { return size; } - public static String[] parseCsvString(String rawText, Resources res, int packageNameResId) { - final String text = resolveStringResource(rawText, res, packageNameResId); + public static String[] parseCsvString(String rawText, KeyboardLabelsSet labelsSet) { + final String text = resolveLabelReference(rawText, labelsSet); final int size = text.length(); if (size == 0) { return null; diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java index 405b7ad05..8e0b21607 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java @@ -34,24 +34,55 @@ public class KeyStyles { private final HashMap mStyles = new HashMap(); - private static final KeyStyle EMPTY_KEY_STYLE = new EmptyKeyStyle(); - public interface KeyStyle { - public String[] getStringArray(TypedArray a, int index); - public String getString(TypedArray a, int index); - public int getInt(TypedArray a, int index, int defaultValue); - public int getFlag(TypedArray a, int index); + private final KeyboardLabelsSet mLabelsSet; + private final KeyStyle mEmptyKeyStyle; + + public KeyStyles(KeyboardLabelsSet labelsSet) { + mLabelsSet = labelsSet; + mEmptyKeyStyle = new EmptyKeyStyle(labelsSet); } - static class EmptyKeyStyle implements KeyStyle { + public static abstract class KeyStyle { + protected final KeyboardLabelsSet mLabelsSet; + + public KeyStyle(KeyboardLabelsSet labelsSet) { + mLabelsSet = labelsSet; + } + + public abstract String[] getStringArray(TypedArray a, int index); + public abstract String getString(TypedArray a, int index); + public abstract int getInt(TypedArray a, int index, int defaultValue); + public abstract int getFlag(TypedArray a, int index); + + protected String parseString(TypedArray a, int index) { + if (a.hasValue(index)) { + return KeySpecParser.resolveLabelReference(a.getString(index), mLabelsSet); + } + return null; + } + + protected String[] parseStringArray(TypedArray a, int index) { + if (a.hasValue(index)) { + return KeySpecParser.parseCsvString(a.getString(index), mLabelsSet); + } + return null; + } + } + + private static class EmptyKeyStyle extends KeyStyle { + public EmptyKeyStyle(KeyboardLabelsSet labelsSet) { + super(labelsSet); + } + @Override public String[] getStringArray(TypedArray a, int index) { - return KeyStyles.parseStringArray(a, index); + return parseStringArray(a, index); } @Override public String getString(TypedArray a, int index) { - return a.getString(index); + return parseString(a, index); } @Override @@ -65,9 +96,13 @@ public class KeyStyles { } } - static class DeclaredKeyStyle implements KeyStyle { + private static class DeclaredKeyStyle extends KeyStyle { private final HashMap mStyleAttributes = new HashMap(); + public DeclaredKeyStyle(KeyboardLabelsSet labelsSet) { + super(labelsSet); + } + @Override public String[] getStringArray(TypedArray a, int index) { if (a.hasValue(index)) { @@ -79,7 +114,7 @@ public class KeyStyles { @Override public String getString(TypedArray a, int index) { if (a.hasValue(index)) { - return a.getString(index); + return parseString(a, index); } return (String)mStyleAttributes.get(index); } @@ -120,7 +155,7 @@ public class KeyStyles { private void readString(TypedArray a, int index) { if (a.hasValue(index)) { - mStyleAttributes.put(index, a.getString(index)); + mStyleAttributes.put(index, parseString(a, index)); } } @@ -131,16 +166,15 @@ public class KeyStyles { } private void readFlag(TypedArray a, int index) { - final Integer value = (Integer)mStyleAttributes.get(index); if (a.hasValue(index)) { + final Integer value = (Integer)mStyleAttributes.get(index); mStyleAttributes.put(index, a.getInt(index, 0) | (value != null ? value : 0)); } } private void readStringArray(TypedArray a, int index) { - final String[] value = parseStringArray(a, index); - if (value != null) { - mStyleAttributes.put(index, value); + if (a.hasValue(index)) { + mStyleAttributes.put(index, parseStringArray(a, index)); } } @@ -149,14 +183,6 @@ public class KeyStyles { } } - static String[] parseStringArray(TypedArray a, int index) { - if (a.hasValue(index)) { - return KeySpecParser.parseCsvString( - a.getString(index), a.getResources(), R.string.english_ime_name); - } - return null; - } - public void parseKeyStyleAttributes(TypedArray keyStyleAttr, TypedArray keyAttrs, XmlPullParser parser) throws XmlPullParserException { final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName); @@ -169,7 +195,7 @@ public class KeyStyles { } } - final DeclaredKeyStyle style = new DeclaredKeyStyle(); + final DeclaredKeyStyle style = new DeclaredKeyStyle(mLabelsSet); if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) { final String parentStyle = keyStyleAttr.getString( R.styleable.Keyboard_KeyStyle_parentStyle); @@ -188,7 +214,7 @@ public class KeyStyles { return mStyles.get(styleName); } - public static KeyStyle getEmptyKeyStyle() { - return EMPTY_KEY_STYLE; + public KeyStyle getEmptyKeyStyle() { + return mEmptyKeyStyle; } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardLabelsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardLabelsSet.java new file mode 100644 index 000000000..a46f3bf1b --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardLabelsSet.java @@ -0,0 +1,2477 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import android.content.Context; +import android.content.res.Resources; + +import com.android.inputmethod.latin.R; + +import java.util.HashMap; + +/** + * !!!!! DO NOT EDIT THIS FILE !!!!! + * This file is generated by tools/makelabel. + */ +public final class KeyboardLabelsSet { + // Language to labels map. + private static final HashMap sLocaleToLabelsMap = + new HashMap(); + private static final HashMap sNameToIdMap = new HashMap(); + + private String[] mLabels; + // Resource name to label map. + private HashMap mResourceNameToLabelsMap = new HashMap(); + + public void setLanguage(final String language) { + mLabels = sLocaleToLabelsMap.get(language); + if (mLabels == null) { + mLabels = LANGUAGE_DEFAULT; + } + } + + public void loadStringResources(Context context) { + loadStringResourcesInternal(context, RESOURCE_NAMES, R.string.english_ime_name); + } + + /* package for test */ + void loadStringResourcesInternal(Context context, final String[] resourceNames, + int referenceId) { + final Resources res = context.getResources(); + final String packageName = res.getResourcePackageName(referenceId); + for (final String resName : resourceNames) { + final int resId = res.getIdentifier(resName, "string", packageName); + mResourceNameToLabelsMap.put(resName, res.getString(resId)); + } + } + + public String getLabel(final String name) { + if (mResourceNameToLabelsMap.containsKey(name)) { + return mResourceNameToLabelsMap.get(name); + } + final Integer id = sNameToIdMap.get(name); + if (id == null) throw new RuntimeException("Unknown label: " + name); + final String label = (id < mLabels.length) ? mLabels[id] : null; + return (label == null) ? LANGUAGE_DEFAULT[id] : label; + } + + private static final String[] RESOURCE_NAMES = { + // These labels' name should be aligned with the @string/ in values/strings.xml. + // Labels for action. + "label_go_key", + // "label_search_key", + "label_send_key", + "label_next_key", + "label_done_key", + "label_previous_key", + // Other labels. + "label_to_alpha_key", + "label_to_symbol_key", + "label_to_symbol_with_microphone_key", + "label_pause_key", + "label_wait_key", + }; + + private static final String[] NAMES = { + /* 0 */ "more_keys_for_a", + /* 1 */ "more_keys_for_e", + /* 2 */ "more_keys_for_i", + /* 3 */ "more_keys_for_o", + /* 4 */ "more_keys_for_u", + /* 5 */ "more_keys_for_s", + /* 6 */ "more_keys_for_n", + /* 7 */ "more_keys_for_c", + /* 8 */ "more_keys_for_y", + /* 9 */ "more_keys_for_d", + /* 10 */ "more_keys_for_r", + /* 11 */ "more_keys_for_t", + /* 12 */ "more_keys_for_z", + /* 13 */ "more_keys_for_k", + /* 14 */ "more_keys_for_l", + /* 15 */ "more_keys_for_g", + /* 16 */ "more_keys_for_v", + /* 17 */ "more_keys_for_h", + /* 18 */ "more_keys_for_j", + /* 19 */ "more_keys_for_w", + /* 20 */ "keylabel_for_nordic_row1_11", + /* 21 */ "keylabel_for_nordic_row2_10", + /* 22 */ "keylabel_for_nordic_row2_11", + /* 23 */ "more_keys_for_nordic_row2_10", + /* 24 */ "more_keys_for_nordic_row2_11", + /* 25 */ "keylabel_for_east_slavic_row1_9", + /* 26 */ "keylabel_for_east_slavic_row2_1", + /* 27 */ "keylabel_for_east_slavic_row3_5", + /* 28 */ "more_keys_for_cyrillic_u", + /* 29 */ "more_keys_for_cyrillic_ye", + /* 30 */ "more_keys_for_cyrillic_en", + /* 31 */ "more_keys_for_cyrillic_ha", + /* 32 */ "more_keys_for_east_slavic_row2_1", + /* 33 */ "more_keys_for_cyrillic_o", + /* 34 */ "more_keys_for_cyrillic_soft_sign", + /* 35 */ "keylabel_for_south_slavic_row1_6", + /* 36 */ "keylabel_for_south_slavic_row2_11", + /* 37 */ "keylabel_for_south_slavic_row3_1", + /* 38 */ "keylabel_for_south_slavic_row3_8", + /* 39 */ "more_keys_for_cyrillic_ie", + /* 40 */ "more_keys_for_cyrillic_i", + /* 41 */ "more_keys_for_single_quote", + /* 42 */ "more_keys_for_double_quote", + /* 43 */ "more_keys_for_tablet_double_quote", + /* 44 */ "more_keys_for_currency_dollar", + /* 45 */ "more_keys_for_currency_euro", + /* 46 */ "more_keys_for_currency_pound", + /* 47 */ "more_keys_for_currency_general", + /* 48 */ "more_keys_for_smiley", + /* 49 */ "more_keys_for_punctuation", + /* 50 */ "keyhintlabel_for_punctuation", + /* 51 */ "keylabel_for_popular_domain", + /* 52 */ "more_keys_for_popular_domain", + /* 53 */ "keylabel_for_symbols_1", + /* 54 */ "keylabel_for_symbols_2", + /* 55 */ "keylabel_for_symbols_3", + /* 56 */ "keylabel_for_symbols_4", + /* 57 */ "keylabel_for_symbols_5", + /* 58 */ "keylabel_for_symbols_6", + /* 59 */ "keylabel_for_symbols_7", + /* 60 */ "keylabel_for_symbols_8", + /* 61 */ "keylabel_for_symbols_9", + /* 62 */ "keylabel_for_symbols_0", + /* 63 */ "additional_more_keys_for_symbols_1", + /* 64 */ "additional_more_keys_for_symbols_2", + /* 65 */ "additional_more_keys_for_symbols_3", + /* 66 */ "additional_more_keys_for_symbols_4", + /* 67 */ "additional_more_keys_for_symbols_5", + /* 68 */ "additional_more_keys_for_symbols_6", + /* 69 */ "additional_more_keys_for_symbols_7", + /* 70 */ "additional_more_keys_for_symbols_8", + /* 71 */ "additional_more_keys_for_symbols_9", + /* 72 */ "additional_more_keys_for_symbols_0", + /* 73 */ "more_keys_for_symbols_1", + /* 74 */ "more_keys_for_symbols_2", + /* 75 */ "more_keys_for_symbols_3", + /* 76 */ "more_keys_for_symbols_4", + /* 77 */ "more_keys_for_symbols_5", + /* 78 */ "more_keys_for_symbols_6", + /* 79 */ "more_keys_for_symbols_7", + /* 80 */ "more_keys_for_symbols_8", + /* 81 */ "more_keys_for_symbols_9", + /* 82 */ "more_keys_for_symbols_0", + /* 83 */ "more_keys_for_am_pm", + /* 84 */ "settings_as_more_key", + /* 85 */ "keylabel_for_comma", + /* 86 */ "more_keys_for_comma", + /* 87 */ "action_next_as_more_key", + /* 88 */ "action_previous_as_more_key", + /* 89 */ "keylabel_for_symbols_question", + /* 90 */ "keylabel_for_symbols_semicolon", + /* 91 */ "keylabel_for_symbols_percent", + /* 92 */ "more_keys_for_symbols_question", + /* 93 */ "more_keys_for_symbols_semicolon", + /* 94 */ "more_keys_for_symbols_percent", + /* 95 */ "keylabel_for_tablet_comma", + /* 96 */ "keyhintlabel_for_tablet_comma", + /* 97 */ "more_keys_for_tablet_comma", + /* 98 */ "keyhintlabel_for_tablet_period", + /* 99 */ "more_keys_for_tablet_period", + /* 100 */ "keylabel_for_apostrophe", + /* 101 */ "keylabel_for_dash", + /* 102 */ "keyhintlabel_for_apostrophe", + /* 103 */ "keyhintlabel_for_dash", + /* 104 */ "more_keys_for_apostrophe", + /* 105 */ "more_keys_for_dash", + /* 106 */ "more_keys_for_bullet", + /* 107 */ "more_keys_for_star", + /* 108 */ "more_keys_for_plus", + /* 109 */ "more_keys_for_left_parenthesis", + /* 110 */ "more_keys_for_right_parenthesis", + /* 111 */ "more_keys_for_less_than", + /* 112 */ "more_keys_for_greater_than", + /* 113 */ "label_to_more_symbol_key", + /* 114 */ "label_to_more_symbol_for_tablet_key", + /* 115 */ "label_tab_key", + /* 116 */ "label_to_phone_numeric_key", + /* 117 */ "label_to_phone_symbols_key", + /* 118 */ "label_time_am", + /* 119 */ "label_time_pm", + }; + + private static final String EMPTY = ""; + + /* Default labels */ + private static final String[] LANGUAGE_DEFAULT = { + /* 0~ */ + EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, + EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, + EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, + EMPTY, EMPTY, + /* ~40 */ + /* 41 */ "!fixedColumnOrder!4,\u2018,\u2019,\u201A,\u201B", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. !fixedColumnOrder!6,“,”,„,‟,«,» + /* 42 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB,\u00BB", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. !fixedColumnOrder!6,“,”,„,‟,«,»,‘,’,‚,‛ + /* 43 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB,\u00BB,\u2018,\u2019,\u201A,\u201B", + // U+00A2: "¢" CENT SIGN + // U+00A3: "£" POUND SIGN + // U+20AC: "€" EURO SIGN + // U+00A5: "¥" YEN SIGN + // U+20B1: "₱" PESO SIGN + /* 44 */ "\u00A2,\u00A3,\u20AC,\u00A5,\u20B1", + /* 45 */ "\u00A2,\u00A3,$,\u00A5,\u20B1", + /* 46 */ "\u00A2,$,\u20AC,\u00A5,\u20B1", + /* 47 */ "\u00A2,$,\u20AC,\u00A3,\u00A5,\u20B1", + /* 48 */ "!fixedColumnOrder!5,!hasLabels!,=-O|=-O ,:-P|:-P ,;-)|;-) ,:-(|:-( ,:-)|:-) ,:-!|:-! ,:-$|:-$ ,B-)|B-) ,:O|:O ,:-*|:-* ,:-D|:-D ,:\'(|:\'( ,:-\\\\|:-\\\\ ,O:-)|O:-) ,:-[|:-[ ", + /* 49 */ "!fixedColumnOrder!8,\",\',#,-,:,!,\\,,?,@,&,\\%,+,;,/,(,)", + /* 50 */ EMPTY, + /* 51 */ ".com", + // popular web domains for the locale - most popular, displayed on the keyboard + /* 52 */ "!hasLabels!,.net,.org,.gov,.edu", + /* 53 */ "1", + /* 54 */ "2", + /* 55 */ "3", + /* 56 */ "4", + /* 57 */ "5", + /* 58 */ "6", + /* 59 */ "7", + /* 60 */ "8", + /* 61 */ "9", + /* 62 */ "0", + /* 63~ */ + EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, + /* ~72 */ + // U+00B9: "¹" SUPERSCRIPT ONE + // U+00BD: "½" VULGAR FRACTION ONE HALF + // U+2153: "⅓" VULGAR FRACTION ONE THIRD + // U+00BC: "¼" VULGAR FRACTION ONE QUARTER + // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH + /* 73 */ "\u00B9,\u00BD,\u2153,\u00BC,\u215B", + // U+00B2: "²" SUPERSCRIPT TWO + // U+2154: "⅔" VULGAR FRACTION TWO THIRDS + /* 74 */ "\u00B2,\u2154", + // U+00B3: "³" SUPERSCRIPT THREE + // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS + // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS + /* 75 */ "\u00B3,\u00BE,\u215C", + // U+2074: "⁴" SUPERSCRIPT FOUR + /* 76 */ "\u2074", + // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS + /* 77 */ "\u215D", + /* 78 */ EMPTY, + // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS + /* 79 */ "\u215E", + /* 80 */ EMPTY, + /* 81 */ EMPTY, + // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N + // U+2205: "∅" EMPTY SET + /* 82 */ "\u207F,\u2205", + /* 83 */ "!fixedColumnOrder!2,!hasLabels!,!label/label_time_am,!label/label_time_pm", + /* 84 */ "!icon/settingsKey|!code/key_settings", + /* 85 */ ",", + /* 86 */ EMPTY, + /* 87 */ "!hasLabels!,!label/label_next_key|!code/key_action_next", + /* 88 */ "!hasLabels!,!label/label_previous_key|!code/key_action_previous", + /* 89 */ "?", + /* 90 */ ";", + /* 91 */ "%", + // U+00BF: "¿" INVERTED QUESTION MARK + /* 92 */ "\u00BF", + /* 93 */ EMPTY, + // U+2030: "‰" PER MILLE SIGN + /* 94 */ "\u2030", + /* 95 */ ",", + /* 96 */ "!", + /* 97 */ "!", + /* 98 */ "?", + /* 99 */ "?", + /* 100 */ "\'", + /* 101 */ "-", + /* 102 */ "\"", + /* 103 */ "_", + /* 104 */ "\"", + /* 105 */ "_", + // U+266A: "♪" EIGHTH NOTE + // U+2665: "♥" BLACK HEART SUIT + // U+2660: "♠" BLACK SPADE SUIT + // U+2666: "♦" BLACK DIAMOND SUIT + // U+2663: "♣" BLACK CLUB SUIT + /* 106 */ "\u266A,\u2665,\u2660,\u2666,\u2663", + // U+2020: "†" DAGGER + // U+2021: "‡" DOUBLE DAGGER + // U+2605: "★" BLACK STAR + /* 107 */ "\u2020,\u2021,\u2605", + // U+00B1: "±" PLUS-MINUS SIGN + /* 108 */ "\u00B1", + // The all letters need to be mirrored are found at + // http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt + /* 109 */ "!fixedColumnOrder!3,<,{,[", + /* 110 */ "!fixedColumnOrder!3,>,},]", + // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK + // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + // U+2264: "≤" LESS-THAN OR EQUAL TO + // U+2265: "≥" GREATER-THAN EQUAL TO + // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + // The following characters don't need BIDI mirroring. + // U+2018: "‘" LEFT SINGLE QUOTATION MARK + // U+2019: "’" RIGHT SINGLE QUOTATION MARK + // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK + // U+201B: "‛" SINGLE HIGH-REVERSED-9 QUOTATION MARK + // U+201C: "“" LEFT DOUBLE QUOTATION MARK + // U+201D: "”" RIGHT DOUBLE QUOTATION MARK + // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK + // U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK + /* 111 */ "!fixedColumnOrder!3,\u2039,\u2264,\u00AB", + /* 112 */ "!fixedColumnOrder!3,\u203A,\u2265,\u00BB", + // Label for "switch to more symbol" modifier key. Must be short to fit on key! + /* 113 */ "= \\ <", + // Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! + /* 114 */ "~ \\ {", + // Label for "Tab" key. Must be short to fit on key! + /* 115 */ "Tab", + // Label for "switch to phone numeric" key. Must be short to fit on key! + /* 116 */ "123", + // Label for "switch to phone symbols" key. Must be short to fit on key! U+FF0A: "*" FULLWIDTH ASTERISK + // U+FF03: "#" FULLWIDTH NUMBER SIGN + /* 117 */ "\uFF0A\uFF03", + // Key label for "ante meridiem" + /* 118 */ "AM", + // Key label for "post meridiem" + /* 119 */ "PM", + }; + + /* Language ar: Arabic */ + private static final String[] LANGUAGE_ar = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~41 */ + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK “,”,„,‟,«|»,»|« + /* 42 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB|\u00BB,\u00BB|\u00AB", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK !fixedColumnOrder!6,“,”,„,‟,«|»,»|«;,‘,’,‚,‛ + /* 43 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB|\u00BB,\u00BB|\u00AB,\u2018,\u2019,\u201A,\u201B", + /* 44~ */ + null, null, null, null, null, + /* ~48 */ + // U+061F: "؟" ARABIC QUESTION MARK + // U+060C: "،" ARABIC COMMA + // U+061B: "؛" ARABIC SEMICOLON U+0650: "ِ" ARABIC KASRA + // U+064E: "َ" ARABIC FATHA + // U+064D: "ٍ" ARABIC KASRATAN + // U+064B: "ً" ARABIC FATHATAN + // U+0656: "ٖ" ARABIC SUBSCRIPT ALEF + // U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF + // U+0655: "ٕ" ARABIC HAMZA BELOW + // U+0654: "ٔ" ARABIC HAMZA ABOVE U+064F: "ُ" ARABIC DAMMA + // U+064C: "ٌ" ARABIC DAMMATAN + // U+0651: "ّ" ARABIC SHADDA + // U+0652: "ْ" ARABIC SUKUN + // U+0653: "ٓ" ARABIC MADDAH ABOVE + // U+0640: "ـ" ARABIC TATWEEL In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. + /* 49 */ "!fixedColumnOrder!8,\",\',-,:,!,\u061F,\u060C,\u061B,\u0650,\u064E,\u064D,\u064B,\u0656,\u0670,\u0655,\u0654,\u064F,\u064C,\u0651,\u0652,\u0653,\u0640\u0640\u0640|\u0640,/", + /* 50 */ "\u064B", + /* 51 */ null, + /* 52 */ null, + // U+0661: "١" ARABIC-INDIC DIGIT ONE + /* 53 */ "\u0661", + // U+0662: "٢" ARABIC-INDIC DIGIT TWO + /* 54 */ "\u0662", + // U+0663: "٣" ARABIC-INDIC DIGIT THREE + /* 55 */ "\u0663", + // U+0664: "٤" ARABIC-INDIC DIGIT FOUR + /* 56 */ "\u0664", + // U+0665: "٥" ARABIC-INDIC DIGIT FIVE + /* 57 */ "\u0665", + // U+0666: "٦" ARABIC-INDIC DIGIT SIX + /* 58 */ "\u0666", + // U+0667: "٧" ARABIC-INDIC DIGIT SEVEN + /* 59 */ "\u0667", + // U+0668: "٨" ARABIC-INDIC DIGIT EIGHT + /* 60 */ "\u0668", + // U+0669: "٩" ARABIC-INDIC DIGIT NINE + /* 61 */ "\u0669", + // U+0660: "٠" ARABIC-INDIC DIGIT ZERO + /* 62 */ "\u0660", + /* 63 */ "1", + /* 64 */ "2", + /* 65 */ "3", + /* 66 */ "4", + /* 67 */ "5", + /* 68 */ "6", + /* 69 */ "7", + /* 70 */ "8", + /* 71 */ "9", + // U+066B: "٫" ARABIC DECIMAL SEPARATOR + // U+066C: "٬" ARABIC THOUSANDS SEPARATOR + /* 72 */ "0,\u066B,\u066C", + /* 73~ */ + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~84 */ + // U+060C: "،" ARABIC COMMA + /* 85 */ "\u060C", + /* 86 */ "\\,", + /* 87 */ null, + /* 88 */ null, + /* 89 */ "\u061F", + /* 90 */ "\u061B", + // U+066A: "٪" ARABIC PERCENT SIGN + /* 91 */ "\u066A", + /* 92 */ "?", + /* 93 */ ";", + // U+2030: "‰" PER MILLE SIGN + /* 94 */ "%,\u2030", + /* 95~ */ + null, null, null, null, null, + /* ~99 */ + // U+060C: "،" ARABIC COMMA + // U+061B: "؛" ARABIC SEMICOLON + // U+061F: "؟" ARABIC QUESTION MARK + /* 100 */ "\u060C", + /* 101 */ ".", + /* 102 */ "\u061F", + /* 103 */ "\u064B", + /* 104 */ "\u061F,\u061B,!,:,-,/,\',\"", + // U+0651: "ّ" ARABIC SHADDA + // U+0652: "ْ" ARABIC SUKUN + // U+064C: "ٌ" ARABIC DAMMATAN + // U+0653: "ٓ" ARABIC MADDAH ABOVE + // U+064F: "ُ" ARABIC DAMMA U+0650: "ِ" ARABIC KASRA + // U+064E: "َ" ARABIC FATHA + // U+064B: "ً" ARABIC FATHATAN + // U+0640: "ـ" ARABIC TATWEEL + // U+064D: "ٍ" ARABIC KASRATAN U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF + // U+0656: "ٖ" ARABIC SUBSCRIPT ALEF + // U+0654: "ٔ" ARABIC HAMZA ABOVE + // U+0655: "ٕ" ARABIC HAMZA BELOW In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. + /* 105 */ "\u0651,\u0652,\u064C,\u0653,\u064F,\u0650,\u064E,\u064B,\u0640\u0640\u0640|\u0640,\u064D,\u0654,\u0656,\u0655,\u0670", + // U+266A: "♪" EIGHTH NOTE + /* 106 */ "\u266A", + // U+2605: "★" BLACK STAR + // U+066D: "٭" ARABIC FIVE POINTED STAR + /* 107 */ "\u2605,\u066D", + /* 108 */ null, + // The all letters need to be mirrored are found at + // http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt U+FD3E: "﴾" ORNATE LEFT PARENTHESIS + // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS TODO: DroidSansArabic lacks the glyph of U+FD3E ORNATE LEFT PARENTHESIS TODO: DroidSansArabic lacks the glyph of U+FD3F ORNATE RIGHT PARENTHESIS + /* 109 */ "!fixedColumnOrder!4,\uFD3E|\uFD3F,<|>,{|},[|]", + /* 110 */ "!fixedColumnOrder!4,\uFD3F|\uFD3E,>|<,}|{,]|[", + // U+2264: "≤" LESS-THAN OR EQUAL TO + // U+2265: "≥" GREATER-THAN EQUAL TO + // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK + // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + // The following characters don't need BIDI mirroring. + // U+2018: "‘" LEFT SINGLE QUOTATION MARK + // U+2019: "’" RIGHT SINGLE QUOTATION MARK + // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK + // U+201B: "‛" SINGLE HIGH-REVERSED-9 QUOTATION MARK + // U+201C: "“" LEFT DOUBLE QUOTATION MARK + // U+201D: "”" RIGHT DOUBLE QUOTATION MARK + // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK + // U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK + /* 111 */ "!fixedColumnOrder!3,\u2039|\u203A,\u2264|\u2265,\u00AB|\u00BB", + /* 112 */ "!fixedColumnOrder!3,\u203A|\u2039,\u2265|\u2264,\u00BB|\u00AB", + }; + + /* Language be: Belarusian */ + private static final String[] LANGUAGE_be = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, + /* ~24 */ + // U+045E: "ў" CYRILLIC SMALL LETTER SHORT U + /* 25 */ "\u045E", + // U+044B: "ы" CYRILLIC SMALL LETTER YERU + /* 26 */ "\u044B", + // U+0456: "і" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + /* 27 */ "\u0456", + /* 28~ */ + null, null, null, + /* ~30 */ + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 31 */ "\u044A", + /* 32 */ null, + /* 33 */ null, + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 34 */ "\u044A", + }; + + /* Language ca: Catalan */ + private static final String[] LANGUAGE_ca = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00AA: "ª" FEMININE ORDINAL INDICATOR + /* 0 */ "\u00E0,\u00E1,\u00E4,\u00E2,\u00E3,\u00E5,\u0105,\u00E6,\u0101,\u00AA", + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E8,\u00E9,\u00EB,\u00EA,\u0119,\u0117,\u0113", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B", + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+00BA: "º" MASCULINE ORDINAL INDICATOR + /* 3 */ "\u00F2,\u00F3,\u00F6,\u00F4,\u00F5,\u00F8,\u0153,\u014D,\u00BA", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B", + /* 5 */ null, + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u00F1,\u0144", + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + /* 7 */ "\u00E7,\u0107,\u010D", + /* 8~ */ + null, null, null, null, null, null, + /* ~13 */ + // U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + /* 14 */ "\u0140,\u0142", + }; + + /* Language cs: Czech */ + private static final String[] LANGUAGE_cs = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E1,\u00E0,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u011B,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00ED,\u00EE,\u00EF,\u00EC,\u012F,\u012B", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F3,\u00F6,\u00F4,\u00F2,\u00F5,\u0153,\u00F8,\u014D", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u016F,\u00FB,\u00FC,\u00F9,\u016B", + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + /* 5 */ "\u0161,\u00DF,\u015B", + // U+0148: "ň" LATIN SMALL LETTER N WITH CARON + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u0148,\u00F1,\u0144", + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u010D,\u00E7,\u0107", + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + /* 9 */ "\u010F", + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + /* 10 */ "\u0159", + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + /* 11 */ "\u0165", + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + /* 12 */ "\u017E,\u017A,\u017C", + }; + + /* Language da: Danish */ + private static final String[] LANGUAGE_da = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E1,\u00E4,\u00E0,\u00E2,\u00E3,\u0101", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + /* 1 */ "\u00E9,\u00EB", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + /* 2 */ "\u00ED,\u00EF", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F3,\u00F4,\u00F2,\u00F5,\u0153,\u014D", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u00FB,\u00F9,\u016B", + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u00DF,\u015B,\u0161", + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u00F1,\u0144", + /* 7 */ null, + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+00F0: "ð" LATIN SMALL LETTER ETH + /* 9 */ "\u00F0", + /* 10~ */ + null, null, null, null, + /* ~13 */ + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + /* 14 */ "\u0142", + /* 15~ */ + null, null, null, null, null, + /* ~19 */ + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + /* 20 */ "\u00E5", + // U+00E6: "æ" LATIN SMALL LETTER AE + /* 21 */ "\u00E6", + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 22 */ "\u00F8", + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + /* 23 */ "\u00E4", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + /* 24 */ "\u00F6", + }; + + /* Language de: German */ + private static final String[] LANGUAGE_de = { + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E4,\u00E2,\u00E0,\u00E1,\u00E6,\u00E3,\u00E5,\u0101", + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + /* 1 */ "\u0117", + /* 2 */ null, + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F6,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u00F8,\u014D", + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B", + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u00DF,\u015B,\u0161", + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u00F1,\u0144", + }; + + /* Language en: English */ + private static final String[] LANGUAGE_en = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E0,\u00E1,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101", + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0103", + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + /* 2 */ "\u00EE,\u00EF,\u00ED,\u012B,\u00EC", + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + /* 3 */ "\u00F4,\u00F6,\u00F2,\u00F3,\u0153,\u00F8\u014D,\u00F5", + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FB,\u00FC,\u00F9,\u00FA,\u016B", + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + /* 5 */ "\u00DF", + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + /* 6 */ "\u00F1", + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + /* 7 */ "\u00E7", + }; + + /* Language es: Spanish */ + private static final String[] LANGUAGE_es = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00AA: "ª" FEMININE ORDINAL INDICATOR + /* 0 */ "\u00E1,\u00E0,\u00E4,\u00E2,\u00E3,\u00E5,\u0105,\u00E6,\u0101,\u00AA", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u00E8,\u00EB,\u00EA,\u0119,\u0117,\u0113", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+00BA: "º" MASCULINE ORDINAL INDICATOR + /* 3 */ "\u00F3,\u00F2,\u00F6,\u00F4,\u00F5,\u00F8,\u0153,\u014D,\u00BA", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B", + /* 5 */ null, + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u00F1,\u0144", + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + /* 7 */ "\u00E7,\u0107,\u010D", + /* 8~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, + /* ~48 */ + // U+00A1: "¡" INVERTED EXCLAMATION MARK + // U+00BF: "¿" INVERTED QUESTION MARK + /* 49 */ "!fixedColumnOrder!7,#,-,\u00A1,!,\u00BF,\\,,?,\\%,+,;,:,/,(,),@,&,\",\'", + }; + + /* Language et: Estonian */ + private static final String[] LANGUAGE_et = { + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + /* 0 */ "\u00E4,\u0101,\u00E0,\u00E1,\u00E2,\u00E3,\u00E5,\u00E6,\u0105", + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + /* 1 */ "\u0113,\u00E8,\u0117,\u00E9,\u00EA,\u00EB,\u0119,\u011B", + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + /* 2 */ "\u012B,\u00EC,\u012F,\u00ED,\u00EE,\u00EF,\u0131", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 3 */ "\u00F6,\u00F5,\u00F2,\u00F3,\u00F4,\u0153,\u0151,\u00F8", + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + /* 4 */ "\u00FC,\u016B,\u0173,\u00F9,\u00FA,\u00FB,\u016F,\u0171", + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + /* 5 */ "\u0161,\u00DF,\u015B,\u015F", + // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u0146,\u00F1,\u0144,\u0144", + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u010D,\u00E7,\u0107", + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + /* 9 */ "\u010F", + // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE + /* 10 */ "\u0157,\u0159,\u0155", + // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + /* 11 */ "\u0163,\u0165", + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + /* 12 */ "\u017E,\u017C,\u017A", + // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA + /* 13 */ "\u0137", + // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE + // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON + /* 14 */ "\u013C,\u0142,\u013A,\u013E", + // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + /* 15 */ "\u0123,\u011F", + /* 16~ */ + null, null, null, null, + /* ~19 */ + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + /* 20 */ "\u00FC", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + /* 21 */ "\u00F6", + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + /* 22 */ "\u00E4", + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + /* 23 */ "\u00F5", + }; + + /* Language fa: Persian */ + private static final String[] LANGUAGE_fa = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~41 */ + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK “,”,„,‟,«|»,»|« + /* 42 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB|\u00BB,\u00BB|\u00AB", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK !fixedColumnOrder!6,“,”,„,‟,«|»,»|«;,‘,’,‚,‛ + /* 43 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB|\u00BB,\u00BB|\u00AB,\u2018,\u2019,\u201A,\u201B", + /* 44~ */ + null, null, null, null, null, + /* ~48 */ + // U+061F: "؟" ARABIC QUESTION MARK + // U+060C: "،" ARABIC COMMA + // U+061B: "؛" ARABIC SEMICOLON U+0650: "ِ" ARABIC KASRA + // U+064E: "َ" ARABIC FATHA + // U+064D: "ٍ" ARABIC KASRATAN + // U+064B: "ً" ARABIC FATHATAN + // U+0656: "ٖ" ARABIC SUBSCRIPT ALEF + // U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF + // U+0655: "ٕ" ARABIC HAMZA BELOW + // U+0654: "ٔ" ARABIC HAMZA ABOVE U+064F: "ُ" ARABIC DAMMA + // U+064C: "ٌ" ARABIC DAMMATAN + // U+0651: "ّ" ARABIC SHADDA + // U+0652: "ْ" ARABIC SUKUN + // U+0653: "ٓ" ARABIC MADDAH ABOVE + // U+0640: "ـ" ARABIC TATWEEL In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. + /* 49 */ "!fixedColumnOrder!8,\",\',-,:,!,\u061F,\u060C,\u061B,\u0650,\u064E,\u064D,\u064B,\u0656,\u0670,\u0655,\u0654,\u064F,\u064C,\u0651,\u0652,\u0653,\u0640\u0640\u0640|\u0640,/", + /* 50 */ "\u064B", + /* 51 */ null, + /* 52 */ null, + // U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE + /* 53 */ "\u06F1", + // U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO + /* 54 */ "\u06F2", + // U+06F3: "۳" EXTENDED ARABIC-INDIC DIGIT THREE + /* 55 */ "\u06F3", + // U+06F4: "۴" EXTENDED ARABIC-INDIC DIGIT FOUR + /* 56 */ "\u06F4", + // U+06F5: "۵" EXTENDED ARABIC-INDIC DIGIT FIVE + /* 57 */ "\u06F5", + // U+06F6: "۶" EXTENDED ARABIC-INDIC DIGIT SIX + /* 58 */ "\u06F6", + // U+06F7: "۷" EXTENDED ARABIC-INDIC DIGIT SEVEN + /* 59 */ "\u06F7", + // U+06F8: "۸" EXTENDED ARABIC-INDIC DIGIT EIGHT + /* 60 */ "\u06F8", + // U+06F9: "۹" EXTENDED ARABIC-INDIC DIGIT NINE + /* 61 */ "\u06F9", + // U+06F0: "۰" EXTENDED ARABIC-INDIC DIGIT ZERO + /* 62 */ "\u06F0", + /* 63 */ "1", + /* 64 */ "2", + /* 65 */ "3", + /* 66 */ "4", + /* 67 */ "5", + /* 68 */ "6", + /* 69 */ "7", + /* 70 */ "8", + /* 71 */ "9", + // U+066B: "٫" ARABIC DECIMAL SEPARATOR + // U+066C: "٬" ARABIC THOUSANDS SEPARATOR + /* 72 */ "0,\u066B,\u066C", + /* 73~ */ + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~84 */ + // U+060C: "،" ARABIC COMMA + /* 85 */ "\u060C", + /* 86 */ "\\,", + /* 87 */ null, + /* 88 */ null, + /* 89 */ "\u061F", + /* 90 */ "\u061B", + // U+066A: "٪" ARABIC PERCENT SIGN + /* 91 */ "\u066A", + /* 92 */ "?", + /* 93 */ ";", + // U+2030: "‰" PER MILLE SIGN + /* 94 */ "%,\u2030", + // U+060C: "،" ARABIC COMMA + // U+061B: "؛" ARABIC SEMICOLON + // U+061F: "؟" ARABIC QUESTION MARK + /* 95 */ "\u060C", + /* 96 */ "!", + /* 97 */ "!,\\,", + /* 98 */ "\u061F", + /* 99 */ "\u061F,?", + /* 100~ */ + null, null, null, + /* ~102 */ + /* 103 */ "\u064B", + /* 104 */ "\u061F,\u061B,!,:,-,/,\',\"", + // U+0651: "ّ" ARABIC SHADDA + // U+0652: "ْ" ARABIC SUKUN + // U+064C: "ٌ" ARABIC DAMMATAN + // U+0653: "ٓ" ARABIC MADDAH ABOVE + // U+064F: "ُ" ARABIC DAMMA U+0650: "ِ" ARABIC KASRA + // U+064E: "َ" ARABIC FATHA + // U+064B: "ً" ARABIC FATHATAN + // U+0640: "ـ" ARABIC TATWEEL + // U+064D: "ٍ" ARABIC KASRATAN U+0670: "ٰ" ARABIC LETTER SUPERSCRIPT ALEF + // U+0656: "ٖ" ARABIC SUBSCRIPT ALEF + // U+0654: "ٔ" ARABIC HAMZA ABOVE + // U+0655: "ٕ" ARABIC HAMZA BELOW In order to make Tatweel easily distinguishable from other punctuations, we use consecutive Tatweels only for its displayed label. + /* 105 */ "\u0651,\u0652,\u064C,\u0653,\u064F,\u0650,\u064E,\u064B,\u0640\u0640\u0640|\u0640,\u064D,\u0654,\u0656,\u0655,_,\u0670", + // U+266A: "♪" EIGHTH NOTE + /* 106 */ "\u266A", + // U+2605: "★" BLACK STAR + // U+066D: "٭" ARABIC FIVE POINTED STAR + /* 107 */ "\u2605,\u066D", + /* 108 */ null, + // The all letters need to be mirrored are found at + // http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt U+FD3E: "﴾" ORNATE LEFT PARENTHESIS + // U+FD3F: "﴿" ORNATE RIGHT PARENTHESIS TODO: DroidSansArabic lacks the glyph of U+FD3E ORNATE LEFT PARENTHESIS TODO: DroidSansArabic lacks the glyph of U+FD3F ORNATE RIGHT PARENTHESIS + /* 109 */ "!fixedColumnOrder!4,\uFD3E|\uFD3F,<|>,{|},[|]", + /* 110 */ "!fixedColumnOrder!4,\uFD3F|\uFD3E,>|<,}|{,]|[", + // U+2264: "≤" LESS-THAN OR EQUAL TO + // U+2265: "≥" GREATER-THAN EQUAL TO + // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK + // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + // The following characters don't need BIDI mirroring. + // U+2018: "‘" LEFT SINGLE QUOTATION MARK + // U+2019: "’" RIGHT SINGLE QUOTATION MARK + // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK + // U+201B: "‛" SINGLE HIGH-REVERSED-9 QUOTATION MARK + // U+201C: "“" LEFT DOUBLE QUOTATION MARK + // U+201D: "”" RIGHT DOUBLE QUOTATION MARK + // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK + // U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK + /* 111 */ "!fixedColumnOrder!3,\u2039|\u203A,\u2264|\u2265,\u00AB|\u00BB", + /* 112 */ "!fixedColumnOrder!3,\u203A|\u2039,\u2265|\u2264,\u00BB|\u00AB", + }; + + /* Language fi: Finnish */ + private static final String[] LANGUAGE_fi = { + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E6,\u00E0,\u00E1,\u00E2,\u00E3,\u0101", + /* 1 */ null, + /* 2 */ null, + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F8,\u00F4,\u00F2,\u00F3,\u00F5,\u0153,\u014D", + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + /* 4 */ "\u00FC", + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + /* 5 */ "\u0161,\u00DF,\u015B", + /* 6~ */ + null, null, null, null, null, null, + /* ~11 */ + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + /* 12 */ "\u017E,\u017A,\u017C", + /* 13~ */ + null, null, null, null, null, null, null, + /* ~19 */ + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + /* 20 */ "\u00E5", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + /* 21 */ "\u00F6", + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + /* 22 */ "\u00E4", + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 23 */ "\u00F8", + // U+00E6: "æ" LATIN SMALL LETTER AE + /* 24 */ "\u00E6", + }; + + /* Language fr: French */ + private static final String[] LANGUAGE_fr = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00AA: "ª" FEMININE ORDINAL INDICATOR + /* 0 */ "\u00E0,\u00E2,%,\u00E6,\u00E1,\u00E4,\u00E3,\u00E5,\u0101,\u00AA", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u00E8,\u00EA,\u00EB,%,\u0119,\u0117,\u0113", + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00EE,%,\u00EF,\u00EC,\u00ED,\u012F,\u012B", + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+00BA: "º" MASCULINE ORDINAL INDICATOR + /* 3 */ "\u00F4,\u0153,%,\u00F6,\u00F2,\u00F3,\u00F5,\u00F8,\u014D,\u00BA", + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00F9,\u00FB,%,\u00FC,\u00FA,\u016B", + /* 5 */ null, + /* 6 */ null, + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + /* 7 */ "\u00E7,\u0107,\u010D", + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "%,\u00FF", + }; + + /* Language hi: Hindi */ + private static final String[] LANGUAGE_hi = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, + /* ~52 */ + // U+0967: "१" DEVANAGARI DIGIT ONE + /* 53 */ "\u0967", + // U+0968: "२" DEVANAGARI DIGIT TWO + /* 54 */ "\u0968", + // U+0969: "३" DEVANAGARI DIGIT THREE + /* 55 */ "\u0969", + // U+096A: "४" DEVANAGARI DIGIT FOUR + /* 56 */ "\u096A", + // U+096B: "५" DEVANAGARI DIGIT FIVE + /* 57 */ "\u096B", + // U+096C: "६" DEVANAGARI DIGIT SIX + /* 58 */ "\u096C", + // U+096D: "७" DEVANAGARI DIGIT SEVEN + /* 59 */ "\u096D", + // U+096E: "८" DEVANAGARI DIGIT EIGHT + /* 60 */ "\u096E", + // U+096F: "९" DEVANAGARI DIGIT NINE + /* 61 */ "\u096F", + // U+0966: "०" DEVANAGARI DIGIT ZERO + /* 62 */ "\u0966", + /* 63 */ "1", + /* 64 */ "2", + /* 65 */ "3", + /* 66 */ "4", + /* 67 */ "5", + /* 68 */ "6", + /* 69 */ "7", + /* 70 */ "8", + /* 71 */ "9", + /* 72 */ "0", + }; + + /* Language hr: Croatian */ + private static final String[] LANGUAGE_hr = { + /* 0~ */ + null, null, null, null, null, + /* ~4 */ + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + /* 5 */ "\u0161,\u015B,\u00DF", + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u00F1,\u0144", + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + /* 7 */ "\u010D,\u0107,\u00E7", + /* 8 */ null, + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + /* 9 */ "\u0111", + /* 10 */ null, + /* 11 */ null, + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + /* 12 */ "\u017E,\u017A,\u017C", + }; + + /* Language hu: Hungarian */ + private static final String[] LANGUAGE_hu = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E1,\u00E0,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00ED,\u00EE,\u00EF,\u00EC,\u012F,\u012B", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F3,\u00F6,\u0151,\u00F4,\u00F2,\u00F5,\u0153,\u00F8,\u014D", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u0171,\u00FB,\u00F9,\u016B", + }; + + /* Language is: Icelandic */ + private static final String[] LANGUAGE_is = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E1,\u00E4,\u00E6,\u00E5,\u00E0,\u00E2,\u00E3,\u0101", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u00EB,\u00E8,\u00EA,\u0119,\u0117,\u0113", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00ED,\u00EF,\u00EE,\u00EC,\u012F,\u012B", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F3,\u00F6,\u00F4,\u00F2,\u00F5,\u0153,\u00F8,\u014D", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u00FB,\u00F9,\u016B", + /* 5~ */ + null, null, null, + /* ~7 */ + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+00F0: "ð" LATIN SMALL LETTER ETH + /* 9 */ "\u00F0", + /* 10 */ null, + // U+00FE: "þ" LATIN SMALL LETTER THORN + /* 11 */ "\u00FE", + /* 12~ */ + null, null, null, null, null, null, null, null, + /* ~19 */ + // U+00F0: "ð" LATIN SMALL LETTER ETH + /* 20 */ "\u00F0", + // U+00E6: "æ" LATIN SMALL LETTER AE + /* 21 */ "\u00E6", + // U+00FE: "þ" LATIN SMALL LETTER THORN + /* 22 */ "\u00FE", + }; + + /* Language it: Italian */ + private static final String[] LANGUAGE_it = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00AA: "ª" FEMININE ORDINAL INDICATOR + /* 0 */ "\u00E0,\u00E1,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101,\u00AA", + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0119,\u0117,\u0113", + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00EC,\u00ED,\u00EE,\u00EF,\u012F,\u012B", + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+00BA: "º" MASCULINE ORDINAL INDICATOR + /* 3 */ "\u00F2,\u00F3,\u00F4,\u00F6,\u00F5,\u0153,\u00F8,\u014D,\u00BA", + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00F9,\u00FA,\u00FB,\u00FC,\u016B", + }; + + /* Language iw: Hebrew */ + private static final String[] LANGUAGE_iw = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + /* ~41 */ + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK “,”,„,‟,«|»,»|« + /* 42 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB|\u00BB,\u00BB|\u00AB", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK !fixedColumnOrder!6,“,”,„,‟,«|»,»|«;,‘,’,‚,‛ + /* 43 */ "!fixedColumnOrder!4,\u201C,\u201D,\u00AB|\u00BB,\u00BB|\u00AB,\u2018,\u2019,\u201A,\u201B", + /* 44~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, + /* ~106 */ + // U+2605: "★" BLACK STAR + /* 107 */ "\u2605", + // U+00B1: "±" PLUS-MINUS SIGN + // U+FB29: "﬩" HEBREW LETTER ALTERNATIVE PLUS SIGN + /* 108 */ "\u00B1,\uFB29", + // The all letters need to be mirrored are found at + // http://www.unicode.org/Public/6.1.0/ucd/BidiMirroring.txt + /* 109 */ "!fixedColumnOrder!3,<|>,{|},[|]", + /* 110 */ "!fixedColumnOrder!3,>|<,}|{,]|[", + // U+2264: "≤" LESS-THAN OR EQUAL TO + // U+2265: "≥" GREATER-THAN EQUAL TO + // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK + // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + // The following characters don't need BIDI mirroring. + // U+2018: "‘" LEFT SINGLE QUOTATION MARK + // U+2019: "’" RIGHT SINGLE QUOTATION MARK + // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK + // U+201B: "‛" SINGLE HIGH-REVERSED-9 QUOTATION MARK + // U+201C: "“" LEFT DOUBLE QUOTATION MARK + // U+201D: "”" RIGHT DOUBLE QUOTATION MARK + // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK + // U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK + /* 111 */ "!fixedColumnOrder!3,\u2039|\u203A,\u2264|\u2265,\u00AB|\u00BB", + /* 112 */ "!fixedColumnOrder!3,\u203A|\u2039,\u2265|\u2264,\u00BB|\u00AB", + }; + + /* Language ky: Kirghiz */ + private static final String[] LANGUAGE_ky = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, + /* ~24 */ + // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA + /* 25 */ "\u0449", + // U+044B: "ы" CYRILLIC SMALL LETTER YERU + /* 26 */ "\u044B", + // U+0438: "и" CYRILLIC SMALL LETTER I + /* 27 */ "\u0438", + // U+04AF: "ү" CYRILLIC SMALL LETTER STRAIGHT U + /* 28 */ "\u04AF", + /* 29 */ null, + // U+04A3: "ң" CYRILLIC SMALL LETTER EN WITH DESCENDER + /* 30 */ "\u04A3", + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 31 */ "\u044A", + /* 32 */ null, + // U+04E9: "ө" CYRILLIC SMALL LETTER BARRED O + /* 33 */ "\u04E9", + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 34 */ "\u044A", + }; + + /* Language lt: Lithuanian */ + private static final String[] LANGUAGE_lt = { + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + /* 0 */ "\u0105,\u00E4,\u0101,\u00E0,\u00E1,\u00E2,\u00E3,\u00E5,\u00E6", + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + /* 1 */ "\u0117,\u0119,\u0113,\u00E8,\u00E9,\u00EA,\u00EB,\u011B", + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + /* 2 */ "\u012F,\u012B,\u00EC,\u00ED,\u00EE,\u00EF,\u0131", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 3 */ "\u00F6,\u00F5,\u00F2,\u00F3,\u00F4,\u0153,\u0151,\u00F8", + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + /* 4 */ "\u016B,\u0173,\u00FC,\u016B,\u00F9,\u00FA,\u00FB,\u016F,\u0171", + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + /* 5 */ "\u0161,\u00DF,\u015B,\u015F", + // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u0146,\u00F1,\u0144,\u0144", + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u010D,\u00E7,\u0107", + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + /* 9 */ "\u010F", + // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE + /* 10 */ "\u0157,\u0159,\u0155", + // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + /* 11 */ "\u0163,\u0165", + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + /* 12 */ "\u017E,\u017C,\u017A", + // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA + /* 13 */ "\u0137", + // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE + // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON + /* 14 */ "\u013C,\u0142,\u013A,\u013E", + // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + /* 15 */ "\u0123,\u011F", + }; + + /* Language lv: Latvian */ + private static final String[] LANGUAGE_lv = { + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + /* 0 */ "\u0101,\u00E0,\u00E1,\u00E2,\u00E3,\u00E4,\u00E5,\u00E6,\u0105", + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + /* 1 */ "\u0113,\u0117,\u00E8,\u00E9,\u00EA,\u00EB,\u0119,\u011B", + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + /* 2 */ "\u012B,\u012F,\u00EC,\u00ED,\u00EE,\u00EF,\u0131", + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 3 */ "\u00F2,\u00F3,\u00F4,\u00F5,\u00F6,\u0153,\u0151,\u00F8", + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + /* 4 */ "\u016B,\u0173,\u00F9,\u00FA,\u00FB,\u00FC,\u016F,\u0171", + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + /* 5 */ "\u0161,\u00DF,\u015B,\u015F", + // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u0146,\u00F1,\u0144,\u0144", + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u010D,\u00E7,\u0107", + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + /* 9 */ "\u010F", + // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE + /* 10 */ "\u0157,\u0159,\u0155", + // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + /* 11 */ "\u0163,\u0165", + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + /* 12 */ "\u017E,\u017C,\u017A", + // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA + /* 13 */ "\u0137", + // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE + // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON + /* 14 */ "\u013C,\u0142,\u013A,\u013E", + // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + /* 15 */ "\u0123,\u011F", + }; + + /* Language mk: Macedonian */ + private static final String[] LANGUAGE_mk = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, + /* ~34 */ + // U+0455: "ѕ" CYRILLIC SMALL LETTER DZE + /* 35 */ "\u0455", + // U+045C: "ќ" CYRILLIC SMALL LETTER KJE + /* 36 */ "\u045C", + // U+0437: "з" CYRILLIC SMALL LETTER ZE + /* 37 */ "\u0437", + // U+0453: "ѓ" CYRILLIC SMALL LETTER GJE + /* 38 */ "\u0453", + // U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE + /* 39 */ "\u0450", + // U+045D: "ѝ" CYRILLIC SMALL LETTER I WITH GRAVE + /* 40 */ "\u045D", + /* 41 */ null, + // U+2018: "‘" LEFT SINGLE QUOTATION MARK + // U+2019: "’" RIGHT SINGLE QUOTATION MARK + // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK + // U+201B: "‛" SINGLE HIGH-REVERSED-9 QUOTATION MARK + // U+201C: "“" LEFT DOUBLE QUOTATION MARK + // U+201D: "”" RIGHT DOUBLE QUOTATION MARK + // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK + // U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. !fixedColumnOrder!6,„,“,”,‟,«,» + /* 42 */ "!fixedColumnOrder!5,\u201E,\u201C,\u201D,\u00AB,\u00BB", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. !fixedColumnOrder!6,“,”,„,‟,«,»,‘,’,‚,‛ + /* 43 */ "!fixedColumnOrder!5,\u201E,\u201C,\u201D,\u00AB,\u00BB,\u2018,\u2019,\u201A,\u201B", + }; + + /* Language nb: Norwegian Bokmål */ + private static final String[] LANGUAGE_nb = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E0,\u00E4,\u00E1,\u00E2,\u00E3,\u0101", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119,\u0117,\u0113", + /* 2 */ null, + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F4,\u00F2,\u00F3,\u00F6,\u00F5,\u0153,\u014D", + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B", + /* 5~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + /* ~19 */ + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + /* 20 */ "\u00E5", + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 21 */ "\u00F8", + // U+00E6: "æ" LATIN SMALL LETTER AE + /* 22 */ "\u00E6", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + /* 23 */ "\u00F6", + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + /* 24 */ "\u00E4", + }; + + /* Language nl: Dutch */ + private static final String[] LANGUAGE_nl = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E1,\u00E4,\u00E2,\u00E0,\u00E6,\u00E3,\u00E5,\u0101", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u00E9,\u00EB,\u00EA,\u00E8,\u0119,\u0117,\u0113", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+0133: "ij" LATIN SMALL LIGATURE IJ + /* 2 */ "\u00ED,\u00EF,\u00EC,\u00EE,\u012F,\u012B,\u0133", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F3,\u00F6,\u00F4,\u00F2,\u00F5,\u0153,\u00F8,\u014D", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u00FB,\u00F9,\u016B", + /* 5 */ null, + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u00F1,\u0144", + /* 7 */ null, + // U+0133: "ij" LATIN SMALL LIGATURE IJ + /* 8 */ "\u0133", + }; + + /* Language pl: Polish */ + private static final String[] LANGUAGE_pl = { + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u0105,\u00E1,\u00E0,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101", + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + /* 1 */ "\u0119,\u00E8,\u00E9,\u00EA,\u00EB,\u0117,\u0113", + /* 2 */ null, + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F3,\u00F6,\u00F4,\u00F2,\u00F5,\u0153,\u00F8,\u014D", + /* 4 */ null, + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u015B,\u00DF,\u0161", + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + /* 6 */ "\u0144,\u00F1", + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + /* 7 */ "\u0107,\u00E7,\u010D", + /* 8~ */ + null, null, null, null, + /* ~11 */ + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + /* 12 */ "\u017C,\u017A,\u017E", + /* 13 */ null, + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + /* 14 */ "\u0142", + }; + + /* Language pt: Portuguese */ + private static final String[] LANGUAGE_pt = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00AA: "ª" FEMININE ORDINAL INDICATOR + /* 0 */ "\u00E1,\u00E3,\u00E0,\u00E2,\u00E4,\u00E5,\u00E6,\u00AA", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + /* 1 */ "\u00E9,\u00EA,\u00E8,\u0119,\u0117,\u0113,\u00EB", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00ED,\u00EE,\u00EC,\u00EF,\u012F,\u012B", + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+00BA: "º" MASCULINE ORDINAL INDICATOR + /* 3 */ "\u00F3,\u00F5,\u00F4,\u00F2,\u00F6,\u0153,\u00F8,\u014D,\u00BA", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FA,\u00FC,\u00F9,\u00FB,\u016B", + /* 5 */ null, + /* 6 */ null, + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u00E7,\u010D,\u0107", + }; + + /* Language rm: Raeto-Romance */ + private static final String[] LANGUAGE_rm = { + /* 0~ */ + null, null, null, + /* ~2 */ + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 3 */ "\u00F2,\u00F3,\u00F6,\u00F4,\u00F5,\u0153,\u00F8", + }; + + /* Language ro: Romanian */ + private static final String[] LANGUAGE_ro = { + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + /* 0 */ "\u00E2,\u00E3,\u0103,\u00E0,\u00E1,\u00E4,\u00E6,\u00E5,\u0101", + /* 1 */ null, + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u00EE,\u00EF,\u00EC,\u00ED,\u012F,\u012B", + /* 3 */ null, + /* 4 */ null, + // U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u0219,\u00DF,\u015B,\u0161", + /* 6~ */ + null, null, null, null, null, + /* ~10 */ + // U+021B: "ț" LATIN SMALL LETTER T WITH COMMA BELOW + /* 11 */ "\u021B", + }; + + /* Language ru: Russian */ + private static final String[] LANGUAGE_ru = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, + /* ~24 */ + // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA + /* 25 */ "\u0449", + // U+044B: "ы" CYRILLIC SMALL LETTER YERU + /* 26 */ "\u044B", + // U+0438: "и" CYRILLIC SMALL LETTER I + /* 27 */ "\u0438", + /* 28 */ null, + // U+0451: "ё" CYRILLIC SMALL LETTER IO + /* 29 */ "\u0451", + /* 30 */ null, + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 31 */ "\u044A", + /* 32 */ null, + /* 33 */ null, + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 34 */ "\u044A", + }; + + /* Language sk: Slovak */ + private static final String[] LANGUAGE_sk = { + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + /* 0 */ "\u00E1,\u00E4,\u0101,\u00E0,\u00E2,\u00E3,\u00E5,\u00E6,\u0105", + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + /* 1 */ "\u00E9,\u011B,\u0113,\u0117,\u00E8,\u00EA,\u00EB,\u0119", + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + /* 2 */ "\u00ED,\u012B,\u012F,\u00EC,\u00EE,\u00EF,\u0131", + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 3 */ "\u00F4,\u00F3,\u00F6,\u00F2,\u00F5,\u0153,\u0151,\u00F8", + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + /* 4 */ "\u00FA,\u016F,\u00FC,\u016B,\u0173,\u00F9,\u00FB,\u0171", + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + /* 5 */ "\u0161,\u00DF,\u015B,\u015F", + // U+0148: "ň" LATIN SMALL LETTER N WITH CARON + // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + /* 6 */ "\u0148,\u0146,\u00F1,\u0144,\u0144", + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u010D,\u00E7,\u0107", + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + /* 8 */ "\u00FD,\u00FF", + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + /* 9 */ "\u010F", + // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA + /* 10 */ "\u0155,\u0159,\u0157", + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA + /* 11 */ "\u0165,\u0163", + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + /* 12 */ "\u017E,\u017C,\u017A", + // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA + /* 13 */ "\u0137", + // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON + // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE + // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + /* 14 */ "\u013E,\u013A,\u013C,\u0142", + // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + /* 15 */ "\u0123,\u011F", + }; + + /* Language sl: Slovenian */ + private static final String[] LANGUAGE_sl = { + /* 0~ */ + null, null, null, null, null, + /* ~4 */ + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u0161", + /* 6 */ null, + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + /* 7 */ "\u010D,\u0107", + /* 8 */ null, + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + /* 9 */ "\u0111", + /* 10 */ null, + /* 11 */ null, + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + /* 12 */ "\u017E", + }; + + /* Language sr: Serbian */ + private static final String[] LANGUAGE_sr = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, + /* ~34 */ + // U+0437: "з" CYRILLIC SMALL LETTER ZE + /* 35 */ "\u0437", + // U+045B: "ћ" CYRILLIC SMALL LETTER TSHE + /* 36 */ "\u045B", + // U+0455: "ѕ" CYRILLIC SMALL LETTER DZE + /* 37 */ "\u0455", + // U+0452: "ђ" CYRILLIC SMALL LETTER DJE + /* 38 */ "\u0452", + // U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE + /* 39 */ "\u0450", + // U+045D: "ѝ" CYRILLIC SMALL LETTER I WITH GRAVE + /* 40 */ "\u045D", + /* 41 */ null, + // U+2018: "‘" LEFT SINGLE QUOTATION MARK + // U+2019: "’" RIGHT SINGLE QUOTATION MARK + // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK + // U+201B: "‛" SINGLE HIGH-REVERSED-9 QUOTATION MARK + // U+201C: "“" LEFT DOUBLE QUOTATION MARK + // U+201D: "”" RIGHT DOUBLE QUOTATION MARK + // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK + // U+201F: "‟" DOUBLE HIGH-REVERSED-9 QUOTATION MARK TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. !fixedColumnOrder!6,„,“,”,‟,«,» + /* 42 */ "!fixedColumnOrder!5,\u201E,\u201C,\u201D,\u00AB,\u00BB", + // TODO: Neither DroidSans nor Roboto have the glyph for U+201F DOUBLE HIGH-REVERSED-9 QUOTATION MARK. !fixedColumnOrder!6,“,”,„,‟,«,»,‘,’,‚,‛ + /* 43 */ "!fixedColumnOrder!5,\u201E,\u201C,\u201D,\u00AB,\u00BB,\u2018,\u2019,\u201A,\u201B", + }; + + /* Language sv: Swedish */ + private static final String[] LANGUAGE_sv = { + /* 0 */ null, + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + /* 1 */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0119", + /* 2 */ null, + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u0153,\u00F4,\u00F2,\u00F3,\u00F5,\u014D", + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B", + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u00DF,\u015B,\u0161", + /* 6~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, + /* ~19 */ + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + /* 20 */ "\u00E5", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + /* 21 */ "\u00F6", + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + /* 22 */ "\u00E4", + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + /* 23 */ "\u00F8", + // U+00E6: "æ" LATIN SMALL LETTER AE + /* 24 */ "\u00E6", + }; + + /* Language tr: Turkish */ + private static final String[] LANGUAGE_tr = { + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + /* 0 */ "\u00E2", + /* 1 */ null, + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + /* 2 */ "\u0131,\u00EE,\u00EF,\u00EC,\u00ED,\u012F,\u012B", + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + /* 3 */ "\u00F6,\u00F4,\u0153,\u00F2,\u00F3,\u00F5,\u00F8,\u014D", + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + /* 4 */ "\u00FC,\u00FB,\u00F9,\u00FA,\u016B", + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + /* 5 */ "\u015F,\u00DF,\u015B,\u0161", + /* 6 */ null, + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + /* 7 */ "\u00E7,\u0107,\u010D", + /* 8~ */ + null, null, null, null, null, null, null, + /* ~14 */ + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + /* 15 */ "\u011F", + }; + + /* Language uk: Ukrainian */ + private static final String[] LANGUAGE_uk = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, + /* ~24 */ + // U+0449: "щ" CYRILLIC SMALL LETTER SHCHA + /* 25 */ "\u0449", + // U+0456: "і" CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + /* 26 */ "\u0456", + // U+0438: "и" CYRILLIC SMALL LETTER I + /* 27 */ "\u0438", + /* 28~ */ + null, null, null, + /* ~30 */ + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 31 */ "\u044A", + // U+0457: "ї" CYRILLIC SMALL LETTER YI + /* 32 */ "\u0457", + /* 33 */ null, + // U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN + /* 34 */ "\u044A", + }; + + /* Language vi: Vietnamese */ + private static final String[] LANGUAGE_vi = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+1EA3: "ả" LATIN SMALL LETTER A WITH HOOK ABOVE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+1EA1: "ạ" LATIN SMALL LETTER A WITH DOT BELOW + // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE + // U+1EB1: "ằ" LATIN SMALL LETTER A WITH BREVE AND GRAVE + // U+1EAF: "ắ" LATIN SMALL LETTER A WITH BREVE AND ACUTE + // U+1EB3: "ẳ" LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE + // U+1EB5: "ẵ" LATIN SMALL LETTER A WITH BREVE AND TILDE + // U+1EB7: "ặ" LATIN SMALL LETTER A WITH BREVE AND DOT BELOW + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+1EA7: "ầ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE + // U+1EA5: "ấ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + // U+1EA9: "ẩ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + // U+1EAB: "ẫ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE + // U+1EAD: "ậ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW + /* 0 */ "\u00E0,\u00E1,\u1EA3,\u00E3,\u1EA1,\u0103,\u1EB1,\u1EAF,\u1EB3,\u1EB5,\u1EB7,\u00E2,\u1EA7,\u1EA5,\u1EA9,\u1EAB,\u1EAD", + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+1EBB: "ẻ" LATIN SMALL LETTER E WITH HOOK ABOVE + // U+1EBD: "ẽ" LATIN SMALL LETTER E WITH TILDE + // U+1EB9: "ẹ" LATIN SMALL LETTER E WITH DOT BELOW + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+1EC1: "ề" LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE + // U+1EBF: "ế" LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE + // U+1EC3: "ể" LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + // U+1EC5: "ễ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE + // U+1EC7: "ệ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW + /* 1 */ "\u00E8,\u00E9,\u1EBB,\u1EBD,\u1EB9,\u00EA,\u1EC1,\u1EBF,\u1EC3,\u1EC5,\u1EC7", + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+1EC9: "ỉ" LATIN SMALL LETTER I WITH HOOK ABOVE + // U+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE + // U+1ECB: "ị" LATIN SMALL LETTER I WITH DOT BELOW + /* 2 */ "\u00EC,\u00ED,\u1EC9,\u0129,\u1ECB", + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+1ECF: "ỏ" LATIN SMALL LETTER O WITH HOOK ABOVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+1ECD: "ọ" LATIN SMALL LETTER O WITH DOT BELOW + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+1ED3: "ồ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE + // U+1ED1: "ố" LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE + // U+1ED5: "ổ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + // U+1ED7: "ỗ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE + // U+1ED9: "ộ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW + // U+01A1: "ơ" LATIN SMALL LETTER O WITH HORN + // U+1EDD: "ờ" LATIN SMALL LETTER O WITH HORN AND GRAVE + // U+1EDB: "ớ" LATIN SMALL LETTER O WITH HORN AND ACUTE + // U+1EDF: "ở" LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE + // U+1EE1: "ỡ" LATIN SMALL LETTER O WITH HORN AND TILDE + // U+1EE3: "ợ" LATIN SMALL LETTER O WITH HORN AND DOT BELOW + /* 3 */ "\u00F2,\u00F3,\u1ECF,\u00F5,\u1ECD,\u00F4,\u1ED3,\u1ED1,\u1ED5,\u1ED7,\u1ED9,\u01A1,\u1EDD,\u1EDB,\u1EDF,\u1EE1,\u1EE3", + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+1EE7: "ủ" LATIN SMALL LETTER U WITH HOOK ABOVE + // U+0169: "ũ" LATIN SMALL LETTER U WITH TILDE + // U+1EE5: "ụ" LATIN SMALL LETTER U WITH DOT BELOW + // U+01B0: "ư" LATIN SMALL LETTER U WITH HORN + // U+1EEB: "ừ" LATIN SMALL LETTER U WITH HORN AND GRAVE + // U+1EE9: "ứ" LATIN SMALL LETTER U WITH HORN AND ACUTE + // U+1EED: "ử" LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE + // U+1EEF: "ữ" LATIN SMALL LETTER U WITH HORN AND TILDE + // U+1EF1: "ự" LATIN SMALL LETTER U WITH HORN AND DOT BELOW + /* 4 */ "\u00F9,\u00FA,\u1EE7,\u0169,\u1EE5,\u01B0,\u1EEB,\u1EE9,\u1EED,\u1EEF,\u1EF1", + /* 5~ */ + null, null, null, + /* ~7 */ + // U+1EF3: "ỳ" LATIN SMALL LETTER Y WITH GRAVE + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+1EF7: "ỷ" LATIN SMALL LETTER Y WITH HOOK ABOVE + // U+1EF9: "ỹ" LATIN SMALL LETTER Y WITH TILDE + // U+1EF5: "ỵ" LATIN SMALL LETTER Y WITH DOT BELOW + /* 8 */ "\u1EF3,\u00FD,\u1EF7,\u1EF9,\u1EF5", + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + /* 9 */ "\u0111", + }; + + /* Language zz: No language */ + private static final String[] LANGUAGE_zz = { + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00AA: "ª" FEMININE ORDINAL INDICATOR + /* 0 */ "\u00E0,\u00E1,\u00E2,\u00E3,\u00E4,\u00E5,\u00E6,\u00E3,\u00E5,\u0101,\u0103,\u0105,\u00AA", + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+0115: "ĕ" LATIN SMALL LETTER E WITH BREVE + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + /* 1 */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0113,\u0115,\u0117,\u0119,\u011B", + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+012D: "ĭ" LATIN SMALL LETTER I WITH BREVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + // U+0133: "ij" LATIN SMALL LIGATURE IJ + /* 2 */ "\u00EC,\u00ED,\u00EE,\u00EF,\u0129,\u012B,\u012D,\u012F,\u0131,\u0133", + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + // U+014F: "ŏ" LATIN SMALL LETTER O WITH BREVE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00BA: "º" MASCULINE ORDINAL INDICATOR + /* 3 */ "\u00F2,\u00F3,\u00F4,\u00F5,\u00F6,\u00F8,\u014D,\u014F,\u0151,\u0153,\u00BA", + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+0169: "ũ" LATIN SMALL LETTER U WITH TILDE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+016D: "ŭ" LATIN SMALL LETTER U WITH BREVE + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + /* 4 */ "\u00F9,\u00FA,\u00FB,\u00FC,\u0169,\u016B,\u016D,\u016F,\u0171,\u0173", + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+017F: "ſ" LATIN SMALL LETTER LONG S + /* 5 */ "\u00DF,\u015B,\u015D,\u015F,\u0161,\u017F", + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA + // U+0148: "ň" LATIN SMALL LETTER N WITH CARON + // U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + // U+014B: "ŋ" LATIN SMALL LETTER ENG + /* 6 */ "\u00F1,\u0144,\u0146,\u0148,\u0149,\u014B", + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+0109: "ĉ" LATIN SMALL LETTER C WITH CIRCUMFLEX + // U+010B: "ċ" LATIN SMALL LETTER C WITH DOT ABOVE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + /* 7 */ "\u00E7,\u0107,\u0109,\u010B,\u010D", + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + // U+0133: "ij" LATIN SMALL LIGATURE IJ + /* 8 */ "\u00FD,\u0177,\u00FF,\u0133", + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + // U+00F0: "ð" LATIN SMALL LETTER ETH + /* 9 */ "\u010F,\u0111,\u00F0", + // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE + // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + /* 10 */ "\u0155,\u0157,\u0159", + // U+00FE: "þ" LATIN SMALL LETTER THORN + // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + // U+0167: "ŧ" LATIN SMALL LETTER T WITH STROKE + /* 11 */ "\u00FE,\u0163,\u0165,\u0167", + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + /* 12 */ "\u017A,\u017C,\u017E", + // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA + // U+0138: "ĸ" LATIN SMALL LETTER KRA + /* 13 */ "\u0137,\u0138", + // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE + // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA + // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON + // U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + /* 14 */ "\u013A,\u013C,\u013E,\u0140,\u0142", + // U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + // U+0121: "ġ" LATIN SMALL LETTER G WITH DOT ABOVE + // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA + /* 15 */ "\u011D,\u011F,\u0121,\u0123", + /* 16 */ null, + // U+0125: "ĥ" LATIN SMALL LETTER H WITH CIRCUMFLEX + /* 17 */ "\u0125", + // U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX + /* 18 */ "\u0135", + // U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX + /* 19 */ "\u0175", + }; + + private static final Object[] LANGUAGES_AND_LABELS = { + "DEFAULT", LANGUAGE_DEFAULT, /* default */ + "ar", LANGUAGE_ar, /* Arabic */ + "be", LANGUAGE_be, /* Belarusian */ + "ca", LANGUAGE_ca, /* Catalan */ + "cs", LANGUAGE_cs, /* Czech */ + "da", LANGUAGE_da, /* Danish */ + "de", LANGUAGE_de, /* German */ + "en", LANGUAGE_en, /* English */ + "es", LANGUAGE_es, /* Spanish */ + "et", LANGUAGE_et, /* Estonian */ + "fa", LANGUAGE_fa, /* Persian */ + "fi", LANGUAGE_fi, /* Finnish */ + "fr", LANGUAGE_fr, /* French */ + "hi", LANGUAGE_hi, /* Hindi */ + "hr", LANGUAGE_hr, /* Croatian */ + "hu", LANGUAGE_hu, /* Hungarian */ + "is", LANGUAGE_is, /* Icelandic */ + "it", LANGUAGE_it, /* Italian */ + "iw", LANGUAGE_iw, /* Hebrew */ + "ky", LANGUAGE_ky, /* Kirghiz */ + "lt", LANGUAGE_lt, /* Lithuanian */ + "lv", LANGUAGE_lv, /* Latvian */ + "mk", LANGUAGE_mk, /* Macedonian */ + "nb", LANGUAGE_nb, /* Norwegian Bokmål */ + "nl", LANGUAGE_nl, /* Dutch */ + "pl", LANGUAGE_pl, /* Polish */ + "pt", LANGUAGE_pt, /* Portuguese */ + "rm", LANGUAGE_rm, /* Raeto-Romance */ + "ro", LANGUAGE_ro, /* Romanian */ + "ru", LANGUAGE_ru, /* Russian */ + "sk", LANGUAGE_sk, /* Slovak */ + "sl", LANGUAGE_sl, /* Slovenian */ + "sr", LANGUAGE_sr, /* Serbian */ + "sv", LANGUAGE_sv, /* Swedish */ + "tr", LANGUAGE_tr, /* Turkish */ + "uk", LANGUAGE_uk, /* Ukrainian */ + "vi", LANGUAGE_vi, /* Vietnamese */ + "zz", LANGUAGE_zz, /* No language */ + }; + + static { + int id = 0; + for (final String name : NAMES) { + sNameToIdMap.put(name, id++); + } + + for (int i = 0; i < LANGUAGES_AND_LABELS.length; i += 2) { + final String language = (String)LANGUAGES_AND_LABELS[i]; + final String[] labels = (String[])LANGUAGES_AND_LABELS[i + 1]; + sLocaleToLabelsMap.put(language, labels); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 49ab7f9d7..526acf128 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -97,7 +97,7 @@ public class SettingsValues { } } final String[] suggestPuncsSpec = KeySpecParser.parseCsvString( - res.getString(R.string.suggested_punctuations), res, R.string.english_ime_name); + res.getString(R.string.suggested_punctuations), null); mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec); mSymbolsExcludedFromWordSeparators = res.getString(R.string.symbols_excluded_from_word_separators); diff --git a/tests/res/values/donottranslate.xml b/tests/res/values/donottranslate.xml index 1ca4451d4..42181ed92 100644 --- a/tests/res/values/donottranslate.xml +++ b/tests/res/values/donottranslate.xml @@ -50,7 +50,7 @@ " \\abc , d\\ef , gh\\i " "ab\\\\,d\\\\\\,,g\\,i" " ab\\\\ , d\\\\\\, , g\\,i " - @string/multiple_chars - x,@string/multiple_chars,y - infinite,@string/infinite_indirection,loop + !label/multiple_chars + x,!label/multiple_chars,y + infinite,!label/infinite_indirection,loop diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java index e090031e4..000623bc0 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java @@ -16,22 +16,37 @@ package com.android.inputmethod.keyboard.internal; -import android.content.res.Resources; import android.test.AndroidTestCase; import android.text.TextUtils; -import com.android.inputmethod.latin.tests.R; - +import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Locale; public class KeySpecParserCsvTests extends AndroidTestCase { - private Resources mTestResources; + private final KeyboardLabelsSet mLabelsSet = new KeyboardLabelsSet(); @Override protected void setUp() throws Exception { super.setUp(); - mTestResources = getTestContext().getResources(); + mLabelsSet.setLanguage(Locale.ENGLISH.getLanguage()); + final String[] testResourceNames = getAllResourceIdNames( + com.android.inputmethod.latin.tests.R.string.class); + mLabelsSet.loadStringResourcesInternal(getTestContext(), + testResourceNames, + com.android.inputmethod.latin.tests.R.string.empty_string); + } + + private static String[] getAllResourceIdNames(final Class resourceIdClass) { + final ArrayList names = new ArrayList(); + for (final Field field : resourceIdClass.getFields()) { + if (field.getType() == Integer.TYPE) { + names.add(field.getName()); + } + } + return names.toArray(new String[names.size()]); } private static String format(String message, Object expected, Object actual) { @@ -39,8 +54,7 @@ public class KeySpecParserCsvTests extends AndroidTestCase { } private void assertTextArray(String message, String value, String ... expected) { - final String actual[] = KeySpecParser.parseCsvString(value, mTestResources, - R.string.empty_string); + final String actual[] = KeySpecParser.parseCsvString(value, mLabelsSet); if (expected.length == 0) { assertNull(message + ": expected=null actual=" + Arrays.toString(actual), actual); @@ -104,10 +118,10 @@ public class KeySpecParserCsvTests extends AndroidTestCase { "ab" + SURROGATE1 + "cd", "ab" + SURROGATE1 + "cd"); - assertTextArray("Incomplete resource reference 1", "string", "string"); - assertTextArray("Incomplete resource reference 2", "@string", "@string"); - assertTextArray("Incomplete resource reference 3", "string/", "string/"); - assertTextArray("Incomplete resource reference 4", "@" + SURROGATE2, "@" + SURROGATE2); + assertTextArray("Incomplete resource reference 1", "label", "label"); + assertTextArray("Incomplete resource reference 2", "!label", "!label"); + assertTextArray("Incomplete resource reference 3", "label/", "label/"); + assertTextArray("Incomplete resource reference 4", "!" + SURROGATE2, "!" + SURROGATE2); } public void testParseCsvTextSingleEscaped() { @@ -138,9 +152,9 @@ public class KeySpecParserCsvTests extends AndroidTestCase { assertTextArray("Escaped surrogate with escape", PAIR1 + "\\\\" + PAIR2, PAIR1 + "\\\\" + PAIR2); - assertTextArray("Escaped @string", "\\@string", "\\@string"); - assertTextArray("Escaped @string/", "\\@string/", "\\@string/"); - assertTextArray("Escaped @string/", "\\@string/empty_string", "\\@string/empty_string"); + assertTextArray("Escaped !label", "\\!label", "\\!label"); + assertTextArray("Escaped !label/", "\\!label/", "\\!label/"); + assertTextArray("Escaped !label/", "\\!label/empty_string", "\\!label/empty_string"); } public void testParseCsvTextMulti() { @@ -171,133 +185,133 @@ public class KeySpecParserCsvTests extends AndroidTestCase { assertTextArray("Multiple labels with comma and escape surrounded by spaces", " ab\\\\ , d\\\\\\, , g\\,i ", " ab\\\\ ", " d\\\\\\, ", " g\\,i "); - assertTextArray("Multiple escaped @string", "\\@,\\@string/empty_string", - "\\@", "\\@string/empty_string"); + assertTextArray("Multiple escaped !label", "\\!,\\!label/empty_string", + "\\!", "\\!label/empty_string"); } public void testParseCsvResourceError() { - assertError("Incomplete resource name", "@string/", "@string/"); - assertError("Non existing resource", "@string/non_existing"); + assertError("Incomplete resource name", "!label/", "!label/"); + assertError("Non existing resource", "!label/non_existing"); } public void testParseCsvResourceZero() { assertTextArray("Empty string", - "@string/empty_string"); + "!label/empty_string"); } public void testParseCsvResourceSingle() { assertTextArray("Single char", - "@string/single_char", "a"); + "!label/single_char", "a"); assertTextArray("Space", - "@string/space", " "); + "!label/space", " "); assertTextArray("Single label", - "@string/single_label", "abc"); + "!label/single_label", "abc"); assertTextArray("Spaces", - "@string/spaces", " "); + "!label/spaces", " "); assertTextArray("Spaces in label", - "@string/spaces_in_label", "a b c"); + "!label/spaces_in_label", "a b c"); assertTextArray("Spaces at beginning of label", - "@string/spaces_at_beginning_of_label", " abc"); + "!label/spaces_at_beginning_of_label", " abc"); assertTextArray("Spaces at end of label", - "@string/spaces_at_end_of_label", "abc "); + "!label/spaces_at_end_of_label", "abc "); assertTextArray("label surrounded by spaces", - "@string/label_surrounded_by_spaces", " abc "); + "!label/label_surrounded_by_spaces", " abc "); assertTextArray("Escape and single char", - "\\\\@string/single_char", "\\\\a"); + "\\\\!label/single_char", "\\\\a"); } public void testParseCsvResourceSingleEscaped() { assertTextArray("Escaped char", - "@string/escaped_char", "\\a"); + "!label/escaped_char", "\\a"); assertTextArray("Escaped comma", - "@string/escaped_comma", "\\,"); + "!label/escaped_comma", "\\,"); assertTextArray("Escaped comma escape", - "@string/escaped_comma_escape", "a\\,\\"); + "!label/escaped_comma_escape", "a\\,\\"); assertTextArray("Escaped escape", - "@string/escaped_escape", "\\\\"); + "!label/escaped_escape", "\\\\"); assertTextArray("Escaped label", - "@string/escaped_label", "a\\bc"); + "!label/escaped_label", "a\\bc"); assertTextArray("Escaped label at beginning", - "@string/escaped_label_at_beginning", "\\abc"); + "!label/escaped_label_at_beginning", "\\abc"); assertTextArray("Escaped label at end", - "@string/escaped_label_at_end", "abc\\"); + "!label/escaped_label_at_end", "abc\\"); assertTextArray("Escaped label with comma", - "@string/escaped_label_with_comma", "a\\,c"); + "!label/escaped_label_with_comma", "a\\,c"); assertTextArray("Escaped label with comma at beginning", - "@string/escaped_label_with_comma_at_beginning", "\\,bc"); + "!label/escaped_label_with_comma_at_beginning", "\\,bc"); assertTextArray("Escaped label with comma at end", - "@string/escaped_label_with_comma_at_end", "ab\\,"); + "!label/escaped_label_with_comma_at_end", "ab\\,"); assertTextArray("Escaped label with successive", - "@string/escaped_label_with_successive", "\\,\\\\bc"); + "!label/escaped_label_with_successive", "\\,\\\\bc"); assertTextArray("Escaped label with escape", - "@string/escaped_label_with_escape", "a\\\\c"); + "!label/escaped_label_with_escape", "a\\\\c"); } public void testParseCsvResourceMulti() { assertTextArray("Multiple chars", - "@string/multiple_chars", "a", "b", "c"); + "!label/multiple_chars", "a", "b", "c"); assertTextArray("Multiple chars surrounded by spaces", - "@string/multiple_chars_surrounded_by_spaces", + "!label/multiple_chars_surrounded_by_spaces", " a ", " b ", " c "); assertTextArray("Multiple labels", - "@string/multiple_labels", "abc", "def", "ghi"); + "!label/multiple_labels", "abc", "def", "ghi"); assertTextArray("Multiple labels surrounded by spaces", - "@string/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi "); + "!label/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi "); } public void testParseCsvResourcetMultiEscaped() { assertTextArray("Multiple chars with comma", - "@string/multiple_chars_with_comma", + "!label/multiple_chars_with_comma", "a", "\\,", "c"); assertTextArray("Multiple chars with comma surrounded by spaces", - "@string/multiple_chars_with_comma_surrounded_by_spaces", + "!label/multiple_chars_with_comma_surrounded_by_spaces", " a ", " \\, ", " c "); assertTextArray("Multiple labels with escape", - "@string/multiple_labels_with_escape", + "!label/multiple_labels_with_escape", "\\abc", "d\\ef", "gh\\i"); assertTextArray("Multiple labels with escape surrounded by spaces", - "@string/multiple_labels_with_escape_surrounded_by_spaces", + "!label/multiple_labels_with_escape_surrounded_by_spaces", " \\abc ", " d\\ef ", " gh\\i "); assertTextArray("Multiple labels with comma and escape", - "@string/multiple_labels_with_comma_and_escape", + "!label/multiple_labels_with_comma_and_escape", "ab\\\\", "d\\\\\\,", "g\\,i"); assertTextArray("Multiple labels with comma and escape surrounded by spaces", - "@string/multiple_labels_with_comma_and_escape_surrounded_by_spaces", + "!label/multiple_labels_with_comma_and_escape_surrounded_by_spaces", " ab\\\\ ", " d\\\\\\, ", " g\\,i "); } public void testParseMultipleResources() { assertTextArray("Literals and resources", - "1,@string/multiple_chars,z", "1", "a", "b", "c", "z"); + "1,!label/multiple_chars,z", "1", "a", "b", "c", "z"); assertTextArray("Literals and resources and escape at end", - "\\1,@string/multiple_chars,z\\", "\\1", "a", "b", "c", "z\\"); + "\\1,!label/multiple_chars,z\\", "\\1", "a", "b", "c", "z\\"); assertTextArray("Multiple single resource chars and labels", - "@string/single_char,@string/single_label,@string/escaped_comma", + "!label/single_char,!label/single_label,!label/escaped_comma", "a", "abc", "\\,"); assertTextArray("Multiple single resource chars and labels 2", - "@string/single_char,@string/single_label,@string/escaped_comma_escape", + "!label/single_char,!label/single_label,!label/escaped_comma_escape", "a", "abc", "a\\,\\"); assertTextArray("Multiple multiple resource chars and labels", - "@string/multiple_chars,@string/multiple_labels,@string/multiple_chars_with_comma", + "!label/multiple_chars,!label/multiple_labels,!label/multiple_chars_with_comma", "a", "b", "c", "abc", "def", "ghi", "a", "\\,", "c"); assertTextArray("Concatenated resources", - "@string/multiple_chars@string/multiple_labels@string/multiple_chars_with_comma", + "!label/multiple_chars!label/multiple_labels!label/multiple_chars_with_comma", "a", "b", "cabc", "def", "ghia", "\\,", "c"); assertTextArray("Concatenated resource and literal", - "abc@string/multiple_labels", + "abc!label/multiple_labels", "abcabc", "def", "ghi"); } public void testParseIndirectReference() { assertTextArray("Indirect", - "@string/indirect_string", "a", "b", "c"); + "!label/indirect_string", "a", "b", "c"); assertTextArray("Indirect with literal", - "1,@string/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2"); + "1,!label/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2"); } public void testParseInfiniteIndirectReference() { assertError("Infinite indirection", - "1,@string/infinite_indirection,2", "1", "infinite", "", "loop", "2"); + "1,!label/infinite_indirection,2", "1", "infinite", "", "loop", "2"); } } diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java index 980b1e4d5..e4879ad2a 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java @@ -97,10 +97,10 @@ public class KeySpecParserTests extends AndroidTestCase { "a", null, ICON_UNDEFINED, 'a'); assertParser("Single escaped surrogate", "\\" + PAIR2, PAIR2, null, ICON_UNDEFINED, CODE2); - assertParser("Single at", "@", - "@", null, ICON_UNDEFINED, '@'); - assertParser("Single escaped at", "\\@", - "@", null, ICON_UNDEFINED, '@'); + assertParser("Single bang", "!", + "!", null, ICON_UNDEFINED, '!'); + assertParser("Single escaped bang", "\\!", + "!", null, ICON_UNDEFINED, '!'); assertParser("Single output text letter", "a|a", "a", null, ICON_UNDEFINED, 'a'); assertParser("Single surrogate pair outputText", "G Clef|" + PAIR1, @@ -120,14 +120,14 @@ public class KeySpecParserTests extends AndroidTestCase { "a", "a,b", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Single letter with escaped comma outputText", "a|a\\,b", "a", "a,b", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Single letter with outputText starts with at", "a|@bc", - "a", "@bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Single letter with surrogate outputText starts with at", "a|@" + SURROGATE2, - "a", "@" + SURROGATE2, ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Single letter with outputText contains at", "a|a@c", - "a", "a@c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Single letter with escaped at outputText", "a|\\@bc", - "a", "@bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Single letter with outputText starts with bang", "a|!bc", + "a", "!bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Single letter with surrogate outputText starts with bang", "a|!" + SURROGATE2, + "a", "!" + SURROGATE2, ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Single letter with outputText contains bang", "a|a!c", + "a", "a!c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Single letter with escaped bang outputText", "a|\\!bc", + "a", "!bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Single escaped escape with single outputText", "\\\\|\\\\", "\\", null, ICON_UNDEFINED, '\\'); assertParser("Single escaped bar with single outputText", "\\||\\|", @@ -152,14 +152,14 @@ public class KeySpecParserTests extends AndroidTestCase { "a,c", "a,c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Label with escaped comma", "a\\,c", "a,c", "a,c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label starts with at", "@bc", - "@bc", "@bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Surrogate label starts with at", "@" + SURROGATE1, - "@" + SURROGATE1, "@" + SURROGATE1, ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label contains at", "a@c", - "a@c", "a@c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label with escaped at", "\\@bc", - "@bc", "@bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label starts with bang", "!bc", + "!bc", "!bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Surrogate label starts with bang", "!" + SURROGATE1, + "!" + SURROGATE1, "!" + SURROGATE1, ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label contains bang", "a!c", + "a!c", "a!c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label with escaped bang", "\\!bc", + "!bc", "!bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Label with escaped letter", "\\abc", "abc", "abc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Label with outputText", "abc|def", @@ -174,22 +174,22 @@ public class KeySpecParserTests extends AndroidTestCase { "abc", "d|f", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Escaped escape label with outputText", "a\\\\|def", "a\\", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label starts with at and outputText", "@bc|def", - "@bc", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label contains at label and outputText", "a@c|def", - "a@c", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Escaped at label with outputText", "\\@bc|def", - "@bc", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label starts with bang and outputText", "!bc|def", + "!bc", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label contains bang label and outputText", "a!c|def", + "a!c", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Escaped bang label with outputText", "\\!bc|def", + "!bc", "def", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Label with comma outputText", "abc|a,b", "abc", "a,b", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Label with escaped comma outputText", "abc|a\\,b", "abc", "a,b", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label with outputText starts with at", "abc|@bc", - "abc", "@bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label with outputText contains at", "abc|a@c", - "abc", "a@c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label with escaped at outputText", "abc|\\@bc", - "abc", "@bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label with outputText starts with bang", "abc|!bc", + "abc", "!bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label with outputText contains bang", "abc|a!c", + "abc", "a!c", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label with escaped bang outputText", "abc|\\!bc", + "abc", "!bc", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Label with escaped bar outputText", "abc|d\\|f", "abc", "d|f", ICON_UNDEFINED, Keyboard.CODE_OUTPUT_TEXT); assertParser("Escaped bar label with escaped bar outputText", "a\\|c|d\\|f", @@ -203,18 +203,18 @@ public class KeySpecParserTests extends AndroidTestCase { public void testIconAndCode() { assertParser("Icon with outputText", ICON_SETTINGS + "|abc", null, "abc", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Icon with outputText starts with at", ICON_SETTINGS + "|@bc", - null, "@bc", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Icon with outputText contains at", ICON_SETTINGS + "|a@c", - null, "a@c", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Icon with escaped at outputText", ICON_SETTINGS + "|\\@bc", - null, "@bc", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); - assertParser("Label starts with at and code", "@bc|" + CODE_SETTINGS, - "@bc", null, ICON_UNDEFINED, mCodeSettings); - assertParser("Label contains at and code", "a@c|" + CODE_SETTINGS, - "a@c", null, ICON_UNDEFINED, mCodeSettings); - assertParser("Escaped at label with code", "\\@bc|" + CODE_SETTINGS, - "@bc", null, ICON_UNDEFINED, mCodeSettings); + assertParser("Icon with outputText starts with bang", ICON_SETTINGS + "|!bc", + null, "!bc", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Icon with outputText contains bang", ICON_SETTINGS + "|a!c", + null, "a!c", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Icon with escaped bang outputText", ICON_SETTINGS + "|\\!bc", + null, "!bc", mSettingsIconId, Keyboard.CODE_OUTPUT_TEXT); + assertParser("Label starts with bang and code", "!bc|" + CODE_SETTINGS, + "!bc", null, ICON_UNDEFINED, mCodeSettings); + assertParser("Label contains bang and code", "a!c|" + CODE_SETTINGS, + "a!c", null, ICON_UNDEFINED, mCodeSettings); + assertParser("Escaped bang label with code", "\\!bc|" + CODE_SETTINGS, + "!bc", null, ICON_UNDEFINED, mCodeSettings); assertParser("Icon with code", ICON_SETTINGS + "|" + CODE_SETTINGS, null, null, mSettingsIconId, mCodeSettings); } diff --git a/tools/makelabel/Android.mk b/tools/makelabel/Android.mk new file mode 100644 index 000000000..9fa865084 --- /dev/null +++ b/tools/makelabel/Android.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES += $(call all-java-files-under,src) +LOCAL_JAR_MANIFEST := etc/manifest.txt +LOCAL_JAVA_RESOURCE_DIRS := res +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE := makelabel + +include $(BUILD_HOST_JAVA_LIBRARY) +include $(LOCAL_PATH)/etc/Android.mk diff --git a/tools/makelabel/etc/Android.mk b/tools/makelabel/etc/Android.mk new file mode 100644 index 000000000..2d2e9a6ed --- /dev/null +++ b/tools/makelabel/etc/Android.mk @@ -0,0 +1,21 @@ +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := eng + +LOCAL_PREBUILT_EXECUTABLES := makelabel +include $(BUILD_HOST_PREBUILT) diff --git a/tools/makelabel/etc/makelabel b/tools/makelabel/etc/makelabel new file mode 100755 index 000000000..44a05b612 --- /dev/null +++ b/tools/makelabel/etc/makelabel @@ -0,0 +1,63 @@ +#!/bin/sh +# Copyright 2012, The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Set up prog to be the path of this script, including following symlinks, +# and set up progdir to be the fully-qualified pathname of its directory. +prog="$0" +while [ -h "${prog}" ]; do + newProg=`/bin/ls -ld "${prog}"` + newProg=`expr "${newProg}" : ".* -> \(.*\)$"` + if expr "x${newProg}" : 'x/' >/dev/null; then + prog="${newProg}" + else + progdir=`dirname "${prog}"` + prog="${progdir}/${newProg}" + fi +done +oldwd=`pwd` +progdir=`dirname "${prog}"` +cd "${progdir}" +progdir=`pwd` +prog="${progdir}"/`basename "${prog}"` +cd "${oldwd}" + +jarfile=makelabel.jar +frameworkdir="$progdir" +if [ ! -r "$frameworkdir/$jarfile" ] +then + frameworkdir=`dirname "$progdir"`/tools/lib + libdir=`dirname "$progdir"`/tools/lib +fi +if [ ! -r "$frameworkdir/$jarfile" ] +then + frameworkdir=`dirname "$progdir"`/framework + libdir=`dirname "$progdir"`/lib +fi +if [ ! -r "$frameworkdir/$jarfile" ] +then + echo `basename "$prog"`": can't find $jarfile" + exit 1 +fi + +if [ "$OSTYPE" = "cygwin" ] ; then + jarpath=`cygpath -w "$frameworkdir/$jarfile"` + progdir=`cygpath -w "$progdir"` +else + jarpath="$frameworkdir/$jarfile" +fi + +# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored +# might need more memory, e.g. -Xmx128M +exec java -ea -jar "$jarpath" "$@" diff --git a/tools/makelabel/etc/manifest.txt b/tools/makelabel/etc/manifest.txt new file mode 100644 index 000000000..18bf0be09 --- /dev/null +++ b/tools/makelabel/etc/manifest.txt @@ -0,0 +1 @@ +Main-Class: com.android.inputmethod.latin.makelabel.LabelMaker diff --git a/tools/makelabel/res/com/android/inputmethod/keyboard/internal/KeyboardLabelsSet.tmpl b/tools/makelabel/res/com/android/inputmethod/keyboard/internal/KeyboardLabelsSet.tmpl new file mode 100644 index 000000000..0e887e494 --- /dev/null +++ b/tools/makelabel/res/com/android/inputmethod/keyboard/internal/KeyboardLabelsSet.tmpl @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import android.content.Context; +import android.content.res.Resources; + +import com.android.inputmethod.latin.R; + +import java.util.HashMap; + +/** + * !!!!! DO NOT EDIT THIS FILE !!!!! + * This file is generated by tools/makelabel. + */ +public final class KeyboardLabelsSet { + // Language to labels map. + private static final HashMap sLocaleToLabelsMap = + new HashMap(); + private static final HashMap sNameToIdMap = new HashMap(); + + private String[] mLabels; + // Resource name to label map. + private HashMap mResourceNameToLabelsMap = new HashMap(); + + public void setLanguage(final String language) { + mLabels = sLocaleToLabelsMap.get(language); + if (mLabels == null) { + mLabels = LANGUAGE_DEFAULT; + } + } + + public void loadStringResources(Context context) { + loadStringResourcesInternal(context, RESOURCE_NAMES, R.string.english_ime_name); + } + + /* package for test */ + void loadStringResourcesInternal(Context context, final String[] resourceNames, + int referenceId) { + final Resources res = context.getResources(); + final String packageName = res.getResourcePackageName(referenceId); + for (final String resName : resourceNames) { + final int resId = res.getIdentifier(resName, "string", packageName); + mResourceNameToLabelsMap.put(resName, res.getString(resId)); + } + } + + public String getLabel(final String name) { + if (mResourceNameToLabelsMap.containsKey(name)) { + return mResourceNameToLabelsMap.get(name); + } + final Integer id = sNameToIdMap.get(name); + if (id == null) throw new RuntimeException("Unknown label: " + name); + final String label = (id < mLabels.length) ? mLabels[id] : null; + return (label == null) ? LANGUAGE_DEFAULT[id] : label; + } + + private static final String[] RESOURCE_NAMES = { + // These labels' name should be aligned with the @string/ in values/strings.xml. + // Labels for action. + "label_go_key", + // "label_search_key", + "label_send_key", + "label_next_key", + "label_done_key", + "label_previous_key", + // Other labels. + "label_to_alpha_key", + "label_to_symbol_key", + "label_to_symbol_with_microphone_key", + "label_pause_key", + "label_wait_key", + }; + + private static final String[] NAMES = { + /* @NAMES@ */ + }; + + private static final String EMPTY = ""; + + /* Default labels */ + private static final String[] LANGUAGE_DEFAULT = { + /* @DEFAULT_LABELS@ */ + }; + + /* @LABELS@ */ + private static final Object[] LANGUAGES_AND_LABELS = { + /* @LANGUAGES_AND_LABELS@ */ + }; + + static { + int id = 0; + for (final String name : NAMES) { + sNameToIdMap.put(name, id++); + } + + for (int i = 0; i < LANGUAGES_AND_LABELS.length; i += 2) { + final String language = (String)LANGUAGES_AND_LABELS[i]; + final String[] labels = (String[])LANGUAGES_AND_LABELS[i + 1]; + sLocaleToLabelsMap.put(language, labels); + } + } +} diff --git a/java/res/values-ar/donottranslate-more-keys.xml b/tools/makelabel/res/values-ar/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-ar/donottranslate-more-keys.xml rename to tools/makelabel/res/values-ar/donottranslate-more-keys.xml diff --git a/java/res/values-be/donottranslate-more-keys.xml b/tools/makelabel/res/values-be/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-be/donottranslate-more-keys.xml rename to tools/makelabel/res/values-be/donottranslate-more-keys.xml diff --git a/java/res/values-ca/donottranslate-more-keys.xml b/tools/makelabel/res/values-ca/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-ca/donottranslate-more-keys.xml rename to tools/makelabel/res/values-ca/donottranslate-more-keys.xml diff --git a/java/res/values-cs/donottranslate-more-keys.xml b/tools/makelabel/res/values-cs/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-cs/donottranslate-more-keys.xml rename to tools/makelabel/res/values-cs/donottranslate-more-keys.xml diff --git a/java/res/values-da/donottranslate-more-keys.xml b/tools/makelabel/res/values-da/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-da/donottranslate-more-keys.xml rename to tools/makelabel/res/values-da/donottranslate-more-keys.xml diff --git a/java/res/values-de/donottranslate-more-keys.xml b/tools/makelabel/res/values-de/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-de/donottranslate-more-keys.xml rename to tools/makelabel/res/values-de/donottranslate-more-keys.xml diff --git a/java/res/values-en/donottranslate-more-keys.xml b/tools/makelabel/res/values-en/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-en/donottranslate-more-keys.xml rename to tools/makelabel/res/values-en/donottranslate-more-keys.xml diff --git a/java/res/values-es/donottranslate-more-keys.xml b/tools/makelabel/res/values-es/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-es/donottranslate-more-keys.xml rename to tools/makelabel/res/values-es/donottranslate-more-keys.xml diff --git a/java/res/values-et/donottranslate-more-keys.xml b/tools/makelabel/res/values-et/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-et/donottranslate-more-keys.xml rename to tools/makelabel/res/values-et/donottranslate-more-keys.xml diff --git a/java/res/values-fa/donottranslate-more-keys.xml b/tools/makelabel/res/values-fa/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-fa/donottranslate-more-keys.xml rename to tools/makelabel/res/values-fa/donottranslate-more-keys.xml diff --git a/java/res/values-fi/donottranslate-more-keys.xml b/tools/makelabel/res/values-fi/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-fi/donottranslate-more-keys.xml rename to tools/makelabel/res/values-fi/donottranslate-more-keys.xml diff --git a/java/res/values-fr/donottranslate-more-keys.xml b/tools/makelabel/res/values-fr/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-fr/donottranslate-more-keys.xml rename to tools/makelabel/res/values-fr/donottranslate-more-keys.xml diff --git a/java/res/values-hi/donottranslate-more-keys.xml b/tools/makelabel/res/values-hi/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-hi/donottranslate-more-keys.xml rename to tools/makelabel/res/values-hi/donottranslate-more-keys.xml diff --git a/java/res/values-hr/donottranslate-more-keys.xml b/tools/makelabel/res/values-hr/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-hr/donottranslate-more-keys.xml rename to tools/makelabel/res/values-hr/donottranslate-more-keys.xml diff --git a/java/res/values-hu/donottranslate-more-keys.xml b/tools/makelabel/res/values-hu/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-hu/donottranslate-more-keys.xml rename to tools/makelabel/res/values-hu/donottranslate-more-keys.xml diff --git a/java/res/values-is/donottranslate-more-keys.xml b/tools/makelabel/res/values-is/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-is/donottranslate-more-keys.xml rename to tools/makelabel/res/values-is/donottranslate-more-keys.xml diff --git a/java/res/values-it/donottranslate-more-keys.xml b/tools/makelabel/res/values-it/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-it/donottranslate-more-keys.xml rename to tools/makelabel/res/values-it/donottranslate-more-keys.xml diff --git a/java/res/values-iw/donottranslate-more-keys.xml b/tools/makelabel/res/values-iw/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-iw/donottranslate-more-keys.xml rename to tools/makelabel/res/values-iw/donottranslate-more-keys.xml diff --git a/java/res/values-ky/donottranslate-more-keys.xml b/tools/makelabel/res/values-ky/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-ky/donottranslate-more-keys.xml rename to tools/makelabel/res/values-ky/donottranslate-more-keys.xml diff --git a/java/res/values-lt/donottranslate-more-keys.xml b/tools/makelabel/res/values-lt/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-lt/donottranslate-more-keys.xml rename to tools/makelabel/res/values-lt/donottranslate-more-keys.xml diff --git a/java/res/values-lv/donottranslate-more-keys.xml b/tools/makelabel/res/values-lv/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-lv/donottranslate-more-keys.xml rename to tools/makelabel/res/values-lv/donottranslate-more-keys.xml diff --git a/java/res/values-mk/donottranslate-more-keys.xml b/tools/makelabel/res/values-mk/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-mk/donottranslate-more-keys.xml rename to tools/makelabel/res/values-mk/donottranslate-more-keys.xml diff --git a/java/res/values-nb/donottranslate-more-keys.xml b/tools/makelabel/res/values-nb/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-nb/donottranslate-more-keys.xml rename to tools/makelabel/res/values-nb/donottranslate-more-keys.xml diff --git a/java/res/values-nl/donottranslate-more-keys.xml b/tools/makelabel/res/values-nl/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-nl/donottranslate-more-keys.xml rename to tools/makelabel/res/values-nl/donottranslate-more-keys.xml diff --git a/java/res/values-pl/donottranslate-more-keys.xml b/tools/makelabel/res/values-pl/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-pl/donottranslate-more-keys.xml rename to tools/makelabel/res/values-pl/donottranslate-more-keys.xml diff --git a/java/res/values-pt/donottranslate-more-keys.xml b/tools/makelabel/res/values-pt/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-pt/donottranslate-more-keys.xml rename to tools/makelabel/res/values-pt/donottranslate-more-keys.xml diff --git a/java/res/values-rm/donottranslate-more-keys.xml b/tools/makelabel/res/values-rm/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-rm/donottranslate-more-keys.xml rename to tools/makelabel/res/values-rm/donottranslate-more-keys.xml diff --git a/java/res/values-ro/donottranslate-more-keys.xml b/tools/makelabel/res/values-ro/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-ro/donottranslate-more-keys.xml rename to tools/makelabel/res/values-ro/donottranslate-more-keys.xml diff --git a/java/res/values-ru/donottranslate-more-keys.xml b/tools/makelabel/res/values-ru/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-ru/donottranslate-more-keys.xml rename to tools/makelabel/res/values-ru/donottranslate-more-keys.xml diff --git a/java/res/values-sk/donottranslate-more-keys.xml b/tools/makelabel/res/values-sk/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-sk/donottranslate-more-keys.xml rename to tools/makelabel/res/values-sk/donottranslate-more-keys.xml diff --git a/java/res/values-sl/donottranslate-more-keys.xml b/tools/makelabel/res/values-sl/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-sl/donottranslate-more-keys.xml rename to tools/makelabel/res/values-sl/donottranslate-more-keys.xml diff --git a/java/res/values-sr/donottranslate-more-keys.xml b/tools/makelabel/res/values-sr/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-sr/donottranslate-more-keys.xml rename to tools/makelabel/res/values-sr/donottranslate-more-keys.xml diff --git a/java/res/values-sv/donottranslate-more-keys.xml b/tools/makelabel/res/values-sv/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-sv/donottranslate-more-keys.xml rename to tools/makelabel/res/values-sv/donottranslate-more-keys.xml diff --git a/java/res/values-tr/donottranslate-more-keys.xml b/tools/makelabel/res/values-tr/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-tr/donottranslate-more-keys.xml rename to tools/makelabel/res/values-tr/donottranslate-more-keys.xml diff --git a/java/res/values-uk/donottranslate-more-keys.xml b/tools/makelabel/res/values-uk/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-uk/donottranslate-more-keys.xml rename to tools/makelabel/res/values-uk/donottranslate-more-keys.xml diff --git a/java/res/values-vi/donottranslate-more-keys.xml b/tools/makelabel/res/values-vi/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-vi/donottranslate-more-keys.xml rename to tools/makelabel/res/values-vi/donottranslate-more-keys.xml diff --git a/java/res/values-zz/donottranslate-more-keys.xml b/tools/makelabel/res/values-zz/donottranslate-more-keys.xml similarity index 100% rename from java/res/values-zz/donottranslate-more-keys.xml rename to tools/makelabel/res/values-zz/donottranslate-more-keys.xml diff --git a/java/res/values/donottranslate-more-keys.xml b/tools/makelabel/res/values/donottranslate-more-keys.xml similarity index 91% rename from java/res/values/donottranslate-more-keys.xml rename to tools/makelabel/res/values/donottranslate-more-keys.xml index 14c278af9..7878757f7 100644 --- a/java/res/values/donottranslate-more-keys.xml +++ b/tools/makelabel/res/values/donottranslate-more-keys.xml @@ -59,6 +59,13 @@ + !fixedColumnOrder!4,‘,’,‚,‛ + + + !fixedColumnOrder!4,“,”,«,» + + + !fixedColumnOrder!4,“,”,«,»,‘,’,‚,‛ !fixedColumnOrder!3,‹,≤,« !fixedColumnOrder!3,›,≥,» - !fixedColumnOrder!4,‘,’,‚,‛ - - - !fixedColumnOrder!4,“,”,«,» - - - !fixedColumnOrder!4,“,”,«,»,‘,’,‚,‛ + + = \\ < + + ~ \\ { + + Tab + + 123 + + + *# + + "AM" + + "PM" diff --git a/tools/makelabel/src/com/android/inputmethod/latin/makelabel/ArrayInitializerFormatter.java b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/ArrayInitializerFormatter.java new file mode 100644 index 000000000..0cf2991b0 --- /dev/null +++ b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/ArrayInitializerFormatter.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makelabel; + +import java.io.PrintStream; + +public class ArrayInitializerFormatter { + private final PrintStream mOut; + private final int mMaxWidth; + private final String mIndent; + + private int mCurrentIndex = 0; + private String mFixedElement; + private final StringBuilder mBuffer = new StringBuilder(); + private int mBufferedLen; + private int mBufferedIndex = Integer.MIN_VALUE; + + public ArrayInitializerFormatter(PrintStream out, int width, String indent) { + mOut = out; + mMaxWidth = width - indent.length(); + mIndent = indent; + } + + public void flush() { + if (mBuffer.length() == 0) { + 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]); + } else { + mOut.format("%s/* %d~ */\n" + + "%s%s\n" + + "%s/* ~%d */\n", mIndent, mBufferedIndex, + mIndent, mBuffer, + mIndent, lastIndex); + } + mBuffer.setLength(0); + mBufferedLen = 0; + } + + public void outCommentLines(String lines) { + flush(); + mOut.print(lines); + mFixedElement = null; + } + + public void outElement(String element) { + if (!element.equals(mFixedElement)) { + flush(); + mBufferedIndex = mCurrentIndex; + } + final int nextLen = mBufferedLen + " ".length() + element.length(); + if (mBufferedLen != 0 && nextLen < mMaxWidth) { + mBuffer.append(' '); + mBuffer.append(element); + mBufferedLen = nextLen; + } else { + if (mBufferedLen != 0) { + mBuffer.append('\n'); + mBuffer.append(mIndent); + } + mBuffer.append(element); + mBufferedLen = element.length(); + } + mCurrentIndex++; + mFixedElement = element; + } +} diff --git a/tools/makelabel/src/com/android/inputmethod/latin/makelabel/JarUtils.java b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/JarUtils.java new file mode 100644 index 000000000..b24b2ca30 --- /dev/null +++ b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/JarUtils.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makelabel; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public class JarUtils { + private static final String MANIFEST = "META-INF/MANIFEST.MF"; + + private JarUtils() { + // This utility class is not publicly instantiable. + } + + public static JarFile getJarFile(final ClassLoader loader) { + final URL resUrl = loader.getResource(MANIFEST); + if (!resUrl.getProtocol().equals("jar")) { + throw new RuntimeException("Should run as jar"); + } + final String path = resUrl.getPath(); + if (!path.startsWith("file:")) { + throw new RuntimeException("Unknown jar path: " + path); + } + final String jarPath = path.substring("file:".length(), path.indexOf('!')); + try { + return new JarFile(URLDecoder.decode(jarPath, "UTF-8")); + } catch (UnsupportedEncodingException e) { + } catch (IOException e) { + } + return null; + } + + public static InputStream openResource(final String name) { + return JarUtils.class.getResourceAsStream("/" + name); + } + + public interface JarFilter { + public boolean accept(String dirName, String name); + } + + public static ArrayList getNameListing(final JarFile jar, final JarFilter filter) { + final ArrayList result = new ArrayList(); + final Enumeration entries = jar.entries(); + while (entries.hasMoreElements()) { + final JarEntry entry = entries.nextElement(); + final String path = entry.getName(); + final int pos = path.lastIndexOf('/'); + final String dirName = (pos >= 0) ? path.substring(0, pos) : ""; + final String name = (pos >= 0) ? path.substring(pos + 1) : path; + if (filter.accept(dirName, name)) { + result.add(path); + } + } + return result; + } + + public static ArrayList getNameListing(final JarFile jar, final String filterName) { + return getNameListing(jar, new JarFilter() { + @Override + public boolean accept(final String dirName, final String name) { + return name.equals(filterName); + } + }); + } +} diff --git a/tools/makelabel/src/com/android/inputmethod/latin/makelabel/LabelMaker.java b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/LabelMaker.java new file mode 100644 index 000000000..e02f80283 --- /dev/null +++ b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/LabelMaker.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin.makelabel; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.NoSuchElementException; +import java.util.jar.JarFile; + +public class LabelMaker { + static class Options { + private static final String OPTION_JAVA = "-java"; + + public final String mJava; + + public static void usage(String message) { + if (message != null) { + System.err.println(message); + } + System.err.println("usage: makelabel " + OPTION_JAVA + " "); + System.exit(1); + } + + public Options(final String[] argsArray) { + final LinkedList args = new LinkedList(Arrays.asList(argsArray)); + String arg = null; + String java = null; + try { + while (!args.isEmpty()) { + arg = args.removeFirst(); + if (arg.equals(OPTION_JAVA)) { + java = args.removeFirst(); + } else { + usage("Unknown option: " + arg); + } + } + } catch (NoSuchElementException e) { + usage("Option " + arg + " needs argument"); + } + + mJava = java; + } + } + + public static void main(final String[] args) { + final Options options = new Options(args); + final JarFile jar = JarUtils.getJarFile(LabelMaker.class.getClassLoader()); + final MoreKeysResources resources = new MoreKeysResources(jar); + resources.writeToJava(options.mJava); + } +} diff --git a/tools/makelabel/src/com/android/inputmethod/latin/makelabel/MoreKeysResources.java b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/MoreKeysResources.java new file mode 100644 index 000000000..1dfb8533f --- /dev/null +++ b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/MoreKeysResources.java @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makelabel; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.jar.JarFile; + +public class MoreKeysResources { + private static final String LABEL_RESOURCE_NAME = "donottranslate-more-keys.xml"; + + private static final String JAVA_TEMPLATE = "KeyboardLabelsSet.tmpl"; + private static final String MARK_NAMES = "@NAMES@"; + private static final String MARK_DEFAULT_LABELS = "@DEFAULT_LABELS@"; + private static final String MARK_LABELS = "@LABELS@"; + private static final String MARK_LANGUAGES_AND_LABELS = "@LANGUAGES_AND_LABELS@"; + private static final String DEFAUT_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"; + private static final String NO_LANGUAGE_DISPLAY_NAME = "No language"; + + private final JarFile mJar; + // Language to string resources map. + private final HashMap mResourcesMap = + new HashMap(); + // Name to id map. + private final HashMap mNameToIdMap = new HashMap(); + + public MoreKeysResources(final JarFile jar) { + mJar = jar; + final ArrayList resources = JarUtils.getNameListing(jar, LABEL_RESOURCE_NAME); + for (final String name : resources) { + final String dirName = name.substring(0, name.lastIndexOf('/')); + final int pos = dirName.lastIndexOf('/'); + final String parentName = (pos >= 0) ? dirName.substring(pos + 1) : dirName; + final String language = getLanguageFromResDir(parentName); + final InputStream stream = JarUtils.openResource(name); + try { + mResourcesMap.put(language, new StringResourceMap(stream)); + } finally { + close(stream); + } + } + } + + private static String getLanguageFromResDir(final String dirName) { + final int languagePos = dirName.indexOf('-'); + if (languagePos < 0) { + // Default resource. + return DEFAUT_LANGUAGE_NAME; + } + final String language = dirName.substring(languagePos + 1); + final int countryPos = language.indexOf("-r"); + if (countryPos < 0) { + return language; + } + return language.replace("-r", "_"); + } + + public void writeToJava(final String outDir) { + final ArrayList list = JarUtils.getNameListing(mJar, JAVA_TEMPLATE); + if (list.isEmpty()) + throw new RuntimeException("Can't find java template " + JAVA_TEMPLATE); + if (list.size() > 1) + throw new RuntimeException("Found multiple java template " + JAVA_TEMPLATE); + final String template = list.get(0); + final String javaPackage = template.substring(0, template.lastIndexOf('/')); + PrintStream ps = null; + LineNumberReader lnr = null; + try { + if (outDir == null) { + ps = System.out; + } else { + final File outPackage = new File(outDir, javaPackage); + final File outputFile = new File(outPackage, + JAVA_TEMPLATE.replace(".tmpl", ".java")); + outPackage.mkdirs(); + ps = new PrintStream(outputFile); + } + lnr = new LineNumberReader(new InputStreamReader(JarUtils.openResource(template))); + inflateTemplate(lnr, ps); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + close(lnr); + close(ps); + } + } + + private void inflateTemplate(final LineNumberReader in, final PrintStream out) + throws IOException { + String line; + while ((line = in.readLine()) != null) { + if (line.contains(MARK_NAMES)) { + dumpNames(out); + } else if (line.contains(MARK_DEFAULT_LABELS)) { + dumpDefaultLabels(out); + } else if (line.contains(MARK_LABELS)) { + dumpLabels(out); + } else if (line.contains(MARK_LANGUAGES_AND_LABELS)) { + dumpLanguageMap(out); + } else { + out.println(line); + } + } + } + + private void dumpNames(final PrintStream out) { + final StringResourceMap defaultResMap = mResourcesMap.get(DEFAUT_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++; + } + } + + private void dumpDefaultLabels(final PrintStream out) { + final StringResourceMap defaultResMap = mResourcesMap.get(DEFAUT_LANGUAGE_NAME); + dumpLabelsInternal(out, defaultResMap, defaultResMap); + } + + private void dumpLabels(final PrintStream out) { + final StringResourceMap defaultResMap = mResourcesMap.get(DEFAUT_LANGUAGE_NAME); + final ArrayList allLanguages = new ArrayList(); + allLanguages.addAll(mResourcesMap.keySet()); + Collections.sort(allLanguages); + for (final String language : allLanguages) { + if (language.equals(DEFAUT_LANGUAGE_NAME)) { + continue; + } + out.format(" /* Language %s: %s */\n", language, getLanguageDisplayName(language)); + out.format(" private static final String[] " + ARRAY_NAME_FOR_LANGUAGE + " = {\n", + language); + final StringResourceMap resMap = mResourcesMap.get(language); + dumpLabelsInternal(out, resMap, defaultResMap); + out.format(" };\n\n"); + } + } + + private void dumpLanguageMap(final PrintStream out) { + final ArrayList allLanguages = new ArrayList(); + allLanguages.addAll(mResourcesMap.keySet()); + Collections.sort(allLanguages); + for (final String language : allLanguages) { + out.format(" \"%s\", " + ARRAY_NAME_FOR_LANGUAGE + ", /* %s */\n", + language, language, getLanguageDisplayName(language)); + } + } + + private static String getLanguageDisplayName(final String language) { + if (language.equals(NO_LANGUAGE_CODE)) { + return NO_LANGUAGE_DISPLAY_NAME; + } else { + return new Locale(language).getDisplayLanguage(); + } + } + + private static void dumpLabelsInternal(final PrintStream out, final StringResourceMap resMap, + final StringResourceMap defaultResMap) { + final ArrayInitializerFormatter formatter = + new ArrayInitializerFormatter(out, 100, " "); + boolean successiveNull = false; + for (final StringResource defaultRes : defaultResMap.getResources()) { + if (resMap.contains(defaultRes.mName)) { + final StringResource res = resMap.get(defaultRes.mName); + if (res.mComment != null) { + formatter.outCommentLines(addPrefix(" // ", res. mComment)); + } + final String escaped = escapeNonAscii(res.mValue); + if (escaped.length() == 0) { + formatter.outElement(EMPTY_STRING_VAR + ","); + } else { + formatter.outElement(String.format("\"%s\",", escaped)); + } + successiveNull = false; + } else { + formatter.outElement("null,"); + successiveNull = true; + } + } + if (!successiveNull) { + formatter.flush(); + } + } + + private static String addPrefix(final String prefix, final String lines) { + final StringBuilder sb = new StringBuilder(); + for (final String line : lines.split("\n")) { + sb.append(prefix + line.trim() + "\n"); + } + return sb.toString(); + } + + private static String escapeNonAscii(final String text) { + final StringBuilder sb = new StringBuilder(); + final int length = text.length(); + for (int i = 0; i < length; i++) { + final char c = text.charAt(i); + if (c >= ' ' && c < 0x7f) { + sb.append(c); + } else { + 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/", "!label/"); + 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; + } + + private static void close(Closeable stream) { + try { + if (stream != null) { + stream.close(); + } + } catch (IOException e) { + } + } +} diff --git a/tools/makelabel/src/com/android/inputmethod/latin/makelabel/StringResource.java b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/StringResource.java new file mode 100644 index 000000000..793483ce1 --- /dev/null +++ b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/StringResource.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makelabel; + +public class StringResource { + public final String mName; + public final String mValue; + public final String mComment; + + public StringResource(final String name, final String value, final String comment) { + mName = name; + mValue = value; + mComment = comment; + } +} diff --git a/tools/makelabel/src/com/android/inputmethod/latin/makelabel/StringResourceMap.java b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/StringResourceMap.java new file mode 100644 index 000000000..afb1aa7ac --- /dev/null +++ b/tools/makelabel/src/com/android/inputmethod/latin/makelabel/StringResourceMap.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makelabel; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.ext.DefaultHandler2; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +public class StringResourceMap { + // String resource list. + private final List mResources; + // Name to string resource map. + private final Map mResourcesMap; + + public StringResourceMap(final InputStream is) { + final StringResourceHandler handler = new StringResourceHandler(); + final SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + try { + final SAXParser parser = factory.newSAXParser(); + // In order to get comment tag. + parser.setProperty("http://xml.org/sax/properties/lexical-handler", handler); + parser.parse(is, handler); + } catch (ParserConfigurationException e) { + } catch (SAXException e) { + throw new RuntimeException(e.getMessage()); + } catch (IOException e) { + } + + mResources = Collections.unmodifiableList(handler.mResources); + final HashMap map = new HashMap(); + for (final StringResource res : mResources) { + map.put(res.mName, res); + } + mResourcesMap = map; + } + + public List getResources() { + return mResources; + } + + public boolean contains(final String name) { + return mResourcesMap.containsKey(name); + } + + public StringResource get(final String name) { + return mResourcesMap.get(name); + } + + static class StringResourceHandler extends DefaultHandler2 { + private static final String TAG_RESOURCES = "resources"; + private static final String TAG_STRING = "string"; + private static final String ATTR_NAME = "name"; + + final ArrayList mResources = new ArrayList(); + + private String mName; + private final StringBuilder mValue = new StringBuilder(); + private final StringBuilder mComment = new StringBuilder(); + + private void init() { + mName = null; + mComment.setLength(0); + } + + @Override + public void comment(char[] ch, int start, int length) { + mComment.append(ch, start, length); + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attr) { + if (TAG_RESOURCES.equals(localName)) { + init(); + } else if (TAG_STRING.equals(localName)) { + mName = attr.getValue(ATTR_NAME); + mValue.setLength(0); + } + } + + @Override + public void characters(char[] ch, int start, int length) { + mValue.append(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + if (TAG_STRING.equals(localName)) { + if (mName == null) + throw new SAXException(TAG_STRING + " doesn't have name"); + final String comment = mComment.length() > 0 ? mComment.toString() : null; + String value = mValue.toString(); + if (value.startsWith("\"") && value.endsWith("\"")) { + // Trim surroundings double quote. + value = value.substring(1, value.length() - 1); + } + mResources.add(new StringResource(mName, value, comment)); + init(); + } + } + } +}