notations 0.0.67 → 0.0.68

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.
Files changed (52) hide show
  1. package/dist/NotationView.css +100 -0
  2. package/dist/NotationView.css.map +1 -0
  3. package/dist/NotationView.min.css +1 -0
  4. package/dist/NotationView.min.css.map +1 -0
  5. package/dist/notations.umd.js +35875 -0
  6. package/dist/notations.umd.min.js +112 -0
  7. package/dist/notations.umd.min.js.LICENSE.txt +24 -0
  8. package/dist/notations.umd.min.js.map +1 -0
  9. package/lib/cjs/beats.js.map +1 -1
  10. package/lib/cjs/beatutils.js.map +1 -1
  11. package/lib/cjs/beatview.js.map +1 -1
  12. package/lib/cjs/carnatic/LineView.js.map +1 -1
  13. package/lib/cjs/carnatic/NotationView.js.map +1 -1
  14. package/lib/cjs/carnatic/embelishments.js +3 -8
  15. package/lib/cjs/carnatic/embelishments.js.map +1 -1
  16. package/lib/cjs/carnatic/gamakas.js.map +1 -1
  17. package/lib/cjs/commands.js.map +1 -1
  18. package/lib/cjs/core.js.map +1 -1
  19. package/lib/cjs/cycle.js.map +1 -1
  20. package/lib/cjs/entity.js.map +1 -1
  21. package/lib/cjs/grids.js.map +1 -1
  22. package/lib/cjs/iterators.js.map +1 -1
  23. package/lib/cjs/layouts.js.map +1 -1
  24. package/lib/cjs/loader.js.map +1 -1
  25. package/lib/cjs/notation.js.map +1 -1
  26. package/lib/cjs/parser.js.map +1 -1
  27. package/lib/cjs/shapes.js +1 -1
  28. package/lib/cjs/shapes.js.map +1 -1
  29. package/lib/cjs/utils.js.map +1 -1
  30. package/lib/esm/beats.js.map +1 -1
  31. package/lib/esm/beatutils.js.map +1 -1
  32. package/lib/esm/beatview.js.map +1 -1
  33. package/lib/esm/carnatic/LineView.js.map +1 -1
  34. package/lib/esm/carnatic/NotationView.js.map +1 -1
  35. package/lib/esm/carnatic/embelishments.js +3 -8
  36. package/lib/esm/carnatic/embelishments.js.map +1 -1
  37. package/lib/esm/carnatic/gamakas.js.map +1 -1
  38. package/lib/esm/commands.js.map +1 -1
  39. package/lib/esm/core.js.map +1 -1
  40. package/lib/esm/cycle.js.map +1 -1
  41. package/lib/esm/entity.js.map +1 -1
  42. package/lib/esm/grids.js.map +1 -1
  43. package/lib/esm/iterators.js.map +1 -1
  44. package/lib/esm/layouts.js.map +1 -1
  45. package/lib/esm/loader.js.map +1 -1
  46. package/lib/esm/notation.js.map +1 -1
  47. package/lib/esm/parser.js.map +1 -1
  48. package/lib/esm/shapes.js +1 -1
  49. package/lib/esm/shapes.js.map +1 -1
  50. package/lib/esm/utils.js.map +1 -1
  51. package/package.json +22 -15
  52. package/styles/NotationView.scss +74 -1
@@ -1 +1 @@
1
- {"version":3,"file":"iterators.js","sourceRoot":"","sources":["../../src/iterators.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { TimedEntity } from \"./entity\";\nimport { Atom, LeafAtom, Space, Group, AtomType } from \"./core\";\n\ntype Fraction = TSU.Num.Fraction;\n// type FlatAtom2 = [atom: Atom, duration: TSU.Num.Fraction, offset: TSU.Num.Fraction];\n\n/**\n * Represents a flattened atom with timing information.\n * FlatAtom is used to process nested atom structures in a flat, sequential manner\n * with proper timing information.\n */\nexport class FlatAtom extends TimedEntity {\n readonly TYPE = \"FlatAtom\";\n\n /** Nesting depth of this atom in the original structure */\n depth: number;\n \n /** Duration of this atom */\n duration: TSU.Num.Fraction;\n \n /** Time offset of this atom */\n offset: TSU.Num.Fraction;\n \n /** Whether this atom is a continuation of a previous atom */\n private isContinuation: boolean;\n\n /**\n * Creates a new FlatAtom.\n * @param atom The leaf atom this flat atom represents\n * @param config Optional configuration with depth, duration, offset, and continuation info\n */\n constructor(public atom: LeafAtom, config: any = null) {\n super((config = config || {}));\n this.depth = config.depth || 0;\n this.duration = config.duration || atom.duration;\n this.offset = config.offset || TSU.Num.Fraction.ZERO;\n this.isContinuation = \"isContinuation\" in config ? config.isContinuation : false;\n }\n\n /**\n * Gets the end offset of this atom (offset + duration).\n */\n get endOffset(): TSU.Num.Fraction {\n return this.offset.plus(this.duration);\n }\n\n /**\n * Returns a debug-friendly representation of this FlatAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n atom: this.atom.debugValue(),\n duration: this.duration.toString(),\n offset: this.offset.toString(),\n depth: this.depth,\n };\n if (this.isContinuation) out.isContinuation = true;\n return out;\n }\n}\n\n/**\n * A nested atom iterator that returns one atom at a time at the leaf-most level.\n * If we have a Group (or nested Groups) only the leaf atoms are returned as if\n * in an in-order traversal, thus ensuring time order of atoms.\n */\nexport class AtomIterator {\n private atomQueue = new TSU.Lists.List<[Atom, number, Fraction]>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<FlatAtom> = null;\n\n /**\n * Creates a new AtomIterator with optional initial atoms.\n * @param atoms Initial atoms to iterate through\n */\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be flattened and served by this iterator.\n * @param atoms The atoms to add to the queue\n * @returns This iterator instance for method chaining\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add([atom, 0, atom.duration]);\n }\n return this;\n }\n\n /**\n * Gets the next atom in the sequence and advances the iterator.\n * @returns The next FlatAtom, or null if no more atoms are available\n */\n next(): TSU.Nullable<FlatAtom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration).factorized;\n }\n return out;\n }\n\n /**\n * Peeks at the next atom without advancing the iterator.\n * @returns The next FlatAtom, or null if no more atoms are available\n */\n peek(): TSU.Nullable<FlatAtom> {\n if (this.peeked == null) {\n if (this.hasNext) {\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.popFront();\n this.peeked = new FlatAtom(nextAtom as LeafAtom, {\n depth: nextDepth,\n offset: this.currOffset,\n duration: nextDuration,\n });\n }\n }\n return this.peeked;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n * This may process group atoms to find the next leaf atom.\n */\n get hasNext(): boolean {\n while (this.atomQueue.first != null) {\n // Get from front of queue\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.first.value;\n if (nextAtom.TYPE != AtomType.GROUP) {\n return true;\n } else {\n this.atomQueue.popFront();\n const group = nextAtom as Group;\n for (const child of group.atoms.reversedValues()) {\n this.atomQueue.pushFront([\n child,\n nextDepth + 1,\n nextDuration.times(child.duration).divby(group.totalChildDuration).factorized,\n ]);\n }\n }\n }\n return false;\n }\n\n /**\n * Gets the atom with the minimum offset from multiple iterators.\n * @param iterators An array of AtomIterators to compare\n * @returns A tuple containing the index of the selected iterator and its next atom\n */\n static getMin(iterators: AtomIterator[]): [number, FlatAtom] {\n let currRole = -1;\n let currAtom: TSU.Nullable<FlatAtom> = null;\n for (let ri = 0; ri < iterators.length; ri++) {\n const flatAtom = iterators[ri].peek();\n if (flatAtom != null) {\n if (currAtom == null || flatAtom.offset.cmp(currAtom.offset) < 0) {\n currRole = ri;\n currAtom = flatAtom;\n }\n }\n }\n if (currRole >= 0) {\n iterators[currRole].next();\n }\n return [currRole, currAtom!];\n }\n}\n\n/**\n * An iterator that provides atoms within specified time windows.\n * WindowIterator allows fetching atoms to cover a specific duration,\n * handling the splitting of atoms if necessary.\n */\nexport class WindowIterator {\n private atomQueue = new TSU.Lists.List<Atom>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<Atom> = null;\n\n /**\n * Creates a new WindowIterator with optional initial atoms.\n * @param atoms Initial atoms to iterate through\n */\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be served by this iterator.\n * @param atoms The atoms to add to the queue\n * @returns This iterator instance for method chaining\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add(atom);\n }\n return this;\n }\n\n /**\n * Gets the next atom in the sequence and advances the iterator.\n * @returns The next Atom, or null if no more atoms are available\n */\n next(): TSU.Nullable<Atom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration, true);\n }\n return out;\n }\n\n /**\n * Peeks at the next atom without advancing the iterator.\n * @returns The next Atom, or null if no more atoms are available\n */\n peek(): TSU.Nullable<Atom> {\n if (this.peeked == null && this.hasMore) {\n this.peeked = this.atomQueue.popFront();\n }\n return this.peeked;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n */\n get hasMore(): boolean {\n return !this.atomQueue.isEmpty;\n }\n\n /**\n * Gets atoms to cover the specified duration.\n * \n * If the number of atoms left in the iterator is 0, an empty list\n * is returned. Otherwise, the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n * \n * @param duration The duration to cover\n * @returns A tuple containing the array of atoms and whether the full duration was filled\n */\n get(duration: TSU.Num.Fraction): [Atom[], boolean] {\n const out: Atom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0) && this.hasMore) {\n const next = this.next();\n TSU.assert(next != null, \"Next cannot be null here\");\n out.push(next);\n const spillOver = next.splitAt(remaining);\n remaining = remaining.minus(next.duration);\n if (spillOver != null) {\n // push the spill over to the front of the queue to be\n // picked up on the next \"get\" call\n this.atomQueue.pushFront(spillOver);\n }\n }\n return [out, remaining.isZero];\n }\n}\n\n/**\n * An iterator that provides atoms with specific durations.\n * DurationIterator ensures that atoms fit within specified duration windows,\n * splitting atoms if necessary to fit.\n */\nexport class DurationIterator {\n private atomIterator: AtomIterator;\n private spillOver: TSU.Nullable<FlatAtom> = null;\n\n /**\n * Creates a new DurationIterator.\n * @param atomIterator The AtomIterator to use as a source of atoms\n */\n constructor(atomIterator: AtomIterator) {\n this.atomIterator = atomIterator;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n */\n get hasMore(): boolean {\n if (this.spillOver != null) {\n return true;\n }\n return this.atomIterator.hasNext;\n }\n\n /**\n * Gets atoms to cover the specified duration.\n * \n * If the number of atoms left in the iterator is 0, an empty list\n * is returned. Otherwise, the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n * \n * @param duration The duration to cover\n * @returns A tuple containing the array of FlatAtoms and whether the full duration was filled\n */\n get(duration: TSU.Num.Fraction): [FlatAtom[], boolean] {\n const iter = this.atomIterator;\n const out: FlatAtom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0)) {\n const next = this.spillOver == null ? iter.next() : this.spillOver;\n this.spillOver = null;\n if (next == null) {\n // stop here\n break;\n } else {\n out.push(next);\n if (next.duration.cmp(remaining) <= 0) {\n remaining = remaining.minus(next.duration);\n } else {\n // Next leaf atom is > duration\n // so split it into two\n this.spillOver = new FlatAtom(new Space(next.duration.minus(remaining)));\n next.duration = remaining;\n remaining = TSU.Num.Fraction.ZERO;\n }\n }\n }\n return [out, remaining.isZero];\n }\n}\n"]}
1
+ {"version":3,"file":"iterators.js","sourceRoot":"","sources":["../../src/iterators.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { TimedEntity } from \"./entity\";\nimport { Atom, LeafAtom, Space, Group, AtomType } from \"./core\";\n\ntype Fraction = TSU.Num.Fraction;\n// type FlatAtom2 = [atom: Atom, duration: TSU.Num.Fraction, offset: TSU.Num.Fraction];\n\n/**\n * Represents a flattened atom with timing information.\n * FlatAtom is used to process nested atom structures in a flat, sequential manner\n * with proper timing information.\n */\nexport class FlatAtom extends TimedEntity {\n readonly TYPE = \"FlatAtom\";\n\n /** Nesting depth of this atom in the original structure */\n depth: number;\n\n /** Duration of this atom */\n duration: TSU.Num.Fraction;\n\n /** Time offset of this atom */\n offset: TSU.Num.Fraction;\n\n /** Whether this atom is a continuation of a previous atom */\n private isContinuation: boolean;\n\n /**\n * Creates a new FlatAtom.\n * @param atom The leaf atom this flat atom represents\n * @param config Optional configuration with depth, duration, offset, and continuation info\n */\n constructor(\n public atom: LeafAtom,\n config: any = null,\n ) {\n super((config = config || {}));\n this.depth = config.depth || 0;\n this.duration = config.duration || atom.duration;\n this.offset = config.offset || TSU.Num.Fraction.ZERO;\n this.isContinuation = \"isContinuation\" in config ? config.isContinuation : false;\n }\n\n /**\n * Gets the end offset of this atom (offset + duration).\n */\n get endOffset(): TSU.Num.Fraction {\n return this.offset.plus(this.duration);\n }\n\n /**\n * Returns a debug-friendly representation of this FlatAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n atom: this.atom.debugValue(),\n duration: this.duration.toString(),\n offset: this.offset.toString(),\n depth: this.depth,\n };\n if (this.isContinuation) out.isContinuation = true;\n return out;\n }\n}\n\n/**\n * A nested atom iterator that returns one atom at a time at the leaf-most level.\n * If we have a Group (or nested Groups) only the leaf atoms are returned as if\n * in an in-order traversal, thus ensuring time order of atoms.\n */\nexport class AtomIterator {\n private atomQueue = new TSU.Lists.List<[Atom, number, Fraction]>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<FlatAtom> = null;\n\n /**\n * Creates a new AtomIterator with optional initial atoms.\n * @param atoms Initial atoms to iterate through\n */\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be flattened and served by this iterator.\n * @param atoms The atoms to add to the queue\n * @returns This iterator instance for method chaining\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add([atom, 0, atom.duration]);\n }\n return this;\n }\n\n /**\n * Gets the next atom in the sequence and advances the iterator.\n * @returns The next FlatAtom, or null if no more atoms are available\n */\n next(): TSU.Nullable<FlatAtom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration).factorized;\n }\n return out;\n }\n\n /**\n * Peeks at the next atom without advancing the iterator.\n * @returns The next FlatAtom, or null if no more atoms are available\n */\n peek(): TSU.Nullable<FlatAtom> {\n if (this.peeked == null) {\n if (this.hasNext) {\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.popFront();\n this.peeked = new FlatAtom(nextAtom as LeafAtom, {\n depth: nextDepth,\n offset: this.currOffset,\n duration: nextDuration,\n });\n }\n }\n return this.peeked;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n * This may process group atoms to find the next leaf atom.\n */\n get hasNext(): boolean {\n while (this.atomQueue.first != null) {\n // Get from front of queue\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.first.value;\n if (nextAtom.TYPE != AtomType.GROUP) {\n return true;\n } else {\n this.atomQueue.popFront();\n const group = nextAtom as Group;\n for (const child of group.atoms.reversedValues()) {\n this.atomQueue.pushFront([\n child,\n nextDepth + 1,\n nextDuration.times(child.duration).divby(group.totalChildDuration).factorized,\n ]);\n }\n }\n }\n return false;\n }\n\n /**\n * Gets the atom with the minimum offset from multiple iterators.\n * @param iterators An array of AtomIterators to compare\n * @returns A tuple containing the index of the selected iterator and its next atom\n */\n static getMin(iterators: AtomIterator[]): [number, FlatAtom] {\n let currRole = -1;\n let currAtom: TSU.Nullable<FlatAtom> = null;\n for (let ri = 0; ri < iterators.length; ri++) {\n const flatAtom = iterators[ri].peek();\n if (flatAtom != null) {\n if (currAtom == null || flatAtom.offset.cmp(currAtom.offset) < 0) {\n currRole = ri;\n currAtom = flatAtom;\n }\n }\n }\n if (currRole >= 0) {\n iterators[currRole].next();\n }\n return [currRole, currAtom!];\n }\n}\n\n/**\n * An iterator that provides atoms within specified time windows.\n * WindowIterator allows fetching atoms to cover a specific duration,\n * handling the splitting of atoms if necessary.\n */\nexport class WindowIterator {\n private atomQueue = new TSU.Lists.List<Atom>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<Atom> = null;\n\n /**\n * Creates a new WindowIterator with optional initial atoms.\n * @param atoms Initial atoms to iterate through\n */\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be served by this iterator.\n * @param atoms The atoms to add to the queue\n * @returns This iterator instance for method chaining\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add(atom);\n }\n return this;\n }\n\n /**\n * Gets the next atom in the sequence and advances the iterator.\n * @returns The next Atom, or null if no more atoms are available\n */\n next(): TSU.Nullable<Atom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration, true);\n }\n return out;\n }\n\n /**\n * Peeks at the next atom without advancing the iterator.\n * @returns The next Atom, or null if no more atoms are available\n */\n peek(): TSU.Nullable<Atom> {\n if (this.peeked == null && this.hasMore) {\n this.peeked = this.atomQueue.popFront();\n }\n return this.peeked;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n */\n get hasMore(): boolean {\n return !this.atomQueue.isEmpty;\n }\n\n /**\n * Gets atoms to cover the specified duration.\n *\n * If the number of atoms left in the iterator is 0, an empty list\n * is returned. Otherwise, the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n *\n * @param duration The duration to cover\n * @returns A tuple containing the array of atoms and whether the full duration was filled\n */\n get(duration: TSU.Num.Fraction): [Atom[], boolean] {\n const out: Atom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0) && this.hasMore) {\n const next = this.next();\n TSU.assert(next != null, \"Next cannot be null here\");\n out.push(next);\n const spillOver = next.splitAt(remaining);\n remaining = remaining.minus(next.duration);\n if (spillOver != null) {\n // push the spill over to the front of the queue to be\n // picked up on the next \"get\" call\n this.atomQueue.pushFront(spillOver);\n }\n }\n return [out, remaining.isZero];\n }\n}\n\n/**\n * An iterator that provides atoms with specific durations.\n * DurationIterator ensures that atoms fit within specified duration windows,\n * splitting atoms if necessary to fit.\n */\nexport class DurationIterator {\n private atomIterator: AtomIterator;\n private spillOver: TSU.Nullable<FlatAtom> = null;\n\n /**\n * Creates a new DurationIterator.\n * @param atomIterator The AtomIterator to use as a source of atoms\n */\n constructor(atomIterator: AtomIterator) {\n this.atomIterator = atomIterator;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n */\n get hasMore(): boolean {\n if (this.spillOver != null) {\n return true;\n }\n return this.atomIterator.hasNext;\n }\n\n /**\n * Gets atoms to cover the specified duration.\n *\n * If the number of atoms left in the iterator is 0, an empty list\n * is returned. Otherwise, the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n *\n * @param duration The duration to cover\n * @returns A tuple containing the array of FlatAtoms and whether the full duration was filled\n */\n get(duration: TSU.Num.Fraction): [FlatAtom[], boolean] {\n const iter = this.atomIterator;\n const out: FlatAtom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0)) {\n const next = this.spillOver == null ? iter.next() : this.spillOver;\n this.spillOver = null;\n if (next == null) {\n // stop here\n break;\n } else {\n out.push(next);\n if (next.duration.cmp(remaining) <= 0) {\n remaining = remaining.minus(next.duration);\n } else {\n // Next leaf atom is > duration\n // so split it into two\n this.spillOver = new FlatAtom(new Space(next.duration.minus(remaining)));\n next.duration = remaining;\n remaining = TSU.Num.Fraction.ZERO;\n }\n }\n }\n return [out, remaining.isZero];\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"layouts.js","sourceRoot":"","sources":["../../src/layouts.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Cycle, CyclePosition, CycleCursor } from \"./cycle\";\n\ntype Fraction = TSU.Num.Fraction;\nconst ZERO = TSU.Num.Fraction.ZERO;\n\n/**\n * Manages layout parameters for arranging beats and notes in the notation.\n * LayoutParams determines how beats are organized into lines and rows based on\n * cycle patterns and line breaks.\n */\nexport class LayoutParams {\n private static counter = 0;\n /** Unique identifier for this layout parameters instance */\n readonly uuid = LayoutParams.counter++;\n \n /** Duration of a single beat (multiplier for beat lengths) */\n beatDuration: number;\n \n /** The cycle pattern to use for this layout */\n cycle: Cycle;\n \n /** The pattern of line breaks to apply */\n protected _lineBreaks: number[];\n \n /** Cache of row start offsets */\n private _rowStartOffsets: Fraction[];\n \n /** Cache of row end offsets */\n private _rowEndOffsets: Fraction[];\n \n /** Cache of row durations */\n private _rowDurations: Fraction[];\n \n /** Total duration of the layout pattern */\n private _totalLayoutDuration;\n \n /** Cached beat layout information */\n private _beatLayouts: [CyclePosition, Fraction][][];\n \n /** Total number of beats across all layout lines */\n private _totalBeats: number;\n\n /**\n * Creates a new LayoutParams instance.\n * @param config Configuration object containing beatDuration, cycle, and lineBreaks\n */\n constructor(config?: any) {\n config = config || {};\n this.beatDuration = config.beatDuration || 1;\n if (\"cycle\" in config) this.cycle = config.cycle;\n if (!this.cycle || this.cycle.duration.isZero) {\n this.cycle = Cycle.DEFAULT;\n }\n\n this._rowStartOffsets = [];\n this._rowEndOffsets = [];\n this._rowDurations = [];\n this._totalLayoutDuration = ZERO;\n this._totalBeats = 0;\n this._beatLayouts = [];\n this.lineBreaks = config.lineBreaks || config.layout || [];\n }\n\n /**\n * Checks if this LayoutParams is equal to another LayoutParams.\n * @param another The LayoutParams to compare with\n * @returns True if the LayoutParams are equal, false otherwise\n */\n equals(another: this): boolean {\n return (\n // super.equals(another) &&\n this.beatDuration == another.beatDuration &&\n this.cycle.equals(another.cycle) &&\n this.lineBreaksEqual(another._lineBreaks)\n );\n }\n\n /**\n * Checks if the line breaks pattern is equal to another pattern.\n * @param another The line breaks pattern to compare with\n * @returns True if the patterns are equal, false otherwise\n */\n lineBreaksEqual(another: number[]): boolean {\n return this._lineBreaks.length == another.length && this._lineBreaks.every((x, i) => x == another[i]);\n }\n\n /**\n * Returns a debug-friendly representation of this LayoutParams.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return {\n // ...super.debugValue(),\n cycle: this.cycle?.debugValue(),\n beatDuration: this.beatDuration,\n lineBreaks: this._lineBreaks,\n };\n }\n\n /**\n * Returns the \"location\" of a beat within a layout.\n * \n * Lines are broken into beats of notes and those beats are aligned as per\n * the specs in the LayoutParams (breaks). For example if the breaks param\n * stipulates [5, 5, 4] then we have 5 beats in the first 2 lines and 4 in\n * the last line.\n * \n * @param beat The beat to locate\n * @returns A tuple containing [layoutLine, layoutColumn, rowOffset]\n * - layoutLine: The line in the layout break spec this beat falls in\n * - layoutColumn: The column within the layoutLine\n * - rowOffset: The offset of the beat from the start of the row/line\n */\n getBeatLocation(beat: {\n index: number;\n barIndex: number;\n beatIndex: number;\n instance: number;\n }): [number, number, Fraction] {\n //\n // If a line contains say 50 beats (B1 - B50), then it is laid out as:\n //\n // C0 C1 C2 C3 C4\n // ---------------------\n // L0 | B1 B2 B3 B4 B5\n // L1 | B6 B7 B8 B9 B10\n // L2 | B11 B12 B13 B14\n // L0 | B15 B16 B17 B18 B19\n // L1 | B20 B21 B22 B23 B24\n // L2 | B25 B26 B27 B28\n // L0 | B29 B30 B31 B32 B33\n // L1 | B34 B35 B36 B37 B38\n // L2 | B39 B40 B41 B42\n // L0 | B43 B44 B45 B46 B47\n // L1 | B48 B49 B50\n //\n // This methods returns the triple: [layoutLine, layoutColumn, rowOffset]\n // where\n //\n // layoutLine: The particular line in the layout break spec this index falls in.\n // *Note*: Since lines can start with negative offsets, we can\n // even return a layoutLine that is towards the end and then go\n // back to 0, eg 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 ...\n // (eg returns L0 or L1 ... Ln)\n // layoutColumn: The column within the layoutLine line where this beat falls.\n // (eg C0 - C4 above - or depending on how many columns exist\n // in the particular layout line).\n // rowOffset: The note offset of the beat from the start of the row/line\n // (not from the start of the cycle).\n //\n // Note the beatIndex can also be negative so we can return a beat\n // starting from before the cycle starting point.\n //\n // To calculate the \"real\" line globally simply do:\n //\n // realLine = lineBreaks.length // Math.floor(beatIndex / this.totalBeats) + layoutLine;\n //\n // Some examples here are (using B1-B50 above):\n const modIndex = beat.index % this.totalBeats;\n let total = 0;\n for (let i = 0; i < this._lineBreaks.length; i++) {\n if (modIndex < total + this._lineBreaks[i]) {\n // TODO: What is the right offset here?\n let offset = ZERO;\n if (modIndex > total) {\n const cursor = new CycleCursor(this.cycle, beat.barIndex, beat.beatIndex, beat.instance);\n let [, duration] = cursor.prev;\n for (let i = total; i < modIndex; i++) {\n [, duration] = cursor.prev;\n offset = offset.plus(duration.timesNum(this.beatDuration));\n }\n }\n return [i, modIndex - total, offset];\n }\n total += this._lineBreaks[i];\n }\n throw new Error(\"Invalid beat index: \" + beat.index);\n return [-1, -1, ZERO];\n }\n\n /**\n * Gets the line layout pattern - i.e., number of beats in each line - as a\n * repeating pattern.\n * \n * For example 4,2,4 indicates that the notes in our song should be\n * laid out 4 beats in line 1, 2 beats in line 2, 4 beats in line 3 and\n * 4 beats in line 4 and so on as long as there are more notes available\n * in this line.\n */\n get lineBreaks(): number[] {\n if (!this._lineBreaks || this._lineBreaks.length == 0) {\n // trigger a refresh\n this.lineBreaks = [this.cycle.beatCount];\n }\n return this._lineBreaks;\n }\n\n /**\n * Sets the line layout pattern.\n */\n set lineBreaks(val: number[]) {\n this._lineBreaks = val;\n this.refreshLayout();\n }\n\n /**\n * Returns the number of beats in each line based on the line layout\n * after taking beatDuration into account.\n */\n get beatLayouts(): ReadonlyArray<ReadonlyArray<[CyclePosition, Fraction]>> {\n if (!this._beatLayouts || this._beatLayouts.length < this.lineBreaks.length) {\n this.refreshLayout();\n }\n return this._beatLayouts;\n }\n\n /**\n * Gets the total number of beats across all lines in the layout pattern.\n */\n get totalBeats(): number {\n this.beatLayouts;\n return this._totalBeats;\n }\n\n /**\n * Gets the total duration of all beats across all lines in the layout pattern.\n */\n get totalLayoutDuration(): Fraction {\n this.beatLayouts;\n return this._totalLayoutDuration;\n }\n\n /**\n * Refreshes the layout calculations based on the current cycle and line breaks.\n * This rebuilds the beat layouts, row durations, and offset information.\n */\n protected refreshLayout(): void {\n const cycleIter = this.cycle.iterateBeats();\n const akb = this.beatDuration;\n this._beatLayouts = this.lineBreaks.map((numBeats, index) => {\n const beats: [CyclePosition, Fraction][] = [];\n // see what the beat lengths are here\n for (let i = 0; i < numBeats; i++) {\n const nextCP = cycleIter.next().value;\n nextCP[1] = nextCP[1].timesNum(akb);\n beats.push(nextCP);\n }\n return beats;\n });\n this._totalBeats = this.lineBreaks.reduce((a, b) => a + b, 0);\n this._rowDurations = this._beatLayouts.map((beats) => beats.reduce((x, y) => x.plus(y[1]), ZERO));\n this._rowDurations.forEach((rd, index) => {\n this._rowStartOffsets[index] = index == 0 ? ZERO : this._rowStartOffsets[index - 1].plus(rd);\n });\n this._rowEndOffsets = this._rowDurations.map((rd, index) => {\n return this._rowStartOffsets[index].plus(rd);\n });\n this._totalLayoutDuration = this._rowDurations.reduce((x, y) => x.plus(y), ZERO);\n }\n}\n"]}
1
+ {"version":3,"file":"layouts.js","sourceRoot":"","sources":["../../src/layouts.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Cycle, CyclePosition, CycleCursor } from \"./cycle\";\n\ntype Fraction = TSU.Num.Fraction;\nconst ZERO = TSU.Num.Fraction.ZERO;\n\n/**\n * Manages layout parameters for arranging beats and notes in the notation.\n * LayoutParams determines how beats are organized into lines and rows based on\n * cycle patterns and line breaks.\n */\nexport class LayoutParams {\n private static counter = 0;\n /** Unique identifier for this layout parameters instance */\n readonly uuid = LayoutParams.counter++;\n\n /** Duration of a single beat (multiplier for beat lengths) */\n beatDuration: number;\n\n /** The cycle pattern to use for this layout */\n cycle: Cycle;\n\n /** The pattern of line breaks to apply */\n protected _lineBreaks: number[];\n\n /** Cache of row start offsets */\n private _rowStartOffsets: Fraction[];\n\n /** Cache of row end offsets */\n private _rowEndOffsets: Fraction[];\n\n /** Cache of row durations */\n private _rowDurations: Fraction[];\n\n /** Total duration of the layout pattern */\n private _totalLayoutDuration;\n\n /** Cached beat layout information */\n private _beatLayouts: [CyclePosition, Fraction][][];\n\n /** Total number of beats across all layout lines */\n private _totalBeats: number;\n\n /**\n * Creates a new LayoutParams instance.\n * @param config Configuration object containing beatDuration, cycle, and lineBreaks\n */\n constructor(config?: any) {\n config = config || {};\n this.beatDuration = config.beatDuration || 1;\n if (\"cycle\" in config) this.cycle = config.cycle;\n if (!this.cycle || this.cycle.duration.isZero) {\n this.cycle = Cycle.DEFAULT;\n }\n\n this._rowStartOffsets = [];\n this._rowEndOffsets = [];\n this._rowDurations = [];\n this._totalLayoutDuration = ZERO;\n this._totalBeats = 0;\n this._beatLayouts = [];\n this.lineBreaks = config.lineBreaks || config.layout || [];\n }\n\n /**\n * Checks if this LayoutParams is equal to another LayoutParams.\n * @param another The LayoutParams to compare with\n * @returns True if the LayoutParams are equal, false otherwise\n */\n equals(another: this): boolean {\n return (\n // super.equals(another) &&\n this.beatDuration == another.beatDuration &&\n this.cycle.equals(another.cycle) &&\n this.lineBreaksEqual(another._lineBreaks)\n );\n }\n\n /**\n * Checks if the line breaks pattern is equal to another pattern.\n * @param another The line breaks pattern to compare with\n * @returns True if the patterns are equal, false otherwise\n */\n lineBreaksEqual(another: number[]): boolean {\n return this._lineBreaks.length == another.length && this._lineBreaks.every((x, i) => x == another[i]);\n }\n\n /**\n * Returns a debug-friendly representation of this LayoutParams.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return {\n // ...super.debugValue(),\n cycle: this.cycle?.debugValue(),\n beatDuration: this.beatDuration,\n lineBreaks: this._lineBreaks,\n };\n }\n\n /**\n * Returns the \"location\" of a beat within a layout.\n *\n * Lines are broken into beats of notes and those beats are aligned as per\n * the specs in the LayoutParams (breaks). For example if the breaks param\n * stipulates [5, 5, 4] then we have 5 beats in the first 2 lines and 4 in\n * the last line.\n *\n * @param beat The beat to locate\n * @returns A tuple containing [layoutLine, layoutColumn, rowOffset]\n * - layoutLine: The line in the layout break spec this beat falls in\n * - layoutColumn: The column within the layoutLine\n * - rowOffset: The offset of the beat from the start of the row/line\n */\n getBeatLocation(beat: {\n index: number;\n barIndex: number;\n beatIndex: number;\n instance: number;\n }): [number, number, Fraction] {\n //\n // If a line contains say 50 beats (B1 - B50), then it is laid out as:\n //\n // C0 C1 C2 C3 C4\n // ---------------------\n // L0 | B1 B2 B3 B4 B5\n // L1 | B6 B7 B8 B9 B10\n // L2 | B11 B12 B13 B14\n // L0 | B15 B16 B17 B18 B19\n // L1 | B20 B21 B22 B23 B24\n // L2 | B25 B26 B27 B28\n // L0 | B29 B30 B31 B32 B33\n // L1 | B34 B35 B36 B37 B38\n // L2 | B39 B40 B41 B42\n // L0 | B43 B44 B45 B46 B47\n // L1 | B48 B49 B50\n //\n // This methods returns the triple: [layoutLine, layoutColumn, rowOffset]\n // where\n //\n // layoutLine: The particular line in the layout break spec this index falls in.\n // *Note*: Since lines can start with negative offsets, we can\n // even return a layoutLine that is towards the end and then go\n // back to 0, eg 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 ...\n // (eg returns L0 or L1 ... Ln)\n // layoutColumn: The column within the layoutLine line where this beat falls.\n // (eg C0 - C4 above - or depending on how many columns exist\n // in the particular layout line).\n // rowOffset: The note offset of the beat from the start of the row/line\n // (not from the start of the cycle).\n //\n // Note the beatIndex can also be negative so we can return a beat\n // starting from before the cycle starting point.\n //\n // To calculate the \"real\" line globally simply do:\n //\n // realLine = lineBreaks.length // Math.floor(beatIndex / this.totalBeats) + layoutLine;\n //\n // Some examples here are (using B1-B50 above):\n const modIndex = beat.index % this.totalBeats;\n let total = 0;\n for (let i = 0; i < this._lineBreaks.length; i++) {\n if (modIndex < total + this._lineBreaks[i]) {\n // TODO: What is the right offset here?\n let offset = ZERO;\n if (modIndex > total) {\n const cursor = new CycleCursor(this.cycle, beat.barIndex, beat.beatIndex, beat.instance);\n let [, duration] = cursor.prev;\n for (let i = total; i < modIndex; i++) {\n [, duration] = cursor.prev;\n offset = offset.plus(duration.timesNum(this.beatDuration));\n }\n }\n return [i, modIndex - total, offset];\n }\n total += this._lineBreaks[i];\n }\n throw new Error(\"Invalid beat index: \" + beat.index);\n return [-1, -1, ZERO];\n }\n\n /**\n * Gets the line layout pattern - i.e., number of beats in each line - as a\n * repeating pattern.\n *\n * For example 4,2,4 indicates that the notes in our song should be\n * laid out 4 beats in line 1, 2 beats in line 2, 4 beats in line 3 and\n * 4 beats in line 4 and so on as long as there are more notes available\n * in this line.\n */\n get lineBreaks(): number[] {\n if (!this._lineBreaks || this._lineBreaks.length == 0) {\n // trigger a refresh\n this.lineBreaks = [this.cycle.beatCount];\n }\n return this._lineBreaks;\n }\n\n /**\n * Sets the line layout pattern.\n */\n set lineBreaks(val: number[]) {\n this._lineBreaks = val;\n this.refreshLayout();\n }\n\n /**\n * Returns the number of beats in each line based on the line layout\n * after taking beatDuration into account.\n */\n get beatLayouts(): ReadonlyArray<ReadonlyArray<[CyclePosition, Fraction]>> {\n if (!this._beatLayouts || this._beatLayouts.length < this.lineBreaks.length) {\n this.refreshLayout();\n }\n return this._beatLayouts;\n }\n\n /**\n * Gets the total number of beats across all lines in the layout pattern.\n */\n get totalBeats(): number {\n this.beatLayouts;\n return this._totalBeats;\n }\n\n /**\n * Gets the total duration of all beats across all lines in the layout pattern.\n */\n get totalLayoutDuration(): Fraction {\n this.beatLayouts;\n return this._totalLayoutDuration;\n }\n\n /**\n * Refreshes the layout calculations based on the current cycle and line breaks.\n * This rebuilds the beat layouts, row durations, and offset information.\n */\n protected refreshLayout(): void {\n const cycleIter = this.cycle.iterateBeats();\n const akb = this.beatDuration;\n this._beatLayouts = this.lineBreaks.map((numBeats, index) => {\n const beats: [CyclePosition, Fraction][] = [];\n // see what the beat lengths are here\n for (let i = 0; i < numBeats; i++) {\n const nextCP = cycleIter.next().value;\n nextCP[1] = nextCP[1].timesNum(akb);\n beats.push(nextCP);\n }\n return beats;\n });\n this._totalBeats = this.lineBreaks.reduce((a, b) => a + b, 0);\n this._rowDurations = this._beatLayouts.map((beats) => beats.reduce((x, y) => x.plus(y[1]), ZERO));\n this._rowDurations.forEach((rd, index) => {\n this._rowStartOffsets[index] = index == 0 ? ZERO : this._rowStartOffsets[index - 1].plus(rd);\n });\n this._rowEndOffsets = this._rowDurations.map((rd, index) => {\n return this._rowStartOffsets[index].plus(rd);\n });\n this._totalLayoutDuration = this._rowDurations.reduce((x, y) => x.plus(y), ZERO);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,sBAEC;AASD,oBAkCC;AA1DD,qDAAuC;AAGvC,mCAA2C;AAC3C,qCAAkC;AASlC,SAAgB,KAAK,CAAC,KAAa;IACjC,OAAO,IAAI,eAAM,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AASD,SAAgB,IAAI,CAClB,QAAgB,EAChB,SAAc,EAAE;IAEhB,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,wBAAgB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAGpC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,IAAI,CAAE,KAAc,CAAC,OAAO,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,KAAa,CAAC;YAG3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,mDAAmD,CAAC,CAAC;YAC3F,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,GAAG,SAAS,mBAAmB,SAAS,GAAG,SAAS,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO;QACL,QAAQ;QACR,UAAU;QACV,MAAM;QACN;YACE,SAAS,EAAE,SAAS,GAAG,SAAS;YAChC,SAAS,EAAE,SAAS,GAAG,SAAS;SACjC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport * as G from \"galore\";\nimport { Line } from \"./core\";\nimport { GlobalBeatLayout } from \"./beats\";\nimport { Parser } from \"./parser\";\nimport { Notation } from \"./notation\";\n\n/**\n * Parses a notation string into a Notation object.\n * \n * @param input The notation string to parse\n * @returns A tuple containing the parsed Notation and any parsing errors\n */\nexport function parse(input: string): [Notation, G.ParseError[]] {\n return new Parser().parseAndBuild(input);\n}\n\n/**\n * Loads a notation from a string and builds the beat layout.\n * \n * @param codeText The notation string to load\n * @param config Optional configuration object\n * @returns A tuple containing the Notation, GlobalBeatLayout, parsing errors, and timing information\n */\nexport function load(\n codeText: string,\n config: any = {},\n): [Notation, GlobalBeatLayout, G.ParseError[], TSU.StringMap<number>] {\n codeText = codeText || \"\";\n const beatLayout = new GlobalBeatLayout();\n const startTime = performance.now();\n const [notation, errors] = parse(codeText);\n const parseTime = performance.now();\n\n // Create Line Beats\n for (const block of notation.blocks) {\n if (block.TYPE == \"Line\" && !(block as Line).isEmpty) {\n const line = block as Line;\n // LP should exist by now\n // Probably because this is an empty line and AddAtoms was not called\n TSU.assert(line.layoutParams != null, \"Layout params for a non empty line *SHOULD* exist\");\n beatLayout.addLine(line);\n }\n }\n\n const buildTime = performance.now();\n if (config.log) {\n console.log(`V4 Document, Parse Time: ${parseTime - startTime}ms, Build Time: ${buildTime - parseTime}ms`);\n }\n return [\n notation,\n beatLayout,\n errors,\n {\n parseTime: parseTime - startTime,\n buildTime: buildTime - parseTime,\n },\n ];\n}\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,sBAEC;AASD,oBAkCC;AA1DD,qDAAuC;AAGvC,mCAA2C;AAC3C,qCAAkC;AASlC,SAAgB,KAAK,CAAC,KAAa;IACjC,OAAO,IAAI,eAAM,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AASD,SAAgB,IAAI,CAClB,QAAgB,EAChB,SAAc,EAAE;IAEhB,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,wBAAgB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAGpC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,IAAI,CAAE,KAAc,CAAC,OAAO,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,KAAa,CAAC;YAG3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,mDAAmD,CAAC,CAAC;YAC3F,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,GAAG,SAAS,mBAAmB,SAAS,GAAG,SAAS,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO;QACL,QAAQ;QACR,UAAU;QACV,MAAM;QACN;YACE,SAAS,EAAE,SAAS,GAAG,SAAS;YAChC,SAAS,EAAE,SAAS,GAAG,SAAS;SACjC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport * as G from \"galore\";\nimport { Line } from \"./core\";\nimport { GlobalBeatLayout } from \"./beats\";\nimport { Parser } from \"./parser\";\nimport { Notation } from \"./notation\";\n\n/**\n * Parses a notation string into a Notation object.\n *\n * @param input The notation string to parse\n * @returns A tuple containing the parsed Notation and any parsing errors\n */\nexport function parse(input: string): [Notation, G.ParseError[]] {\n return new Parser().parseAndBuild(input);\n}\n\n/**\n * Loads a notation from a string and builds the beat layout.\n *\n * @param codeText The notation string to load\n * @param config Optional configuration object\n * @returns A tuple containing the Notation, GlobalBeatLayout, parsing errors, and timing information\n */\nexport function load(\n codeText: string,\n config: any = {},\n): [Notation, GlobalBeatLayout, G.ParseError[], TSU.StringMap<number>] {\n codeText = codeText || \"\";\n const beatLayout = new GlobalBeatLayout();\n const startTime = performance.now();\n const [notation, errors] = parse(codeText);\n const parseTime = performance.now();\n\n // Create Line Beats\n for (const block of notation.blocks) {\n if (block.TYPE == \"Line\" && !(block as Line).isEmpty) {\n const line = block as Line;\n // LP should exist by now\n // Probably because this is an empty line and AddAtoms was not called\n TSU.assert(line.layoutParams != null, \"Layout params for a non empty line *SHOULD* exist\");\n beatLayout.addLine(line);\n }\n }\n\n const buildTime = performance.now();\n if (config.log) {\n console.log(`V4 Document, Parse Time: ${parseTime - startTime}ms, Build Time: ${buildTime - parseTime}ms`);\n }\n return [\n notation,\n beatLayout,\n errors,\n {\n parseTime: parseTime - startTime,\n buildTime: buildTime - parseTime,\n },\n ];\n}\n"]}
@@ -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\";\n\n/**\n * Definition of a role in the notation.\n * A role represents a specific voice or part in the music notation.\n */\nexport class RoleDef {\n /** Name of the role */\n name = \"\";\n \n /** Whether this role contains only notes (true) or can also contain syllables/text (false) */\n notesOnly = false;\n \n /** Index of this role in the notation */\n index = 0;\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 notation.\n * @param notation The notation to apply this command to\n */\n abstract applyToNotation(notebook: Notation): void;\n}\n\n/**\n * Represents a raw block of content in the notation.\n * Raw blocks can contain arbitrary content like markdown, HTML, etc.\n */\nexport class RawBlock extends Entity {\n readonly TYPE: string = \"RawBlock\";\n \n /**\n * Creates a new RawBlock.\n * @param content The content of the block\n * @param contentType The type of content (e.g., \"md\" for markdown)\n */\n constructor(public content: string, public contentType: string = \"md\") {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this raw block.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), content: this.content, contentType: this.contentType };\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(public readonly key: string, public readonly value: string, public readonly params?: any) {\n params = params || {};\n }\n}\n\n/**\n * The main class representing a complete notation.\n * Notation contains all the elements, settings, and layout information for a piece of music.\n */\nexport class Notation extends Entity {\n readonly TYPE = \"Notation\";\n private _unnamedLayoutParams: LayoutParams[] = [];\n private _namedLayoutParams = new Map<string, LayoutParams>();\n private _currRoleDef: TSU.Nullable<RoleDef> = null;\n \n /** Roles defined in this notation */\n roles: RoleDef[] = [];\n \n /** Blocks (lines or raw blocks) in this notation */\n blocks: (Line | RawBlock)[] = [];\n \n /** Current beat duration multiplier */\n currentAPB = 1;\n \n /** Current cycle pattern */\n currentCycle: Cycle = Cycle.DEFAULT;\n \n /** Current line breaks pattern */\n currentBreaks: number[] = [];\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 * 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 * Adds a line to this notation.\n * @param line The line to add\n */\n addLine(line: Line): void {\n this.blocks.push(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 const index = this.blocks.findIndex((l) => l == line);\n if (index >= 0) {\n this.blocks.splice(index, 1);\n }\n return index;\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.blocks.push(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 * Returns a debug-friendly representation of this notation.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return {\n ...super.debugValue,\n roles: this.roles,\n blocks: this.blocks.map((b) => b.debugValue()),\n currentAPB: this.currentAPB,\n currentCycle: this.currentCycle?.uuid,\n currentBreaks: this.currentBreaks,\n };\n }\n\n /**\n * Gets a role definition by name.\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 this.roles[this.roles.length - 1] || null;\n }\n for (let i = 0; i < this.roles.length; i++) {\n const rd = this.roles[i];\n if (name == rd.name) return rd;\n }\n return 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.trim() == \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n const roleDef = this.getRoleDef(name);\n if (roleDef != null) {\n throw new Error(\"Role already exists\");\n // roleDef.notesOnly = notesOnly;\n // return roleDef;\n }\n // create new and add\n const rd = new RoleDef();\n rd.name = name;\n rd.notesOnly = notesOnly;\n rd.index = this.roles.length;\n this.roles.push(rd);\n\n return rd;\n }\n\n /**\n * Gets the current role definition.\n */\n get currRoleDef(): RoleDef | null {\n if (this._currRoleDef == null) {\n if (this.roles.length == 0) {\n return null;\n } else {\n this._currRoleDef = this.roles[this.roles.length - 1];\n }\n }\n return this._currRoleDef;\n }\n\n /**\n * Sets the current role by name.\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.getRoleDef(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 // Gets the current line, creating it if needed\n private _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 * Resets the current line pointer to null.\n */\n resetLine(): void {\n this._currentLine = null;\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 private _layoutParams: LayoutParams | null = null;\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 * 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 * 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"]}
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\";\n\n/**\n * Definition of a role in the notation.\n * A role represents a specific voice or part in the music notation.\n */\nexport class RoleDef {\n /** Name of the role */\n name = \"\";\n\n /** Whether this role contains only notes (true) or can also contain syllables/text (false) */\n notesOnly = false;\n\n /** Index of this role in the notation */\n index = 0;\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 notation.\n * @param notation The notation to apply this command to\n */\n abstract applyToNotation(notebook: Notation): void;\n}\n\n/**\n * Represents a raw block of content in the notation.\n * Raw blocks can contain arbitrary content like markdown, HTML, etc.\n */\nexport class RawBlock extends Entity {\n readonly TYPE: string = \"RawBlock\";\n\n /**\n * Creates a new RawBlock.\n * @param content The content of the block\n * @param contentType The type of content (e.g., \"md\" for markdown)\n */\n constructor(\n public content: string,\n public contentType: string = \"md\",\n ) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this raw block.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), content: this.content, contentType: this.contentType };\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 contains all the elements, settings, and layout information for a piece of music.\n */\nexport class Notation extends Entity {\n readonly TYPE = \"Notation\";\n private _unnamedLayoutParams: LayoutParams[] = [];\n private _namedLayoutParams = new Map<string, LayoutParams>();\n private _currRoleDef: TSU.Nullable<RoleDef> = null;\n\n /** Roles defined in this notation */\n roles: RoleDef[] = [];\n\n /** Blocks (lines or raw blocks) in this notation */\n blocks: (Line | RawBlock)[] = [];\n\n /** Current beat duration multiplier */\n currentAPB = 1;\n\n /** Current cycle pattern */\n currentCycle: Cycle = Cycle.DEFAULT;\n\n /** Current line breaks pattern */\n currentBreaks: number[] = [];\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 * 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 * Adds a line to this notation.\n * @param line The line to add\n */\n addLine(line: Line): void {\n this.blocks.push(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 const index = this.blocks.findIndex((l) => l == line);\n if (index >= 0) {\n this.blocks.splice(index, 1);\n }\n return index;\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.blocks.push(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 * Returns a debug-friendly representation of this notation.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return {\n ...super.debugValue,\n roles: this.roles,\n blocks: this.blocks.map((b) => b.debugValue()),\n currentAPB: this.currentAPB,\n currentCycle: this.currentCycle?.uuid,\n currentBreaks: this.currentBreaks,\n };\n }\n\n /**\n * Gets a role definition by name.\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 this.roles[this.roles.length - 1] || null;\n }\n for (let i = 0; i < this.roles.length; i++) {\n const rd = this.roles[i];\n if (name == rd.name) return rd;\n }\n return 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.trim() == \"\") {\n throw new Error(\"Role name cannot be empty\");\n }\n const roleDef = this.getRoleDef(name);\n if (roleDef != null) {\n throw new Error(\"Role already exists\");\n // roleDef.notesOnly = notesOnly;\n // return roleDef;\n }\n // create new and add\n const rd = new RoleDef();\n rd.name = name;\n rd.notesOnly = notesOnly;\n rd.index = this.roles.length;\n this.roles.push(rd);\n\n return rd;\n }\n\n /**\n * Gets the current role definition.\n */\n get currRoleDef(): RoleDef | null {\n if (this._currRoleDef == null) {\n if (this.roles.length == 0) {\n return null;\n } else {\n this._currRoleDef = this.roles[this.roles.length - 1];\n }\n }\n return this._currRoleDef;\n }\n\n /**\n * Sets the current role by name.\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.getRoleDef(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 // Gets the current line, creating it if needed\n private _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 * Resets the current line pointer to null.\n */\n resetLine(): void {\n this._currentLine = null;\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 private _layoutParams: LayoutParams | null = null;\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 * 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 * 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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport * as G from \"galore\";\nimport * as TLEX from \"tlex\";\nimport matter from \"gray-matter\";\nimport { Literal, AtomType, Note, Atom, Rest, Space, Syllable, Group, Marker } from \"./core\";\nimport { Notation, MetaData as Meta, Command, CmdParam } from \"./notation\";\nimport {\n RawEmbedding,\n ApplyLayout,\n AddAtoms,\n SetCycle,\n SetBeatDuration,\n SetBreaks,\n ActivateRole,\n CreateRole,\n CreateLine,\n MetaData,\n} from \"./commands\";\n\n// TODO - Make this plugable from the client instead of hard coded\nimport * as carnatic from \"./carnatic\";\n\nconst ONE = TSU.Num.Fraction.ONE;\nconst TWO = ONE.timesNum(2);\n\n/**\n * V4 of our parser builds on V3 and has the following improvements:\n *\n * 1. Embedding Headings to demarcate sections so users dont have to use\n * explicit MD for headings.\n * 2. Unlike V3 here users break out *of* song instead instead break out \"into\"\n * song. So users spend more time writing notation and less worrying about\n * other things like headings etc.\n */\nconst [parser /*itemGraph*/] = G.newParser(\n String.raw`\n %define IdentChar /[^%!@$#&\\^|\\[\\]={}()<>+\\-,;~: \\t\\f\\r\\n\\v\\\\\\.\\'\\\"]/\n\n %token BSLASH \"\\\\\"\n %token OPEN_SQ \"[\"\n %token CLOSE_SQ \"]\"\n %token EQUALS \"=\"\n %token OPEN_PAREN \"(\"\n %token CLOSE_PAREN \")\"\n %token OPEN_BRACE \"{\"\n %token CLOSE_BRACE \"}\"\n %token SLASH \"/\"\n %token STAR \"*\"\n %token CARET \"^\"\n // %skip \"-\"\n %token COMMA \",\"\n %token SEMI_COLON \";\"\n %token COLON \":\"\n\n %token FRONT_MATTER /^---$/m { toFrontMatter }\n %token SINGLE_LINE_RAW_STRING />(.*)$/m { toSingleLineRawString }\n %token MULTI_LINE_RAW_STRING /r(#{0,})\"/ { toMultiLineRawString }\n\n %token EMBELISHMENT /~[^\\s]*/ { toEmbelishment }\n %token NUMBER /-?\\d+/ { toNumber }\n %token BOOLEAN /true|false/ { toBoolean }\n %token POST_MARKER /<<\"(([^\"\\\\\\n]|\\\\.|\\\\\\n)*)\"/ { toMarker }\n %token POST_MARKER /<<'(([^'\\\\\\n]|\\\\.|\\\\\\n)*)'/ { toMarker }\n %token PRE_MARKER /\"(([^\"\\\\\\n]|\\\\.|\\\\\\n)*)\">>/ { toMarker }\n %token PRE_MARKER /'(([^'\\\\\\n]|\\\\.|\\\\\\n)*)'>>/ { toMarker }\n %token STRING /\"([^\"\\\\\\n]|\\\\.|\\\\\\n)*\"/ { toString }\n %token STRING /'([^'\\\\\\n]|\\\\.|\\\\\\n)*'/ { toString }\n %token DOTS_IDENT /(\\.+)({IdentChar}+)/ { toOctavedNote }\n %token IDENT_DOTS /({IdentChar}+)(\\.+)/ { toOctavedNote }\n %token IDENT_COLON /{IdentChar}+:/ { toRoleSelector }\n %token IDENT /{IdentChar}+/\n %token BSLASH_IDENT /\\\\{IDENT}/ { toCommandName }\n %token BSLASH_NUMBER /\\\\{NUMBER}/\n %token HYPHEN /-/\n %skip /[ \\t\\n\\f\\r]+/\n %skip_flex \"//.*$\"\n %skip /\\/\\*.*?\\*\\//\n\n Document -> Elements\n | FRONT_MATTER Elements { prependFrontMatter }\n ;\n\n Elements -> Elements Command Atoms { appendCommand } \n | Elements RoleSelector Atoms { appendRoleSelector } \n | Elements Embedding Atoms { insertEmbedding }\n | Atoms { appendAtoms }\n ;\n\n Embedding -> SINGLE_LINE_RAW_STRING | MULTI_LINE_RAW_STRING ;\n\n Command -> BSLASH_IDENT CommandParams ? { newCommand } ;\n CommandParams -> OPEN_PAREN ParamList ? CLOSE_PAREN { $2 } ;\n\n ParamList -> ParamList COMMA Param { concatParamList } ;\n ParamList -> Param { newParamList };\n Param -> ParamValue { newParam } ;\n Param -> ParamKey EQUALS ParamValue { newParam } ;\n ParamKey -> IDENT ;\n ParamValue -> ( STRING | Fraction | NUMBER | BOOLEAN ) ;\n\n RoleSelector -> IDENT_COLON ;\n\n Atoms -> Atoms Atom { concatAtoms } ;\n Atoms -> { newArray } ;\n\n Atom -> Atom POST_MARKER { applyPostMarker }\n | PreMarkedAtom\n ;\n PreMarkedAtom -> Leaf\n | PRE_MARKER PreMarkedAtom { applyPreMarker }\n ;\n\n Leaf -> Space | Lit | Group | Rest ;\n Leaf -> Duration Leaf { applyDuration } ;\n Rest -> HYPHEN { newRest };\n Space -> COMMA { newSpace } \n | SEMI_COLON { newDoubleSpace } \n | UNDER_SCORE { newSilentSpace } \n ;\n\n /* - An alternative representation to support both pre and\n * post embelishment operators. Here PRE_EMBs have a higher\n * associativity over POST_EMBs\n */\n Lit -> Lit POST_EMB { litWithPostEmb }\n | PreEmbLit\n ;\n\n PreEmbLit -> LitToken \n | LitToken CARET NUMBER { litWithCaret }\n | LitToken CARET STAR { litWithCaret }\n | PRE_EMB PreEmbLit { litWithPreEmb }\n ;\n \n LitToken -> DOTS_IDENT { litToAtom }\n | IDENT { litToAtom }\n | IDENT_DOTS { litToAtom }\n | STRING { litToAtom }\n ;\n\n Group -> OPEN_SQ Atoms CLOSE_SQ { newGroup };\n\n Duration -> Fraction | NUMBER;\n Fraction -> NUMBER SLASH NUMBER { newFraction } ;\n `,\n {\n allowLeftRecursion: true,\n debug: \"\",\n type: \"lalr\",\n tokenHandlers: {\n toEmbelishment: (token: TLEX.Token, tape: TLEX.Tape, owner: Parser) => {\n const [emb, pre] = owner.parseEmbelishment(token.value);\n if (emb == null) {\n console.log(\"Skipping Embelishment: \", token.value);\n owner.errors.push(\n new TLEX.TokenizerError(\n `Invalid embelishment: ${token.value}`,\n token.start,\n 1 + token.end - token.start,\n \"InvalidEmbelishment\",\n token.value,\n ),\n );\n return null;\n }\n token.value = emb;\n token.tag = pre ? \"PRE_EMB\" : \"POST_EMB\";\n return token;\n },\n toCommandName: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value.substring(1);\n return token;\n },\n toBoolean: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value == \"true\";\n return token;\n },\n toNumber: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = parseInt(token.value);\n return token;\n },\n toString: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value.substring(1, token.value.length - 1);\n return token;\n },\n toMarker: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n if (token.tag != \"PRE_MARKER\" && token.tag != \"POST_MARKER\") {\n throw new Error(\"Invalid token for converting to note: \" + token.tag);\n }\n const isBefore = token.tag == \"PRE_MARKER\";\n const markerText = isBefore\n ? token.value.substring(1, token.value.length - 3)\n : token.value.substring(3, token.value.length - 1);\n // console.log(\"TokVal: \", token.value, token.positions);\n // console.log(\"Marker Text: \", markerText, isBefore);\n token.value = new Marker(markerText, isBefore);\n return token;\n },\n toOctavedNote: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n if (token.tag == \"DOTS_IDENT\") {\n const octave = token.positions[1][1] - token.positions[1][0];\n const note = token.value.substring(octave);\n token.value = new Note(note, ONE, -octave);\n } else if (token.tag == \"IDENT_DOTS\") {\n const octave = token.positions[2][1] - token.positions[2][0];\n const note = token.value.substring(0, token.value.length - octave);\n token.value = new Note(note, ONE, octave);\n } else {\n throw new Error(\"Invalid token for converting to note: \" + token.tag);\n }\n return token;\n },\n toRoleSelector: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value.substring(0, token.value.length - 1);\n return token;\n },\n toLineAnnotation: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // skip the initial \"!\"\n token.value = token.value.substring(1);\n return token;\n },\n toSingleLineRawString: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // skip the initial \">\"\n token.value = token.value.substring(1);\n return token;\n },\n toMultiLineRawString: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // consume everything until \"#<N times> as start\n const hashes = tape.substring(token.positions[1][0], token.positions[1][1]);\n const endPat = '\"' + hashes;\n const startPos = tape.index;\n const endPos = TLEX.TapeHelper.advanceAfter(tape, endPat) - endPat.length;\n if (endPos < 0) {\n throw new Error(\"EOF expected while finding end of Raw String Literal: '\" + endPat + \"'\");\n }\n token.value = tape.substring(startPos, endPos);\n return token;\n },\n toFrontMatter: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // skip the initial \">\"\n const endPat = \"\\n---\";\n const startPos = tape.index;\n const endPos = TLEX.TapeHelper.advanceAfter(tape, endPat) - endPat.length;\n if (endPos < 0) {\n throw new Error(\"EOF expected while finding end of front matter\");\n }\n token.value = tape.substring(startPos, endPos);\n // console.log(\"Found FM: \", token.value);\n return token;\n },\n },\n },\n);\n\n/**\n * A notation doc is a list of lines that are found in a single document.\n *\n * Since our document (md or html etc) can contain multiple snippets\n * all these snippets are related\n */\nexport class Parser {\n errors: (TLEX.TokenizerError | G.ParseError)[] = [];\n metadata: any = {};\n readonly commands: Command[] = [];\n // readonly notation: Notation = new Notation();\n // private runCommandFound = false;\n // readonly parseTree = new PTNodeList(\"Snippet\", null);\n\n protected ruleHandlers = {\n newFraction: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n if (children.length == 1) {\n return new TSU.Num.Fraction(children[0].value);\n } else {\n return new TSU.Num.Fraction(children[0].value, children[2].value);\n }\n },\n newGroup: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const out = new Group(...children[1].value).setDuration(TWO, true);\n return out;\n },\n litWithCaret: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const lit = Note.fromLit(children[0].value as Literal);\n const opnode = children[2];\n const shiftValue = opnode.sym.label == \"STAR\" ? true : opnode.value;\n lit.shift = shiftValue;\n return lit;\n },\n litWithPreEmb: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const emb = children[0];\n const lit = children[1].value as Literal;\n lit.embelishments.splice(0, 0, emb.value);\n return lit;\n },\n litWithPostEmb: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const lit = children[0].value as Literal;\n const emb = children[1];\n lit.embelishments.push(emb);\n return lit;\n },\n litToAtom: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const lit = children[0];\n if (lit.sym.label == \"DOTS_IDENT\" || lit.sym.label == \"IDENT_DOTS\") {\n return lit.value;\n } else if (lit.sym.label == \"IDENT\") {\n // Mark this as a Literal to be processed later\n return new Literal(lit.value);\n // return role.notesOnly ? new Note(lit.value) : new Syllable(lit.value);\n } else if (lit.sym.label == \"STRING\") {\n // const role = this.snippet.currRole;\n // if (role.notesOnly) throw new Error(\"Strings cannot appear in notes only mode\");\n return new Syllable(lit.value);\n } else {\n throw new Error(\"Invalid lit: \" + lit);\n }\n },\n newSpace: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Space();\n },\n newRest: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Rest();\n },\n newDoubleSpace: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Space(ONE.timesNum(2));\n },\n newSilentSpace: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Space(ONE, true);\n },\n applyPreMarker: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const marker = children[0].value as Marker;\n const leaf = children[1].value as Atom;\n // console.log(\"marker, leaf: \", marker, leaf);\n if (!leaf.markersBefore) {\n leaf.markersBefore = [];\n }\n leaf.markersBefore.splice(0, 0, marker);\n return leaf;\n },\n applyPostMarker: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const leaf = children[0].value as Atom;\n const marker = children[1].value as Marker;\n if (!leaf.markersAfter) {\n leaf.markersAfter = [];\n }\n leaf.markersAfter.push(marker);\n return leaf;\n },\n applyDuration: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n let dur = children[0].value as TSU.Num.Fraction | number;\n const leaf = children[1].value as Atom;\n if (typeof dur === \"number\") {\n dur = ONE.timesNum(dur);\n }\n if (leaf.TYPE == AtomType.GROUP) {\n (leaf as Group).setDuration(dur, true);\n } else {\n leaf.duration = dur;\n }\n return leaf;\n },\n newArray: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n // create an array of values from all the values of child nodes\n return children.map((c) => c.value);\n },\n concatAtoms: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const atoms = children[0].value;\n const atom = children[1].value;\n atoms.push(atom);\n return atoms;\n },\n newParam: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n if (children.length == 1) {\n return { key: null, value: children[0].value };\n } else {\n return { key: children[0].value, value: children[2].value };\n }\n },\n newParamList: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return [children[0].value];\n },\n concatParamList: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const params = children[0].value;\n const newParam = children[2].value;\n params.push(newParam);\n return params;\n },\n newCommand: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return this.createCommand(children[0].value, children[1].value);\n },\n appendAtoms: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const atoms = children[0].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n prependFrontMatter: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const fm = children[0].value;\n // console.log(\"Child 0: \", fm);\n // console.log(\"Child 1: \", children[1].value);\n const { data } = matter(\"---\\n\" + fm + \"\\n---\");\n console.log(\"Parsed FM: \", data);\n this.metadata = data;\n return children[1].value;\n },\n appendCommand: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const command = children[1].value as Command;\n this.addCommand(command);\n\n const atoms = children[2].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n appendRoleSelector: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const roleName = children[1].value;\n const lName = roleName.toLowerCase().trim();\n this.addCommand(new ActivateRole([{ key: null, value: lName }]));\n\n const atoms = children[2].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n insertEmbedding: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n // How to handle embeddings - these are just blocks\n // to escape out of song (most likely for some rendering of html/md etc)\n const rawVal = children[1].value;\n this.addCommand(new RawEmbedding([{ key: null, value: rawVal }]));\n const atoms = children[2].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n };\n\n constructor(config?: any) {\n config = config || {};\n }\n\n createCommand(name: string, params: CmdParam[]): Command {\n const lName = name.trim().toLowerCase();\n params = params || [];\n if (lName == \"line\") {\n return new CreateLine(params);\n // } else if (lName == \"meta\") { return new MetaData(params);\n } else if (lName == \"role\") {\n return new CreateRole(params);\n } else if (lName == \"layout\") {\n return new ApplyLayout(params);\n } else if (lName == \"beatduration\") {\n return new SetBeatDuration(params);\n } else if (lName == \"breaks\") {\n return new SetBreaks(params);\n } else if (lName == \"cycle\") {\n return new SetCycle(params);\n } else {\n // Try to set this as the current role\n throw new Error(\"Invalid command: \" + lName);\n }\n }\n\n addCommand(cmd: Command): void {\n cmd.index = this.commands.length;\n this.commands.push(cmd);\n }\n\n parse(input: string): any {\n this.errors = [];\n try {\n const ptree = parser.parse(input, {\n tokenizerContext: this,\n ruleHandlers: this.ruleHandlers,\n onTokenError: (err: TLEX.TokenizerError) => {\n this.errors.push(err);\n return true;\n },\n });\n return ptree;\n } catch (err) {\n if (err instanceof G.ParseError) {\n this.errors.push(err);\n } else {\n throw err;\n }\n }\n return null;\n }\n\n parseAndBuild(input: string): [Notation, G.ParseError[]] {\n this.parse(input);\n const notation = new Notation();\n const errors: G.ParseError[] = [];\n errors.push(...this.errors);\n\n // First add the metadata then we can set it\n for (const key in this.metadata) notation.addMetaData(new Meta(key, this.metadata[key]));\n for (const cmd of this.commands) cmd.applyToNotation(notation);\n return [notation, errors];\n }\n\n parseEmbelishment(value: string): [any, boolean] {\n return carnatic.parseEmbelishment(value);\n }\n}\n"]}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport * as G from \"galore\";\nimport * as TLEX from \"tlex\";\nimport matter from \"gray-matter\";\nimport { Literal, AtomType, Note, Atom, Rest, Space, Syllable, Group, Marker } from \"./core\";\nimport { Notation, MetaData as Meta, Command, CmdParam } from \"./notation\";\nimport {\n RawEmbedding,\n ApplyLayout,\n AddAtoms,\n SetCycle,\n SetBeatDuration,\n SetBreaks,\n ActivateRole,\n CreateRole,\n CreateLine,\n MetaData,\n} from \"./commands\";\n\n// TODO - Make this plugable from the client instead of hard coded\nimport * as carnatic from \"./carnatic\";\n\nconst ONE = TSU.Num.Fraction.ONE;\nconst TWO = ONE.timesNum(2);\n\n/**\n * V4 of our parser builds on V3 and has the following improvements:\n *\n * 1. Embedding Headings to demarcate sections so users dont have to use\n * explicit MD for headings.\n * 2. Unlike V3 here users break out *of* song instead instead break out \"into\"\n * song. So users spend more time writing notation and less worrying about\n * other things like headings etc.\n */\nconst [parser /*itemGraph*/] = G.newParser(\n String.raw`\n %define IdentChar /[^%!@$#&\\^|\\[\\]={}()<>+\\-,;~: \\t\\f\\r\\n\\v\\\\\\.\\'\\\"]/\n\n %token BSLASH \"\\\\\"\n %token OPEN_SQ \"[\"\n %token CLOSE_SQ \"]\"\n %token EQUALS \"=\"\n %token OPEN_PAREN \"(\"\n %token CLOSE_PAREN \")\"\n %token OPEN_BRACE \"{\"\n %token CLOSE_BRACE \"}\"\n %token SLASH \"/\"\n %token STAR \"*\"\n %token CARET \"^\"\n // %skip \"-\"\n %token COMMA \",\"\n %token SEMI_COLON \";\"\n %token COLON \":\"\n\n %token FRONT_MATTER /^---$/m { toFrontMatter }\n %token SINGLE_LINE_RAW_STRING />(.*)$/m { toSingleLineRawString }\n %token MULTI_LINE_RAW_STRING /r(#{0,})\"/ { toMultiLineRawString }\n\n %token EMBELISHMENT /~[^\\s]*/ { toEmbelishment }\n %token NUMBER /-?\\d+/ { toNumber }\n %token BOOLEAN /true|false/ { toBoolean }\n %token POST_MARKER /<<\"(([^\"\\\\\\n]|\\\\.|\\\\\\n)*)\"/ { toMarker }\n %token POST_MARKER /<<'(([^'\\\\\\n]|\\\\.|\\\\\\n)*)'/ { toMarker }\n %token PRE_MARKER /\"(([^\"\\\\\\n]|\\\\.|\\\\\\n)*)\">>/ { toMarker }\n %token PRE_MARKER /'(([^'\\\\\\n]|\\\\.|\\\\\\n)*)'>>/ { toMarker }\n %token STRING /\"([^\"\\\\\\n]|\\\\.|\\\\\\n)*\"/ { toString }\n %token STRING /'([^'\\\\\\n]|\\\\.|\\\\\\n)*'/ { toString }\n %token DOTS_IDENT /(\\.+)({IdentChar}+)/ { toOctavedNote }\n %token IDENT_DOTS /({IdentChar}+)(\\.+)/ { toOctavedNote }\n %token IDENT_COLON /{IdentChar}+:/ { toRoleSelector }\n %token IDENT /{IdentChar}+/\n %token BSLASH_IDENT /\\\\{IDENT}/ { toCommandName }\n %token BSLASH_NUMBER /\\\\{NUMBER}/\n %token HYPHEN /-/\n %skip /[ \\t\\n\\f\\r]+/\n %skip_flex \"//.*$\"\n %skip /\\/\\*.*?\\*\\//\n\n Document -> Elements\n | FRONT_MATTER Elements { prependFrontMatter }\n ;\n\n Elements -> Elements Command Atoms { appendCommand } \n | Elements RoleSelector Atoms { appendRoleSelector } \n | Elements Embedding Atoms { insertEmbedding }\n | Atoms { appendAtoms }\n ;\n\n Embedding -> SINGLE_LINE_RAW_STRING | MULTI_LINE_RAW_STRING ;\n\n Command -> BSLASH_IDENT CommandParams ? { newCommand } ;\n CommandParams -> OPEN_PAREN ParamList ? CLOSE_PAREN { $2 } ;\n\n ParamList -> ParamList COMMA Param { concatParamList } ;\n ParamList -> Param { newParamList };\n Param -> ParamValue { newParam } ;\n Param -> ParamKey EQUALS ParamValue { newParam } ;\n ParamKey -> IDENT ;\n ParamValue -> ( STRING | Fraction | NUMBER | BOOLEAN ) ;\n\n RoleSelector -> IDENT_COLON ;\n\n Atoms -> Atoms Atom { concatAtoms } ;\n Atoms -> { newArray } ;\n\n Atom -> Atom POST_MARKER { applyPostMarker }\n | PreMarkedAtom\n ;\n PreMarkedAtom -> Leaf\n | PRE_MARKER PreMarkedAtom { applyPreMarker }\n ;\n\n Leaf -> Space | Lit | Group | Rest ;\n Leaf -> Duration Leaf { applyDuration } ;\n Rest -> HYPHEN { newRest };\n Space -> COMMA { newSpace } \n | SEMI_COLON { newDoubleSpace } \n | UNDER_SCORE { newSilentSpace } \n ;\n\n /* - An alternative representation to support both pre and\n * post embelishment operators. Here PRE_EMBs have a higher\n * associativity over POST_EMBs\n */\n Lit -> Lit POST_EMB { litWithPostEmb }\n | PreEmbLit\n ;\n\n PreEmbLit -> LitToken \n | LitToken CARET NUMBER { litWithCaret }\n | LitToken CARET STAR { litWithCaret }\n | PRE_EMB PreEmbLit { litWithPreEmb }\n ;\n \n LitToken -> DOTS_IDENT { litToAtom }\n | IDENT { litToAtom }\n | IDENT_DOTS { litToAtom }\n | STRING { litToAtom }\n ;\n\n Group -> OPEN_SQ Atoms CLOSE_SQ { newGroup };\n\n Duration -> Fraction | NUMBER;\n Fraction -> NUMBER SLASH NUMBER { newFraction } ;\n `,\n {\n allowLeftRecursion: true,\n debug: \"\",\n type: \"lalr\",\n tokenHandlers: {\n toEmbelishment: (token: TLEX.Token, tape: TLEX.Tape, owner: Parser) => {\n const [emb, pre] = owner.parseEmbelishment(token.value);\n if (emb == null) {\n console.log(\"Skipping Embelishment: \", token.value);\n owner.errors.push(\n new TLEX.TokenizerError(\n `Invalid embelishment: ${token.value}`,\n token.start,\n 1 + token.end - token.start,\n \"InvalidEmbelishment\",\n token.value,\n ),\n );\n return null;\n }\n token.value = emb;\n token.tag = pre ? \"PRE_EMB\" : \"POST_EMB\";\n return token;\n },\n toCommandName: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value.substring(1);\n return token;\n },\n toBoolean: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value == \"true\";\n return token;\n },\n toNumber: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = parseInt(token.value);\n return token;\n },\n toString: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value.substring(1, token.value.length - 1);\n return token;\n },\n toMarker: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n if (token.tag != \"PRE_MARKER\" && token.tag != \"POST_MARKER\") {\n throw new Error(\"Invalid token for converting to note: \" + token.tag);\n }\n const isBefore = token.tag == \"PRE_MARKER\";\n const markerText = isBefore\n ? token.value.substring(1, token.value.length - 3)\n : token.value.substring(3, token.value.length - 1);\n // console.log(\"TokVal: \", token.value, token.positions);\n // console.log(\"Marker Text: \", markerText, isBefore);\n token.value = new Marker(markerText, isBefore);\n return token;\n },\n toOctavedNote: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n if (token.tag == \"DOTS_IDENT\") {\n const octave = token.positions[1][1] - token.positions[1][0];\n const note = token.value.substring(octave);\n token.value = new Note(note, ONE, -octave);\n } else if (token.tag == \"IDENT_DOTS\") {\n const octave = token.positions[2][1] - token.positions[2][0];\n const note = token.value.substring(0, token.value.length - octave);\n token.value = new Note(note, ONE, octave);\n } else {\n throw new Error(\"Invalid token for converting to note: \" + token.tag);\n }\n return token;\n },\n toRoleSelector: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n token.value = token.value.substring(0, token.value.length - 1);\n return token;\n },\n toLineAnnotation: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // skip the initial \"!\"\n token.value = token.value.substring(1);\n return token;\n },\n toSingleLineRawString: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // skip the initial \">\"\n token.value = token.value.substring(1);\n return token;\n },\n toMultiLineRawString: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // consume everything until \"#<N times> as start\n const hashes = tape.substring(token.positions[1][0], token.positions[1][1]);\n const endPat = '\"' + hashes;\n const startPos = tape.index;\n const endPos = TLEX.TapeHelper.advanceAfter(tape, endPat) - endPat.length;\n if (endPos < 0) {\n throw new Error(\"EOF expected while finding end of Raw String Literal: '\" + endPat + \"'\");\n }\n token.value = tape.substring(startPos, endPos);\n return token;\n },\n toFrontMatter: (token: TLEX.Token, tape: TLEX.Tape, owner: any) => {\n // skip the initial \">\"\n const endPat = \"\\n---\";\n const startPos = tape.index;\n const endPos = TLEX.TapeHelper.advanceAfter(tape, endPat) - endPat.length;\n if (endPos < 0) {\n throw new Error(\"EOF expected while finding end of front matter\");\n }\n token.value = tape.substring(startPos, endPos);\n // console.log(\"Found FM: \", token.value);\n return token;\n },\n },\n },\n);\n\n/**\n * A notation doc is a list of lines that are found in a single document.\n *\n * Since our document (md or html etc) can contain multiple snippets\n * all these snippets are related\n */\nexport class Parser {\n errors: (TLEX.TokenizerError | G.ParseError)[] = [];\n metadata: any = {};\n readonly commands: Command[] = [];\n // readonly notation: Notation = new Notation();\n // private runCommandFound = false;\n // readonly parseTree = new PTNodeList(\"Snippet\", null);\n\n protected ruleHandlers = {\n newFraction: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n if (children.length == 1) {\n return new TSU.Num.Fraction(children[0].value);\n } else {\n return new TSU.Num.Fraction(children[0].value, children[2].value);\n }\n },\n newGroup: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const out = new Group(...children[1].value).setDuration(TWO, true);\n return out;\n },\n litWithCaret: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const lit = Note.fromLit(children[0].value as Literal);\n const opnode = children[2];\n const shiftValue = opnode.sym.label == \"STAR\" ? true : opnode.value;\n lit.shift = shiftValue;\n return lit;\n },\n litWithPreEmb: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const emb = children[0];\n const lit = children[1].value as Literal;\n lit.embelishments.splice(0, 0, emb.value);\n return lit;\n },\n litWithPostEmb: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const lit = children[0].value as Literal;\n const emb = children[1];\n lit.embelishments.push(emb);\n return lit;\n },\n litToAtom: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const lit = children[0];\n if (lit.sym.label == \"DOTS_IDENT\" || lit.sym.label == \"IDENT_DOTS\") {\n return lit.value;\n } else if (lit.sym.label == \"IDENT\") {\n // Mark this as a Literal to be processed later\n return new Literal(lit.value);\n // return role.notesOnly ? new Note(lit.value) : new Syllable(lit.value);\n } else if (lit.sym.label == \"STRING\") {\n // const role = this.snippet.currRole;\n // if (role.notesOnly) throw new Error(\"Strings cannot appear in notes only mode\");\n return new Syllable(lit.value);\n } else {\n throw new Error(\"Invalid lit: \" + lit);\n }\n },\n newSpace: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Space();\n },\n newRest: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Rest();\n },\n newDoubleSpace: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Space(ONE.timesNum(2));\n },\n newSilentSpace: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return new Space(ONE, true);\n },\n applyPreMarker: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const marker = children[0].value as Marker;\n const leaf = children[1].value as Atom;\n // console.log(\"marker, leaf: \", marker, leaf);\n if (!leaf.markersBefore) {\n leaf.markersBefore = [];\n }\n leaf.markersBefore.splice(0, 0, marker);\n return leaf;\n },\n applyPostMarker: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const leaf = children[0].value as Atom;\n const marker = children[1].value as Marker;\n if (!leaf.markersAfter) {\n leaf.markersAfter = [];\n }\n leaf.markersAfter.push(marker);\n return leaf;\n },\n applyDuration: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n let dur = children[0].value as TSU.Num.Fraction | number;\n const leaf = children[1].value as Atom;\n if (typeof dur === \"number\") {\n dur = ONE.timesNum(dur);\n }\n if (leaf.TYPE == AtomType.GROUP) {\n (leaf as Group).setDuration(dur, true);\n } else {\n leaf.duration = dur;\n }\n return leaf;\n },\n newArray: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n // create an array of values from all the values of child nodes\n return children.map((c) => c.value);\n },\n concatAtoms: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const atoms = children[0].value;\n const atom = children[1].value;\n atoms.push(atom);\n return atoms;\n },\n newParam: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n if (children.length == 1) {\n return { key: null, value: children[0].value };\n } else {\n return { key: children[0].value, value: children[2].value };\n }\n },\n newParamList: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return [children[0].value];\n },\n concatParamList: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const params = children[0].value;\n const newParam = children[2].value;\n params.push(newParam);\n return params;\n },\n newCommand: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n return this.createCommand(children[0].value, children[1].value);\n },\n appendAtoms: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const atoms = children[0].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n prependFrontMatter: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const fm = children[0].value;\n // console.log(\"Child 0: \", fm);\n // console.log(\"Child 1: \", children[1].value);\n const { data } = matter(\"---\\n\" + fm + \"\\n---\");\n console.log(\"Parsed FM: \", data);\n this.metadata = data;\n return children[1].value;\n },\n appendCommand: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const command = children[1].value as Command;\n this.addCommand(command);\n\n const atoms = children[2].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n appendRoleSelector: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n const roleName = children[1].value;\n const lName = roleName.toLowerCase().trim();\n this.addCommand(new ActivateRole([{ key: null, value: lName }]));\n\n const atoms = children[2].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n insertEmbedding: (rule: G.Rule, parent: G.PTNode, ...children: G.PTNode[]) => {\n // How to handle embeddings - these are just blocks\n // to escape out of song (most likely for some rendering of html/md etc)\n const rawVal = children[1].value;\n this.addCommand(new RawEmbedding([{ key: null, value: rawVal }]));\n const atoms = children[2].value as Atom[];\n if (atoms.length > 0) {\n this.addCommand(new AddAtoms(...atoms));\n }\n return null;\n },\n };\n\n constructor(config?: any) {\n config = config || {};\n }\n\n createCommand(name: string, params: CmdParam[]): Command {\n const lName = name.trim().toLowerCase();\n params = params || [];\n if (lName == \"line\") {\n return new CreateLine(params);\n // } else if (lName == \"meta\") { return new MetaData(params);\n } else if (lName == \"role\") {\n return new CreateRole(params);\n } else if (lName == \"layout\") {\n return new ApplyLayout(params);\n } else if (lName == \"beatduration\") {\n return new SetBeatDuration(params);\n } else if (lName == \"breaks\") {\n return new SetBreaks(params);\n } else if (lName == \"cycle\") {\n return new SetCycle(params);\n } else {\n // Try to set this as the current role\n throw new Error(\"Invalid command: \" + lName);\n }\n }\n\n addCommand(cmd: Command): void {\n cmd.index = this.commands.length;\n this.commands.push(cmd);\n }\n\n parse(input: string): any {\n this.errors = [];\n try {\n const ptree = parser.parse(input, {\n tokenizerContext: this,\n ruleHandlers: this.ruleHandlers,\n onTokenError: (err: TLEX.TokenizerError) => {\n this.errors.push(err);\n return true;\n },\n });\n return ptree;\n } catch (err) {\n if (err instanceof G.ParseError) {\n this.errors.push(err);\n } else {\n throw err;\n }\n }\n return null;\n }\n\n parseAndBuild(input: string): [Notation, G.ParseError[]] {\n this.parse(input);\n const notation = new Notation();\n const errors: G.ParseError[] = [];\n errors.push(...this.errors);\n\n // First add the metadata then we can set it\n for (const key in this.metadata) notation.addMetaData(new Meta(key, this.metadata[key]));\n for (const cmd of this.commands) cmd.applyToNotation(notation);\n return [notation, errors];\n }\n\n parseEmbelishment(value: string): [any, boolean] {\n return carnatic.parseEmbelishment(value);\n }\n}\n"]}
package/lib/cjs/shapes.js CHANGED
@@ -293,7 +293,7 @@ class GroupView extends AtomView {
293
293
  const totalDur = this.group.totalChildDuration;
294
294
  let currTime = core_1.ZERO;
295
295
  this.atomViews.forEach((av, index) => {
296
- let newX = currTime.timesNum(this.minSize.width).divby(this.group.duration).floor;
296
+ const newX = currTime.timesNum(this.minSize.width).divby(this.group.duration).floor;
297
297
  if (newX >= currX) {
298
298
  currX = newX;
299
299
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shapes.js","sourceRoot":"","sources":["../../src/shapes.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { ZERO, Atom, LeafAtom, Group } from \"./core\";\n\n/**\n * Base class for all renderable objects.\n * \n * Shape caches properties like bounding boxes to improve performance,\n * since bounding box calculations can be expensive. This also allows\n * testing layouts and positioning without worrying about implementation details.\n */\nexport abstract class Shape {\n private static idCounter = 0;\n readonly shapeId: number = Shape.idCounter++;\n \n /**\n * Note that x and y coordinates are not always the x and y coordinates\n * of the bounding box.\n * E.g., a circle's x and y coordinates are its center point and not the\n * top left corner.\n * These \"main\" coordinates are referred to as control coordinates.\n */\n protected _x: number | null = null;\n protected _y: number | null = null;\n protected _width: number | null = null;\n protected _height: number | null = null;\n protected _bbox: TSU.Geom.Rect;\n protected _minSize: TSU.Geom.Size;\n protected parentShape: Shape | null = null;\n /** Child shapes contained within this shape */\n children: Shape[] = [];\n\n /**\n * Gets the bounding box of this shape.\n * Calculates it if it hasn't been calculated yet.\n */\n get bbox(): TSU.Geom.Rect {\n if (!this._bbox) {\n this._bbox = this.refreshBBox();\n }\n return this._bbox;\n }\n\n /**\n * Gets the minimum size of this shape.\n * This is usually the size of the bounding box.\n */\n get minSize(): TSU.Geom.Size {\n if (!this._minSize) {\n this._minSize = this.refreshMinSize();\n }\n return this._minSize;\n }\n\n /**\n * Refreshes the bounding box of this shape.\n * Called when the shape knows the bbox it is tracking cannot be trusted\n * and has to be refreshed by calling native methods.\n * @returns The refreshed bounding box\n */\n protected abstract refreshBBox(): TSU.Geom.Rect;\n \n /**\n * Refreshes the minimum size of this shape.\n * @returns The refreshed minimum size\n */\n protected abstract refreshMinSize(): TSU.Geom.Size;\n \n /**\n * Updates the bounds of this shape.\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @returns The updated bounds values\n */\n protected abstract updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null];\n\n /**\n * Invalidates the cached bounds of this shape.\n * Forces recalculation of bounding box and minimum size.\n */\n invalidateBounds(): void {\n this._minSize = null as unknown as TSU.Geom.Size;\n this._bbox = null as unknown as TSU.Geom.Rect;\n }\n\n /**\n * Sets the bounds of this shape.\n * \n * Note that null and NaN are valid values and mean the following:\n * - null: Don't change the value\n * - NaN: Set the value to null (use the bounding box's value)\n * \n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @param applyLayout Whether to apply layout immediately\n * @returns The updated bounds values\n */\n setBounds(\n x: number | null,\n y: number | null,\n w: number | null,\n h: number | null,\n applyLayout = false,\n ): [number | null, number | null, number | null, number | null] {\n if (x != null) {\n if (isNaN(x)) {\n this._x = null;\n } else {\n this._x = x;\n }\n }\n if (y != null) {\n if (isNaN(y)) {\n this._y = null;\n } else {\n this._y = y;\n }\n }\n if (w != null) {\n if (isNaN(w)) {\n this._width = null;\n } else {\n this._width = w;\n }\n }\n if (h != null) {\n if (isNaN(h)) {\n this._height = null;\n } else {\n this._height = h;\n }\n }\n const [nx, ny, nw, nh] = this.updateBounds(x, y, w, h);\n if (nx != null) {\n if (isNaN(nx)) {\n this._x = null;\n } else {\n this._x = nx;\n }\n }\n if (ny != null) {\n if (isNaN(ny)) {\n this._y = null;\n } else {\n this._y = ny;\n }\n }\n if (nw != null) {\n if (isNaN(nw)) {\n this._width = null;\n } else {\n this._width = nw;\n }\n }\n if (nh != null) {\n if (isNaN(nh)) {\n this._height = null;\n } else {\n this._height = nh;\n }\n }\n if (applyLayout) this.refreshLayout();\n // this.resetBBox();\n return [nx, ny, nw, nh];\n }\n\n /**\n * Checks if this shape has an explicit x coordinate.\n */\n get hasX(): boolean {\n return this._x != null && !isNaN(this._x);\n }\n\n /**\n * Checks if this shape has an explicit y coordinate.\n */\n get hasY(): boolean {\n return this._y != null && !isNaN(this._y);\n }\n\n /**\n * Checks if this shape has an explicit width.\n */\n get hasWidth(): boolean {\n return this._width != null && !isNaN(this._width);\n }\n\n /**\n * Checks if this shape has an explicit height.\n */\n get hasHeight(): boolean {\n return this._height != null && !isNaN(this._height);\n }\n\n /**\n * Gets the x coordinate within the parent's coordinate system.\n */\n get x(): number {\n return this._x || 0;\n }\n\n /**\n * Sets the x coordinate within the parent's coordinate system.\n */\n set x(x: number | null) {\n // Here a manual x is being set - how does this interfere with the bounding box?\n // We should _x to the new value to indicate a manual value was set.\n // and reset bbox so that based on this x a new bbox may need to be calculated\n this.setBounds(x == null ? NaN : x, null, null, null);\n }\n\n /**\n * Gets the y coordinate within the parent's coordinate system.\n */\n get y(): number {\n if (this._y != null) return this._y;\n return 0; // this.bbox.y;\n }\n\n /**\n * Sets the y coordinate within the parent's coordinate system.\n */\n set y(y: number | null) {\n this.setBounds(null, y == null ? NaN : y, null, null);\n }\n\n /**\n * Gets the width of this shape.\n */\n get width(): number {\n if (this._width != null) return this._width;\n return 0; // this.bbox.width;\n }\n\n /**\n * Sets the width of this shape.\n */\n set width(w: number | null) {\n this.setBounds(null, null, w == null ? NaN : w, null);\n }\n\n /**\n * Gets the height of this shape.\n */\n get height(): number {\n if (this._height != null) return this._height;\n return 0; // this.bbox.height;\n }\n\n /**\n * Sets the height of this shape.\n */\n set height(h: number | null) {\n this.setBounds(null, null, null, h == null ? NaN : h);\n }\n\n /**\n * Refreshes the layout of this shape.\n * Called when bounds or other properties have changed to give the shape an\n * opportunity to layout its children. For shapes with no children this is a no-op.\n */\n refreshLayout(): void {\n // throw new Error(\"Implement this\");\n }\n}\n\n/**\n * Represents an embellishment applied to a musical element.\n */\nexport abstract class Embelishment extends Shape {}\n\n/**\n * A shape that wraps an SVG element.\n * ElementShape provides the base class for all shapes that are rendered as SVG elements.\n */\nexport class ElementShape<T extends SVGGraphicsElement = SVGGraphicsElement> extends Shape {\n /**\n * Creates a new ElementShape.\n * @param element The SVG element this shape wraps\n */\n constructor(public readonly element: T) {\n super();\n }\n\n /**\n * Refreshes the bounding box of this element.\n * @returns The refreshed bounding box\n */\n protected refreshBBox(): TSU.Geom.Rect {\n return TSU.DOM.svgBBox(this.element);\n }\n\n /**\n * Refreshes the minimum size of this element.\n * @returns The refreshed minimum size\n */\n protected refreshMinSize(): TSU.Geom.Size {\n return TSU.DOM.svgBBox(this.element);\n }\n\n /**\n * Updates the bounds of this element.\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @returns The updated bounds values\n */\n protected updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null] {\n return [x, y, w, h];\n }\n\n /**\n * Refreshes the layout of this element.\n * Updates the element's attributes based on the shape's properties.\n */\n refreshLayout(): void {\n if (this.hasX) this.element.setAttribute(\"x\", \"\" + this._x);\n if (this.hasY) this.element.setAttribute(\"y\", \"\" + this._y);\n }\n}\n\n/**\n * Base class for views that represent atoms in the notation.\n * AtomView provides the visual representation of an atom.\n */\nexport abstract class AtomView extends Shape {\n /** Nesting depth of this atom in the structure */\n depth = 0;\n /** Index of the role containing this atom */\n roleIndex = 0;\n\n // LayoutMetrics for the AtomView so all atomviews laid out on the\n // same baseline will show up aligned vertically\n /** Baseline position for vertical alignment */\n baseline: number;\n /** Ascent (space above baseline) */\n ascent: number;\n /** Descent (space below baseline) */\n descent: number;\n /** Height of capital letters */\n capHeight: number;\n /** Space between lines */\n leading: number;\n\n /**\n * Checks if this atom view represents a leaf atom.\n */\n abstract isLeaf(): boolean;\n\n abstract get totalDuration(): TSU.Num.Fraction;\n\n /**\n * Creates the SVG elements needed for this atom view.\n * @param parent The parent SVG element to attach to\n */\n abstract createElements(parent: SVGGraphicsElement): void;\n}\n\n/**\n * A view for leaf atoms (those that cannot contain other atoms).\n */\nexport abstract class LeafAtomView extends AtomView {\n /**\n * Creates a new LeafAtomView.\n * @param leafAtom The leaf atom this view represents\n */\n constructor(public leafAtom: LeafAtom) {\n super();\n }\n\n /**\n * Leaf atom views always return true for isLeaf().\n */\n isLeaf(): boolean {\n return true;\n }\n\n /**\n * Gets a unique identifier for this view based on the atom's UUID.\n */\n get viewId(): number {\n return this.leafAtom.uuid;\n }\n\n /**\n * Returns the total duration of the atom rendered by this view.\n */\n get totalDuration(): TSU.Num.Fraction {\n return this.leafAtom.duration\n }\n}\n\n/**\n * A view for group atoms that contain multiple child atoms.\n */\nexport abstract class GroupView extends AtomView {\n /** Space between atoms in this group */\n protected atomSpacing: number;\n /** The SVG group element for this view */\n protected groupElement: SVGGElement;\n /** Views for the atoms in this group */\n protected atomViews: AtomView[] = [];\n private _embelishments: Embelishment[];\n /** Whether this group represents notes by default */\n defaultToNotes = true;\n /** Whether this view needs layout */\n needsLayout = true;\n /** Scale factor for this group */\n scaleFactor = 1.0;\n \n /**\n * Creates a new GroupView.\n * @param group The group atom this view represents\n * @param config Optional configuration object\n */\n constructor(public group: Group, config?: any) {\n super();\n this.atomSpacing = 5;\n this.setStyles(config || {});\n }\n\n /**\n * Returns the total duration of the group rendered by this view.\n */\n get totalDuration(): TSU.Num.Fraction {\n return this.group.totalChildDuration\n }\n\n /**\n * Creates the SVG elements needed for this group view.\n * @param parent The parent SVG element to attach to\n */\n createElements(parent: SVGGraphicsElement): void {\n this.groupElement = TSU.DOM.createSVGNode(\"g\", {\n parent: parent,\n attrs: {\n class: \"groupViewRoot\",\n id: \"groupViewRoot\" + this.group.uuid,\n },\n });\n\n // now create child atom views for each atom in this Group\n for (const atom of this.group.atoms.values()) {\n const atomView = this.createAtomView(atom);\n this.atomViews.push(atomView);\n }\n this.invalidateBounds();\n }\n\n /**\n * Group views always return false for isLeaf().\n */\n isLeaf(): boolean {\n return false;\n }\n\n /**\n * Refreshes the bounding box of this group.\n * @returns The refreshed bounding box\n */\n protected refreshBBox(): TSU.Geom.Rect {\n return TSU.DOM.svgBBox(this.groupElement);\n }\n\n /**\n * Refreshes the minimum size of this group.\n * @returns The refreshed minimum size\n */\n protected refreshMinSize(): TSU.Geom.Size {\n let totalWidth = 0;\n let maxHeight = 0;\n this.atomViews.forEach((av, index) => {\n const ms = av.minSize;\n totalWidth += ms.width + this.atomSpacing;\n maxHeight = Math.max(maxHeight, ms.height);\n });\n return new TSU.Geom.Size(totalWidth * this.scaleFactor, maxHeight * this.scaleFactor);\n }\n\n /**\n * Creates an atom view for a specific atom.\n * @param atom The atom to create a view for\n * @returns The created atom view\n */\n abstract createAtomView(atom: Atom): AtomView;\n\n /**\n * Updates the bounds of this group.\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @returns The updated bounds values\n */\n protected updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null] {\n return [x, y, w, h];\n }\n\n /**\n * Refreshes the layout of this group.\n * Updates the position and size of the group and its child atoms.\n */\n refreshLayout(): void {\n let transform = \"translate(\" + this.x + \",\" + this.y + \")\";\n if (this.scaleFactor < 1) {\n transform += \" scale(\" + this.scaleFactor + \")\";\n }\n this.groupElement.setAttribute(\"transform\", transform);\n // if (this.widthChanged) {\n // All our atoms have to be laid out between startX and endX\n // old way of doing where we just set dx between atom views\n // this worked when atomviews were single glyphs. But\n // as atomViews can be complex (eg with accents and pre/post\n // spaces etc) explicitly setting x/y may be important\n let currX = 0;\n const currY = 0; // null; // this.y; // + 10;\n\n if (true) {\n this.atomViews.forEach((av, index) => {\n av.setBounds(currX, currY, null, null, true);\n currX += this.atomSpacing + av.minSize.width;\n });\n } else { // currently this is disabled because \"smaller\" beats are not EXPANDED to what they could be\n // smart alignment based layout where X = F(offset)\n // we want an atom's X offset to be something like (atom.timeOffset / group.duration) * groupWidth\n const totalDur = this.group.totalChildDuration;\n let currTime = ZERO\n this.atomViews.forEach((av, index) => {\n let newX = currTime.timesNum(this.minSize.width).divby(this.group.duration).floor\n if (newX >= currX) {\n currX = newX\n }\n av.setBounds(currX, currY, null, null, true);\n currX += this.atomSpacing + av.minSize.width;\n currTime = currTime.plus(av.totalDuration)\n });\n }\n this.invalidateBounds();\n for (const e of this.embelishments) e.refreshLayout();\n this.invalidateBounds();\n }\n\n /**\n * Gets the embellishments for this group.\n */\n get embelishments(): Embelishment[] {\n if (!this._embelishments) {\n this._embelishments = this.createEmbelishments();\n }\n return this._embelishments;\n }\n\n /**\n * Creates the embellishments for this group.\n * @returns An array of embellishments\n */\n protected createEmbelishments(): Embelishment[] {\n return [];\n }\n\n /**\n * Sets the styles for this group.\n * @param config Style configuration object\n */\n setStyles(config: any): void {\n if (\"atomSpacing\" in config) this.atomSpacing = config.atomSpacing;\n this.needsLayout = true;\n }\n}\n"]}
1
+ {"version":3,"file":"shapes.js","sourceRoot":"","sources":["../../src/shapes.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { ZERO, Atom, LeafAtom, Group } from \"./core\";\n\n/**\n * Base class for all renderable objects.\n *\n * Shape caches properties like bounding boxes to improve performance,\n * since bounding box calculations can be expensive. This also allows\n * testing layouts and positioning without worrying about implementation details.\n */\nexport abstract class Shape {\n private static idCounter = 0;\n readonly shapeId: number = Shape.idCounter++;\n\n /**\n * Note that x and y coordinates are not always the x and y coordinates\n * of the bounding box.\n * E.g., a circle's x and y coordinates are its center point and not the\n * top left corner.\n * These \"main\" coordinates are referred to as control coordinates.\n */\n protected _x: number | null = null;\n protected _y: number | null = null;\n protected _width: number | null = null;\n protected _height: number | null = null;\n protected _bbox: TSU.Geom.Rect;\n protected _minSize: TSU.Geom.Size;\n protected parentShape: Shape | null = null;\n /** Child shapes contained within this shape */\n children: Shape[] = [];\n\n /**\n * Gets the bounding box of this shape.\n * Calculates it if it hasn't been calculated yet.\n */\n get bbox(): TSU.Geom.Rect {\n if (!this._bbox) {\n this._bbox = this.refreshBBox();\n }\n return this._bbox;\n }\n\n /**\n * Gets the minimum size of this shape.\n * This is usually the size of the bounding box.\n */\n get minSize(): TSU.Geom.Size {\n if (!this._minSize) {\n this._minSize = this.refreshMinSize();\n }\n return this._minSize;\n }\n\n /**\n * Refreshes the bounding box of this shape.\n * Called when the shape knows the bbox it is tracking cannot be trusted\n * and has to be refreshed by calling native methods.\n * @returns The refreshed bounding box\n */\n protected abstract refreshBBox(): TSU.Geom.Rect;\n\n /**\n * Refreshes the minimum size of this shape.\n * @returns The refreshed minimum size\n */\n protected abstract refreshMinSize(): TSU.Geom.Size;\n\n /**\n * Updates the bounds of this shape.\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @returns The updated bounds values\n */\n protected abstract updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null];\n\n /**\n * Invalidates the cached bounds of this shape.\n * Forces recalculation of bounding box and minimum size.\n */\n invalidateBounds(): void {\n this._minSize = null as unknown as TSU.Geom.Size;\n this._bbox = null as unknown as TSU.Geom.Rect;\n }\n\n /**\n * Sets the bounds of this shape.\n *\n * Note that null and NaN are valid values and mean the following:\n * - null: Don't change the value\n * - NaN: Set the value to null (use the bounding box's value)\n *\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @param applyLayout Whether to apply layout immediately\n * @returns The updated bounds values\n */\n setBounds(\n x: number | null,\n y: number | null,\n w: number | null,\n h: number | null,\n applyLayout = false,\n ): [number | null, number | null, number | null, number | null] {\n if (x != null) {\n if (isNaN(x)) {\n this._x = null;\n } else {\n this._x = x;\n }\n }\n if (y != null) {\n if (isNaN(y)) {\n this._y = null;\n } else {\n this._y = y;\n }\n }\n if (w != null) {\n if (isNaN(w)) {\n this._width = null;\n } else {\n this._width = w;\n }\n }\n if (h != null) {\n if (isNaN(h)) {\n this._height = null;\n } else {\n this._height = h;\n }\n }\n const [nx, ny, nw, nh] = this.updateBounds(x, y, w, h);\n if (nx != null) {\n if (isNaN(nx)) {\n this._x = null;\n } else {\n this._x = nx;\n }\n }\n if (ny != null) {\n if (isNaN(ny)) {\n this._y = null;\n } else {\n this._y = ny;\n }\n }\n if (nw != null) {\n if (isNaN(nw)) {\n this._width = null;\n } else {\n this._width = nw;\n }\n }\n if (nh != null) {\n if (isNaN(nh)) {\n this._height = null;\n } else {\n this._height = nh;\n }\n }\n if (applyLayout) this.refreshLayout();\n // this.resetBBox();\n return [nx, ny, nw, nh];\n }\n\n /**\n * Checks if this shape has an explicit x coordinate.\n */\n get hasX(): boolean {\n return this._x != null && !isNaN(this._x);\n }\n\n /**\n * Checks if this shape has an explicit y coordinate.\n */\n get hasY(): boolean {\n return this._y != null && !isNaN(this._y);\n }\n\n /**\n * Checks if this shape has an explicit width.\n */\n get hasWidth(): boolean {\n return this._width != null && !isNaN(this._width);\n }\n\n /**\n * Checks if this shape has an explicit height.\n */\n get hasHeight(): boolean {\n return this._height != null && !isNaN(this._height);\n }\n\n /**\n * Gets the x coordinate within the parent's coordinate system.\n */\n get x(): number {\n return this._x || 0;\n }\n\n /**\n * Sets the x coordinate within the parent's coordinate system.\n */\n set x(x: number | null) {\n // Here a manual x is being set - how does this interfere with the bounding box?\n // We should _x to the new value to indicate a manual value was set.\n // and reset bbox so that based on this x a new bbox may need to be calculated\n this.setBounds(x == null ? NaN : x, null, null, null);\n }\n\n /**\n * Gets the y coordinate within the parent's coordinate system.\n */\n get y(): number {\n if (this._y != null) return this._y;\n return 0; // this.bbox.y;\n }\n\n /**\n * Sets the y coordinate within the parent's coordinate system.\n */\n set y(y: number | null) {\n this.setBounds(null, y == null ? NaN : y, null, null);\n }\n\n /**\n * Gets the width of this shape.\n */\n get width(): number {\n if (this._width != null) return this._width;\n return 0; // this.bbox.width;\n }\n\n /**\n * Sets the width of this shape.\n */\n set width(w: number | null) {\n this.setBounds(null, null, w == null ? NaN : w, null);\n }\n\n /**\n * Gets the height of this shape.\n */\n get height(): number {\n if (this._height != null) return this._height;\n return 0; // this.bbox.height;\n }\n\n /**\n * Sets the height of this shape.\n */\n set height(h: number | null) {\n this.setBounds(null, null, null, h == null ? NaN : h);\n }\n\n /**\n * Refreshes the layout of this shape.\n * Called when bounds or other properties have changed to give the shape an\n * opportunity to layout its children. For shapes with no children this is a no-op.\n */\n refreshLayout(): void {\n // throw new Error(\"Implement this\");\n }\n}\n\n/**\n * Represents an embellishment applied to a musical element.\n */\nexport abstract class Embelishment extends Shape {}\n\n/**\n * A shape that wraps an SVG element.\n * ElementShape provides the base class for all shapes that are rendered as SVG elements.\n */\nexport class ElementShape<T extends SVGGraphicsElement = SVGGraphicsElement> extends Shape {\n /**\n * Creates a new ElementShape.\n * @param element The SVG element this shape wraps\n */\n constructor(public readonly element: T) {\n super();\n }\n\n /**\n * Refreshes the bounding box of this element.\n * @returns The refreshed bounding box\n */\n protected refreshBBox(): TSU.Geom.Rect {\n return TSU.DOM.svgBBox(this.element);\n }\n\n /**\n * Refreshes the minimum size of this element.\n * @returns The refreshed minimum size\n */\n protected refreshMinSize(): TSU.Geom.Size {\n return TSU.DOM.svgBBox(this.element);\n }\n\n /**\n * Updates the bounds of this element.\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @returns The updated bounds values\n */\n protected updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null] {\n return [x, y, w, h];\n }\n\n /**\n * Refreshes the layout of this element.\n * Updates the element's attributes based on the shape's properties.\n */\n refreshLayout(): void {\n if (this.hasX) this.element.setAttribute(\"x\", \"\" + this._x);\n if (this.hasY) this.element.setAttribute(\"y\", \"\" + this._y);\n }\n}\n\n/**\n * Base class for views that represent atoms in the notation.\n * AtomView provides the visual representation of an atom.\n */\nexport abstract class AtomView extends Shape {\n /** Nesting depth of this atom in the structure */\n depth = 0;\n /** Index of the role containing this atom */\n roleIndex = 0;\n\n // LayoutMetrics for the AtomView so all atomviews laid out on the\n // same baseline will show up aligned vertically\n /** Baseline position for vertical alignment */\n baseline: number;\n /** Ascent (space above baseline) */\n ascent: number;\n /** Descent (space below baseline) */\n descent: number;\n /** Height of capital letters */\n capHeight: number;\n /** Space between lines */\n leading: number;\n\n /**\n * Checks if this atom view represents a leaf atom.\n */\n abstract isLeaf(): boolean;\n\n abstract get totalDuration(): TSU.Num.Fraction;\n\n /**\n * Creates the SVG elements needed for this atom view.\n * @param parent The parent SVG element to attach to\n */\n abstract createElements(parent: SVGGraphicsElement): void;\n}\n\n/**\n * A view for leaf atoms (those that cannot contain other atoms).\n */\nexport abstract class LeafAtomView extends AtomView {\n /**\n * Creates a new LeafAtomView.\n * @param leafAtom The leaf atom this view represents\n */\n constructor(public leafAtom: LeafAtom) {\n super();\n }\n\n /**\n * Leaf atom views always return true for isLeaf().\n */\n isLeaf(): boolean {\n return true;\n }\n\n /**\n * Gets a unique identifier for this view based on the atom's UUID.\n */\n get viewId(): number {\n return this.leafAtom.uuid;\n }\n\n /**\n * Returns the total duration of the atom rendered by this view.\n */\n get totalDuration(): TSU.Num.Fraction {\n return this.leafAtom.duration;\n }\n}\n\n/**\n * A view for group atoms that contain multiple child atoms.\n */\nexport abstract class GroupView extends AtomView {\n /** Space between atoms in this group */\n protected atomSpacing: number;\n /** The SVG group element for this view */\n protected groupElement: SVGGElement;\n /** Views for the atoms in this group */\n protected atomViews: AtomView[] = [];\n private _embelishments: Embelishment[];\n /** Whether this group represents notes by default */\n defaultToNotes = true;\n /** Whether this view needs layout */\n needsLayout = true;\n /** Scale factor for this group */\n scaleFactor = 1.0;\n\n /**\n * Creates a new GroupView.\n * @param group The group atom this view represents\n * @param config Optional configuration object\n */\n constructor(\n public group: Group,\n config?: any,\n ) {\n super();\n this.atomSpacing = 5;\n this.setStyles(config || {});\n }\n\n /**\n * Returns the total duration of the group rendered by this view.\n */\n get totalDuration(): TSU.Num.Fraction {\n return this.group.totalChildDuration;\n }\n\n /**\n * Creates the SVG elements needed for this group view.\n * @param parent The parent SVG element to attach to\n */\n createElements(parent: SVGGraphicsElement): void {\n this.groupElement = TSU.DOM.createSVGNode(\"g\", {\n parent: parent,\n attrs: {\n class: \"groupViewRoot\",\n id: \"groupViewRoot\" + this.group.uuid,\n },\n });\n\n // now create child atom views for each atom in this Group\n for (const atom of this.group.atoms.values()) {\n const atomView = this.createAtomView(atom);\n this.atomViews.push(atomView);\n }\n this.invalidateBounds();\n }\n\n /**\n * Group views always return false for isLeaf().\n */\n isLeaf(): boolean {\n return false;\n }\n\n /**\n * Refreshes the bounding box of this group.\n * @returns The refreshed bounding box\n */\n protected refreshBBox(): TSU.Geom.Rect {\n return TSU.DOM.svgBBox(this.groupElement);\n }\n\n /**\n * Refreshes the minimum size of this group.\n * @returns The refreshed minimum size\n */\n protected refreshMinSize(): TSU.Geom.Size {\n let totalWidth = 0;\n let maxHeight = 0;\n this.atomViews.forEach((av, index) => {\n const ms = av.minSize;\n totalWidth += ms.width + this.atomSpacing;\n maxHeight = Math.max(maxHeight, ms.height);\n });\n return new TSU.Geom.Size(totalWidth * this.scaleFactor, maxHeight * this.scaleFactor);\n }\n\n /**\n * Creates an atom view for a specific atom.\n * @param atom The atom to create a view for\n * @returns The created atom view\n */\n abstract createAtomView(atom: Atom): AtomView;\n\n /**\n * Updates the bounds of this group.\n * @param x New x coordinate, or null to keep current value\n * @param y New y coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @returns The updated bounds values\n */\n protected updateBounds(\n x: null | number,\n y: null | number,\n w: null | number,\n h: null | number,\n ): [number | null, number | null, number | null, number | null] {\n return [x, y, w, h];\n }\n\n /**\n * Refreshes the layout of this group.\n * Updates the position and size of the group and its child atoms.\n */\n refreshLayout(): void {\n let transform = \"translate(\" + this.x + \",\" + this.y + \")\";\n if (this.scaleFactor < 1) {\n transform += \" scale(\" + this.scaleFactor + \")\";\n }\n this.groupElement.setAttribute(\"transform\", transform);\n // if (this.widthChanged) {\n // All our atoms have to be laid out between startX and endX\n // old way of doing where we just set dx between atom views\n // this worked when atomviews were single glyphs. But\n // as atomViews can be complex (eg with accents and pre/post\n // spaces etc) explicitly setting x/y may be important\n let currX = 0;\n const currY = 0; // null; // this.y; // + 10;\n\n if (true) {\n this.atomViews.forEach((av, index) => {\n av.setBounds(currX, currY, null, null, true);\n currX += this.atomSpacing + av.minSize.width;\n });\n } else {\n // currently this is disabled because \"smaller\" beats are not EXPANDED to what they could be\n // smart alignment based layout where X = F(offset)\n // we want an atom's X offset to be something like (atom.timeOffset / group.duration) * groupWidth\n const totalDur = this.group.totalChildDuration;\n let currTime = ZERO;\n this.atomViews.forEach((av, index) => {\n const newX = currTime.timesNum(this.minSize.width).divby(this.group.duration).floor;\n if (newX >= currX) {\n currX = newX;\n }\n av.setBounds(currX, currY, null, null, true);\n currX += this.atomSpacing + av.minSize.width;\n currTime = currTime.plus(av.totalDuration);\n });\n }\n this.invalidateBounds();\n for (const e of this.embelishments) e.refreshLayout();\n this.invalidateBounds();\n }\n\n /**\n * Gets the embellishments for this group.\n */\n get embelishments(): Embelishment[] {\n if (!this._embelishments) {\n this._embelishments = this.createEmbelishments();\n }\n return this._embelishments;\n }\n\n /**\n * Creates the embellishments for this group.\n * @returns An array of embellishments\n */\n protected createEmbelishments(): Embelishment[] {\n return [];\n }\n\n /**\n * Sets the styles for this group.\n * @param config Style configuration object\n */\n setStyles(config: any): void {\n if (\"atomSpacing\" in config) this.atomSpacing = config.atomSpacing;\n this.needsLayout = true;\n }\n}\n"]}