Skip to content

Commit 6e20c3b

Browse files
committed
fix: ignore nested KaTeX tables for line highlights
1 parent 5e912cb commit 6e20c3b

3 files changed

Lines changed: 74 additions & 20 deletions

File tree

packages/client/builtin/KaTexBlockWrapper.vue

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { parseRangeString } from '@slidev/parser/utils'
2525
import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue'
2626
import { CLASS_VCLICK_HIDDEN, CLASS_VCLICK_TARGET, CLICKS_MAX } from '../constants'
2727
import { useSlideContext } from '../context'
28+
import { getKatexEquationRows } from '../logic/katex'
2829
import { makeId } from '../logic/utils'
2930
3031
const props = defineProps({
@@ -77,26 +78,7 @@ onMounted(() => {
7778
if (hide)
7879
rangeStr = props.ranges[index.value + 1] ?? finallyRange.value
7980
80-
// KaTeX equations have col-align-XXX as parent
81-
const equationParents = el.value.querySelectorAll('.mtable > [class*=col-align]')
82-
if (!equationParents)
83-
return
84-
85-
// For each row we extract the individual equation rows
86-
const equationRowsOfEachParent = Array.from(equationParents)
87-
.map(item => Array.from(item.querySelectorAll(':scope > .vlist-t > .vlist-r > .vlist > span > .mord')))
88-
// This list maps rows from different parents to line them up
89-
const lines: Element[][] = []
90-
for (const equationRowParent of equationRowsOfEachParent) {
91-
equationRowParent.forEach((equationRow, idx) => {
92-
if (!equationRow)
93-
return
94-
if (Array.isArray(lines[idx]))
95-
lines[idx].push(equationRow)
96-
else
97-
lines[idx] = [equationRow]
98-
})
99-
}
81+
const lines = getKatexEquationRows(el.value)
10082
10183
const startLine = props.startLine
10284
const highlights: number[] = parseRangeString(lines.length + startLine - 1, rangeStr)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { getKatexEquationRows } from './katex'
3+
4+
describe('getKatexEquationRows', () => {
5+
it('ignores nested KaTeX tables when collecting equation rows', () => {
6+
const leftRows = createRows('left', 3)
7+
const rightRows = createRows('right', 3)
8+
9+
const root = {
10+
querySelectorAll(selector: string) {
11+
expect(selector).toBe('.mtable > [class*=col-align]')
12+
return [
13+
createColumn(leftRows),
14+
createColumn(rightRows),
15+
createColumn(createRows('substack', 2), true),
16+
createColumn(createRows('matrix', 4), true),
17+
]
18+
},
19+
} as unknown as Element
20+
21+
expect(getKatexEquationRows(root)).toEqual([
22+
[leftRows[0], rightRows[0]],
23+
[leftRows[1], rightRows[1]],
24+
[leftRows[2], rightRows[2]],
25+
])
26+
})
27+
})
28+
29+
function createColumn(rows: Element[], nested = false) {
30+
return {
31+
parentElement: {
32+
parentElement: {
33+
closest(selector: string) {
34+
expect(selector).toBe('.mtable')
35+
return nested ? {} : null
36+
},
37+
},
38+
},
39+
querySelectorAll(selector: string) {
40+
expect(selector).toBe(':scope > .vlist-t > .vlist-r > .vlist > span > .mord')
41+
return rows
42+
},
43+
} as unknown as Element
44+
}
45+
46+
function createRows(name: string, count: number) {
47+
return Array.from({ length: count }, (_, index) => ({ name, index } as unknown as Element))
48+
}

packages/client/logic/katex.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export function getKatexEquationRows(el: Element): Element[][] {
2+
const equationParents = Array.from(el.querySelectorAll('.mtable > [class*=col-align]'))
3+
.filter(isTopLevelKatexColumn)
4+
5+
const equationRowsOfEachParent = equationParents
6+
.map(item => Array.from(item.querySelectorAll(':scope > .vlist-t > .vlist-r > .vlist > span > .mord')))
7+
8+
const lines: Element[][] = []
9+
for (const equationRowParent of equationRowsOfEachParent) {
10+
equationRowParent.forEach((equationRow, idx) => {
11+
if (Array.isArray(lines[idx]))
12+
lines[idx].push(equationRow)
13+
else
14+
lines[idx] = [equationRow]
15+
})
16+
}
17+
18+
return lines
19+
}
20+
21+
function isTopLevelKatexColumn(column: Element) {
22+
const table = column.parentElement
23+
return !!table && !table.parentElement?.closest('.mtable')
24+
}

0 commit comments

Comments
 (0)