text.ts 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import { TextMatch } from 'app/types/explore';
  2. /**
  3. * Adapt findMatchesInText for react-highlight-words findChunks handler.
  4. * See https://github.com/bvaughn/react-highlight-words#props
  5. */
  6. export function findHighlightChunksInText({ searchWords, textToHighlight }) {
  7. return findMatchesInText(textToHighlight, searchWords.join(' '));
  8. }
  9. const cleanNeedle = (needle: string): string => {
  10. return needle.replace(/[[{(][\w,.-?:*+]+$/, '');
  11. };
  12. /**
  13. * Returns a list of substring regexp matches.
  14. */
  15. export function findMatchesInText(haystack: string, needle: string): TextMatch[] {
  16. // Empty search can send re.exec() into infinite loop, exit early
  17. if (!haystack || !needle) {
  18. return [];
  19. }
  20. const matches = [];
  21. const cleaned = cleanNeedle(needle);
  22. let regexp;
  23. try {
  24. regexp = new RegExp(`(?:${cleaned})`, 'g');
  25. } catch (error) {
  26. return matches;
  27. }
  28. haystack.replace(regexp, (substring, ...rest) => {
  29. if (substring) {
  30. const offset = rest[rest.length - 2];
  31. matches.push({
  32. text: substring,
  33. start: offset,
  34. length: substring.length,
  35. end: offset + substring.length,
  36. });
  37. }
  38. return '';
  39. });
  40. return matches;
  41. }