26 lines
1004 B
JavaScript
26 lines
1004 B
JavaScript
/* PCO Plan — how a song key is written.
|
|||
|
|
|
||
|
|
Planning Center stores keys as typed: "Bb", "F#m", "Ab". Every tile in this
|
||
|
|
module shows them as notes instead — B♭, F♯m, A♭ — so the plan, the badge
|
||
|
|
on an item and the Song Key tile all agree. Shared rather than repeated
|
||
|
|
because the day one of them changes, they all should. */
|
||
|
|
|
||
|
|
/** "F#m" → { note: 'F', accidental: '♯', quality: 'm' }; anything odd → null. */
|
||
|
|
export function parseKey(raw) {
|
||
|
|
const match = /^([A-G])\s*([#b♯♭]?)\s*(.*)$/.exec(String(raw || '').trim());
|
||
|
|
if (!match) return null;
|
||
|
|
const [, note, accidental, quality] = match;
|
||
|
|
return {
|
||
|
|
note,
|
||
|
|
accidental: accidental === '#' ? '♯' : accidental === 'b' ? '♭' : accidental,
|
||
|
|
quality: quality.trim(),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/** The same thing as one string, for a badge or a caption. */
|
||
|
|
export function prettyKey(raw) {
|
||
|
|
const parts = parseKey(raw);
|
||
|
|
if (!parts) return String(raw || '').trim();
|
||
|
|
return `${parts.note}${parts.accidental}${parts.quality}`;
|
||
|
|
}
|