diff --git a/README.md b/README.md index 4fe207e..79311c9 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,164 @@ if (asserts.isTiedNote(noteVariation)) { } ``` +### End-to-end Example + +This example renders MusicXML for a single measure with an image of a single measure with a C/4 whole note. + +![image of a single measure with a C/4 whole note](https://github.com/user-attachments/assets/7480ec5e-2aac-4653-86e3-2717ecfca8c2) + +You can validate the MusicXML on https://vexml.dev. + +```ts +const musicXml = MusicXML.createPartwise(); + +musicXml + .getRoot() + .setPartList( + new elements.PartList({ + contents: [ + new Array(), + new elements.ScorePart({ + attributes: { id: 'P1' }, + contents: [ + null, // elements.Identification + new Array(), + new elements.PartName({ contents: ['Part 1'] }), + null, // elements.PartNameDisplay + null, // elements.PartAbbreviation + null, // elements.PartAbbreviationDisplay + new Array(), + new Array(), + new Array(), + new Array(), + ], + }), + new Array(), + ], + }) + ) + .setParts([ + new elements.PartPartwise({ + attributes: { id: 'P1' }, + }).setMeasures([ + new elements.MeasurePartwise({ + attributes: { number: '1' }, + contents: [ + [ + new elements.Attributes({ + attributes: { divisions: 1 }, + contents: [ + null, // elements.Footnote + null, // elements.Level + null, // elements.Divisions + new Array(), + new Array( + new elements.Time({ + contents: [ + [ + [ + [ + new elements.Beats({ + contents: ['4'], + }), + new elements.BeatType({ + contents: ['4'], + }), + ], + ], + null, + ], + ], + }) + ), + null, // elements.Staves + null, // elements.PartSymbol + null, // elements.Instruments + new Array(), + new Array(), + new Array(), + new Array(), + new Array(), + ], + }), + new elements.Note({ + contents: [ + [ + null, // elements.TiedNote + new elements.Pitch({ + contents: [ + new elements.Step({ + contents: ['C'], + }), + null, // elements.Alter + new elements.Octave({ + contents: [4], + }), + ], + }), + new elements.Duration({ + contents: [4], + }), + [], // elements.Tie, + ], + new Array(), + null, // elements.Footnote + null, // elements.Level + null, // elements.Voice + null, // elements.Type + new Array(), + null, // elements.Accidental + null, // elements.TimeModification + null, // elements.Stem + null, // elements.Notehead + null, // elements.NoteheadText + null, // elements.Staff + [], // elements.Beam + new Array(), + new Array(), + null, // elements.Play + null, // elements.Listen + ], + }), + ], + ], + }), + ]), + ]); + +console.log(musicXml.serialize()); +``` + +which logs the following MusicXML: + +```xml + + + + + Part 1 + + + + + + + + + + C + 4 + + 4 + + + + +``` + ## 💻 Development ### Prerequisites diff --git a/src/MusicXML.test.ts b/src/MusicXML.test.ts index 68de667..eb6c19f 100644 --- a/src/MusicXML.test.ts +++ b/src/MusicXML.test.ts @@ -73,6 +73,150 @@ describe('MusicXML', () => { expect(note.getStaff()).not.toBeNull(); expect(note.getStaff()!.getValue()).toBe(4); }); + + it('creates a document with a single measure and a single note', () => { + const musicXml = MusicXML.createPartwise(); + + musicXml + .getRoot() + .setPartList( + new elements.PartList({ + contents: [ + new Array(), + new elements.ScorePart({ + attributes: { id: 'P1' }, + contents: [ + null, // elements.Identification + new Array(), + new elements.PartName({ contents: ['Part 1'] }), + null, // elements.PartNameDisplay + null, // elements.PartAbbreviation + null, // elements.PartAbbreviationDisplay + new Array(), + new Array(), + new Array(), + new Array(), + ], + }), + new Array(), + ], + }) + ) + .setParts([ + new elements.PartPartwise({ + attributes: { id: 'P1' }, + }).setMeasures([ + new elements.MeasurePartwise({ + attributes: { number: '1' }, + contents: [ + [ + new elements.Attributes({ + attributes: { divisions: 1 }, + contents: [ + null, // elements.Footnote + null, // elements.Level + null, // elements.Divisions + new Array(), + new Array( + new elements.Time({ + contents: [ + [ + [ + [ + new elements.Beats({ + contents: ['4'], + }), + new elements.BeatType({ + contents: ['4'], + }), + ], + ], + null, + ], + ], + }) + ), + null, // elements.Staves + null, // elements.PartSymbol + null, // elements.Instruments + new Array(), + new Array(), + new Array(), + new Array(), + new Array(), + ], + }), + new elements.Note({ + contents: [ + [ + null, // elements.TiedNote + new elements.Pitch({ + contents: [ + new elements.Step({ + contents: ['C'], + }), + null, // elements.Alter + new elements.Octave({ + contents: [4], + }), + ], + }), + new elements.Duration({ + contents: [4], + }), + [], // elements.Tie, + ], + new Array(), + null, // elements.Footnote + null, // elements.Level + null, // elements.Voice + null, // elements.Type + new Array(), + null, // elements.Accidental + null, // elements.TimeModification + null, // elements.Stem + null, // elements.Notehead + null, // elements.NoteheadText + null, // elements.Staff + [], // elements.Beam + new Array(), + new Array(), + null, // elements.Play + null, // elements.Listen + ], + }), + ], + ], + }), + ]), + ]); + + expect(musicXml.serialize()).toBe(` + + + + Part 1 + + + + + + + + + + C + 4 + + 4 + + + +`); + }); }); describe('parse', () => {