1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-10 09:13:59 +02:00
Files
slate/site/examples/js/utils/normalize-tokens.js
Ravi Lamkoti 01dc30b81d Add Javascript Examples Support (#5722)
* chore: moved all ts files for examples to examples/ts

* add: tsc to eject js and jsx output

* example: add js transpiled examples

* example: update example site to show both js and ts code

* chore: fix yarn lint

* fix(example): getAllExamplesPath
2024-09-26 00:24:11 -07:00

90 lines
2.9 KiB
JavaScript

/**
* Copied from prism-react-renderer repo
* https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/utils/normalizeTokens.js
* */
const newlineRe = /\r\n|\r|\n/
// Empty lines need to contain a single empty token, denoted with { empty: true }
const normalizeEmptyLines = line => {
if (line.length === 0) {
line.push({
types: ['plain'],
content: '\n',
empty: true,
})
} else if (line.length === 1 && line[0].content === '') {
line[0].content = '\n'
line[0].empty = true
}
}
const appendTypes = (types, add) => {
const typesSize = types.length
if (typesSize > 0 && types[typesSize - 1] === add) {
return types
}
return types.concat(add)
}
// Takes an array of Prism's tokens and groups them by line, turning plain
// strings into tokens as well. Tokens can become recursive in some cases,
// which means that their types are concatenated. Plain-string tokens however
// are always of type "plain".
// This is not recursive to avoid exceeding the call-stack limit, since it's unclear
// how nested Prism's tokens can become
export const normalizeTokens = tokens => {
const typeArrStack = [[]]
const tokenArrStack = [tokens]
const tokenArrIndexStack = [0]
const tokenArrSizeStack = [tokens.length]
let i = 0
let stackIndex = 0
let currentLine = []
const acc = [currentLine]
while (stackIndex > -1) {
while (
(i = tokenArrIndexStack[stackIndex]++) < tokenArrSizeStack[stackIndex]
) {
let content
let types = typeArrStack[stackIndex]
const tokenArr = tokenArrStack[stackIndex]
const token = tokenArr[i]
// Determine content and append type to types if necessary
if (typeof token === 'string') {
types = stackIndex > 0 ? types : ['plain']
content = token
} else {
types = appendTypes(types, token.type)
if (token.alias) {
types = appendTypes(types, token.alias)
}
content = token.content
}
// If token.content is an array, increase the stack depth and repeat this while-loop
if (typeof content !== 'string') {
stackIndex++
typeArrStack.push(types)
tokenArrStack.push(content)
tokenArrIndexStack.push(0)
tokenArrSizeStack.push(content.length)
continue
}
// Split by newlines
const splitByNewlines = content.split(newlineRe)
const newlineCount = splitByNewlines.length
currentLine.push({ types, content: splitByNewlines[0] })
// Create a new line for each string on a new line
for (let i = 1; i < newlineCount; i++) {
normalizeEmptyLines(currentLine)
acc.push((currentLine = []))
currentLine.push({ types, content: splitByNewlines[i] })
}
}
// Decreate the stack depth
stackIndex--
typeArrStack.pop()
tokenArrStack.pop()
tokenArrIndexStack.pop()
tokenArrSizeStack.pop()
}
normalizeEmptyLines(currentLine)
return acc
}