mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 22:21:40 +03:00
65 lines
1.5 KiB
JavaScript
65 lines
1.5 KiB
JavaScript
/**
|
|
* @param {string | TemplateStringsArray} strings
|
|
* @param {...unknown[]} values
|
|
* @returns {string}
|
|
*/
|
|
export function dedent(strings, ...values) {
|
|
const raw = typeof strings === 'string' ? [strings] : strings.raw
|
|
const escapeSpecialCharacters = Array.isArray(strings)
|
|
|
|
// first, perform interpolation
|
|
let result = ''
|
|
for (let i = 0; i < raw.length; i++) {
|
|
let next = raw[i]
|
|
|
|
if (next === undefined) {
|
|
continue
|
|
}
|
|
|
|
if (escapeSpecialCharacters) {
|
|
// handle escaped newlines, backticks, and interpolation characters
|
|
next = next
|
|
.replace(/\\\n[ \t]*/g, '')
|
|
.replace(/\\`/g, '`')
|
|
.replace(/\\\$/g, '$')
|
|
.replace(/\\\{/g, '{')
|
|
}
|
|
|
|
result += next
|
|
|
|
if (i < values.length) {
|
|
result += values[i]
|
|
}
|
|
}
|
|
|
|
// now strip indentation
|
|
const lines = result.split('\n')
|
|
let mindent = null
|
|
for (const l of lines) {
|
|
const m = l.match(/^(\s+)\S+/)
|
|
if (m && m[1]) {
|
|
const indent = m[1].length
|
|
if (!mindent) {
|
|
// this is the first indented line
|
|
mindent = indent
|
|
} else {
|
|
mindent = Math.min(mindent, indent)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mindent !== null) {
|
|
const m = mindent
|
|
result = lines.map((l) => (l[0] === ' ' || l[0] === '\t' ? l.slice(m) : l)).join('\n')
|
|
}
|
|
|
|
// dedent eats leading and trailing whitespace too
|
|
result = result.trim()
|
|
if (escapeSpecialCharacters) {
|
|
// handle escaped newlines at the end to ensure they don't get stripped too
|
|
result = result.replace(/\\n/g, '\n')
|
|
}
|
|
|
|
return result
|
|
}
|