Skip to content

Commit 232f0d7

Browse files
committed
Remove throwOnError option, improve message
This improves KaTeX errors and removes the `throwOnError` option: messages are always emitted as warnings.
1 parent 2cc0743 commit 232f0d7

File tree

4 files changed

+63
-62
lines changed

4 files changed

+63
-62
lines changed

packages/rehype-katex/index.js

+25-15
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22
* @typedef {import('hast').ElementContent} ElementContent
33
* @typedef {import('hast').Root} Root
44
*
5-
* @typedef {import('katex').KatexOptions} Options
5+
* @typedef {import('katex').KatexOptions} KatexOptions
66
*
77
* @typedef {import('vfile').VFile} VFile
88
*/
99

10+
/**
11+
* @typedef {Omit<KatexOptions, 'throwOnError'>} Options
12+
*/
13+
1014
import {fromHtmlIsomorphic} from 'hast-util-from-html-isomorphic'
1115
import {toText} from 'hast-util-to-text'
1216
import katex from 'katex'
@@ -28,7 +32,6 @@ const emptyClasses = []
2832
*/
2933
export default function rehypeKatex(options) {
3034
const settings = options || emptyOptions
31-
const throwOnError = settings.throwOnError || false
3235

3336
/**
3437
* Transform.
@@ -41,7 +44,7 @@ export default function rehypeKatex(options) {
4144
* Nothing.
4245
*/
4346
return function (tree, file) {
44-
visit(tree, 'element', function (element) {
47+
visit(tree, 'element', function (element, _, parent) {
4548
const classes = Array.isArray(element.properties.className)
4649
? element.properties.className
4750
: emptyClasses
@@ -64,16 +67,30 @@ export default function rehypeKatex(options) {
6467
throwOnError: true
6568
})
6669
} catch (error) {
67-
const exception = /** @type {Error} */ (error)
68-
const fn = throwOnError ? 'fail' : 'message'
69-
const origin = ['rehype-katex', exception.name.toLowerCase()].join(':')
70+
const cause = /** @type {Error} */ (error)
71+
const ruleId = cause.name.toLowerCase()
7072

71-
file[fn](exception.message, element.position, origin)
73+
file.message('Could not render math with KaTeX', {
74+
/* c8 ignore next -- verbose to test */
75+
ancestors: parent ? [parent, element] : [element],
76+
cause,
77+
place: element.position,
78+
ruleId,
79+
source: 'rehype-katex'
80+
})
7281

7382
// KaTeX can handle `ParseError` itself, but not others.
83+
if (ruleId === 'parseerror') {
84+
result = katex.renderToString(value, {
85+
...settings,
86+
displayMode,
87+
strict: 'ignore',
88+
throwOnError: false
89+
})
90+
}
7491
// Generate similar markup if this is an other error.
7592
// See: <https://github.com/KaTeX/KaTeX/blob/5dc7af0/docs/error.md>.
76-
if (exception.name !== 'ParseError') {
93+
else {
7794
element.children = [
7895
{
7996
type: 'element',
@@ -88,13 +105,6 @@ export default function rehypeKatex(options) {
88105
]
89106
return
90107
}
91-
92-
result = katex.renderToString(value, {
93-
...settings,
94-
displayMode,
95-
strict: 'ignore',
96-
throwOnError: false
97-
})
98108
}
99109

100110
const root = fromHtmlIsomorphic(result, {fragment: true})

packages/rehype-katex/readme.md

-5
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,6 @@ Transform `<span class="math-inline">` and `<div class="math-display">` with
144144
Configuration (optional).
145145
All options, except for `displayMode`, are passed to [KaTeX][katex-options].
146146

147-
###### `options.throwOnError`
148-
149-
Throw if a KaTeX parse error occurs (`boolean`, default: `false`).
150-
See [KaTeX options][katex-options].
151-
152147
## CSS
153148

154149
The HTML produced by KaTeX requires CSS to render correctly.

packages/rehype-katex/test.js

+37-41
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,15 @@ test('rehype-katex', async function (t) {
142142
)
143143
})
144144

145-
await t.test('should support `errorColor`', async function () {
145+
await t.test('should handle errors, support `errorColor`', async function () {
146+
const file = await unified()
147+
.use(rehypeParse, {fragment: true})
148+
.use(rehypeKatex, {errorColor: 'orange'})
149+
.use(rehypeStringify)
150+
.process('<code class="math-inline">\\alpa</code>')
151+
146152
assert.deepEqual(
147-
String(
148-
await unified()
149-
.use(rehypeParse, {fragment: true})
150-
.use(rehypeKatex, {errorColor: 'orange'})
151-
.use(rehypeStringify)
152-
.process('<code class="math-inline">\\alpa</code>')
153-
),
153+
String(file),
154154
String(
155155
await unified()
156156
.use(rehypeParse, {fragment: true})
@@ -165,41 +165,37 @@ test('rehype-katex', async function (t) {
165165
)
166166
)
167167
)
168-
})
169-
170-
await t.test('should create a message for errors', async function () {
171-
const file = await unified()
172-
.use(rehypeParse, {fragment: true})
173-
.use(rehypeKatex)
174-
.use(rehypeStringify)
175-
.process('<p>Lorem</p>\n<p><code class="math-inline">\\alpa</code></p>')
176168

177-
assert.deepEqual(file.messages.map(String), [
178-
'2:4-2:42: KaTeX parse error: Undefined control sequence: \\alpa at position 1: \\̲a̲l̲p̲a̲'
179-
])
180-
})
181-
182-
await t.test(
183-
'should throw an error if `throwOnError: true`',
184-
async function () {
185-
try {
186-
await unified()
187-
.use(rehypeParse, {fragment: true})
188-
.use(rehypeKatex, {throwOnError: true})
189-
.use(rehypeStringify)
190-
.process(
191-
'<p>Lorem</p>\n<p><code class="math-inline">\\alpa</code></p>'
192-
)
193-
/* c8 ignore next 2 -- some c8 bug. */
194-
assert.fail()
195-
} catch (error) {
196-
assert.match(
197-
String(error),
198-
/KaTeX parse error: Undefined control sequence: \\alpa at position 1: \\̲a̲l̲p̲a̲/
199-
)
169+
assert.equal(file.messages.length, 1)
170+
const message = file.messages[0]
171+
assert(message)
172+
assert(message.cause)
173+
assert(message.ancestors)
174+
assert.match(
175+
String(message.cause),
176+
/KaTeX parse error: Undefined control sequence/
177+
)
178+
assert.equal(message.ancestors.length, 2)
179+
assert.deepEqual(
180+
{...file.messages[0], cause: undefined, ancestors: []},
181+
{
182+
ancestors: [],
183+
cause: undefined,
184+
column: 1,
185+
fatal: false,
186+
line: 1,
187+
message: 'Could not render math with KaTeX',
188+
name: '1:1-1:39',
189+
place: {
190+
start: {column: 1, line: 1, offset: 0},
191+
end: {column: 39, line: 1, offset: 38}
192+
},
193+
reason: 'Could not render math with KaTeX',
194+
ruleId: 'parseerror',
195+
source: 'rehype-katex'
200196
}
201-
}
202-
)
197+
)
198+
})
203199

204200
await t.test('should support `strict: ignore`', async function () {
205201
assert.deepEqual(

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"declaration": true,
66
"emitDeclarationOnly": true,
77
"exactOptionalPropertyTypes": true,
8-
"lib": ["es2020"],
8+
"lib": ["es2022"],
99
"module": "node16",
1010
// To do: remove when `mathjax-full` types are fixed.
1111
"skipLibCheck": true,

0 commit comments

Comments
 (0)