Skip to content

Commit d45faf3

Browse files
authored
💰 Dollarmath settings for markdown parsing (#2542)
See #2477
1 parent 8d382f4 commit d45faf3

File tree

9 files changed

+129
-1
lines changed

9 files changed

+129
-1
lines changed

.changeset/twenty-impalas-tap.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'myst-frontmatter': patch
3+
'myst-cli': patch
4+
---
5+
6+
Add dollarmath parser settings to project

docs/settings.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,31 @@ output_matplotlib_strings
6060
- `"remove-warn"` (default) or `"remove-error"`: remove all matplotlib strings in outputs, and log a warning or error
6161
- `"warn"` or "error": log a warning or error if matplotlib strings in outputs
6262

63+
## Markdown Parsing Settings
64+
65+
Adding an object of `parser` to the settings will allow you to control various parser behaviors.
66+
67+
```{code-block} yaml
68+
:filename: myst.yml
69+
project:
70+
settings:
71+
parser:
72+
dollarmath: false
73+
```
74+
75+
:::{warning}
76+
Markdown parsing settings currently only work on the `myst.yml` project settings, not the page frontmatter.
77+
:::
78+
79+
(setting:parser:dollarmath)=
80+
dollarmath
81+
: Enable or disable inline dollar math parsing (e.g., `$x^2$` syntax).
82+
83+
- `true` (default): Enable inline dollar math parsing
84+
- `false`: Disable inline dollar math parsing
85+
86+
When disabled, dollar signs (`$`) will be treated as regular text characters and not parsed as math delimiters. This can be useful if you have frequent uses of dollar signs, such as currency, in your content that are not meant to be math.
87+
6388
## LaTeX Rendering Settings
6489

6590
Adding an object of `myst_to_tex` to the settings will allow you to control various default parts of how the LaTeX renderer behaves.

packages/myst-cli/src/process/myst.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { VFile } from 'vfile';
99
import type { ISession } from '../session/types.js';
1010
import { logMessagesFromVFile } from '../utils/logging.js';
1111
import type { GenericParent } from 'myst-common';
12+
import { selectCurrentProjectConfig } from '../store/selectors.js';
1213

1314
/**
1415
* Boiled-down options for parseMyst
@@ -21,6 +22,16 @@ type Options = {
2122
};
2223

2324
export function getMystParserOptions(session: ISession, opts?: Options): Partial<AllOptions> {
25+
// Get parser settings from project config
26+
// Right now this is only project level, but in the future we will allow page level settings.
27+
const parserOptions = selectCurrentProjectConfig(session.store.getState())?.settings?.parser;
28+
// Configure math extensions based on parser settings
29+
let mathExtension: boolean | { dollarmath?: boolean; amsmath?: boolean } = true;
30+
if (parserOptions?.dollarmath === false) {
31+
// If dollarmath is explicitly disabled, configure math to only enable amsmath
32+
mathExtension = { dollarmath: false, amsmath: true };
33+
}
34+
2435
return {
2536
markdownit: { linkify: true },
2637
directives: [
@@ -33,6 +44,7 @@ export function getMystParserOptions(session: ISession, opts?: Options): Partial
3344
],
3445
extensions: {
3546
frontmatter: !opts?.ignoreFrontmatter,
47+
math: mathExtension,
3648
},
3749
roles: [buttonRole, ...(session.plugins?.roles ?? [])],
3850
};

packages/myst-cli/src/process/notebook.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {
77
ICell,
88
IMimeBundle,
99
INotebookContent,
10-
INotebookMetadata,
1110
IOutput,
1211
MultilineString,
1312
} from '@jupyterlab/nbformat';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './types.js';
22
export * from './validators.js';
33
export * from './validatorsMystToTex.js';
4+
export * from './validatorsParser.js';
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
title: parser
2+
frontmatter: project
3+
cases:
4+
- title: unknown option
5+
raw:
6+
settings:
7+
parser:
8+
unknown: unknown
9+
warnings: 1
10+
normalized: {}
11+
- title: dollarmath true
12+
raw:
13+
settings:
14+
parser:
15+
dollarmath: true
16+
errors: 0
17+
normalized:
18+
settings:
19+
parser:
20+
dollarmath: true
21+
- title: dollarmath false
22+
raw:
23+
settings:
24+
parser:
25+
dollarmath: false
26+
errors: 0
27+
normalized:
28+
settings:
29+
parser:
30+
dollarmath: false
31+
- title: dollarmath with alias
32+
raw:
33+
settings:
34+
parser:
35+
dollar_math: false
36+
errors: 0
37+
normalized:
38+
settings:
39+
parser:
40+
dollarmath: false
41+
- title: dollarmath invalid boolean
42+
raw:
43+
settings:
44+
parser:
45+
dollarmath: invalid
46+
errors: 1
47+
normalized: {}

packages/myst-frontmatter/src/settings/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ export type MystToTexSettings = {
55
beamer?: boolean;
66
};
77

8+
export type ParserSettings = {
9+
dollarmath?: boolean;
10+
};
11+
812
export type ProjectSettings = {
913
output_stderr?: OutputRemovalOptions;
1014
output_stdout?: OutputRemovalOptions;
1115
output_matplotlib_strings?: OutputRemovalOptions;
1216
myst_to_tex?: MystToTexSettings;
17+
parser?: ParserSettings;
1318
};

packages/myst-frontmatter/src/settings/validators.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { ValidationOptions } from 'simple-validators';
22
import { defined, incrementOptions, validateChoice, validateObjectKeys } from 'simple-validators';
33
import type { ProjectSettings } from './types.js';
44
import { validateMystToTexSettings } from './validatorsMystToTex.js';
5+
import { validateParserSettings } from './validatorsParser.js';
56

67
const OUTPUT_REMOVAL_OPTIONS: Required<ProjectSettings>['output_stderr'][] = [
78
'show',
@@ -16,6 +17,7 @@ export const PROJECT_SETTINGS = [
1617
'output_stdout',
1718
'output_matplotlib_strings',
1819
'myst_to_tex',
20+
'parser',
1921
];
2022
export const PROJECT_SETTINGS_ALIAS = {
2123
stderr_output: 'output_stderr',
@@ -63,6 +65,10 @@ export function validateProjectAndPageSettings(
6365
);
6466
if (myst_to_tex) output.myst_to_tex = myst_to_tex;
6567
}
68+
if (defined(settings.parser)) {
69+
const parser = validateParserSettings(settings.parser, incrementOptions('parser', opts));
70+
if (parser) output.parser = parser;
71+
}
6672
if (Object.keys(output).length === 0) return undefined;
6773
return output;
6874
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { ValidationOptions } from 'simple-validators';
2+
import { defined, incrementOptions, validateBoolean, validateObjectKeys } from 'simple-validators';
3+
import type { ParserSettings } from './types.js';
4+
5+
export const PARSER_SETTINGS = ['dollarmath'];
6+
export const PARSER_SETTINGS_ALIAS = {
7+
dollar_math: 'dollarmath',
8+
};
9+
10+
export function validateParserSettings(
11+
value: Record<string, any>,
12+
opts: ValidationOptions,
13+
): ParserSettings | undefined {
14+
const output: ParserSettings = {};
15+
const settings = validateObjectKeys(
16+
value,
17+
{ optional: PARSER_SETTINGS, alias: PARSER_SETTINGS_ALIAS },
18+
opts,
19+
);
20+
if (!settings) return undefined;
21+
if (defined(settings.dollarmath)) {
22+
const dollarmath = validateBoolean(settings.dollarmath, incrementOptions('dollarmath', opts));
23+
if (dollarmath != null) output.dollarmath = dollarmath;
24+
}
25+
if (Object.keys(output).length === 0) return undefined;
26+
return output;
27+
}

0 commit comments

Comments
 (0)