tree.mjs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { createUTF16EmojiRegexItem, createOptionalEmojiRegexItem, createSequenceEmojiRegexItem, createSetEmojiRegexItem } from './base.mjs';
  2. import { splitEmojiSequences } from '../cleanup.mjs';
  3. import { convertEmojiSequenceToUTF32 } from '../convert.mjs';
  4. import { createRegexForNumbersSequence } from './numbers.mjs';
  5. import { joinerEmoji } from '../data.mjs';
  6. import { mergeSimilarItemsInSet } from './similar.mjs';
  7. function createEmojisTree(sequences) {
  8. const root = [];
  9. for (let i = 0; i < sequences.length; i++) {
  10. const split = splitEmojiSequences(
  11. convertEmojiSequenceToUTF32(sequences[i])
  12. );
  13. let parent = root;
  14. for (let j = 0; j < split.length; j++) {
  15. const regex = createRegexForNumbersSequence(split[j]);
  16. let item;
  17. const match = parent.find(
  18. (item2) => item2.regex.regex === regex.regex
  19. );
  20. if (!match) {
  21. item = {
  22. regex
  23. };
  24. parent.push(item);
  25. } else {
  26. item = match;
  27. }
  28. if (j === split.length - 1) {
  29. item.end = true;
  30. break;
  31. }
  32. parent = item.children || (item.children = []);
  33. }
  34. }
  35. return root;
  36. }
  37. function parseEmojiTree(items) {
  38. function mergeParsedChildren(items2) {
  39. const parsedItems = [];
  40. const mapWithoutEnd = /* @__PURE__ */ Object.create(null);
  41. const mapWithEnd = /* @__PURE__ */ Object.create(null);
  42. for (let i = 0; i < items2.length; i++) {
  43. const item = items2[i];
  44. const children = item.children;
  45. if (children) {
  46. const fullItem = item;
  47. const target = item.end ? mapWithEnd : mapWithoutEnd;
  48. const regex = children.regex;
  49. if (!target[regex]) {
  50. target[regex] = [fullItem];
  51. } else {
  52. target[regex].push(fullItem);
  53. }
  54. } else {
  55. parsedItems.push(item.regex);
  56. }
  57. }
  58. [mapWithEnd, mapWithoutEnd].forEach((source) => {
  59. for (const regex in source) {
  60. const items3 = source[regex];
  61. const firstItem = items3[0];
  62. let childSequence = [
  63. createUTF16EmojiRegexItem([joinerEmoji]),
  64. firstItem.children
  65. ];
  66. if (firstItem.end) {
  67. childSequence = [
  68. createOptionalEmojiRegexItem(
  69. createSequenceEmojiRegexItem(childSequence)
  70. )
  71. ];
  72. }
  73. let mergedRegex;
  74. if (items3.length === 1) {
  75. mergedRegex = firstItem.regex;
  76. } else {
  77. mergedRegex = mergeSimilarItemsInSet(
  78. createSetEmojiRegexItem(items3.map((item) => item.regex))
  79. );
  80. }
  81. const sequence = createSequenceEmojiRegexItem([
  82. mergedRegex,
  83. ...childSequence
  84. ]);
  85. parsedItems.push(sequence);
  86. }
  87. });
  88. if (parsedItems.length === 1) {
  89. return parsedItems[0];
  90. }
  91. const set = createSetEmojiRegexItem(parsedItems);
  92. const result = mergeSimilarItemsInSet(set);
  93. return result;
  94. }
  95. function parseItemChildren(item) {
  96. const result = {
  97. regex: item.regex,
  98. end: !!item.end
  99. };
  100. const children = item.children;
  101. if (!children) {
  102. return result;
  103. }
  104. const parsedChildren = children.map(parseItemChildren);
  105. result.children = mergeParsedChildren(parsedChildren);
  106. return result;
  107. }
  108. const parsed = items.map(parseItemChildren);
  109. return mergeParsedChildren(parsed);
  110. }
  111. export { createEmojisTree, parseEmojiTree };