linked-rolls 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -1
- package/lib/Assumption.d.ts +124 -0
- package/lib/Assumption.js +34 -0
- package/lib/Collation.d.ts +11 -0
- package/lib/ConditionState.d.ts +8 -3
- package/lib/ConditionState.js +0 -5
- package/lib/Edit.d.ts +44 -14
- package/lib/Edit.js +2 -95
- package/lib/Edition.d.ts +144 -4
- package/lib/EditionView.d.ts +51 -0
- package/lib/EditionView.js +294 -0
- package/lib/Emulation.d.ts +21 -68
- package/lib/Emulation.js +94 -386
- package/lib/Feature.d.ts +137 -16
- package/lib/Feature.js +9 -1
- package/lib/Plan.d.ts +190 -0
- package/lib/Plan.js +555 -0
- package/lib/ReproducingSystem.d.ts +80 -0
- package/lib/RollCopy.d.ts +259 -24
- package/lib/RollCopy.js +232 -215
- package/lib/Symbol.d.ts +70 -37
- package/lib/Symbol.js +2 -27
- package/lib/TrackCalibration.d.ts +33 -0
- package/lib/TrackCalibration.js +14 -0
- package/lib/TrackerBar.d.ts +52 -5
- package/lib/TrackerBar.js +70 -49
- package/lib/Version.d.ts +32 -33
- package/lib/Version.js +3 -209
- package/lib/alignFeatures.d.ts +3 -2
- package/lib/alignFeatures.js +5 -4
- package/lib/asJsonLd.d.ts +1 -1
- package/lib/asJsonLd.js +13 -26
- package/lib/importJsonLd.d.ts +0 -1
- package/lib/importJsonLd.js +9 -72
- package/lib/index.d.ts +7 -3
- package/lib/index.js +7 -3
- package/lib/schema.json +1739 -0
- package/lib/spec/context.json +125 -144
- package/lib/systems/welteT100.d.ts +55 -0
- package/lib/systems/welteT100.js +191 -0
- package/lib/utils.d.ts +29 -0
- package/lib/validate.d.ts +3 -0
- package/lib/validate.js +10 -0
- package/package.json +41 -8
- package/lib/Condition.d.ts +0 -10
- package/lib/EditorialAssumption.d.ts +0 -67
- package/lib/EditorialAssumption.js +0 -26
- package/lib/Measurement.d.ts +0 -9
- package/lib/PlaceTimeConversion.d.ts +0 -65
- package/lib/PlaceTimeConversion.js +0 -175
- package/lib/RollEvent.d.ts +0 -76
- package/lib/RollEvent.js +0 -3
- package/lib/Stage.d.ts +0 -37
- package/lib/Stage.js +0 -165
- package/lib/Transcription.d.ts +0 -7
- package/lib/Transcription.js +0 -9
- package/lib/WithId.d.ts +0 -3
- package/lib/WithId.js +0 -1
- package/lib/alignRolls.d.ts +0 -7
- package/lib/alignRolls.js +0 -49
- package/lib/alignSymbols.d.ts +0 -7
- package/lib/alignSymbols.js +0 -49
- package/lib/aton/AtonParser.test.d.ts +0 -1
- package/lib/aton/AtonParser.test.js +0 -16
- package/lib/build-schema.cjs +0 -113
- /package/lib/{Condition.js → ReproducingSystem.js} +0 -0
- /package/lib/{Measurement.js → utils.js} +0 -0
package/README.md
CHANGED
|
@@ -8,11 +8,58 @@ and exporting digital editions of piano roll. In particular it allows to:
|
|
|
8
8
|
- collate differing piano roll copies
|
|
9
9
|
- create an manipulate editorial assumptions
|
|
10
10
|
- export the edition as JSON-LD (based on the
|
|
11
|
-
linked-rolls
|
|
11
|
+
[Roll Edition Format](https://pfefferniels.github.io/linked-rolls/))
|
|
12
12
|
|
|
13
|
+
This library is the foundation of the
|
|
14
|
+
[Roll Desk](https://github.com/pfefferniels/roll-desk).
|
|
15
|
+
|
|
16
|
+
## Emulation
|
|
17
|
+
|
|
18
|
+
`Emulation` turns a version of the edition into MIDI. The core of the
|
|
19
|
+
library does the part that belongs to the edition: it negotiates the
|
|
20
|
+
symbols of a version into placed events, hands them to a
|
|
21
|
+
`ReproducingSystem`, and writes the performance out with every note and
|
|
22
|
+
pedal step labelled by the symbol it performs. A reproducing system is a
|
|
23
|
+
tracker bar and a `perform` function; the core does not depend on any one
|
|
24
|
+
instrument's model.
|
|
25
|
+
|
|
26
|
+
The first system is the red Welte, `linked-rolls/welte-t100`, built on
|
|
27
|
+
[welte-t100-emulator](https://github.com/pfefferniels/welte-t100): the
|
|
28
|
+
take-up spool sets the time axis, the Nuancierbälge fill through their
|
|
29
|
+
conduits and are arrested by the Mezzoforte pin, and the two pedals travel
|
|
30
|
+
rather than switch. The constants are those fitted against the hand-drawn
|
|
31
|
+
nuance lines of roll 3309, with the terms that describe the drawing
|
|
32
|
+
apparatus switched off. What the emulator does not determine is how
|
|
33
|
+
bellows travel maps onto MIDI velocity; `WelteT100Options.velocity`
|
|
34
|
+
anchors that map at the open rail, the Mezzoforte pin and the closed rail,
|
|
35
|
+
and its defaults are midi2exp's.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { Emulation } from 'linked-rolls'
|
|
39
|
+
import { welteT100System } from 'linked-rolls/welte-t100'
|
|
40
|
+
|
|
41
|
+
const emulation = new Emulation(welteT100System)
|
|
42
|
+
emulation.emulateVersion(version, view)
|
|
43
|
+
const midi = emulation.asMIDI()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The emulator is an optional peer dependency: an application that uses the
|
|
47
|
+
T-100 system installs `welte-t100-emulator` itself, and one that only
|
|
48
|
+
reads editions does not need it. For development on both at once, a
|
|
49
|
+
checkout of [welte-t100](https://github.com/pfefferniels/welte-t100)
|
|
50
|
+
beside this repository, declared as `file:../welte-t100`, works too.
|
|
13
51
|
|
|
14
52
|
## Building
|
|
15
53
|
```
|
|
16
54
|
npm i
|
|
17
55
|
npm run build
|
|
18
56
|
```
|
|
57
|
+
|
|
58
|
+
## Releasing
|
|
59
|
+
|
|
60
|
+
Releases go out through `.github/workflows/publish.yml`, never from a
|
|
61
|
+
laptop: raise the version in `package.json`, commit, and push a tag
|
|
62
|
+
`v<version>`, or run the workflow by hand from the Actions tab. The
|
|
63
|
+
workflow builds, runs the tests and publishes with provenance through
|
|
64
|
+
npm's trusted publishing, so no token is stored. It checks out the
|
|
65
|
+
emulator beside this repository to build the T-100 entry point.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { WithActor, WithNote, WithId } from "./utils";
|
|
2
|
+
export declare const certainties: readonly ["true", "likely", "possible", "unlikely", "false"];
|
|
3
|
+
/**
|
|
4
|
+
* Certainty levels for beliefs, ranging from 'true' to 'false'
|
|
5
|
+
* and some values in between.
|
|
6
|
+
*/
|
|
7
|
+
export type Certainty = typeof certainties[number];
|
|
8
|
+
/**
|
|
9
|
+
* An argumentation provides reasons for a belief and
|
|
10
|
+
* may be associated with a person carrying out that argumentation.
|
|
11
|
+
* @see crminf:I1 Argumentation
|
|
12
|
+
*/
|
|
13
|
+
export interface Argumentation<T extends string = 'simpleArgumentation'> extends WithActor, WithNote {
|
|
14
|
+
type: T;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A meaning comprehension interprets or disambiguates the meaning of
|
|
18
|
+
* symbols or features. For example, interpreting a pencil mark
|
|
19
|
+
* as an instruction to add or remove a perforation or as the dating
|
|
20
|
+
* of the roll.
|
|
21
|
+
*/
|
|
22
|
+
export interface MeaningComprehension extends Argumentation<'meaningComprehension'> {
|
|
23
|
+
/**
|
|
24
|
+
* References (by `@id`) to the symbols or features
|
|
25
|
+
* whose meaning is being interpreted.
|
|
26
|
+
* @see crminf:J22 interpreted meaning of
|
|
27
|
+
*/
|
|
28
|
+
comprehends: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* An inference draws a conclusion from given premises.
|
|
32
|
+
* @see crminf:I5 Inference Making
|
|
33
|
+
*/
|
|
34
|
+
export interface Inference extends Argumentation<'inference'> {
|
|
35
|
+
/**
|
|
36
|
+
* References (by `@id`) to the beliefs or facts
|
|
37
|
+
* from which the conclusion is drawn.
|
|
38
|
+
* @see crminf:J1 used as premise
|
|
39
|
+
*/
|
|
40
|
+
premises: string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A belief adoption adopts someone else's belief. This type is used
|
|
44
|
+
* to indicate e.g. knowledge through private communication or
|
|
45
|
+
* from secondary literature.
|
|
46
|
+
* @see crminf:I7 Belief Adoption
|
|
47
|
+
*/
|
|
48
|
+
export interface BeliefAdoption extends Argumentation<'beliefAdoption'> {
|
|
49
|
+
/**
|
|
50
|
+
* A note describing the source of the adopted belief,
|
|
51
|
+
* e.g. a bibliographic reference or personal communication.
|
|
52
|
+
* @see crm:P3 has note
|
|
53
|
+
*/
|
|
54
|
+
note: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* An argumentation can be either a plain argumentation, a
|
|
58
|
+
* meaning comprehension, an inference, or a belief adoption.
|
|
59
|
+
*/
|
|
60
|
+
export type AnyArgumentation = MeaningComprehension | Inference | BeliefAdoption | Argumentation;
|
|
61
|
+
/**
|
|
62
|
+
* A belief is a temporal object and associates a proposition (i.e.
|
|
63
|
+
* a statement) with a certainty. It comes into existence through
|
|
64
|
+
* argumentations (reasons).
|
|
65
|
+
* @see crminf:I2 Belief
|
|
66
|
+
*/
|
|
67
|
+
export interface Belief extends WithId {
|
|
68
|
+
type: 'belief';
|
|
69
|
+
/**
|
|
70
|
+
* The level of certainty associated with this belief.
|
|
71
|
+
* @see crminf:J5 holds to be
|
|
72
|
+
*/
|
|
73
|
+
certainty: Certainty;
|
|
74
|
+
/**
|
|
75
|
+
* The argumentations providing reasons for this belief.
|
|
76
|
+
* @see crminf:J2 was concluded by
|
|
77
|
+
*/
|
|
78
|
+
reasons: AnyArgumentation[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* An assumption is the reification of a triple. This leverages the
|
|
82
|
+
* `@annotation` element from JSON-LD-star. Any property in the edition
|
|
83
|
+
* can be annotated with a belief to express uncertainty or provide
|
|
84
|
+
* justification for the stated value.
|
|
85
|
+
*/
|
|
86
|
+
export interface Assumption {
|
|
87
|
+
/**
|
|
88
|
+
* An optional annotation expressing a belief about this assumption.
|
|
89
|
+
* Uses the JSON-LD-star `@annotation` mechanism to attach
|
|
90
|
+
* epistemic metadata (certainty and reasons) to any triple.
|
|
91
|
+
*/
|
|
92
|
+
'@annotation'?: WithId & {
|
|
93
|
+
belief: Belief;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A value assumption wraps a literal value, e.g. a string, a number, a date, with an optional annotation.
|
|
98
|
+
* Used for properties where the value itself may be uncertain,
|
|
99
|
+
* e.g. dates or alignment references.
|
|
100
|
+
*/
|
|
101
|
+
export interface ValueAssumption<ValueT> extends Assumption {
|
|
102
|
+
/**
|
|
103
|
+
* The assumed value.
|
|
104
|
+
*/
|
|
105
|
+
'@value': ValueT;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* A reference assumption wraps a reference (by `@id`) with an optional annotation.
|
|
109
|
+
* Used when pointing to another entity whose association may be uncertain.
|
|
110
|
+
*/
|
|
111
|
+
export type ReferenceAssumption = Assumption & WithId;
|
|
112
|
+
/**
|
|
113
|
+
* An object assumption wraps a complex object with an optional annotation.
|
|
114
|
+
* Used for structured values (e.g. persons, conditions) whose properties
|
|
115
|
+
* may be uncertain.
|
|
116
|
+
*/
|
|
117
|
+
export type ObjectAssumption<O extends object> = Assumption & O;
|
|
118
|
+
export declare function valueOf<ValueT>(assumption: ValueAssumption<ValueT>): ValueT;
|
|
119
|
+
export declare function valuesOf<ValueT>(assumptions: ValueAssumption<ValueT>[]): ValueT[];
|
|
120
|
+
export declare function idOf(assumption: ReferenceAssumption): string;
|
|
121
|
+
export declare function idsOf(assumptions: ReferenceAssumption[]): string[];
|
|
122
|
+
export declare function assignValue<ValueT>(value: ValueT): ValueAssumption<ValueT>;
|
|
123
|
+
export declare function assignReference(id: string): ReferenceAssumption;
|
|
124
|
+
export declare function assignObject<O extends object>(obj: O): ObjectAssumption<O>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const certainties = [
|
|
2
|
+
'true',
|
|
3
|
+
'likely',
|
|
4
|
+
'possible',
|
|
5
|
+
'unlikely',
|
|
6
|
+
'false'
|
|
7
|
+
];
|
|
8
|
+
export function valueOf(assumption) {
|
|
9
|
+
return assumption['@value'];
|
|
10
|
+
}
|
|
11
|
+
export function valuesOf(assumptions) {
|
|
12
|
+
return assumptions.map(a => a['@value']);
|
|
13
|
+
}
|
|
14
|
+
export function idOf(assumption) {
|
|
15
|
+
return assumption.id;
|
|
16
|
+
}
|
|
17
|
+
export function idsOf(assumptions) {
|
|
18
|
+
return assumptions.map(a => a.id);
|
|
19
|
+
}
|
|
20
|
+
export function assignValue(value) {
|
|
21
|
+
return {
|
|
22
|
+
'@value': value
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function assignReference(id) {
|
|
26
|
+
return {
|
|
27
|
+
id
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function assignObject(obj) {
|
|
31
|
+
return {
|
|
32
|
+
...obj
|
|
33
|
+
};
|
|
34
|
+
}
|
package/lib/Collation.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tolerance used in collation of roll copies.
|
|
3
|
+
* The start and end tolerances define the acceptable
|
|
4
|
+
* deviation (in mm) when aligning features across copies.
|
|
5
|
+
*/
|
|
1
6
|
export interface CollationTolerance {
|
|
7
|
+
/**
|
|
8
|
+
* Tolerance at the start position of a feature (in mm).
|
|
9
|
+
*/
|
|
2
10
|
toleranceStart: number;
|
|
11
|
+
/**
|
|
12
|
+
* Tolerance at the end position of a feature (in mm).
|
|
13
|
+
*/
|
|
3
14
|
toleranceEnd: number;
|
|
4
15
|
}
|
package/lib/ConditionState.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { WithType } from "./utils";
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
+
* Physical condition of a roll or
|
|
3
4
|
* of a feature on the roll (e.g. a damaged
|
|
4
5
|
* or unsuccessful perforation).
|
|
5
6
|
*/
|
|
6
|
-
export interface ConditionState<T extends string> {
|
|
7
|
-
|
|
7
|
+
export interface ConditionState<T extends string> extends WithType<T> {
|
|
8
|
+
/**
|
|
9
|
+
* A free-text description of the condition, providing
|
|
10
|
+
* details beyond the type classification.
|
|
11
|
+
* @see crm:P3 has note
|
|
12
|
+
*/
|
|
8
13
|
description?: string;
|
|
9
14
|
}
|
package/lib/ConditionState.js
CHANGED
package/lib/Edit.d.ts
CHANGED
|
@@ -1,21 +1,51 @@
|
|
|
1
|
+
import { Assumption, ObjectAssumption } from "./Assumption";
|
|
1
2
|
import { Person } from "./Edition";
|
|
2
|
-
import { EditorialAssumption, Motivation } from "./EditorialAssumption";
|
|
3
3
|
import { AnySymbol } from "./Symbol";
|
|
4
|
-
import { WithId } from "./
|
|
5
|
-
export declare const
|
|
6
|
-
export type EditMotivation = typeof editMotivations[number];
|
|
7
|
-
export type ActorAssignment = EditorialAssumption<'actorAssignment', Person>;
|
|
4
|
+
import { WithId } from "./utils";
|
|
5
|
+
export declare const editTypes: readonly ["short-dynamic-differentation", "additional-accent", "add-redundancy", "remove-redundancy", "replace-with-equivalent", "shift", "correct-error", "shorten", "prolong"];
|
|
8
6
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* The type of editorial change applied to a symbol or set of symbols.
|
|
8
|
+
* Classifies the nature of the edit, e.g. whether it corrects an error,
|
|
9
|
+
* adds an accent, shifts a note, or shortens/prolongs a perforation.
|
|
11
10
|
*/
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export type EditType = typeof editTypes[number];
|
|
12
|
+
/**
|
|
13
|
+
* An actor assignment associates a person with an action.
|
|
14
|
+
* It is an object assumption so that the attribution can be
|
|
15
|
+
* annotated with a belief about its certainty.
|
|
16
|
+
*/
|
|
17
|
+
export type ActorAssignment = ObjectAssumption<Person>;
|
|
18
|
+
/**
|
|
19
|
+
* A set of edits transforms a version of a roll into another version.
|
|
20
|
+
* Edits insert or delete symbols, or both (= replace).
|
|
21
|
+
* Edits may be motivated by a given set of reasons, e.g.
|
|
22
|
+
* to add an additional accent or to correct an error.
|
|
23
|
+
* If an edit is the interpretation of a metamark,
|
|
24
|
+
* such as a pencil mark, this should be made explicit
|
|
25
|
+
* using a meaning comprehension on the `@annotation` field.
|
|
26
|
+
* @see reo:C8 Edit
|
|
27
|
+
*/
|
|
28
|
+
export interface Edit extends WithId, Assumption {
|
|
29
|
+
type: 'edit';
|
|
30
|
+
/**
|
|
31
|
+
* The type of editorial change (e.g. 'correct-error', 'additional-accent').
|
|
32
|
+
*/
|
|
33
|
+
editType?: EditType;
|
|
34
|
+
/**
|
|
35
|
+
* A textual description of the motivation for this edit,
|
|
36
|
+
* referencing a motivation defined in the version's motivations list.
|
|
37
|
+
* @see crm:P17 was motivated by
|
|
38
|
+
*/
|
|
39
|
+
motivation?: string;
|
|
40
|
+
/**
|
|
41
|
+
* The symbols to be inserted by this edit.
|
|
42
|
+
* @see reo:P7 added
|
|
43
|
+
*/
|
|
15
44
|
insert?: AnySymbol[];
|
|
16
|
-
|
|
17
|
-
|
|
45
|
+
/**
|
|
46
|
+
* References (by `@id`) to the symbols to be deleted by this edit.
|
|
47
|
+
* @see reo:P8 removed
|
|
48
|
+
*/
|
|
49
|
+
delete?: string[];
|
|
18
50
|
}
|
|
19
51
|
export declare const isEdit: (object: any) => object is Edit;
|
|
20
|
-
export declare const merge: (selection: Edit[]) => Edit;
|
|
21
|
-
export declare const split: (edit: Edit) => Edit[];
|
package/lib/Edit.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { assign } from "./EditorialAssumption";
|
|
3
|
-
import { dimensionOf } from "./Symbol";
|
|
4
|
-
export const editMotivations = [
|
|
1
|
+
export const editTypes = [
|
|
5
2
|
/**
|
|
6
3
|
* An additional accent that can only be encoded with
|
|
7
4
|
* sforzando on/off due to the short space left between
|
|
@@ -18,95 +15,5 @@ export const editMotivations = [
|
|
|
18
15
|
'prolong',
|
|
19
16
|
];
|
|
20
17
|
export const isEdit = (object) => {
|
|
21
|
-
return '
|
|
22
|
-
};
|
|
23
|
-
const arraysIdentical = (a, b) => {
|
|
24
|
-
let i = a.length;
|
|
25
|
-
if (i != b.length)
|
|
26
|
-
return false;
|
|
27
|
-
while (i--) {
|
|
28
|
-
if (Array.isArray(a[i]) && Array.isArray(b[i])) {
|
|
29
|
-
return arraysIdentical(a[i], b[i]);
|
|
30
|
-
}
|
|
31
|
-
if (a[i] !== b[i])
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return true;
|
|
35
|
-
};
|
|
36
|
-
const guessMotivation = (edit) => {
|
|
37
|
-
const inserts = (edit.insert || []);
|
|
38
|
-
const deletes = (edit.delete || []);
|
|
39
|
-
const types = [
|
|
40
|
-
inserts.filter(e => e.type === 'expression').map(e => e.expressionType),
|
|
41
|
-
deletes.filter(e => e.type === 'expression').map(e => e.expressionType)
|
|
42
|
-
];
|
|
43
|
-
if (arraysIdentical(types, [['SlowCrescendoOn', 'SlowCrescendoOff'], []])) {
|
|
44
|
-
return 'additional-accent';
|
|
45
|
-
}
|
|
46
|
-
else if (arraysIdentical(types, [['ForzandoOn', 'ForzandoOff'], []])) {
|
|
47
|
-
// TODO: check if the inserts are very close
|
|
48
|
-
// and return 'short-dynamic-differentation'
|
|
49
|
-
return 'additional-accent';
|
|
50
|
-
}
|
|
51
|
-
else if (types.every(t => t.length > 1) && arraysIdentical(types[0], types[1])) {
|
|
52
|
-
return 'shift';
|
|
53
|
-
}
|
|
54
|
-
else if (types[0].length === 0 && types[1].length === 1) {
|
|
55
|
-
return 'remove-redundancy';
|
|
56
|
-
}
|
|
57
|
-
if (inserts.length === 1 && deletes.length === 1) {
|
|
58
|
-
const insertDim = dimensionOf(inserts[0]).horizontal;
|
|
59
|
-
const deleteDim = dimensionOf(deletes[0]).horizontal;
|
|
60
|
-
if (Math.abs(insertDim.from - deleteDim.from) < 5) {
|
|
61
|
-
const insertLength = Math.abs(insertDim.to - insertDim.from);
|
|
62
|
-
const deleteLength = Math.abs(deleteDim.to - deleteDim.from);
|
|
63
|
-
if (insertLength < deleteLength) {
|
|
64
|
-
return 'shorten';
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
return 'prolong';
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return 'correct-error';
|
|
72
|
-
};
|
|
73
|
-
export const merge = (selection) => {
|
|
74
|
-
const result = selection[0];
|
|
75
|
-
selection
|
|
76
|
-
.slice(1)
|
|
77
|
-
.forEach(edit => {
|
|
78
|
-
if (result.insert) {
|
|
79
|
-
result.insert.push(...(edit.insert || []));
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
result.insert = edit.insert;
|
|
83
|
-
}
|
|
84
|
-
if (result.delete) {
|
|
85
|
-
result.delete.push(...(edit.delete || []));
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
result.delete = edit.delete;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
return {
|
|
92
|
-
...result,
|
|
93
|
-
id: v4(),
|
|
94
|
-
motivation: assign('motivationAssignment', guessMotivation(result)),
|
|
95
|
-
};
|
|
96
|
-
};
|
|
97
|
-
export const split = (edit) => {
|
|
98
|
-
const result = [];
|
|
99
|
-
for (const insert of edit.insert ?? []) {
|
|
100
|
-
result.push({
|
|
101
|
-
id: v4(),
|
|
102
|
-
insert: [insert]
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
for (const remove of edit.delete ?? []) {
|
|
106
|
-
result.push({
|
|
107
|
-
id: v4(),
|
|
108
|
-
delete: [remove]
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
return result;
|
|
18
|
+
return 'type' in object && object.type === 'edit';
|
|
112
19
|
};
|
package/lib/Edition.d.ts
CHANGED
|
@@ -1,54 +1,194 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { WithId } from "./WithId";
|
|
1
|
+
import { WithId } from "./utils";
|
|
3
2
|
import { DateAssignment, RollCopy } from "./RollCopy";
|
|
4
3
|
import { Version } from "./Version";
|
|
5
4
|
import { CollationTolerance } from "./Collation";
|
|
5
|
+
import { ObjectAssumption } from "./Assumption";
|
|
6
|
+
/**
|
|
7
|
+
* A person, e.g. a pianist, editor, publisher, etc.
|
|
8
|
+
* @see crm:E21 Person
|
|
9
|
+
*/
|
|
6
10
|
export interface Person extends Partial<WithId> {
|
|
11
|
+
/**
|
|
12
|
+
* The full name of the person.
|
|
13
|
+
* @see rdfs:label
|
|
14
|
+
* @example "Grünfeld, Alfred"
|
|
15
|
+
*/
|
|
7
16
|
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* This property can be used to point to a
|
|
19
|
+
* GND, Wikidata, or similar entry.
|
|
20
|
+
* @see owl:sameAs
|
|
21
|
+
* @example "https://d-nb.info/gnd/116888652"
|
|
22
|
+
*/
|
|
8
23
|
sameAs: string[];
|
|
24
|
+
/**
|
|
25
|
+
* The role of the person in the context of the edition,
|
|
26
|
+
* e.g. 'pianist', 'editor', 'publisher', etc.
|
|
27
|
+
* @see crm:P2 has type
|
|
28
|
+
*/
|
|
9
29
|
role?: string;
|
|
10
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* A place, e.g. a recording location, publishing location, etc.
|
|
33
|
+
* @see crm:E53 Place
|
|
34
|
+
*/
|
|
11
35
|
export interface Place {
|
|
36
|
+
/**
|
|
37
|
+
* The name of the place.
|
|
38
|
+
* @example "Wien"
|
|
39
|
+
*/
|
|
12
40
|
name: string;
|
|
41
|
+
/**
|
|
42
|
+
* This property can be used to point to a
|
|
43
|
+
* geonames or wikidata entry.
|
|
44
|
+
*/
|
|
13
45
|
sameAs: string[];
|
|
14
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* This type describes the creation of an edition,
|
|
49
|
+
* i.e. the editor, publisher, and publication date.
|
|
50
|
+
* @see lrm:F28 Expression Creation
|
|
51
|
+
*/
|
|
15
52
|
export interface EditionCreation {
|
|
53
|
+
/**
|
|
54
|
+
* The person or institution responsible for publishing the edition.
|
|
55
|
+
* @see crm:P14 carried out by
|
|
56
|
+
*/
|
|
16
57
|
publisher: Person;
|
|
58
|
+
/**
|
|
59
|
+
* The date on which the edition was published.
|
|
60
|
+
* @format date
|
|
61
|
+
* @see crm:P4 has time-span
|
|
62
|
+
*/
|
|
17
63
|
publicationDate: Date;
|
|
64
|
+
/**
|
|
65
|
+
* The tolerance parameters used when collating (aligning)
|
|
66
|
+
* the different roll copies for this edition.
|
|
67
|
+
* @see L13 used parameters
|
|
68
|
+
*/
|
|
18
69
|
collationTolerance?: CollationTolerance;
|
|
19
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Describes the event of recording and documents
|
|
73
|
+
* the persons involved in the process (e.g. pianist),
|
|
74
|
+
* the place, and the date of the recording.
|
|
75
|
+
* @see reo:C14 Recording
|
|
76
|
+
*/
|
|
20
77
|
export interface RecordingEvent {
|
|
78
|
+
/**
|
|
79
|
+
* Documents the performance which was recorded.
|
|
80
|
+
* @see lrm:R81 recorded
|
|
81
|
+
*/
|
|
21
82
|
recorded: {
|
|
22
83
|
pianist: Person;
|
|
84
|
+
/**
|
|
85
|
+
* This property should point to a standard
|
|
86
|
+
* URI, e.g. the GND.
|
|
87
|
+
*/
|
|
23
88
|
playing: string;
|
|
24
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* The place where the recording took place.
|
|
92
|
+
* @see crm:P7 took place at
|
|
93
|
+
*/
|
|
25
94
|
place: Place;
|
|
26
95
|
/**
|
|
27
96
|
* The recording date of the roll. This is a date
|
|
28
97
|
* assignment so that we can state e.g. the catalogue
|
|
29
98
|
* or the roll label which indicates the date of the recording.
|
|
99
|
+
* @see crm:P4 has time-span
|
|
30
100
|
*/
|
|
31
101
|
date: DateAssignment;
|
|
102
|
+
/**
|
|
103
|
+
* The version of the roll which was created in
|
|
104
|
+
* the recording. Since it is usually not handed
|
|
105
|
+
* down, this is an optional property.
|
|
106
|
+
* @see lrm:R17 created
|
|
107
|
+
*/
|
|
32
108
|
created?: Version;
|
|
33
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* The abstract concept of a roll, identified
|
|
112
|
+
* by its catalogue number.
|
|
113
|
+
* @see lrm:F1 Work
|
|
114
|
+
*/
|
|
34
115
|
export interface Roll {
|
|
116
|
+
/**
|
|
117
|
+
* The catalogue number of the roll.
|
|
118
|
+
* @example "WM 225"
|
|
119
|
+
*/
|
|
35
120
|
catalogueNumber: string;
|
|
121
|
+
/**
|
|
122
|
+
* @see lrm:R19i was realized through
|
|
123
|
+
*/
|
|
36
124
|
recordingEvent: RecordingEvent;
|
|
37
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* The playback tempo of the roll, specified as a starting
|
|
128
|
+
* and ending speed. The tempo may change over the course
|
|
129
|
+
* of the roll due to acceleration effects.
|
|
130
|
+
*/
|
|
38
131
|
export interface RollTempo {
|
|
132
|
+
/**
|
|
133
|
+
* The tempo at the beginning of the roll.
|
|
134
|
+
*/
|
|
39
135
|
startsWith: number;
|
|
136
|
+
/**
|
|
137
|
+
* The tempo at the end of the roll.
|
|
138
|
+
*/
|
|
40
139
|
endsWith: number;
|
|
140
|
+
/**
|
|
141
|
+
* The unit of the tempo measurement (e.g. 'ft/min', 'm/min').
|
|
142
|
+
*/
|
|
41
143
|
unit: string;
|
|
42
144
|
}
|
|
43
|
-
|
|
145
|
+
/**
|
|
146
|
+
* Describes the specific digital edition of a piano roll.
|
|
147
|
+
* @see lrm:F2 Expression
|
|
148
|
+
*/
|
|
44
149
|
export interface Edition {
|
|
150
|
+
/**
|
|
151
|
+
* The base URI for all entities in this edition.
|
|
152
|
+
* @example "https://edition.encoded-ghosts.org/wm225"
|
|
153
|
+
*/
|
|
45
154
|
base: string;
|
|
155
|
+
/**
|
|
156
|
+
* Information about the creation of this edition,
|
|
157
|
+
* including publisher and publication date.
|
|
158
|
+
* @see lrm:R17i was created by
|
|
159
|
+
*/
|
|
46
160
|
creation: EditionCreation;
|
|
161
|
+
/**
|
|
162
|
+
* The title of the edition.
|
|
163
|
+
* @see crm:P102 has title
|
|
164
|
+
* @example "Alfred Grünfeld spielt Robert Schumann, Träumerei"
|
|
165
|
+
*/
|
|
47
166
|
title: string;
|
|
167
|
+
/**
|
|
168
|
+
* The license under which the edition is published.
|
|
169
|
+
* @see dcterms:license
|
|
170
|
+
* @example "https://creativecommons.org/licenses/by/4.0/"
|
|
171
|
+
*/
|
|
48
172
|
license: string;
|
|
173
|
+
/**
|
|
174
|
+
* The roll which is edited in this edition.
|
|
175
|
+
* @see lrm:R3i realises
|
|
176
|
+
*/
|
|
49
177
|
roll: Roll;
|
|
178
|
+
/**
|
|
179
|
+
* The physical roll copies on which this edition is based.
|
|
180
|
+
*/
|
|
50
181
|
copies: RollCopy[];
|
|
182
|
+
/**
|
|
183
|
+
* The different versions of the roll on which
|
|
184
|
+
* this edition is based.
|
|
185
|
+
* @see lrm:R76 is derivative of
|
|
186
|
+
*/
|
|
51
187
|
versions: Version[];
|
|
52
|
-
|
|
188
|
+
/**
|
|
189
|
+
* An optional tempo adjustment for playback of the roll,
|
|
190
|
+
* annotatable with a belief about its correctness.
|
|
191
|
+
*/
|
|
192
|
+
tempoAdjustment?: ObjectAssumption<RollTempo>;
|
|
53
193
|
}
|
|
54
194
|
export type EditionMetadata = Pick<Edition, 'base' | 'title' | 'license' | 'creation' | 'roll'>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CollationTolerance } from "./Collation";
|
|
2
|
+
import { Edition } from "./Edition";
|
|
3
|
+
import { HorizontalSpan, VerticalSpan, AnyFeature } from "./Feature";
|
|
4
|
+
import { AnySymbol, Expression, Note } from "./Symbol";
|
|
5
|
+
import { Version } from "./Version";
|
|
6
|
+
import { NegotiatedEvent } from "./ReproducingSystem";
|
|
7
|
+
export type Path = (string | number)[];
|
|
8
|
+
export declare const getAt: <T>(path: Path, obj: unknown) => T | undefined;
|
|
9
|
+
export declare class EditionView {
|
|
10
|
+
readonly edition: Edition;
|
|
11
|
+
/**
|
|
12
|
+
* Map from id to object
|
|
13
|
+
*/
|
|
14
|
+
private readonly byId;
|
|
15
|
+
/**
|
|
16
|
+
* Map from id to its path within the edition
|
|
17
|
+
*/
|
|
18
|
+
private readonly paths;
|
|
19
|
+
/**
|
|
20
|
+
* Map from id to paths where it is referenced
|
|
21
|
+
*/
|
|
22
|
+
private readonly links;
|
|
23
|
+
/**
|
|
24
|
+
* Dimensions cache: one frequent operation is to find the average
|
|
25
|
+
* dimensions of a symbol based on its carriers. This cache stores
|
|
26
|
+
* the computed dimensions for reuse.
|
|
27
|
+
*/
|
|
28
|
+
constructor(edition: Edition);
|
|
29
|
+
atPath<T>(path: Path): T | null;
|
|
30
|
+
indexObjects(): void;
|
|
31
|
+
get<T>(anyId: string): T | undefined;
|
|
32
|
+
getAll<T>(anyIds: readonly string[]): T[];
|
|
33
|
+
getPath(anyId: string): Path | undefined;
|
|
34
|
+
linksTo(anyId: string): Path[];
|
|
35
|
+
travelUp(versionId: string, callback: (version: Readonly<Version>) => void): void;
|
|
36
|
+
carriersOf(symbol: AnySymbol): Readonly<AnyFeature>[];
|
|
37
|
+
predecessorOf(versionId: string): Readonly<Version> | undefined;
|
|
38
|
+
dimensionOf(symbol: AnySymbol): Readonly<{
|
|
39
|
+
horizontal: HorizontalSpan;
|
|
40
|
+
vertical: VerticalSpan;
|
|
41
|
+
}> | undefined;
|
|
42
|
+
snapshot(versionId: string): readonly Readonly<AnySymbol>[];
|
|
43
|
+
isCollatable(symbolA: AnySymbol, symbolB: AnySymbol, tolerance?: CollationTolerance): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Assigns a generation (depth) to every node.
|
|
46
|
+
*/
|
|
47
|
+
withGenerations(): Array<Version & {
|
|
48
|
+
generation: number;
|
|
49
|
+
}>;
|
|
50
|
+
simplifySymbol(symbol: Note | Expression): NegotiatedEvent | null;
|
|
51
|
+
}
|