notations 0.0.70 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,6 @@
1
1
  import { Entity } from "./entity";
2
2
  import { Cycle } from "./cycle";
3
3
  import { Line } from "./core";
4
- import { LayoutParams } from "./layouts";
5
4
  import { RoleDef, RawBlock, Block, SectionBlock, RepeatBlock, CycleBlock, BeatDurationBlock, BreaksBlock, RoleBlock, GroupBlock, isBlock, isLine, isRawBlock, findContainingBlock, } from "./block";
6
5
  export { RoleDef, RawBlock, Block, SectionBlock, RepeatBlock, CycleBlock, BeatDurationBlock, BreaksBlock, RoleBlock, GroupBlock, isBlock, isLine, isRawBlock, findContainingBlock, };
7
6
  export class Command extends Entity {
@@ -50,9 +49,6 @@ export class Notation extends Block {
50
49
  this.TYPE = "Notation";
51
50
  this.metadata = new Map();
52
51
  this.onMissingRole = (name) => this.newRoleDef(name, name == "sw");
53
- this._unnamedLayoutParams = [];
54
- this._namedLayoutParams = new Map();
55
- this._layoutParams = null;
56
52
  this._currRoleDef = null;
57
53
  this._currentLine = null;
58
54
  this.localCycle = Cycle.DEFAULT;
@@ -86,57 +82,6 @@ export class Notation extends Block {
86
82
  get roles() {
87
83
  return Array.from(this.localRoles.values());
88
84
  }
89
- get unnamedLayoutParams() {
90
- return this._unnamedLayoutParams;
91
- }
92
- get namedLayoutParams() {
93
- return this._namedLayoutParams;
94
- }
95
- get layoutParams() {
96
- if (this._layoutParams == null) {
97
- this._layoutParams = this.findUnnamedLayoutParams();
98
- if (this._layoutParams == null) {
99
- this._layoutParams = this.snapshotLayoutParams();
100
- this._unnamedLayoutParams.push(this._layoutParams);
101
- }
102
- }
103
- return this._layoutParams;
104
- }
105
- resetLayoutParams() {
106
- this._layoutParams = null;
107
- this.resetLine();
108
- }
109
- ensureNamedLayoutParams(name) {
110
- let lp = this._namedLayoutParams.get(name) || null;
111
- if (lp == null || this._layoutParams != lp) {
112
- if (lp == null) {
113
- lp = this.snapshotLayoutParams();
114
- this._namedLayoutParams.set(name, lp);
115
- }
116
- else {
117
- this.currentCycle = lp.cycle;
118
- this.currentAPB = lp.beatDuration;
119
- this.currentBreaks = lp.lineBreaks;
120
- }
121
- this._layoutParams = lp;
122
- this.resetLine();
123
- }
124
- return this._layoutParams;
125
- }
126
- snapshotLayoutParams() {
127
- return new LayoutParams({
128
- cycle: this.currentCycle,
129
- beatDuration: this.currentAPB,
130
- layout: this.currentBreaks,
131
- });
132
- }
133
- findUnnamedLayoutParams() {
134
- return (this._unnamedLayoutParams.find((lp) => {
135
- return (lp.beatDuration == this.currentAPB &&
136
- this.currentCycle.equals(lp.cycle) &&
137
- lp.lineBreaksEqual(this.currentBreaks));
138
- }) || null);
139
- }
140
85
  setCurrRole(name) {
141
86
  name = name.trim().toLowerCase();
142
87
  if (name.trim() == "") {
@@ -1 +1 @@
1
- {"version":3,"file":"notation.js","sourceRoot":"","sources":["../../src/notation.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity } from \"./entity\";\nimport { Cycle } from \"./cycle\";\nimport { Line } from \"./core\";\nimport { LayoutParams } from \"./layouts\";\nimport {\n RoleDef,\n RawBlock,\n BlockItem,\n Block,\n SectionBlock,\n RepeatBlock,\n CycleBlock,\n BeatDurationBlock,\n BreaksBlock,\n RoleBlock,\n GroupBlock,\n isBlock,\n isLine,\n isRawBlock,\n findContainingBlock,\n} from \"./block\";\n\n// Re-export for backward compatibility\nexport {\n RoleDef,\n RawBlock,\n BlockItem,\n Block,\n SectionBlock,\n RepeatBlock,\n CycleBlock,\n BeatDurationBlock,\n BreaksBlock,\n RoleBlock,\n GroupBlock,\n isBlock,\n isLine,\n isRawBlock,\n findContainingBlock,\n};\n\n/**\n * Type representing a command parameter with optional key and value.\n */\nexport type CmdParam = { key: TSU.Nullable<string>; value: any };\n\n/**\n * Base class for commands in the notation.\n * Commands modify the notation in various ways, such as adding content,\n * changing layout, setting roles, etc.\n */\nexport abstract class Command extends Entity {\n /** Whether this command was auto-generated */\n autoGenerated = false;\n\n /** Previous command in the sequence */\n prevSibling: null | Command = null;\n\n /** Next command in the sequence */\n nextSibling: null | Command = null;\n\n /** Parameters for this command */\n params: CmdParam[];\n\n /** Index of this command in the sequence */\n index: number;\n\n /**\n * Creates a new Command.\n * @param params Optional parameters for the command\n */\n constructor(params: CmdParam[] = []) {\n super();\n this.params = params;\n this.index = 0;\n this.validateParams();\n }\n\n /**\n * Validates the parameters for this command.\n * @throws Error if parameters are invalid\n */\n validateParams(): void {\n //\n }\n\n /**\n * Gets the name of this command.\n */\n get name(): string {\n return this.constructor.name;\n }\n\n /**\n * Returns a debug-friendly representation of this command.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { name: this.name, index: this.index, params: this.params };\n }\n\n /**\n * Gets a parameter value by name.\n * @param name The name of the parameter\n * @returns The parameter value, or null if not found\n */\n getParam(name: string): any {\n for (const param of this.params) {\n if (param.key == name) return param.value;\n }\n return null;\n }\n\n /**\n * Gets a parameter value by index.\n * @param index The index of the parameter\n * @returns The parameter value, or null if not found\n */\n getParamAt(index: number): any {\n return index < this.params.length ? this.params[index].value : null;\n }\n\n /**\n * Applies this command to a block (the primary method).\n * Since Notation extends Block, this works for both.\n * @param container The block to apply this command to\n */\n abstract applyToBlock(container: Block): void;\n\n /**\n * @deprecated Use applyToBlock instead\n * Applies this command to a notation.\n * Default implementation delegates to applyToBlock.\n * @param notation The notation to apply this command to\n */\n applyToNotation(notation: Notation): void {\n this.applyToBlock(notation);\n }\n}\n\n/**\n * Represents metadata for the notation.\n */\nexport class MetaData {\n /**\n * Creates a new MetaData.\n * @param key The key for this metadata\n * @param value The value of this metadata\n * @param params Optional additional parameters\n */\n constructor(\n public readonly key: string,\n public readonly value: string,\n public readonly params?: any,\n ) {\n params = params || {};\n }\n}\n\n/**\n * The main class representing a complete notation.\n * Notation is the root Block of the notation hierarchy.\n * It contains all the elements, settings, and layout information for a piece of music.\n */\nexport class Notation extends Block {\n readonly TYPE = \"Notation\";\n\n // ============================================\n // Notation-specific properties\n // ============================================\n\n /** Metadata associated with this notation */\n metadata = new Map<string, MetaData>();\n\n /** Handler for missing roles */\n onMissingRole: (name: string) => RoleDef | null = (name) => this.newRoleDef(name, name == \"sw\");\n\n /** Layout parameters management */\n private _unnamedLayoutParams: LayoutParams[] = [];\n private _namedLayoutParams = new Map<string, LayoutParams>();\n private _layoutParams: LayoutParams | null = null;\n\n /**\n * Creates a new Notation.\n */\n constructor() {\n super(\"notation\", null);\n // Set default values for root notation\n this.localCycle = Cycle.DEFAULT;\n this.localAtomsPerBeat = 1;\n this.localBreaks = [];\n }\n\n // ============================================\n // Backward compatibility aliases\n // ============================================\n\n /**\n * @deprecated Use blockItems instead\n * Legacy accessor for blocks array.\n */\n get blocks(): BlockItem[] {\n return this.blockItems;\n }\n\n /**\n * @deprecated Use localAtomsPerBeat instead\n * Legacy accessor for current atoms per beat.\n */\n get currentAPB(): number {\n return this.localAtomsPerBeat ?? 1;\n }\n\n set currentAPB(value: number) {\n this.localAtomsPerBeat = value;\n }\n\n /**\n * @deprecated Use localCycle instead\n * Legacy accessor for current cycle.\n */\n get currentCycle(): Cycle {\n return this.localCycle ?? Cycle.DEFAULT;\n }\n\n set currentCycle(value: Cycle) {\n this.localCycle = value;\n }\n\n /**\n * @deprecated Use localBreaks instead\n * Legacy accessor for current breaks.\n */\n get currentBreaks(): number[] {\n return this.localBreaks ?? [];\n }\n\n set currentBreaks(value: number[]) {\n this.localBreaks = value;\n }\n\n /**\n * @deprecated Use localRoles instead\n * Legacy accessor for roles array.\n */\n get roles(): RoleDef[] {\n return Array.from(this.localRoles.values());\n }\n\n // ============================================\n // Layout parameters management\n // ============================================\n\n /**\n * Gets the unnamed layout parameters.\n */\n get unnamedLayoutParams(): ReadonlyArray<LayoutParams> {\n return this._unnamedLayoutParams;\n }\n\n /**\n * Gets the named layout parameters.\n */\n get namedLayoutParams(): ReadonlyMap<string, LayoutParams> {\n return this._namedLayoutParams;\n }\n\n /**\n * Gets the current layout parameters, creating or finding an appropriate one if needed.\n */\n get layoutParams(): LayoutParams {\n if (this._layoutParams == null) {\n // create it or find one that matches current params\n this._layoutParams = this.findUnnamedLayoutParams();\n if (this._layoutParams == null) {\n this._layoutParams = this.snapshotLayoutParams();\n this._unnamedLayoutParams.push(this._layoutParams);\n }\n }\n return this._layoutParams;\n }\n\n /**\n * Resets the current layout parameters to null.\n */\n resetLayoutParams(): void {\n this._layoutParams = null;\n this.resetLine();\n }\n\n /**\n * Ensures that named layout parameters with the given name exist.\n * Creates them if they don't exist, or updates current layout parameters to match.\n *\n * @param name The name of the layout parameters\n * @returns The layout parameters\n */\n ensureNamedLayoutParams(name: string): LayoutParams {\n let lp = this._namedLayoutParams.get(name) || null;\n if (lp == null || this._layoutParams != lp) {\n // no change so go ahead\n if (lp == null) {\n // does not exist so create one by re-snapshotting it\n // and saving it\n lp = this.snapshotLayoutParams();\n this._namedLayoutParams.set(name, lp);\n } else {\n // copy named LPs attributes into our locals\n this.currentCycle = lp.cycle;\n this.currentAPB = lp.beatDuration;\n this.currentBreaks = lp.lineBreaks;\n }\n this._layoutParams = lp;\n this.resetLine(); // since layout params have changed\n }\n return this._layoutParams;\n }\n\n /**\n * Creates a snapshot of the current layout parameters.\n * @returns A new LayoutParams object with the current settings\n */\n protected snapshotLayoutParams(): LayoutParams {\n return new LayoutParams({\n cycle: this.currentCycle,\n beatDuration: this.currentAPB,\n layout: this.currentBreaks,\n });\n }\n\n /**\n * Finds an unnamed layout parameters object that matches the current settings.\n * @returns Matching layout parameters, or null if none found\n */\n protected findUnnamedLayoutParams(): LayoutParams | null {\n return (\n this._unnamedLayoutParams.find((lp) => {\n return (\n lp.beatDuration == this.currentAPB &&\n this.currentCycle.equals(lp.cycle) &&\n lp.lineBreaksEqual(this.currentBreaks)\n );\n }) || null\n );\n }\n\n // ============================================\n // Overridden methods\n // ============================================\n\n /**\n * Sets the current role by name.\n * Uses onMissingRole callback for auto-creation of missing roles.\n * @param name The name of the role to set as current\n * @throws Error if the name is empty or the role is not found\n */\n setCurrRole(name: string): void {\n name = name.trim().toLowerCase();\n if (name.trim() == \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n const roleDef = this.getRole(name) || (this.onMissingRole ? this.onMissingRole(name) || null : null);\n if (roleDef == null) {\n throw new Error(\"Role not found: \" + name);\n }\n this._currRoleDef = roleDef;\n }\n\n /**\n * Gets a role definition by name.\n * Handles empty name by returning the last added role.\n * @param name The name of the role\n * @returns The role definition, or null if not found\n */\n getRoleDef(name: string): TSU.Nullable<RoleDef> {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n // Return the last added role if name is empty\n const roles = Array.from(this.localRoles.values());\n return roles[roles.length - 1] || null;\n }\n return this.localRoles.get(name) ?? null;\n }\n\n /**\n * Creates a new role definition.\n * @param name The name of the role\n * @param notesOnly Whether the role contains only notes, defaults to false\n * @returns The created role definition\n * @throws Error if the name is empty or the role already exists\n */\n newRoleDef(name: string, notesOnly = false): RoleDef {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n if (this.localRoles.has(name)) {\n throw new Error(\"Role already exists: \" + name);\n }\n // create new and add\n const rd = new RoleDef();\n rd.name = name;\n rd.notesOnly = notesOnly;\n rd.index = this.localRoles.size;\n this.localRoles.set(name, rd);\n\n return rd;\n }\n\n // ============================================\n // Additional methods\n // ============================================\n\n /**\n * Adds a line to this notation.\n * @param line The line to add\n */\n addLine(line: Line): void {\n this.addBlockItem(line);\n }\n\n /**\n * Removes a line from this notation.\n * @param line The line to remove\n * @returns The index of the removed line, or -1 if not found\n */\n removeLine(line: Line): number {\n return this.removeBlockItem(line);\n }\n\n /**\n * Adds a raw block to this notation.\n * @param raw The raw block to add\n */\n addRawBlock(raw: RawBlock): void {\n this.addBlockItem(raw);\n this.resetLine();\n }\n\n /**\n * Adds metadata to this notation.\n * @param meta The metadata to add\n * @param addBlock Whether to add a corresponding raw block, defaults to true\n */\n addMetaData(meta: MetaData, addBlock = true): void {\n if (addBlock && !this.metadata.has(meta.key)) {\n // Add a new raw block here\n // set this by key so even if metadata changes we can\n // get latest value of it\n const raw = new RawBlock(meta.key, \"metadata\");\n this.addRawBlock(raw);\n }\n this.metadata.set(meta.key, meta);\n }\n\n /**\n * Resets the current line pointer to null.\n */\n resetLine(): void {\n this._currentLine = null;\n }\n\n /**\n * Returns a debug-friendly representation of this notation.\n * Uses Notation-specific property names for backward compatibility.\n * @returns An object containing debug information\n */\n debugValue(): any {\n // Use Notation-specific names (blocks, currentCycle, etc.)\n // instead of Block names (blockItems, localCycle, etc.)\n // to maintain backward compatibility with existing tests\n return {\n blocks: this.blocks.map((b) => b.debugValue()),\n currentAPB: this.currentAPB,\n currentBreaks: this.currentBreaks,\n currentCycle: this.currentCycle?.uuid,\n roles: this.roles,\n };\n }\n\n // Need protected access to _currRoleDef for setCurrRole override\n protected _currRoleDef: TSU.Nullable<RoleDef> = null;\n\n /**\n * Gets the current role definition.\n */\n get currRoleDef(): RoleDef | null {\n if (this._currRoleDef == null) {\n const roles = Array.from(this.localRoles.values());\n if (roles.length === 0) {\n return null;\n } else {\n this._currRoleDef = roles[roles.length - 1];\n }\n }\n return this._currRoleDef;\n }\n\n // Need protected access to _currentLine for resetLine\n protected _currentLine: Line | null = null;\n\n /**\n * Gets the current line, creating it if needed.\n */\n get currentLine(): Line {\n if (this._currentLine == null) {\n return this.newLine();\n }\n return this._currentLine;\n }\n\n /**\n * Creates a new line and makes it the current line.\n * @returns The newly created line\n */\n newLine(): Line {\n if (this._currentLine && this._currentLine.isEmpty) {\n // then remove it first instead of adding another\n // so we dont have a string of empty lines\n this.removeLine(this._currentLine);\n }\n this._currentLine = new Line();\n this.addLine(this._currentLine);\n return this._currentLine;\n }\n}\n"]}
1
+ {"version":3,"file":"notation.js","sourceRoot":"","sources":["../../src/notation.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity } from \"./entity\";\nimport { Cycle } from \"./cycle\";\nimport { Line } from \"./core\";\nimport {\n RoleDef,\n RawBlock,\n BlockItem,\n Block,\n SectionBlock,\n RepeatBlock,\n CycleBlock,\n BeatDurationBlock,\n BreaksBlock,\n RoleBlock,\n GroupBlock,\n isBlock,\n isLine,\n isRawBlock,\n findContainingBlock,\n} from \"./block\";\n\n// Re-export for backward compatibility\nexport {\n RoleDef,\n RawBlock,\n BlockItem,\n Block,\n SectionBlock,\n RepeatBlock,\n CycleBlock,\n BeatDurationBlock,\n BreaksBlock,\n RoleBlock,\n GroupBlock,\n isBlock,\n isLine,\n isRawBlock,\n findContainingBlock,\n};\n\n/**\n * Type representing a command parameter with optional key and value.\n */\nexport type CmdParam = { key: TSU.Nullable<string>; value: any };\n\n/**\n * Base class for commands in the notation.\n * Commands modify the notation in various ways, such as adding content,\n * changing layout, setting roles, etc.\n */\nexport abstract class Command extends Entity {\n /** Whether this command was auto-generated */\n autoGenerated = false;\n\n /** Previous command in the sequence */\n prevSibling: null | Command = null;\n\n /** Next command in the sequence */\n nextSibling: null | Command = null;\n\n /** Parameters for this command */\n params: CmdParam[];\n\n /** Index of this command in the sequence */\n index: number;\n\n /**\n * Creates a new Command.\n * @param params Optional parameters for the command\n */\n constructor(params: CmdParam[] = []) {\n super();\n this.params = params;\n this.index = 0;\n this.validateParams();\n }\n\n /**\n * Validates the parameters for this command.\n * @throws Error if parameters are invalid\n */\n validateParams(): void {\n //\n }\n\n /**\n * Gets the name of this command.\n */\n get name(): string {\n return this.constructor.name;\n }\n\n /**\n * Returns a debug-friendly representation of this command.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { name: this.name, index: this.index, params: this.params };\n }\n\n /**\n * Gets a parameter value by name.\n * @param name The name of the parameter\n * @returns The parameter value, or null if not found\n */\n getParam(name: string): any {\n for (const param of this.params) {\n if (param.key == name) return param.value;\n }\n return null;\n }\n\n /**\n * Gets a parameter value by index.\n * @param index The index of the parameter\n * @returns The parameter value, or null if not found\n */\n getParamAt(index: number): any {\n return index < this.params.length ? this.params[index].value : null;\n }\n\n /**\n * Applies this command to a block (the primary method).\n * Since Notation extends Block, this works for both.\n * @param container The block to apply this command to\n */\n abstract applyToBlock(container: Block): void;\n\n /**\n * @deprecated Use applyToBlock instead\n * Applies this command to a notation.\n * Default implementation delegates to applyToBlock.\n * @param notation The notation to apply this command to\n */\n applyToNotation(notation: Notation): void {\n this.applyToBlock(notation);\n }\n}\n\n/**\n * Represents metadata for the notation.\n */\nexport class MetaData {\n /**\n * Creates a new MetaData.\n * @param key The key for this metadata\n * @param value The value of this metadata\n * @param params Optional additional parameters\n */\n constructor(\n public readonly key: string,\n public readonly value: string,\n public readonly params?: any,\n ) {\n params = params || {};\n }\n}\n\n/**\n * The main class representing a complete notation.\n * Notation is the root Block of the notation hierarchy.\n * It contains all the elements, settings, and layout information for a piece of music.\n */\nexport class Notation extends Block {\n readonly TYPE = \"Notation\";\n\n // ============================================\n // Notation-specific properties\n // ============================================\n\n /** Metadata associated with this notation */\n metadata = new Map<string, MetaData>();\n\n /** Handler for missing roles */\n onMissingRole: (name: string) => RoleDef | null = (name) => this.newRoleDef(name, name == \"sw\");\n\n /**\n * Creates a new Notation.\n */\n constructor() {\n super(\"notation\", null);\n // Set default values for root notation\n this.localCycle = Cycle.DEFAULT;\n this.localAtomsPerBeat = 1;\n this.localBreaks = [];\n }\n\n // ============================================\n // Backward compatibility aliases\n // ============================================\n\n /**\n * @deprecated Use blockItems instead\n * Legacy accessor for blocks array.\n */\n get blocks(): BlockItem[] {\n return this.blockItems;\n }\n\n /**\n * @deprecated Use localAtomsPerBeat instead\n * Legacy accessor for current atoms per beat.\n */\n get currentAPB(): number {\n return this.localAtomsPerBeat ?? 1;\n }\n\n set currentAPB(value: number) {\n this.localAtomsPerBeat = value;\n }\n\n /**\n * @deprecated Use localCycle instead\n * Legacy accessor for current cycle.\n */\n get currentCycle(): Cycle {\n return this.localCycle ?? Cycle.DEFAULT;\n }\n\n set currentCycle(value: Cycle) {\n this.localCycle = value;\n }\n\n /**\n * @deprecated Use localBreaks instead\n * Legacy accessor for current breaks.\n */\n get currentBreaks(): number[] {\n return this.localBreaks ?? [];\n }\n\n set currentBreaks(value: number[]) {\n this.localBreaks = value;\n }\n\n /**\n * @deprecated Use localRoles instead\n * Legacy accessor for roles array.\n */\n get roles(): RoleDef[] {\n return Array.from(this.localRoles.values());\n }\n\n // ============================================\n // Overridden methods\n // ============================================\n\n /**\n * Sets the current role by name.\n * Uses onMissingRole callback for auto-creation of missing roles.\n * @param name The name of the role to set as current\n * @throws Error if the name is empty or the role is not found\n */\n setCurrRole(name: string): void {\n name = name.trim().toLowerCase();\n if (name.trim() == \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n const roleDef = this.getRole(name) || (this.onMissingRole ? this.onMissingRole(name) || null : null);\n if (roleDef == null) {\n throw new Error(\"Role not found: \" + name);\n }\n this._currRoleDef = roleDef;\n }\n\n /**\n * Gets a role definition by name.\n * Handles empty name by returning the last added role.\n * @param name The name of the role\n * @returns The role definition, or null if not found\n */\n getRoleDef(name: string): TSU.Nullable<RoleDef> {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n // Return the last added role if name is empty\n const roles = Array.from(this.localRoles.values());\n return roles[roles.length - 1] || null;\n }\n return this.localRoles.get(name) ?? null;\n }\n\n /**\n * Creates a new role definition.\n * @param name The name of the role\n * @param notesOnly Whether the role contains only notes, defaults to false\n * @returns The created role definition\n * @throws Error if the name is empty or the role already exists\n */\n newRoleDef(name: string, notesOnly = false): RoleDef {\n name = name.trim().toLowerCase();\n if (name === \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n if (this.localRoles.has(name)) {\n throw new Error(\"Role already exists: \" + name);\n }\n // create new and add\n const rd = new RoleDef();\n rd.name = name;\n rd.notesOnly = notesOnly;\n rd.index = this.localRoles.size;\n this.localRoles.set(name, rd);\n\n return rd;\n }\n\n // ============================================\n // Additional methods\n // ============================================\n\n /**\n * Adds a line to this notation.\n * @param line The line to add\n */\n addLine(line: Line): void {\n this.addBlockItem(line);\n }\n\n /**\n * Removes a line from this notation.\n * @param line The line to remove\n * @returns The index of the removed line, or -1 if not found\n */\n removeLine(line: Line): number {\n return this.removeBlockItem(line);\n }\n\n /**\n * Adds a raw block to this notation.\n * @param raw The raw block to add\n */\n addRawBlock(raw: RawBlock): void {\n this.addBlockItem(raw);\n this.resetLine();\n }\n\n /**\n * Adds metadata to this notation.\n * @param meta The metadata to add\n * @param addBlock Whether to add a corresponding raw block, defaults to true\n */\n addMetaData(meta: MetaData, addBlock = true): void {\n if (addBlock && !this.metadata.has(meta.key)) {\n // Add a new raw block here\n // set this by key so even if metadata changes we can\n // get latest value of it\n const raw = new RawBlock(meta.key, \"metadata\");\n this.addRawBlock(raw);\n }\n this.metadata.set(meta.key, meta);\n }\n\n /**\n * Resets the current line pointer to null.\n */\n resetLine(): void {\n this._currentLine = null;\n }\n\n /**\n * Returns a debug-friendly representation of this notation.\n * Uses Notation-specific property names for backward compatibility.\n * @returns An object containing debug information\n */\n debugValue(): any {\n // Use Notation-specific names (blocks, currentCycle, etc.)\n // instead of Block names (blockItems, localCycle, etc.)\n // to maintain backward compatibility with existing tests\n return {\n blocks: this.blocks.map((b) => b.debugValue()),\n currentAPB: this.currentAPB,\n currentBreaks: this.currentBreaks,\n currentCycle: this.currentCycle?.uuid,\n roles: this.roles,\n };\n }\n\n // Need protected access to _currRoleDef for setCurrRole override\n protected _currRoleDef: TSU.Nullable<RoleDef> = null;\n\n /**\n * Gets the current role definition.\n */\n get currRoleDef(): RoleDef | null {\n if (this._currRoleDef == null) {\n const roles = Array.from(this.localRoles.values());\n if (roles.length === 0) {\n return null;\n } else {\n this._currRoleDef = roles[roles.length - 1];\n }\n }\n return this._currRoleDef;\n }\n\n // Need protected access to _currentLine for resetLine\n protected _currentLine: Line | null = null;\n\n /**\n * Gets the current line, creating it if needed.\n */\n get currentLine(): Line {\n if (this._currentLine == null) {\n return this.newLine();\n }\n return this._currentLine;\n }\n\n /**\n * Creates a new line and makes it the current line.\n * @returns The newly created line\n */\n newLine(): Line {\n if (this._currentLine && this._currentLine.isEmpty) {\n // then remove it first instead of adding another\n // so we dont have a string of empty lines\n this.removeLine(this._currentLine);\n }\n this._currentLine = new Line();\n this.addLine(this._currentLine);\n return this._currentLine;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notations",
3
- "version": "0.0.70",
3
+ "version": "1.0.0",
4
4
  "author": "Sriram Panyam",
5
5
  "description": "A package for modelling, parsing, laying out carnatic musical notation",
6
6
  "homepage": "https://github.com/panyam/notations#readme",
@@ -74,6 +74,28 @@
74
74
  color: var(--notation-text-color);
75
75
  }
76
76
 
77
+ /* ========================================
78
+ Role-specific Styles
79
+ ======================================== */
80
+
81
+ /* Swara (Sw) role - blue in light theme for distinction from Sahitya */
82
+ .role_sw text {
83
+ fill: #2563eb; /* Blue-600 */
84
+ }
85
+
86
+ /* Dark mode - red for swara */
87
+ :root.dark .role_sw text,
88
+ [data-theme="dark"] .role_sw text {
89
+ fill: #ef4444; /* Red-500 */
90
+ }
91
+
92
+ /* System preference fallback for dark mode */
93
+ @media (prefers-color-scheme: dark) {
94
+ :root:not(.light):not([data-theme="light"]) .role_sw text {
95
+ fill: #ef4444; /* Red-500 */
96
+ }
97
+ }
98
+
77
99
  /* ========================================
78
100
  Layout Styles
79
101
  ======================================== */