From 884955195a1285886f7b662cfe92adaf1bb3235e Mon Sep 17 00:00:00 2001 From: c0dev0id Date: Mon, 6 Jul 2026 21:14:36 +0200 Subject: [PATCH] refactor: underscore-prefix all non-exported functions --- static/ast-parser.js | 114 ++++++++++++++-------------- static/components/PaneFO.js | 32 ++++---- static/components/PaneSubObjects.js | 10 +-- static/exporter.js | 84 ++++++++++---------- 4 files changed, 120 insertions(+), 120 deletions(-) diff --git a/static/ast-parser.js b/static/ast-parser.js index cd0528e..2bb4bdb 100644 --- a/static/ast-parser.js +++ b/static/ast-parser.js @@ -25,7 +25,7 @@ export function parseAstLog(text) { slot = slotFull.slice(dotIdx + 1); } - const { positionals, props } = parseRest(rest); + const { positionals, props } = _parseRest(rest); const node = { slot, parentSlot, depth, positionals, props, children: [] }; @@ -46,7 +46,7 @@ export function parseAstLog(text) { return root; } -function parseRest(rest) { +function _parseRest(rest) { const positionals = []; const props = {}; let i = 0; @@ -100,7 +100,7 @@ function parseRest(rest) { // ── Second pass: build typed model ────────────────────────────────────────── -function collectUnknownProps(nodeProps, knownKeys) { +function _collectUnknownProps(nodeProps, knownKeys) { return Object.fromEntries(Object.entries(nodeProps).filter(([k]) => !knownKeys.has(k))); } @@ -143,7 +143,7 @@ export function buildModel(rawTree) { score.info = { ...node.props }; break; case 'tuning': - score.tuning = buildTuning(node); + score.tuning = _buildTuning(node); break; case 'stage.cone': score.stageCone = { type: 'stage_cone', ...node.props }; @@ -157,16 +157,16 @@ export function buildModel(rawTree) { }); break; case 'instrument': - score.instruments.push(buildInstrument(node)); + score.instruments.push(_buildInstrument(node)); break; case 'bar': - score.bars.push(buildBar(node)); + score.bars.push(_buildBar(node)); break; default: if (node.parentSlot === 'articles') { - mergeArticleEntry(score, node); + _mergeArticleEntry(score, node); } else { - score[node.slot] = buildGeneric(node); + score[node.slot] = _buildGeneric(node); } } } @@ -178,7 +178,7 @@ export function buildModel(rawTree) { // — e.g. `articles.defaults 'f'` and (future) `articles.overwrites 'f'`. // We merge them into one entry per label whose properties carry the scope // of their originating subtype, so the UI can toggle scope per property. -function mergeArticleEntry(score, node) { +function _mergeArticleEntry(score, node) { const name = node.positionals[0]; let entry = score.articles.find(a => a.name === name); if (!entry) { @@ -192,7 +192,7 @@ function mergeArticleEntry(score, node) { return entry; } -function buildTuning(node) { +function _buildTuning(node) { const t = { type: 'tuning', base: node.props.base, scales: {}, chords: {}, frequencyFactors: null }; for (const child of node.children) { if (child.slot === 'scales') { @@ -209,7 +209,7 @@ function buildTuning(node) { return t; } -function buildInstrument(node) { +function _buildInstrument(node) { const instr = { type: 'instrument', name: node.positionals[0], @@ -228,16 +228,16 @@ function buildInstrument(node) { for (const child of node.children) { switch (child.parentSlot + '.' + child.slot) { case 'character.variation': - instr.variations.push(buildVariation(child)); + instr.variations.push(_buildVariation(child)); break; case 'character.basic_properties': - instr.basicProperties = buildBasicProperties(child); + instr.basicProperties = _buildBasicProperties(child); break; case 'VOLUMES.shape': - instr.volumes = buildShape(child); + instr.volumes = _buildShape(child); break; case 'TIMBRE.shape': - instr.timbre = buildShape(child); + instr.timbre = _buildShape(child); break; case 'FM.modulation': instr.fmModulations.push({ ...child.props }); @@ -246,14 +246,14 @@ function buildInstrument(node) { instr.amModulations.push({ ...child.props }); break; default: - instr.unknownSlots.push(buildGeneric(child)); + instr.unknownSlots.push(_buildGeneric(child)); } } return instr; } -function buildVariation(node) { +function _buildVariation(node) { const v = { type: 'variation', dependsOn: node.props.depends_on ?? node.props.for_value ?? null, @@ -269,29 +269,29 @@ function buildVariation(node) { const key = (child.parentSlot ?? child.slot) + '.' + child.slot; switch (key) { case 'variation.basic_properties': - v.basicProperties = buildBasicProperties(child); + v.basicProperties = _buildBasicProperties(child); break; case 'variation.label_spec': - v.labelSpecs.push(buildLabelSpec(child)); + v.labelSpecs.push(_buildLabelSpec(child)); break; case 'variation.subvariation': - v.subvariations.push(buildVariation(child)); + v.subvariations.push(_buildVariation(child)); break; case 'variation.SPREAD': v.spread = child.positionals; break; case 'RAILSBACK_CURVE.shape': - v.railsbackCurve = buildShape(child); + v.railsbackCurve = _buildShape(child); break; default: - v.unknownSlots.push(buildGeneric(child)); + v.unknownSlots.push(_buildGeneric(child)); } } return v; } -function buildBasicProperties(node) { +function _buildBasicProperties(node) { const bp = { type: 'basic_properties', A: null, S: null, R: null, @@ -304,32 +304,32 @@ function buildBasicProperties(node) { for (const child of node.children) { const fqSlot = (child.parentSlot ?? '') + (child.parentSlot ? '.' : '') + child.slot; if (child.parentSlot === 'A' && child.slot === 'shape') { - bp.A = buildShape(child); + bp.A = _buildShape(child); } else if (child.parentSlot === 'S' && child.slot === 'shape') { - bp.S = buildShape(child); + bp.S = _buildShape(child); } else if (child.parentSlot === 'R' && child.slot === 'shape') { - bp.R = buildShape(child); + bp.R = _buildShape(child); } else if (child.parentSlot === 'variation' && child.slot === 'O') { bp.oscillator = child.props.ref ?? child.positionals[0]; } else if (child.parentSlot === 'FM' && child.slot === 'modulation') { const fm = { ...child.props }; const envChild = child.children.find(c => c.slot === 'shape'); - if (envChild) fm.shape = buildShape(envChild); + if (envChild) fm.shape = _buildShape(envChild); bp.fmModulations.push(fm); } else if (child.parentSlot === 'AM' && child.slot === 'modulation') { const am = { ...child.props }; const envChild = child.children.find(c => c.slot === 'shape'); - if (envChild) am.shape = buildShape(envChild); + if (envChild) am.shape = _buildShape(envChild); bp.amModulations.push(am); } else { - bp.unknownSlots.push(buildGeneric(child)); + bp.unknownSlots.push(_buildGeneric(child)); } } return bp; } -function buildLabelSpec(node) { +function _buildLabelSpec(node) { const ls = { type: 'label_spec', label: node.positionals[0], @@ -340,7 +340,7 @@ function buildLabelSpec(node) { const directBpChildren = []; for (const child of node.children) { if (child.parentSlot === 'variation' && child.slot === 'basic_properties') { - ls.basicProperties = buildBasicProperties(child); + ls.basicProperties = _buildBasicProperties(child); } else if ( (child.slot === 'shape' && (child.parentSlot === 'A' || child.parentSlot === 'S' || child.parentSlot === 'R')) || (child.parentSlot === 'variation' && child.slot === 'O') || @@ -348,17 +348,17 @@ function buildLabelSpec(node) { ) { directBpChildren.push(child); } else { - ls.unknownSlots.push(buildGeneric(child)); + ls.unknownSlots.push(_buildGeneric(child)); } } if (!ls.basicProperties && directBpChildren.length > 0) { - ls.basicProperties = buildBasicProperties({ children: directBpChildren }); + ls.basicProperties = _buildBasicProperties({ children: directBpChildren }); } return ls; } -function buildShape(node) { +function _buildShape(node) { return { type: 'shape', length: node.props.length, @@ -374,7 +374,7 @@ function buildShape(node) { }; } -function buildBar(node) { +function _buildBar(node) { const bar = { type: 'bar', id: node.positionals[0] ?? '', @@ -393,35 +393,35 @@ function buildBar(node) { const fqSlot = (child.parentSlot ?? '') + (child.parentSlot ? '.' : '') + child.slot; switch (fqSlot) { case 'stress_pattern.stressor': - bar.stressor = buildStressor(child); + bar.stressor = _buildStressor(child); break; case 'tempo.shape': - bar.tempoShape = buildShape(child); + bar.tempoShape = _buildShape(child); break; case 'tempo.levels': bar.tempoLevels = child.positionals[0]; break; case 'lower_stress_bound.shape': - bar.lowerStressBound = buildShape(child); + bar.lowerStressBound = _buildShape(child); break; case 'upper_stress_bound.shape': - bar.upperStressBound = buildShape(child); + bar.upperStressBound = _buildShape(child); break; case 'bar.tuning': bar.tunings.push({ ...child.props }); break; case 'bar.voice': - bar.voices[child.positionals[0]] = buildVoice(child); + bar.voices[child.positionals[0]] = _buildVoice(child); break; default: - bar.unknownSlots.push(buildGeneric(child)); + bar.unknownSlots.push(_buildGeneric(child)); } } return bar; } -function buildStressor(node) { +function _buildStressor(node) { const levels = []; let currentGroup = []; for (const child of node.children) { @@ -436,7 +436,7 @@ function buildStressor(node) { return { type: 'stressor', groups: levels }; } -function buildVoice(node) { +function _buildVoice(node) { const voice = { type: 'voice', name: node.positionals[0], @@ -449,13 +449,13 @@ function buildVoice(node) { const fqSlot = (child.parentSlot ?? '') + (child.parentSlot ? '.' : '') + child.slot; switch (fqSlot) { case 'voice.offset': - voice.offsets.push(buildOffset(child)); + voice.offsets.push(_buildOffset(child)); break; case 'voice.article': voice.articles.push(child.positionals[0]); break; case 'voice.motif': - voice.motifs.push(buildMotif(child)); + voice.motifs.push(_buildMotif(child)); break; default: // ignore @@ -465,24 +465,24 @@ function buildVoice(node) { return voice; } -function buildOffset(node) { +function _buildOffset(node) { const offset = { type: 'offset', tick: node.props.tick, stemNotes: [], motifRefs: [], - unknownProps: collectUnknownProps(node.props, new Set(['tick'])), + unknownProps: _collectUnknownProps(node.props, new Set(['tick'])), }; for (const child of node.children) { if (child.parentSlot === 'line' && child.slot === 'stem_note') - offset.stemNotes.push(buildStemNote(child)); + offset.stemNotes.push(_buildStemNote(child)); else if (child.parentSlot === 'line' && child.slot === 'motif') offset.motifRefs.push({ label: child.positionals[0], chord: child.props.chord ?? null }); } return offset; } -function buildStemNote(node) { +function _buildStemNote(node) { const KNOWN = new Set(['pitch', 'eff_length', 'adj_stress', 'adjacent']); const chainNode = node.children.find(c => c.parentSlot === 'stem_note' && c.slot === 'chain'); const writeToNode = node.children.find(c => c.parentSlot === 'stem_note' && c.slot === 'write_to'); @@ -498,13 +498,13 @@ function buildStemNote(node) { writeToName: writeToNode?.positionals[0] ?? null, clauses: (chainNode?.children ?? []) .filter(c => c.parentSlot === 'chain' && c.slot === 'clause') - .map(buildClause), + .map(_buildClause), isDirty: false, - unknownProps: collectUnknownProps(node.props, KNOWN), + unknownProps: _collectUnknownProps(node.props, KNOWN), }; } -function buildClause(node) { +function _buildClause(node) { return { type: 'clause', index: node.positionals[0] ?? 0, @@ -518,28 +518,28 @@ function buildClause(node) { }; } -function buildMotif(node) { +function _buildMotif(node) { const m = { type: 'motif', label: node.props.label, stemNotes: [], - unknownProps: collectUnknownProps(node.props, new Set(['label'])), + unknownProps: _collectUnknownProps(node.props, new Set(['label'])), }; for (const child of node.children) { if (child.parentSlot === 'line' && child.slot === 'stem_note') - m.stemNotes.push(buildStemNote(child)); + m.stemNotes.push(_buildStemNote(child)); } m.isStatic = m.stemNotes.length > 0 && !m.stemNotes.some(sn => Number.isInteger(sn.pitch)); return m; } -function buildGeneric(node) { +function _buildGeneric(node) { return { type: node.slot, parentSlot: node.parentSlot, depth: node.depth, positionals: node.positionals, props: node.props, - children: node.children.map(buildGeneric), + children: node.children.map(_buildGeneric), }; } diff --git a/static/components/PaneFO.js b/static/components/PaneFO.js index fd501d9..9dc0891 100644 --- a/static/components/PaneFO.js +++ b/static/components/PaneFO.js @@ -7,19 +7,19 @@ import { coerce, stressorToString } from '../util.js'; const H4 = { style: 'margin:0 0 0.5rem' }; -function unknownPropFields(node) { +function _unknownPropFields(node) { return Object.entries(node.unknownProps ?? {}) .map(([key, value]) => ({ key, value: String(value), editable: false })); } -function parseStressor(str) { +function _parseStressor(str) { const groups = str.split(';').map(seg => seg.split(',').map(n => parseInt(n, 10)).filter(n => !isNaN(n)) ).filter(g => g.length > 0); return groups.length ? { type: 'stressor', groups } : null; } -function scoreInfoFields(info) { +function _scoreInfoFields(info) { return [ { key: 'title', value: info?.title ?? '', editable: true }, { key: 'composer', value: info?.composer ?? '', editable: true }, @@ -28,7 +28,7 @@ function scoreInfoFields(info) { ]; } -function instrFields(instr) { +function _instrFields(instr) { return [ { key: 'name', value: instr.name, editable: false }, { key: 'linked', value: instr.isLinked, editable: false, type: 'boolean' }, @@ -36,11 +36,11 @@ function instrFields(instr) { ]; } -function variationFields(v) { +function _variationFields(v) { return [{ key: 'depends_on', value: v.dependsOn ?? '—', editable: true }]; } -function shapeSection(label, shape, onChange) { +function _shapeSection(label, shape, onChange) { if (!shape) return null; return h('div', { style: 'margin-top:0.5rem' }, [ h('strong', null, label), @@ -101,7 +101,7 @@ export const PaneFO = { return h('div', { class: 'se-fo-pane' }, [ h('h4', H4, 'Score'), h(ObjectExtended, { - fields: scoreInfoFields(model.info), + fields: _scoreInfoFields(model.info), onChange: ({ key, value }) => { if (!model.info) model.info = {}; model.info[key] = value; @@ -114,7 +114,7 @@ export const PaneFO = { if (node.type === 'instrument') { children.push( h('h4', H4, `Instrument: ${node.name}`), - h(ObjectExtended, { fields: instrFields(node), onChange: null }), + h(ObjectExtended, { fields: _instrFields(node), onChange: null }), ); } else if (node.type === 'variation') { const instr = props.store.scoreModel.instruments.find( @@ -125,7 +125,7 @@ export const PaneFO = { children.push( h('h4', H4, 'Variation'), - h(ObjectExtended, { fields: variationFields(node), onChange: ({ key, value }) => { + h(ObjectExtended, { fields: _variationFields(node), onChange: ({ key, value }) => { if (key === 'depends_on') { const old = node.dependsOn; node.dependsOn = value; @@ -223,13 +223,13 @@ export const PaneFO = { onChange: ({ key, value }) => { if (key === 'id') { node.id = value; markBarDirty(); return; } if (key === 'beats_per_minute') node.tempoLevels = isNaN(value) ? null : value; - if (key === 'stress_pattern') node.stressor = parseStressor(value); + if (key === 'stress_pattern') node.stressor = _parseStressor(value); markBarDirty(); }, }), - shapeSection('Upper stress bound', node.upperStressBound, markBarDirty), - shapeSection('Lower stress bound', node.lowerStressBound, markBarDirty), - shapeSection('Tempo shape', node.tempoShape, markBarDirty), + _shapeSection('Upper stress bound', node.upperStressBound, markBarDirty), + _shapeSection('Lower stress bound', node.lowerStressBound, markBarDirty), + _shapeSection('Tempo shape', node.tempoShape, markBarDirty), ); } else if (node.type === 'voice') { children.push( @@ -254,7 +254,7 @@ export const PaneFO = { node.motifRefs?.length ? { key: 'motifRefs', value: node.motifRefs.map(m => m.chord ? `${m.label}(${m.chord})` : m.label).join(', '), editable: false } : null, - ...unknownPropFields(node), + ..._unknownPropFields(node), ].filter(Boolean), onChange: null, }), @@ -269,7 +269,7 @@ export const PaneFO = { { key: 'label', value: node.label, editable: false }, { key: 'static', value: node.isStatic, editable: false, type: 'boolean' }, { key: 'stem notes', value: node.stemNotes.map(pitchLabel).join(', ') || '—', editable: false }, - ...unknownPropFields(node), + ..._unknownPropFields(node), ], onChange: null, }), @@ -291,7 +291,7 @@ export const PaneFO = { { key: 'adj_stress', value: node.adjStress != null ? String(node.adjStress) : '', editable: true, type: 'number' }, { key: 'chain', value: node.chainText, editable: true }, { key: 'clauses', value: String(node.clauses.length), editable: false }, - ...unknownPropFields(node), + ..._unknownPropFields(node), ], onChange: ({ key, value }) => { if (key === 'pitch') node.pitch = value; diff --git a/static/components/PaneSubObjects.js b/static/components/PaneSubObjects.js index 33b44a0..200e577 100644 --- a/static/components/PaneSubObjects.js +++ b/static/components/PaneSubObjects.js @@ -4,13 +4,13 @@ import { getKindGroups } from '../subobject-kinds.js'; // Strip the final maximal run of same-class characters (all-digits or all-non-digits) // from the ID tail. Everything before that run is the group key. -function barGroupKey(id) { +function _barGroupKey(id) { const m = id.match(/(\d+|\D+)$/); return m ? id.slice(0, m.index) : id; } // Increment the trailing numeric run of an ID, preserving zero-padding width. -function incrementId(id) { +function _incrementId(id) { const m = id.match(/(\d+)$/); if (!m) return id + '1'; const num = parseInt(m[1], 10) + 1; @@ -70,10 +70,10 @@ export const PaneSubObjects = { if (!model) return; let newId; if (afterId) { - newId = incrementId(afterId); + newId = _incrementId(afterId); } else { const liveBars = (model.bars ?? []).filter(b => !b.deleted); - newId = liveBars.length ? incrementId(liveBars[liveBars.length - 1].id) : 'bar001'; + newId = liveBars.length ? _incrementId(liveBars[liveBars.length - 1].id) : 'bar001'; } const newBar = { type: 'bar', id: newId, isDirty: true, isNew: true, @@ -103,7 +103,7 @@ export const PaneSubObjects = { const barGroups = []; const seen = new Map(); for (const item of visibleItems) { - const key = barGroupKey(item.label); + const key = _barGroupKey(item.label); if (!seen.has(key)) { const g = { key, items: [] }; barGroups.push(g); diff --git a/static/exporter.js b/static/exporter.js index fae3558..d405fc6 100644 --- a/static/exporter.js +++ b/static/exporter.js @@ -5,7 +5,7 @@ import { stressorToString } from './util.js'; // Node = x "," y ["*" z] ["!"] // PREFIX+colon is the duration/resolution; optional START+semicolon follows. -function serializeShape(shape) { +function _serializeShape(shape) { if (!shape) return null; const nodes = shape.coords.map(c => { let s = `${c.x},${c.y}`; @@ -22,10 +22,10 @@ function serializeShape(shape) { // ── FM / AM modulation ───────────────────────────────────────────────────── // RFC §3.2.1.1.6-7: FM = FREQUENCY ["f"/"F"] ["@" OSC] ["[" SHAPE "]"] ";" MOD ":" BASE -function serializeModulation(m) { +function _serializeModulation(m) { let s = String(m.frequency ?? ''); if (m.oscillator) s += `@${m.oscillator}`; - if (m.shape) s += `[${serializeShape(m.shape)}]`; + if (m.shape) s += `[${_serializeShape(m.shape)}]`; s += `;${m.mod_share ?? ''}:${m.base_share ?? ''}`; if (m.init_phase != null) s += m.init_phase >= 0 ? `+${m.init_phase}` : String(m.init_phase); return s; @@ -35,18 +35,18 @@ function serializeModulation(m) { // RFC §3.2.1.1: O, A, S, R, FM go directly in the variation MAPPING. // Returns array of YAML lines at 0 indent. -function basicPropLines(bp) { +function _basicPropLines(bp) { if (!bp) return []; const lines = []; if (bp.oscillator) lines.push(`O: ${bp.oscillator}`); - const a = serializeShape(bp.A); + const a = _serializeShape(bp.A); if (a) lines.push(`A: "${a}"`); - const s = serializeShape(bp.S); + const s = _serializeShape(bp.S); if (s) lines.push(`S: "${s}"`); - const r = serializeShape(bp.R); + const r = _serializeShape(bp.R); if (r) lines.push(`R: "${r}"`); - for (const fm of (bp.fmModulations ?? [])) lines.push(`FM: "${serializeModulation(fm)}"`); - for (const am of (bp.amModulations ?? [])) lines.push(`AM: "${serializeModulation(am)}"`); + for (const fm of (bp.fmModulations ?? [])) lines.push(`FM: "${_serializeModulation(fm)}"`); + for (const am of (bp.amModulations ?? [])) lines.push(`AM: "${_serializeModulation(am)}"`); return lines; } @@ -54,8 +54,8 @@ function basicPropLines(bp) { // RFC §3.2.1.2: label name (3+ lowercase chars) is the MAPPING KEY directly. // Returns array of YAML lines at 0 indent. -function labelSpecLines(ls) { - const inner = basicPropLines(ls.basicProperties); +function _labelSpecLines(ls) { + const inner = _basicPropLines(ls.basicProperties); if (!inner.length) return [`${ls.label}:`]; return [`${ls.label}:`, ...inner.map(l => ` ${l}`)]; } @@ -64,20 +64,20 @@ function labelSpecLines(ls) { // Returns YAML lines for one variation MAPPING (no leading "- "). // RFC §3.2.1.3: VOLUMES, TIMBRE are variation properties, not instrument-level. -function variationLines(v) { +function _variationLines(v) { const lines = []; if (v.dependsOn) lines.push(`ATTR: ${v.dependsOn}`); - lines.push(...basicPropLines(v.basicProperties)); - for (const ls of (v.labelSpecs ?? [])) lines.push(...labelSpecLines(ls)); + lines.push(..._basicPropLines(v.basicProperties)); + for (const ls of (v.labelSpecs ?? [])) lines.push(..._labelSpecLines(ls)); if (v.spread?.length) lines.push(`SPREAD: [${v.spread.join(', ')}]`); - if (v.railsbackCurve) { const rc = serializeShape(v.railsbackCurve); if (rc) lines.push(`RAILSBACK_CURVE: "${rc}"`); } - const vol = serializeShape(v.volumes); + if (v.railsbackCurve) { const rc = _serializeShape(v.railsbackCurve); if (rc) lines.push(`RAILSBACK_CURVE: "${rc}"`); } + const vol = _serializeShape(v.volumes); if (vol) lines.push(`VOLUMES: "${vol}"`); - const timbre = serializeShape(v.timbre); + const timbre = _serializeShape(v.timbre); if (timbre) lines.push(`TIMBRE: "${timbre}"`); - for (const fm of (v.fmModulations ?? [])) lines.push(`FM: "${serializeModulation(fm)}"`); - for (const am of (v.amModulations ?? [])) lines.push(`AM: "${serializeModulation(am)}"`); - for (const sv of (v.subvariations ?? [])) lines.push(...variationLines(sv)); + for (const fm of (v.fmModulations ?? [])) lines.push(`FM: "${_serializeModulation(fm)}"`); + for (const am of (v.amModulations ?? [])) lines.push(`AM: "${_serializeModulation(am)}"`); + for (const sv of (v.subvariations ?? [])) lines.push(..._variationLines(sv)); return lines; } @@ -87,7 +87,7 @@ function variationLines(v) { // is implicit when no character: wrapper exists). Promote them into a synthetic // root variation here so the export structure is RFC-correct. -function instrCharacterLines(instr) { +function _instrCharacterLines(instr) { const variations = instr.variations ?? []; const hasRootProps = instr.basicProperties || instr.volumes || instr.timbre || (instr.fmModulations ?? []).length > 0 || @@ -110,14 +110,14 @@ function instrCharacterLines(instr) { ]; if (allVariations.length <= 1) { - const vLines = allVariations.length ? variationLines(allVariations[0]) : []; + const vLines = allVariations.length ? _variationLines(allVariations[0]) : []; return vLines.map(l => ` ${l}`); } // Multiple variations — RFC MAYBE_LIST as YAML sequence. const result = []; for (const v of allVariations) { - const vLines = variationLines(v); + const vLines = _variationLines(v); if (!vLines.length) continue; result.push(` - ${vLines[0]}`); for (const l of vLines.slice(1)) result.push(` ${l}`); @@ -132,33 +132,33 @@ export function exportInstrument(instr) { const lines = [`instrument ${instr.name}:`]; if (instr.notChangedSince) lines.push(` NOT_CHANGED_SINCE: ${instr.notChangedSince}`); lines.push(` character:`); - lines.push(...instrCharacterLines(instr)); + lines.push(..._instrCharacterLines(instr)); return lines.join('\n'); } // ── Articles ─────────────────────────────────────────────────────────────── // RFC §4.3: articles: MAPPING { LABEL: { ATTR: VALUE ... } ... } -function serializeArticleValue(v) { +function _serializeArticleValue(v) { if (typeof v === 'boolean') return String(v); if (typeof v === 'number') return String(v); const s = String(v); return /[:#\[\]{}&*!,|>'"%@`]/.test(s) ? JSON.stringify(s) : s; } -function buildArticlesBlock(articles) { +function _buildArticlesBlock(articles) { const lines = ['articles:']; for (const art of articles) { const props = (art.properties ?? []).filter(p => p.name); if (!props.length) continue; lines.push(` ${art.name}:`); - for (const p of props) lines.push(` ${p.name}: ${serializeArticleValue(p.value)}`); + for (const p of props) lines.push(` ${p.name}: ${_serializeArticleValue(p.value)}`); } return lines.length > 1 ? lines.join('\n') : null; } -function patchArticles(text, articles) { - const newBlock = buildArticlesBlock(articles); +function _patchArticles(text, articles) { + const newBlock = _buildArticlesBlock(articles); if (!newBlock) return text; const lines = text.split('\n'); const artIdx = lines.findIndex(l => /^articles\s*:/.test(l)); @@ -180,7 +180,7 @@ function patchArticles(text, articles) { const META_KEYS = ['title', 'composer', 'source', 'encrypter']; -function patchMetadata(text, info) { +function _patchMetadata(text, info) { if (!info) return text; const lines = text.split('\n'); const replaced = new Set(); @@ -203,7 +203,7 @@ function patchMetadata(text, info) { return out.join('\n'); } -function patchInstrumentHeader(text, instruments) { +function _patchInstrumentHeader(text, instruments) { const lines = text.split('\n'); const result = []; const instrMap = {}; @@ -241,17 +241,17 @@ function patchInstrumentHeader(text, instruments) { } -function patchBarMeta(doc, bar) { +function _patchBarMeta(doc, bar) { const props = []; const sp = stressorToString(bar.stressor); if (sp) props.push(` stress_pattern: ${sp}`); if (bar.tempoLevels != null) props.push(` beats_per_minute: ${bar.tempoLevels}`); - const ub = serializeShape(bar.upperStressBound); + const ub = _serializeShape(bar.upperStressBound); if (ub) props.push(` upper_stress_bound: ${ub}`); - const lb = serializeShape(bar.lowerStressBound); + const lb = _serializeShape(bar.lowerStressBound); if (lb) props.push(` lower_stress_bound: ${lb}`); - if (bar.tempoShape) { const ts = serializeShape(bar.tempoShape); if (ts) props.push(` tempo_shape: "${ts}"`); } + if (bar.tempoShape) { const ts = _serializeShape(bar.tempoShape); if (ts) props.push(` tempo_shape: "${ts}"`); } const lines = doc.split('\n'); const out = []; @@ -278,7 +278,7 @@ function patchBarMeta(doc, bar) { return out.join('\n'); } -function buildNewBarDoc(bar) { +function _buildNewBarDoc(bar) { const lines = [`_id: ${bar.id}`, '_meta:']; const sp = stressorToString(bar.stressor); if (sp) lines.push(` stress_pattern: ${sp}`); @@ -291,15 +291,15 @@ export function patchScore(rawScoreText, instruments, bars = [], info = null, ar const SEP = '\n---\n'; const [header, ...barDocs] = rawScoreText.split(SEP); - let patchedHeader = patchMetadata(header, info); + let patchedHeader = _patchMetadata(header, info); const dirtyArticles = articles.filter(a => a.isDirty); if (dirtyArticles.length || flags.articlesModified) { - patchedHeader = patchArticles(patchedHeader, articles); + patchedHeader = _patchArticles(patchedHeader, articles); for (const a of dirtyArticles) log.push({ level: 'changed', path: `articles / ${a.name}` }); } - patchedHeader = patchInstrumentHeader(patchedHeader, instruments); + patchedHeader = _patchInstrumentHeader(patchedHeader, instruments); for (const i of instruments) { if (i.deleted) log.push({ level: 'changed', path: `instrument / ${i.name} (deleted)` }); else if (i.isDirty) log.push({ level: 'changed', path: `instrument / ${i.name}` }); @@ -309,7 +309,7 @@ export function patchScore(rawScoreText, instruments, bars = [], info = null, ar for (const bar of bars) barMap[bar.id] = bar; if (!barDocs.length) { - const newBarDocs = bars.filter(b => b.isNew && !b.deleted).map(b => buildNewBarDoc(b)); + const newBarDocs = bars.filter(b => b.isNew && !b.deleted).map(b => _buildNewBarDoc(b)); for (const b of bars.filter(b => b.isNew && !b.deleted)) log.push({ level: 'changed', path: `bar / ${b.id}` }); return { text: [patchedHeader, ...newBarDocs].join(SEP), log }; } @@ -324,11 +324,11 @@ export function patchScore(rawScoreText, instruments, bars = [], info = null, ar if (bar.deleted) continue; if (!bar.isDirty) { passedThrough++; patchedBarDocs.push(doc); continue; } log.push({ level: 'changed', path: `bar / ${bar.id}` }); - patchedBarDocs.push(patchBarMeta(doc, bar)); + patchedBarDocs.push(_patchBarMeta(doc, bar)); } for (const bar of bars.filter(b => b.isNew && !b.deleted)) { - patchedBarDocs.push(buildNewBarDoc(bar)); + patchedBarDocs.push(_buildNewBarDoc(bar)); log.push({ level: 'changed', path: `bar / ${bar.id}` }); }