diff --git a/package.json b/package.json index fdd234c..4e67d3a 100644 --- a/package.json +++ b/package.json @@ -84,10 +84,6 @@ "typescript": "^5.0.2", "vitest": "^1.6.0" }, - "dependencies": { - "detect-indent": "^6.1.0", - "strip-indent": "^3.0.0" - }, "peerDependencies": { "@babel/core": "^7.10.2", "coffeescript": "^2.5.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f5c1446..aab9c16 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,13 +7,6 @@ settings: importers: .: - dependencies: - detect-indent: - specifier: ^6.1.0 - version: 6.1.0 - strip-indent: - specifier: ^3.0.0 - version: 3.0.0 devDependencies: '@babel/core': specifier: ^7.23.6 @@ -1974,10 +1967,6 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -6564,8 +6553,6 @@ snapshots: dequal@2.0.3: {} - detect-indent@6.1.0: {} - detect-newline@3.1.0: optional: true diff --git a/src/modules/prepareContent.ts b/src/modules/prepareContent.ts index b296edb..5dadf5d 100644 --- a/src/modules/prepareContent.ts +++ b/src/modules/prepareContent.ts @@ -1,6 +1,4 @@ -import stripIndent from 'strip-indent'; - -// todo: could use magig-string and generate some sourcemaps 🗺 +// todo: could use magic-string and generate some sourcemaps 🗺 export function prepareContent({ options, content, @@ -22,3 +20,27 @@ export function prepareContent({ return content; } + +/** Get the shortest leading whitespace from lines in a string */ +function minIndent(s: string) { + const match = s.match(/^[ \t]*(?=\S)/gm); + + if (!match) { + return 0; + } + + return match.reduce((r, a) => Math.min(r, a.length), Infinity); +} + +/** Strip leading whitespace from each line in a string */ +function stripIndent(s: string) { + const indent = minIndent(s); + + if (indent === 0) { + return s; + } + + const regex = new RegExp(`^[ \\t]{${indent}}`, 'gm'); + + return s.replace(regex, ''); +} diff --git a/src/transformers/pug.ts b/src/transformers/pug.ts index b02192b..dfad060 100644 --- a/src/transformers/pug.ts +++ b/src/transformers/pug.ts @@ -1,4 +1,3 @@ -import detectIndent from 'detect-indent'; import pug from 'pug'; import type { Transformer, Options } from '../types'; @@ -67,8 +66,8 @@ const transformer: Transformer = async ({ ...options, }; - const { type: indentationType } = detectIndent(content); - const input = `${GET_MIXINS(indentationType ?? 'space')}\n${content}`; + const spaces = guessIndentString(content); + const input = `${GET_MIXINS(spaces ? 'space' : 'tab')}\n${content}`; const compiled = pug.compile( input, pugOptions, @@ -94,4 +93,41 @@ const transformer: Transformer = async ({ }; }; +// Sourced from `golden-fleece` +// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 +function guessIndentString(str: string): number | undefined { + const lines = str.split('\n'); + + let tabs = 0; + let spaces = 0; + let minSpaces = 8; + + lines.forEach((line) => { + const match = /^(?: +|\t+)/.exec(line); + + if (!match) return; + + const [whitespace] = match; + + if (whitespace.length === line.length) return; + + if (whitespace[0] === '\t') { + tabs += 1; + } else { + spaces += 1; + if (whitespace.length > 1 && whitespace.length < minSpaces) { + minSpaces = whitespace.length; + } + } + }); + + if (spaces > tabs) { + let result = ''; + + while (minSpaces--) result += ' '; + + return result.length; + } +} + export { transformer }; diff --git a/src/types/modules.d.ts b/src/types/modules.d.ts index e762681..6b524a7 100644 --- a/src/types/modules.d.ts +++ b/src/types/modules.d.ts @@ -1,6 +1,5 @@ declare module 'svelte/package.json'; declare module 'coffeescript'; -declare module 'strip-indent'; declare module 'postcss-load-config'; declare module 'less'; declare module 'sorcery';