From 859381839185d1ef2edc0b86b1aefe82e332a05c Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Sun, 28 Jan 2024 01:25:52 +0100 Subject: [PATCH 1/2] feat(alphaTex): allow specifying tempo as a float in a string --- src/importer/AlphaTexImporter.ts | 27 ++++++++++++++++++++++---- test/importer/AlphaTexImporter.test.ts | 15 ++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/importer/AlphaTexImporter.ts b/src/importer/AlphaTexImporter.ts index 804cde7c5..40239dc36 100644 --- a/src/importer/AlphaTexImporter.ts +++ b/src/importer/AlphaTexImporter.ts @@ -727,8 +727,16 @@ export class AlphaTexImporter extends ScoreImporter { break; case 'tempo': this._sy = this.newSy(); - if (this._sy === AlphaTexSymbols.Number) { - this._score.tempo = this._syData as number; + if (this._sy === AlphaTexSymbols.Number || this._sy === AlphaTexSymbols.String) { + if (this._sy === AlphaTexSymbols.Number) { + this._score.tempo = this._syData as number; + } else if (this._sy === AlphaTexSymbols.String) { + let f: number = parseFloat(this._syData as string); + if (isNaN(f)) { + this.errorMessage('invalid temp string'); + } + this._score.tempo = f; + } } else { this.error('tempo', AlphaTexSymbols.Number, true); } @@ -1879,13 +1887,24 @@ export class AlphaTexImporter extends ScoreImporter { this._sy = this.newSy(); } else if (syData === 'tempo') { this._sy = this.newSy(); - if (this._sy !== AlphaTexSymbols.Number) { + let value: number = 0; + if (this._sy === AlphaTexSymbols.Number || this._sy === AlphaTexSymbols.String) { + if (this._sy === AlphaTexSymbols.Number) { + value = this._syData as number; + } else if (this._sy === AlphaTexSymbols.String) { + let f: number = parseFloat(this._syData as string); + if (isNaN(f)) { + this.errorMessage('invalid temp string'); + } + value = f; + } + } else { this.error('tempo', AlphaTexSymbols.Number, true); } let tempoAutomation: Automation = new Automation(); tempoAutomation.isLinear = false; tempoAutomation.type = AutomationType.Tempo; - tempoAutomation.value = this._syData as number; + tempoAutomation.value = value; master.tempoAutomation = tempoAutomation; this._sy = this.newSy(); } else if (syData === 'section') { diff --git a/test/importer/AlphaTexImporter.test.ts b/test/importer/AlphaTexImporter.test.ts index f82d4d38e..79f5f7abc 100644 --- a/test/importer/AlphaTexImporter.test.ts +++ b/test/importer/AlphaTexImporter.test.ts @@ -1129,4 +1129,19 @@ describe('AlphaTexImporterTest', () => { expect(i.message?.includes('ABC')).to.be.true; } }); + + it('tempo-as-float-string', () => { + const score = parseTex('\\tempo "112.5" .'); + expect(score.tempo).to.equal(112.5); + }); + + it('tempo-as-float-string-in-bar', () => { + const score = parseTex('\\tempo 112 . 3.3.1 | \\tempo "333.3" 3.3'); + expect(score.tempo).to.equal(112); + expect(score.tracks[0].staves[0].bars[1].masterBar.tempoAutomation?.value).to.equal(333.3); + }); + + it('tempo-invalid-float-string', () => { + expect(() => parseTex('\\tempo "a a 112" .')).to.throw(UnsupportedFormatError); + }); }); From f972f191ddb9ac68158d3fa004675050b3aebab2 Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:07:05 +0100 Subject: [PATCH 2/2] fix: use parser flag for when floats are allowed --- src/importer/AlphaTexImporter.ts | 39 +++++++++----------------- test/importer/AlphaTexImporter.test.ts | 12 ++++---- 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/importer/AlphaTexImporter.ts b/src/importer/AlphaTexImporter.ts index 40239dc36..44b890539 100644 --- a/src/importer/AlphaTexImporter.ts +++ b/src/importer/AlphaTexImporter.ts @@ -136,6 +136,7 @@ export class AlphaTexImporter extends ScoreImporter { private _sy: AlphaTexSymbols = AlphaTexSymbols.No; private _syData: unknown = ""; private _allowNegatives: boolean = false; + private _allowFloat: boolean = false; private _allowTuning: boolean = false; private _currentDuration: Duration = Duration.QuadrupleWhole; private _currentDynamics: DynamicValue = DynamicValue.PPP; @@ -548,7 +549,7 @@ export class AlphaTexImporter extends ScoreImporter { } else if (this._ch === 0x2d /* - */) { // negative number // is number? - if (this._allowNegatives && this.isDigit(this._ch)) { + if (this._allowNegatives) { this._sy = AlphaTexSymbols.Number; this._syData = this.readNumber(); } else { @@ -649,7 +650,8 @@ export class AlphaTexImporter extends ScoreImporter { private isDigit(ch: number): boolean { return ( (ch >= 0x30 && ch <= 0x39) /* 0-9 */ || - (this._allowNegatives && ch === 0x2d /* - */) // allow minus sign if negatives + (this._allowNegatives && ch === 0x2d /* - */) || // allow minus sign if negatives + (this._allowFloat && ch === 0x2e /* . */) // allow dot if float ); } @@ -676,7 +678,7 @@ export class AlphaTexImporter extends ScoreImporter { str += String.fromCharCode(this._ch); this._ch = this.nextChar(); } while (this.isDigit(this._ch)); - return parseInt(str); + return this._allowFloat ? parseFloat(str) : parseInt(str); } private metaData(): boolean { @@ -726,17 +728,11 @@ export class AlphaTexImporter extends ScoreImporter { anyMeta = true; break; case 'tempo': + this._allowFloat = true; this._sy = this.newSy(); - if (this._sy === AlphaTexSymbols.Number || this._sy === AlphaTexSymbols.String) { - if (this._sy === AlphaTexSymbols.Number) { - this._score.tempo = this._syData as number; - } else if (this._sy === AlphaTexSymbols.String) { - let f: number = parseFloat(this._syData as string); - if (isNaN(f)) { - this.errorMessage('invalid temp string'); - } - this._score.tempo = f; - } + this._allowFloat = false; + if (this._sy === AlphaTexSymbols.Number) { + this._score.tempo = this._syData as number; } else { this.error('tempo', AlphaTexSymbols.Number, true); } @@ -1886,25 +1882,16 @@ export class AlphaTexImporter extends ScoreImporter { } this._sy = this.newSy(); } else if (syData === 'tempo') { + this._allowFloat = true; this._sy = this.newSy(); - let value: number = 0; - if (this._sy === AlphaTexSymbols.Number || this._sy === AlphaTexSymbols.String) { - if (this._sy === AlphaTexSymbols.Number) { - value = this._syData as number; - } else if (this._sy === AlphaTexSymbols.String) { - let f: number = parseFloat(this._syData as string); - if (isNaN(f)) { - this.errorMessage('invalid temp string'); - } - value = f; - } - } else { + this._allowFloat = false; + if (this._sy !== AlphaTexSymbols.Number) { this.error('tempo', AlphaTexSymbols.Number, true); } let tempoAutomation: Automation = new Automation(); tempoAutomation.isLinear = false; tempoAutomation.type = AutomationType.Tempo; - tempoAutomation.value = value; + tempoAutomation.value = this._syData as number; master.tempoAutomation = tempoAutomation; this._sy = this.newSy(); } else if (syData === 'section') { diff --git a/test/importer/AlphaTexImporter.test.ts b/test/importer/AlphaTexImporter.test.ts index 79f5f7abc..bf7d79e1c 100644 --- a/test/importer/AlphaTexImporter.test.ts +++ b/test/importer/AlphaTexImporter.test.ts @@ -1130,18 +1130,18 @@ describe('AlphaTexImporterTest', () => { } }); - it('tempo-as-float-string', () => { - const score = parseTex('\\tempo "112.5" .'); + it('tempo-as-float', () => { + const score = parseTex('\\tempo 112.5 .'); expect(score.tempo).to.equal(112.5); }); - it('tempo-as-float-string-in-bar', () => { - const score = parseTex('\\tempo 112 . 3.3.1 | \\tempo "333.3" 3.3'); + it('tempo-as-float-in-bar', () => { + const score = parseTex('\\tempo 112 . 3.3.1 | \\tempo 333.3 3.3'); expect(score.tempo).to.equal(112); expect(score.tracks[0].staves[0].bars[1].masterBar.tempoAutomation?.value).to.equal(333.3); }); - it('tempo-invalid-float-string', () => { - expect(() => parseTex('\\tempo "a a 112" .')).to.throw(UnsupportedFormatError); + it('tempo-invalid-float', () => { + expect(() => parseTex('\\tempo 112.Q .')).to.throw(UnsupportedFormatError); }); });