I have the following template literal:
let message = `
1 call
Alert time: 6:00:57 PM
`
I've tried various answers from here on SO but for the API I'm working with, none of those solutions work correctly. Those solutions seem to be causing the line breaks after the opening backtick and the ending backtick to be removed along with the indentation.
Because this is happening the API I'm working with is treating the template literal as a single string with no line breaks.
How can I retain all of the line breaks but remove only the indentation in front of 1 call
and Alert time: 6:00:57 PM
?
My expected output would be this:
1 call
Alert time: 6:00:57 PM
I have the following template literal:
let message = `
1 call
Alert time: 6:00:57 PM
`
I've tried various answers from here on SO but for the API I'm working with, none of those solutions work correctly. Those solutions seem to be causing the line breaks after the opening backtick and the ending backtick to be removed along with the indentation.
Because this is happening the API I'm working with is treating the template literal as a single string with no line breaks.
How can I retain all of the line breaks but remove only the indentation in front of 1 call
and Alert time: 6:00:57 PM
?
My expected output would be this:
1 call
Alert time: 6:00:57 PM
Share
Improve this question
asked Apr 30, 2021 at 23:37
DshizDshiz
3,3514 gold badges34 silver badges63 bronze badges
1
- 1 This question is similar to: How can I have multiline strings that don't break indentation in JavaScript?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – double-beep Commented Sep 2, 2024 at 12:02
4 Answers
Reset to default 6A regular expression can match space characters at the beginning of the line and replace them with nothing, leaving the newlines alone:
message.replace(/^ +/gm, '')
Demo:
let message = `
1 call
Alert time: 6:00:57 PM
`
document.querySelector('textarea').value = message.replace(/^ +/gm, '');
<textarea></textarea>
There are, of course, a infinte ways to get to your solution. To make only the indent of the content disappear you can use the following method with your template strings. This ensures that only the indent created by the template string disappears, but the basic formatting remains intact.
function trimIndent(strings, ...values) {
const result = new Array(strings.length);
result[0] = strings[0].replace(/^\n/, '');
const endIndex = strings.length - 1;
result[endIndex] = strings[endIndex].replace(/\n$/, '');
var indent = result[0].match(/^\s+/g);
result[0] = result[0].replace(/^\s+/, '');
for (let i = 0, m = result.length; i < m; i++) {
var input = result[i] ?? strings[i];
result[i] = input.replace(new RegExp('\n' + indent, "gm"), '\n');
}
return result.flatMap((value, index) => {
return value + (index < values.length ? values[index] : '')
}).join("");
}
// example call:
var user = {
id: 10,
name: "Kevin",
}
if (true) {
console.log(trimIndent`
<div>
<span>ID: ${user.id}</span>
<span>
Username: ${user.name}
</span>
</div>
`);
}
I would split
the string by all the new lines \n
, then trim the items in the array to remove the spaces then join them again with new lines \n
. The filter
is to remove the items in the split
array that could be empty strings
let message = `
1 call
Alert time: 6:00:57 PM
`;
console.log(['', ...message.split('\n').filter(Boolean).map(str => str.trim()), ''].join('\n'));
Here's a more readable approach for correcting indentation in code. Such as when formatting a string function
/**
* Fixes indentation on strings of code.
*
* @param {string} value A string of code.
* @return {string} A string of code with proper indentation.
*/
const unindent = function (value) {
if (!value || typeof(value) !== 'string') {
return '';
}
let amountOfSpaces = 0;
let indentAmount = 2; // 2 space indentation
return value
.split('\n')
.map((line) => {
const amountOfOpenBrace = line.split('[').length - 1;
const amountOfOpenCurly = line.split('{').length - 1;
const amountOfOpenParen = line.split('(').length - 1;
const amountOfCloseBrace = line.split(']').length - 1;
const amountOfCloseCurly = line.split('}').length - 1;
const amountOfCloseParen = line.split(')').length - 1;
const opens = (
Math.max(amountOfOpenBrace - amountOfCloseBrace, 0) +
Math.max(amountOfOpenCurly - amountOfCloseCurly, 0) +
Math.max(amountOfOpenParen - amountOfCloseParen, 0)
);
const closes = (
Math.max(amountOfCloseBrace - amountOfOpenBrace, 0) +
Math.max(amountOfCloseCurly - amountOfOpenCurly, 0) +
Math.max(amountOfCloseParen - amountOfOpenParen, 0)
);
amountOfSpaces = amountOfSpaces - (closes * indentAmount);
const indentation = (new Array(amountOfSpaces)).fill(' ').join('');
amountOfSpaces = amountOfSpaces + (opens * indentAmount);
return indentation + line.trim();
})
.join('\n');
};
console.log(unindent('' + unindent));