diff --git a/src/importer/GpifParser.ts b/src/importer/GpifParser.ts index 4278a91c8..94a994f2c 100644 --- a/src/importer/GpifParser.ts +++ b/src/importer/GpifParser.ts @@ -92,6 +92,7 @@ export class GpifParser { private _lyricsByTrack!: Map; private _hasAnacrusis: boolean = false; private _articulationByName!: Map; + private _skipApplyLyrics: boolean = false; public parseXml(xml: string, settings: Settings): void { this._masterTrackAutomations = new Map(); @@ -110,6 +111,8 @@ export class GpifParser { this._noteById = new Map(); this._tappedNotes = new Map(); this._lyricsByTrack = new Map(); + this._skipApplyLyrics = false; + let dom: XmlDocument; try { dom = new XmlDocument(xml); @@ -120,7 +123,7 @@ export class GpifParser { this.parseDom(dom); this.buildModel(); this.score.finish(settings); - if (this._lyricsByTrack.size > 0) { + if (!this._skipApplyLyrics && this._lyricsByTrack.size > 0) { this._lyricsByTrack.forEach((lyrics, t) => { let track: Track = this._tracksById.get(t)!; track.applyLyrics(lyrics); @@ -1396,12 +1399,32 @@ export class GpifParser { break; } break; + case 'Lyrics': + beat.lyrics = this.parseBeatLyrics(c); + this._skipApplyLyrics = true; + break; } } } this._beatById.set(beatId, beat); } + private parseBeatLyrics(node: XmlNode): string[] | null { + const lines: string[] = []; + + for (let c of node.childNodes) { + if (c.nodeType === XmlNodeType.Element) { + switch (c.localName) { + case 'Line': + lines.push(c.innerText); + break; + } + } + } + + return lines; + } + private parseBeatXProperties(node: XmlNode, beat: Beat): void { for (let c of node.childNodes) { if (c.nodeType === XmlNodeType.Element) { diff --git a/test-data/guitarpro7/beat-lyrics.gp b/test-data/guitarpro7/beat-lyrics.gp new file mode 100644 index 000000000..530728743 Binary files /dev/null and b/test-data/guitarpro7/beat-lyrics.gp differ diff --git a/test/importer/Gp7Importer.test.ts b/test/importer/Gp7Importer.test.ts index ec9e5085d..8e70163cc 100644 --- a/test/importer/Gp7Importer.test.ts +++ b/test/importer/Gp7Importer.test.ts @@ -856,4 +856,18 @@ describe('Gp7ImporterTest', () => { ); expect(score.tracks[0].staves[0].bars[4].voices[0].beats[0].notes[0].fret).toEqual(20); }); + + it('beat-lyrics', async () => { + const reader = await prepareGp7ImporterWithFile('guitarpro7/beat-lyrics.gp'); + let score: Score = reader.readScore(); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[0].lyrics![0]).toBe("This"); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[1].lyrics![0]).toBe("is"); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[2].lyrics![0]).toBe("a"); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[3].lyrics![0]).toBe("test file"); + expect(score.tracks[0].staves[0].bars[1].voices[0].beats[0].lyrics![0]).toBe("for"); + expect(score.tracks[0].staves[0].bars[1].voices[0].beats[1].lyrics![0]).toBe("lyrics"); + expect(score.tracks[0].staves[0].bars[1].voices[0].beats[2].lyrics).toBe(null); + expect(score.tracks[0].staves[0].bars[1].voices[0].beats[3].lyrics).toBe(null); + }); + });