find.mjs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import { convertEmojiSequenceToUTF32 } from '../convert.mjs';
  2. import { vs16Emoji } from '../data.mjs';
  3. import { getEmojiSequenceKeyword } from '../format.mjs';
  4. function createEmojiRegExp(regexp) {
  5. return new RegExp(regexp, "g");
  6. }
  7. function getEmojiMatchesInText(regexp, content) {
  8. const results = [];
  9. const found = /* @__PURE__ */ new Set();
  10. (regexp instanceof Array ? regexp : [regexp]).forEach((regexp2, index) => {
  11. const matches = content.match(
  12. typeof regexp2 === "string" ? createEmojiRegExp(regexp2) : regexp2
  13. );
  14. if (matches) {
  15. for (let i = 0; i < matches.length; i++) {
  16. const match = matches[i];
  17. if (found.has(match)) {
  18. continue;
  19. }
  20. found.add(match);
  21. const sequence = [];
  22. for (const codePoint of match) {
  23. const num = codePoint.codePointAt(0);
  24. if (num !== vs16Emoji) {
  25. sequence.push(num);
  26. }
  27. }
  28. results.push({
  29. match,
  30. sequence,
  31. keyword: getEmojiSequenceKeyword(
  32. convertEmojiSequenceToUTF32(sequence)
  33. ),
  34. regexp: index
  35. });
  36. }
  37. }
  38. });
  39. results.sort((a, b) => {
  40. const match1 = a.match;
  41. const match2 = b.match;
  42. if (match2.length === match1.length) {
  43. return match1.localeCompare(match2);
  44. }
  45. return match2.length - match1.length;
  46. });
  47. return results;
  48. }
  49. function sortEmojiMatchesInText(content, matches) {
  50. const ranges = [];
  51. const check = (start, end) => {
  52. for (let i = 0; i < ranges.length; i++) {
  53. if (start < ranges[i].end && end > ranges[i].start) {
  54. return false;
  55. }
  56. }
  57. return true;
  58. };
  59. for (let i = 0; i < matches.length; i++) {
  60. const match = matches[i];
  61. const search = match.match;
  62. let startFrom = 0;
  63. let start;
  64. while ((start = content.indexOf(search, startFrom)) !== -1) {
  65. const end = start + search.length;
  66. startFrom = end;
  67. if (check(start, end)) {
  68. ranges.push({
  69. start,
  70. end,
  71. match
  72. });
  73. }
  74. }
  75. }
  76. ranges.sort((a, b) => a.start - b.start);
  77. const list = [];
  78. let prevRange;
  79. let lastEnd;
  80. for (let i = 0; i < ranges.length; i++) {
  81. const range = ranges[i];
  82. const prev = content.slice(prevRange ? prevRange.end : 0, range.start);
  83. list.push({
  84. match: range.match,
  85. prev
  86. });
  87. prevRange = range;
  88. lastEnd = range.end;
  89. }
  90. if (!lastEnd) {
  91. return [];
  92. }
  93. const replacements = list.map((item, index) => {
  94. const nextItem = list[index + 1];
  95. return {
  96. ...item,
  97. next: nextItem ? nextItem.prev : content.slice(lastEnd)
  98. };
  99. });
  100. return replacements;
  101. }
  102. export { createEmojiRegExp, getEmojiMatchesInText, sortEmojiMatchesInText };