UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

126 lines (117 loc) 3.44 kB
// Example copied from https://github.com/wooorm/starry-night#example-adding-line-numbers /** * Counts the number of lines in a HAST tree without mutating it. * Uses the same logic as starryNightGutter but only returns the count. * @param tree - The HAST tree to count lines in * @returns The number of lines in the tree */ export function countLines(tree) { var search = /\r?\n|\r/g; var index = -1; var start = 0; var startTextRemainder = ''; var lineNumber = 0; while (index + 1 < tree.children.length) { index += 1; var child = tree.children[index]; if (child.type === 'text') { var textStart = 0; var match = search.exec(child.value); while (match) { lineNumber += 1; start = index + 1; textStart = match.index + match[0].length; match = search.exec(child.value); } // If we matched, make sure to not drop the text after the last line ending. if (start === index + 1) { startTextRemainder = child.value.slice(textStart); } } } // Check if we have remaining content to process as a line if (start < tree.children.length || startTextRemainder) { lineNumber += 1; } return lineNumber; } export function starryNightGutter(tree) { /** @type {Array<RootContent>} */ var replacement = []; var search = /\r?\n|\r/g; var index = -1; var start = 0; var startTextRemainder = ''; var lineNumber = 0; while (index + 1 < tree.children.length) { index += 1; var child = tree.children[index]; if (child.type === 'text') { var textStart = 0; var match = search.exec(child.value); while (match) { // Nodes in this line. var _line = tree.children.slice(start, index); // Prepend text from a partial matched earlier text. if (startTextRemainder) { _line.unshift({ type: 'text', value: startTextRemainder }); startTextRemainder = ''; } // Append text from this text. if (match.index > textStart) { _line.push({ type: 'text', value: child.value.slice(textStart, match.index) }); } // Add a line, and the eol. lineNumber += 1; replacement.push(createLine(_line, lineNumber), { type: 'text', value: match[0] }); start = index + 1; textStart = match.index + match[0].length; match = search.exec(child.value); } // If we matched, make sure to not drop the text after the last line ending. if (start === index + 1) { startTextRemainder = child.value.slice(textStart); } } } var line = tree.children.slice(start); // Prepend text from a partial matched earlier text. if (startTextRemainder) { line.unshift({ type: 'text', value: startTextRemainder }); startTextRemainder = ''; } if (line.length > 0) { lineNumber += 1; replacement.push(createLine(line, lineNumber)); } // Replace children with new array. tree.children = replacement; // Add total line count to root data if (!tree.data) { tree.data = {}; } tree.data.totalLines = lineNumber; } function createLine(children, line) { return { type: 'element', tagName: 'span', properties: { className: 'line', dataLineNumber: line }, children: children }; }