User:Erutuon/scripts/combiningCharacters.js

From Wiktionary, the free dictionary
Jump to navigation Jump to search

Note – after saving, you may have to bypass your browser’s cache to see the changes.

  • Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
  • Konqueror and Chrome: click Reload or press F5;
  • Opera: clear the cache in Tools → Preferences;
  • Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.

/* jshint esversion: 6 */

(function () {
	/*
	A JavaScript copy of [[Module:Unicode data/combining]].
	individual matches individual codepoints to their combining category;
	ranges gives inclusive ranges (the first two indices) that have the same
	combining category (the third index).
	*/
	
	const individual = {
		0x00315: 232,
		0x0031A: 232,
		0x0031B: 216,
		0x00345: 240,
		0x00346: 230,
		0x00357: 230,
		0x00358: 232,
		0x0035B: 230,
		0x0035C: 233,
		0x0035F: 233,
		0x00362: 233,
		0x00591: 220,
		0x00596: 220,
		0x0059A: 222,
		0x0059B: 220,
		0x005AA: 220,
		0x005AD: 222,
		0x005AE: 228,
		0x005AF: 230,
		0x005B0:  10,
		0x005B1:  11,
		0x005B2:  12,
		0x005B3:  13,
		0x005B4:  14,
		0x005B5:  15,
		0x005B6:  16,
		0x005B7:  17,
		0x005B8:  18,
		0x005BB:  20,
		0x005BC:  21,
		0x005BD:  22,
		0x005BF:  23,
		0x005C1:  24,
		0x005C2:  25,
		0x005C4: 230,
		0x005C5: 220,
		0x005C7:  18,
		0x00618:  30,
		0x00619:  31,
		0x0061A:  32,
		0x0064B:  27,
		0x0064C:  28,
		0x0064D:  29,
		0x0064E:  30,
		0x0064F:  31,
		0x00650:  32,
		0x00651:  33,
		0x00652:  34,
		0x0065C: 220,
		0x0065F: 220,
		0x00670:  35,
		0x006E3: 220,
		0x006E4: 230,
		0x006EA: 220,
		0x006ED: 220,
		0x00711:  36,
		0x00730: 230,
		0x00731: 220,
		0x00734: 220,
		0x0073A: 230,
		0x0073D: 230,
		0x0073E: 220,
		0x00742: 220,
		0x00743: 230,
		0x00744: 220,
		0x00745: 230,
		0x00746: 220,
		0x00747: 230,
		0x00748: 220,
		0x007F2: 220,
		0x007F3: 230,
		0x008E3: 220,
		0x008E6: 220,
		0x008E9: 220,
		0x008F0:  27,
		0x008F1:  28,
		0x008F2:  29,
		0x008F6: 220,
		0x0093C:   7,
		0x0094D:   9,
		0x00951: 230,
		0x00952: 220,
		0x009BC:   7,
		0x009CD:   9,
		0x00A3C:   7,
		0x00A4D:   9,
		0x00ABC:   7,
		0x00ACD:   9,
		0x00B3C:   7,
		0x00B4D:   9,
		0x00BCD:   9,
		0x00C4D:   9,
		0x00C55:  84,
		0x00C56:  91,
		0x00CBC:   7,
		0x00CCD:   9,
		0x00D4D:   9,
		0x00DCA:   9,
		0x00E3A:   9,
		0x00F35: 220,
		0x00F37: 220,
		0x00F39: 216,
		0x00F71: 129,
		0x00F72: 130,
		0x00F74: 132,
		0x00F80: 130,
		0x00F84:   9,
		0x00FC6: 220,
		0x01037:   7,
		0x0108D: 220,
		0x01714:   9,
		0x01734:   9,
		0x017D2:   9,
		0x017DD: 230,
		0x018A9: 228,
		0x01939: 222,
		0x0193A: 230,
		0x0193B: 220,
		0x01A17: 230,
		0x01A18: 220,
		0x01A60:   9,
		0x01A7F: 220,
		0x01ABD: 220,
		0x01B34:   7,
		0x01B44:   9,
		0x01B6B: 230,
		0x01B6C: 220,
		0x01BAA:   9,
		0x01BAB:   9,
		0x01BE6:   7,
		0x01C37:   7,
		0x01CD4:   1,
		0x01CE0: 230,
		0x01CED: 220,
		0x01CF4: 230,
		0x01DC2: 220,
		0x01DCA: 220,
		0x01DCD: 234,
		0x01DCE: 214,
		0x01DCF: 220,
		0x01DD0: 202,
		0x01DF6: 232,
		0x01DF9: 220,
		0x01DFB: 230,
		0x01DFC: 233,
		0x01DFD: 220,
		0x01DFE: 230,
		0x01DFF: 220,
		0x020E1: 230,
		0x020E7: 230,
		0x020E8: 220,
		0x020E9: 230,
		0x020F0: 230,
		0x02D7F:   9,
		0x0302A: 218,
		0x0302B: 228,
		0x0302C: 232,
		0x0302D: 222,
		0x0A66F: 230,
		0x0A806:   9,
		0x0A8C4:   9,
		0x0A953:   9,
		0x0A9B3:   7,
		0x0A9C0:   9,
		0x0AAB0: 230,
		0x0AAB4: 220,
		0x0AAC1: 230,
		0x0AAF6:   9,
		0x0ABED:   9,
		0x0FB1E:  26,
		0x101FD: 220,
		0x102E0: 220,
		0x10A0D: 220,
		0x10A0F: 230,
		0x10A38: 230,
		0x10A39:   1,
		0x10A3A: 220,
		0x10A3F:   9,
		0x10AE5: 230,
		0x10AE6: 220,
		0x11046:   9,
		0x1107F:   9,
		0x110B9:   9,
		0x110BA:   7,
		0x11173:   7,
		0x111C0:   9,
		0x111CA:   7,
		0x11235:   9,
		0x11236:   7,
		0x112E9:   7,
		0x112EA:   9,
		0x1133C:   7,
		0x1134D:   9,
		0x11442:   9,
		0x11446:   7,
		0x114C2:   9,
		0x114C3:   7,
		0x115BF:   9,
		0x115C0:   7,
		0x1163F:   9,
		0x116B6:   9,
		0x116B7:   7,
		0x1172B:   9,
		0x11A34:   9,
		0x11A47:   9,
		0x11A99:   9,
		0x11C3F:   9,
		0x11D42:   7,
		0x1BC9E:   1,
		0x1D16D: 226,
		0x1E94A:   7,
	};
	
	const ranges = [
		[ 0x00300, 0x00314, 230 ],
		[ 0x00316, 0x00319, 220 ],
		[ 0x0031C, 0x00320, 220 ],
		[ 0x00321, 0x00322, 202 ],
		[ 0x00323, 0x00326, 220 ],
		[ 0x00327, 0x00328, 202 ],
		[ 0x00329, 0x00333, 220 ],
		[ 0x00334, 0x00338,   1 ],
		[ 0x00339, 0x0033C, 220 ],
		[ 0x0033D, 0x00344, 230 ],
		[ 0x00347, 0x00349, 220 ],
		[ 0x0034A, 0x0034C, 230 ],
		[ 0x0034D, 0x0034E, 220 ],
		[ 0x00350, 0x00352, 230 ],
		[ 0x00353, 0x00356, 220 ],
		[ 0x00359, 0x0035A, 220 ],
		[ 0x0035D, 0x0035E, 234 ],
		[ 0x00360, 0x00361, 234 ],
		[ 0x00363, 0x0036F, 230 ],
		[ 0x00483, 0x00487, 230 ],
		[ 0x00592, 0x00595, 230 ],
		[ 0x00597, 0x00599, 230 ],
		[ 0x0059C, 0x005A1, 230 ],
		[ 0x005A2, 0x005A7, 220 ],
		[ 0x005A8, 0x005A9, 230 ],
		[ 0x005AB, 0x005AC, 230 ],
		[ 0x005B9, 0x005BA,  19 ],
		[ 0x00610, 0x00617, 230 ],
		[ 0x00653, 0x00654, 230 ],
		[ 0x00655, 0x00656, 220 ],
		[ 0x00657, 0x0065B, 230 ],
		[ 0x0065D, 0x0065E, 230 ],
		[ 0x006D6, 0x006DC, 230 ],
		[ 0x006DF, 0x006E2, 230 ],
		[ 0x006E7, 0x006E8, 230 ],
		[ 0x006EB, 0x006EC, 230 ],
		[ 0x00732, 0x00733, 230 ],
		[ 0x00735, 0x00736, 230 ],
		[ 0x00737, 0x00739, 220 ],
		[ 0x0073B, 0x0073C, 220 ],
		[ 0x0073F, 0x00741, 230 ],
		[ 0x00749, 0x0074A, 230 ],
		[ 0x007EB, 0x007F1, 230 ],
		[ 0x00816, 0x00819, 230 ],
		[ 0x0081B, 0x00823, 230 ],
		[ 0x00825, 0x00827, 230 ],
		[ 0x00829, 0x0082D, 230 ],
		[ 0x00859, 0x0085B, 220 ],
		[ 0x008D4, 0x008E1, 230 ],
		[ 0x008E4, 0x008E5, 230 ],
		[ 0x008E7, 0x008E8, 230 ],
		[ 0x008EA, 0x008EC, 230 ],
		[ 0x008ED, 0x008EF, 220 ],
		[ 0x008F3, 0x008F5, 230 ],
		[ 0x008F7, 0x008F8, 230 ],
		[ 0x008F9, 0x008FA, 220 ],
		[ 0x008FB, 0x008FF, 230 ],
		[ 0x00953, 0x00954, 230 ],
		[ 0x00D3B, 0x00D3C,   9 ],
		[ 0x00E38, 0x00E39, 103 ],
		[ 0x00E48, 0x00E4B, 107 ],
		[ 0x00EB8, 0x00EB9, 118 ],
		[ 0x00EC8, 0x00ECB, 122 ],
		[ 0x00F18, 0x00F19, 220 ],
		[ 0x00F7A, 0x00F7D, 130 ],
		[ 0x00F82, 0x00F83, 230 ],
		[ 0x00F86, 0x00F87, 230 ],
		[ 0x01039, 0x0103A,   9 ],
		[ 0x0135D, 0x0135F, 230 ],
		[ 0x01A75, 0x01A7C, 230 ],
		[ 0x01AB0, 0x01AB4, 230 ],
		[ 0x01AB5, 0x01ABA, 220 ],
		[ 0x01ABB, 0x01ABC, 230 ],
		[ 0x01B6D, 0x01B73, 230 ],
		[ 0x01BF2, 0x01BF3,   9 ],
		[ 0x01CD0, 0x01CD2, 230 ],
		[ 0x01CD5, 0x01CD9, 220 ],
		[ 0x01CDA, 0x01CDB, 230 ],
		[ 0x01CDC, 0x01CDF, 220 ],
		[ 0x01CE2, 0x01CE8,   1 ],
		[ 0x01CF8, 0x01CF9, 230 ],
		[ 0x01DC0, 0x01DC1, 230 ],
		[ 0x01DC3, 0x01DC9, 230 ],
		[ 0x01DCB, 0x01DCC, 230 ],
		[ 0x01DD1, 0x01DF5, 230 ],
		[ 0x01DF7, 0x01DF8, 228 ],
		[ 0x020D0, 0x020D1, 230 ],
		[ 0x020D2, 0x020D3,   1 ],
		[ 0x020D4, 0x020D7, 230 ],
		[ 0x020D8, 0x020DA,   1 ],
		[ 0x020DB, 0x020DC, 230 ],
		[ 0x020E5, 0x020E6,   1 ],
		[ 0x020EA, 0x020EB,   1 ],
		[ 0x020EC, 0x020EF, 220 ],
		[ 0x02CEF, 0x02CF1, 230 ],
		[ 0x02DE0, 0x02DFF, 230 ],
		[ 0x0302E, 0x0302F, 224 ],
		[ 0x03099, 0x0309A,   8 ],
		[ 0x0A674, 0x0A67D, 230 ],
		[ 0x0A69E, 0x0A69F, 230 ],
		[ 0x0A6F0, 0x0A6F1, 230 ],
		[ 0x0A8E0, 0x0A8F1, 230 ],
		[ 0x0A92B, 0x0A92D, 220 ],
		[ 0x0AAB2, 0x0AAB3, 230 ],
		[ 0x0AAB7, 0x0AAB8, 230 ],
		[ 0x0AABE, 0x0AABF, 230 ],
		[ 0x0FE20, 0x0FE26, 230 ],
		[ 0x0FE27, 0x0FE2D, 220 ],
		[ 0x0FE2E, 0x0FE2F, 230 ],
		[ 0x10376, 0x1037A, 230 ],
		[ 0x11100, 0x11102, 230 ],
		[ 0x11133, 0x11134,   9 ],
		[ 0x11366, 0x1136C, 230 ],
		[ 0x11370, 0x11374, 230 ],
		[ 0x11D44, 0x11D45,   9 ],
		[ 0x16AF0, 0x16AF4,   1 ],
		[ 0x16B30, 0x16B36, 230 ],
		[ 0x1D165, 0x1D166, 216 ],
		[ 0x1D167, 0x1D169,   1 ],
		[ 0x1D16E, 0x1D172, 216 ],
		[ 0x1D17B, 0x1D182, 220 ],
		[ 0x1D185, 0x1D189, 230 ],
		[ 0x1D18A, 0x1D18B, 220 ],
		[ 0x1D1AA, 0x1D1AD, 230 ],
		[ 0x1D242, 0x1D244, 230 ],
		[ 0x1E000, 0x1E006, 230 ],
		[ 0x1E008, 0x1E018, 230 ],
		[ 0x1E01B, 0x1E021, 230 ],
		[ 0x1E023, 0x1E024, 230 ],
		[ 0x1E026, 0x1E02A, 230 ],
		[ 0x1E8D0, 0x1E8D6, 220 ],
		[ 0x1E944, 0x1E949, 230 ],
	];
	
	function simpleRangeSearch(codePoint, ranges) {
		for (let [lower, higher, result] of ranges) {
			// If ranges are greater than codepoint, no match will be found. Short-circuit the loop.
			if ( codePoint < lower) {
				return null;
			} else if (codePoint <= higher) {
				return result;
			}
		}
	}
	
	const binaryRangeSearch = function (codePoint, ranges) {
		if (!ranges) {
			return null;
		}
	
		let iBottom = 0, iMiddle = 0, iTop = ranges.length;
	
		while (iBottom <= iTop) {
			iMiddle = (iBottom + iTop) >> 1;
			let range = ranges[iMiddle];
			if (range === undefined) {
				return null;
			}
			if (codePoint < range[0]) {
				iTop = iMiddle - 1;
			} else if (codePoint <= range[1]) {
				return range[2];
			} else {
				iBottom = iMiddle + 1;
			}
		}
	
		return null;
	};
	
	const getCombiningCategory = function (codePoint) {
		return individual[codePoint] || binaryRangeSearch(codePoint, ranges) || 0;
	};
	
	const isCombining = function (codePoint) {
		return getCombiningCategory(codePoint) !== 0;
	};
	
	window.getCombiningCategory = getCombiningCategory;
	window.isCombining = isCombining;
}());