UNPKG

@visulima/fs

Version:

Human friendly file system utilities for Node.js

101 lines (99 loc) 3.09 kB
const INDENT_REGEX = /^(?:( )+|\t+)/; const INDENT_TYPE_SPACE = "space"; const INDENT_TYPE_TAB = "tab"; function shouldIgnoreSingleSpace(ignoreSingleSpaces, indentType, value) { return ignoreSingleSpaces && indentType === INDENT_TYPE_SPACE && value === 1; } function makeIndentsMap(string, ignoreSingleSpaces) { const indents = /* @__PURE__ */ new Map(); let previousSize = 0; let previousIndentType; let key; for (const line of string.split(/\n/g)) { if (!line) { continue; } const matches = line.match(INDENT_REGEX); if (matches === null) { previousSize = 0; previousIndentType = ""; } else { const indent = matches[0].length; const indentType = matches[1] ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB; if (shouldIgnoreSingleSpace(ignoreSingleSpaces, indentType, indent)) { continue; } if (indentType !== previousIndentType) { previousSize = 0; } previousIndentType = indentType; let use = 1; let weight = 0; const indentDifference = indent - previousSize; previousSize = indent; if (indentDifference === 0) { use = 0; weight = 1; } else { const absoluteIndentDifference = Math.abs(indentDifference); if (shouldIgnoreSingleSpace(ignoreSingleSpaces, indentType, absoluteIndentDifference)) { continue; } key = encodeIndentsKey(indentType, absoluteIndentDifference); } const entry = indents.get(key); indents.set(key, entry === void 0 ? [1, 0] : [entry[0] + use, entry[1] + weight]); } } return indents; } function encodeIndentsKey(indentType, indentAmount) { const typeCharacter = indentType === INDENT_TYPE_SPACE ? "s" : "t"; return typeCharacter + String(indentAmount); } function decodeIndentsKey(indentsKey) { const keyHasTypeSpace = indentsKey[0] === "s"; const type = keyHasTypeSpace ? INDENT_TYPE_SPACE : INDENT_TYPE_TAB; const amount = Number(indentsKey.slice(1)); return { type, amount }; } function getMostUsedKey(indents) { let result; let maxUsed = 0; let maxWeight = 0; for (const [key, [usedCount, weight]] of indents) { if (usedCount > maxUsed || usedCount === maxUsed && weight > maxWeight) { maxUsed = usedCount; maxWeight = weight; result = key; } } return result; } function makeIndentString(type, amount) { const indentCharacter = type === INDENT_TYPE_SPACE ? " " : " "; return indentCharacter.repeat(amount); } function detectIndent(string) { if (typeof string !== "string") { throw new TypeError("Expected a string"); } let indents = makeIndentsMap(string, true); if (indents.size === 0) { indents = makeIndentsMap(string, false); } const keyOfMostUsedIndent = getMostUsedKey(indents); let type; let amount = 0; let indent = ""; if (keyOfMostUsedIndent !== void 0) { ({ type, amount } = decodeIndentsKey(keyOfMostUsedIndent)); indent = makeIndentString(type, amount); } return { amount, type, indent }; } export { detectIndent as d };