@uurtech/jdf-cli 0.2.0 → 0.2.1
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/dist/index.js +95 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1699,6 +1699,10 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1699
1699
|
if (arr) arr.push(op);
|
|
1700
1700
|
else opBins.set(key, [op]);
|
|
1701
1701
|
}
|
|
1702
|
+
const sizePenalty = (op, fontSize) => {
|
|
1703
|
+
if (!op.fontSize || !fontSize) return 0;
|
|
1704
|
+
return Math.abs(Math.log(op.fontSize / fontSize)) * 6;
|
|
1705
|
+
};
|
|
1702
1706
|
const findOp = (x, y, fontSize) => {
|
|
1703
1707
|
let best = null;
|
|
1704
1708
|
let bestD = Infinity;
|
|
@@ -1708,7 +1712,7 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1708
1712
|
const arr = opBins.get(`${bx + dx},${by + dy}`);
|
|
1709
1713
|
if (!arr) continue;
|
|
1710
1714
|
for (const op of arr) {
|
|
1711
|
-
const d = Math.hypot(op.x - x, op.y - y);
|
|
1715
|
+
const d = Math.hypot(op.x - x, op.y - y) + sizePenalty(op, fontSize);
|
|
1712
1716
|
if (d < bestD) {
|
|
1713
1717
|
bestD = d;
|
|
1714
1718
|
best = op;
|
|
@@ -1718,8 +1722,9 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1718
1722
|
}
|
|
1719
1723
|
if (best) return best;
|
|
1720
1724
|
const tol = Math.max(2, fontSize * 0.6);
|
|
1725
|
+
const sizeOk = (op) => !op.fontSize || !fontSize || op.fontSize / fontSize > 0.6 && op.fontSize / fontSize < 1.7;
|
|
1721
1726
|
for (const op of ops.textOps) {
|
|
1722
|
-
if (Math.abs(op.y - y) > tol) continue;
|
|
1727
|
+
if (!sizeOk(op) || Math.abs(op.y - y) > tol) continue;
|
|
1723
1728
|
const d = Math.abs(op.x - x) + Math.abs(op.y - y) * 4;
|
|
1724
1729
|
if (d < bestD) {
|
|
1725
1730
|
bestD = d;
|
|
@@ -1728,6 +1733,7 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1728
1733
|
}
|
|
1729
1734
|
if (best) return best;
|
|
1730
1735
|
for (const op of ops.textOps) {
|
|
1736
|
+
if (!sizeOk(op)) continue;
|
|
1731
1737
|
const d = Math.hypot(op.x - x, op.y - y);
|
|
1732
1738
|
if (d < bestD) {
|
|
1733
1739
|
bestD = d;
|
|
@@ -1746,6 +1752,7 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1746
1752
|
const conv = viewport.convertToViewportPoint(baseX, baseY);
|
|
1747
1753
|
const vx = safeNum(conv?.[0], 0);
|
|
1748
1754
|
const vy = safeNum(conv?.[1], 0);
|
|
1755
|
+
if (fontSize < 1.5) return;
|
|
1749
1756
|
const op = findOp(vx, vy, fontSize);
|
|
1750
1757
|
const mode = op?.mode ?? 0;
|
|
1751
1758
|
if (mode === 7) return;
|
|
@@ -1869,10 +1876,92 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1869
1876
|
sizeChars.set(k, (sizeChars.get(k) ?? 0) + l.text.length);
|
|
1870
1877
|
}
|
|
1871
1878
|
const bodyFontSize = [...sizeChars.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] ?? 0;
|
|
1879
|
+
const rowOf = /* @__PURE__ */ new Map();
|
|
1880
|
+
const rowStartOf = /* @__PURE__ */ new Map();
|
|
1881
|
+
const nextOnRow = /* @__PURE__ */ new Map();
|
|
1882
|
+
{
|
|
1883
|
+
const order = lines.map((_, i) => i).filter((i) => !consumedLines.has(i));
|
|
1884
|
+
for (let a = 0; a < order.length; a++) {
|
|
1885
|
+
const i = order[a], li = lines[i];
|
|
1886
|
+
const tolY = Math.max(0.6, li.fontSize * PT_TO_MM2 * 0.35);
|
|
1887
|
+
let bestNext = -1, bestX = Infinity;
|
|
1888
|
+
for (let b = 0; b < order.length; b++) {
|
|
1889
|
+
const j = order[b], lj = lines[j];
|
|
1890
|
+
if (j === i || Math.abs(lj.y - li.y) > tolY || lj.x <= li.x) continue;
|
|
1891
|
+
if (lj.x < bestX) {
|
|
1892
|
+
bestX = lj.x;
|
|
1893
|
+
bestNext = j;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
if (bestNext >= 0) nextOnRow.set(i, bestNext);
|
|
1897
|
+
}
|
|
1898
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1899
|
+
for (const i of order) {
|
|
1900
|
+
if (seen.has(i)) continue;
|
|
1901
|
+
const row = [i];
|
|
1902
|
+
seen.add(i);
|
|
1903
|
+
let cur = i;
|
|
1904
|
+
while (nextOnRow.has(cur)) {
|
|
1905
|
+
const j = nextOnRow.get(cur), lc = lines[cur], lj = lines[j];
|
|
1906
|
+
const em = Math.min(lc.fontSize, lj.fontSize) * PT_TO_MM2;
|
|
1907
|
+
const gap = lj.x - (lc.x + lc.width);
|
|
1908
|
+
if (gap < -em * 0.3 || gap > em * 0.6) break;
|
|
1909
|
+
row.push(j);
|
|
1910
|
+
seen.add(j);
|
|
1911
|
+
cur = j;
|
|
1912
|
+
}
|
|
1913
|
+
rowOf.set(i, row);
|
|
1914
|
+
for (const j of row) rowStartOf.set(j, i);
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
const runStyle = (l) => {
|
|
1918
|
+
const cls = fontMap.get(l.fontName) || classifyFont(l.fontName || "");
|
|
1919
|
+
return { cls, bold: cls.weight === "bold", italic: cls.style === "italic" };
|
|
1920
|
+
};
|
|
1872
1921
|
lines.forEach((l, lineIdx) => {
|
|
1873
1922
|
const tableEl = tableAtLine.get(lineIdx);
|
|
1874
1923
|
if (tableEl) elements.push(tableEl);
|
|
1875
1924
|
if (consumedLines.has(lineIdx)) return;
|
|
1925
|
+
const row = rowOf.get(lineIdx);
|
|
1926
|
+
if (!row) return;
|
|
1927
|
+
if (row.length > 1) {
|
|
1928
|
+
const first = lines[row[0]], last = lines[row[row.length - 1]];
|
|
1929
|
+
const base = runStyle(first);
|
|
1930
|
+
const rowEnd = last.x + last.width;
|
|
1931
|
+
const measuredW = Math.max((rowEnd - first.x) * 1.2 + first.fontSize * PT_TO_MM2 * 0.4, first.fontSize * PT_TO_MM2);
|
|
1932
|
+
const nextIdx2 = nextOnRow.get(row[row.length - 1]);
|
|
1933
|
+
const cap2 = nextIdx2 != null ? lines[nextIdx2].x - first.x - first.fontSize * PT_TO_MM2 * 0.3 : pageWmm - first.x;
|
|
1934
|
+
const runs2 = [];
|
|
1935
|
+
row.forEach((idx, k) => {
|
|
1936
|
+
const r = lines[idx];
|
|
1937
|
+
const st = runStyle(r);
|
|
1938
|
+
let text2 = r.text;
|
|
1939
|
+
if (k > 0) {
|
|
1940
|
+
const prev2 = lines[row[k - 1]];
|
|
1941
|
+
const gap = r.x - (prev2.x + prev2.width);
|
|
1942
|
+
if (gap > r.fontSize * PT_TO_MM2 * 0.08 && !/\s$/.test(prev2.text) && !/^\s/.test(text2)) text2 = " " + text2;
|
|
1943
|
+
}
|
|
1944
|
+
const run = { text: text2 };
|
|
1945
|
+
if (st.bold) run.bold = true;
|
|
1946
|
+
if (st.italic) run.italic = true;
|
|
1947
|
+
if (r.color !== "#000000") run.color = r.color;
|
|
1948
|
+
if (Math.abs(r.fontSize - first.fontSize) >= 0.5) run.fontSize = Math.round(r.fontSize * 10) / 10;
|
|
1949
|
+
if (st.cls.family !== base.cls.family) run.fontFamily = st.cls.family;
|
|
1950
|
+
const lk = findLinkForRun2(r);
|
|
1951
|
+
if (lk) run.link = lk.url ? lk.url : lk.destPage != null ? { type: "internal", target: `#page-${lk.destPage + 1}` } : void 0;
|
|
1952
|
+
runs2.push(run);
|
|
1953
|
+
});
|
|
1954
|
+
const style2 = { fontSize: Math.round(first.fontSize * 10) / 10, fontFamily: base.cls.family };
|
|
1955
|
+
if (first.opacity < 0.999) style2.opacity = Math.round(first.opacity * 100) / 100;
|
|
1956
|
+
elements.push({
|
|
1957
|
+
type: "richtext",
|
|
1958
|
+
runs: runs2,
|
|
1959
|
+
position: { x: Math.max(0, Math.round(first.x * 100) / 100), y: Math.max(0, Math.round(Math.min(...row.map((i) => lines[i].y)) * 100) / 100) },
|
|
1960
|
+
width: Math.max(2, Math.round(Math.max(first.fontSize * PT_TO_MM2, Math.min(measuredW, cap2)) * 100) / 100),
|
|
1961
|
+
style: style2
|
|
1962
|
+
});
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1876
1965
|
const cls = fontMap.get(l.fontName) || classifyFont(l.fontName || "");
|
|
1877
1966
|
const style = {
|
|
1878
1967
|
fontSize: Math.round(l.fontSize * 10) / 10,
|
|
@@ -1883,9 +1972,11 @@ async function importPdfToJdf(source, title, runtime, options = {}) {
|
|
|
1883
1972
|
if (l.color !== "#000000") style.color = l.color;
|
|
1884
1973
|
if (l.opacity < 0.999) style.opacity = Math.round(l.opacity * 100) / 100;
|
|
1885
1974
|
const link = findLinkForRun2(l);
|
|
1886
|
-
const measured = Math.max(l.width + l.fontSize * PT_TO_MM2 * 0.4, l.fontSize * PT_TO_MM2);
|
|
1975
|
+
const measured = Math.max(l.width * 1.2 + l.fontSize * PT_TO_MM2 * 0.4, l.fontSize * PT_TO_MM2);
|
|
1887
1976
|
const remaining = Math.max(measured, pageWmm - l.x);
|
|
1888
|
-
const
|
|
1977
|
+
const nextIdx = nextOnRow.get(lineIdx);
|
|
1978
|
+
const cap = nextIdx != null ? Math.max(l.fontSize * PT_TO_MM2, lines[nextIdx].x - l.x - l.fontSize * PT_TO_MM2 * 0.3) : Infinity;
|
|
1979
|
+
const elWidth = Math.min(measured, remaining, cap);
|
|
1889
1980
|
const text = {
|
|
1890
1981
|
type: "text",
|
|
1891
1982
|
content: l.text,
|