Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
<section class="ImportDialog" id="importDialog">
<button class="ImportDialog__close-button" id="importDialog__closeButton" type="button">×</button>
<div class="ImportDialog__contents"><h1>Import chord sheet</h1>
<label class="ImportDialog__label" for="importDialog__format">Import format</label>
<select class="ImportDialog__format" id="importDialog__format"></select>
<textarea class="ChordSheetEditor ImportDialog__editor" id="importDialog__editor"></textarea>
<div class="ImportDialog__buttons">
<button class="large" id="importDialog__confirmButton" type="button">Import chord sheet</button>
Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import chordsheetjs from 'chordsheetjs';

import './sass/main.sass';

import { convertChordSheetToChordPro } from './js/chord_sheet_transformations';
import { getQueryParams, setQueryParams } from './js/location_hash';
import { convertImportedChordSheetToChordPro } from './js/import_format';
import ChordSheetEditor from './js/chord_sheet_editor';
import ChordSheetViewer from './js/chord_sheet_viewer';
import ImportDialog from './js/import_dialog';
Expand Down Expand Up @@ -53,8 +53,8 @@ class App {
this.render();
};

this.importDialog.onImportConfirmed = (chordSheet) => {
const chordProSheet = convertChordSheetToChordPro(chordSheet);
this.importDialog.onImportConfirmed = (chordSheet, format) => {
const chordProSheet = convertImportedChordSheetToChordPro(chordSheet, format);
this.chordSheetEditor.setValue(chordProSheet);
this.render();
};
Expand Down
4 changes: 2 additions & 2 deletions src/js/chord_sheet_transformations.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
ChordProFormatter,
ChordProParser,
ChordSheetParser,
ChordsOverWordsParser,
} from 'chordsheetjs';

const transformChordSheet = (chordSheet, processor) => {
Expand All @@ -27,7 +27,7 @@ export const switchToFlat = (chordSheet) => (
);

export const convertChordSheetToChordPro = (chordSheet) => {
const parser = new ChordSheetParser({ preserveWhitespace: false });
const parser = new ChordsOverWordsParser({ preserveWhitespace: false });
const formatter = new ChordProFormatter();
const song = parser.parse(chordSheet);
return formatter.format(song);
Expand Down
16 changes: 15 additions & 1 deletion src/js/import_dialog.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import Component from './component';
import { getImportFormatOptions } from './import_format';

class ImportDialog extends Component {
onImportConfirmed = () => {};

setup() {
this.populateFormatOptions();

this.onClick('confirmButton', () => {
const editor = this.element('editor');
const format = this.element('format').value;
const chordSheet = editor.value;
editor.value = '';
this.close();
this.onImportConfirmed(chordSheet);
this.onImportConfirmed(chordSheet, format);
});

this.onClick('closeButton', () => this.close());
}

populateFormatOptions() {
const select = this.element('format');

select.innerHTML = getImportFormatOptions()
.map(({ label, value }) => `<option value="${value}">${label}</option>`)
.join('');

select.value = 'ultimate-guitar';
}

setOpen(open) {
this.container.classList.toggle('ImportDialog--visible', open);
}
Expand Down
32 changes: 32 additions & 0 deletions src/js/import_format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
ChordProFormatter,
ChordProParser,
ChordsOverWordsParser,
UltimateGuitarParser,
} from 'chordsheetjs';

const PARSER_BY_FORMAT = {
chordpro: ChordProParser,
'chords-over-words': ChordsOverWordsParser,
'ultimate-guitar': UltimateGuitarParser,
};

export const getImportFormatOptions = () => [
{ label: 'Ultimate Guitar', value: 'ultimate-guitar' },
{ label: 'Chords over Words', value: 'chords-over-words' },
];

export const getParserForFormat = (format = 'ultimate-guitar') => (
PARSER_BY_FORMAT[format] || PARSER_BY_FORMAT['ultimate-guitar']
);

export const convertImportedChordSheetToChordPro = (chordSheet, format = 'ultimate-guitar') => {
const Parser = getParserForFormat(format);

const parser = Parser === ChordsOverWordsParser
? new Parser({ preserveWhitespace: false })
: new Parser();

const song = parser.parse(chordSheet);
return new ChordProFormatter().format(song);
};
18 changes: 18 additions & 0 deletions src/js/import_format.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import chordsheetjs from 'chordsheetjs';

import { getImportFormatOptions, getParserForFormat } from './import_format.js';

test('import format options include Ultimate Guitar and Chords over Words', () => {
const names = getImportFormatOptions().map((option) => option.value);

assert.ok(names.includes('ultimate-guitar'));
assert.ok(names.includes('chords-over-words'));
});

test('Ultimate Guitar format uses the expected parser class', () => {
const parser = getParserForFormat('ultimate-guitar');

assert.equal(parser, chordsheetjs.UltimateGuitarParser);
});