File size: 1,293 Bytes
b9499ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { Fragment } from "react";

// A name ending in digits, such as w1 or x_1, with or without a bar or dot; not a number like 2 or 1e5
const SUBSCRIPTED_NAME = /(?<![A-Za-z0-9_.]|̄|̇)([A-Za-z](?:̄|̇)?[A-Za-z_]*)(\d+)(?![A-Za-z0-9_])/g;

// In SVG, a subscript's size, and how far it drops in the surrounding text's ems
const SVG_SIZE = 0.75;
const SVG_DROP = 0.3;

// Text with the digits of names drawn as subscripts. Use svg inside an SVG <text>.
export default function MathText({ text, svg = false }: { text: string; svg?: boolean }) {
  const parts = text.split(SUBSCRIPTED_NAME);
  // split gives [before, name, digits, before, name, digits, ..., after]
  return parts.map((part, i) => {
    if (i % 3 !== 2) {
      // x_1 is drawn as x with a subscript, without its underscore
      const shown = i % 3 === 1 ? part.replace(/_$/, "") : part;
      const afterSubscript = svg && i % 3 === 0 && i > 0;
      return afterSubscript ? (
        <tspan key={i} dy={`${-SVG_DROP}em`}>
          {shown}
        </tspan>
      ) : (
        <Fragment key={i}>{shown}</Fragment>
      );
    }
    return svg ? (
      <tspan key={i} dy={`${SVG_DROP / SVG_SIZE}em`} fontSize={`${SVG_SIZE * 100}%`}>
        {part}
      </tspan>
    ) : (
      <sub key={i}>{part}</sub>
    );
  });
}