linked-rolls 0.45.0 → 0.46.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/scatter.d.ts CHANGED
@@ -89,7 +89,18 @@ export interface Departure {
89
89
  * told which test did it.
90
90
  */
91
91
  separatedBy: BothEnds<boolean>;
92
- /** Whether the tolerance the edition states at present still admits it. Absent where none was given to compare against. */
92
+ /**
93
+ * Whether the tolerance the edition states at present still admits
94
+ * it. Absent where none was given to compare against.
95
+ *
96
+ * This sees one direction only. A departure is by definition a
97
+ * reading the calculated window rejects, so this says which of
98
+ * those the stated window joined and which would therefore be taken
99
+ * apart. It cannot show the converse, a reading the stated window
100
+ * rejects and the calculated one would join, because such a reading
101
+ * is no departure and never reaches this list. `changesBetween`
102
+ * reports both, and the ones it adds are the silent ones.
103
+ */
93
104
  admittedAsStated?: boolean;
94
105
  }
95
106
  /** How far a sample departs from the normal shape the tolerance assumes of it. */
@@ -178,8 +189,44 @@ export type Side = 'child' | 'parent';
178
189
  * sample's own median. Only the collation is wrong, and it is wrong in
179
190
  * both directions at once, separating readings that belong together and
180
191
  * merging readings that do not. Nothing where there is no sample.
192
+ *
193
+ * Covering has a cost where the samples sit at different centres, and
194
+ * it falls on the sample that does not move. One window has one centre,
195
+ * so where one sample's window contains another's the covering window
196
+ * is simply the wider one, centred where that sample sits, and the
197
+ * narrower sample is then judged against an offset it does not have.
198
+ * On the Phillips edge of welte225.org the expression punches sit
199
+ * 1.2 mm from the notes and the notes' onsets agree exactly, so the
200
+ * covering window shifts every note onset by a displacement only the
201
+ * expressions show. `changesBetween` makes that visible as readings the
202
+ * window moves; it is the price of one tolerance per derivation, and it
203
+ * is the same skew the grouping stands in for.
181
204
  */
182
205
  export declare const toleranceAcross: (scatters: readonly Scatter[], named: Side) => CollationTolerance | undefined;
206
+ /** What putting one window in force in place of another would do to a collation. */
207
+ export interface Changes {
208
+ /** Readings the window in force joins and the proposed one would take apart. */
209
+ separated: Reading[];
210
+ /** Readings the window in force takes apart and the proposed one would join. */
211
+ merged: Reading[];
212
+ }
213
+ /**
214
+ * Which readings two windows disagree about, taken apart by the
215
+ * direction they disagree in.
216
+ *
217
+ * The two are worth seeing separately because they do not cost the
218
+ * same. A separation leaves a visible edit in the apparatus that a
219
+ * reader can challenge; a merge erases a reading and says nothing, and
220
+ * the edition has no way to show what it lost. So the merges are the
221
+ * list to read first, and an edge that only separates is the safer kind
222
+ * of change however many readings it touches.
223
+ *
224
+ * This is what to ask before applying a calculated window, rather than
225
+ * reading `admittedAsStated` off the departures, which sees separations
226
+ * only. An edge both windows agree about throughout needs no
227
+ * re-collation at all, and its tolerance may simply be stated.
228
+ */
229
+ export declare const changesBetween: (readings: readonly Reading[], inForce: CollationTolerance, proposed: CollationTolerance) => Changes;
183
230
  /** How many of a side's symbols a copy bears. */
184
231
  export interface Attestation {
185
232
  copy: string;
package/lib/scatter.js CHANGED
@@ -143,6 +143,18 @@ const covering = (windows) => {
143
143
  * sample's own median. Only the collation is wrong, and it is wrong in
144
144
  * both directions at once, separating readings that belong together and
145
145
  * merging readings that do not. Nothing where there is no sample.
146
+ *
147
+ * Covering has a cost where the samples sit at different centres, and
148
+ * it falls on the sample that does not move. One window has one centre,
149
+ * so where one sample's window contains another's the covering window
150
+ * is simply the wider one, centred where that sample sits, and the
151
+ * narrower sample is then judged against an offset it does not have.
152
+ * On the Phillips edge of welte225.org the expression punches sit
153
+ * 1.2 mm from the notes and the notes' onsets agree exactly, so the
154
+ * covering window shifts every note onset by a displacement only the
155
+ * expressions show. `changesBetween` makes that visible as readings the
156
+ * window moves; it is the price of one tolerance per derivation, and it
157
+ * is the same skew the grouping stands in for.
146
158
  */
147
159
  export const toleranceAcross = (scatters, named) => {
148
160
  if (scatters.length === 0)
@@ -157,6 +169,26 @@ export const toleranceAcross = (scatters, named) => {
157
169
  toleranceEnd: end.tolerance
158
170
  };
159
171
  };
172
+ /**
173
+ * Which readings two windows disagree about, taken apart by the
174
+ * direction they disagree in.
175
+ *
176
+ * The two are worth seeing separately because they do not cost the
177
+ * same. A separation leaves a visible edit in the apparatus that a
178
+ * reader can challenge; a merge erases a reading and says nothing, and
179
+ * the edition has no way to show what it lost. So the merges are the
180
+ * list to read first, and an edge that only separates is the safer kind
181
+ * of change however many readings it touches.
182
+ *
183
+ * This is what to ask before applying a calculated window, rather than
184
+ * reading `admittedAsStated` off the departures, which sees separations
185
+ * only. An edge both windows agree about throughout needs no
186
+ * re-collation at all, and its tolerance may simply be stated.
187
+ */
188
+ export const changesBetween = (readings, inForce, proposed) => ({
189
+ separated: readings.filter(({ displacement }) => admits(inForce, displacement) && !admits(proposed, displacement)),
190
+ merged: readings.filter(({ displacement }) => !admits(inForce, displacement) && admits(proposed, displacement))
191
+ });
160
192
  const copiesBearing = (view, symbols) => {
161
193
  const tally = symbols.reduce((counts, symbol) => {
162
194
  const bearers = new Set(view.carriersOf(symbol).flatMap(carrier => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linked-rolls",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "Digital editions of piano rolls: import, collation, editorial assumptions, JSON-LD export, and emulation through a reproducing system",
5
5
  "license": "MIT",
6
6
  "repository": {