pseudolocalize.cpp revision a2ef5c0d4fb863c0382e77ae00f986a019b11cbe
1093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber#include "pseudolocalize.h"
2093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
3093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberusing namespace std;
4093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
5093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber// String basis to generate expansion
6093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const String16 k_expansion_string = String16("one two three "
7093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    "four five six seven eight nine ten eleven twelve thirteen "
8093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    "fourteen fiveteen sixteen seventeen nineteen twenty");
9093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
10093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber// Special unicode characters to override directionality of the words
11093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const String16 k_rlm = String16("\xe2\x80\x8f");
12093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const String16 k_rlo = String16("\xE2\x80\xae");
13093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const String16 k_pdf = String16("\xE2\x80\xac");
14093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
15093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber// Placeholder marks
16093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const String16 k_placeholder_open = String16("\xc2\xbb");
17093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const String16 k_placeholder_close = String16("\xc2\xab");
18093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
19093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const char*
20093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberpseudolocalize_char(const char16_t c)
21093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber{
22093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    switch (c) {
23b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        case 'a':   return "\xc3\xa5";
24b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        case 'b':   return "\xc9\x93";
25093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'c':   return "\xc3\xa7";
26093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'd':   return "\xc3\xb0";
27093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'e':   return "\xc3\xa9";
28093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'f':   return "\xc6\x92";
29093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'g':   return "\xc4\x9d";
30093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'h':   return "\xc4\xa5";
31b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        case 'i':   return "\xc3\xae";
32093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'j':   return "\xc4\xb5";
33093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'k':   return "\xc4\xb7";
34b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        case 'l':   return "\xc4\xbc";
35b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross        case 'm':   return "\xe1\xb8\xbf";
36093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'n':   return "\xc3\xb1";
37093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'o':   return "\xc3\xb6";
38093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'p':   return "\xc3\xbe";
39093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'q':   return "\x51";
40093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'r':   return "\xc5\x95";
41093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 's':   return "\xc5\xa1";
42093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 't':   return "\xc5\xa3";
43093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'u':   return "\xc3\xbb";
44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'v':   return "\x56";
45093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'w':   return "\xc5\xb5";
46093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'x':   return "\xd1\x85";
47093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'y':   return "\xc3\xbd";
48093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'z':   return "\xc5\xbe";
49093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'A':   return "\xc3\x85";
50093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'B':   return "\xce\xb2";
51093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'C':   return "\xc3\x87";
52093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'D':   return "\xc3\x90";
53093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'E':   return "\xc3\x89";
54093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'G':   return "\xc4\x9c";
55093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'H':   return "\xc4\xa4";
56093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'I':   return "\xc3\x8e";
57093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'J':   return "\xc4\xb4";
58093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'K':   return "\xc4\xb6";
59093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'L':   return "\xc4\xbb";
60093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'M':   return "\xe1\xb8\xbe";
61c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        case 'N':   return "\xc3\x91";
62093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'O':   return "\xc3\x96";
63d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        case 'P':   return "\xc3\x9e";
64d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        case 'Q':   return "\x71";
65d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        case 'R':   return "\xc5\x94";
66d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        case 'S':   return "\xc5\xa0";
67093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'T':   return "\xc5\xa2";
68093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'U':   return "\xc3\x9b";
69093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'V':   return "\xce\xbd";
70093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'W':   return "\xc5\xb4";
71093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'X':   return "\xc3\x97";
72093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'Y':   return "\xc3\x9d";
73093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'Z':   return "\xc5\xbd";
74093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case '!':   return "\xc2\xa1";
75093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case '?':   return "\xc2\xbf";
76093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case '$':   return "\xe2\x82\xac";
77093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        default:    return NULL;
78093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
79093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
80093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
81093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberstatic const bool
82093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberis_possible_normal_placeholder_end(const char16_t c) {
83093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    switch (c) {
84093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 's': return true;
85093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'S': return true;
86093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'c': return true;
87093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'C': return true;
88093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        case 'd': return true;
895279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'o': return true;
902f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        case 'x': return true;
915279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'X': return true;
925279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'f': return true;
935279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'e': return true;
945279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'E': return true;
955279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'g': return true;
965ec58d925520e6913fba3fc54413881af751c610Andreas Huber        case 'G': return true;
975ec58d925520e6913fba3fc54413881af751c610Andreas Huber        case 'a': return true;
98f02a7f5c42db707d20e59ff28f32d1eaebcc5429Johann        case 'A': return true;
995ec58d925520e6913fba3fc54413881af751c610Andreas Huber        case 'b': return true;
1005279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'B': return true;
1015279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'h': return true;
1025279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'H': return true;
1035279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case '%': return true;
1045279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        case 'n': return true;
105d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber        default:  return false;
106b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    }
1072f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
1085279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
109d42573cace9db2b5948e540c32beaef80f04153cAndreas HuberString16
1105279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huberpseudo_generate_expansion(const unsigned int length) {
111d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    String16 result = k_expansion_string;
112d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    const char16_t* s = result.string();
113d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    if (result.size() < length) {
1145279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        result += String16(" ");
1155279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        result += pseudo_generate_expansion(length - result.size());
1165279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    } else {
1175279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        int ext = 0;
1185279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        // Should contain only whole words, so looking for a space
119093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        for (unsigned int i = length + 1; i < result.size(); ++i) {
120093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber          ++ext;
121093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber          if (s[i] == ' ') {
122093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            break;
123093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber          }
124093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
125093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        result.remove(length + ext, 0);
126093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
127093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    return result;
128093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber}
129093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber
130093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber/**
13150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber * Converts characters so they look like they've been localized.
13250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber *
13350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber * Note: This leaves escape sequences untouched so they can later be
134093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber * processed by ResTable::collectString in the normal way.
135093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber */
136093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas HuberString16
137093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huberpseudolocalize_string(const String16& source)
138093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber{
139093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const char16_t* s = source.string();
140093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    String16 result;
141093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const size_t I = source.size();
142093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    for (size_t i=0; i<I; i++) {
143093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        char16_t c = s[i];
14474a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber        if (c == '\\') {
1455279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber            // Escape syntax, no need to pseudolocalize
146b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            if (i<I-1) {
147093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                result += String16("\\");
14850c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                i++;
14950c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                c = s[i];
150093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                switch (c) {
151093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    case 'u':
15250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        // this one takes up 5 chars
15350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        result += String16(s+i, 5);
15450c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber                        i += 4;
155093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                        break;
156093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    case 't':
157093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    case 'n':
158093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    case '#':
1592f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    case '@':
1602f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    case '?':
1612f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    case '"':
1622f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    case '\'':
1632f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    case '\\':
1642f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    default:
1652f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        result.append(&c, 1);
1662f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        break;
1672f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                }
1682f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            } else {
1692f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                result.append(&c, 1);
1702f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            }
1712f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        } else if (c == '%') {
1722f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            // Placeholder syntax, no need to pseudolocalize
1732f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            result += k_placeholder_open;
1742f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            bool end = false;
1752f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            result.append(&c, 1);
1762f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            while (!end && i < I) {
1772f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                ++i;
1782f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                c = s[i];
1792f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                result.append(&c, 1);
1802f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                if (is_possible_normal_placeholder_end(c)) {
1812f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    end = true;
1822f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                } else if (c == 't') {
1832f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    ++i;
1842f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    c = s[i];
1852f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    result.append(&c, 1);
1862f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    end = true;
1872f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                }
1882f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            }
1892f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            result += k_placeholder_close;
1902f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih        } else if (c == '<' || c == '&') {
1912f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            // html syntax, no need to pseudolocalize
1922f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            bool tag_closed = false;
1932f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih            while (!tag_closed && i < I) {
1942f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                if (c == '&') {
1952f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    String16 escape_text;
1962f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    escape_text.append(&c, 1);
1972f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    bool end = false;
1982f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    size_t htmlCodePos = i;
1992f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                    while (!end && htmlCodePos < I) {
2002f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        ++htmlCodePos;
2012f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        c = s[htmlCodePos];
2022f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        escape_text.append(&c, 1);
2032f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        // Valid html code
2042f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        if (c == ';') {
2052f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                            end = true;
206093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                            i = htmlCodePos;
207093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                        }
208093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                        // Wrong html code
209093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                        else if (!((c == '#' ||
210093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                                 (c >= 'a' && c <= 'z') ||
21174a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber                                 (c >= 'A' && c <= 'Z') ||
212d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber                                 (c >= '0' && c <= '9')))) {
2132f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                            end = true;
2142f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih                        }
215b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    }
216b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    result += escape_text;
217b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    if (escape_text != String16("&lt;")) {
218093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                        tag_closed = true;
219b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    }
220093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    continue;
22174a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber                }
22274a0a0d7f766d63330a00c3fa8f133c44c1d5be6Andreas Huber                if (c == '>') {
223093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    tag_closed = true;
224093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                    result.append(&c, 1);
225b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                    continue;
226b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                }
227b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                result.append(&c, 1);
228b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                i++;
229b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber                c = s[i];
230b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            }
231b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber        } else {
232b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            // This is a pure text that should be pseudolocalized
233b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            const char* p = pseudolocalize_char(c);
234b10f3669a9b73cd024662c2b70f5155bc0c2cd21Andreas Huber            if (p != NULL) {
235b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                result += String16(p);
236093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            } else {
237093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                result.append(&c, 1);
238093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            }
239093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber        }
240093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    }
24150c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber    return result;
24250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber}
24350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber
24450c8bea8fba2fcafb14696399028bdbc094dc995Andreas HuberString16
24584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberpseudobidi_string(const String16& source)
2465279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber{
247093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    const char16_t* s = source.string();
248093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    String16 result;
249093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    result += k_rlm;
250093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    result += k_rlo;
251093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber    for (size_t i=0; i<source.size(); i++) {
25250c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        char16_t c = s[i];
25350c8bea8fba2fcafb14696399028bdbc094dc995Andreas Huber        switch(c) {
254093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            case ' ': result += k_pdf;
255093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                      result += k_rlm;
256093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                      result.append(&c, 1);
257093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                      result += k_rlm;
258093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                      result += k_rlo;
259093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber                      break;
260093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber            default: result.append(&c, 1);
2615279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber                     break;
2625279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber        }
2635279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    }
2642f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih    result += k_pdf;
265d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber    result += k_rlm;
2665279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber    return result;
2672f46e8152fb881d3a1d7afd223f1ed51f6e358b8Robert Shih}
2685279d1d8c19e5fdbb177805db0da8e8aadac3079Andreas Huber
269d42573cace9db2b5948e540c32beaef80f04153cAndreas Huber