I’m attempting to create a javascript function that will take an input, count the characters before a piece of content surrounded by square brackets and output the content above that line of the input with correct spacing based on the amount of characters leading up to that content. This project is to create music charts while being able to write the chords inline with the lyrics.
Example input:
This is a [G]lyric to a [C]song
I could [D]sing it all day [Em]long
Desired output:
G C
This is a lyrics to a song
D Em
I could sing it all day long
I’m not incredibly experienced with Javascript, but I know the basics. This project is just a little over my head. I’ve attached the code I have so far.
function processText(input) {
const lines = input.split("n");
let output = "";
for (let line of lines) {
let startIndex = line.indexOf("[");
let endIndex = line.indexOf("]", startIndex);
let lastIndex = 0;
let lineOutput = "";
while (startIndex !== -1 && endIndex !== -1) {
const padding = startIndex - lastIndex;
const content = line.substring(startIndex + 1, endIndex);
lineOutput += " ".repeat(padding);
lineOutput += content + " ";
lastIndex = endIndex + 1;
line = line.substring(endIndex + 1);
startIndex = line.indexOf("[");
endIndex = line.indexOf("]", startIndex);
}
lineOutput += line.substring(lastIndex);
output += lineOutput.trim() + "n";
}
return output;
}
const input = `This is a [G]lyric to a [C]song
I could [D]sing it all day [Em]long`;
const output = processText(input);
console.log(output);
I’m afraid my limited experience with JS has me at a standstill currently.
The current output of the code is
$ node test.js
G C
D Em
Which actually wouldn’t be as problematic if the spacing was actually correct.. but I can’t seem to get that right..
3
Answers
reference
🙂
In order to solve problem to get desired output you need to first split the content into lines and then process each line .
Here i created a processLine function which processes the line and splits the line into 2 parts the lyric string and string without those G ,C or EM .
The logic is pretty simple . The processLine function will use regex to find the match and then create another string .
To position the lyrics the algo finds the distance between the previous match and next match and append space using
Array(space).join()
method.Heres the complete implementation :
You can so something like this:
What this does, is to first split the input into lines.
Then, reduce those lines to generate an array of alternating notes and lyrics.
How that is done is to split each line so it will separate it into an array of lyrics and notes (
c.split(/([[^]]+])/)
).That array is then reduced to an object that has as properties
notes
andlyrics
which are strings.To calculate the offset, you can simply subtract the current length of the notes line from the current length of the lyrics line add add to that the length of the note (
acc.lyrics.length - acc.notes.length + cleanNote.length
).