@timhall/dedent
Version:
Remove extra indentation from template strings
63 lines (59 loc) • 2.61 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.dedent = factory());
}(this, (function () { 'use strict';
const placeholder = `{${String.fromCharCode(32)}}`;
function dedent(strings, ...values) {
const raw = typeof strings === 'string'
? [strings]
: isTemplateStringsArray(strings)
? strings.raw
: strings;
// Handle template string formatting (backticks, \ line endings)
const formatted = raw.map((part) => pipeline(part, unescapeBackticks, joinSuppressedNewline));
// Find minimum indentation of template strings
const lines = formatted.join(placeholder).split(/\r?\n/);
const minimumIndentation = Math.min(...lines.map((line) => {
const leadingSpaces = line.match(/^(\s+)\S+/);
return leadingSpaces ? leadingSpaces[1].length : Infinity;
}));
// Rejoin formatted lines with unindentation and placeholders
const shouldDedent = minimumIndentation > 0 && minimumIndentation < Infinity;
const joined = !shouldDedent
? lines.join('\n')
: lines
.map((line, lineIndex) => {
const isFirstLine = lineIndex === 0;
const hasLeadingSpaces = !!line.match(/^(\s+)\S+/);
const isUnindented = isFirstLine && !hasLeadingSpaces;
return !isUnindented ? line.slice(minimumIndentation) : line;
})
.join('\n');
// Replace placeholders with values
const replaced = joined.split(placeholder).reduce((memo, part, partIndex) => {
return memo + part + (values[partIndex] || '');
}, '');
return pipeline(replaced, trim, unescapeNewlines);
}
function isTemplateStringsArray(value) {
return value && Array.isArray(value.raw);
}
function joinSuppressedNewline(value) {
return value.replace(/\\\n[ \t]*/g, '');
}
function unescapeBackticks(value) {
return value.replace(/\\`/g, '`');
}
function trim(value) {
return value.trim();
}
function unescapeNewlines(value) {
return value.replace(/\\n/g, '\n');
}
function pipeline(value, ...functions) {
return functions.reduce((value, fn) => fn(value), value);
}
return dedent;
})));
//# sourceMappingURL=dedent.js.map