Repository: excalidraw/excalidraw
File: src/components/Trans.tsx (TypeScript)

Code before:
import React from "react";

import { useI18n } from "../i18n";

const REGEXP = /({{\w+?}})|(<\w+?>)|(<\/\w+?>)/g;
const KEY_REGEXP = /{{(\w+?)}}/;
const TAG_START_REGEXP = /<(\w+?)>/;
const TAG_END_REGEXP = /<\/(\w+?)>/;

const getTransChildren = (
  format: string,
  props: {
    [key: string]: React.ReactNode | ((el: React.ReactNode) => React.ReactNode);
  },
) => {
  const stack: { name: string; children: React.ReactNode[] }[] = [
    {
      name: "",
      children: [],
    },
  ];

  format.split(REGEXP).forEach((match) => {
    if (match === undefined || match.length === 0) {
      return;
    }

    const tagStartMatch = match.match(TAG_START_REGEXP);

    if (tagStartMatch !== null) {
      // Set the tag name as the name if it's one of the props, eg for "Please
      // <link>click the button</link> to continue" tagStartMatch[1] = "link"
      // and props contain "link" then it will be pushed to stack.
      const name = tagStartMatch[1];
      if (props.hasOwnProperty(name)) {
        stack.push({
          name,
          children: [],
        });
      } else {
        console.warn(
          `Trans: missed to pass in variable start/end ${match} for interpolating ${format}`,
        );
      }

      return;
    }


Review comment (suggestion):
the `split` here could be confusing as its introducing unncessary `undefined` tags so I think its better if we improve the split here so tokens are correct
eg for "Hello {{audience}}" its splitting to
```
 [ 'Hello ', '{{audience}}', undefined, undefined, '' ]
 ```
 so we should remove those `undefined` tokens

Code after:
import React from "react";

import { useI18n } from "../i18n";

// Used for splitting i18nKey into tokens in Trans component
// Example:
// "Please <link>click {{location}}</link> to continue.".split(SPLIT_REGEX).filter(Boolean)
// produces
// ["Please ", "<link>", "click ", "{{location}}", "</link>", " to continue."]
const SPLIT_REGEX = /({{[\w-]+}})|(<[\w-]+>)|(<\/[\w-]+>)/g;
// Used for extracting "location" from "{{location}}"
const KEY_REGEXP = /{{([\w-]+)}}/;
// Used for extracting "link" from "<link>"
const TAG_START_REGEXP = /<([\w-]+)>/;
// Used for extracting "link" from "</link>"
const TAG_END_REGEXP = /<\/([\w-]+)>/;

const getTransChildren = (
  format: string,
  props: {
    [key: string]: React.ReactNode | ((el: React.ReactNode) => React.ReactNode);
  },
): React.ReactNode[] => {
  const stack: { name: string; children: React.ReactNode[] }[] = [
    {
      name: "",
      children: [],
    },
  ];

  format
    .split(SPLIT_REGEX)
    .filter(Boolean)
    .forEach((match) => {
      const tagStartMatch = match.match(TAG_START_REGEXP);
      const tagEndMatch = match.match(TAG_END_REGEXP);
      const keyMatch = match.match(KEY_REGEXP);

      if (tagStartMatch !== null) {
        // The match is <tag>. Set the tag name as the name if it's one of the
        // props, e.g. for "Please <link>click the button</link> to continue"
        // tagStartMatch[1] = "link" and props contain "link" then it will be
        // pushed to stack.
        const name = tagStartMatch[1];
        if (props.hasOwnProperty(name)) {
          stack.push({
            name,
            children: [],