Last active
March 25, 2023 18:45
-
-
Save Grohden/dbae82df61595d990dd079cc5b72f55b to your computer and use it in GitHub Desktop.
Transform a tab (?) format into an AlphaTex (for AlphaTab)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this heavily uses ramda | |
// this was done quickly to just make it work, its variale names essentialy do not have correct names | |
// this does not generate duration information | |
// you can just past it in ramda and it will run | |
// https://ramdajs.com/repl | |
// take the result and feed it into the alphaTab | |
const notes = `\ | |
—---------8------------------------------------------------ | |
—----9-11----11-9-11-----9-9-11------9-9------------------- | |
—-10-----------------10-----------10-----10---8-10-10-10--- | |
—---------------------------------------------------------- | |
—---------------------------------------------------------- | |
—----------------------------------------------------------` | |
const duration = 2 | |
const lines = split('\n', notes) | |
const spaceTokens = new Set(['—', '-']); | |
const extractLineInfo = reduce( | |
(info, token) => { | |
if(spaceTokens.has(token)) { | |
if (info.currentFret) { | |
const newLoc = info.location + info.currentFret.length + 1 | |
return { | |
data: [...info.data, { | |
fret: parseInt(info.currentFret, 10), | |
location: newLoc | |
}], | |
currentFret: '', | |
location: newLoc | |
} | |
} else { | |
return { | |
...info, | |
location: info.location + 1 | |
} | |
} | |
} | |
return { | |
...info, | |
currentFret: info.currentFret + token | |
} | |
}, | |
{ data: [], location: 0, currentFret: '' }, | |
); | |
const blockInfo = map(pipe(split(''), extractLineInfo, prop('data'))); | |
const orderedData = pipe( | |
blockInfo, | |
addIndex(map)((a, i) => ({string: i + 1, data: a })), | |
); | |
const localizeValues = map( | |
(parsed) => ({ | |
string: parsed.string, | |
locationToFret: pipe( | |
groupBy((value) => value.location), | |
map(map(prop('fret'))) | |
)(parsed.data) | |
}), | |
); | |
const localizedValues = localizeValues(orderedData(lines)); | |
const biggestLineLen = reduce(max, 0, map(length, lines)); | |
const generateForPosition = (position) => pipe( | |
map(({ locationToFret, string }) => { | |
const atex = map( | |
fret => `${fret}.${string}`, | |
locationToFret[position] || [] | |
) | |
const count = length(atex); | |
if(count === 0) { | |
return | |
} | |
const notes = length(atex) == 1 ? head(atex) : `(${join(' ', atex)})`; | |
return `${notes}.${duration}`; | |
}, | |
), | |
filter(complement(isNil)), | |
)(localizedValues); | |
// you still need to split lines | |
// you still need to split lines | |
const getTexLines = pipe( | |
range(0), | |
map(generateForPosition), | |
flatten, | |
splitEvery(4), | |
map(join(' ')) | |
); | |
console.clear(); | |
getTexLines(biggestLineLen).forEach((l) => console.log(l + ' |')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment