Skip to content

Commit

Permalink
start on json schema, abandon xml schema maybe
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronDavidNewman committed Apr 27, 2024
1 parent f732fcf commit b8335c6
Show file tree
Hide file tree
Showing 26 changed files with 27,677 additions and 386 deletions.
2 changes: 1 addition & 1 deletion build/html/smoosic.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<!-- link href="https://aarondavidnewman.github.io/Smoosic/build/styles/bravura-font-codes.css" rel="stylesheet" -->
<link href="../styles/bravura-font-codes.css" rel="stylesheet">
<!-- script type="text/javascript" src="https://aarondavidnewman.github.io/vexflow_smoosic/releases/vexflow-debug.js"></script -->
<script type="text/javascript" src="../../node_modules/vexflow_smoosic/build/cjs/vexflow-debug.js"></script>
<script type="text/javascript" src="../../node_modules/vexflow_smoosic/build/cjs/vexflow-debug-with-tests.js"></script>
<!-- script src="https://unpkg.com/vexflow@4.0.1/build/cjs/vexflow-debug.js"></script -->
<!-- script type="text/javascript" src="..\..\node_modules\vxflw-early-access\build\cjs\vexflow-debug.js"></script -->
<!---- script type="text/javascript" src="../../vxflw-early-access/build/cjs/vexflow-debug.js"></script -->
Expand Down
16 changes: 16 additions & 0 deletions build/styles/bravura-font-codes.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,19 @@
.icon-accidentalFlat:before {
content: "\e260";
}

.icon-caesura:before {
content: "\e4d2"
}

.icon-breath:before {
content: "\e4ce"
}

.icon-pedal-open:before {
content: "\e650"
}

.icon-pedal-closed:before {
content: "\e655"
}
599 changes: 324 additions & 275 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"ts-loader": "^9.2.5",
"typedoc": "^0.25.0",
"typescript": "^5.2.2",
"vexflow_smoosic": "4.2.6",
"vexflow_smoosic": "4.2.7",
"xmldom": "^0.6.0"
},
"description": "<sub>[Github site](https://github.com/AaronDavidNewman/smoosic) | [source documentation](https://aarondavidnewman.github.io/Smoosic/release/docs/modules.html) | [change notes](https://aarondavidnewman.github.io/Smoosic/changes.html) | [application](https://aarondavidnewman.github.io/Smoosic/release/html/smoosic.html)<sub>",
Expand Down
16 changes: 16 additions & 0 deletions release/styles/bravura-font-codes.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,19 @@
.icon-accidentalFlat:before {
content: "\e260";
}

.icon-caesura:before {
content: "\e4d2"
}

.icon-breath-mark:before {
content: "\e4ce"
}

.icon-pedal-open:before {
content: "\e650"
}

.icon-pedal-closed:before {
content: "\e655"
}
11 changes: 8 additions & 3 deletions src/common/vex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Vex as SmoVex, Note as VexNote, StaveNote as VexStaveNote, StemmableNot
Voice as VexVoice, Formatter as VexFormatter, Accidental as VexAccidental,
Annotation as VexAnnotation, StaveNoteStruct as VexStaveNoteStruct,
StaveText as VexStaveText, StaveModifier as VexStaveModifier,
TextNote as VexTextNote,
Stave as VexStave, StaveModifierPosition as VexStaveModifierPosition,
Font as VexFont, FontInfo as VexFontInfo, FontStyle as VexFontStyle, FontWeight as VexFontWeight,
TupletOptions as VexTupletOptions, Curve as VexCurve, StaveTie as VexStaveTie,
Expand Down Expand Up @@ -32,6 +33,7 @@ export type FontStyle = VexFontStyle;
export type FontWeight = VexFontWeight;
export type Formatter = VexFormatter;
export type Annotation = VexAnnotation;
export type TextNote = VexTextNote;
export type StaveNoteStruct = VexStaveNoteStruct;
export type StaveModifier = VexStaveModifier;
export type StaveText = VexStaveText;
Expand Down Expand Up @@ -366,6 +368,9 @@ export function getVexGlyphFromChordCode(code: string) {
}
return ChordSymbolGlyphs[code].code;
}
export function createTextNote(code: string) {
return new VexTextNote({ glyph: code, duration: '8' }).setLine(2);
}
/**
* Get the chord symbol glyph from the vex glyph
* @export
Expand Down Expand Up @@ -418,13 +423,13 @@ export const ChordSymbolGlyphs: Record<string, { code: string }> = {
code: 'csymMajorSeventh',
},
csymMinor: {
code: 'csymMinor',
code: 'minor',
},
minor: {
code: 'csymMinor',
code: 'minor',
},
'-': {
code: 'csymMinor',
code: 'minor',
},
'(': {
code: 'csymParensLeftTall',
Expand Down
7 changes: 6 additions & 1 deletion src/render/vex/vxMeasure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import { VexFlow, Stave,StemmableNote, Note, Beam, Tuplet, Voice,
Formatter, Accidental, Annotation, StaveNoteStruct, StaveText, StaveModifier,
createStaveText, renderDynamics, applyStemDirection,
getVexNoteParameters, defaultNoteScale, defaultCueScale, getVexTuplets,
createStave, createVoice, getOrnamentGlyph, getSlashGlyph, getRepeatBar, getMultimeasureRest
createStave, createVoice, getOrnamentGlyph, getSlashGlyph, getRepeatBar, getMultimeasureRest,
createTextNote
} from '../../common/vex';

import { VxMeasureIf, VexNoteModifierIf, VxNote } from './vxNote';
Expand Down Expand Up @@ -258,6 +259,7 @@ export class VxMeasure implements VxMeasureIf {
for (i = 0;
i < voice.notes.length; ++i) {
const smoNote = voice.notes[i];
const textNotes = smoNote.getTextOrnaments();
const vexNote = this.createVexNote(smoNote, i, voiceIx);
this.noteToVexMap[smoNote.attrs.id] = vexNote.noteData.staveNote;
this.vexNotes.push(vexNote.noteData.staveNote);
Expand All @@ -267,6 +269,9 @@ export class VxMeasure implements VxMeasureIf {
clefNoteAdded = true; // ignore 2nd in a measure
}
this.voiceNotes.push(vexNote.noteData.staveNote);
textNotes.forEach((tn) => {
this.voiceNotes.push(createTextNote(SmoOrnament.textNoteOrnaments[tn.ornament]));
});
if (isNaN(smoNote.ticks.numerator) || isNaN(smoNote.ticks.denominator)
|| isNaN(smoNote.ticks.remainder)) {
throw ('vxMeasure: NaN in ticks');
Expand Down
12 changes: 7 additions & 5 deletions src/render/vex/vxNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,14 @@ export class VxNote {
createOrnaments() {
const o = this.noteData.smoNote.getOrnaments();
o.forEach((ll) => {
const ornamentCode = getOrnamentGlyph(ll.ornament);
const mod = new VF.Ornament(ornamentCode);
if (ll.offset === SmoOrnament.offsets.after) {
mod.setDelayed(true);
if (!SmoOrnament.textNoteOrnaments[ll.ornament]) {
const ornamentCode = getOrnamentGlyph(ll.ornament);
const mod = new VF.Ornament(ornamentCode);
if (ll.offset === SmoOrnament.offsets.after) {
mod.setDelayed(true);
}
this.noteData.staveNote.addModifier(mod, 0);
}
this.noteData.staveNote.addModifier(mod, 0);
});
}
addLyricAnnotationToNote(vexNote: Note, lyric: SmoLyric) {
Expand Down
9 changes: 8 additions & 1 deletion src/smo/data/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,15 @@ export function createChildElementArray(object: any[], namespace: string, parent
createXmlAttribute(arEl, 'container', 'array');
createXmlAttribute(arEl, 'name', tag);
for (var j = 0; j < object.length; ++j) {
const inst = object[j];
const instKey = `${tag}-instance`;
createChildElementRecurse(object[j], namespace, arEl, instKey);
if (typeof(inst) === 'number' || typeof(inst) === 'string' || typeof(inst) === 'boolean') {
const instEl = parentElement.ownerDocument.createElementNS(namespace, `${tag}-instance`);
arEl.appendChild(instEl);
createXmlAttribute(instEl, 'value', inst);
} else {
createChildElementRecurse(object[j], namespace, arEl, instKey);
}
}
return arEl;
}
Expand Down
7 changes: 6 additions & 1 deletion src/smo/data/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,13 +508,18 @@ export class SmoNote implements Transposable {
}

getOrnaments() {
return this.ornaments.filter((oo) => oo.isJazz() === false);
return this.ornaments.filter((oo) => oo.isJazz() === false
&& typeof(SmoOrnament.textNoteOrnaments[oo.ornament]) !== 'string');
}

getJazzOrnaments() {
return this.ornaments.filter((oo) => oo.isJazz());
}

getTextOrnaments() {
return this.ornaments.filter((oo) => typeof(SmoOrnament.textNoteOrnaments[oo.ornament]) === 'string');
}

/**
* Toggle the ornament up/down/off
* @param ornament
Expand Down
6 changes: 6 additions & 0 deletions src/smo/data/noteModifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,12 @@ export class SmoOrnament extends SmoNoteModifierBase {
prallup: 'schleifer',
tr: 'trill-mark'
}
static readonly textNoteOrnaments: Record<string, string> = {
breath: 'breath',
caesura: 'caesura_straight',
pedalOpen: 'pedal_open',
pedalClosed: 'pedal_close'
}
// jazz ornaments in vex are articulations in music xml
static readonly xmlJazz: Record<string, string> = {
doit: 'doit',
Expand Down
2 changes: 1 addition & 1 deletion src/smo/data/partInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export class SmoPartInfo extends StaffModifierBase {
if (this.midiInstrument) {
createChildElementRecurse(this.midiDevice, namespace, el, "midiInstrument");
}
serializeXmlArray(namespace, el, this.textGroups, 'testGroups');
serializeXmlArray(namespace, el, this.textGroups, 'textGroups');
return el;
}
updateTextGroup(textGroup: SmoTextGroup, toAdd: boolean) {
Expand Down
65 changes: 49 additions & 16 deletions src/smo/data/scoreText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
import { smoSerialize } from '../../common/serializationHelpers';
import { SmoScoreModifierBase, ScaledPageLayout } from './scoreModifiers';
import { SmoAttrs, SmoModifierBase, createChildElementRecurse } from './common';
import { SmoAttrs, SmoModifierBase, createChildElementRecurse, createXmlAttribute } from './common';
import { SmoSelector } from '../xform/selections';
import { FontInfo } from '../../common/vex';
import { TextFormatter } from '../../common/textformatter';
Expand Down Expand Up @@ -167,16 +167,9 @@ export class SmoScoreText extends SmoScoreModifierBase {
weight: 'normal'
};
fill: string = 'black';
rotate: number = 0;
classes: string = 'score-text';
boxModel: string = 'none';
scaleX: number = 1.0;
scaleY: number = 1.0;
translateX: number = 0;
translateY: number = 0;
pagination: string = 'once';
position: string = 'custom';
autoLayout: boolean = false; // set to true if one of the pre-canned positions are used.

getText() {
return this.text;
Expand Down Expand Up @@ -217,14 +210,28 @@ export class SmoScoreText extends SmoScoreModifierBase {
return params;
}
serializeXml(namespace: string, parentElement: Element, tagName: string) {
const ser = this.serialize();
return createChildElementRecurse(ser, namespace, parentElement, tagName);
const el = parentElement.ownerDocument.createElementNS(namespace, tagName);
parentElement.appendChild(el);
const defaults = SmoTextGroup.defaults;
// Create attributes for non-default values
SmoScoreText.simpleAttributes.forEach((attr) => {
if (!(this as any)[attr] === (defaults as any)[attr]) {
createXmlAttribute(el, attr, (this as any)[attr]);
}
});
createChildElementRecurse({
size: this.fontInfo.size, family: this.fontInfo.family, weight: this.fontInfo.weight, style: this.fontInfo.style},
namespace, el, 'fontInfo');
return el;
}

static get attributes(): string[] {
return ['x', 'y', 'text', 'pagination', 'position', 'fontInfo', 'classes',
'boxModel', 'justification', 'fill', 'width', 'height', 'scaleX', 'scaleY',
'translateX', 'translateY', 'autoLayout'];
return ['x', 'y', 'text', 'fontInfo', 'classes',
'fill', 'width', 'height', 'scaleX', 'scaleY'];
}
static get simpleAttributes(): string[] {
return ['x', 'y', 'text', 'classes',
'fill', 'width', 'height', 'scaleX', 'scaleY'];
}
constructor(parameters: SmoScoreTextParams) {
super('SmoScoreText');
Expand Down Expand Up @@ -411,8 +418,11 @@ export class SmoTextGroup extends SmoScoreModifierBase {
static get nonTextAttributes() {
return ['justification', 'relativePosition', 'spacing', 'pagination',
'attachToSelector', 'selector', 'musicXOffset', 'musicYOffset'];

}
static get simpleAttributes() {
return ['justification', 'relativePosition', 'spacing', 'pagination',
'attachToSelector', 'musicXOffset', 'musicYOffset'];
}
static isTextGroup(modifier: SmoTextGroup | SmoModifierBase): modifier is SmoTextGroup {
return modifier.ctor === 'SmoTextGroup';
}
Expand Down Expand Up @@ -591,8 +601,31 @@ export class SmoTextGroup extends SmoScoreModifierBase {
return params;
}
serializeXml(namespace: string, parentElement: Element, tagName: string) {
const ser = this.serialize();
return createChildElementRecurse(ser, namespace, parentElement, tagName);
const el = parentElement.ownerDocument.createElementNS(namespace, tagName);
parentElement.appendChild(el);
const defaults = SmoTextGroup.defaults;
createXmlAttribute(el, 'ctor', 'SmoTextGroup');
// Create attributes for non-default values
SmoTextGroup.simpleAttributes.forEach((attr) => {
if (!(this as any)[attr] === (defaults as any)[attr]) {
createXmlAttribute(el, attr, (this as any)[attr]);
}
});
if (this.selector) {
createChildElementRecurse(this.selector, namespace, el, 'selector');
}
const tbEl = parentElement.ownerDocument.createElementNS(namespace, 'textBlocks-array');
el.appendChild(tbEl);
createXmlAttribute(tbEl, 'container', 'array');
createXmlAttribute(tbEl, 'name', 'textBlocks');
for (var i = 0; i < this.textBlocks.length; ++i) {
const textBlock = this.textBlocks[i];
const tbiEl = parentElement.ownerDocument.createElementNS(namespace, 'textBlocks-instance');
tbEl.appendChild(tbiEl);
createXmlAttribute(tbiEl, 'position', textBlock.position);
textBlock.text.serializeXml(namespace, tbiEl, 'text');
}
return el;
}
/* _isScoreText(st: ) {
return st.ctor && st.ctor === 'SmoScoreText';
Expand Down
16 changes: 16 additions & 0 deletions src/styles/bravura-font-codes.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,19 @@
.icon-accidentalFlat:before {
content: "\e260";
}

.icon-caesura:before {
content: "\e4d2"
}

.icon-breath:before {
content: "\e4ce"
}

.icon-pedal-open:before {
content: "\e650"
}

.icon-pedal-closed:before {
content: "\e655"
}
10 changes: 9 additions & 1 deletion src/ui/buttons/articulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class ArticulationButtons extends SuiButton {
mordentButton: SmoOrnament.ornaments.mordent,
mordentInvertedButton: SmoOrnament.ornaments.mordentInverted,
trillButton: SmoOrnament.ornaments.trill,
breathButton: 'breath',
caesuraButton: 'caesura',
pedalOpenButton: 'pedalOpen',
pedalClosedButton: 'pedalClosed',
scoopButton: SmoOrnament.ornaments.scoop,
dropButton: SmoOrnament.ornaments.fall_short,
dropLongButton: SmoOrnament.ornaments.dropLong,
Expand All @@ -35,13 +39,17 @@ export class ArticulationButtons extends SuiButton {
mordentButton: 'SmoOrnament',
mordentInvertedButton: 'SmoOrnament',
trillButton: 'SmoOrnament',
breathButton: 'SmoOrnament',
pedalOpenButton: 'SmoOrnament',
pedalClosedButton: 'SmoOrnament',
caesuraButton: 'SmoOrnament',
scoopButton: 'SmoOrnament',
dropButton: 'SmoOrnament',
dropLongButton: 'SmoOrnament',
doitButton: 'SmoOrnament',
doitLongButton: 'SmoOrnament',
flipButton: 'SmoOrnament',
smearButton: 'SmoOrnament'
smearButton: 'SmoOrnament',
};
}
articulation: string;
Expand Down
Loading

0 comments on commit b8335c6

Please sign in to comment.