Skip to content

Commit b3e8071

Browse files
authored
feat: support Math in Markdown (#299)
1 parent ef5285f commit b3e8071

6 files changed

Lines changed: 74 additions & 10 deletions

File tree

e2e-tests/options.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ test("should switch language and show options for each", async ({ page }) => {
109109
await expect(
110110
page.getByRole("combobox", { exact: true, name: "Front Matter" }),
111111
).toBeVisible();
112+
113+
// `Math` Switch
114+
await expect(
115+
page.getByRole("switch", {
116+
exact: true,
117+
name: "Math",
118+
}),
119+
).toBeVisible();
112120
});
113121

114122
// CSS

e2e-tests/persistence.test.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,15 @@ async function getPersistedJavaScriptCode(page: Page): Promise<string> {
2727
}
2828

2929
async function getPersistedExplorerState(page: Page): Promise<string> {
30-
const persistedValue = await page.evaluate(
31-
key => window.localStorage.getItem(key),
32-
storageKey,
33-
);
30+
return page.evaluate(key => {
31+
const storedValue = window.localStorage.getItem(key);
3432

35-
if (!persistedValue) {
36-
throw new Error("Expected explorer state to be persisted");
37-
}
33+
if (!storedValue) {
34+
throw new Error("No persisted state found in localStorage");
35+
}
3836

39-
return persistedValue;
37+
return storedValue;
38+
}, storageKey);
4039
}
4140

4241
async function getStoredHashValue(page: Page): Promise<string> {
@@ -163,3 +162,37 @@ test("should fall back to localStorage when a v2 hash is malformed", async ({
163162

164163
await expect(codeEditor).toContainText(fallbackCode);
165164
});
165+
166+
test("should patch legacy Markdown options without math", async ({ page }) => {
167+
await page.addInitScript(key => {
168+
window.localStorage.setItem(
169+
key,
170+
JSON.stringify({
171+
state: {
172+
language: "markdown",
173+
markdownOptions: {
174+
markdownMode: "commonmark",
175+
markdownFrontmatter: "off",
176+
},
177+
},
178+
version: 0,
179+
}),
180+
);
181+
}, storageKey);
182+
await page.goto("/");
183+
184+
await expect
185+
.poll(async () => {
186+
const explorerState = JSON.parse(
187+
await getPersistedExplorerState(page),
188+
);
189+
return explorerState.state.markdownOptions.markdownMath;
190+
})
191+
.toBe(false);
192+
193+
await page.getByRole("button", { name: "Language Options" }).click();
194+
195+
await expect(
196+
page.getByRole("switch", { exact: true, name: "Math" }),
197+
).toHaveAttribute("aria-checked", "false");
198+
});

src/components/options.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const JSONPanel: FC = () => {
6767
const MarkdownPanel: FC = () => {
6868
const explorer = useExplorer();
6969
const { markdownOptions, setMarkdownOptions } = explorer;
70-
const { markdownMode, markdownFrontmatter } = markdownOptions;
70+
const { markdownMode, markdownFrontmatter, markdownMath } = markdownOptions;
7171
return (
7272
<>
7373
<LabeledSelect
@@ -96,6 +96,18 @@ const MarkdownPanel: FC = () => {
9696
items={markdownFrontmatters}
9797
placeholder="Front Matter"
9898
/>
99+
100+
<LabeledSwitch
101+
id="markdownMath"
102+
label="Math"
103+
checked={markdownMath}
104+
onCheckedChange={(value: boolean) => {
105+
setMarkdownOptions({
106+
...markdownOptions,
107+
markdownMath: value,
108+
});
109+
}}
110+
/>
99111
</>
100112
);
101113
};

src/hooks/use-ast.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ export function useAST() {
6666
}
6767

6868
case "markdown": {
69-
const { markdownMode, markdownFrontmatter } = markdownOptions;
69+
const { markdownMode, markdownFrontmatter, markdownMath } =
70+
markdownOptions;
7071
const language = markdown.languages[markdownMode];
7172
astParseResult = language.parse(
7273
{ body: code.markdown, path: "", physicalPath: "", bom: false },
@@ -76,6 +77,7 @@ export function useAST() {
7677
markdownFrontmatter === "off"
7778
? false
7879
: markdownFrontmatter,
80+
math: markdownMath,
7981
},
8082
},
8183
);

src/hooks/use-explorer.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export type JsonOptions = {
4848
export type MarkdownOptions = {
4949
markdownMode: MarkdownMode;
5050
markdownFrontmatter: MarkdownFrontmatter;
51+
markdownMath: boolean;
5152
};
5253

5354
export type CssOptions = {
@@ -287,6 +288,13 @@ export const useExplorer = create<ExplorerState>()(
287288
if (needsPatching) {
288289
state.setCode(patchedCode);
289290
}
291+
292+
if (state.markdownOptions.markdownMath === undefined) {
293+
state.setMarkdownOptions({
294+
...defaultMarkdownOptions,
295+
...state.markdownOptions,
296+
});
297+
}
290298
},
291299
},
292300
),

src/lib/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ export const defaultJsonOptions: JsonOptions = {
484484
export const defaultMarkdownOptions: MarkdownOptions = {
485485
markdownMode: "commonmark",
486486
markdownFrontmatter: "off",
487+
markdownMath: false,
487488
};
488489

489490
export const defaultCssOptions: CssOptions = {

0 commit comments

Comments
 (0)