js.documents 7.1.10 → 7.1.12

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.
@@ -15,8 +15,37 @@ const ZERO_MARGINS = {
15
15
  leftPt: 0
16
16
  };
17
17
  const LINE_BASELINE_TOLERANCE_FACTOR = .5;
18
+ const DUPLICATE_PAINT_BUCKET_PT = .1;
19
+ function duplicatePaintKey(item) {
20
+ const xBucket = Math.round(item.xPt / DUPLICATE_PAINT_BUCKET_PT);
21
+ const yBucket = Math.round(item.yPt / DUPLICATE_PAINT_BUCKET_PT);
22
+ return `${item.text.trim()}|${String(xBucket)}|${String(yBucket)}`;
23
+ }
24
+ function dropDuplicatePaints(items) {
25
+ const seen = /* @__PURE__ */ new Set();
26
+ const kept = [];
27
+ for (const item of items) {
28
+ const key = duplicatePaintKey(item);
29
+ if (seen.has(key)) continue;
30
+ seen.add(key);
31
+ kept.push(item);
32
+ }
33
+ return kept;
34
+ }
35
+ function dropOverlappingRepeatsWithinLine(items) {
36
+ const rightEdgeByText = /* @__PURE__ */ new Map();
37
+ const kept = [];
38
+ for (const item of items) {
39
+ const textKey = item.text.trim();
40
+ const priorRightEdge = rightEdgeByText.get(textKey);
41
+ if (priorRightEdge !== void 0 && item.xPt < priorRightEdge) continue;
42
+ rightEdgeByText.set(textKey, item.xPt + (item.widthPt ?? 0));
43
+ kept.push(item);
44
+ }
45
+ return kept;
46
+ }
18
47
  function clusterIntoLines(items) {
19
- const sorted = [...items].sort((a, b) => b.yPt - a.yPt || a.xPt - b.xPt);
48
+ const sorted = [...dropDuplicatePaints(items)].sort((a, b) => b.yPt - a.yPt || a.xPt - b.xPt);
20
49
  const working = [];
21
50
  for (const item of sorted) {
22
51
  const tolerance = LINE_BASELINE_TOLERANCE_FACTOR * item.sizePt;
@@ -27,7 +56,10 @@ function clusterIntoLines(items) {
27
56
  });
28
57
  else line.items.push(item);
29
58
  }
30
- for (const line of working) line.items.sort((a, b) => a.xPt - b.xPt);
59
+ for (const line of working) {
60
+ line.items.sort((a, b) => a.xPt - b.xPt);
61
+ line.items = dropOverlappingRepeatsWithinLine(line.items);
62
+ }
31
63
  working.sort((a, b) => b.baselineY - a.baselineY);
32
64
  return working;
33
65
  }
@@ -14,8 +14,37 @@ const ZERO_MARGINS = {
14
14
  leftPt: 0
15
15
  };
16
16
  const LINE_BASELINE_TOLERANCE_FACTOR = .5;
17
+ const DUPLICATE_PAINT_BUCKET_PT = .1;
18
+ function duplicatePaintKey(item) {
19
+ const xBucket = Math.round(item.xPt / DUPLICATE_PAINT_BUCKET_PT);
20
+ const yBucket = Math.round(item.yPt / DUPLICATE_PAINT_BUCKET_PT);
21
+ return `${item.text.trim()}|${String(xBucket)}|${String(yBucket)}`;
22
+ }
23
+ function dropDuplicatePaints(items) {
24
+ const seen = /* @__PURE__ */ new Set();
25
+ const kept = [];
26
+ for (const item of items) {
27
+ const key = duplicatePaintKey(item);
28
+ if (seen.has(key)) continue;
29
+ seen.add(key);
30
+ kept.push(item);
31
+ }
32
+ return kept;
33
+ }
34
+ function dropOverlappingRepeatsWithinLine(items) {
35
+ const rightEdgeByText = /* @__PURE__ */ new Map();
36
+ const kept = [];
37
+ for (const item of items) {
38
+ const textKey = item.text.trim();
39
+ const priorRightEdge = rightEdgeByText.get(textKey);
40
+ if (priorRightEdge !== void 0 && item.xPt < priorRightEdge) continue;
41
+ rightEdgeByText.set(textKey, item.xPt + (item.widthPt ?? 0));
42
+ kept.push(item);
43
+ }
44
+ return kept;
45
+ }
17
46
  function clusterIntoLines(items) {
18
- const sorted = [...items].sort((a, b) => b.yPt - a.yPt || a.xPt - b.xPt);
47
+ const sorted = [...dropDuplicatePaints(items)].sort((a, b) => b.yPt - a.yPt || a.xPt - b.xPt);
19
48
  const working = [];
20
49
  for (const item of sorted) {
21
50
  const tolerance = LINE_BASELINE_TOLERANCE_FACTOR * item.sizePt;
@@ -26,7 +55,10 @@ function clusterIntoLines(items) {
26
55
  });
27
56
  else line.items.push(item);
28
57
  }
29
- for (const line of working) line.items.sort((a, b) => a.xPt - b.xPt);
58
+ for (const line of working) {
59
+ line.items.sort((a, b) => a.xPt - b.xPt);
60
+ line.items = dropOverlappingRepeatsWithinLine(line.items);
61
+ }
30
62
  working.sort((a, b) => b.baselineY - a.baselineY);
31
63
  return working;
32
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.documents",
3
- "version": "7.1.10",
3
+ "version": "7.1.12",
4
4
  "description": "Bidirectional docx/pptx <-> PDF conversion and a read+write editable OOXML document model, built on ooxml.js and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -84,12 +84,12 @@
84
84
  "fflate": "^0.8.3",
85
85
  "markdown-codec": "^6.3.4",
86
86
  "odf.js": "^7.1.5",
87
- "ooxml.js": "^7.1.6",
87
+ "ooxml.js": "^8.0.0",
88
88
  "pdf-codec": "^4.0.4",
89
89
  "ppt-codec": "^1.2.5",
90
- "rtf-codec": "^3.0.4",
90
+ "rtf-codec": "^4.0.0",
91
91
  "temml": "0.13.4",
92
- "wpd-codec": "^2.1.5",
92
+ "wpd-codec": "^3.0.0",
93
93
  "xls-codec": "^4.1.5",
94
94
  "zod": "^4.4.3"
95
95
  },