-
Notifications
You must be signed in to change notification settings - Fork 52
/
mathEscape.js
66 lines (52 loc) · 2.17 KB
/
mathEscape.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const katexConstants = require('../../src/preprocessors/katexConstants.json')
const endOfCommandChars = ['\\', '[', ']', '{', '}', ' ', '(', ')', '\t', '\n', '^', '_', ',']
function isEndOfCommand (nodeLine, index) {
if (index >= nodeLine.length) {
return true
}
return endOfCommandChars.includes(nodeLine.charAt(index))
}
module.exports = () => node => {
let commandStart = node.value.indexOf('\\')
while (commandStart !== -1) {
// Eat leading backslashes (at most two)
let leadSlashes = 1
let isSlash = (node.value.charAt(commandStart + leadSlashes) === '\\')
while (isSlash && leadSlashes < 2) {
isSlash = (node.value.charAt(commandStart + leadSlashes) === '\\')
leadSlashes++
}
let currentCommand = ''
// Find end of command
let potentialEnd = leadSlashes + commandStart
while (!isEndOfCommand(node.value, potentialEnd)) {
currentCommand += node.value.charAt(potentialEnd)
potentialEnd++
}
// if we just had a \{ or \, for example
if (currentCommand === '' && potentialEnd < node.value.length &&
katexConstants.includes(`\\${node.value.charAt(potentialEnd)}`)) {
currentCommand = node.value.charAt(potentialEnd)
}
// Check for unknown commands
const slashedCommand = '\\'.repeat(leadSlashes).concat(currentCommand)
const commandLength = slashedCommand.length
if (!katexConstants.includes(slashedCommand)) {
const beforeCommand = node.value.substring(0, commandStart)
const afterCommand = node.value.substring(commandStart + commandLength, node.value.length)
node.value = `${beforeCommand} ${afterCommand}`
// As we changed the command we need to restart from the beginning
potentialEnd = 1
}
commandStart = node.value.indexOf('\\', potentialEnd)
}
// Check count of brackets
const openingBracesCount = (node.value.match(/(?<!\\){/g) || []).length
const closingBracesCount = (node.value.match(/(?<!\\)}/g) || []).length
const bracesDelta = closingBracesCount - openingBracesCount
if (bracesDelta < 0) {
node.value += '}'.repeat(-bracesDelta)
} else if (bracesDelta > 0) {
node.value = '{'.repeat(bracesDelta) + node.value
}
}