const RE_EMPTY_LINE = /^\s*$/;
const DEFAULT_OPTIONS = {
tabSize: 8,
inputNewline: '\n',
newlineAtEnd: true
};
function getTrimmedLines(strings, args, opts) {
const input = [];
for (let i = 0; i < strings.length; ++i) {
input.push(strings[i]);
if (args.length > i) {
input.push(args[i]);
}
}
const lines = input.join('').split(opts.inputNewline);
if (lines.length > 0 && lines[0].length === 0) {
lines.shift();
}
const lastIndex = lines.length - 1;
if (lines.length > 0 && RE_EMPTY_LINE.test(lines[lastIndex])) {
if (opts.newlineAtEnd) {
lines[lastIndex] = '';
} else {
lines.pop();
}
}
return lines;
}
function indentOf(line, opts) {
let count = 0;
for (let i = 0; i < line.length; ++i) {
const c = line[i];
if (c === ' ') {
count += 1;
} else if (c === '\t') {
count += opts.tabSize;
} else {
break;
}
}
return count;
}
function commonIndentFromLines(lines, opts) {
let pad = -1;
for (const l of lines) {
if (l.length === 0) {
continue;
}
if (pad < 0) {
pad = indentOf(l, opts);
continue;
}
pad = Math.min(pad, indentOf(l, opts));
}
return pad >= 0 ? pad : 0;
}
function trimCommonIndent(pad, line, opts) {
let idx = 0;
while (pad > 0) {
if (line[idx] === ' ') {
pad -= 1;
} else if (line[idx] === '\t') {
pad -= opts.tabSize;
} else {
throw Error(`FATAL: Char is not whitespace: '${line[idx]}' at ${idx} in '${line}' (pad: ${pad})`);
}
++idx;
}
if (pad === 0) {
return line.slice(idx);
}
return ' '.repeat(-pad) + line.slice(idx);
}
function heredoc(strings, ...args) {
if (!Array.isArray(strings)) {
return heredoc.bind(Object.assign({}, DEFAULT_OPTIONS, strings));
}
const lines = getTrimmedLines(strings, args, this);
if (lines.length === 0) {
return '';
}
const newline = this.outputNewline !== undefined ? this.outputNewline : this.inputNewline;
const pad = commonIndentFromLines(lines, this);
if (pad <= 0) {
return lines.join(newline);
}
for (let i = 0; i < lines.length; ++i) {
const l = lines[i];
if (l.length === 0) {
continue;
}
lines[i] = trimCommonIndent(pad, l, this);
}
return lines.join(newline);
}
const exported = heredoc.bind(DEFAULT_OPTIONS);
exported.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
exported.commonIndentFromLines = commonIndentFromLines;
if (typeof module !== 'undefined') {
exported.default = exported;
module.exports = exported;
}
if (typeof window !== 'undefined') {
window.Heredoc = exported;
}