Skip to content

Commit

Permalink
Make decapo configurable (#1533)
Browse files Browse the repository at this point in the history
  • Loading branch information
martijnversluis authored Jan 3, 2025
1 parent a6ff9fe commit 4ee1543
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 70 deletions.
1 change: 1 addition & 0 deletions src/formatter/chords_over_words_formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class ChordsOverWordsFormatter extends Formatter {
{
renderKey: this.configuration.key,
normalizeChords: this.configuration.normalizeChords,
decapo: this.configuration.decapo,
},
);
}
Expand Down
4 changes: 4 additions & 0 deletions src/formatter/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type ConfigurationProperties = Record<string, any> & {
delegates: Partial<Record<ContentType, Delegate>>;
instrument?: InstrumentConfigurationProperties;
user?: UserConfigurationProperties;
decapo?: boolean;
};

export const defaultConfiguration: ConfigurationProperties = {
Expand Down Expand Up @@ -58,6 +59,8 @@ class Configuration {

user?: UserConfiguration;

decapo?: boolean;

get metadataSeparator(): string {
return this.metadata.separator ?? '';
}
Expand All @@ -73,6 +76,7 @@ class Configuration {
this.delegates = { ...defaultConfiguration.delegates, ...configuration.delegates };
this.instrument = configuration.instrument ? new InstrumentConfiguration(configuration.instrument) : undefined;
this.user = configuration.user ? new UserConfiguration(configuration.user) : undefined;
this.decapo = !!configuration.decapo;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/formatter/templates/html_div_formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default (
renderKey: key,
useUnicodeModifier: configuration.useUnicodeModifiers,
normalizeChords: configuration.normalizeChords,
decapo: configuration.decapo,
},
) }
</div>
Expand Down
1 change: 1 addition & 0 deletions src/formatter/templates/html_table_formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default (
renderKey: key,
useUnicodeModifier: configuration.useUnicodeModifiers,
normalizeChords: configuration.normalizeChords,
decapo: configuration.decapo,
},
)
}</td>
Expand Down
1 change: 1 addition & 0 deletions src/formatter/text_formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class TextFormatter extends Formatter {
renderKey: this.configuration.key,
useUnicodeModifier: this.configuration.useUnicodeModifiers,
normalizeChords: this.configuration.normalizeChords,
decapo: this.configuration.decapo,
},
);
return chords;
Expand Down
16 changes: 15 additions & 1 deletion src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,21 @@ interface RenderChordOptions {
renderKey?: Key | null;
useUnicodeModifier?: boolean;
normalizeChords?: boolean;
decapo?: boolean;
}

/**
* Renders a chord in the context of a line and song and taking into account some options
* @param chordString The chord to render
* @param line The line the chord is in
* @param song The song the line is in
* @param renderKey The key to render the chord in. If not provided, the line key will be used,
* or the song key if the line key is not provided.
* @param useUnicodeModifier Whether to use unicode modifiers ('\u266f'/'\u266d') or plain text ('#'/'b').
* Default `false`.
* @param normalizeChords Whether to normalize the chord to the key (default `true`)
* @param decapo Whether to transpose all chords to eliminate the capo (default `false`)
*/
export function renderChord(
chordString: string,
line: Line,
Expand All @@ -68,12 +81,13 @@ export function renderChord(
renderKey = null,
useUnicodeModifier = false,
normalizeChords = true,
decapo = false,
}: RenderChordOptions = {},
): string {
const chord = Chord.parse(chordString);
const songKey = song.key;
const capoString = song.metadata.getSingle(CAPO);
const capo = capoString ? parseInt(capoString, 10) : null;
const capo = (decapo && capoString) ? parseInt(capoString, 10) : null;
const chordStyle = song.metadata.getSingle(CHORD_STYLE) as ChordType;

if (!chord) {
Expand Down
54 changes: 53 additions & 1 deletion test/formatter/html_div_formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ describe('HtmlDivFormatter', () => {
expect(typeof cssObject).toEqual('object');
});

it('applies the correct normalization when a capo is active', () => {
it('applies the correct normalization when a capo is active and decapo is on', () => {
const songWithCapo = new ChordSheetSerializer().deserialize({
type: 'chordSheet',
lines: [
Expand Down Expand Up @@ -614,6 +614,58 @@ describe('HtmlDivFormatter', () => {
</div>
`);

expect(new HtmlDivFormatter({ decapo: true }).format(songWithCapo)).toEqual(expectedChordSheet);
});

it('does not apply normalization for capo when decapo is off', () => {
const songWithCapo = new ChordSheetSerializer().deserialize({
type: 'chordSheet',
lines: [
{
type: 'line',
items: [{ type: 'tag', name: 'key', value: 'F' }],
},
{
type: 'line',
items: [{ type: 'tag', name: 'capo', value: '1' }],
},
{
type: 'line',
items: [
{ type: 'chordLyricsPair', chords: '', lyrics: 'My ' },
{ type: 'chordLyricsPair', chords: 'Dm7', lyrics: 'heart has always ' },
{ type: 'chordLyricsPair', chords: 'C/E', lyrics: 'longed for something ' },
{ type: 'chordLyricsPair', chords: 'F', lyrics: 'more' },
],
},
],
});

const expectedChordSheet = stripHTML(`
<div class="chord-sheet">
<div class="paragraph">
<div class="row">
<div class="column">
<div class="chord"></div>
<div class="lyrics">My </div>
</div>
<div class="column">
<div class="chord">Dm7</div>
<div class="lyrics">heart has always </div>
</div>
<div class="column">
<div class="chord">C/E</div>
<div class="lyrics">longed for something </div>
</div>
<div class="column">
<div class="chord">F</div>
<div class="lyrics">more</div>
</div>
</div>
</div>
</div>
`);

expect(new HtmlDivFormatter().format(songWithCapo)).toEqual(expectedChordSheet);
});

Expand Down
50 changes: 49 additions & 1 deletion test/formatter/html_table_formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ describe('HtmlTableFormatter', () => {
expect(typeof cssObject).toEqual('object');
});

it('applies the correct normalization when a capo is active', () => {
it('applies the correct normalization when a capo is active and decapo is on', () => {
const songWithCapo = new ChordSheetSerializer().deserialize({
type: 'chordSheet',
lines: [
Expand Down Expand Up @@ -660,6 +660,54 @@ describe('HtmlTableFormatter', () => {
</div>
`);

expect(new HtmlTableFormatter({ decapo: true }).format(songWithCapo)).toEqual(expectedChordSheet);
});

it('does not apply normalization for capo when decapo is off', () => {
const songWithCapo = new ChordSheetSerializer().deserialize({
type: 'chordSheet',
lines: [
{
type: 'line',
items: [{ type: 'tag', name: 'key', value: 'F' }],
},
{
type: 'line',
items: [{ type: 'tag', name: 'capo', value: '1' }],
},
{
type: 'line',
items: [
{ type: 'chordLyricsPair', chords: '', lyrics: 'My ' },
{ type: 'chordLyricsPair', chords: 'Dm7', lyrics: 'heart has always ' },
{ type: 'chordLyricsPair', chords: 'C/E', lyrics: 'longed for something ' },
{ type: 'chordLyricsPair', chords: 'F', lyrics: 'more' },
],
},
],
});

const expectedChordSheet = stripHTML(`
<div class="chord-sheet">
<div class="paragraph">
<table class="row">
<tr>
<td class="chord"></td>
<td class="chord">Dm7</td>
<td class="chord">C/E</td>
<td class="chord">F</td>
</tr>
<tr>
<td class="lyrics">My </td>
<td class="lyrics">heart has always </td>
<td class="lyrics">longed for something </td>
<td class="lyrics">more</td>
</tr>
</table>
</div>
</div>
`);

expect(new HtmlTableFormatter().format(songWithCapo)).toEqual(expectedChordSheet);
});

Expand Down
21 changes: 20 additions & 1 deletion test/formatter/text_formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Let it be, let it be, let it be, let it be`;
expect(formatter.format(songWithIntro)).toEqual(expectedChordSheet);
});

it('applies the correct normalization when a capo is active', () => {
it('applies the correct normalization when a capo is active and decapo is on', () => {
const songWithCapo = createSongFromAst([
[tag('key', 'F')],
[tag('capo', '1')],
Expand All @@ -140,6 +140,25 @@ Let it be, let it be, let it be, let it be`;
C#m7 B/D# E
My heart has always longed for something more`;

expect(new TextFormatter({ decapo: true }).format(songWithCapo)).toEqual(expectedChordSheet);
});

it('does not apply normalization for capo when decapo is off', () => {
const songWithCapo = createSongFromAst([
[tag('key', 'F')],
[tag('capo', '1')],
[
chordLyricsPair('', 'My '),
chordLyricsPair('Dm7', 'heart has always '),
chordLyricsPair('C/E', 'longed for something '),
chordLyricsPair('F', 'more'),
],
]);

const expectedChordSheet = heredoc`
Dm7 C/E F
My heart has always longed for something more`;

expect(new TextFormatter().format(songWithCapo)).toEqual(expectedChordSheet);
});

Expand Down
13 changes: 11 additions & 2 deletions test/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ import Metadata from '../src/chord_sheet/metadata';
import Configuration from '../src/formatter/configuration/configuration';

describe('renderChord', () => {
it('correctly normalizes when a capo is set', () => {
it('correctly normalizes when a capo is set and decapo is enabled', () => {
const line = createLine();
const song = new Song();
song.setMetadata('key', 'F');
song.setMetadata('capo', '1');

expect(renderChord('Dm7', line, song)).toEqual('C#m7');
expect(renderChord('Dm7', line, song, { decapo: true })).toEqual('C#m7');
});

it('does not normalize for capo when decapo is disabled', () => {
const line = createLine();
const song = new Song();
song.setMetadata('key', 'F');
song.setMetadata('capo', '1');

expect(renderChord('Dm7', line, song, { decapo: false })).toEqual('Dm7');
});

it('can render in a different key', () => {
Expand Down
Loading

0 comments on commit 4ee1543

Please sign in to comment.