linked-rolls 0.75.0 → 0.76.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 +53 -47
- package/lib/collation/Collation.d.ts +12 -46
- package/lib/collation/Collation.js +15 -53
- package/lib/filiation/adoption.d.ts +22 -26
- package/lib/filiation/adoption.js +71 -73
- package/lib/filiation/edits.d.ts +36 -31
- package/lib/filiation/edits.js +70 -85
- package/lib/filiation/index.d.ts +2 -2
- package/lib/filiation/index.js +1 -1
- package/lib/filiation/record.d.ts +14 -44
- package/lib/filiation/record.js +12 -83
- package/lib/io/asJsonLd.d.ts +1 -5
- package/lib/io/asJsonLd.js +17 -36
- package/lib/io/importJsonLd.js +33 -6
- package/lib/io/migrate.d.ts +7 -0
- package/lib/io/migrate.js +167 -2
- package/lib/model/Agent.d.ts +3 -1
- package/lib/model/Assumption.d.ts +9 -85
- package/lib/model/Assumption.js +3 -39
- package/lib/model/Edit.d.ts +75 -20
- package/lib/model/Edit.js +52 -5
- package/lib/model/Edition.d.ts +31 -11
- package/lib/model/Version.d.ts +5 -41
- package/lib/model/Version.js +6 -30
- package/lib/ops/collation.d.ts +8 -4
- package/lib/ops/collation.js +40 -23
- package/lib/ops/copies.js +1 -2
- package/lib/ops/draft.d.ts +1 -9
- package/lib/ops/draft.js +0 -12
- package/lib/ops/edits.d.ts +20 -5
- package/lib/ops/edits.js +29 -21
- package/lib/ops/index.d.ts +1 -1
- package/lib/ops/index.js +1 -1
- package/lib/ops/versions.d.ts +3 -2
- package/lib/ops/versions.js +4 -5
- package/lib/schema.json +121 -140
- package/lib/software.d.ts +7 -6
- package/lib/software.js +7 -6
- package/lib/spec/context.json +8 -11
- package/package.json +1 -1
package/lib/model/Edit.d.ts
CHANGED
|
@@ -1,14 +1,66 @@
|
|
|
1
1
|
import { Assumption } from "./Assumption.js";
|
|
2
2
|
import { AnySymbol } from "./Symbol.js";
|
|
3
|
-
import { WithId } from "../shared/utils.js";
|
|
3
|
+
import { WithId, WithNote, WithType } from "../shared/utils.js";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* A reason for a musical change, in the editor's words. The edition
|
|
6
|
+
* states its motivations once (`Edition.motivations`), and an edit of
|
|
7
|
+
* any version names the one it was made for. Every change of a version
|
|
8
|
+
* that derives from another states a motivation: a program states
|
|
9
|
+
* whether it is musical or technical (`musicalChange`,
|
|
10
|
+
* `technicalChange`), and the editor puts a reason of their own in
|
|
11
|
+
* place of a musical one. Speculating about why a change was made is
|
|
12
|
+
* kept to the musical changes.
|
|
13
|
+
* @see crm:E33 Linguistic Object
|
|
14
|
+
* @category Format types
|
|
15
|
+
*/
|
|
16
|
+
export type Motivation = WithType<'motivation'> & WithId & WithNote;
|
|
17
|
+
/**
|
|
18
|
+
* The motivation of a musical change whose reason is not given yet: a
|
|
19
|
+
* change of the performance, such as an added accent or a perforation
|
|
20
|
+
* put elsewhere. A program states it for a change whose shape a musical
|
|
21
|
+
* decision makes, under the rule that later versions are the more
|
|
22
|
+
* refined; the editor puts a reason of their own in its place.
|
|
23
|
+
* @category Versions and stemma
|
|
24
|
+
*/
|
|
25
|
+
export declare const musicalChange = "https://w3id.org/reo/type/motivation/musical";
|
|
26
|
+
/**
|
|
27
|
+
* The motivation of a technical change: one that changes only how the
|
|
28
|
+
* performance is carried, a redundancy cleaned up or added, or a
|
|
29
|
+
* command recoded for another reproducing system. A program states it
|
|
30
|
+
* for a change of such a shape, and the procedure of the version's
|
|
31
|
+
* creation explains it, so that no reason of its own is given.
|
|
32
|
+
* @category Versions and stemma
|
|
33
|
+
*/
|
|
34
|
+
export declare const technicalChange = "https://w3id.org/reo/type/motivation/technical";
|
|
35
|
+
/**
|
|
36
|
+
* The kinds of change an edit can be: one that changes the
|
|
37
|
+
* performance, and one that changes only how it is carried.
|
|
9
38
|
* @category Vocabulary
|
|
10
39
|
*/
|
|
11
|
-
export declare const
|
|
40
|
+
export declare const changeKinds: readonly ['musical', 'technical'];
|
|
41
|
+
/**
|
|
42
|
+
* The kind of change an edit is (`kindOfChange`).
|
|
43
|
+
* @category Format types
|
|
44
|
+
*/
|
|
45
|
+
export type ChangeKind = typeof changeKinds[number];
|
|
46
|
+
/**
|
|
47
|
+
* What kind of change the edit is, as its motivation says: technical
|
|
48
|
+
* if it is `technicalChange`, musical if it is `musicalChange` or a
|
|
49
|
+
* reason of the editor's.
|
|
50
|
+
*
|
|
51
|
+
* An edit without a motivation is of no kind: the edits of a version
|
|
52
|
+
* that derives from none state its text rather than a change.
|
|
53
|
+
* @category Versions and stemma
|
|
54
|
+
*/
|
|
55
|
+
export declare const kindOfChange: (edit: Readonly<Pick<Edit, 'motivation'>>) => ChangeKind | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* The shapes a change can take, read off what it inserts and deletes
|
|
58
|
+
* and the systems of the two versions (`shapeOf`, `proposeEdits`). A
|
|
59
|
+
* shape is not stated: it is what a program reads to propose a
|
|
60
|
+
* motivation, and what a view can call a change.
|
|
61
|
+
* @category Vocabulary
|
|
62
|
+
*/
|
|
63
|
+
export declare const editShapes: readonly ['additional-accent', 'add-redundancy', 'remove-redundancy',
|
|
12
64
|
/**
|
|
13
65
|
* Carries the text into another reproducing system's coding: a
|
|
14
66
|
* latched pair of one system giving way to the other's held command,
|
|
@@ -17,18 +69,24 @@ export declare const editTypes: readonly ['additional-accent', 'add-redundancy',
|
|
|
17
69
|
*/
|
|
18
70
|
'recoding', 'shift', 'shorten', 'prolong'];
|
|
19
71
|
/**
|
|
20
|
-
* The
|
|
21
|
-
* Classifies the shape of the edit, e.g. whether it adds an accent,
|
|
22
|
-
* shifts a note, or shortens/prolongs a perforation. Why it was made is
|
|
23
|
-
* its motivation.
|
|
72
|
+
* The shape of a change (`editShapes`).
|
|
24
73
|
* @category Format types
|
|
25
74
|
*/
|
|
26
|
-
export type
|
|
75
|
+
export type EditShape = typeof editShapes[number];
|
|
76
|
+
/**
|
|
77
|
+
* The motivation a program states for a change of this shape. A
|
|
78
|
+
* recoding and a redundancy removed or added are technical changes
|
|
79
|
+
* (`technicalChange`). Every other change of a later version is taken
|
|
80
|
+
* for a refinement, and so for a musical change whose reason is not
|
|
81
|
+
* given yet (`musicalChange`).
|
|
82
|
+
* @category Versions and stemma
|
|
83
|
+
*/
|
|
84
|
+
export declare const motivationProposedFor: (shape: EditShape | undefined) => string;
|
|
27
85
|
/**
|
|
28
86
|
* A set of edits transforms a version of a roll into another version.
|
|
29
87
|
* Edits insert or delete symbols, or both (= replace).
|
|
30
|
-
*
|
|
31
|
-
*
|
|
88
|
+
* What kind of change an edit is follows from its motivation
|
|
89
|
+
* (`kindOfChange`).
|
|
32
90
|
* If an edit is the interpretation of a metamark,
|
|
33
91
|
* such as a pencil mark, this should be made explicit
|
|
34
92
|
* using a meaning comprehension on the `@annotation` field.
|
|
@@ -42,13 +100,10 @@ export type EditType = typeof editTypes[number];
|
|
|
42
100
|
export interface Edit extends WithId, Assumption {
|
|
43
101
|
type: 'edit';
|
|
44
102
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* A textual description of the motivation for this edit,
|
|
51
|
-
* referencing a motivation defined in the version's motivations list.
|
|
103
|
+
* Why the edit was made: one of the edition's motivations, by id,
|
|
104
|
+
* or one the vocabulary publishes, by IRI (`musicalChange`,
|
|
105
|
+
* `technicalChange`). An edit of a version that derives from none
|
|
106
|
+
* states none.
|
|
52
107
|
* @see crm:P17 was motivated by
|
|
53
108
|
*/
|
|
54
109
|
motivation?: string;
|
package/lib/model/Edit.js
CHANGED
|
@@ -1,11 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The motivation of a musical change whose reason is not given yet: a
|
|
3
|
+
* change of the performance, such as an added accent or a perforation
|
|
4
|
+
* put elsewhere. A program states it for a change whose shape a musical
|
|
5
|
+
* decision makes, under the rule that later versions are the more
|
|
6
|
+
* refined; the editor puts a reason of their own in its place.
|
|
7
|
+
* @category Versions and stemma
|
|
8
|
+
*/
|
|
9
|
+
export const musicalChange = 'https://w3id.org/reo/type/motivation/musical';
|
|
10
|
+
/**
|
|
11
|
+
* The motivation of a technical change: one that changes only how the
|
|
12
|
+
* performance is carried, a redundancy cleaned up or added, or a
|
|
13
|
+
* command recoded for another reproducing system. A program states it
|
|
14
|
+
* for a change of such a shape, and the procedure of the version's
|
|
15
|
+
* creation explains it, so that no reason of its own is given.
|
|
16
|
+
* @category Versions and stemma
|
|
17
|
+
*/
|
|
18
|
+
export const technicalChange = 'https://w3id.org/reo/type/motivation/technical';
|
|
19
|
+
/**
|
|
20
|
+
* The kinds of change an edit can be: one that changes the
|
|
21
|
+
* performance, and one that changes only how it is carried.
|
|
6
22
|
* @category Vocabulary
|
|
7
23
|
*/
|
|
8
|
-
export const
|
|
24
|
+
export const changeKinds = ['musical', 'technical'];
|
|
25
|
+
/**
|
|
26
|
+
* What kind of change the edit is, as its motivation says: technical
|
|
27
|
+
* if it is `technicalChange`, musical if it is `musicalChange` or a
|
|
28
|
+
* reason of the editor's.
|
|
29
|
+
*
|
|
30
|
+
* An edit without a motivation is of no kind: the edits of a version
|
|
31
|
+
* that derives from none state its text rather than a change.
|
|
32
|
+
* @category Versions and stemma
|
|
33
|
+
*/
|
|
34
|
+
export const kindOfChange = (edit) => edit.motivation === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: edit.motivation === technicalChange ? 'technical' : 'musical';
|
|
37
|
+
/**
|
|
38
|
+
* The shapes a change can take, read off what it inserts and deletes
|
|
39
|
+
* and the systems of the two versions (`shapeOf`, `proposeEdits`). A
|
|
40
|
+
* shape is not stated: it is what a program reads to propose a
|
|
41
|
+
* motivation, and what a view can call a change.
|
|
42
|
+
* @category Vocabulary
|
|
43
|
+
*/
|
|
44
|
+
export const editShapes = [
|
|
9
45
|
'additional-accent',
|
|
10
46
|
'add-redundancy',
|
|
11
47
|
'remove-redundancy',
|
|
@@ -20,6 +56,17 @@ export const editTypes = [
|
|
|
20
56
|
'shorten',
|
|
21
57
|
'prolong',
|
|
22
58
|
];
|
|
59
|
+
/**
|
|
60
|
+
* The motivation a program states for a change of this shape. A
|
|
61
|
+
* recoding and a redundancy removed or added are technical changes
|
|
62
|
+
* (`technicalChange`). Every other change of a later version is taken
|
|
63
|
+
* for a refinement, and so for a musical change whose reason is not
|
|
64
|
+
* given yet (`musicalChange`).
|
|
65
|
+
* @category Versions and stemma
|
|
66
|
+
*/
|
|
67
|
+
export const motivationProposedFor = (shape) => shape === 'recoding' || shape === 'remove-redundancy' || shape === 'add-redundancy'
|
|
68
|
+
? technicalChange
|
|
69
|
+
: musicalChange;
|
|
23
70
|
/**
|
|
24
71
|
* Whether the object is an edit.
|
|
25
72
|
* @category Lookups
|
package/lib/model/Edition.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { RollCopy } from "./RollCopy.js";
|
|
2
2
|
import { Version } from "./Version.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { Motivation } from "./Edit.js";
|
|
4
|
+
import { DateAssignment } from "./Assumption.js";
|
|
5
|
+
import { Editor, Person, Place, Software } from "./Agent.js";
|
|
5
6
|
/**
|
|
6
|
-
* This type describes the creation of an edition,
|
|
7
|
-
*
|
|
7
|
+
* This type describes the creation of an edition: the editors,
|
|
8
|
+
* publisher and publication date, the editorial principles the edition
|
|
9
|
+
* follows, and the programs it was made with.
|
|
8
10
|
* @see lrmoo:F28 Expression Creation
|
|
9
11
|
* @category Format types
|
|
10
12
|
*/
|
|
@@ -28,6 +30,25 @@ export interface EditionCreation {
|
|
|
28
30
|
* @see dcterms:date
|
|
29
31
|
*/
|
|
30
32
|
publicationDate: Date;
|
|
33
|
+
/**
|
|
34
|
+
* The editorial principles the edition follows, by IRI: the
|
|
35
|
+
* published rules its stemma and its edits rest on, whether the
|
|
36
|
+
* editor applied them or a program did, such as that the same
|
|
37
|
+
* addition at the same place is not made twice independently
|
|
38
|
+
* (`stemmaRules`, `editRules`). Adopting a proposal names those it
|
|
39
|
+
* follows. An edition that names none leaves it out.
|
|
40
|
+
* @see crm:P33 used specific technique
|
|
41
|
+
*/
|
|
42
|
+
principles?: string[];
|
|
43
|
+
/**
|
|
44
|
+
* The programs the edition was made with, each with its release:
|
|
45
|
+
* the release of this library that found its stemma and grouped its
|
|
46
|
+
* edits, which finds them again with the defaults it has. Adopting a
|
|
47
|
+
* proposal names it, and saving the edition does not, so that the
|
|
48
|
+
* release named is the one that found what the edition states.
|
|
49
|
+
* @see crm:P16 used specific object
|
|
50
|
+
*/
|
|
51
|
+
software?: Software[];
|
|
31
52
|
}
|
|
32
53
|
/**
|
|
33
54
|
* Describes the event of recording and documents
|
|
@@ -160,14 +181,13 @@ export interface Edition {
|
|
|
160
181
|
*/
|
|
161
182
|
versions: Version[];
|
|
162
183
|
/**
|
|
163
|
-
* The
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* @see crminf:I4 Proposition Set
|
|
184
|
+
* The editor's motivations, each a reason for musical changes in
|
|
185
|
+
* words, stated once and named by the edits of any version
|
|
186
|
+
* (`Edit.motivation`). The motivations the vocabulary publishes are
|
|
187
|
+
* named by IRI and not stated here (`musicalChange`,
|
|
188
|
+
* `technicalChange`).
|
|
169
189
|
*/
|
|
170
|
-
|
|
190
|
+
motivations?: Motivation[];
|
|
171
191
|
}
|
|
172
192
|
/**
|
|
173
193
|
* What an edition states about itself rather than about the copies and
|
package/lib/model/Version.d.ts
CHANGED
|
@@ -1,36 +1,9 @@
|
|
|
1
1
|
import { Edit } from "./Edit.js";
|
|
2
2
|
import { Concept } from "./Agent.js";
|
|
3
|
-
import { ActorAssignment, Belief, Certainty, DateAssignment, ObjectAssumption,
|
|
3
|
+
import { ActorAssignment, Belief, Certainty, DateAssignment, ObjectAssumption, ReferenceAssumption } from "./Assumption.js";
|
|
4
4
|
import { CollationTolerance } from "../collation/Collation.js";
|
|
5
5
|
import { AnySymbol } from "./Symbol.js";
|
|
6
|
-
import { WithId
|
|
7
|
-
/**
|
|
8
|
-
* A motivation provides a reason or rationale for an editorial change.
|
|
9
|
-
* Motivations are defined at the version level and referenced by edits.
|
|
10
|
-
* @see crm:E33 Linguistic Object
|
|
11
|
-
* @category Format types
|
|
12
|
-
*/
|
|
13
|
-
export type Motivation = WithType<'motivation'> & WithId & WithNote;
|
|
14
|
-
/**
|
|
15
|
-
* The motivation of an edit that puts right what the version it derives
|
|
16
|
-
* from got wrong: a perforation put in the wrong place, struck or left
|
|
17
|
-
* out. Whether a change corrects an error is not read off its shape, as
|
|
18
|
-
* its type is, but is a reason for it, and so the editor's to give.
|
|
19
|
-
* The edit types held it once, and a document written then is read with
|
|
20
|
-
* this motivation in place of that type.
|
|
21
|
-
* @category Versions and stemma
|
|
22
|
-
*/
|
|
23
|
-
export declare const correctedError = "corrected-error";
|
|
24
|
-
/**
|
|
25
|
-
* The version's statement of what the motivation of a corrected error
|
|
26
|
-
* means, to stand in its `motivations`.
|
|
27
|
-
* @category Versions and stemma
|
|
28
|
-
*/
|
|
29
|
-
export declare const correctedErrorMotivation: {
|
|
30
|
-
readonly type: 'motivation';
|
|
31
|
-
readonly id: "corrected-error";
|
|
32
|
-
readonly note: 'Puts right an error of the version it derives from.';
|
|
33
|
-
};
|
|
6
|
+
import { WithId } from "../shared/utils.js";
|
|
34
7
|
/**
|
|
35
8
|
* A derivation names the version another one was derived from, together
|
|
36
9
|
* with the tolerance the two were collated at. How precisely the copies
|
|
@@ -168,10 +141,6 @@ export interface Version extends WithId {
|
|
|
168
141
|
* @see reo:involvedEdit
|
|
169
142
|
*/
|
|
170
143
|
edits?: Edit[];
|
|
171
|
-
/**
|
|
172
|
-
* A collection of motivations used in this version's edits.
|
|
173
|
-
*/
|
|
174
|
-
motivations: Motivation[];
|
|
175
144
|
}
|
|
176
145
|
/**
|
|
177
146
|
* The edits the version states, none where it leaves its text unstated.
|
|
@@ -190,19 +159,14 @@ export declare const insertedBy: (version: Readonly<Version>) => AnySymbol[];
|
|
|
190
159
|
export declare const deletedBy: (version: Readonly<Version>) => string[];
|
|
191
160
|
/**
|
|
192
161
|
* The parents the version names, in the order of `basedOn`, each with the
|
|
193
|
-
* certainty its derivation is held with and the belief it rests on
|
|
194
|
-
*
|
|
195
|
-
* adopted stemma's do, is read with the belief of the set, and names it
|
|
196
|
-
* (`propositionSet`); without it, only a belief of its own is read.
|
|
162
|
+
* certainty its derivation is held with and the belief it rests on, where
|
|
163
|
+
* it carries one.
|
|
197
164
|
* @category Versions and stemma
|
|
198
165
|
*/
|
|
199
|
-
export declare const derivationsOf: (version: Readonly<Version
|
|
200
|
-
propositionSets?: readonly PropositionSet[];
|
|
201
|
-
}) => {
|
|
166
|
+
export declare const derivationsOf: (version: Readonly<Version>) => {
|
|
202
167
|
parent: string;
|
|
203
168
|
certainty: Certainty;
|
|
204
169
|
belief?: Belief;
|
|
205
|
-
propositionSet?: string;
|
|
206
170
|
}[];
|
|
207
171
|
/**
|
|
208
172
|
* The derivation the version's text is read against: the first of those
|
package/lib/model/Version.js
CHANGED
|
@@ -1,25 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { certainties, certaintyOf, idOf } from "./Assumption.js";
|
|
2
2
|
import { defaultCollationTolerance } from "../collation/Collation.js";
|
|
3
|
-
/**
|
|
4
|
-
* The motivation of an edit that puts right what the version it derives
|
|
5
|
-
* from got wrong: a perforation put in the wrong place, struck or left
|
|
6
|
-
* out. Whether a change corrects an error is not read off its shape, as
|
|
7
|
-
* its type is, but is a reason for it, and so the editor's to give.
|
|
8
|
-
* The edit types held it once, and a document written then is read with
|
|
9
|
-
* this motivation in place of that type.
|
|
10
|
-
* @category Versions and stemma
|
|
11
|
-
*/
|
|
12
|
-
export const correctedError = 'corrected-error';
|
|
13
|
-
/**
|
|
14
|
-
* The version's statement of what the motivation of a corrected error
|
|
15
|
-
* means, to stand in its `motivations`.
|
|
16
|
-
* @category Versions and stemma
|
|
17
|
-
*/
|
|
18
|
-
export const correctedErrorMotivation = {
|
|
19
|
-
type: 'motivation',
|
|
20
|
-
id: correctedError,
|
|
21
|
-
note: 'Puts right an error of the version it derives from.'
|
|
22
|
-
};
|
|
23
3
|
/**
|
|
24
4
|
* The tolerance the derivation was collated at, or the default where it states none.
|
|
25
5
|
* @category Collation and alignment
|
|
@@ -42,20 +22,16 @@ export const insertedBy = (version) => editsOf(version).flatMap(edit => edit.ins
|
|
|
42
22
|
export const deletedBy = (version) => editsOf(version).flatMap(edit => edit.delete ?? []);
|
|
43
23
|
/**
|
|
44
24
|
* The parents the version names, in the order of `basedOn`, each with the
|
|
45
|
-
* certainty its derivation is held with and the belief it rests on
|
|
46
|
-
*
|
|
47
|
-
* adopted stemma's do, is read with the belief of the set, and names it
|
|
48
|
-
* (`propositionSet`); without it, only a belief of its own is read.
|
|
25
|
+
* certainty its derivation is held with and the belief it rests on, where
|
|
26
|
+
* it carries one.
|
|
49
27
|
* @category Versions and stemma
|
|
50
28
|
*/
|
|
51
|
-
export const derivationsOf = (version
|
|
52
|
-
const belief =
|
|
53
|
-
const set = derivation['@annotation']?.belief === undefined ? derivation['@annotation']?.id : undefined;
|
|
29
|
+
export const derivationsOf = (version) => (version.basedOn ?? []).map(derivation => {
|
|
30
|
+
const belief = derivation['@annotation']?.belief;
|
|
54
31
|
return {
|
|
55
32
|
parent: idOf(derivation),
|
|
56
33
|
certainty: belief?.certainty ?? 'true',
|
|
57
|
-
...(belief && { belief })
|
|
58
|
-
...(set !== undefined && { propositionSet: set })
|
|
34
|
+
...(belief && { belief })
|
|
59
35
|
};
|
|
60
36
|
});
|
|
61
37
|
const rankOf = (derivation) => certainties.indexOf(certaintyOf(derivation));
|
package/lib/ops/collation.d.ts
CHANGED
|
@@ -9,15 +9,18 @@ import { EditionOp } from "./draft.js";
|
|
|
9
9
|
* tolerance it was collated at and becomes the principal one; the
|
|
10
10
|
* hypotheses the child stated beside its former one stay.
|
|
11
11
|
*
|
|
12
|
-
* The edits the child already stated are rewritten only as far as
|
|
13
|
-
*
|
|
12
|
+
* The edits the child already stated are rewritten only as far as they
|
|
13
|
+
* are the program's (`isCollationsOwn`). An editor's reading of the
|
|
14
14
|
* difference between the two texts stays, and the symbols it speaks for
|
|
15
15
|
* are left out of the collation, so that connecting the two again
|
|
16
16
|
* neither doubles them nor silently drops what somebody established by
|
|
17
17
|
* hand. An equivalence is the collation's own, since it is drawn from
|
|
18
18
|
* the two systems' vocabularies rather than read off the paper, but one
|
|
19
19
|
* drawn again over the very same symbols is kept as it stands, with its
|
|
20
|
-
* identifier and whatever was written on it.
|
|
20
|
+
* identifier and whatever was written on it. An insertion or deletion
|
|
21
|
+
* drawn anew has the motivation its shape calls for
|
|
22
|
+
* (`motivationProposedFor`): the generic musical one, or the technical
|
|
23
|
+
* one, which an equivalence drawn anew always has.
|
|
21
24
|
*
|
|
22
25
|
* The child's own text is what it shows less what the parent hands
|
|
23
26
|
* down, so that connecting two versions already connected collates the
|
|
@@ -40,7 +43,8 @@ export declare const collateSymbols: (versionId: string, symbolIds: readonly str
|
|
|
40
43
|
* Takes the named copies' reading of a symbol back out of the symbol it
|
|
41
44
|
* was collated into: their carriers pass to a new symbol of the
|
|
42
45
|
* version's own, the remaining copies keep the symbol they had, and the
|
|
43
|
-
* version states the exchange
|
|
46
|
+
* version states the exchange, with the motivation its shape calls for
|
|
47
|
+
* (`motivationProposedFor`) where the version derives from another.
|
|
44
48
|
*
|
|
45
49
|
* This is the inverse of the hand-over a collation makes, and it is
|
|
46
50
|
* what lets a derivation be collated a second time. A collated symbol
|
package/lib/ops/collation.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { v4 } from "uuid";
|
|
2
2
|
import { getAt, pathIn } from "../lookup/paths.js";
|
|
3
|
-
import { collationsOf, defaultCollationTolerance, isCollationsOwn
|
|
3
|
+
import { collationsOf, defaultCollationTolerance, isCollationsOwn } from "../collation/Collation.js";
|
|
4
|
+
import { motivationProposedFor, technicalChange } from "../model/Edit.js";
|
|
4
5
|
import { collationToleranceOf, derivesFrom, editsOf, insertedBy, principalDerivationOf } from "../model/Version.js";
|
|
5
6
|
import { substitutionsBetween } from "../collation/substitution.js";
|
|
6
7
|
import { trackerBarOf } from "../systems/index.js";
|
|
7
8
|
import { assignReference, idOf } from "../model/Assumption.js";
|
|
8
|
-
import { noChange, onVersion, insertion, deletion,
|
|
9
|
+
import { noChange, onVersion, insertion, deletion, dropInsertions, reading } from "./draft.js";
|
|
9
10
|
import { hypothesesBeside } from "./versions.js";
|
|
11
|
+
import { shapeOf } from "./edits.js";
|
|
12
|
+
import { predecessorOf } from "../analysis/stemma.js";
|
|
10
13
|
import { placeOf, snapshotOf } from "../analysis/text.js";
|
|
11
14
|
import { copyOfFeature, versionIn } from "../lookup/lookup.js";
|
|
15
|
+
import { motivationOfChanges, proposedMotivations } from "../filiation/edits.js";
|
|
12
16
|
/** The carriers of each collated symbol pass to its counterpart. */
|
|
13
17
|
const handOverCarriers = (edition, draft, collations) => collations.forEach(({ symbol, counterpart }) => {
|
|
14
18
|
const path = pathIn(edition, counterpart.id);
|
|
@@ -43,15 +47,18 @@ const byExchange = (edits) => new Map(edits.map(edit => [exchangeKey((edit.inser
|
|
|
43
47
|
* tolerance it was collated at and becomes the principal one; the
|
|
44
48
|
* hypotheses the child stated beside its former one stay.
|
|
45
49
|
*
|
|
46
|
-
* The edits the child already stated are rewritten only as far as
|
|
47
|
-
*
|
|
50
|
+
* The edits the child already stated are rewritten only as far as they
|
|
51
|
+
* are the program's (`isCollationsOwn`). An editor's reading of the
|
|
48
52
|
* difference between the two texts stays, and the symbols it speaks for
|
|
49
53
|
* are left out of the collation, so that connecting the two again
|
|
50
54
|
* neither doubles them nor silently drops what somebody established by
|
|
51
55
|
* hand. An equivalence is the collation's own, since it is drawn from
|
|
52
56
|
* the two systems' vocabularies rather than read off the paper, but one
|
|
53
57
|
* drawn again over the very same symbols is kept as it stands, with its
|
|
54
|
-
* identifier and whatever was written on it.
|
|
58
|
+
* identifier and whatever was written on it. An insertion or deletion
|
|
59
|
+
* drawn anew has the motivation its shape calls for
|
|
60
|
+
* (`motivationProposedFor`): the generic musical one, or the technical
|
|
61
|
+
* one, which an equivalence drawn anew always has.
|
|
55
62
|
*
|
|
56
63
|
* The child's own text is what it shows less what the parent hands
|
|
57
64
|
* down, so that connecting two versions already connected collates the
|
|
@@ -101,31 +108,36 @@ export const connectVersions = (childId, parentId, tolerance = defaultCollationT
|
|
|
101
108
|
return alreadyStated.get(exchangeKey(inserted, deleted)) ?? {
|
|
102
109
|
type: 'edit',
|
|
103
110
|
id: v4(),
|
|
104
|
-
|
|
105
|
-
motivation: unchecked,
|
|
111
|
+
motivation: technicalChange,
|
|
106
112
|
insert: [...by],
|
|
107
113
|
delete: deleted
|
|
108
114
|
};
|
|
109
115
|
};
|
|
110
|
-
const
|
|
111
|
-
...
|
|
112
|
-
...substituted.map(equivalence),
|
|
113
|
-
...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion).map(asUnchecked),
|
|
116
|
+
const bare = [
|
|
117
|
+
...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion),
|
|
114
118
|
...inherited
|
|
115
119
|
.filter(symbol => !matched.has(symbol.id) && !paired.has(symbol.id))
|
|
116
|
-
.map(symbol =>
|
|
120
|
+
.map(symbol => deletion(symbol.id))
|
|
117
121
|
];
|
|
122
|
+
const drawn = [...established, ...substituted.map(equivalence), ...bare];
|
|
118
123
|
// Read off the child as it stands, since once its edits are written a
|
|
119
124
|
// reading of it would copy them all.
|
|
120
|
-
const motivations = declaring(child?.motivations ?? [], edits);
|
|
121
125
|
const basedOn = [
|
|
122
126
|
{ ...assignReference(parentId), collationTolerance: tolerance },
|
|
123
127
|
...(child ? hypothesesBeside(child, parentId) : [])
|
|
124
128
|
];
|
|
129
|
+
// What kind of change an insertion or a deletion is depends on what it stands among.
|
|
130
|
+
const connected = { ...edition, versions: edition.versions.map(version => version.id === childId ? { ...version, edits: drawn, basedOn } : version) };
|
|
131
|
+
const motivations = proposedMotivations(connected, childId);
|
|
132
|
+
const anew = new Set(bare.map(edit => edit.id));
|
|
133
|
+
const edits = drawn.map(edit => {
|
|
134
|
+
if (!anew.has(edit.id))
|
|
135
|
+
return edit;
|
|
136
|
+
return { ...edit, motivation: motivationOfChanges(motivations, [...(edit.insert ?? []).map(symbol => symbol.id), ...(edit.delete ?? [])]) };
|
|
137
|
+
});
|
|
125
138
|
return onVersion(childId, (version, draft) => {
|
|
126
139
|
handOverCarriers(edition, draft, collations);
|
|
127
140
|
version.edits = edits;
|
|
128
|
-
version.motivations = motivations;
|
|
129
141
|
version.basedOn = basedOn;
|
|
130
142
|
});
|
|
131
143
|
});
|
|
@@ -184,7 +196,8 @@ const sharedWith = (edition, symbol, copies) => {
|
|
|
184
196
|
* Takes the named copies' reading of a symbol back out of the symbol it
|
|
185
197
|
* was collated into: their carriers pass to a new symbol of the
|
|
186
198
|
* version's own, the remaining copies keep the symbol they had, and the
|
|
187
|
-
* version states the exchange
|
|
199
|
+
* version states the exchange, with the motivation its shape calls for
|
|
200
|
+
* (`motivationProposedFor`) where the version derives from another.
|
|
188
201
|
*
|
|
189
202
|
* This is the inverse of the hand-over a collation makes, and it is
|
|
190
203
|
* what lets a derivation be collated a second time. A collated symbol
|
|
@@ -217,14 +230,18 @@ export const separateReadings = (versionId, copies, symbolIds) => reading(editio
|
|
|
217
230
|
return noChange;
|
|
218
231
|
const inserted = new Set(insertedBy(version).map(symbol => symbol.id));
|
|
219
232
|
const stated = editsOf(version);
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
233
|
+
const derived = predecessorOf(edition, versionId) !== undefined;
|
|
234
|
+
const separations = shared.map(({ symbol, mine }) => {
|
|
235
|
+
const separation = {
|
|
236
|
+
type: 'edit',
|
|
237
|
+
id: v4(),
|
|
238
|
+
insert: [readingOf(symbol, [...mine])],
|
|
239
|
+
// A symbol the version inserts itself stays where it is, minus
|
|
240
|
+
// the carriers that leave it. Only one it inherits is exchanged.
|
|
241
|
+
...(inserted.has(symbol.id) ? {} : { delete: [symbol.id] })
|
|
242
|
+
};
|
|
243
|
+
return derived ? { ...separation, motivation: motivationProposedFor(shapeOf(edition, versionId, separation)) } : separation;
|
|
244
|
+
});
|
|
228
245
|
return onVersion(versionId, (version, draft) => {
|
|
229
246
|
shared.forEach(({ symbol, theirs }) => {
|
|
230
247
|
const path = pathIn(edition, symbol.id);
|
package/lib/ops/copies.js
CHANGED
|
@@ -21,8 +21,7 @@ export const createVersion = (copy) => draft => {
|
|
|
21
21
|
draft.versions.push({
|
|
22
22
|
id: v4(),
|
|
23
23
|
system: systemOf(bar),
|
|
24
|
-
edits: asSymbols(featuresOf(copy), bar).map(insertion)
|
|
25
|
-
motivations: []
|
|
24
|
+
edits: asSymbols(featuresOf(copy), bar).map(insertion)
|
|
26
25
|
});
|
|
27
26
|
};
|
|
28
27
|
/**
|
package/lib/ops/draft.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Draft } from "immer";
|
|
|
3
3
|
import { Edition } from "../model/Edition.js";
|
|
4
4
|
import { AnySymbol } from "../model/Symbol.js";
|
|
5
5
|
import { Edit } from "../model/Edit.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Version } from "../model/Version.js";
|
|
7
7
|
import { RollCopy } from "../model/RollCopy.js";
|
|
8
8
|
import { Belief, ReferenceAssumption } from "../model/Assumption.js";
|
|
9
9
|
import { FeatureOrPatch } from "../model/Feature.js";
|
|
@@ -42,14 +42,6 @@ export declare const droppedIds: (before: readonly WithId[], after: readonly Wit
|
|
|
42
42
|
export type Ids = ReadonlySet<string>;
|
|
43
43
|
export declare const insertion: (symbol: AnySymbol) => Edit;
|
|
44
44
|
export declare const deletion: (symbolId: string) => Edit;
|
|
45
|
-
/** The edit as a collation leaves it: made by rule, and not yet read by anybody. */
|
|
46
|
-
export declare const asUnchecked: (edit: Edit) => Edit;
|
|
47
|
-
/**
|
|
48
|
-
* The motivations with the unchecked one declared, where any edit
|
|
49
|
-
* names it and the version does not state it yet. An edit naming a
|
|
50
|
-
* motivation the version leaves undeclared points at nothing.
|
|
51
|
-
*/
|
|
52
|
-
export declare const declaring: (motivations: Motivation[], edits: readonly Edit[]) => Motivation[];
|
|
53
45
|
export declare const insertedIn: (versions: readonly Version[]) => AnySymbol[];
|
|
54
46
|
/** The edits with the change applied, less those it emptied; the very same array where it changed none. */
|
|
55
47
|
export declare const edited: (edits: Edit[], change: (edit: Edit) => Edit) => Edit[];
|
package/lib/ops/draft.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** What the operations are built from: the type of an operation, how one finds what it writes to on the draft, and the edits it writes. */
|
|
2
2
|
import { isDraft } from "immer";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
|
-
import { unchecked, uncheckedMotivation } from "../collation/Collation.js";
|
|
5
4
|
import { insertedBy } from "../model/Version.js";
|
|
6
5
|
import { featuresOf } from "../model/RollCopy.js";
|
|
7
6
|
import { assignReference } from "../model/Assumption.js";
|
|
@@ -45,17 +44,6 @@ export const droppedIds = (before, after) => {
|
|
|
45
44
|
};
|
|
46
45
|
export const insertion = (symbol) => ({ type: 'edit', id: v4(), insert: [symbol] });
|
|
47
46
|
export const deletion = (symbolId) => ({ type: 'edit', id: v4(), delete: [symbolId] });
|
|
48
|
-
/** The edit as a collation leaves it: made by rule, and not yet read by anybody. */
|
|
49
|
-
export const asUnchecked = (edit) => ({ ...edit, motivation: unchecked });
|
|
50
|
-
/**
|
|
51
|
-
* The motivations with the unchecked one declared, where any edit
|
|
52
|
-
* names it and the version does not state it yet. An edit naming a
|
|
53
|
-
* motivation the version leaves undeclared points at nothing.
|
|
54
|
-
*/
|
|
55
|
-
export const declaring = (motivations, edits) => edits.some(edit => edit.motivation === unchecked)
|
|
56
|
-
&& !motivations.some(motivation => motivation.id === unchecked)
|
|
57
|
-
? [...motivations, uncheckedMotivation]
|
|
58
|
-
: motivations;
|
|
59
47
|
const isEmpty = (edit) => !edit.insert?.length && !edit.delete?.length;
|
|
60
48
|
export const insertedIn = (versions) => versions.flatMap(insertedBy);
|
|
61
49
|
/** The edits with the change applied, less those it emptied; the very same array where it changed none. */
|
package/lib/ops/edits.d.ts
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
|
-
import { Edit } from "../model/Edit.js";
|
|
1
|
+
import { Edit, EditShape } from "../model/Edit.js";
|
|
2
2
|
import { EditionOp } from "./draft.js";
|
|
3
|
+
import { Edition } from "../model/Edition.js";
|
|
4
|
+
/**
|
|
5
|
+
* A guess at the shape of an edit, from the symbols it exchanges and
|
|
6
|
+
* from the systems the version and the one it is based on are coded
|
|
7
|
+
* for, or nothing where it takes no shape the guess knows. It looks at
|
|
8
|
+
* the edit alone: a single expression deleted is taken for a redundancy
|
|
9
|
+
* removed, which `proposeEdits` checks against the text.
|
|
10
|
+
* @category Lookups
|
|
11
|
+
*/
|
|
12
|
+
export declare const shapeOf: (edition: Edition, versionId: string, edit: Readonly<Edit>) => EditShape | undefined;
|
|
3
13
|
/**
|
|
4
14
|
* Replaces the edits with a single one carrying all their insertions
|
|
5
|
-
* and deletions
|
|
6
|
-
*
|
|
7
|
-
*
|
|
15
|
+
* and deletions. It keeps the first motivation of the editor's that any
|
|
16
|
+
* of them states, and where none does, it has the one its shape calls
|
|
17
|
+
* for (`motivationProposedFor`), so that a merge says it is a musical
|
|
18
|
+
* or a technical change, unless the version derives from none. A
|
|
19
|
+
* grouping that says no more is the program's by rule
|
|
20
|
+
* (`isCollationsOwn`), until the editor says why it was made.
|
|
8
21
|
* @category Operations
|
|
9
22
|
*/
|
|
10
23
|
export declare const mergeEdits: (versionId: string, toMerge: readonly Edit[]) => EditionOp;
|
|
11
24
|
/**
|
|
12
|
-
* Replaces the edit with one edit per inserted and one per deleted
|
|
25
|
+
* Replaces the edit with one edit per inserted and one per deleted
|
|
26
|
+
* symbol. Each part keeps the motivation of the edit, since splitting
|
|
27
|
+
* an edit does not change why it was made.
|
|
13
28
|
* @category Operations
|
|
14
29
|
*/
|
|
15
30
|
export declare const splitEdit: (versionId: string, toSplit: Edit) => EditionOp;
|