├── .npmignore ├── .gitignore ├── .dockerignore ├── src ├── examples │ ├── index.ts │ ├── mostly_invalid.xml │ └── loadExample.ts ├── lib │ ├── resolutions │ │ ├── index.ts │ │ ├── resolutions.ts │ │ └── types.ts │ ├── schema │ │ ├── index.ts │ │ └── schema.ts │ ├── operations │ │ └── index.ts │ ├── util │ │ ├── index.ts │ │ └── types.ts │ ├── dataTypes │ │ ├── bendShape.ts │ │ ├── cancelLocation.ts │ │ ├── circularArrow.ts │ │ ├── clefSign.ts │ │ ├── breathMarkValue.ts │ │ ├── caesuraValue.ts │ │ ├── anyURI.ts │ │ ├── percent.ts │ │ ├── date.ts │ │ ├── milliseconds.ts │ │ ├── onOff.ts │ │ ├── token.ts │ │ ├── integer.ts │ │ ├── string.ts │ │ ├── decimal.ts │ │ ├── nmtoken.ts │ │ ├── stemValue.ts │ │ ├── lineShape.ts │ │ ├── nonNegativeDecimal.ts │ │ ├── midi16.ts │ │ ├── wedgeType.ts │ │ ├── id.ts │ │ ├── numberOfLines.ts │ │ ├── rightLeftMiddle.ts │ │ ├── lineType.ts │ │ ├── marginType.ts │ │ ├── fan.ts │ │ ├── aboveBelow.ts │ │ ├── octave.ts │ │ ├── positiveInteger.ts │ │ ├── topBottom.ts │ │ ├── trillStep.ts │ │ ├── leftCenterRight.ts │ │ ├── leftRight.ts │ │ ├── startStopDiscontinue.ts │ │ ├── nonNegativeInteger.ts │ │ ├── rotationDegrees.ts │ │ ├── startNote.ts │ │ ├── tremoloType.ts │ │ ├── yesNoNumber.ts │ │ ├── lineLength.ts │ │ ├── noteSizeType.ts │ │ ├── positiveDivisions.ts │ │ ├── staffLine.ts │ │ ├── harmonyType.ts │ │ ├── positiveIntegerOrEmpty.ts │ │ ├── stringNumber.ts │ │ ├── symbolSize.ts │ │ ├── trillBeats.ts │ │ ├── twoNoteTurn.ts │ │ ├── staffNumber.ts │ │ ├── uprightInverted.ts │ │ ├── tremoloMarks.ts │ │ ├── upDown.ts │ │ ├── yesNo.ts │ │ ├── idref.ts │ │ ├── lineEnd.ts │ │ ├── numeralValue.ts │ │ ├── pedalType.ts │ │ ├── overUnder.ts │ │ ├── showFrets.ts │ │ ├── yyyyMmDd.ts │ │ ├── fontStyle.ts │ │ ├── numberOrNormal.ts │ │ ├── valign.ts │ │ ├── fontWeight.ts │ │ ├── commaSeparatedText.ts │ │ ├── principalVoiceSymbol.ts │ │ ├── staffType.ts │ │ ├── step.ts │ │ ├── systemRelation.ts │ │ ├── holeClosedLocation.ts │ │ ├── millimeters.ts │ │ ├── tapHand.ts │ │ ├── holeClosedValue.ts │ │ ├── showTuplet.ts │ │ ├── valignImage.ts │ │ ├── divisions.ts │ │ ├── harmonClosedLocation.ts │ │ ├── backwardFoward.ts │ │ ├── degreeSymbolValue.ts │ │ ├── groupBarlineValue.ts │ │ ├── harmonClosedValue.ts │ │ ├── midi128.ts │ │ ├── swingTypeValue.ts │ │ ├── accordionMiddle.ts │ │ ├── glassValue.ts │ │ ├── fifths.ts │ │ ├── midi16384.ts │ │ ├── smuflCodaGlyphName.ts │ │ ├── staffDivideSymbol.ts │ │ ├── upDownStopContinue.ts │ │ ├── smuflSegnoGlyphName.ts │ │ ├── stickMaterial.ts │ │ ├── syncType.ts │ │ ├── semitones.ts │ │ ├── smuflLyricsGlyphName.ts │ │ ├── tipDirection.ts │ │ ├── semiPitched.ts │ │ ├── smuflPictogramGlyphName.ts │ │ ├── stickLocation.ts │ │ ├── enclosureShape.ts │ │ ├── groupSymbolValue.ts │ │ ├── systemRelationNumber.ts │ │ ├── timeRelation.ts │ │ ├── beamValue.ts │ │ ├── measureNumberingValue.ts │ │ ├── beamLevel.ts │ │ ├── degreeTypeValue.ts │ │ ├── smuflGlyphName.ts │ │ ├── fontSize.ts │ │ ├── textDirection.ts │ │ ├── staffLinePosition.ts │ │ ├── syllabic.ts │ │ ├── measureText.ts │ │ ├── cssFontSize.ts │ │ ├── timeOnly.ts │ │ ├── winged.ts │ │ ├── startStopSingle.ts │ │ ├── endingNumber.ts │ │ ├── smuflAccidentalGlyphName.ts │ │ ├── fermataShape.ts │ │ ├── harmonyArrangement.ts │ │ ├── smuflWavyLineGlyphName.ts │ │ ├── distanceType.ts │ │ ├── fontFamily.ts │ │ ├── xml.ts │ │ ├── pitchedValue.ts │ │ ├── stickType.ts │ │ ├── handbellValue.ts │ │ ├── woodValue.ts │ │ ├── mode.ts │ │ ├── arrowStyle.ts │ │ ├── color.ts │ │ └── arrowDirection.ts │ ├── xml │ │ ├── getDefaultDeclaration.ts │ │ ├── index.ts │ │ └── types.ts │ └── elements │ │ ├── F.ts │ │ ├── P.ts │ │ ├── N.ts │ │ ├── Ff.ts │ │ ├── Fp.ts │ │ ├── Fz.ts │ │ ├── Mf.ts │ │ ├── Mp.ts │ │ ├── Pf.ts │ │ ├── Pp.ts │ │ ├── Rf.ts │ │ ├── Sf.ts │ │ ├── Fff.ts │ │ ├── Ffff.ts │ │ ├── Ppp.ts │ │ ├── Pppp.ts │ │ ├── Sfz.ts │ │ ├── Fffff.ts │ │ ├── Humming.ts │ │ ├── Ppppp.ts │ │ ├── Rfz.ts │ │ ├── Sffz.ts │ │ ├── Sfp.ts │ │ ├── Ffffff.ts │ │ ├── Laughing.ts │ │ ├── Pppppp.ts │ │ ├── Sfzp.ts │ │ ├── Sfpp.ts │ │ ├── EncodingDate.ts │ │ ├── Artificial.ts │ │ ├── NormalDot.ts │ │ ├── PreBend.ts │ │ ├── Software.ts │ │ ├── Solo.ts │ │ ├── Straight.ts │ │ ├── MetronomeDot.ts │ │ ├── Sign.ts │ │ ├── Natural.ts │ │ ├── SlashDot.ts │ │ ├── Arrowhead.ts │ │ ├── BeatUnitDot.ts │ │ ├── GroupTime.ts │ │ ├── SoundingPitch.ts │ │ ├── BasePitch.ts │ │ ├── EndLine.ts │ │ ├── WorkNumber.ts │ │ ├── Mute.ts │ │ ├── Octave.ts │ │ ├── PedalStep.ts │ │ ├── Step.ts │ │ ├── SwingStyle.ts │ │ ├── WorkTitle.ts │ │ ├── MidiBank.ts │ │ ├── TouchingPitch.ts │ │ ├── Beats.ts │ │ ├── EndParagraph.ts │ │ ├── HoleShape.ts │ │ ├── MetronomeArrows.ts │ │ ├── MidiName.ts │ │ ├── PedalAlter.ts │ │ ├── ArrowStyle.ts │ │ ├── MidiChannel.ts │ │ ├── MidiProgram.ts │ │ ├── SemiPitched.ts │ │ ├── StaffType.ts │ │ ├── VirtualLibrary.ts │ │ ├── VirtualName.ts │ │ ├── BeatType.ts │ │ ├── BeatUnit.ts │ │ ├── AccordionLow.ts │ │ ├── MovementNumber.ts │ │ ├── PageWidth.ts │ │ ├── StickMaterial.ts │ │ ├── AccordionHigh.ts │ │ ├── NumeralMode.ts │ │ ├── PageHeight.ts │ │ ├── MetronomeType.ts │ │ ├── SlashType.ts │ │ ├── Ipa.ts │ │ ├── TopMargin.ts │ │ ├── HoleType.ts │ │ ├── MovementTitle.ts │ │ ├── First.ts │ │ ├── PlayerName.ts │ │ ├── Second.ts │ │ ├── ArrowDirection.ts │ │ ├── PedalTuning.ts │ │ ├── BottomMargin.ts │ │ ├── StickType.ts │ │ ├── CircularArrow.ts │ │ ├── FrameFrets.ts │ │ ├── MeasureLayout.ts │ │ ├── RightMargin.ts │ │ ├── Alter.ts │ │ ├── Millimeters.ts │ │ ├── Mode.ts │ │ ├── NumeralFifths.ts │ │ ├── FrameStrings.ts │ │ ├── LeftMargin.ts │ │ ├── TuningStep.ts │ │ ├── InstrumentName.ts │ │ ├── Pitch.ts │ │ ├── TuningAlter.ts │ │ ├── Cue.ts │ │ ├── StickLocation.ts │ │ ├── TuningOctave.ts │ │ ├── SwingType.ts │ │ ├── TimeRelation.ts │ │ ├── Voice.ts │ │ ├── KeyStep.ts │ │ ├── Source.ts │ │ ├── SystemMargins.ts │ │ ├── Timpani.ts │ │ ├── Syllabic.ts │ │ ├── EncodingDescription.ts │ │ ├── BarStyle.ts │ │ ├── Group.ts │ │ ├── InstrumentAbbreviation.ts │ │ ├── Staff.ts │ │ ├── ActualNotes.ts │ │ ├── ClefOctaveChange.ts │ │ ├── NormalNotes.ts │ │ ├── StaffDistance.ts │ │ ├── Volume.ts │ │ ├── Wood.ts │ │ ├── Metal.ts │ │ ├── TopSystemDistance.ts │ │ ├── Capo.ts │ │ ├── Effect.ts │ │ ├── GroupBarline.ts │ │ ├── OtherPlay.ts │ │ ├── SystemDistance.ts │ │ ├── AccordionMiddle.ts │ │ ├── Instruments.ts │ │ ├── Membrane.ts │ │ ├── VirtualInstrument.ts │ │ ├── SenzaMisura.ts │ │ ├── Distance.ts │ │ ├── Fifths.ts │ │ ├── Tenths.ts │ │ ├── LineWidth.ts │ │ ├── Chromatic.ts │ │ ├── Work.ts │ │ ├── HoleClosed.ts │ │ ├── NormalType.ts │ │ ├── MetronomeRelation.ts │ │ ├── ExceptVoice.ts │ │ ├── StaffLines.ts │ │ ├── Ensemble.ts │ │ ├── Pan.ts │ │ ├── Staves.ts │ │ ├── Beater.ts │ │ ├── GroupLink.ts │ │ ├── InstrumentSound.ts │ │ ├── MidiUnpitched.ts │ │ ├── Elevation.ts │ │ ├── Miscellaneous.ts │ │ ├── Glass.ts │ │ ├── HarmonClosed.ts │ │ ├── Encoder.ts │ │ ├── KeyAlter.ts │ │ ├── Root.ts │ │ ├── Numeral.ts │ │ ├── Player.ts │ │ ├── FrameNote.ts │ │ ├── MiscellaneousField.ts │ │ ├── OctaveChange.ts │ │ ├── Feature.ts │ │ ├── CreditType.ts │ │ ├── DisplayStep.ts │ │ ├── MeasureDistance.ts │ │ ├── Diatonic.ts │ │ ├── OtherAppearance.ts │ │ ├── Pitched.ts │ │ ├── DisplayOctave.ts │ │ ├── Scordatura.ts │ │ ├── Line.ts │ │ ├── Release.ts │ │ ├── Figure.ts │ │ └── Accord.ts ├── index.ts ├── testing │ ├── jest.d.ts │ └── jest.setup.ts ├── generated │ └── asserts.test.ts ├── compatibility │ ├── w3.test.ts │ ├── guitarPro.test.ts │ ├── lilypond.test.ts │ ├── osmd.test.ts │ └── testCompatibility.ts └── MusicXMLError.ts ├── .husky └── pre-commit ├── xmlvalidator ├── go.mod ├── go.sum └── Dockerfile ├── docs ├── .nojekyll └── assets │ └── highlight.css ├── .prettierrc.json ├── babel.config.json ├── typedoc.json ├── Dockerfile ├── tsconfig.build.json ├── .github └── workflows │ └── test.yml ├── .vscode ├── settings.json └── launch.json ├── tsconfig.docs.json ├── tsconfig.json ├── docker-compose.yml └── .eslintrc.json /.npmignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | .bin/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log 3 | dist -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .husky 2 | .vscode 3 | node_modules 4 | xmlvalidator -------------------------------------------------------------------------------- /src/examples/index.ts: -------------------------------------------------------------------------------- 1 | export * from './loadExample'; 2 | export * from './manifest'; 3 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /src/lib/resolutions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './resolutions'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /src/lib/schema/index.ts: -------------------------------------------------------------------------------- 1 | export * from './schema'; 2 | export * from './t'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /src/lib/operations/index.ts: -------------------------------------------------------------------------------- 1 | export * from './merge'; 2 | export * from './validate'; 3 | export * from './zero'; 4 | -------------------------------------------------------------------------------- /src/lib/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Cursor'; 2 | export * from './typeGuards'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /xmlvalidator/go.mod: -------------------------------------------------------------------------------- 1 | module musicxmlvalidator 2 | 3 | go 1.17 4 | require github.com/terminalstatic/go-xsd-validate v0.1.4 -------------------------------------------------------------------------------- /src/lib/util/types.ts: -------------------------------------------------------------------------------- 1 | export type AnyFunction = (...args: any[]) => any; 2 | 3 | export type Ctor = { 4 | new (...args: any[]): T; 5 | }; 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * as asserts from './generated/asserts'; 2 | export * as elements from './generated/elements'; 3 | export * from './MusicXML'; 4 | -------------------------------------------------------------------------------- /src/lib/dataTypes/bendShape.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const bendShape = () => t.choices('angled' as const, 'curved' as const); 3 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /src/testing/jest.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace jest { 2 | interface Matchers { 3 | toBeValidMusicXML(): Promise; 4 | toEqualXML(xml: string): R; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/dataTypes/cancelLocation.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const cancelLocation = () => t.choices('left' as const, 'right' as const, 'beforeBarline' as const); 3 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5", 4 | "bracketSpacing": true, 5 | "arrowParens": "always", 6 | "semi": true, 7 | "printWidth": 120 8 | } 9 | -------------------------------------------------------------------------------- /src/lib/xml/getDefaultDeclaration.ts: -------------------------------------------------------------------------------- 1 | import { Declaration } from './types'; 2 | 3 | export const getDefaultDeclaration = (): Declaration => ({ 4 | attributes: { version: '1.0', encoding: 'UTF-8' }, 5 | }); 6 | -------------------------------------------------------------------------------- /src/lib/xml/index.ts: -------------------------------------------------------------------------------- 1 | export * from './conform'; 2 | export * from './getDefaultDeclaration'; 3 | export * from './parse'; 4 | export * from './serialize'; 5 | export * from './toString'; 6 | export * from './types'; 7 | -------------------------------------------------------------------------------- /src/testing/jest.setup.ts: -------------------------------------------------------------------------------- 1 | import 'jest-extended'; 2 | import * as matchers from './matchers'; 3 | 4 | expect.extend({ 5 | toBeValidMusicXML: matchers.toBeValidMusicXML, 6 | toEqualXML: matchers.toEqualXML, 7 | }); 8 | -------------------------------------------------------------------------------- /xmlvalidator/go.sum: -------------------------------------------------------------------------------- 1 | github.com/terminalstatic/go-xsd-validate v0.1.4 h1:fL4kJdcFCmDaIpy9kXZSv/NapJsJUC8RDO6P8TdOSQk= 2 | github.com/terminalstatic/go-xsd-validate v0.1.4/go.mod h1:e6HmA0iGH3en7FFUPH9iE6EtwbAw6oWWH4nn41hNozM= -------------------------------------------------------------------------------- /src/lib/dataTypes/circularArrow.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const circularArrow = () => { 3 | return t.label({ label: 'circular-arrow', value: t.choices('anticlockwise' as const, 'clockwise' as const) }); 4 | }; 5 | -------------------------------------------------------------------------------- /src/generated/asserts.test.ts: -------------------------------------------------------------------------------- 1 | import * as asserts from './asserts'; 2 | 3 | describe('asserts', () => { 4 | it.each(Object.values(asserts))('%p refutes unrelated values', (assert) => { 5 | expect(assert(Symbol())).toBeFalse(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-typescript"], 3 | "plugins": [["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties"]] 4 | } 5 | -------------------------------------------------------------------------------- /src/lib/dataTypes/clefSign.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const clefSign = () => { 3 | return t.label({ 4 | label: 'clef-sign', 5 | value: t.choices(...(['G', 'F', 'C', 'percussion', 'TAB', 'jianpu', 'none'] as const)), 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/breathMarkValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const breathMarkValue = () => { 3 | return t.label({ 4 | label: 'breath-mark-value', 5 | value: t.choices(...(['comma', 'tick', 'upbow', 'salzedo', ''] as const)), 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/caesuraValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const caesuraValue = () => { 3 | return t.label({ 4 | label: 'caesura-value', 5 | value: t.choices(...(['normal', 'thick', 'short', 'curved', 'single', ''] as const)), 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "entryPoints": [ 3 | "src/index.ts" 4 | ], 5 | "out": "./docs", 6 | "entryPointStrategy": "expand", 7 | "exclude": [ 8 | "src/test/**/*.ts", 9 | ], 10 | "readme": "none", 11 | "plugin": [], 12 | "visibilityFilters": {} 13 | } -------------------------------------------------------------------------------- /src/lib/dataTypes/anyURI.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the definition in the W3C XML Schema standard. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-anyURI/} 6 | */ 7 | export const anyURI = () => t.string(); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/percent.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The percent type specifies a percentage from 0 to 100. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/percent/} 6 | */ 7 | export const percent = () => t.float({ min: 0, max: 100 }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/date.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#date) 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-date/} 6 | */ 7 | export const date = t.date; 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18.0.0 2 | 3 | WORKDIR /musicxml 4 | 5 | # install dependencies 6 | COPY package.json . 7 | COPY yarn.lock . 8 | RUN yarn 9 | 10 | # copy the rest of the files for tests 11 | COPY babel.config.json . 12 | COPY tsconfig.json . 13 | COPY src src 14 | 15 | CMD [ "yarn", "jest" ] 16 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*"], 4 | "exclude": [ 5 | "**/*.test.ts", 6 | "src/compatibility", 7 | "src/examples", 8 | "src/testing", 9 | "src/scripts", 10 | "src/lib/dataTypes", 11 | "src/lib/elements" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/lib/dataTypes/milliseconds.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The milliseconds type represents an integral number of milliseconds. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/milliseconds/} 6 | */ 7 | export const milliseconds = () => t.int({ min: 0 }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/onOff.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The on-off type is used for notation elements such as string mutes. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/on-off/} 6 | */ 7 | export const onOff = () => t.choices('on' as const, 'off' as const); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/token.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#token) 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-token/} 6 | */ 7 | export const token = () => t.string(); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/integer.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#integer) 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-integer/} 6 | */ 7 | export const integer = () => t.int(); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/string.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#string) 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-string/} 6 | */ 7 | export const string = () => t.string(); 8 | -------------------------------------------------------------------------------- /src/compatibility/w3.test.ts: -------------------------------------------------------------------------------- 1 | import { EXAMPLE_SUITES } from '../examples'; 2 | import { testCompatibility } from './testCompatibility'; 3 | 4 | describe('w3', () => { 5 | // Test that the examples from https://www.w3.org/2021/06/musicxml40/ are compatible with this library. 6 | testCompatibility(EXAMPLE_SUITES.W3); 7 | }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/decimal.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#decimal) 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-decimal/} 6 | */ 7 | export const decimal = () => t.float(); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/nmtoken.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the 4 | * [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#NMTOKEN) 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-NMTOKEN/} 7 | */ 8 | export const nmtoken = () => t.string(); 9 | -------------------------------------------------------------------------------- /src/compatibility/guitarPro.test.ts: -------------------------------------------------------------------------------- 1 | import { EXAMPLE_SUITES } from '../examples'; 2 | import { testCompatibility } from './testCompatibility'; 3 | 4 | describe('guitarPro', () => { 5 | // Test that MusicXML documents exported from GuitarPro are compatible with this library. 6 | testCompatibility(EXAMPLE_SUITES.GUITAR_PRO); 7 | }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/stemValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The stem-value type represents the notated stem direction. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/stem-value/} 6 | */ 7 | export const stemValue = () => t.choices(...(['none', 'down', 'up', 'double'] as const)); 8 | -------------------------------------------------------------------------------- /src/compatibility/lilypond.test.ts: -------------------------------------------------------------------------------- 1 | import { EXAMPLE_SUITES } from '../examples'; 2 | import { testCompatibility } from './testCompatibility'; 3 | 4 | describe('lilypond', () => { 5 | // MusicXML examples from http://lilypond.org/doc/v2.20/input/regression/musicxml/collated-files#top 6 | testCompatibility(EXAMPLE_SUITES.LILYPOND); 7 | }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/lineShape.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The line-shape type distinguishes between straight and curved lines. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/line-shape/} 6 | */ 7 | export const lineShape = () => t.choices('straight' as const, 'curved' as const); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/nonNegativeDecimal.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The non-negative-decimal type specifies a non-negative decimal value. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/non-negative-decimal/} 6 | */ 7 | export const nonNegativeDecimal = () => t.float({ min: 0 }); 8 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | test: 10 | name: run tests 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: checkout 14 | uses: actions/checkout@v4 15 | - name: test 16 | run: yarn test --ci 17 | -------------------------------------------------------------------------------- /src/lib/dataTypes/midi16.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The midi-16 type is used to express MIDI 1.0 values that range from 1 to 16. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/midi-16/} 6 | */ 7 | export const midi16 = () => t.label({ label: 'midi16', value: t.int({ min: 1, max: 16 }) }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/wedgeType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The wedge-type type is used to specify `` types. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/wedge-type/} 6 | */ 7 | export const wedgeType = () => t.choices(...(['crescendo', 'diminuendo', 'stop', 'continue'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/id.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#ID) 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-ID/} 6 | */ 7 | export const id = () => t.regex({ pattern: /[A-Za-z_][A-Za-z0-9.-_]*/, zero: '_' }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/numberOfLines.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The number-of-lines type is used to specify the number of lines in text decoration attributes. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/number-of-lines/} 6 | */ 7 | export const numberOfLines = () => t.int({ min: 0, max: 3 }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/rightLeftMiddle.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The right-left-middle type is used to specify barline location. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/right-left-middle/} 6 | */ 7 | export const rightLeftMiddle = () => t.choices(...(['right', 'left', 'middle'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/lineType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The line-type type distinguishes between solid, dashed, dotted, and wavy lines. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/line-type/} 6 | */ 7 | export const lineType = () => t.choices(...(['dashed', 'dotted', 'solid', 'wavy'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/marginType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The margin-type type specifies whether margins apply to even page, odd pages, or both. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/margin-type/} 6 | */ 7 | export const marginType = () => t.choices(...(['both', 'even', 'odd'] as const)); 8 | -------------------------------------------------------------------------------- /src/compatibility/osmd.test.ts: -------------------------------------------------------------------------------- 1 | import { EXAMPLE_SUITES } from '../examples'; 2 | import { testCompatibility } from './testCompatibility'; 3 | 4 | describe('osmd', () => { 5 | // Test that the examples in https://github.com/opensheetmusicdisplay/opensheetmusicdisplay are compatible with this 6 | // library. 7 | testCompatibility(EXAMPLE_SUITES.OSMD); 8 | }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/fan.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The fan type represents the type of beam fanning present on a note, used to represent accelerandos and ritardandos. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/fan/} 6 | */ 7 | export const fan = () => t.choices(...(['accel', 'none', 'rit'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/elements/F.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a forte dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/f/} 11 | */ 12 | export const F = schema('f', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/P.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `

` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `

` element represents a piano dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/p/} 11 | */ 12 | export const P = schema('p', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/examples/mostly_invalid.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | baz 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/aboveBelow.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The above-below type is used to indicate whether one element appears above or below another element. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/above-below/} 6 | */ 7 | export const aboveBelow = () => t.choices('above' as const, 'below' as const); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/octave.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * Octaves are represented by the numbers 0 to 9, where 4 indicates the octave started by middle C. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/octave/} 6 | */ 7 | export const octave = () => t.label({ label: 'octave', value: t.int({ min: 0, max: 9 }) }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/positiveInteger.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the 4 | * [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#positiveInteger) 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-positiveInteger/} 7 | */ 8 | export const positiveInteger = () => t.int({ min: 1 }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/topBottom.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The top-bottom type is used to indicate the top or bottom part of a vertical shape like non-arpeggiate. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/top-bottom/} 6 | */ 7 | export const topBottom = () => t.choices('top' as const, 'bottom' as const); 8 | -------------------------------------------------------------------------------- /src/lib/elements/N.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a niente dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/n/} 11 | */ 12 | export const N = schema('n', {}, [] as const); 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "typescript.preferences.importModuleSpecifier": "relative", 4 | "javascript.preferences.importModuleSpecifier": "relative", 5 | "editor.formatOnSave": true, 6 | "editor.codeActionsOnSave": { 7 | "source.fixAll.eslint": true 8 | }, 9 | "editor.rulers": [120] 10 | } 11 | -------------------------------------------------------------------------------- /src/lib/dataTypes/trillStep.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The trill-step type describes the alternating note of trills and mordents for playback, relative to the current note. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/trill-step/} 6 | */ 7 | export const trillStep = () => t.choices('unison', 'half', 'whole'); 8 | -------------------------------------------------------------------------------- /src/MusicXMLError.ts: -------------------------------------------------------------------------------- 1 | export class MusicXMLError extends Error { 2 | constructor(message: string, ctx: Record = {}) { 3 | super( 4 | `message:\n\t${message}\n\ncontext:\n\t${ 5 | Object.entries(ctx) 6 | .map(([k, v]) => `${k}=${JSON.stringify(v)}`) 7 | .join('\n\t') || '(None)' 8 | }` 9 | ); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/lib/dataTypes/leftCenterRight.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The left-center-right type is used to define horizontal alignment and text justification. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/left-center-right/} 6 | */ 7 | export const leftCenterRight = () => t.choices(...(['left', 'center', 'right'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/leftRight.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The left-right type is used to indicate whether one element appears to the left or the right of another element. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/left-right/} 6 | */ 7 | export const leftRight = () => t.choices('left' as const, 'right' as const); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/startStopDiscontinue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The start-stop-discontinue type is used to specify `` types. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/start-stop-discontinue/} 6 | */ 7 | export const startStopDiscontinue = () => t.choices(...(['start', 'stop', 'discontinue'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/elements/Ff.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a fortissimo dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/ff/} 11 | */ 12 | export const Ff = schema('ff', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Fp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a forte piano dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/fp/} 11 | */ 12 | export const Fp = schema('fp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Fz.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a forzando fz dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/fz/} 11 | */ 12 | export const Fz = schema('fz', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Mf.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a mezzo forte dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/mf/} 11 | */ 12 | export const Mf = schema('mf', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Mp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a mezzo piano dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/mp/} 11 | */ 12 | export const Mp = schema('mp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Pf.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a piano forte dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/pf/} 11 | */ 12 | export const Pf = schema('pf', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Pp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a pianissimo dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/pp/} 11 | */ 12 | export const Pp = schema('pp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Rf.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a rinforzando rf dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/rf/} 11 | */ 12 | export const Rf = schema('rf', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Sf.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a sforzando sf dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sf/} 11 | */ 12 | export const Sf = schema('sf', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/nonNegativeInteger.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the 4 | * [definition in the W3C XML Schema standard.](https://www.w3.org/TR/xmlschema-2/#nonNegativeInteger) 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-nonNegativeInteger/} 7 | */ 8 | export const nonNegativeInteger = () => t.int({ min: 0 }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/rotationDegrees.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The rotation-degrees type specifies rotation, pan, and elevation values in degrees. Values range from -180 to 180. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/rotation-degrees/} 6 | */ 7 | export const rotationDegrees = () => t.float({ min: -180, max: 180 }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/startNote.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The start-note type describes the starting note of trills and mordents for playback, relative to the current note. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/start-note/} 6 | */ 7 | export const startNote = () => t.choices(...(['below', 'main', 'upper'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/tremoloType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The tremolo-type is used to distinguish double-note, single-note, and unmeasured tremolos. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/tremolo-type/} 6 | */ 7 | export const tremoloType = () => t.choices(...(['start', 'stop', 'single', 'unmeasured'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/yesNoNumber.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The yes-no-number type is used for attributes that can be either boolean or numeric values. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/yes-no-number/} 6 | */ 7 | export const yesNoNumber = () => t.choices('no' as const, 'yes' as const, 0 as const, 1 as const); 8 | -------------------------------------------------------------------------------- /src/lib/elements/Fff.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a triple forte dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/fff/} 11 | */ 12 | export const Fff = schema('fff', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Ffff.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents an ffff dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/ffff/} 11 | */ 12 | export const Ffff = schema('ffff', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Ppp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a triple piano dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/ppp/} 11 | */ 12 | export const Ppp = schema('ppp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Pppp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a pppp dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/pppp/} 11 | */ 12 | export const Pppp = schema('pppp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Sfz.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a sforzando sfz dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sfz/} 11 | */ 12 | export const Sfz = schema('sfz', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/lineLength.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The line-length type distinguishes between different line lengths for doit, falloff, plop, and scoop articulations. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/line-length/} 6 | */ 7 | export const lineLength = () => t.choices(...(['short', 'medium', 'long'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/noteSizeType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The note-size-type type indicates the type of note size being defined by a `` element. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/note-size-type/} 6 | */ 7 | export const noteSizeType = () => t.choices(...(['cue', 'grace', 'grace-cue', 'large'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/positiveDivisions.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The positive-divisions type restricts divisions values to positive numbers. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/positive-divisions/} 6 | */ 7 | export const positiveDivisions = () => t.label({ label: 'positive-divisions', value: t.float({ min: 1 }) }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/staffLine.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The staff-line type indicates the line on a given staff. Staff lines are numbered from bottom to top, with 1 being 4 | * the bottom line on a staff. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/staff-line/} 7 | */ 8 | export const staffLine = () => t.int({ min: 1 }); 9 | -------------------------------------------------------------------------------- /src/lib/elements/Fffff.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents an fffff dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/fffff/} 11 | */ 12 | export const Fffff = schema('fffff', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Humming.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a humming voice. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/humming/} 11 | */ 12 | export const Humming = schema('humming', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Ppppp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a ppppp dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/ppppp/} 11 | */ 12 | export const Ppppp = schema('ppppp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Rfz.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a rinforzando rfz dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/rfz/} 11 | */ 12 | export const Rfz = schema('rfz', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/harmonyType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The harmony-type type differentiates different types of harmonies when alternate harmonies are possible. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/harmony-type/} 6 | */ 7 | export const harmonyType = () => t.choices(...(['alternate', 'explicit', 'implied'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/positiveIntegerOrEmpty.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The positive-integer-or-empty values can be either a positive integer or an empty string. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/positive-integer-or-empty/} 6 | */ 7 | export const positiveIntegerOrEmpty = () => t.choices('' as const, t.int({ min: 1 })); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/stringNumber.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The string-number type indicates a string number. Strings are numbered from high to low, with 1 being the highest 4 | * pitched full-length string. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/string-number/} 7 | */ 8 | export const stringNumber = () => t.int({ min: 1 }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/symbolSize.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The symbol-size type is used to distinguish between full, cue sized, grace cue sized, and oversized symbols. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/symbol-size/} 6 | */ 7 | export const symbolSize = () => t.choices(...(['cue', 'full', 'grace-cue', 'large'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/trillBeats.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The trill-beats type specifies the beats used in a trill-sound or bend-sound attribute group. It is a decimal value 4 | * with a minimum value of 2. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/trill-beats/} 7 | */ 8 | export const trillBeats = () => t.float({ min: 2 }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/twoNoteTurn.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The two-note-turn type describes the ending notes of trills and mordents for playback, relative to the current note. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/two-note-turn/} 6 | */ 7 | export const twoNoteTurn = () => t.choices(...(['none', 'whole', 'half'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/elements/Sffz.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a sforzando sffz dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sffz/} 11 | */ 12 | export const Sffz = schema('sffz', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Sfp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a sforzando piano sfp dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sfp/} 11 | */ 12 | export const Sfp = schema('sfp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/resolutions/resolutions.ts: -------------------------------------------------------------------------------- 1 | import { NoneResolution, ResolvedResolution, ZeroResolution } from './types'; 2 | 3 | export const resolved = (value: T): ResolvedResolution => ({ type: 'resolved', value }); 4 | 5 | export const zero = (value: T): ZeroResolution => ({ type: 'zero', value }); 6 | 7 | export const none = (): NoneResolution => ({ type: 'none', value: undefined }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/staffNumber.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The staff-number type indicates staff numbers within a multi-staff part. Staves are numbered from top to bottom, with 4 | * 1 being the top staff on a part. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/staff-number/} 7 | */ 8 | export const staffNumber = () => t.int({ min: 1 }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/uprightInverted.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The upright-inverted type describes the appearance of a fermata element. The value is upright if not specified. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/upright-inverted/} 6 | */ 7 | export const uprightInverted = () => t.choices('upright' as const, 'inverted' as const); 8 | -------------------------------------------------------------------------------- /src/lib/elements/Ffffff.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents an ffffff dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/ffffff/} 11 | */ 12 | export const Ffffff = schema('ffffff', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Laughing.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a laughing voice. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/laughing/} 11 | */ 12 | export const Laughing = schema('laughing', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Pppppp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a pppppp dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/pppppp/} 11 | */ 12 | export const Pppppp = schema('pppppp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Sfzp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a sforzando piano sfzp dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sfzp/} 11 | */ 12 | export const Sfzp = schema('sfzp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /tsconfig.docs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "lib": ["es2017"], 5 | "types": [] 6 | }, 7 | "include": ["src/**/*"], 8 | "exclude": [ 9 | "**/*.test.ts", 10 | "src/compatibility", 11 | "src/examples", 12 | "src/testing", 13 | "src/scripts", 14 | "src/lib/dataTypes", 15 | "src/lib/elements" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/examples/loadExample.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | import * as path from 'path'; 3 | import { EXAMPLES } from '../examples'; 4 | 5 | export type Example = typeof EXAMPLES[keyof typeof EXAMPLES]; 6 | 7 | export const loadExample = (example: Example): string => { 8 | const fileName = path.join(__dirname, '..', 'examples', example); 9 | return fs.readFileSync(fileName, 'utf-8'); 10 | }; 11 | -------------------------------------------------------------------------------- /src/lib/dataTypes/tremoloMarks.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The number of tremolo marks is represented by a number from 0 to 8: the same as beam-level with 0 added. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/tremolo-marks/} 6 | */ 7 | export const tremoloMarks = () => t.label({ label: 'tremolo-marks', value: t.int({ min: 0, max: 8 }) }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/upDown.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The up-down type is used for the direction of arrows and other pointed symbols like vertical accents, indicating 4 | * which way the tip is pointing. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/up-down/} 7 | */ 8 | export const upDown = () => t.choices('up' as const, 'down' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/yesNo.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The yes-no type is used for boolean-like attributes. We cannot use W3C XML Schema booleans due to their restrictions 4 | * on expression of boolean values. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/yes-no/} 7 | */ 8 | export const yesNo = () => t.choices('yes' as const, 'no' as const); 9 | -------------------------------------------------------------------------------- /src/lib/elements/Sfpp.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element represents a sforzando pianissimo sfpp dynamic marking. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sfpp/} 11 | */ 12 | export const Sfpp = schema('sfpp', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/idref.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * See the 4 | * [definition in the W3C XML Schema standard.](https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-IDREF/) 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/xsd-IDREF/} 7 | */ 8 | export const idref = () => t.regex({ pattern: /[A-Za-z_][A-Za-z0-9.-_]*/, zero: '_' }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/lineEnd.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The line-end type specifies if there is a jog up or down (or both), an arrow, or nothing at the start or end of a 4 | * bracket. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/line-end/} 7 | */ 8 | export const lineEnd = () => t.choices(...(['none', 'up', 'down', 'both', 'arrow'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/numeralValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The numeral-value type represents a Roman numeral or Nashville number value as a positive integer from 1 to 7. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/numeral-value/} 6 | */ 7 | export const numeralValue = () => t.label({ label: 'numeral-value', value: t.int({ min: 1, max: 7 }) }); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/pedalType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The pedal-type distinguishes types of pedal directions. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/pedal-type/} 6 | */ 7 | export const pedalType = () => { 8 | return t.choices(...(['start', 'stop', 'sostenuto', 'change', 'continue', 'discountiue', 'resume'] as const)); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/resolutions/types.ts: -------------------------------------------------------------------------------- 1 | export type Resolution = ResolvedResolution | ZeroResolution | NoneResolution; 2 | 3 | export type ResolvedResolution = { 4 | type: 'resolved'; 5 | value: T; 6 | }; 7 | 8 | export type ZeroResolution = { 9 | type: 'zero'; 10 | value: T; 11 | }; 12 | 13 | export type NoneResolution = { 14 | type: 'none'; 15 | value: undefined; 16 | }; 17 | -------------------------------------------------------------------------------- /src/lib/dataTypes/overUnder.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The over-under type is used to indicate whether the tips of curved lines such as slurs and ties are overhand 4 | * (tips down) or underhand (tips up). 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/over-under/} 7 | */ 8 | export const overUnder = () => t.choices('over' as const, 'under' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/showFrets.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The show-frets type indicates whether to show tablature frets as numbers (0, 1, 2) or letters (a, b, c). The default 4 | * choice is numbers. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/show-frets/} 7 | */ 8 | export const showFrets = () => t.choices('letters' as const, 'numbers' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/yyyyMmDd.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * Calendar dates are represented yyyy-mm-dd format, following ISO 8601. This is a W3C XML Schema date type, but without 4 | * the optional timezone data. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/yyyy-mm-dd/} 7 | */ 8 | export const yyyyMmDd = () => t.label({ label: 'yyyy-mm-dd', value: t.date() }); 9 | -------------------------------------------------------------------------------- /src/lib/elements/EncodingDate.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element specifies the date of the digital encoding. 10 | */ 11 | export const EncodingDate = schema('encoding-date', {}, [t.required(dataTypes.yyyyMmDd())] as const); 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Debug Jest Tests", 6 | "type": "node", 7 | "request": "launch", 8 | "runtimeArgs": ["--inspect-brk", "${workspaceRoot}/node_modules/.bin/jest", "--runInBand"], 9 | "console": "integratedTerminal", 10 | "internalConsoleOptions": "neverOpen", 11 | "port": 9229 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/lib/dataTypes/fontStyle.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The font-style type represents a simplified version of the 4 | * [CSS font-style property.](https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/#font-prop-desc) 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/font-style/} 7 | */ 8 | export const fontStyle = () => t.choices('normal' as const, 'italic' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/numberOrNormal.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The number-or-normal values can be either a decimal number or the string "normal". This is used by the line-height 4 | * and letter-spacing attributes. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/number-or-normal/} 7 | */ 8 | export const numberOrNormal = () => t.choices('normal' as const, t.float()); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/valign.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The valign type is used to indicate vertical alignment to the top, middle, bottom, or baseline of the text. Defaults 4 | * are implementation-dependent. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/valign/} 7 | */ 8 | export const valign = () => t.choices(...(['top', 'middle', 'bottom', 'baseline'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/elements/Artificial.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element indicates that this is an artificial harmonic. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/artificial/} 11 | */ 12 | export const Artificial = schema('artificial', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/fontWeight.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The font-weight type represents a simplified version of the 4 | * [CSS font-weight property.](https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/#font-prop-desc) 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/font-weight/} 7 | */ 8 | export const fontWeight = () => t.choices('normal' as const, 'bold' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/commaSeparatedText.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The comma-separated-text type is used to specify a comma-separated list of text elements, as is used by the 4 | * font-family attribute. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/comma-separated-text/} 7 | */ 8 | export const commaSeparatedText = () => t.regex({ pattern: /[^,]+(, ?[^,]+)*/, zero: ' ' }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/principalVoiceSymbol.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The principal-voice-symbol type represents the type of symbol used to indicate a principal or secondary voice. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/principal-voice-symbol/} 6 | */ 7 | export const principalVoiceSymbol = () => t.choices(...(['none', 'Hauptstimme', 'Nebenstimme', 'plain'] as const)); 8 | -------------------------------------------------------------------------------- /src/lib/dataTypes/staffType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The staff-type value specifies different uses for the staff. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/staff-type/} 6 | */ 7 | export const staffType = () => 8 | t.label({ 9 | label: 'staff-type', 10 | value: t.choices(...(['regular', 'alternate', 'cue', 'editorial', 'ossia'] as const)), 11 | }); 12 | -------------------------------------------------------------------------------- /src/lib/dataTypes/step.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The step type represents a step of the diatonic scale, represented using the English letters A through G. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/step/} 6 | */ 7 | export const step = () => { 8 | return t.label({ label: 'step', value: t.choices(...(['A', 'B', 'C', 'D', 'E', 'F', 'G'] as const)) }); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/systemRelation.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The system-relation type distinguishes elements that are associated with a system rather than the particular part 4 | * where the element appears. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/system-relation/} 7 | */ 8 | export const systemRelation = () => t.choices(...(['none', 'only-top', 'also-top'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/elements/NormalDot.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element is used to specify dotted normal tuplet types. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/normal-dot/} 11 | */ 12 | export const NormalDot = schema('normal-dot', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/PreBend.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The ` element 5 | * 6 | * Parent element: ` 7 | * 8 | * The ` element indicates that a bend is a pre-bend rather than a normal bend or a release. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/pre-bend/} 11 | */ 12 | export const PreBend = schema('pre-bend', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Software.ts: -------------------------------------------------------------------------------- 1 | import { schema, t } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element specifies what software created the digital encoding. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/software/} 11 | */ 12 | export const Software = schema('software', {}, [t.string()] as const); 13 | -------------------------------------------------------------------------------- /src/lib/elements/Solo.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent elements: ``, `` 7 | * 8 | * The `` element is present if performance is intended by a solo instrument. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/solo/} 11 | */ 12 | export const Solo = schema('solo', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/holeClosedLocation.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The hole-closed-location type indicates which portion of the hole is filled in when the corresponding 4 | * hole-closed-value is half. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/hole-closed-location/} 7 | */ 8 | export const holeClosedLocation = () => t.choices(...(['bottom', 'left', 'right', 'top'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/millimeters.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The millimeters type is a number representing millimeters. This is used in the `` element to provide a 4 | * default scaling from tenths to physical units. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/millimeters/} 7 | */ 8 | export const millimeters = () => t.label({ label: 'millimeters', value: t.float() }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/tapHand.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The tap-hand type represents the symbol to use for a tap element. The left and right values refer to the SMuFL 4 | * guitarLeftHandTapping and guitarRightHandTapping glyphs respectively. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/tap-hand/} 7 | */ 8 | export const tapHand = () => t.choices('left' as const, 'right' as const); 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "strict": true, 6 | "outDir": "dist", 7 | "declaration": true, 8 | "sourceMap": false, 9 | "allowJs": true, 10 | "types": ["node", "jest", "jest-extended"], 11 | "experimentalDecorators": true, 12 | "skipLibCheck": true 13 | }, 14 | "include": ["src/**/*"], 15 | "exclude": ["node_modules"] 16 | } 17 | -------------------------------------------------------------------------------- /src/lib/dataTypes/holeClosedValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The hole-closed-value type represents whether the hole is closed, open, or half-open. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/hole-closed-value/} 6 | */ 7 | export const holeClosedValue = () => { 8 | return t.label({ label: 'hole-closed-value', value: t.choices(...(['yes', 'no', 'half'] as const)) }); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/showTuplet.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The show-tuplet type indicates whether to show a part of a tuplet relating to the tuplet-actual element, both the 4 | * tuplet-actual and tuplet-normal elements, or neither. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/show-tuplet/} 7 | */ 8 | export const showTuplet = () => t.choices(...(['none', 'actual', 'both'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/valignImage.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The valign-image type is used to indicate vertical alignment for images and graphics, so it does not include a 4 | * baseline value. Defaults are implementation-dependent. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/valign-image/} 7 | */ 8 | export const valignImage = () => t.choices(...(['top', 'middle', 'bottom'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/elements/Straight.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element specifies that no swing is present, so consecutive notes have equal durations. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/straight/} 11 | */ 12 | export const Straight = schema('straight', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/divisions.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The divisions type is used to express values in terms of the musical divisions defined by the divisions element. It 4 | * is preferred that these be integer values both for MIDI interoperability and to avoid roundoff errors. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/divisions/} 7 | */ 8 | export const divisions = () => t.float(); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/harmonClosedLocation.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The harmon-closed-location type indicates which portion of the symbol is filled in when the corresponding 4 | * harmon-closed-value is half. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/harmon-closed-location/} 7 | */ 8 | export const harmonClosedLocation = () => t.choices(...(['bottom', 'left', 'right', 'top'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/backwardFoward.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The backward-forward type is used to specify repeat directions. The start of the repeat has a forward direction while 4 | * the end of the repeat has a backward direction. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/backward-forward/} 7 | */ 8 | export const backwardForward = () => t.choices('backward' as const, 'forward' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/degreeSymbolValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The degree-symbol-value type indicates which symbol should be used in specifying a degree. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/degree-symbol-value/} 6 | */ 7 | export const degreeSymbolValue = () => { 8 | return t.choices(...(['major', 'minor', 'augmented', 'diminished', 'half-diminished'] as const)); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/groupBarlineValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The group-barline-value type indicates if the group should have common barlines. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/group-barline-value/} 6 | */ 7 | export const groupBarlineValue = () => { 8 | return t.label({ label: 'group-barline-value', value: t.choices(...(['yes', 'no', 'Mensurstrich'] as const)) }); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/harmonClosedValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The harmon-closed-value type represents whether the harmon mute is closed, open, half-open. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/harmon-closed-value/} 6 | */ 7 | export const harmonClosedValue = () => { 8 | return t.label({ label: 'harmon-closed-value', value: t.choices(...(['yes', 'no', 'half'] as const)) }); 9 | }; 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/midi128.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The midi-128 type is used to express MIDI 1.0 values that range from 1 to 128. MusicXML uses 1-based numbers rather 4 | * than 0-based numbers often found in MIDI 1.0 documentation. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/midi-128/} 7 | */ 8 | export const midi128 = () => t.label({ label: 'midi128', value: t.int({ min: 1, max: 128 }) }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/swingTypeValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The swing-type-value type specifies the note type, either eighth or 16th, to which the ratio defined in the `` 4 | * element is applied. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/swing-type-value/} 7 | */ 8 | export const swingTypeValue = () => t.label({ label: 'eighth', value: t.choices('eighth' as const, '16th' as const) }); 9 | -------------------------------------------------------------------------------- /src/lib/elements/MetronomeDot.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The metronome-dot element works like the dot element in defining metric relationships. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/metronome-dot/} 11 | */ 12 | export const MetronomeDot = schema('metronome-dot', {}, [] as const); 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | xmlvalidator: 3 | container_name: xmlvalidator 4 | image: xmlvalidator:latest 5 | build: xmlvalidator 6 | environment: 7 | PORT: 8080 8 | ports: 9 | - 8080:8080 10 | 11 | test: 12 | container_name: test 13 | image: musicxml:latest 14 | build: . 15 | volumes: 16 | - './src:/musicxml/src' 17 | links: 18 | - xmlvalidator 19 | ports: 20 | - 9229:9229 21 | -------------------------------------------------------------------------------- /src/lib/dataTypes/accordionMiddle.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The accordion-middle type may have values of 1, 2, or 3, corresponding to having 1 to 3 dots in the middle section of 4 | * the accordion registration symbol. This type is not used if no dots are present. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/accordion-middle/} 7 | */ 8 | export const accordionMiddle = () => t.int({ min: 1, max: 3 }); 9 | -------------------------------------------------------------------------------- /src/lib/elements/Sign.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent elements: ``, `` 8 | * 9 | * The `` element represents the clef symbol. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sign/} 12 | */ 13 | export const Sign = schema('sign', {}, [t.required(dataTypes.clefSign())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/dataTypes/glassValue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The glass-value type represents pictograms for glass percussion instruments. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/glass-value/} 6 | */ 7 | export const glassValue = () => { 8 | return t.label({ 9 | label: 'glass-value', 10 | value: t.choices(...(['glass harmonica', 'glass harp', 'wind chimes'] as const)), 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/fifths.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The fifths type represents the number of flats or sharps in a traditional key signature. Negative numbers are used 4 | * for flats and positive numbers for sharps, reflecting the key's placement within the circle of fifths (hence the type 5 | * name). 6 | * 7 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/fifths/} 8 | */ 9 | export const fifths = () => t.int(); 10 | -------------------------------------------------------------------------------- /src/lib/dataTypes/midi16384.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The midi-16384 type is used to express MIDI 1.0 values that range from 1 to 16,384. MusicXML uses 1-based numbers 4 | * rather than 0-based numbers often found in MIDI 1.0 documentation. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/midi-16384/} 7 | */ 8 | export const midi16384 = () => t.label({ label: 'midi16384', value: t.int({ min: 1, max: 16384 }) }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/smuflCodaGlyphName.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The smufl-coda-glyph-name type is used to reference a specific Standard Music Font Layout (SMuFL) coda character. The 4 | * value is a SMuFL canonical glyph name that starts with coda. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/smufl-coda-glyph-name/} 7 | */ 8 | export const smuflCodaGlyphName = () => t.regex({ pattern: /coda\c*/, zero: 'coda' }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/staffDivideSymbol.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The staff-divide-symbol type is used for staff division symbols. The down, up, and up-down values correspond to SMuFL 4 | * code points U+E00B, U+E00C, and U+E00D respectively. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/staff-divide-symbol/} 7 | */ 8 | export const staffDivideSymbol = () => t.choices('down' as const, 'up' as const, 'up-down' as const); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/upDownStopContinue.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The up-down-stop-continue type is used for octave-shift elements, indicating the direction of the shift from their 4 | * true pitched values because of printing difficulty. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/up-down-stop-continue/} 7 | */ 8 | export const upDownStopContinue = () => t.choices(...(['up', 'down', 'stop', 'continue'] as const)); 9 | -------------------------------------------------------------------------------- /src/lib/elements/Natural.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element indicates that this is a natural harmonic. These are usually notated at base pitch rather 9 | * than sounding pitch. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/natural/} 12 | */ 13 | export const Natural = schema('natural', {}, [] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/SlashDot.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent elements: ``, `` 7 | * 8 | * The `` element is used to specify any augmentation dots in the note type used to display repetition marks. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/slash-dot/} 11 | */ 12 | export const SlashDot = schema('slash-dot', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/smuflSegnoGlyphName.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The smufl-segno-glyph-name type is used to reference a specific Standard Music Font Layout (SMuFL) segno character. 4 | * The value is a SMuFL canonical glyph name that starts with segno. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/smufl-segno-glyph-name/} 7 | */ 8 | export const smuflSegnoGlyphName = () => t.regex({ pattern: /segno\c*/, zero: 'segno' }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/stickMaterial.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The stick-material type represents the material being displayed in a stick pictogram. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/stick-material/} 6 | */ 7 | export const stickMaterial = () => { 8 | return t.label({ 9 | label: 'stick-material', 10 | value: t.choices(...(['x', 'hard', 'medium', 'shaded', 'soft'] as const)), 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/syncType.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The sync-type type specifies the style that a score following application should use to synchronize an accompaniment 4 | * with a performer. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/sync-type/} 7 | */ 8 | export const syncType = () => { 9 | return t.choices(...(['none', 'tempo', 'mostly-tempo', 'mostly-event', 'event', 'always-event'] as const)); 10 | }; 11 | -------------------------------------------------------------------------------- /src/lib/elements/Arrowhead.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The presence of an `` element indicates that only the arrowhead is displayed within the ``, not the 9 | * arrow stem. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/arrowhead/} 12 | */ 13 | export const Arrowhead = schema('arrowhead', {}, [] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/BeatUnitDot.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent elements: ``, `` 7 | * 8 | * The `` element is used to specify any augmentation dots for a metronome mark note. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/beat-unit-dot/} 11 | */ 12 | export const BeatUnitDot = schema('beat-unit-dot', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/semitones.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The semitones type is a number representing semitones, used for chromatic alteration. A value of -1 corresponds to a 4 | * flat and a value of 1 to a sharp. Decimal values like 0.5 (quarter tone sharp) are used for microtones. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/semitones/} 7 | */ 8 | export const semitones = () => t.label({ label: 'semitones', value: t.float() }); 9 | -------------------------------------------------------------------------------- /src/lib/elements/GroupTime.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element indicates that the displayed time signatures should stretch across all parts and staves in 9 | * the group. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/group-time/} 12 | */ 13 | export const GroupTime = schema('group-time', {}, [] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/SoundingPitch.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The presence of the `` element indicates this is the pitch which is heard when playing the harmonic. 9 | * 10 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/sounding-pitch/} 11 | */ 12 | export const SoundingPitch = schema('sounding-pitch', {}, [] as const); 13 | -------------------------------------------------------------------------------- /src/lib/dataTypes/smuflLyricsGlyphName.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The smufl-lyrics-glyph-name type is used to reference a specific Standard Music Font Layout (SMuFL) lyrics elision 4 | * character. The value is a SMuFL canonical glyph name that starts with lyrics. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/smufl-lyrics-glyph-name/} 7 | */ 8 | export const smuflLyricsGlyphName = () => t.regex({ pattern: /lyrics/, zero: 'lyrics' }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/tipDirection.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The tip-direction type represents the direction in which the tip of a stick or beater points, using Unicode arrow 4 | * terminology. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/tip-direction/} 7 | */ 8 | export const tipDirection = () => { 9 | return t.choices(...(['down', 'left', 'northeast', 'northwest', 'right', 'southeast', 'southwest', 'up'] as const)); 10 | }; 11 | -------------------------------------------------------------------------------- /src/lib/elements/BasePitch.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The presence of the `` element indicates this is the pitch at which the string is played before touching 9 | * to create the harmonic. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/base-pitch/} 12 | */ 13 | export const BasePitch = schema('base-pitch', {}, [] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/EndLine.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The `` element comes from RP-017 for Standard MIDI File Lyric meta-events. It facilitates lyric display for 9 | * Karaoke and similar applications. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/end-line/} 12 | */ 13 | export const EndLine = schema('end-line', {}, [] as const); 14 | -------------------------------------------------------------------------------- /src/lib/dataTypes/semiPitched.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The semi-pitched type represents categories of indefinite pitch for percussion instruments. 4 | * 5 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/semi-pitched/} 6 | */ 7 | export const semiPitched = () => { 8 | return t.label({ 9 | label: 'semi-pitched', 10 | value: t.choices(...(['high', 'low', 'medium', 'medium-high', 'medium-low', 'very-low'] as const)), 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /src/lib/elements/WorkNumber.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element specifies the number of a work, such as its opus number. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/work-number/} 12 | */ 13 | export const WorkNumber = schema('work-number', {}, [dataTypes.string()] as const); 14 | -------------------------------------------------------------------------------- /src/lib/dataTypes/smuflPictogramGlyphName.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The smufl-pictogram-glyph-name type is used to reference a specific Standard Music Font Layout (SMuFL) percussion 4 | * pictogram character. The value is a SMuFL canonical glyph name that starts with pict. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/smufl-pictogram-glyph-name/} 7 | */ 8 | export const smuflPictogramGlyphName = () => t.regex({ pattern: /pict/, zero: 'pict' }); 9 | -------------------------------------------------------------------------------- /src/lib/dataTypes/stickLocation.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | /** 3 | * The stick-location type represents pictograms for the location of sticks, beaters, or mallets on cymbals, gongs, 4 | * drums, and other instruments. 5 | * 6 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/data-types/stick-location/} 7 | */ 8 | export const stickLocation = () => 9 | t.label({ label: 'stick-location', value: t.choices(...(['center', 'cymbal bell', 'cymbal edge', 'rim'] as const)) }); 10 | -------------------------------------------------------------------------------- /src/lib/elements/Mute.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element represents muting playback for different instruments, including brass, winds, and strings. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/mute/} 12 | */ 13 | export const Mute = schema('mute', {}, [t.required(dataTypes.mute())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/Octave.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * Octaves are represented by the numbers 0 to 9, where 4 indicates the octave started by middle C. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/octave/} 12 | */ 13 | export const Octave = schema('octave', {}, [t.required(dataTypes.octave())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/PedalStep.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element defines the pitch step for a single harp pedal. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/pedal-step/} 12 | */ 13 | export const PedalStep = schema('pedal-step', {}, [t.required(dataTypes.step())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/Step.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element represents a step of the diatonic scale, represented using the English letters A through G. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/step/} 12 | */ 13 | export const Step = schema('step', {}, [t.required(dataTypes.step())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/SwingStyle.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element is a string describing the style of swing used. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/swing-style/} 12 | */ 13 | export const SwingStyle = schema('swing-style', {}, [t.required(dataTypes.string())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/WorkTitle.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element specifies the title of a work, not including its opus or other work number. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/work-title/} 12 | */ 13 | export const WorkTitle = schema('work-title', {}, [dataTypes.string()] as const); 14 | -------------------------------------------------------------------------------- /src/lib/dataTypes/enclosureShape.ts: -------------------------------------------------------------------------------- 1 | import { t } from '../schema'; 2 | export const enclosureShape = () => { 3 | return t.choices( 4 | ...([ 5 | 'none', 6 | 'rectangle', 7 | 'square', 8 | 'oval', 9 | 'circle', 10 | 'bracket', 11 | 'inverted-bracket', 12 | 'triangle', 13 | 'diamond', 14 | 'pentagon', 15 | 'hexagon', 16 | 'heptagon', 17 | 'octagon', 18 | 'nonagon', 19 | 'decagon', 20 | ] as const) 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /src/lib/elements/MidiBank.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent element: `` 8 | * 9 | * The `` element specifies a MIDI 1.0 bank number ranging from 1 to 16,384. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/midi-bank/} 12 | */ 13 | export const MidiBank = schema('midi-bank', {}, [t.required(dataTypes.midi16384())] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/TouchingPitch.ts: -------------------------------------------------------------------------------- 1 | import { schema } from '../schema'; 2 | 3 | /** 4 | * The `` element 5 | * 6 | * Parent element: `` 7 | * 8 | * The presence of the `` element indicates this is the pitch at which the string is touched lightly to 9 | * produce the harmonic. 10 | * 11 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/touching-pitch/} 12 | */ 13 | export const TouchingPitch = schema('touching-pitch', {}, [] as const); 14 | -------------------------------------------------------------------------------- /src/lib/elements/Beats.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | 4 | /** 5 | * The `` element 6 | * 7 | * Parent elements: ``, `

` element 11 | * 12 | * Parent element: `` 13 | * 14 | * The `
` element represents a single figure within a `` element. 15 | * 16 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/figure/} 17 | */ 18 | export const Figure = schema('figure', {}, [ 19 | t.optional(Prefix), 20 | t.optional(FigureNumber), 21 | t.optional(Suffix), 22 | t.optional(Extend), 23 | t.optional(Footnote), 24 | t.optional(Level), 25 | ] as const); 26 | -------------------------------------------------------------------------------- /src/lib/elements/Accord.ts: -------------------------------------------------------------------------------- 1 | import * as dataTypes from '../dataTypes'; 2 | import { schema, t } from '../schema'; 3 | import { TuningAlter } from './TuningAlter'; 4 | import { TuningOctave } from './TuningOctave'; 5 | import { TuningStep } from './TuningStep'; 6 | 7 | /** 8 | * The `` element 9 | * 10 | * Parent element: `` 11 | * 12 | * The `` element represents the tuning of a single string in the `` element. It uses the same group 13 | * of elements as the `` element. 14 | * 15 | * {@link https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/accord/} 16 | */ 17 | export const Accord = schema( 18 | 'accord', 19 | { 20 | string: t.optional(dataTypes.stringNumber()), 21 | }, 22 | [t.required(TuningStep), t.optional(TuningAlter), t.required(TuningOctave)] 23 | ); 24 | --------------------------------------------------------------------------------