linked-rolls 0.47.0 → 0.48.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/lib/Collation.d.ts +21 -0
- package/lib/Collation.js +24 -1
- package/lib/alignment.d.ts +13 -0
- package/lib/alignment.js +19 -0
- package/lib/editionOps.js +16 -3
- package/package.json +1 -1
package/lib/Collation.d.ts
CHANGED
|
@@ -85,6 +85,27 @@ export type Collation = {
|
|
|
85
85
|
};
|
|
86
86
|
/** Each of the own symbols with every inherited symbol it collates with, both in the order given. */
|
|
87
87
|
export declare const collationsOf: (own: readonly Readonly<AnySymbol>[], inherited: readonly Readonly<AnySymbol>[], locate: Locate, tolerance?: CollationTolerance) => Collation[];
|
|
88
|
+
/**
|
|
89
|
+
* The motivation a collation writes on what it makes, saying that
|
|
90
|
+
* nobody has read it yet.
|
|
91
|
+
*
|
|
92
|
+
* A collation produces its edits by a rule, and an edition that
|
|
93
|
+
* publishes them unmarked would present a machine's output as an
|
|
94
|
+
* editor's reading. Stating that they are unchecked is the honest
|
|
95
|
+
* middle: the readings are there to be seen and argued with, and a
|
|
96
|
+
* reader can tell which of them anybody has weighed.
|
|
97
|
+
*
|
|
98
|
+
* It does not make an edit the editor's. `isCollationsOwn` passes over
|
|
99
|
+
* this motivation exactly, so a collation rewrites what it marked
|
|
100
|
+
* before, and only what somebody has actually written stays.
|
|
101
|
+
*/
|
|
102
|
+
export declare const unchecked = "unchecked";
|
|
103
|
+
/** The version's statement of what the unchecked motivation means, to stand in its `motivations`. */
|
|
104
|
+
export declare const uncheckedMotivation: {
|
|
105
|
+
readonly type: 'motivation';
|
|
106
|
+
readonly id: "unchecked";
|
|
107
|
+
readonly note: 'Made by collating the two texts and not yet read by an editor.';
|
|
108
|
+
};
|
|
88
109
|
/**
|
|
89
110
|
* Whether the edit is one a collation writes by itself: a bare
|
|
90
111
|
* insertion or a bare deletion saying nothing further, or an
|
package/lib/Collation.js
CHANGED
|
@@ -89,6 +89,27 @@ export const collationsOf = (own, inherited, locate, tolerance = defaultCollatio
|
|
|
89
89
|
};
|
|
90
90
|
/** The edit type a collation draws by itself, from the two systems' vocabularies rather than off the paper. */
|
|
91
91
|
const drawnByCollation = 'replace-with-equivalent';
|
|
92
|
+
/**
|
|
93
|
+
* The motivation a collation writes on what it makes, saying that
|
|
94
|
+
* nobody has read it yet.
|
|
95
|
+
*
|
|
96
|
+
* A collation produces its edits by a rule, and an edition that
|
|
97
|
+
* publishes them unmarked would present a machine's output as an
|
|
98
|
+
* editor's reading. Stating that they are unchecked is the honest
|
|
99
|
+
* middle: the readings are there to be seen and argued with, and a
|
|
100
|
+
* reader can tell which of them anybody has weighed.
|
|
101
|
+
*
|
|
102
|
+
* It does not make an edit the editor's. `isCollationsOwn` passes over
|
|
103
|
+
* this motivation exactly, so a collation rewrites what it marked
|
|
104
|
+
* before, and only what somebody has actually written stays.
|
|
105
|
+
*/
|
|
106
|
+
export const unchecked = 'unchecked';
|
|
107
|
+
/** The version's statement of what the unchecked motivation means, to stand in its `motivations`. */
|
|
108
|
+
export const uncheckedMotivation = {
|
|
109
|
+
type: 'motivation',
|
|
110
|
+
id: unchecked,
|
|
111
|
+
note: 'Made by collating the two texts and not yet read by an editor.'
|
|
112
|
+
};
|
|
92
113
|
/**
|
|
93
114
|
* Whether the edit is one a collation writes by itself: a bare
|
|
94
115
|
* insertion or a bare deletion saying nothing further, or an
|
|
@@ -107,4 +128,6 @@ const drawnByCollation = 'replace-with-equivalent';
|
|
|
107
128
|
* draws a second time over the very same symbols.
|
|
108
129
|
*/
|
|
109
130
|
export const isCollationsOwn = (edit) => edit.editType === drawnByCollation
|
|
110
|
-
|| (edit.editType === undefined
|
|
131
|
+
|| (edit.editType === undefined
|
|
132
|
+
&& (edit.motivation === undefined || edit.motivation === unchecked)
|
|
133
|
+
&& edit['@annotation'] === undefined);
|
package/lib/alignment.d.ts
CHANGED
|
@@ -32,6 +32,19 @@ export declare const revertScale: (copy: RollCopy) => void;
|
|
|
32
32
|
*
|
|
33
33
|
* Only holes are touched. What a writing or a mark spans is no valve.
|
|
34
34
|
*/
|
|
35
|
+
/**
|
|
36
|
+
* The holes the extension cannot be taken off, being no longer than it
|
|
37
|
+
* is: the reader reported them open for less time than it holds a valve
|
|
38
|
+
* on beyond the perforation, so the constant over-corrects them and
|
|
39
|
+
* would leave them ending before they begin.
|
|
40
|
+
*
|
|
41
|
+
* They are where the constant shows its limit rather than where the
|
|
42
|
+
* copy is wrong, the extension varying by about half a millimetre with
|
|
43
|
+
* the port. What to do with them is an editorial question — a condition
|
|
44
|
+
* on the feature, a reading of the hole, a smaller extension — and
|
|
45
|
+
* `shortenHoles` throws rather than answer it.
|
|
46
|
+
*/
|
|
47
|
+
export declare const tooShortToShorten: (extension: Millimeters, copy: RollCopy) => Readonly<FeatureOrPatch>[];
|
|
35
48
|
export declare const shortenHoles: (extension: Millimeters, copy: RollCopy) => void;
|
|
36
49
|
/** Puts the reader's extension back on the copy's holes, as far as one was taken off. */
|
|
37
50
|
export declare const revertShortening: (copy: RollCopy) => void;
|
package/lib/alignment.js
CHANGED
|
@@ -78,9 +78,28 @@ const holesOf = (copy) => featuresOf(copy).filter(feature => feature.type === 'H
|
|
|
78
78
|
*
|
|
79
79
|
* Only holes are touched. What a writing or a mark spans is no valve.
|
|
80
80
|
*/
|
|
81
|
+
/**
|
|
82
|
+
* The holes the extension cannot be taken off, being no longer than it
|
|
83
|
+
* is: the reader reported them open for less time than it holds a valve
|
|
84
|
+
* on beyond the perforation, so the constant over-corrects them and
|
|
85
|
+
* would leave them ending before they begin.
|
|
86
|
+
*
|
|
87
|
+
* They are where the constant shows its limit rather than where the
|
|
88
|
+
* copy is wrong, the extension varying by about half a millimetre with
|
|
89
|
+
* the port. What to do with them is an editorial question — a condition
|
|
90
|
+
* on the feature, a reading of the hole, a smaller extension — and
|
|
91
|
+
* `shortenHoles` throws rather than answer it.
|
|
92
|
+
*/
|
|
93
|
+
export const tooShortToShorten = (extension, copy) => holesOf(copy).filter(hole => hole.horizontal.to - hole.horizontal.from <= extension);
|
|
81
94
|
export const shortenHoles = (extension, copy) => {
|
|
82
95
|
if (copy.ops.includes('shortened'))
|
|
83
96
|
return;
|
|
97
|
+
const tooShort = tooShortToShorten(extension, copy);
|
|
98
|
+
if (tooShort.length > 0) {
|
|
99
|
+
throw new Error(`The extension of ${extension} mm cannot be taken off ${tooShort.length} `
|
|
100
|
+
+ `hole(s) of copy ${copy.id}, which are no longer than it: `
|
|
101
|
+
+ `${tooShort.map(hole => hole.id).join(', ')}`);
|
|
102
|
+
}
|
|
84
103
|
holesOf(copy).forEach(hole => { hole.horizontal.to = subtract(hole.horizontal.to, extension); });
|
|
85
104
|
copy.ops = [...copy.ops, 'shortened'];
|
|
86
105
|
copy.measurements.readerExtension = extension;
|
package/lib/editionOps.js
CHANGED
|
@@ -2,7 +2,7 @@ import { current, isDraft } from "immer";
|
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { getAt } from "./EditionView.js";
|
|
4
4
|
import { isCommand, placementRelations } from "./Symbol.js";
|
|
5
|
-
import { collationsOf, defaultCollationTolerance, isCollationsOwn } from "./Collation.js";
|
|
5
|
+
import { collationsOf, defaultCollationTolerance, isCollationsOwn, unchecked, uncheckedMotivation } from "./Collation.js";
|
|
6
6
|
import { collationToleranceOf, editsOf, insertedBy, principalDerivationOf } from "./Version.js";
|
|
7
7
|
import { asSymbols, barOf, featuresByAct, featuresOf, isPaperStretch, statesNothing } from "./RollCopy.js";
|
|
8
8
|
import { systemOf } from "./TrackerBar.js";
|
|
@@ -54,6 +54,17 @@ const droppedIds = (before, after) => {
|
|
|
54
54
|
};
|
|
55
55
|
const insertion = (symbol) => ({ type: 'edit', id: v4(), insert: [symbol] });
|
|
56
56
|
const deletion = (symbolId) => ({ type: 'edit', id: v4(), delete: [symbolId] });
|
|
57
|
+
/** The edit as a collation leaves it: made by rule, and not yet read by anybody. */
|
|
58
|
+
const asUnchecked = (edit) => ({ ...edit, motivation: unchecked });
|
|
59
|
+
/**
|
|
60
|
+
* The motivations with the unchecked one declared, where any edit
|
|
61
|
+
* names it and the version does not state it yet. An edit naming a
|
|
62
|
+
* motivation the version leaves undeclared points at nothing.
|
|
63
|
+
*/
|
|
64
|
+
const declaring = (motivations, edits) => edits.some(edit => edit.motivation === unchecked)
|
|
65
|
+
&& !motivations.some(motivation => motivation.id === unchecked)
|
|
66
|
+
? [...motivations, uncheckedMotivation]
|
|
67
|
+
: motivations;
|
|
57
68
|
const isEmpty = (edit) => !edit.insert?.length && !edit.delete?.length;
|
|
58
69
|
const insertedIn = (versions) => versions.flatMap(insertedBy);
|
|
59
70
|
/** The edits with the change applied, less those it emptied; the very same array where it changed none. */
|
|
@@ -733,6 +744,7 @@ export const connectVersions = (view, childId, parentId, tolerance = defaultColl
|
|
|
733
744
|
type: 'edit',
|
|
734
745
|
id: v4(),
|
|
735
746
|
editType: 'replace-with-equivalent',
|
|
747
|
+
motivation: unchecked,
|
|
736
748
|
insert: [...by],
|
|
737
749
|
delete: deleted
|
|
738
750
|
};
|
|
@@ -740,14 +752,15 @@ export const connectVersions = (view, childId, parentId, tolerance = defaultColl
|
|
|
740
752
|
const edits = [
|
|
741
753
|
...established,
|
|
742
754
|
...substituted.map(equivalence),
|
|
743
|
-
...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion),
|
|
755
|
+
...own.filter(symbol => !collated.has(symbol.id) && !paired.has(symbol.id)).map(insertion).map(asUnchecked),
|
|
744
756
|
...inherited
|
|
745
757
|
.filter(symbol => !matched.has(symbol.id) && !paired.has(symbol.id))
|
|
746
|
-
.map(symbol => deletion(symbol.id))
|
|
758
|
+
.map(symbol => asUnchecked(deletion(symbol.id)))
|
|
747
759
|
];
|
|
748
760
|
return onVersion(childId, (child, draft) => {
|
|
749
761
|
handOverCarriers(view, draft, collations);
|
|
750
762
|
child.edits = edits;
|
|
763
|
+
child.motivations = declaring(stateOf(child).motivations, edits);
|
|
751
764
|
child.basedOn = [
|
|
752
765
|
{ ...assignReference(parentId), collationTolerance: tolerance },
|
|
753
766
|
...hypothesesBeside(stateOf(child), parentId)
|
package/package.json
CHANGED