Export metadata edits (title, composer, source, encrypter) via patchScore
This commit is contained in:
parent
720a0b6b25
commit
097d4488ef
@ -47,7 +47,7 @@ export const PaneCP = {
|
||||
try {
|
||||
const raw = await fetchScoreText(props.store.credentials);
|
||||
props.store.rawScoreText = raw;
|
||||
const patched = patchScore(raw, props.store.scoreModel.instruments, props.store.scoreModel.bars);
|
||||
const patched = patchScore(raw, props.store.scoreModel.instruments, props.store.scoreModel.bars, props.store.scoreModel.info);
|
||||
await putScoreText(patched, props.store.credentials);
|
||||
props.store.synthesisStatus = { frozen: false, currently_rendered_notes: 0, notes_in_total: 0 };
|
||||
} catch (e) {
|
||||
|
||||
@ -141,6 +141,31 @@ export function exportInstrument(instr) {
|
||||
// Replace dirty instrument blocks and dirty bar _meta blocks.
|
||||
// Voice note content in bar documents is left verbatim.
|
||||
|
||||
const META_KEYS = ['title', 'composer', 'source', 'encrypter'];
|
||||
|
||||
function patchMetadata(text, info) {
|
||||
if (!info) return text;
|
||||
const lines = text.split('\n');
|
||||
const replaced = new Set();
|
||||
|
||||
const out = lines.map(line => {
|
||||
for (const key of META_KEYS) {
|
||||
if (line.startsWith(key + ':') && info[key] != null && info[key] !== '') {
|
||||
replaced.add(key);
|
||||
return `${key}: ${info[key]}`;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
});
|
||||
|
||||
const prepend = META_KEYS
|
||||
.filter(k => !replaced.has(k) && info[k] != null && info[k] !== '')
|
||||
.map(k => `${k}: ${info[k]}`);
|
||||
if (prepend.length) out.unshift(...prepend);
|
||||
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
function patchInstrumentHeader(text, instruments) {
|
||||
const lines = text.split('\n');
|
||||
const result = [];
|
||||
@ -217,11 +242,11 @@ function patchBarMeta(doc, bar) {
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
export function patchScore(rawScoreText, instruments, bars = []) {
|
||||
export function patchScore(rawScoreText, instruments, bars = [], info = null) {
|
||||
const SEP = '\n---\n';
|
||||
const [header, ...barDocs] = rawScoreText.split(SEP);
|
||||
|
||||
const patchedHeader = patchInstrumentHeader(header, instruments);
|
||||
const patchedHeader = patchInstrumentHeader(patchMetadata(header, info), instruments);
|
||||
|
||||
if (!barDocs.length) return patchedHeader;
|
||||
|
||||
|
||||
@ -403,6 +403,32 @@ ok('clean bar unchanged', barPatched.includes('beats_per_minute: 100'));
|
||||
ok('clean bar voice preserved', barPatched.includes('- D4 4'));
|
||||
ok('document separators preserved', (barPatched.match(/\n---\n/g) ?? []).length === 2);
|
||||
|
||||
// ── patchScore metadata ────────────────────────────────────────────────────
|
||||
section('patchScore metadata');
|
||||
const META_SCORE = `title: Old Title
|
||||
composer: Old Composer
|
||||
source: Some Book
|
||||
|
||||
instrument alpha:
|
||||
character:
|
||||
A: "1:0,10;1,0"
|
||||
`;
|
||||
const updatedInfo = { title: 'New Title', composer: 'New Composer', source: '', encrypter: 'Me' };
|
||||
const metaPatched = patchScore(META_SCORE, [], [], updatedInfo);
|
||||
ok('existing title replaced', metaPatched.includes('title: New Title'));
|
||||
ok('existing composer replaced', metaPatched.includes('composer: New Composer'));
|
||||
ok('empty value leaves existing line', metaPatched.includes('source: Some Book'));
|
||||
ok('new key prepended', metaPatched.includes('encrypter: Me'));
|
||||
ok('instrument block untouched', metaPatched.includes('instrument alpha:'));
|
||||
|
||||
const META_SCORE_NO_TITLE = `composer: Bach\n\ninstrument ki:\n character:\n`;
|
||||
const noTitlePatched = patchScore(META_SCORE_NO_TITLE, [], [], { title: 'Fugue', composer: 'Bach' });
|
||||
ok('missing title prepended', noTitlePatched.includes('title: Fugue'));
|
||||
ok('existing composer not duplicated', (noTitlePatched.match(/^composer:/mg) ?? []).length === 1);
|
||||
|
||||
const nullInfoPatched = patchScore(META_SCORE, [], [], null);
|
||||
ok('null info leaves metadata unchanged', nullInfoPatched.includes('title: Old Title'));
|
||||
|
||||
// ── Summary ────────────────────────────────────────────────────────────────
|
||||
console.log(`\n══ ${pass} passed, ${fail} failed ══\n`);
|
||||
process.exit(fail > 0 ? 1 : 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user