convert.cjs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict';
  2. const emoji_data = require('./data.cjs');
  3. function getEmojiCodePoint(code) {
  4. return parseInt(code, 16);
  5. }
  6. function utf32FirstNum(code) {
  7. return (code - emoji_data.minUTF32 >> 10 | 0) + emoji_data.startUTF32Pair1;
  8. }
  9. function utf32SecondNum(code) {
  10. return (code - emoji_data.minUTF32 & 1023) + emoji_data.startUTF32Pair2;
  11. }
  12. function splitUTF32Number(code) {
  13. if (code >= emoji_data.minUTF32) {
  14. return [utf32FirstNum(code), utf32SecondNum(code)];
  15. }
  16. }
  17. function isUTF32SplitNumber(value) {
  18. if (value >= emoji_data.startUTF32Pair1) {
  19. if (value < emoji_data.startUTF32Pair2) {
  20. return 1;
  21. }
  22. if (value < emoji_data.endUTF32Pair) {
  23. return 2;
  24. }
  25. }
  26. return false;
  27. }
  28. function mergeUTF32Numbers(part1, part2) {
  29. if (part1 < emoji_data.startUTF32Pair1 || part1 >= emoji_data.startUTF32Pair2 || part2 < emoji_data.startUTF32Pair2 || part2 >= emoji_data.endUTF32Pair) {
  30. return;
  31. }
  32. return (part1 - emoji_data.startUTF32Pair1 << 10) + (part2 - emoji_data.startUTF32Pair2) + emoji_data.minUTF32;
  33. }
  34. function getEmojiUnicode(code) {
  35. return String.fromCodePoint(
  36. typeof code === "number" ? code : getEmojiCodePoint(code)
  37. );
  38. }
  39. function convertEmojiSequenceToUTF16(numbers) {
  40. const results = [];
  41. for (let i = 0; i < numbers.length; i++) {
  42. const code = numbers[i];
  43. if (code >= emoji_data.minUTF32) {
  44. results.push(utf32FirstNum(code));
  45. results.push(utf32SecondNum(code));
  46. } else {
  47. results.push(code);
  48. }
  49. }
  50. return results;
  51. }
  52. function convertEmojiSequenceToUTF32(numbers, throwOnError = true) {
  53. const results = [];
  54. for (let i = 0; i < numbers.length; i++) {
  55. const code = numbers[i];
  56. if (code >= emoji_data.minUTF32) {
  57. results.push(code);
  58. continue;
  59. }
  60. const part = isUTF32SplitNumber(code);
  61. if (!part) {
  62. results.push(code);
  63. continue;
  64. }
  65. if (part === 1 && numbers.length > i + 1) {
  66. const merged = mergeUTF32Numbers(code, numbers[i + 1]);
  67. if (merged) {
  68. i++;
  69. results.push(merged);
  70. continue;
  71. }
  72. }
  73. if (throwOnError) {
  74. const nextCode = numbers[i + 1];
  75. throw new Error(
  76. `Invalid UTF-16 sequence: ${code.toString(16)}-${nextCode ? nextCode.toString(16) : "undefined"}`
  77. );
  78. }
  79. results.push(code);
  80. }
  81. return results;
  82. }
  83. exports.convertEmojiSequenceToUTF16 = convertEmojiSequenceToUTF16;
  84. exports.convertEmojiSequenceToUTF32 = convertEmojiSequenceToUTF32;
  85. exports.getEmojiCodePoint = getEmojiCodePoint;
  86. exports.getEmojiUnicode = getEmojiUnicode;
  87. exports.isUTF32SplitNumber = isUTF32SplitNumber;
  88. exports.mergeUTF32Numbers = mergeUTF32Numbers;
  89. exports.splitUTF32Number = splitUTF32Number;