linked-rolls 0.73.0 → 0.75.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 +71 -6
- package/lib/collation/Collation.d.ts +4 -0
- package/lib/collation/Collation.js +7 -2
- package/lib/filiation/adoption.d.ts +27 -4
- package/lib/filiation/adoption.js +73 -13
- package/lib/filiation/edits.d.ts +145 -0
- package/lib/filiation/edits.js +569 -0
- package/lib/filiation/index.d.ts +4 -2
- package/lib/filiation/index.js +4 -2
- package/lib/filiation/record.d.ts +79 -0
- package/lib/filiation/record.js +120 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/io/asJsonLd.d.ts +5 -1
- package/lib/io/asJsonLd.js +40 -17
- package/lib/io/importJsonLd.js +13 -2
- package/lib/io/migrate.js +30 -1
- package/lib/model/Assumption.d.ts +86 -3
- package/lib/model/Assumption.js +39 -2
- package/lib/model/Edit.d.ts +10 -6
- package/lib/model/Edit.js +4 -2
- package/lib/model/Edition.d.ts +10 -1
- package/lib/model/RollCopy.js +1 -1
- package/lib/model/Version.d.ts +29 -3
- package/lib/model/Version.js +34 -5
- package/lib/ops/edits.d.ts +3 -1
- package/lib/ops/edits.js +20 -7
- package/lib/schema.json +115 -100
- package/lib/software.d.ts +11 -0
- package/lib/software.js +9 -0
- package/lib/spec/context.json +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,11 +132,70 @@ edits the editor wrote, which hold their versions to what they insert
|
|
|
132
132
|
and delete. Motivations, beliefs and versions known only from a
|
|
133
133
|
recording remain the editor's to state.
|
|
134
134
|
|
|
135
|
+
What the program concluded is recorded as a program's conclusion. A
|
|
136
|
+
search scores whole stemmata, so the derivations and edits it states
|
|
137
|
+
are one proposition set (CRMinf I4) held under one belief. Each of
|
|
138
|
+
them names the set in its annotation, and the set states the belief
|
|
139
|
+
once. The belief, likely unless the editor says otherwise, rests on an
|
|
140
|
+
inference that names this library and its release, the copies it
|
|
141
|
+
collated, the published rules its costs carry out (`stemmaRules`) and,
|
|
142
|
+
in its note, the costs and settings it ran with and the margin of each
|
|
143
|
+
grouping. Who ran it and when are the editor's to give. A derivation or
|
|
144
|
+
an edit the editor holds for reasons of their own stays theirs, outside
|
|
145
|
+
the set.
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
const run = { actor: editor, date: { within: new Date() } }
|
|
149
|
+
const adopted = produce(edition, adoptStemma(proposal, run))
|
|
150
|
+
adopted.propositionSets // [{ type: 'propositionSet', id, belief: { certainty: 'likely', reasons: [{ type: 'inference', software: [linkedRolls], … }] } }]
|
|
151
|
+
```
|
|
152
|
+
|
|
135
153
|
The costs are those with which the stemma of WM 225 comes out of its
|
|
136
154
|
six copies. They were found by searching for such values, so they show
|
|
137
155
|
that the stemma is consistent with these principles, not that the
|
|
138
156
|
principles confirm it.
|
|
139
157
|
|
|
158
|
+
## Proposing the edits
|
|
159
|
+
|
|
160
|
+
What a version inserts and deletes can be grouped into edits and typed
|
|
161
|
+
by their shape alone. `proposeEdits` reads a version's changes line by
|
|
162
|
+
line, a latched function, a held one or a pitch, and never across a
|
|
163
|
+
command both texts keep, so that an edit stays at one place. A function
|
|
164
|
+
turned on and off again is one edit, typed an additional accent where
|
|
165
|
+
the bar spells an accent so; a perforation put elsewhere is one move
|
|
166
|
+
with the one it replaces, typed a shift, or shortened or prolonged
|
|
167
|
+
where it begins about where the other did; overlapping notes are one
|
|
168
|
+
edit, a note struck again or two tied; a held command standing for a
|
|
169
|
+
latched pair is one recoding; a command the text makes no use of is a
|
|
170
|
+
redundancy added or removed; cancels punched across lines at one place
|
|
171
|
+
are one row. `adoptEdits` puts the proposal in place of the edits a
|
|
172
|
+
collation or a program's run wrote and nobody has motivated, and keeps
|
|
173
|
+
the rest. The edits it proposes are a proposition set of their own. The
|
|
174
|
+
inference behind its belief names the beliefs the derivations of the
|
|
175
|
+
versions are held with as its premises, so that edits grouped against
|
|
176
|
+
a proposed stemma rest on it.
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { adoptEdits, adoptStemma, proposeEdits, proposeStemma } from 'linked-rolls'
|
|
180
|
+
|
|
181
|
+
proposeEdits(edition, versionId) // [{ insert, delete, editType, grouping }, …]
|
|
182
|
+
|
|
183
|
+
// The stemma and the edits of its versions, as one undo step
|
|
184
|
+
const adopted = produce(edition, draft => {
|
|
185
|
+
adoptStemma(proposeStemma(edition))(draft)
|
|
186
|
+
adoptEdits()(draft)
|
|
187
|
+
})
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Why an edit was made is not read off its shape, and neither is whether
|
|
191
|
+
a shift corrects an error: what is left to the editor is the
|
|
192
|
+
motivation. Correcting an error is therefore one of the motivations
|
|
193
|
+
(`correctedError`), not one of the edit types, and a document written
|
|
194
|
+
while it was a type is read with that motivation in its place. On
|
|
195
|
+
WM 225 the proposal reproduces 370 of the 414 edits the editor wrote,
|
|
196
|
+
from what each version changes, and every type the editor gave them.
|
|
197
|
+
From the copies alone, through the proposed stemma, it reproduces 326.
|
|
198
|
+
|
|
140
199
|
## Format
|
|
141
200
|
|
|
142
201
|
The export uses the Roll Edition Ontology (REO), namespace
|
|
@@ -147,7 +206,12 @@ https://pfefferniels.github.io/linked-rolls/, to which the w3id.org
|
|
|
147
206
|
identifiers redirect.
|
|
148
207
|
|
|
149
208
|
Beliefs are written as JSON-LD-star annotations (`@annotation`), so you
|
|
150
|
-
need a processor that supports JSON-LD-star to read them.
|
|
209
|
+
need a processor that supports JSON-LD-star to read them. A statement
|
|
210
|
+
that belongs to a proposition set carries no belief of its own: its
|
|
211
|
+
annotation names the set by its `@id`, which makes the set the reifier
|
|
212
|
+
of every statement that names it, as RDF 1.2 allows. The set is stated
|
|
213
|
+
once, under `propositionSets`, as a `crminf:I4_Proposition_Set` with its
|
|
214
|
+
belief.
|
|
151
215
|
|
|
152
216
|
## Development
|
|
153
217
|
|
|
@@ -164,11 +228,12 @@ TypeScript 7 no longer has the compiler API it reads the source with.
|
|
|
164
228
|
|
|
165
229
|
## Releasing
|
|
166
230
|
|
|
167
|
-
Raise the version in `package.json
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
231
|
+
Raise the version in `package.json`, in `CITATION.cff`, there with the
|
|
232
|
+
day as `date-released`, and in `src/software.ts`, which names the release
|
|
233
|
+
in the reasonings the library records. Then commit, and push a tag
|
|
234
|
+
`v<version>`. The `publish.yml` workflow builds, tests and publishes to
|
|
235
|
+
npm, then makes a GitHub release of the tag, which Zenodo archives with
|
|
236
|
+
a DOI. A test fails while the versions differ.
|
|
172
237
|
|
|
173
238
|
## About
|
|
174
239
|
|
|
@@ -164,6 +164,10 @@ export declare const uncheckedMotivation: {
|
|
|
164
164
|
* A recoding that only inserts or only deletes is the editor's: a
|
|
165
165
|
* collation types no one-sided edit, so one typed so is a reading of
|
|
166
166
|
* the transfer that collating again must not undo.
|
|
167
|
+
*
|
|
168
|
+
* An edit a program proposed and typed is no reading of the editor's
|
|
169
|
+
* either, as long as nobody has motivated it: it says so by belonging
|
|
170
|
+
* to the proposition set the program's run concluded (`adoptEdits`).
|
|
167
171
|
* @category Collation and alignment
|
|
168
172
|
*/
|
|
169
173
|
export declare const isCollationsOwn: (edit: Readonly<Edit>) => boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isHeldForItself, propositionSetOf } from "../model/Assumption.js";
|
|
1
2
|
import { keyOf } from "../systems/TrackerBar.js";
|
|
2
3
|
import { distance, mm } from "../model/Quantity.js";
|
|
3
4
|
import { partitionPoint } from "../shared/sorted.js";
|
|
@@ -153,9 +154,13 @@ export const uncheckedMotivation = {
|
|
|
153
154
|
* A recoding that only inserts or only deletes is the editor's: a
|
|
154
155
|
* collation types no one-sided edit, so one typed so is a reading of
|
|
155
156
|
* the transfer that collating again must not undo.
|
|
157
|
+
*
|
|
158
|
+
* An edit a program proposed and typed is no reading of the editor's
|
|
159
|
+
* either, as long as nobody has motivated it: it says so by belonging
|
|
160
|
+
* to the proposition set the program's run concluded (`adoptEdits`).
|
|
156
161
|
* @category Collation and alignment
|
|
157
162
|
*/
|
|
158
163
|
export const isCollationsOwn = (edit) => (edit.editType === drawnByCollation && !!edit.insert?.length && !!edit.delete?.length)
|
|
159
|
-
|| (edit.editType === undefined
|
|
164
|
+
|| ((edit.editType === undefined || propositionSetOf(edit) !== undefined)
|
|
160
165
|
&& (edit.motivation === undefined || edit.motivation === unchecked)
|
|
161
|
-
&& edit
|
|
166
|
+
&& !isHeldForItself(edit));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Edition } from "../model/Edition.js";
|
|
2
|
+
import { PropositionSet } from "../model/Assumption.js";
|
|
2
3
|
import { Version } from "../model/Version.js";
|
|
3
4
|
import { EditionOp } from "../ops/draft.js";
|
|
4
5
|
import { StemmaProposal, Unpinned } from "./proposal.js";
|
|
6
|
+
import { Run } from "./record.js";
|
|
5
7
|
/**
|
|
6
8
|
* What adopting a proposal makes of the stemma: the versions it puts in
|
|
7
9
|
* place of the edition's, and what of the edition it leaves out.
|
|
@@ -15,6 +17,12 @@ export interface Adoption {
|
|
|
15
17
|
removed: string[];
|
|
16
18
|
/** The edits the editor wrote that the adoption leaves out, and why. */
|
|
17
19
|
dropped: Unpinned[];
|
|
20
|
+
/**
|
|
21
|
+
* The record of the run: the proposition set the derivations and
|
|
22
|
+
* edits the proposal concluded belong to, held under one belief
|
|
23
|
+
* whose reason is the inference the program drew.
|
|
24
|
+
*/
|
|
25
|
+
propositionSet: PropositionSet;
|
|
18
26
|
}
|
|
19
27
|
/**
|
|
20
28
|
* What adopting the proposal makes of the edition's stemma, worked out
|
|
@@ -35,13 +43,28 @@ export interface Adoption {
|
|
|
35
43
|
* id and whatever it states beside its carriers. A version of the edition
|
|
36
44
|
* nothing stands for goes, unless it states no edits and derives from a
|
|
37
45
|
* version that stays, as a version known only from a recording does.
|
|
46
|
+
*
|
|
47
|
+
* What the program concluded is recorded as one proposition set, since
|
|
48
|
+
* the search scores whole stemmata and concludes the whole: each
|
|
49
|
+
* derivation it states and each edit it makes belongs to the set, which
|
|
50
|
+
* holds them under one belief, likely unless the run says otherwise,
|
|
51
|
+
* concluded by an inference that names this library and its release,
|
|
52
|
+
* the copies it collated, the rules it followed and, in its note, what
|
|
53
|
+
* it was computed with. A derivation or an edit that is the editor's,
|
|
54
|
+
* held under a belief of its own or saying more than a program says,
|
|
55
|
+
* stays the editor's and outside the set. The run gives who ran the
|
|
56
|
+
* program and when (`Run`).
|
|
38
57
|
* @category Filiation
|
|
39
58
|
*/
|
|
40
|
-
export declare const adoptionOf: (edition: Edition, proposal: StemmaProposal) => Adoption;
|
|
59
|
+
export declare const adoptionOf: (edition: Edition, proposal: StemmaProposal, run?: Run) => Adoption;
|
|
41
60
|
/**
|
|
42
61
|
* Puts the proposed stemma in place of the edition's, as `adoptionOf`
|
|
43
|
-
* describes, and takes back a copy's
|
|
44
|
-
* that
|
|
62
|
+
* describes, with the record of the run, and takes back a copy's
|
|
63
|
+
* statement that it carries a version that goes. The record of an
|
|
64
|
+
* earlier run whose conclusions are all replaced goes with them, and
|
|
65
|
+
* one of the very same run, by the same release on the same copies with
|
|
66
|
+
* the same result, stays as it was first recorded. One operation, and
|
|
67
|
+
* so one undo step.
|
|
45
68
|
* @category Operations
|
|
46
69
|
*/
|
|
47
|
-
export declare const adoptStemma: (proposal: StemmaProposal) => EditionOp;
|
|
70
|
+
export declare const adoptStemma: (proposal: StemmaProposal, run?: Run) => EditionOp;
|
|
@@ -1,15 +1,50 @@
|
|
|
1
1
|
/** Taking a proposed stemma into the edition, as one operation. */
|
|
2
2
|
import { v5 } from "uuid";
|
|
3
|
-
import { assignReference, idOf } from "../model/Assumption.js";
|
|
3
|
+
import { assignReference, idOf, isHeldForItself } from "../model/Assumption.js";
|
|
4
4
|
import { derivesFrom, editsOf, insertedBy, principalDerivationOf } from "../model/Version.js";
|
|
5
5
|
import { systemOf } from "../systems/TrackerBar.js";
|
|
6
|
-
import { unchecked } from "../collation/Collation.js";
|
|
6
|
+
import { isCollationsOwn, unchecked } from "../collation/Collation.js";
|
|
7
7
|
import { versionIn } from "../lookup/lookup.js";
|
|
8
8
|
import { declaring, reading } from "../ops/draft.js";
|
|
9
9
|
import { dropStatements } from "../ops/copies.js";
|
|
10
10
|
import { barNamed } from "./systems.js";
|
|
11
|
+
import { inMillimetres, keptSets, memberOf, recorded, stemmaRules } from "./record.js";
|
|
11
12
|
/** The namespace the names of adopted versions and edits are minted in, so that adopting again gives them again. */
|
|
12
13
|
const ADOPTED = '6f1d2c8e-93a4-4f0b-b8a1-2f4c5d7e9a31';
|
|
14
|
+
/** The rules the proposal followed, as far as its costs and settings carry them out. */
|
|
15
|
+
const rulesOf = (proposal) => [
|
|
16
|
+
...(proposal.costs.gain > 1 ? [stemmaRules.sharedAddition] : []),
|
|
17
|
+
...(proposal.costs.redundantLoss < 1 ? [stemmaRules.independentCleanup] : []),
|
|
18
|
+
...(proposal.costs.transferLoss < 1 ? [stemmaRules.recutLoss] : []),
|
|
19
|
+
...(Number.isFinite(proposal.costs.copyDeviation) ? [stemmaRules.copyDeviation] : []),
|
|
20
|
+
...(proposal.costs.lostState > 0 ? [stemmaRules.lostStates] : []),
|
|
21
|
+
...(proposal.sameText >= 0 ? [stemmaRules.oneText] : []),
|
|
22
|
+
stemmaRules.refinement,
|
|
23
|
+
stemmaRules.noContamination
|
|
24
|
+
];
|
|
25
|
+
/** A number as a note gives it: to two places at most. */
|
|
26
|
+
const amount = (value) => String(Math.round(value * 100) / 100);
|
|
27
|
+
/**
|
|
28
|
+
* What the run of `proposeStemma` was, and what it was computed with, in
|
|
29
|
+
* words, so that it can be run again: the copies by siglum, the costs,
|
|
30
|
+
* the settings, and the margin by which the copies decide each grouping.
|
|
31
|
+
*/
|
|
32
|
+
const noteOn = (edition, proposal) => {
|
|
33
|
+
const siglumOf = new Map(edition.copies.map(copy => [copy.id, copy.siglum ?? copy.id]));
|
|
34
|
+
const named = (copies) => copies.map(copy => siglumOf.get(copy) ?? copy).join(', ');
|
|
35
|
+
const { costs } = proposal;
|
|
36
|
+
const supports = proposal.supports.map(support => support.ancestor
|
|
37
|
+
? `${named(support.ancestor)} above ${named(support.copies.filter(copy => !support.ancestor.includes(copy)))} by ${amount(support.margin)}`
|
|
38
|
+
: `${named(support.copies)} together by ${amount(support.margin)}`);
|
|
39
|
+
return [
|
|
40
|
+
`The stemma ${proposal.notation}, the best of ${proposal.scored} that ${named(proposal.copies)} admit, at a cost of ${amount(proposal.cost)}.`,
|
|
41
|
+
`A reading arising costs ${amount(costs.gain)}, a reading lost 1, a redundancy lost ${amount(costs.redundantLoss)}, a reading lost on the way into another system ${amount(costs.transferLoss)}, a copy lacking a reading of its version ${amount(costs.copyDeviation)}, and a lost state ${amount(costs.lostState)}.`,
|
|
42
|
+
`Copies of one system differing in ${proposal.sameText < 0 ? 'any reading' : `no more than ${proposal.sameText} readings`} are taken for one text; a reading of the same kind within ${inMillimetres(proposal.movedWithin)} on the other side of the root for a moved one; and ${inMillimetres(proposal.margin)} beyond a copy's text or a tear for what the copy cannot show.`,
|
|
43
|
+
...(supports.length > 0 ? [`The copies decide its groupings by: ${supports.join('; ')}.`] : [])
|
|
44
|
+
].join(' ');
|
|
45
|
+
};
|
|
46
|
+
/** The set the run of `proposeStemma` concluded, held with the belief the run gives it. */
|
|
47
|
+
const stemmaSetOf = (edition, proposal, run) => recorded('stemma', [proposal.copies, proposal.notation, proposal.costs, proposal.sameText, proposal.movedWithin, proposal.margin], { note: noteOn(edition, proposal), premises: [], used: [...proposal.copies], applies: rulesOf(proposal) }, run);
|
|
13
48
|
const exchangeKey = (inserted, deleted) => `${[...inserted].sort().join(',')}/${[...deleted].sort().join(',')}`;
|
|
14
49
|
/** The carriers of the reading, keeping what the edition states of those it held already. */
|
|
15
50
|
const carriersOf = (reading, stated) => {
|
|
@@ -35,9 +70,21 @@ const carriersOf = (reading, stated) => {
|
|
|
35
70
|
* id and whatever it states beside its carriers. A version of the edition
|
|
36
71
|
* nothing stands for goes, unless it states no edits and derives from a
|
|
37
72
|
* version that stays, as a version known only from a recording does.
|
|
73
|
+
*
|
|
74
|
+
* What the program concluded is recorded as one proposition set, since
|
|
75
|
+
* the search scores whole stemmata and concludes the whole: each
|
|
76
|
+
* derivation it states and each edit it makes belongs to the set, which
|
|
77
|
+
* holds them under one belief, likely unless the run says otherwise,
|
|
78
|
+
* concluded by an inference that names this library and its release,
|
|
79
|
+
* the copies it collated, the rules it followed and, in its note, what
|
|
80
|
+
* it was computed with. A derivation or an edit that is the editor's,
|
|
81
|
+
* held under a belief of its own or saying more than a program says,
|
|
82
|
+
* stays the editor's and outside the set. The run gives who ran the
|
|
83
|
+
* program and when (`Run`).
|
|
38
84
|
* @category Filiation
|
|
39
85
|
*/
|
|
40
|
-
export const adoptionOf = (edition, proposal) => {
|
|
86
|
+
export const adoptionOf = (edition, proposal, run = {}) => {
|
|
87
|
+
const set = stemmaSetOf(edition, proposal, run);
|
|
41
88
|
const readingOf = new Map(proposal.collation.readings.map(reading => [reading.id, reading]));
|
|
42
89
|
const symbolIdOf = (reading) => proposal.symbols[reading] ?? reading;
|
|
43
90
|
const existing = new Map(edition.versions.flatMap(insertedBy).map(symbol => [symbol.id, symbol]));
|
|
@@ -112,16 +159,18 @@ export const adoptionOf = (edition, proposal) => {
|
|
|
112
159
|
const key = exchangeKey(inserted, deleted);
|
|
113
160
|
const same = statedBefore.get(key);
|
|
114
161
|
const insert = inserts.map(reading => symbolOf(reading, proposed.id));
|
|
115
|
-
if (same)
|
|
116
|
-
|
|
117
|
-
|
|
162
|
+
if (same) {
|
|
163
|
+
const taken = { ...same, ...(insert.length > 0 && { insert }), ...(deleted.length > 0 && { delete: deleted }) };
|
|
164
|
+
return isCollationsOwn(same) ? memberOf(set.id, taken) : taken;
|
|
165
|
+
}
|
|
166
|
+
return memberOf(set.id, {
|
|
118
167
|
type: 'edit',
|
|
119
168
|
id: v5(`edit|${id}|${key}`, ADOPTED),
|
|
120
169
|
...(recoding && { editType: 'recoding' }),
|
|
121
170
|
motivation: unchecked,
|
|
122
171
|
...(insert.length > 0 && { insert }),
|
|
123
172
|
...(deleted.length > 0 && { delete: deleted })
|
|
124
|
-
};
|
|
173
|
+
});
|
|
125
174
|
};
|
|
126
175
|
// A recoding an edit of the editor's cuts into is stated reading by reading.
|
|
127
176
|
const whole = proposed.recodings.filter(recoding => ![...recoding.by.map(reading => symbolIdAt(reading, proposed.id)), ...recoding.replaced.map(reading => inheritedAt(reading, proposed.id))]
|
|
@@ -133,11 +182,13 @@ export const adoptionOf = (edition, proposal) => {
|
|
|
133
182
|
...proposed.inserts.filter(reading => !recoded.has(reading)).map(reading => made([reading], [], false)),
|
|
134
183
|
...proposed.deletes.filter(reading => !recoded.has(reading)).map(reading => made([], [reading], false))
|
|
135
184
|
].filter((edit) => edit !== undefined);
|
|
185
|
+
// The derivation is the set's, unless the editor holds it for reasons of their own.
|
|
136
186
|
const parent = proposed.parent ? ids.get(proposed.parent) : undefined;
|
|
137
187
|
const principal = before && principalDerivationOf(before);
|
|
188
|
+
const same = principal && idOf(principal) === parent ? principal : undefined;
|
|
138
189
|
const derivation = parent === undefined
|
|
139
190
|
? undefined
|
|
140
|
-
:
|
|
191
|
+
: same && isHeldForItself(same) ? same : memberOf(set.id, same ?? assignReference(parent));
|
|
141
192
|
const hypotheses = (before?.basedOn ?? [])
|
|
142
193
|
.filter(other => other !== principal && staying.has(idOf(other)) && idOf(other) !== parent);
|
|
143
194
|
const basedOn = [...(derivation ? [derivation] : []), ...hypotheses];
|
|
@@ -171,19 +222,28 @@ export const adoptionOf = (edition, proposal) => {
|
|
|
171
222
|
// The edition's order where a version stays, the new ones after it.
|
|
172
223
|
const rank = new Map(edition.versions.map((version, index) => [version.id, index]));
|
|
173
224
|
const ordered = [...pruned, ...statedOnly].sort((a, b) => (rank.get(a.id) ?? Infinity) - (rank.get(b.id) ?? Infinity));
|
|
174
|
-
return { versions: ordered, ids: Object.fromEntries(ids), removed, dropped: proposal.unpinned };
|
|
225
|
+
return { versions: ordered, ids: Object.fromEntries(ids), removed, dropped: proposal.unpinned, propositionSet: set };
|
|
175
226
|
};
|
|
176
227
|
/**
|
|
177
228
|
* Puts the proposed stemma in place of the edition's, as `adoptionOf`
|
|
178
|
-
* describes, and takes back a copy's
|
|
179
|
-
* that
|
|
229
|
+
* describes, with the record of the run, and takes back a copy's
|
|
230
|
+
* statement that it carries a version that goes. The record of an
|
|
231
|
+
* earlier run whose conclusions are all replaced goes with them, and
|
|
232
|
+
* one of the very same run, by the same release on the same copies with
|
|
233
|
+
* the same result, stays as it was first recorded. One operation, and
|
|
234
|
+
* so one undo step.
|
|
180
235
|
* @category Operations
|
|
181
236
|
*/
|
|
182
|
-
export const adoptStemma = (proposal) => reading(edition => {
|
|
183
|
-
const { versions, removed } = adoptionOf(edition, proposal);
|
|
237
|
+
export const adoptStemma = (proposal, run = {}) => reading(edition => {
|
|
238
|
+
const { versions, removed, propositionSet } = adoptionOf(edition, proposal, run);
|
|
184
239
|
const gone = new Set(removed);
|
|
240
|
+
const sets = keptSets({ ...edition, versions }, [propositionSet]);
|
|
185
241
|
return draft => {
|
|
186
242
|
draft.versions = versions;
|
|
187
243
|
draft.copies.forEach(copy => dropStatements(copy, statement => gone.has(idOf(statement))));
|
|
244
|
+
if (sets)
|
|
245
|
+
draft.propositionSets = sets;
|
|
246
|
+
else
|
|
247
|
+
delete draft.propositionSets;
|
|
188
248
|
};
|
|
189
249
|
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Edition } from "../model/Edition.js";
|
|
2
|
+
import { Edit, EditType } from "../model/Edit.js";
|
|
3
|
+
import { Millimeters } from "../model/Quantity.js";
|
|
4
|
+
import { EditionOp } from "../ops/draft.js";
|
|
5
|
+
import { Run } from "./record.js";
|
|
6
|
+
/**
|
|
7
|
+
* How far a perforation may be put from where it stood for the two to be
|
|
8
|
+
* one move. WM 225 moves commands by up to about 60 mm.
|
|
9
|
+
* @category Filiation
|
|
10
|
+
*/
|
|
11
|
+
export declare const defaultShiftWithin: import("../index.js").Quantity<"mm">;
|
|
12
|
+
/**
|
|
13
|
+
* How far an Off may follow an On for the two to be one function turned
|
|
14
|
+
* on and off again, as an accent is. WM 225 has crescendo accents of up
|
|
15
|
+
* to about 55 mm.
|
|
16
|
+
* @category Filiation
|
|
17
|
+
*/
|
|
18
|
+
export declare const defaultPairWithin: import("../index.js").Quantity<"mm">;
|
|
19
|
+
/**
|
|
20
|
+
* How near the onsets of a perforation and the one put in its place lie
|
|
21
|
+
* for the one to be a longer or shorter version of the other rather than
|
|
22
|
+
* a moved one. The figure `mergeEdits` guesses with.
|
|
23
|
+
* @category Filiation
|
|
24
|
+
*/
|
|
25
|
+
export declare const defaultResizeWithin: import("../index.js").Quantity<"mm">;
|
|
26
|
+
/**
|
|
27
|
+
* How near two perforations lie to stand at one place: the commands of a
|
|
28
|
+
* cancel row, or an accent's On and the note set off for it.
|
|
29
|
+
* @category Filiation
|
|
30
|
+
*/
|
|
31
|
+
export declare const defaultSamePlaceWithin: import("../index.js").Quantity<"mm">;
|
|
32
|
+
/**
|
|
33
|
+
* What a proposal of edits is computed with. Every value has a default,
|
|
34
|
+
* the one the edits of WM 225 are reproduced with.
|
|
35
|
+
* @category Filiation
|
|
36
|
+
*/
|
|
37
|
+
export interface EditOptions {
|
|
38
|
+
/** `defaultShiftWithin` */
|
|
39
|
+
shiftWithin?: Millimeters;
|
|
40
|
+
/** `defaultPairWithin` */
|
|
41
|
+
pairWithin?: Millimeters;
|
|
42
|
+
/** `defaultResizeWithin` */
|
|
43
|
+
resizeWithin?: Millimeters;
|
|
44
|
+
/** `defaultSamePlaceWithin` */
|
|
45
|
+
samePlaceWithin?: Millimeters;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Why changes were taken for one edit.
|
|
49
|
+
* @category Filiation
|
|
50
|
+
*/
|
|
51
|
+
export type EditGrouping =
|
|
52
|
+
/** A change nothing else on its line goes with. */
|
|
53
|
+
'single'
|
|
54
|
+
/** A latched function turned on and off again shortly after, as an accent is, or off and on again, added or withdrawn. */
|
|
55
|
+
| 'pair'
|
|
56
|
+
/** Notes of one pitch, or held commands of one function, that overlap: a note struck again, two tied into one, one made longer. */
|
|
57
|
+
| 'overlap'
|
|
58
|
+
/** What the version deletes on a line, and what it puts nearby in its place. */
|
|
59
|
+
| 'move'
|
|
60
|
+
/** A held command of the version standing for a latched pair of the parent's. */
|
|
61
|
+
| 'substitution'
|
|
62
|
+
/** Cancels punched across several lines at one place. */
|
|
63
|
+
| 'row';
|
|
64
|
+
/**
|
|
65
|
+
* An edit proposed from the changes of a version.
|
|
66
|
+
* @category Filiation
|
|
67
|
+
*/
|
|
68
|
+
export interface ProposedEdit {
|
|
69
|
+
/** The ids of the symbols it inserts, in the order of their places. */
|
|
70
|
+
insert: string[];
|
|
71
|
+
/** The ids of the symbols it deletes, in the order of their places. */
|
|
72
|
+
delete: string[];
|
|
73
|
+
/** The kind of change, where its shape says. */
|
|
74
|
+
editType?: EditType;
|
|
75
|
+
grouping: EditGrouping;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The edits of the version, proposed from what its edits insert and
|
|
79
|
+
* delete, however they group it now. The proposal depends on the
|
|
80
|
+
* version's changes and the text of its parent alone, so it is the same
|
|
81
|
+
* whatever order the changes come in.
|
|
82
|
+
*
|
|
83
|
+
* Changes are read line by line: a latched function on its side of the
|
|
84
|
+
* keyboard, a held one, or a pitch. A command or a note both texts keep
|
|
85
|
+
* divides its line, and no edit runs across one, so that every edit
|
|
86
|
+
* stays at one place. On a latched line, a function turned on and off
|
|
87
|
+
* again shortly after is one edit, as an accent is; a pair withdrawn and
|
|
88
|
+
* put elsewhere whole is one move, and so is a command put elsewhere on
|
|
89
|
+
* its own, the nearest first; an Off with an On right after it breaks
|
|
90
|
+
* the function off and takes it up again. Notes, and commands held for
|
|
91
|
+
* as long as they last, are one edit where they overlap, and one move
|
|
92
|
+
* where a note is put nearby. Where the version's system has no word for
|
|
93
|
+
* a command of the parent's, a held command standing for a latched pair
|
|
94
|
+
* is one edit with it; what has no counterpart stands alone. Cancels
|
|
95
|
+
* punched across three lines or more at one place are one edit, as a
|
|
96
|
+
* cancel row is.
|
|
97
|
+
*
|
|
98
|
+
* The type is read off the shape: a pair the bar spells an accent with is
|
|
99
|
+
* an additional accent, as is a note set off from its chord by a few
|
|
100
|
+
* millimetres where the version puts an accent's On; a perforation put
|
|
101
|
+
* elsewhere is a shift, or where it begins about where the other did,
|
|
102
|
+
* shortened or prolonged; a note struck again is shortened, two tied
|
|
103
|
+
* prolonged; a change the text makes no use of is a redundancy added or
|
|
104
|
+
* removed; and a change the other system has no word for is a recoding.
|
|
105
|
+
* Whether a shift corrects an error, and why any change was made, is
|
|
106
|
+
* not read off the shape.
|
|
107
|
+
*
|
|
108
|
+
* A version that derives from none states its text, not a change of
|
|
109
|
+
* another, and each of its symbols stands alone.
|
|
110
|
+
* @category Filiation
|
|
111
|
+
*/
|
|
112
|
+
export declare const proposeEdits: (edition: Edition, versionId: string, options?: EditOptions) => ProposedEdit[];
|
|
113
|
+
/**
|
|
114
|
+
* Whether the edit is left for a proposal to group again: one a
|
|
115
|
+
* collation or an adoption wrote, that nobody has given a motivation.
|
|
116
|
+
* @category Filiation
|
|
117
|
+
*/
|
|
118
|
+
export declare const isRegroupable: (edit: Readonly<Edit>) => boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Puts the proposed edits (`proposeEdits`) in place of those of the
|
|
121
|
+
* versions that a collation or an adoption wrote and nobody has given a
|
|
122
|
+
* motivation, every version but the root where none are named. An edit
|
|
123
|
+
* someone motivated, typed beyond what a collation types, or held under a
|
|
124
|
+
* belief stays as it is, and what a proposed edit shares with it stands
|
|
125
|
+
* symbol by symbol beside it. An edit stated already over the very same
|
|
126
|
+
* symbols as a proposed one is kept with its id and what was written on
|
|
127
|
+
* it, the proposed type filled in where it states none; the others are
|
|
128
|
+
* new, with ids that adopting again gives again, and marked unchecked,
|
|
129
|
+
* so that what is left to the editor is to say why.
|
|
130
|
+
*
|
|
131
|
+
* Applied on the same draft after `adoptStemma`, it proposes the edits of
|
|
132
|
+
* the stemma adopted, as one undo step.
|
|
133
|
+
*
|
|
134
|
+
* The edits it proposes are recorded as one proposition set, held under
|
|
135
|
+
* one belief, likely unless the run says otherwise, whose reason is the
|
|
136
|
+
* inference the program drew: it names this library and its release,
|
|
137
|
+
* the versions it read, the rule that keeps an edit at one place and, in
|
|
138
|
+
* its note, the distances it grouped with, and it rests on the beliefs
|
|
139
|
+
* the derivations of the versions are held with. An edit of the set
|
|
140
|
+
* that nobody has motivated is the program's, typed and all, and a
|
|
141
|
+
* later proposal groups it again. The run gives who ran the program and
|
|
142
|
+
* when (`Run`).
|
|
143
|
+
* @category Operations
|
|
144
|
+
*/
|
|
145
|
+
export declare const adoptEdits: (versionIds?: readonly string[], options?: EditOptions, run?: Run) => EditionOp;
|