Skip to content

Instantly share code, notes, and snippets.

@themichaelyang
Created November 21, 2025 12:18
Show Gist options
  • Select an option

  • Save themichaelyang/7667a0a9fcd39a7d5a81b26d708814c8 to your computer and use it in GitHub Desktop.

Select an option

Save themichaelyang/7667a0a9fcd39a7d5a81b26d708814c8 to your computer and use it in GitHub Desktop.
Template tag for preserving indents
function getIndentation(lines: string[] | TemplateStringsArray): string {
let firstIndent: string
if (lines[0] === '') {
firstIndent = lines[1]
} else {
firstIndent = lines[0]
}
const matched = firstIndent.match(/^(\s+).*$/)
return matched ? matched[1] : ''
}
function indented(strings: TemplateStringsArray, ...values: string[]) {
const indentLevel = getIndentation(strings[0].split('\n'))
const joined = strings
.map((str, i) => {
const inner = values[i]
const lines = str.split('\n')
const innerIndent = lines[lines.length - 1]
if (inner) {
// don't reindent the first line of inner, since that's where the indent level comes from
const reindentedInner = inner
.split('\n')
.map((v, j) => (j > 0 ? innerIndent + v : v))
.join('\n')
return `${str}${reindentedInner}`
} else {
return str
}
})
.join('')
.trimStart()
.trimEnd() // remove extra empty strings at start and end
return joined
.split('\n')
.map((line) => line.replace(new RegExp(`^${indentLevel}`), ''))
.join('\n')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment