Skip to content

Commit

Permalink
Remove 'katex' from @khanacademy/perseus (#1428)
Browse files Browse the repository at this point in the history
## Summary:

KaTeX was retired from use in Perseus in 2023. Today, I noticed that we still reference the `katex` package in the perseus `package.json`, but we never import it anywhere in the code. 

So I'm removing that dependency. I've also updated some code comments and storybook references to not mention KaTeX anymore. I've left some references to CSS classes and the KaTeX_Main font ref. I'm unsure if they might be important somewhere (especially if host applications may still set it outside of Perseus).

So this doesn't fully remove all references to katex, but it moves us another step closer. 

Issue: "none"

## Test plan:

`yarn tsc`
`yarn lint`

I ran storybook and opened the `ZoomableTex` stories and played with them. 

Note(jeremy): I've restored the code that swaps `\begin{align}` to `\begin{aligned}` and noted LEMS-1608 based on comments from Ben (thanks!).

~I also went to the `EditorPage` story and pasted in the following Tex into the **Question** field (which uses the macro that we used to have to replace for KaTeX, but MathJax supports properly: switching `\begin{align}` to `\begin{aligned}`).~

Author: jeremywiebe

Reviewers: jeremywiebe, benchristel, Myranae, nicolecomputer

Required Reviewers:

Approved By: benchristel

Checks: ✅ codecov/project, ✅ codecov/patch, ✅ Upload Coverage (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Cypress (ubuntu-latest, 20.x), ✅ Jest Coverage (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x), ✅ gerald

Pull Request URL: #1428
  • Loading branch information
jeremywiebe authored Aug 1, 2024
1 parent 8b02682 commit eb9f3f9
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/mighty-news-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/perseus": minor
---

Drop katex dependency - no longer used
1 change: 0 additions & 1 deletion packages/perseus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
"create-react-class": "15.6.3",
"intersection-observer": "^0.12.0",
"jquery": "^2.1.1",
"katex": "0.11.1",
"lodash.debounce": "^4.0.8",
"perseus-build-settings": "^0.4.1",
"prop-types": "15.6.1",
Expand Down
31 changes: 28 additions & 3 deletions packages/perseus/src/__tests__/renderer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,29 @@ describe("renderer", () => {
it("should replace deprecated alignment tags in inline math", async () => {
// Arrange
const question = {
content:
"Hello $\\begin{align}\n2\\text{HCl}(\\text{aq})+\\text{Ca}(\\text{OH})_2(\\text{aq})\\rightarrow\\text{Ca}(\\text{s})+2\\text H_2\\text O(\\text l)+\\text{Cl}_2(\\text g)\n\\end{align}$",
images: {},
widgets: {},
} as const;

// Act
renderQuestion(question);

// Assert
await waitFor(() => {
expect(
screen.getByText(/\\begin\{aligned\}.*\\end\{aligned\}/),
).toBeInTheDocument();
});
});

it("should replace deprecated alignment tags in block math", async () => {
// Arrange
const question = {
// Math that exists by itself in a paragraph is considered
// block math, even if it isn't surrounded by the block math
// delimeters (`$$$...$$$`).
content:
"$\\begin{align}\n2\\text{HCl}(\\text{aq})+\\text{Ca}(\\text{OH})_2(\\text{aq})\\rightarrow\\text{Ca}(\\text{s})+2\\text H_2\\text O(\\text l)+\\text{Cl}_2(\\text g)\n\\end{align}$",
images: {},
Expand All @@ -723,9 +746,11 @@ describe("renderer", () => {
renderQuestion(question);

// Assert
expect(
screen.getByText(/\\begin\{aligned\}.*\\end\{aligned\}/),
).toBeInTheDocument();
await waitFor(() => {
expect(
screen.getByText(/\\begin\{aligned\}.*\\end\{aligned\}/),
).toBeInTheDocument();
});
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from "react";

import Graph from "../graph";
// TODO(scottgrant): Katex is unavailable here. Fix!

type StoryArgs = Record<any, any>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ const ForceZoomWrapper = ({children}: Props): React.ReactElement => (
</>
);

export const KaTeX = (args: StoryArgs): React.ReactElement => {
export const Tex = (args: StoryArgs): React.ReactElement => {
return (
<ForceZoomWrapper>
<ZoomableTex children="\sum_{i=1}^\infty\frac{1}{n^2} =\frac{\pi^2}{6}" />
</ForceZoomWrapper>
);
};

export const ComplexKaTeX = (args: StoryArgs): React.ReactElement => {
export const ComplexTex = (args: StoryArgs): React.ReactElement => {
return (
<ForceZoomWrapper>
{" "}
Expand Down
2 changes: 1 addition & 1 deletion packages/perseus/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export {
*/
export {default as Util} from "./util";
export {default as KhanColors} from "./util/colors";
export {default as preprocessTex} from "./util/katex-preprocess";
export {default as preprocessTex} from "./util/tex-preprocess";
export {registerAllWidgetsForTesting} from "./util/register-all-widgets-for-testing";
export * as SizingUtils from "./util/sizing-utils";
export {
Expand Down
6 changes: 3 additions & 3 deletions packages/perseus/src/interactive2/movable-point.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,9 @@ export class MovablePoint {
* Displays a tooltip above the point, replacing any previous contents. If
* there is no tooltip initialized, adds the tooltip.
*
* If the type of contents is string, the contents will be rendered with
* KaTeX. Otherwise, the content will be assumed to be a DOM node and will
* be appended inside the tooltip.
* If the type of contents is string, the contents will be rendered as TeX
* Otherwise, the content will be assumed to be a DOM node and will be
* appended inside the tooltip.
*/
_showTooltip(contents) {
if (!this._tooltip) {
Expand Down
4 changes: 2 additions & 2 deletions packages/perseus/src/perseus-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ export const PerseusExpressionAnswerFormConsidered = [
] as const;

export type PerseusExpressionAnswerForm = {
// The Katex form of the expression. e.g. "x\\cdot3=y"
// The TeX form of the expression. e.g. "x\\cdot3=y"
value: string;
// The Answer expression must have the same form
form: boolean;
Expand Down Expand Up @@ -889,7 +889,7 @@ export type PerseusGraphTypeRay = {
} & PerseusGraphTypeCommon;

export type PerseusLabelImageWidgetOptions = {
// Translatable Text; Katex representation of choices
// Translatable Text; Tex representation of choices
choices: ReadonlyArray<string>;
// The URL of the image
imageUrl: string;
Expand Down
5 changes: 4 additions & 1 deletion packages/perseus/src/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import PerseusMarkdown from "./perseus-markdown";
import QuestionParagraph from "./question-paragraph";
import TranslationLinter from "./translation-linter";
import Util from "./util";
import preprocessTex from "./util/katex-preprocess";
import preprocessTex from "./util/tex-preprocess";
import WidgetContainer from "./widget-container";
import * as Widgets from "./widgets";

Expand Down Expand Up @@ -1303,6 +1303,9 @@ class Renderer extends React.Component<Props, State> {
// support (yet) with \begin{aligned}...\end{aligned} which renders
// the same is supported by KaTeX. It does the same for align*.
// TODO(kevinb) update content to use aligned instead of align.
// TODO(LEMS-1608) Remove this replacement as MathJax supports the
// "align" macro correctly (and, in fact, it is not synonymous with
// "aligned").
const tex = node.content.replace(/\{align[*]?\}/g, "{aligned}");

// We render math here instead of in perseus-markdown.jsx
Expand Down
1 change: 0 additions & 1 deletion packages/perseus/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ export type APIOptions = Readonly<{

type TeXProps = {
children: string;
katexOptions?: any;
onClick?: () => unknown;
onRender?: (root?: any) => unknown;
style?: any;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/**
* Preprocess TeX code to convert things that KaTeX doesn't know how to handle
* Preprocess TeX code to convert things that MathJax doesn't know how to handle
* to things is does.
*/

export default (texCode: string): string =>
texCode
// Replace uses of \begin{align}...\end{align} which KaTeX doesn't
// support (yet) with \begin{aligned}...\end{aligned} which renders
// the same is supported by KaTeX. It does the same for align*.
// TODO(kevinb) update content to use aligned instead of align.
// TODO(LEMS-1608) Remove this replacement as MathJax supports the
// "align" macro correctly (and, in fact, it is not synonymous with
// "aligned").
.replace(/\{align[*]?\}/g, "{aligned}")
// Replace non-breaking spaces with regular spaces.
.replace(/[\u00a0]/g, " ");
4 changes: 2 additions & 2 deletions packages/perseus/src/util/tex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ function findChildOrAdd(elem: any, className: string) {
}

export default {
// Process a node and add math inside of it. This attempts to use KaTeX to
// format the math, and if that fails it falls back to MathJax.
// Process a node and add math inside of it. This uses MathJax to
// format the math.
//
// elem: The element which the math should be added to.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {usePerseusI18n} from "../../components/i18n-context";
import Renderer from "../../renderer";

export type AnswerType = {
// The answer string, can be plain text or a KaTeX expression.
// The answer string, can be plain text or a TeX expression.
content: string;
// Whether the answer is selected.
checked: boolean;
Expand Down

0 comments on commit eb9f3f9

Please sign in to comment.