Skip to content

Commit

Permalink
intermediate checking
Browse files Browse the repository at this point in the history
Cleaning up schema for XSD for Smoosic format
  • Loading branch information
AaronDavidNewman committed Mar 17, 2024
1 parent 1bb58fc commit 0d9fb66
Show file tree
Hide file tree
Showing 37 changed files with 3,922 additions and 215 deletions.
442 changes: 420 additions & 22 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"copy-webpack-plugin": "^12.0.2",
"jquery": "^3.6.0",
"webpack": "^5.89.0",
"webpack-cli": "^4.7.2"
"webpack-cli": "^4.7.2",
"xsd-validator": "^1.1.1"
},
"dependencies": {
"midi-parser-js": "^4.0.4",
Expand Down
2 changes: 1 addition & 1 deletion release/library/links/hymns.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"name": "Hymn to Freedom",
"composer": "Oscar Peterson"
},
"url": "https://aarondavidnewman.github.io/Smoosic/release/library/hymns/HymnFreedom.json"
"url": "https://aarondavidnewman.github.io/Smoosic/release/library/trumpet/HymnFreedom.json"
},
{
"format": "smoosic",
Expand Down
1 change: 1 addition & 0 deletions release/library/trumpet/BeethovenOp21-old.json

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions src/common/serializationHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,26 @@ export class smoSerialize {
static get tokenValues() {
return smoSerialize.reverseMap(smoSerialize.tokenMap);
}
static prettifyXml(xmlDoc) {
var xsltDoc = new DOMParser().parseFromString([
// describes how we want to modify the XML - indent everything
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
' <xsl:strip-space elements="*"/>',
' <xsl:template match="para[content-style][not(text())]">', // change to just text() to strip space in text nodes
' <xsl:value-of select="normalize-space(.)"/>',
' </xsl:template>',
' <xsl:template match="node()|@*">',
' <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>',
' </xsl:template>',
' <xsl:output indent="yes"/>',
'</xsl:stylesheet>',
].join('\n'), 'application/xml');

var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsltDoc);
var resultDoc = xsltProcessor.transformToDocument(xmlDoc);
return resultDoc;
};
// ## detokenize
// If we are saving, replace token values with keys, since the keys are smaller.
// if we are loading, replace the token keys with values so the score can
Expand Down
4 changes: 2 additions & 2 deletions src/render/sui/renderState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ export class SuiRenderState {
this.handlingRedraw = false;
}
pollRedraw() {
setTimeout(() => {
this.handleRedrawTimer();
setTimeout(async () => {
await this.handleRedrawTimer();
this.pollRedraw();
}, this.demonPollTime);
}
Expand Down
12 changes: 7 additions & 5 deletions src/render/sui/scoreView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export abstract class SuiScoreView {
this.audioAnimation = config.audioAnimation;
this.renderer = new SuiRenderState(renderParams);
this.config = config;
const scoreJson = score.serialize();
const scoreJson = score.serialize({ skipStaves: false, useDictionary: false });
this.scroller = new SuiScroller(scrollSelector, this.renderer.renderer.vexContainers);
this.pasteBuffer = new PasteBuffer();
this.storePaste = new PasteBuffer();
Expand Down Expand Up @@ -509,13 +509,13 @@ export abstract class SuiScoreView {
if (!any) {
return;
}
const nscore = SmoScore.deserialize(JSON.stringify(this.storeScore.serialize(true)));
const nscore = SmoScore.deserialize(JSON.stringify(this.storeScore.serialize({ skipStaves: true, useDictionary: false })));
const staffMap = [];
for (i = 0; i < rows.length; ++i) {
const row = rows[i];
if (row.show) {
const srcStave = this.storeScore.staves[i];
const jsonObj = srcStave.serialize();
const jsonObj = srcStave.serialize({ skipMaps: false });
jsonObj.staffId = staffMap.length;
const nStave = SmoSystemStaff.deserialize(jsonObj);
nStave.mapStaffFromTo(i, nscore.staves.length);
Expand Down Expand Up @@ -560,7 +560,8 @@ export abstract class SuiScoreView {
* view all the staffs in score mode.
*/
viewAll() {
this.score = SmoScore.deserialize(JSON.stringify(this.storeScore.serialize()));
this.score = SmoScore.deserialize(JSON.stringify(
this.storeScore.serialize({ skipStaves: false, useDictionary: false })));
this.staffMap = this.defaultStaffMap;
this.setMappedStaffIds();
this._setTransposing();
Expand Down Expand Up @@ -592,7 +593,8 @@ export abstract class SuiScoreView {
SuiAudioPlayer.stopPlayer();
this.renderer.score = score;
this.renderer.setViewport();
this.storeScore = SmoScore.deserialize(JSON.stringify(score.serialize()));
this.storeScore = SmoScore.deserialize(JSON.stringify(
score.serialize({ skipStaves: false, useDictionary: false })));
this.score = score;
// If the score is non-transposing, hide the instrument xpose settings
this._setTransposing();
Expand Down
5 changes: 5 additions & 0 deletions src/render/vex/smoAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ export function vexAnnotationPosition(chordPos: number) {
return VF.ChordSymbol.symbolModifiers.SUBSCRIPT;
}

/**
* Parse the SmoLyric text and convert it to a VEX chord symbol
* @param athis
* @returns
*/
export function getVexChordBlocks(athis: SmoLyric) {
let mod = VF.ChordSymbol.symbolModifiers.NONE;
let isGlyph = false;
Expand Down
4 changes: 2 additions & 2 deletions src/render/vex/toVex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ function createTuplets(smoMeasure: SmoMeasure, strs: string[]) {
};
const tpParamString = JSON.stringify(tpParams);
const narString = '[' + nar.join(',') + ']';
strs.push(`const ${tp.attrs.id} = new VF.Tuplet(${narString}, JSON.parse('${tpParamString}'));`);
strs.push(`const ${tp.id} = new VF.Tuplet(${narString}, JSON.parse('${tpParamString}'));`);
}
});
}
Expand Down Expand Up @@ -494,7 +494,7 @@ function createMeasure(smoMeasure: SmoMeasure, heightOffset: number, strs: strin
strs.push(`${bg.attrs.id}.draw();`)
});
smoMeasure.tuplets.forEach((tp) => {
strs.push(`${tp.attrs.id}.setContext(context).draw();`)
strs.push(`${tp.id}.setContext(context).draw();`)
})
}
// ## SmoToVex
Expand Down
2 changes: 1 addition & 1 deletion src/render/vex/vxMeasure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ export class VxMeasure implements VxMeasureIf {
location
}
const vexTuplet = getVexTuplets(smoTupletParams);
this.tupletToVexMap[tp.attrs.id] = vexTuplet;
this.tupletToVexMap[tp.id] = vexTuplet;
this.vexTuplets.push(vexTuplet);
}
}
Expand Down
102 changes: 101 additions & 1 deletion src/smo/data/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,91 @@ export interface SmoAttrs {
id: string,
type: string
}
export const smoXmlNs = 'https://aarondavidnewman.github.io/Smoosic';

export function createXmlAttributes(element: Element, obj: any) {
Object.keys(obj).forEach((key) => {
const attr = element.ownerDocument.createAttribute(key);
attr.value = obj[key];
element.setAttributeNode(attr);
});
}
export function createXmlAttribute(element: Element, name: string, value: any) {
const obj: any = {};
obj[name] = value;
createXmlAttributes(element, obj);
}
export function createChildElementRecurse(object: any, namespace: string, parentElement: Element, tag: string): Element {
if (object === null || typeof(object) === 'undefined') {
return parentElement;
}
if (Array.isArray(object)) {
return createChildElementArray(object, namespace, parentElement, tag);
}
// if this is a simple type, don't create an element just add an attribute to the parent element
if (typeof(object) === 'string' || typeof(object) === 'number' || typeof(object) === 'boolean') {
createXmlAttribute(parentElement, tag, object);
return parentElement;
}
const el = parentElement.ownerDocument.createElementNS(namespace, tag);
parentElement.appendChild(el);
const keys = Object.keys(object);
for (var i = 0; i < keys.length; ++i) {
const key = keys[i];
const child = object[key];
if (child === null && typeof(child) === 'undefined') {
continue;
}
// Array, create an array element and an instance element for 'key'
if (Array.isArray(child) && child.length > 0) {
createChildElementArray(child, namespace, el, key);
} else if (typeof(child) === 'object') {
// Object, create element for the object
createChildElementRecurse(child, namespace, el, key);
} else if (typeof(child) === 'string' || typeof(child) === 'number' || typeof(child) === 'boolean'){
createXmlAttribute(el, key, child);
}
};
return el;
}
export function createChildElementArray(object: any[], namespace: string, parentElement: Element, tag: string) {
// Don't make empty array elements
if (object.length < 1) {
return parentElement;
}
const arEl = parentElement.ownerDocument.createElementNS(namespace, `${tag}-array`);
parentElement.appendChild(arEl);
createXmlAttribute(arEl, 'container', 'array');
createXmlAttribute(arEl, 'name', tag);
for (var j = 0; j < object.length; ++j) {
const instKey = `${tag}-instance`;
createChildElementRecurse(object[j], namespace, arEl, instKey);
}
return arEl;
}
export function createChildElementRecord(object: any, namespace: string, parentElement: Element, tag: string, isNumber: boolean) {
if (!object) {
return null;
}
const keys = Object.keys(object);
if (keys.length < 1) {
return null;
}
const el = parentElement.ownerDocument.createElementNS(namespace, tag);
const recType = isNumber ? 'numberRecord' : 'stringRecord';
createXmlAttribute(el, 'container', recType);
createXmlAttribute(el, 'name', tag);
parentElement.appendChild(el);
for (var i = 0; i < keys.length; ++i) {
const key = keys[i];
const rec = object[key];
const instEl = parentElement.ownerDocument.createElementNS(namespace, `${tag}-instance`);
el.appendChild(instEl);
createChildElementRecurse(rec, namespace, instEl, `${tag}-instance`);
createXmlAttribute(instEl, 'key', key);
}
return el;
}
var nextId = 32768;
export const getId = () => `smo` + (nextId++).toString();
/**
Expand Down Expand Up @@ -141,6 +225,9 @@ export interface Transposable {
logicalBox: SvgBox | null
}

export interface SmoSerializable {
serializeXml: (namespace: string, parentElement: Element, tag: string) => Element;
}
/**
* All note, measure etc. modifiers have these attributes. The SVG info
* is for the tracker to track the artifacts in the UI (mouse events, etc)
Expand All @@ -151,7 +238,20 @@ export interface Transposable {
export interface SmoModifierBase {
ctor: string,
logicalBox: SvgBox | null,
attrs: SmoAttrs
attrs: SmoAttrs,
serialize: () => any;
}

export function serializeXmlModifierArray(object: SmoSerializable[], namespace: string, parentElement: Element, tag: string) {
const arEl = parentElement.ownerDocument.createElementNS(namespace, `${tag}-array`);
parentElement.appendChild(arEl);
createXmlAttribute(arEl, 'container', 'array');
createXmlAttribute(arEl, 'name', 'tag');
for (var j = 0; j < object.length; ++j) {
const instKey = `${tag}-instance`;
object[j].serializeXml(namespace, arEl, instKey);
}
return arEl;
}

/**
Expand Down
Loading

0 comments on commit 0d9fb66

Please sign in to comment.