refactor: remove WHAT-comments, keep WHY and RFC references
This commit is contained in:
@@ -29,7 +29,6 @@ export function parseAstLog(text) {
|
|||||||
|
|
||||||
const node = { slot, parentSlot, depth, positionals, props, children: [] };
|
const node = { slot, parentSlot, depth, positionals, props, children: [] };
|
||||||
|
|
||||||
// Pop stack to find correct parent (parent must have depth < current)
|
|
||||||
while (stack.length > 1 && stack[stack.length - 1].depth >= depth) {
|
while (stack.length > 1 && stack[stack.length - 1].depth >= depth) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
@@ -54,18 +53,15 @@ function _parseRest(rest) {
|
|||||||
let inProps = false;
|
let inProps = false;
|
||||||
|
|
||||||
while (i < n) {
|
while (i < n) {
|
||||||
// skip spaces
|
|
||||||
while (i < n && rest[i] === ' ') i++;
|
while (i < n && rest[i] === ' ') i++;
|
||||||
if (i >= n) break;
|
if (i >= n) break;
|
||||||
|
|
||||||
if (rest[i] === "'") {
|
if (rest[i] === "'") {
|
||||||
// single-quoted value (positional string)
|
|
||||||
const j = rest.indexOf("'", i + 1);
|
const j = rest.indexOf("'", i + 1);
|
||||||
const val = rest.slice(i + 1, j === -1 ? n : j);
|
const val = rest.slice(i + 1, j === -1 ? n : j);
|
||||||
i = j === -1 ? n : j + 1;
|
i = j === -1 ? n : j + 1;
|
||||||
if (!inProps) positionals.push(val);
|
if (!inProps) positionals.push(val);
|
||||||
} else {
|
} else {
|
||||||
// scan to next space
|
|
||||||
let j = i;
|
let j = i;
|
||||||
while (j < n && rest[j] !== ' ') j++;
|
while (j < n && rest[j] !== ' ') j++;
|
||||||
const tok = rest.slice(i, j);
|
const tok = rest.slice(i, j);
|
||||||
@@ -78,9 +74,7 @@ function _parseRest(rest) {
|
|||||||
let rawVal = tok.slice(eqIdx + 1);
|
let rawVal = tok.slice(eqIdx + 1);
|
||||||
|
|
||||||
if (rawVal.startsWith("'")) {
|
if (rawVal.startsWith("'")) {
|
||||||
// value continues until next single quote
|
|
||||||
const valStart = i - (tok.length - eqIdx - 1);
|
const valStart = i - (tok.length - eqIdx - 1);
|
||||||
// find closing quote: search from after the opening quote
|
|
||||||
const openPos = rest.indexOf("'", rest.lastIndexOf(key + '=', i) + key.length + 1);
|
const openPos = rest.indexOf("'", rest.lastIndexOf(key + '=', i) + key.length + 1);
|
||||||
const closePos = rest.indexOf("'", openPos + 1);
|
const closePos = rest.indexOf("'", openPos + 1);
|
||||||
rawVal = closePos === -1 ? rest.slice(openPos + 1) : rest.slice(openPos + 1, closePos);
|
rawVal = closePos === -1 ? rest.slice(openPos + 1) : rest.slice(openPos + 1, closePos);
|
||||||
@@ -91,15 +85,12 @@ function _parseRest(rest) {
|
|||||||
} else if (!inProps) {
|
} else if (!inProps) {
|
||||||
positionals.push(coerce(tok));
|
positionals.push(coerce(tok));
|
||||||
}
|
}
|
||||||
// bare token after props start is ignored (shouldn't happen per spec)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { positionals, props };
|
return { positionals, props };
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Second pass: build typed model ──────────────────────────────────────────
|
|
||||||
|
|
||||||
function _collectUnknownProps(nodeProps, knownKeys) {
|
function _collectUnknownProps(nodeProps, knownKeys) {
|
||||||
return Object.fromEntries(Object.entries(nodeProps).filter(([k]) => !knownKeys.has(k)));
|
return Object.fromEntries(Object.entries(nodeProps).filter(([k]) => !knownKeys.has(k)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
// Extended property view rendered as a definition list.
|
|
||||||
// `fields`: array of { key, value, editable?, type? }
|
|
||||||
// `onChange`: called with { key, value } when field changes.
|
|
||||||
export const ObjectExtended = {
|
export const ObjectExtended = {
|
||||||
props: ['fields', 'onChange'],
|
props: ['fields', 'onChange'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
|
|
||||||
// One-line summary row with a drill-down chevron.
|
|
||||||
export const ObjectShort = {
|
export const ObjectShort = {
|
||||||
props: ['label', 'typeTag', 'focused', 'hasChildren', 'readOnly', 'deletable'],
|
props: ['label', 'typeTag', 'focused', 'hasChildren', 'readOnly', 'deletable'],
|
||||||
emits: ['focus', 'drillDown', 'delete'],
|
emits: ['focus', 'drillDown', 'delete'],
|
||||||
|
|||||||
@@ -58,9 +58,7 @@ export const PaneFO = {
|
|||||||
return fp.length ? fp[fp.length - 1] : null;
|
return fp.length ? fp[fp.length - 1] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intercepts the first edit to a linked instrument:
|
// Guard: first edit to a linked instrument triggers embed-or-discard before committing.
|
||||||
// shows embed-or-discard modal before committing. `info.undo`
|
|
||||||
// (forwarded from ShapeEditor/EnvelopeEditor) reverts the mutation on discard.
|
|
||||||
function makeChangeHandler(instr) {
|
function makeChangeHandler(instr) {
|
||||||
return (info) => {
|
return (info) => {
|
||||||
if (instr.isLinked && !instr.isDirty) {
|
if (instr.isLinked && !instr.isDirty) {
|
||||||
|
|||||||
@@ -2,14 +2,11 @@ import { h } from 'vue';
|
|||||||
import { ObjectShort } from './ObjectShort.js';
|
import { ObjectShort } from './ObjectShort.js';
|
||||||
import { getKindGroups } from '../subobject-kinds.js';
|
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+)$/);
|
const m = id.match(/(\d+|\D+)$/);
|
||||||
return m ? id.slice(0, m.index) : id;
|
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+)$/);
|
const m = id.match(/(\d+)$/);
|
||||||
if (!m) return id + '1';
|
if (!m) return id + '1';
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { stressorToString } from './util.js';
|
import { stressorToString } from './util.js';
|
||||||
|
|
||||||
// ── Shape ──────────────────────────────────────────────────────────────────
|
|
||||||
// RFC §1.3.4.5: SHAPE = [PREFIX (":" / ";")] Node 1*(";" Node)
|
// RFC §1.3.4.5: SHAPE = [PREFIX (":" / ";")] Node 1*(";" Node)
|
||||||
// Node = x "," y ["*" z] ["!"]
|
// Node = x "," y ["*" z] ["!"]
|
||||||
// PREFIX+colon is the duration/resolution; optional START+semicolon follows.
|
// PREFIX+colon is the duration/resolution; optional START+semicolon follows.
|
||||||
@@ -19,7 +18,6 @@ function _serializeShape(shape) {
|
|||||||
return prefix + nodes;
|
return prefix + nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── FM / AM modulation ─────────────────────────────────────────────────────
|
|
||||||
// RFC §3.2.1.1.6-7: FM = FREQUENCY ["f"/"F"] ["@" OSC] ["[" SHAPE "]"] ";" MOD ":" BASE
|
// RFC §3.2.1.1.6-7: FM = FREQUENCY ["f"/"F"] ["@" OSC] ["[" SHAPE "]"] ";" MOD ":" BASE
|
||||||
|
|
||||||
function _serializeModulation(m) {
|
function _serializeModulation(m) {
|
||||||
@@ -31,9 +29,7 @@ function _serializeModulation(m) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Basic properties ───────────────────────────────────────────────────────
|
|
||||||
// RFC §3.2.1.1: O, A, S, R, FM go directly in the variation MAPPING.
|
// 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 [];
|
if (!bp) return [];
|
||||||
@@ -50,9 +46,7 @@ function _basicPropLines(bp) {
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Labelled property groups ───────────────────────────────────────────────
|
|
||||||
// RFC §3.2.1.2: label name (3+ lowercase chars) is the MAPPING KEY directly.
|
// 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) {
|
function _labelSpecLines(ls) {
|
||||||
const inner = _basicPropLines(ls.basicProperties);
|
const inner = _basicPropLines(ls.basicProperties);
|
||||||
@@ -60,8 +54,6 @@ function _labelSpecLines(ls) {
|
|||||||
return [`${ls.label}:`, ...inner.map(l => ` ${l}`)];
|
return [`${ls.label}:`, ...inner.map(l => ` ${l}`)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Variation ─────────────────────────────────────────────────────────────
|
|
||||||
// Returns YAML lines for one variation MAPPING (no leading "- ").
|
|
||||||
// RFC §3.2.1.3: VOLUMES, TIMBRE are variation properties, not instrument-level.
|
// RFC §3.2.1.3: VOLUMES, TIMBRE are variation properties, not instrument-level.
|
||||||
|
|
||||||
function _variationLines(v) {
|
function _variationLines(v) {
|
||||||
@@ -81,7 +73,6 @@ function _variationLines(v) {
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Instrument character block ─────────────────────────────────────────────
|
|
||||||
// VOLUMES, TIMBRE, FM are variation properties (RFC §3.2.1.3). The AST parser
|
// VOLUMES, TIMBRE, FM are variation properties (RFC §3.2.1.3). The AST parser
|
||||||
// stores them on the instrument because they appear at depth 01 (root variation
|
// stores them on the instrument because they appear at depth 01 (root variation
|
||||||
// is implicit when no character: wrapper exists). Promote them into a synthetic
|
// is implicit when no character: wrapper exists). Promote them into a synthetic
|
||||||
@@ -125,7 +116,6 @@ function _instrCharacterLines(instr) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Instrument ────────────────────────────────────────────────────────────
|
|
||||||
// RFC §4.4: embedded instrument key is "instrument NAME:" not "instrument: 'NAME'"
|
// RFC §4.4: embedded instrument key is "instrument NAME:" not "instrument: 'NAME'"
|
||||||
|
|
||||||
export function exportInstrument(instr) {
|
export function exportInstrument(instr) {
|
||||||
@@ -136,7 +126,6 @@ export function exportInstrument(instr) {
|
|||||||
return lines.join('\n');
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Articles ───────────────────────────────────────────────────────────────
|
|
||||||
// RFC §4.3: articles: MAPPING { LABEL: { ATTR: VALUE ... } ... }
|
// RFC §4.3: articles: MAPPING { LABEL: { ATTR: VALUE ... } ... }
|
||||||
|
|
||||||
function _serializeArticleValue(v) {
|
function _serializeArticleValue(v) {
|
||||||
@@ -174,8 +163,6 @@ function _patchArticles(text, articles) {
|
|||||||
return lines.join('\n');
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Score patch ────────────────────────────────────────────────────────────
|
|
||||||
// Replace dirty article, instrument, and bar _meta blocks.
|
|
||||||
// Voice note content in bar documents is left verbatim.
|
// Voice note content in bar documents is left verbatim.
|
||||||
|
|
||||||
const META_KEYS = ['title', 'composer', 'source', 'encrypter'];
|
const META_KEYS = ['title', 'composer', 'source', 'encrypter'];
|
||||||
|
|||||||
Reference in New Issue
Block a user