linked-rolls 0.48.0 → 0.49.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/RollCopy.d.ts CHANGED
@@ -259,16 +259,28 @@ export interface RollCopy extends WithType<'RollCopy'>, WithId {
259
259
  */
260
260
  scale: number;
261
261
  /**
262
- * How much longer this copy's reading of a hole ran than the
263
- * perforation that caused it, where that was taken off the ends
264
- * again. A pneumatic reader reports how long a valve stayed
265
- * open, which exceeds the perforation that opened it, so its
266
- * holes are overlong by a constant while its onsets agree.
262
+ * What a pneumatic reader added to this copy's holes, where it
263
+ * was taken off again. Such a reader reports how long a valve
264
+ * stayed open, which exceeds the perforation that opened it, so
265
+ * its holes are overlong by a constant while its onsets agree.
267
266
  * Nothing for a copy read by other means, whose holes are the
268
267
  * punched slots themselves.
269
268
  * Not exported to RDF.
270
269
  */
271
- readerExtension: Millimeters;
270
+ readerExtension: {
271
+ /** How much longer the reading of a hole ran than the perforation that caused it. */
272
+ length: Millimeters;
273
+ /**
274
+ * The holes it was not taken off, by `@id`, being no longer
275
+ * than it is. The constant reaches its limit there rather
276
+ * than the copy being wrong, and why they were left is for
277
+ * the edition to state about the features themselves; this
278
+ * only records that they stand as the reader gave them, so
279
+ * that putting the extension back does not lengthen a hole
280
+ * nothing was taken from.
281
+ */
282
+ leaving?: string[];
283
+ };
272
284
  /**
273
285
  * The resolution this copy's scan was read at, along the roll.
274
286
  * It is what the measurements given in pixels are to be read
@@ -44,9 +44,20 @@ export declare const revertScale: (copy: RollCopy) => void;
44
44
  * on the feature, a reading of the hole, a smaller extension — and
45
45
  * `shortenHoles` throws rather than answer it.
46
46
  */
47
- export declare const tooShortToShorten: (extension: Millimeters, copy: RollCopy) => Readonly<FeatureOrPatch>[];
48
- export declare const shortenHoles: (extension: Millimeters, copy: RollCopy) => void;
49
- /** Puts the reader's extension back on the copy's holes, as far as one was taken off. */
47
+ export declare const tooShortToShorten: (extension: Millimeters, copy: RollCopy, leaving?: ReadonlySet<string>) => Readonly<FeatureOrPatch>[];
48
+ /**
49
+ * Takes the extension off, leaving the named holes as the reader gave
50
+ * them. Naming a hole is an editorial act and not a repair: it says
51
+ * this one is where the constant stops applying, and the edition is
52
+ * what has to say why. The copy records which were left, so that
53
+ * putting the extension back does not lengthen a hole nothing was
54
+ * taken from.
55
+ *
56
+ * Throws where a hole that was not named is no longer than the
57
+ * extension, `tooShortToShorten` saying beforehand which those are.
58
+ */
59
+ export declare const shortenHoles: (extension: Millimeters, copy: RollCopy, leaving?: ReadonlySet<string>) => void;
60
+ /** Puts the reader's extension back on the holes it was taken off, as far as one was taken off. */
50
61
  export declare const revertShortening: (copy: RollCopy) => void;
51
62
  /**
52
63
  * How a copy's places are carried onto another copy's:
package/lib/alignment.js CHANGED
@@ -90,26 +90,43 @@ const holesOf = (copy) => featuresOf(copy).filter(feature => feature.type === 'H
90
90
  * on the feature, a reading of the hole, a smaller extension — and
91
91
  * `shortenHoles` throws rather than answer it.
92
92
  */
93
- export const tooShortToShorten = (extension, copy) => holesOf(copy).filter(hole => hole.horizontal.to - hole.horizontal.from <= extension);
94
- export const shortenHoles = (extension, copy) => {
93
+ export const tooShortToShorten = (extension, copy, leaving = new Set()) => holesOf(copy).filter(hole => !leaving.has(hole.id) && hole.horizontal.to - hole.horizontal.from <= extension);
94
+ /**
95
+ * Takes the extension off, leaving the named holes as the reader gave
96
+ * them. Naming a hole is an editorial act and not a repair: it says
97
+ * this one is where the constant stops applying, and the edition is
98
+ * what has to say why. The copy records which were left, so that
99
+ * putting the extension back does not lengthen a hole nothing was
100
+ * taken from.
101
+ *
102
+ * Throws where a hole that was not named is no longer than the
103
+ * extension, `tooShortToShorten` saying beforehand which those are.
104
+ */
105
+ export const shortenHoles = (extension, copy, leaving = new Set()) => {
95
106
  if (copy.ops.includes('shortened'))
96
107
  return;
97
- const tooShort = tooShortToShorten(extension, copy);
108
+ const tooShort = tooShortToShorten(extension, copy, leaving);
98
109
  if (tooShort.length > 0) {
99
110
  throw new Error(`The extension of ${extension} mm cannot be taken off ${tooShort.length} `
100
111
  + `hole(s) of copy ${copy.id}, which are no longer than it: `
101
112
  + `${tooShort.map(hole => hole.id).join(', ')}`);
102
113
  }
103
- holesOf(copy).forEach(hole => { hole.horizontal.to = subtract(hole.horizontal.to, extension); });
114
+ const left = holesOf(copy).filter(hole => leaving.has(hole.id)).map(hole => hole.id);
115
+ holesOf(copy)
116
+ .filter(hole => !leaving.has(hole.id))
117
+ .forEach(hole => { hole.horizontal.to = subtract(hole.horizontal.to, extension); });
104
118
  copy.ops = [...copy.ops, 'shortened'];
105
- copy.measurements.readerExtension = extension;
119
+ copy.measurements.readerExtension = { length: extension, ...(left.length > 0 && { leaving: left }) };
106
120
  };
107
- /** Puts the reader's extension back on the copy's holes, as far as one was taken off. */
121
+ /** Puts the reader's extension back on the holes it was taken off, as far as one was taken off. */
108
122
  export const revertShortening = (copy) => {
109
- const extension = copy.measurements.readerExtension;
110
- if (!copy.ops.includes('shortened') || extension === undefined)
123
+ const taken = copy.measurements.readerExtension;
124
+ if (!copy.ops.includes('shortened') || taken === undefined)
111
125
  return;
112
- holesOf(copy).forEach(hole => { hole.horizontal.to = add(hole.horizontal.to, extension); });
126
+ const left = new Set(taken.leaving ?? []);
127
+ holesOf(copy)
128
+ .filter(hole => !left.has(hole.id))
129
+ .forEach(hole => { hole.horizontal.to = add(hole.horizontal.to, taken.length); });
113
130
  copy.ops = copy.ops.filter(op => op !== 'shortened');
114
131
  delete copy.measurements.readerExtension;
115
132
  };
@@ -46,7 +46,7 @@ export declare const unalignCopy: (copyId: string) => EditionOp;
46
46
  * copy's holes, and records how much was taken, so that its lengths
47
47
  * can be compared with a scanned copy's at all.
48
48
  */
49
- export declare const shortenCopy: (copyId: string, extension: Millimeters) => EditionOp;
49
+ export declare const shortenCopy: (copyId: string, extension: Millimeters, leaving?: ReadonlySet<string>) => EditionOp;
50
50
  /** Puts the reader's extension back on the copy's holes. */
51
51
  export declare const unshortenCopy: (copyId: string) => EditionOp;
52
52
  /** States what the copy's features were read from, in place of any earlier statement. */
package/lib/editionOps.js CHANGED
@@ -141,7 +141,7 @@ export const unalignCopy = (copyId) => onCopy(copyId, copy => {
141
141
  * copy's holes, and records how much was taken, so that its lengths
142
142
  * can be compared with a scanned copy's at all.
143
143
  */
144
- export const shortenCopy = (copyId, extension) => onCopy(copyId, copy => shortenHoles(extension, copy));
144
+ export const shortenCopy = (copyId, extension, leaving) => onCopy(copyId, copy => shortenHoles(extension, copy, leaving));
145
145
  /** Puts the reader's extension back on the copy's holes. */
146
146
  export const unshortenCopy = (copyId) => onCopy(copyId, copy => revertShortening(copy));
147
147
  /** States what the copy's features were read from, in place of any earlier statement. */
package/lib/schema.json CHANGED
@@ -2829,8 +2829,24 @@
2829
2829
  "ontology": "reo:punchDiameter"
2830
2830
  },
2831
2831
  "readerExtension": {
2832
- "$ref": "#/definitions/Millimeters",
2833
- "description": "How much longer this copy's reading of a hole ran than the perforation that caused it, where that was taken off the ends again. A pneumatic reader reports how long a valve stayed open, which exceeds the perforation that opened it, so its holes are overlong by a constant while its onsets agree. Nothing for a copy read by other means, whose holes are the punched slots themselves. Not exported to RDF."
2832
+ "description": "What a pneumatic reader added to this copy's holes, where it was taken off again. Such a reader reports how long a valve stayed open, which exceeds the perforation that opened it, so its holes are overlong by a constant while its onsets agree. Nothing for a copy read by other means, whose holes are the punched slots themselves. Not exported to RDF.",
2833
+ "properties": {
2834
+ "leaving": {
2835
+ "description": "The holes it was not taken off, by `@id`, being no longer than it is. The constant reaches its limit there rather than the copy being wrong, and why they were left is for the edition to state about the features themselves; this only records that they stand as the reader gave them, so that putting the extension back does not lengthen a hole nothing was taken from.",
2836
+ "items": {
2837
+ "type": "string"
2838
+ },
2839
+ "type": "array"
2840
+ },
2841
+ "length": {
2842
+ "$ref": "#/definitions/Millimeters",
2843
+ "description": "How much longer the reading of a hole ran than the perforation that caused it."
2844
+ }
2845
+ },
2846
+ "required": [
2847
+ "length"
2848
+ ],
2849
+ "type": "object"
2834
2850
  },
2835
2851
  "scale": {
2836
2852
  "description": "The factor this copy's features were scaled by to align them with the others. What it is put down to is stated apart: a paper-stretch condition, or the speed the copy was cut for. Not exported to RDF.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linked-rolls",
3
- "version": "0.48.0",
3
+ "version": "0.49.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": {