Skip to content

Commit

Permalink
Add unicode support to alphaTex (CoderLine#580)
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielku15 committed Apr 3, 2021
1 parent bae294d commit 1f3f956
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src.compiler/csharp/CSharpAstPrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ export default class CSharpAstPrinter extends AstPrinterBase {
let exprs: cs.Expression[] = [];
expr.chunks.forEach(c => {
if (cs.isStringLiteral(c)) {
const escapedText = c.text.split('"').join('""').split('\n').join('\\n').split('\r').join('\\r');
const escapedText = c.text.split('"').join('""');
this.write(escapedText);
} else {
this.write(`{${exprs.length}}`);
Expand Down
6 changes: 3 additions & 3 deletions src.compiler/kotlin/KotlinAstPrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -858,18 +858,18 @@ export default class KotlinAstPrinter extends AstPrinterBase {
}

protected writeStringTemplateExpression(expr: cs.StringTemplateExpression) {
this.write('"');
this.write('"""');
expr.chunks.forEach(c => {
if (cs.isStringLiteral(c)) {
const escapedText = c.text.split('"').join('\\"').split('\n').join('\\n').split('\r').join('\\r');
const escapedText = c.text;
this.write(escapedText);
} else {
this.write('${');
this.writeExpression(c);
this.write('}');
}
});
this.write('"');
this.write('"""');
}

protected writeArrayCreationExpression(expr: cs.ArrayCreationExpression) {
Expand Down
2 changes: 0 additions & 2 deletions src.csharp/AlphaTab/AlphaTab.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
<TargetFramework>netstandard20</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>8</LangVersion>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src.csharp/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<PropertyGroup>
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
<Version>1.1.0</Version>
<AssemblyVersion>1.1.0.0</AssemblyVersion>
<Version>1.3.0</Version>
<AssemblyVersion>1.3.0.0</AssemblyVersion>
<FileVersion>$(AssemblyVersion)</FileVersion>
<Authors>Danielku15</Authors>
<Company>CoderLine</Company>
<Product>AlphaTab</Product>
<NeutralLanguage>en</NeutralLanguage>
<Description>alphaTab is a cross platform music notation and guitar tablature rendering library.</Description>
<Copyright>Copyright © 2020, Daniel Kuschny and Contributors</Copyright>
<Copyright>Copyright © 2021, Daniel Kuschny and Contributors</Copyright>
<PackageLicenseExpression>MPL-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://www.alphatab.net</PackageProjectUrl>
<RepositoryUrl>https://github.com/CoderLine/alphaTab</RepositoryUrl>
Expand Down
4 changes: 1 addition & 3 deletions src/AlphaTabApiBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { EventEmitter, IEventEmitter, IEventEmitterOfT, EventEmitterOfT } from '

import { AlphaTexImporter } from '@src/importer/AlphaTexImporter';

import { ByteBuffer } from '@src/io/ByteBuffer';
import { Beat } from '@src/model/Beat';
import { Score } from '@src/model/Score';
import { Track } from '@src/model/Track';
Expand Down Expand Up @@ -330,8 +329,7 @@ export class AlphaTabApiBase<TSettings> {
public tex(tex: string, tracks?: number[]): void {
try {
let parser: AlphaTexImporter = new AlphaTexImporter();
let data: ByteBuffer = ByteBuffer.fromString(tex);
parser.init(data, this.settings);
parser.initFromString(tex, this.settings);
let score: Score = parser.readScore();
this.renderScore(score, tracks);
} catch (e) {
Expand Down
28 changes: 20 additions & 8 deletions src/importer/AlphaTexImporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import { Logger } from '@src/Logger';
import { ModelUtils, TuningParseResult } from '@src/model/ModelUtils';
import { AlphaTabError, AlphaTabErrorType } from '@src/AlphaTabError';
import { BeatCloner } from '@src/generated/model/BeatCloner';
import { IOHelper } from '@src/io/IOHelper';
import { Settings } from '@src/Settings';
import { ByteBuffer } from '@src/io/ByteBuffer';

/**
* A list of terminals recognized by the alphaTex-parser
Expand Down Expand Up @@ -107,6 +110,7 @@ export class AlphaTexImporter extends ScoreImporter {
private _score!: Score;
private _currentTrack!: Track;
private _currentStaff!: Staff;
private _input: string = "";
private _ch: number = 0;
private _curChPos: number = 0;
private _sy: AlphaTexSymbols = AlphaTexSymbols.No;
Expand All @@ -129,8 +133,18 @@ export class AlphaTexImporter extends ScoreImporter {
return 'AlphaTex';
}

public initFromString(tex: string, settings: Settings) {
this.data = ByteBuffer.empty();
this._input = tex;
this.settings = settings;
}


public readScore(): Score {
try {
if(this.data.length > 0) {
this._input = IOHelper.toString(this.data.readAll(), this.settings.importer.encoding);
}
this._allowTuning = true;
this._lyrics = new Map<number, Lyrics[]>();
this.createDefaultScore();
Expand All @@ -148,7 +162,7 @@ export class AlphaTexImporter extends ScoreImporter {
this.consolidate();
this._score.finish(this.settings);
this._score.rebuildRepeatGroups();
for(const [track, lyrics] of this._lyrics) {
for (const [track, lyrics] of this._lyrics) {
this._score.tracks[track].applyLyrics(lyrics);
}
return this._score;
Expand Down Expand Up @@ -362,12 +376,10 @@ export class AlphaTexImporter extends ScoreImporter {
* Reads the next character of the source stream.
*/
private nextChar(): number {
let b: number = this.data.readByte();
if (b === -1) {
this._ch = 0;
if (this._curChPos < this._input.length) {
this._ch = this._input.charCodeAt(this._curChPos++)
} else {
this._ch = b;
this._curChPos++;
this._ch = 0;
}
return this._ch;
}
Expand Down Expand Up @@ -888,7 +900,7 @@ export class AlphaTexImporter extends ScoreImporter {
let syData: string = (this._syData as string).toLowerCase();
if (syData === 'track') {
this._staffHasExplicitTuning = false;
this._staffTuningApplied = false;
this._staffTuningApplied = false;

this._sy = this.newSy();
// new track starting? - if no masterbars it's the \track of the initial track.
Expand All @@ -911,7 +923,7 @@ export class AlphaTexImporter extends ScoreImporter {
if (syData === 'staff') {
this._staffHasExplicitTuning = false;
this._staffTuningApplied = false;

this._sy = this.newSy();
if (this._currentTrack.staves[0].bars.length > 0) {
this._currentTrack.ensureStaveCount(this._currentTrack.staves.length + 1);
Expand Down
6 changes: 2 additions & 4 deletions src/io/ByteBuffer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IReadable } from '@src/io/IReadable';
import { IWriteable } from '@src/io/IWriteable';
import { IOHelper } from './IOHelper';

export class ByteBuffer implements IWriteable, IReadable {
private _buffer!: Uint8Array;
Expand Down Expand Up @@ -36,10 +37,7 @@ export class ByteBuffer implements IWriteable, IReadable {
}

public static fromString(contents: string): ByteBuffer {
let byteArray: Uint8Array = new Uint8Array(contents.length);
for (let i: number = 0; i < contents.length; i++) {
byteArray[i] = contents.charCodeAt(i);
}
let byteArray: Uint8Array = IOHelper.stringToBytes(contents);
return ByteBuffer.fromBuffer(byteArray);
}

Expand Down
6 changes: 0 additions & 6 deletions test/TestPlatform.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { ByteBuffer } from '@src/io/ByteBuffer';
import { IReadable } from '@src/io/IReadable';
import { IOHelper } from '@src/io/IOHelper';

/**
* @partial
*/
export class TestPlatform {
public static createStringReader(tex: string): IReadable {
return ByteBuffer.fromString(tex);
}

/**
* @target web
* @partial
Expand Down
2 changes: 1 addition & 1 deletion test/audio/AlphaSynth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('AlphaSynthTests', () => {
' (0.4 0.3).8 r.8(3.4 3.3).8 r.8(5.4 5.3).4 r.8(3.4 3.3).8 | ' +
'r.8(0.4 0.3).8(-.3 - .4).2 { d } | ';
let importer: AlphaTexImporter = new AlphaTexImporter();
importer.init(TestPlatform.createStringReader(tex), new Settings());
importer.initFromString(tex, new Settings());
let score: Score = importer.readScore();
let midi: MidiFile = new MidiFile();
let gen: MidiFileGenerator = new MidiFileGenerator(score, null, new AlphaSynthMidiFileHandler(midi));
Expand Down
2 changes: 1 addition & 1 deletion test/audio/MidiFileGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { MetaDataEvent } from '@src/midi/MetaDataEvent';
describe('MidiFileGeneratorTest', () => {
const parseTex: (tex: string) => Score = (tex: string): Score => {
let importer: AlphaTexImporter = new AlphaTexImporter();
importer.init(TestPlatform.createStringReader(tex), new Settings());
importer.initFromString(tex, new Settings());
return importer.readScore();
};

Expand Down
3 changes: 1 addition & 2 deletions test/audio/MidiPlaybackController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Score } from '@src/model/Score';
import { Settings } from '@src/Settings';
import { Logger } from '@src/Logger';
import { GpImporterTestHelper } from '@test/importer/GpImporterTestHelper';
import { TestPlatform } from '@test/TestPlatform';

describe('MidiPlaybackControllerTest', () => {
const testRepeat: ((score: Score, expectedIndexes: number[]) => void) = (score: Score, expectedIndexes: number[]): void => {
Expand Down Expand Up @@ -60,7 +59,7 @@ describe('MidiPlaybackControllerTest', () => {
let tex: string =
'\\ro 1.3 2.3 3.3 4.3 | 5.3 6.3 7.3 8.3 | \\rc 2 1.3 2.3 3.3 4.3 | \\ro \\rc 3 1.3 2.3 3.3 4.3';
let importer: AlphaTexImporter = new AlphaTexImporter();
importer.init(TestPlatform.createStringReader(tex), new Settings());
importer.initFromString(tex, new Settings());
let score: Score = importer.readScore();
let playedBars: number[] = [];
let controller: MidiPlaybackController = new MidiPlaybackController(score);
Expand Down
2 changes: 1 addition & 1 deletion test/exporter/Gp7Exporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ describe('Gp7ExporterTest', () => {
`;

const importer = new AlphaTexImporter();
importer.init(TestPlatform.createStringReader(tex), new Settings());
importer.initFromString(tex, new Settings());
const expected = importer.readScore();
const exported = exportGp7(expected);

Expand Down
28 changes: 20 additions & 8 deletions test/importer/AlphaTexImporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ import { Tuning } from '@src/model/Tuning';
import { HarmonicsEffectInfo } from '@src/rendering/effects/HarmonicsEffectInfo';
import { ScoreRenderer } from '@src/rendering/ScoreRenderer';
import { Settings } from '@src/Settings';
import { TestPlatform } from '@test/TestPlatform';

describe('AlphaTexImporterTest', () => {
const parseTex: (tex:string) => Score = (tex: string): Score => {
const parseTex: (tex: string) => Score = (tex: string): Score => {
let importer: AlphaTexImporter = new AlphaTexImporter();
importer.init(TestPlatform.createStringReader(tex), new Settings());
importer.initFromString(tex, new Settings());
return importer.readScore();
};

Expand Down Expand Up @@ -856,19 +855,19 @@ describe('AlphaTexImporterTest', () => {
try {
parseTex('<xml>');
fail('Expected error');
} catch(e) {
if(!(e instanceof UnsupportedFormatError)) {
} catch (e) {
if (!(e instanceof UnsupportedFormatError)) {
fail(`Expected UnsupportedFormatError got ${e}`);
}
}
});

it('expect-invalid-format-other-text', () => {
try {
parseTex('This is not an alphaTex file');
fail('Expected error');
} catch(e) {
if(!(e instanceof UnsupportedFormatError)) {
} catch (e) {
if (!(e instanceof UnsupportedFormatError)) {
fail(`Expected UnsupportedFormatError got ${e}`);
}
}
Expand All @@ -891,4 +890,17 @@ describe('AlphaTexImporterTest', () => {
expect(score.tracks[0].staves[0].tuning.length).toEqual(0);
expect(score.tracks[0].staves[0].displayTranspositionPitch).toEqual(0);
});

it('multibyte-encoding', () => {
const multiByteChars = '爱你ÖÄÜ🎸🎵🎶';
const score = parseTex(`\\title "${multiByteChars}"
.
\\track "🎸"
\\lyrics "Test Lyrics 🤘"
(1.2 1.1).4 x.2.8 0.1 1.1 | 1.2 3.2 0.1 1.1`);

expect(score.title).toEqual(multiByteChars);
expect(score.tracks[0].name).toEqual("🎸");
expect(score.tracks[0].staves[0].bars[0].voices[0].beats[2].lyrics![0]).toEqual("🤘");
});
});

0 comments on commit 1f3f956

Please sign in to comment.