Skip to content

Commit

Permalink
Add basic MEI export
Browse files Browse the repository at this point in the history
  • Loading branch information
remarcable committed Feb 24, 2022
1 parent 216cf02 commit 41b8f2c
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 4 deletions.
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@mui/material": "^5.4.2",
"@reduxjs/toolkit": "^1.7.2",
"file-saver": "^2.0.5",
"js2xmlparser": "^4.0.2",
"just-debounce-it": "^3.0.1",
"next": "^12.1.0",
"papaparse": "^5.3.1",
Expand Down
74 changes: 71 additions & 3 deletions src/lib/fileExport/exporters/mei.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,78 @@
import { getMarkersWithMeasures } from "lib/getMarkersWithMeasures";
import type { FileExporter } from "..";

const replaceSpacesWithUnderscores = (string: string) =>
string.replaceAll(" ", "_");
export const meiExporter: FileExporter = {
fileType: "mei",
fileType: "xml",
mimeType: "text/xml",
name: "MEI",
stateToFile: async () => {
return "MEI";
stateToFile: async (state) => {
const js2xmlparser = await import("js2xmlparser");

const { markers, duration } = state.player;
const extendedMarkers = getMarkersWithMeasures(markers);

const { name } = state.app.file;
const nameWithoutFileExtension = name.split(".").slice(0, -1).join(".");

const resultObject = {
"@": {
xmlns: "http://www.music-encoding.org/ns/mei",
"xml:id": replaceSpacesWithUnderscores(nameWithoutFileExtension),
},
music: {
performance: {
recording: {
"@": {
"xml:id": "some_recording_id",
decls: "#some_other_recording_id",
},
avFile: {
"@": {
// XXX: This includes the file extension
target: name,
},
},
clip: extendedMarkers.map((marker, i, arr) => ({
"@": {
begin: marker.time,
end: arr[i + 1]?.time ?? duration,
betype: "time",
startid: replaceSpacesWithUnderscores(
`#${nameWithoutFileExtension}_measure${marker.measure}`
),
type: "measure",
},
})),
},
},
body: {
mdiv: {
"@": {
"xml:id": replaceSpacesWithUnderscores(name),
label: name,
},
score: {
section: {
measure: extendedMarkers.map((marker) => ({
"@": {
"xml:id": replaceSpacesWithUnderscores(
`${nameWithoutFileExtension}_measure${marker.measure}`
),
sameas: `../some_file_path.xml#some_id_measure${marker.measure}`,
},
})),
},
},
},
},
},
};

return js2xmlparser.parse("mei", resultObject, {
declaration: { encoding: "UTF-8" },
format: { doubleQuotes: true },
});
},
};
2 changes: 1 addition & 1 deletion src/lib/fileExport/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const fileExporters: readonly FileExporter[] = [
textExporter,
csvExporter,
jsonExporter,
// meiExporter,
meiExporter,
] as const;

export const exportOptions = fileExporters.map((exporter) => exporter.fileType);
Expand Down
3 changes: 3 additions & 0 deletions src/state/playerSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export const playerSlice = createSlice({
builder.addCase(exportAsFile.fulfilled, () => {
return;
});
builder.addCase(exportAsFile.rejected, (_, payload) => {
console.error(payload.error);
});
},
});

Expand Down

0 comments on commit 41b8f2c

Please sign in to comment.