whitespace
[conkeror/arlinius.git] / modules / casual-spelling.js
blob17caf8d9c1161345641e3eed0a6d9382a125b870
1 /**
2  * (C) Copyright 2009 John J. Foerch
3  *
4  * Use, modification, and distribution are subject to the terms specified in the
5  * COPYING file.
6 **/
8 /**
9  * Contributors:
10  *   Kris Maglione
11  *   John J. Foerch
12  */
16 This module provides a pattern matcher for hints_text_match which lets you
17 type ascii characters in the hints minibuffer and match unicode characters
18 such as accented letters and ligatures.
22 var casual_spelling_table = {};
24 function casual_spelling_table_add (table) {
25     table.__proto__ = casual_spelling_table;
26     casual_spelling_table = table;
30 /**
31  * casual_spelling_from_range_table is a constructor of
32  * casual_spelling_table which generates the table from a shorthand form
33  * called a "range table".  A range table is an array where each element
34  * is an array of three elements: range-low, range-high, and range-spec.
35  * Low and high are integer codepoints of unicode characters to be
36  * translated.  The spec can be a string, or an array.  If it is a string,
37  * it should be a single character.  The designated range will have that
38  * character as its low-point translation, and each next character in the
39  * range will be incremented from that point.  This is how you can
40  * compactly denote alphabetic ranges, for example.  If the spec is an
41  * array, the strings in that array will be repeated over the designated
42  * range.  Multi-character translations, such as for ligatures, must be
43  * given in the array form of range-spec.
44  */
45 function casual_spelling_from_range_table (table) {
46     var ret = {};
47     table.map(function (a) {
48         for (var c = a[0]; c <= a[1]; c++) {
49             var chr = String.fromCharCode(c);
50             if (typeof a[2] == "string")
51                 ret[chr] = String.fromCharCode(a[2].charCodeAt(0) + c - a[0]);
52             else
53                 ret[chr] = a[2][(c - a[0]) % a[2].length];
54         }
55     });
56     return ret;
59 function casual_spelling_translate (chr) {
60     return casual_spelling_table[chr] || chr;
63 function casual_spelling_hints_text_match (text, pattern) {
64     if (pattern == "")
65         return [0, 0];
66     var tlen = text.length;
67     var plen = pattern.length;
68     var decoded = Array.map(
69         text, function (x) Array.concat(x, casual_spelling_translate(x)));
70     var matched, mlen;
71     for (var i = 0; i < tlen; i++) {
72         for (var e = 0, j = 0; j < plen && i + e < tlen; e++) {
73             if (! decoded[i+e].some(function (x) (pattern.substring(j, j+(mlen = x.length)) == (matched = x))))
74                 break;
75             j += mlen;
76             if (j == plen)
77                 return [i, i+e+1];
78         }
79     }
80     return false;
83 hints_text_match = casual_spelling_hints_text_match;
86 var casual_spelling_accents = casual_spelling_from_range_table(
87     [[0x00a9, 0x00a9, "C"],//copyright
88      [0x00c0, 0x00c5, ["A"]],
89      [0x00c6, 0x00c7, ["AE", "C"]],
90      [0x00c8, 0x00cb, ["E"]],
91      [0x00cc, 0x00cf, ["I"]],
92      [0x00d1, 0x00d1, "N"],
93      [0x00d2, 0x00d6, ["O"]],
94      [0x00d8, 0x00d8, "O"],
95      [0x00d9, 0x00dc, ["U"]],
96      [0x00dd, 0x00dd, "Y"],
97      [0x00df, 0x00df, ["ss"]],
98      [0x00e0, 0x00e5, ["a"]],
99      [0x00e6, 0x00e7, ["ae", "c"]],
100      [0x00e8, 0x00eb, ["e"]],
101      [0x00ec, 0x00ef, ["i"]],
102      [0x00f1, 0x00f1, "n"],
103      [0x00f2, 0x00f6, ["o"]],
104      [0x00f8, 0x00f8, "o"],
105      [0x00f9, 0x00fc, ["u"]],
106      [0x00fd, 0x00fd, "y"],
107      [0x00ff, 0x00ff, "y"],
108      [0x0100, 0x0105, ["A", "a"]],
109      [0x0106, 0x010d, ["C", "c"]],
110      [0x010e, 0x0111, ["D", "d"]],
111      [0x0112, 0x011b, ["E", "e"]],
112      [0x011c, 0x0123, ["G", "g"]],
113      [0x0124, 0x0127, ["H", "h"]],
114      [0x0128, 0x0130, ["I", "i"]],
115      [0x0132, 0x0133, ["IJ", "ij"]],
116      [0x0134, 0x0135, ["J", "j"]],
117      [0x0136, 0x0136, ["K", "k"]],
118      [0x0139, 0x0142, ["L", "l"]],
119      [0x0143, 0x0148, ["N", "n"]],
120      [0x0149, 0x0149, "n"],
121      [0x014c, 0x0151, ["O", "o"]],
122      [0x0152, 0x0153, ["OE", "oe"]],
123      [0x0154, 0x0159, ["R", "r"]],
124      [0x015a, 0x0161, ["S", "s"]],
125      [0x0162, 0x0167, ["T", "t"]],
126      [0x0168, 0x0173, ["U", "u"]],
127      [0x0174, 0x0175, ["W", "w"]],
128      [0x0176, 0x0178, ["Y", "y", "Y"]],
129      [0x0179, 0x017e, ["Z", "z"]],
130      [0x0180, 0x0183, ["b", "B", "B", "b"]],
131      [0x0187, 0x0189, ["C", "c", "D"]],
132      [0x018a, 0x0192, ["D", "D", "d", "F", "f"]],
133      [0x0193, 0x0194, ["G"]],
134      [0x0197, 0x019b, ["I", "K", "k", "l", "l"]],
135      [0x019d, 0x01a1, ["N", "n", "O", "O", "o"]],
136      [0x01a4, 0x01a5, ["P", "p"]],
137      [0x01ab, 0x01ab, ["t"]],
138      [0x01ac, 0x01b0, ["T", "t", "T", "U", "u"]],
139      [0x01b2, 0x01d2, ["V", "Y", "y", "Z", "z", "D", "L",
140                        "N", "A", "a", "I", "i", "O", "o"]],
141      [0x01d3, 0x01dc, ["U", "u"]],
142      [0x01de, 0x01e1, ["A", "a"]],
143      [0x01e2, 0x01e3, ["AE", "ae"]],
144      [0x01e4, 0x01ed, ["G", "g", "G", "g", "K", "k", "O", "o", "O", "o"]],
145      [0x01f0, 0x01f5, ["j", "D", "G", "g"]],
146      [0x01fa, 0x01fb, ["A", "a"]],
147      [0x01fc, 0x01fd, ["AE", "ae"]],
148      [0x01fe, 0x0217, ["O", "o", "A", "a", "A", "a", "E", "e", "E",
149                        "e", "I", "i", "I", "i", "O", "o", "O", "o",
150                        "R", "r", "R", "r", "U", "u", "U", "u"]],
151      [0x0253, 0x0257, ["b", "c", "d", "d"]],
152      [0x0260, 0x0269, ["g", "h", "h", "i", "i"]],
153      [0x026b, 0x0273, ["l", "l", "l", "l", "m", "n", "n"]],
154      [0x027c, 0x028b, ["r", "r", "r", "r", "s", "t", "u", "u", "v"]],
155      [0x0290, 0x0291, ["z"]],
156      [0x029d, 0x02a0, ["j", "q"]],
157      [0x1e00, 0x1e09, ["A", "a", "B", "b", "B", "b", "B", "b", "C", "c"]],
158      [0x1e0a, 0x1e13, ["D", "d"]],
159      [0x1e14, 0x1e1d, ["E", "e"]],
160      [0x1e1e, 0x1e21, ["F", "f", "G", "g"]],
161      [0x1e22, 0x1e2b, ["H", "h"]],
162      [0x1e2c, 0x1e8f, ["I", "i", "I", "i", "K", "k", "K", "k", "K", "k",
163                        "L", "l", "L", "l", "L", "l", "L", "l", "M", "m",
164                        "M", "m", "M", "m", "N", "n", "N", "n", "N", "n",
165                        "N", "n", "O", "o", "O", "o", "O", "o", "O", "o",
166                        "P", "p", "P", "p", "R", "r", "R", "r", "R", "r",
167                        "R", "r", "S", "s", "S", "s", "S", "s", "S", "s",
168                        "S", "s", "T", "t", "T", "t", "T", "t", "T", "t",
169                        "U", "u", "U", "u", "U", "u", "U", "u", "U", "u",
170                        "V", "v", "V", "v", "W", "w", "W", "w", "W", "w",
171                        "W", "w", "W", "w", "X", "x", "X", "x", "Y", "y"]],
172      [0x1e90, 0x1e9a, ["Z", "z", "Z", "z", "Z", "z", "h", "t", "w", "y", "a"]],
173      [0x1ea0, 0x1eb7, ["A", "a"]],
174      [0x1eb8, 0x1ec7, ["E", "e"]],
175      [0x1ec8, 0x1ecb, ["I", "i"]],
176      [0x1ecc, 0x1ee3, ["O", "o"]],
177      [0x1ee4, 0x1ef1, ["U", "u"]],
178      [0x1ef2, 0x1ef9, ["Y", "y"]],
179      [0x2071, 0x2071, "i"],
180      [0x207f, 0x207f, "n"],
181      [0x249c, 0x24b5, "a"],
182      [0x24b6, 0x24cf, "A"],
183      [0x24d0, 0x24e9, "a"],
184      [0xfb00, 0xfb06, ["ff", "fi", "fl", "ffi", "ffl", "st", "st"]],
185      [0xff21, 0xff3a, "A"],
186      [0xff41, 0xff5a, "a"]]);
188 casual_spelling_table_add(casual_spelling_accents);