mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-10 09:13:59 +02:00
* 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
90 lines
2.9 KiB
JavaScript
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
|
|
}
|