Skip to content

Commit 0c67d27

Browse files
authored
Merge pull request #1514 from 0xfe/doc_improvements
A few doc clarifications
2 parents 94592d4 + 1ddcd83 commit 0c67d27

File tree

7 files changed

+67
-22
lines changed

7 files changed

+67
-22
lines changed

src/element.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,19 @@ export interface ElementStyle {
5858
/**
5959
* Element implements a generic base class for VexFlow, with implementations
6060
* of general functions and properties that can be inherited by all VexFlow elements.
61+
*
62+
* The Element is an abstract class that needs to be subclassed to work. It handles
63+
* style and text-font properties for the Element and any child elements, along with
64+
* working with the Registry to create unique ids, but does not have any tools for
65+
* formatting x or y positions or connections to a Stave.
6166
*/
6267
export abstract class Element {
6368
static get CATEGORY(): string {
6469
return Category.Element;
6570
}
6671

72+
// all Element objects keep a list of children that they are responsible and which
73+
// inherit the style of their parents.
6774
protected children: Element[] = [];
6875
protected static ID: number = 1000;
6976
protected static newID(): string {
@@ -108,6 +115,15 @@ export abstract class Element {
108115
Registry.getDefaultRegistry()?.register(this);
109116
}
110117

118+
/**
119+
* Adds a child Element to the Element, which lets it inherit the
120+
* same style as the parent when setGroupStyle() is called.
121+
*
122+
* Examples of children are noteheads and stems. Modifiers such
123+
* as Accidentals are generally not set as children.
124+
*
125+
* Note that StaveNote calls setGroupStyle() when setStyle() is called.
126+
*/
111127
addChildElement(child: Element): this {
112128
this.children.push(child);
113129
return this;
@@ -186,7 +202,7 @@ export abstract class Element {
186202

187203
/**
188204
* Draw the element and all its sub-elements (ie.: Modifiers in a Stave)
189-
* with the element style.
205+
* with the element's style (see `getStyle()` and `setStyle()`)
190206
*/
191207
drawWithStyle(): void {
192208
this.checkContext();
@@ -258,7 +274,7 @@ export abstract class Element {
258274
return this.attrs;
259275
}
260276

261-
/** Return an attribute. */
277+
/** Return an attribute, such as 'id', 'type' or 'class'. */
262278
// eslint-disable-next-line
263279
getAttribute(name: string): any {
264280
return this.attrs[name];
@@ -271,7 +287,7 @@ export abstract class Element {
271287
if (element) return element as unknown as SVGElement;
272288
}
273289

274-
/** Set an attribute. */
290+
/** Set an attribute such as 'id', 'class', or 'type'. */
275291
setAttribute(name: string, value: string | undefined): this {
276292
const oldID = this.attrs.id;
277293
const oldValue = this.attrs[name];
@@ -286,18 +302,18 @@ export abstract class Element {
286302
return this.boundingBox;
287303
}
288304

289-
/** Return the context. */
305+
/** Return the context, such as an SVGContext or CanvasContext object. */
290306
getContext(): RenderContext | undefined {
291307
return this.context;
292308
}
293309

294-
/** Set the context. */
310+
/** Set the context to an SVGContext or CanvasContext object */
295311
setContext(context?: RenderContext): this {
296312
this.context = context;
297313
return this;
298314
}
299315

300-
/** Validate and return the context. */
316+
/** Validate and return the rendering context. */
301317
checkContext(): RenderContext {
302318
return defined(this.context, 'NoContext', 'No rendering context attached to instance.');
303319
}
@@ -306,19 +322,24 @@ export abstract class Element {
306322
// Font Handling
307323

308324
/**
309-
* Provide a CSS compatible font string (e.g., 'bold 16px Arial').
325+
* Provide a CSS compatible font string (e.g., 'bold 16px Arial') that will be applied
326+
* to text (not glyphs).
310327
*/
311328
set font(f: string) {
312329
this.setFont(f);
313330
}
314331

315-
/** Returns the CSS compatible font string. */
332+
/** Returns the CSS compatible font string for the text font. */
316333
get font(): string {
317334
return Font.toCSSString(this.textFont);
318335
}
319336

320337
/**
321-
* Set the element's font family, size, weight, style (e.g., `Arial`, `10pt`, `bold`, `italic`).
338+
* Set the element's text font family, size, weight, style
339+
* (e.g., `Arial`, `10pt`, `bold`, `italic`).
340+
*
341+
* This attribute does not determine the font used for musical Glyphs like treble clefs.
342+
*
322343
* @param font is 1) a `FontInfo` object or
323344
* 2) a string formatted as CSS font shorthand (e.g., 'bold 10pt Arial') or
324345
* 3) a string representing the font family (at least one of `size`, `weight`, or `style` must also be provided).
@@ -364,6 +385,10 @@ export abstract class Element {
364385
return this;
365386
}
366387

388+
/**
389+
* Get the css string describing this Element's text font. e.g.,
390+
* 'bold 10pt Arial'.
391+
*/
367392
getFont(): string {
368393
if (!this.textFont) {
369394
this.resetFont();

src/formatter.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { TabStave } from './tabstave';
1616
import { Tickable } from './tickable';
1717
import { TickContext } from './tickcontext';
1818
import { isNote, isStaveNote } from './typeguard';
19-
import { defined, log, midLine, RuntimeError } from './util';
19+
import { defined, log, midLine, RuntimeError, sumArray } from './util';
2020
import { Voice } from './voice';
2121

2222
interface Distance {
@@ -61,9 +61,6 @@ export interface AlignmentModifierContexts {
6161
type addToContextFn<T> = (tickable: Tickable, context: T, voiceIndex: number) => void;
6262
type makeContextFn<T> = (tick?: { tickID: number }) => T;
6363

64-
// Helper function
65-
const sumArray = (arr: number[]) => arr.reduce((a, b) => a + b, 0);
66-
6764
/**
6865
* Create `Alignment`s for each tick in `voices`. Also calculate the
6966
* total number of ticks in voices.

src/glyphnote.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// [VexFlow](https://vexflow.com) - Copyright (c) Mohit Muthanna 2010.
2+
//
3+
// Any glyph that is set to appear on a Stave and take up musical time and graphical space.
24

35
import { BoundingBox } from './boundingbox';
46
import { Glyph } from './glyph';

src/modifiercontext.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
// ## Description
44
//
55
// This class implements various types of members to notes (e.g. bends,
6-
// fingering positions etc.)
6+
// fingering positions etc.). The ModifierContext works with tickables
7+
// that are at the same tick to ensure that they and their modifiers
8+
// all have proper alignment. (Note that the ModifierContext also
9+
// runs the spacing of the tickable).
10+
//
11+
// see https://github.com/0xfe/vexflow/wiki/How-Formatting-Works
712

813
import { Accidental } from './accidental';
914
import { Annotation } from './annotation';
@@ -58,7 +63,8 @@ export class ModifierContext {
5863
top_text_line: 0,
5964
};
6065

61-
// Current members
66+
// Current members -- a mapping of Category (string) to a list of Tickables, Modifiers,
67+
// StaveNotes, TabNotes, etc.
6268
protected members: Record<string, ModifierContextMember[]> = {};
6369

6470
protected preFormatted: boolean = false;
@@ -102,6 +108,9 @@ export class ModifierContext {
102108
return this.members[category] ?? [];
103109
}
104110

111+
/**
112+
* Get the width of the entire
113+
*/
105114
getWidth(): number {
106115
return this.width;
107116
}

src/tickable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,13 @@ export abstract class Tickable extends Element {
205205
return this.tuplet;
206206
}
207207

208-
/** Return the intrinsic ticks. */
208+
/** Return a list of Tuplets. */
209209
getTupletStack(): Tuplet[] {
210210
return this.tupletStack;
211211
}
212212

213213
/**
214-
* Reset the specific Tuplet if this is not provided, all tuplets are reset.
214+
* Reset the specific Tuplet (if this is not provided, all tuplets are reset).
215215
* Remove any prior tuplets from the tick calculation and
216216
* reset the intrinsic tick value.
217217
*/

src/util.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,10 @@ export function normalizeAngle(a: number): number {
8989
}
9090
return a;
9191
}
92+
93+
/**
94+
* Return the sum of an array of numbers.
95+
*/
96+
export function sumArray(arr: number[]): number {
97+
return arr.reduce((a, b) => a + b, 0);
98+
}

src/voice.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Stave } from './stave';
99
import { Tables } from './tables';
1010
import { Tickable } from './tickable';
1111
import { Category } from './typeguard';
12-
import { defined, RuntimeError } from './util';
12+
import { defined, RuntimeError, sumArray } from './util';
1313

1414
export interface VoiceTime {
1515
num_beats: number;
@@ -88,6 +88,7 @@ export class Voice extends Element {
8888

8989
// Recalculate total ticks.
9090
this.totalTicks = new Fraction(this.time.num_beats * (this.time.resolution / this.time.beat_value), 1);
91+
// until tickables are added, the smallestTickCount is the same as the stated totalTicks duration.
9192
this.smallestTickCount = this.totalTicks.clone();
9293
}
9394

@@ -116,14 +117,14 @@ export class Voice extends Element {
116117
return this.tickables;
117118
}
118119

119-
/** Get the voice mode. */
120+
/** Get the voice mode (Voice.Mode.SOFT, STRICT, or FULL) */
120121
getMode(): number {
121122
return this.mode;
122123
}
123124

124125
/**
125126
* Set the voice mode.
126-
* @param mode value from `VoiceMode`
127+
* @param mode value from `VoiceMode` or Voice.Mode
127128
*/
128129
setMode(mode: number): this {
129130
this.mode = mode;
@@ -194,17 +195,21 @@ export class Voice extends Element {
194195
*/
195196
setSoftmaxFactor(factor: number): this {
196197
this.options.softmaxFactor = factor;
198+
this.expTicksUsed = 0; // reset
197199
return this;
198200
}
199201

200202
/**
201203
* Calculate the sum of the exponents of all the ticks in this voice to use
202-
* as the denominator of softmax.
204+
* as the denominator of softmax. (It is not the sum of the softmax(t) over all tickables)
205+
*
206+
* Note that the "exp" of "expTicksUsed" stands for "expontential" ticks used,
207+
* not "expected" ticks used.
203208
*/
204209
protected reCalculateExpTicksUsed(): number {
205210
const totalTicks = this.ticksUsed.value();
206211
const exp = (tickable: Tickable) => Math.pow(this.options.softmaxFactor, tickable.getTicks().value() / totalTicks);
207-
this.expTicksUsed = this.tickables.map(exp).reduce((a, b) => a + b, 0);
212+
this.expTicksUsed = sumArray(this.tickables.map(exp));
208213
return this.expTicksUsed;
209214
}
210215

0 commit comments

Comments
 (0)