mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-09-29 16:24:22 +10:00
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
This commit is contained in:
co-authored by
coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Amruth Pillai
parent
c0c658c00c
commit
51ac77295e
@@ -42,16 +42,23 @@ async function listPages(
|
|||||||
try {
|
try {
|
||||||
const doc = await task.promise;
|
const doc = await task.promise;
|
||||||
const pages: string[][] = [];
|
const pages: string[][] = [];
|
||||||
|
const positions: { str: string; x: number; y: number }[][] = [];
|
||||||
for (let n = 1; n <= doc.numPages; n++) {
|
for (let n = 1; n <= doc.numPages; n++) {
|
||||||
const page = await doc.getPage(n);
|
const page = await doc.getPage(n);
|
||||||
const text = await page.getTextContent();
|
const text = await page.getTextContent();
|
||||||
pages.push(text.items.flatMap((item) => ("str" in item && item.str ? [item.str] : [])));
|
pages.push(text.items.flatMap((item) => ("str" in item && item.str ? [item.str] : [])));
|
||||||
|
positions.push(
|
||||||
|
text.items.flatMap((item) =>
|
||||||
|
"str" in item && item.str ? [{ str: item.str, x: item.transform[4], y: item.transform[5] }] : [],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
marker: pages.findIndex((p) => p.some((s) => s.includes("•") || s.startsWith("1."))),
|
marker: pages.findIndex((p) => p.some((s) => s.includes("•") || s.startsWith("1."))),
|
||||||
first: pages.findIndex((p) => p.some((s) => s.includes("TARGET"))),
|
first: pages.findIndex((p) => p.some((s) => s.includes("TARGET"))),
|
||||||
last: pages.findIndex((p) => p.some((s) => s.includes("END"))),
|
last: pages.findIndex((p) => p.some((s) => s.includes("END"))),
|
||||||
pages,
|
pages,
|
||||||
|
positions,
|
||||||
};
|
};
|
||||||
} finally {
|
} finally {
|
||||||
await task.destroy();
|
await task.destroy();
|
||||||
@@ -256,4 +263,40 @@ describe("list marker pagination (#3344)", () => {
|
|||||||
.match(/\bSome\b/g),
|
.match(/\bSome\b/g),
|
||||||
).toHaveLength(30);
|
).toHaveLength(30);
|
||||||
});
|
});
|
||||||
|
it.each(["ul", "ol"])("keeps %s continuation lines at the content indentation", async (tag) => {
|
||||||
|
const result = await listPages(0, 60, "", {
|
||||||
|
html: `<${tag}><li><p>TARGET ${"Some words to fill several lines and force wrapping. ".repeat(60)} END</p></li></${tag}>`,
|
||||||
|
});
|
||||||
|
expect(result.marker).toBe(result.first);
|
||||||
|
expect(result.last).toBeGreaterThan(result.first);
|
||||||
|
// The widest x on the item's first page is its content column; the marker
|
||||||
|
// and the section heading sit further left. Continuation pages must keep it.
|
||||||
|
const contentX = Math.max(...(result.positions[result.first] ?? []).map((item) => item.x));
|
||||||
|
for (const page of result.positions.slice(result.first + 1)) {
|
||||||
|
for (const item of page) expect(item.x).toBeCloseTo(contentX, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("keeps a nested list's inner indentation on continuation pages", async () => {
|
||||||
|
const result = await listPages(0, 1, "", {
|
||||||
|
html: `<ul><li>Outer intro<ul><li><p>TARGET ${"Some words to fill several lines and force wrapping. ".repeat(40)} END</p></li></ul></li></ul>`,
|
||||||
|
});
|
||||||
|
expect(result.last).toBeGreaterThan(result.first);
|
||||||
|
const contentX = Math.max(...(result.positions[result.first] ?? []).map((item) => item.x));
|
||||||
|
for (const page of result.positions.slice(result.first + 1)) {
|
||||||
|
for (const item of page) expect(item.x).toBeCloseTo(contentX, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("preserves a widened ordered-marker column on continuation pages", async () => {
|
||||||
|
const result = await listPages(0, 40, "list-marker { font-size: 24pt; }", {
|
||||||
|
html: `<ol><li><p>TARGET ${"Some words to fill several lines and force wrapping. ".repeat(40)} END</p></li></ol>`,
|
||||||
|
});
|
||||||
|
expect(result.marker).toBe(result.first);
|
||||||
|
expect(result.last).toBeGreaterThan(result.first);
|
||||||
|
const contentX = Math.max(...(result.positions[result.first] ?? []).map((item) => item.x));
|
||||||
|
// The 24pt marker pushes the content column well past the default gutter.
|
||||||
|
expect(contentX).toBeGreaterThan(30);
|
||||||
|
for (const page of result.positions.slice(result.first + 1)) {
|
||||||
|
for (const item of page) expect(item.x).toBeCloseTo(contentX, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
diff --git a/lib/index.js b/lib/index.js
|
diff --git a/lib/index.js b/lib/index.js
|
||||||
index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..8e6117947e87e40dd39f1bf33a1435194cc3f334 100644
|
index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..716ca874d496d40e0709236d4d7fe828a77088a7 100644
|
||||||
--- a/lib/index.js
|
--- a/lib/index.js
|
||||||
+++ b/lib/index.js
|
+++ b/lib/index.js
|
||||||
@@ -1887,7 +1887,7 @@ const isTextInstance$2 = (node) => node.type === P.TextInstance;
|
@@ -1887,7 +1887,7 @@ const isTextInstance$2 = (node) => node.type === P.TextInstance;
|
||||||
@@ -49,7 +49,7 @@ index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..8e6117947e87e40dd39f1bf33a143519
|
|||||||
// But if the current page is empty then we can just include the parent on the current page
|
// But if the current page is empty then we can just include the parent on the current page
|
||||||
if (currentChildren.length === 0) {
|
if (currentChildren.length === 0) {
|
||||||
currentChildren.push(child, ...futureFixedNodes);
|
currentChildren.push(child, ...futureFixedNodes);
|
||||||
@@ -3196,7 +3202,52 @@ const splitChildren = (height, contentArea, node) => {
|
@@ -3196,7 +3202,74 @@ const splitChildren = (height, contentArea, node) => {
|
||||||
};
|
};
|
||||||
const splitView = (node, height, contentArea) => {
|
const splitView = (node, height, contentArea) => {
|
||||||
const [currentNode, nextNode] = splitNode(node, height);
|
const [currentNode, nextNode] = splitNode(node, height);
|
||||||
@@ -99,6 +99,28 @@ index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..8e6117947e87e40dd39f1bf33a143519
|
|||||||
+ if (markerIndex < contentIndex) nextChildren.unshift(nextMarker);
|
+ if (markerIndex < contentIndex) nextChildren.unshift(nextMarker);
|
||||||
+ else nextChildren.push(nextMarker);
|
+ else nextChildren.push(nextMarker);
|
||||||
+ }
|
+ }
|
||||||
|
+ if (markerIndex !== -1 && !hasMarker(nextChildren) && hasText(content(nextChildren))) {
|
||||||
|
+ // The marker was fully consumed on an earlier fragment while the
|
||||||
|
+ // content continues. Page relayout runs Yoga on the remaining
|
||||||
|
+ // children only, so a missing marker collapses the flex gutter and
|
||||||
|
+ // continuation lines shift to the row's left edge. Re-seat an
|
||||||
|
+ // empty marker column pinned to the width Yoga already measured,
|
||||||
|
+ // preserving the authored indentation without drawing a marker.
|
||||||
|
+ const marker = node.children[markerIndex];
|
||||||
|
+ const ghostMarker = {
|
||||||
|
+ ...marker,
|
||||||
|
+ children: [],
|
||||||
|
+ lines: [],
|
||||||
|
+ box: { ...marker.box, top: 0, height: 0 },
|
||||||
|
+ props: { ...marker.props, break: false, minPresenceAhead: 0 },
|
||||||
|
+ style: {
|
||||||
|
+ ...marker.style,
|
||||||
|
+ ...(typeof marker.box?.width === 'number' ? { width: marker.box.width } : {}),
|
||||||
|
+ },
|
||||||
|
+ };
|
||||||
|
+ if (markerIndex < contentIndex) nextChildren.unshift(ghostMarker);
|
||||||
|
+ else nextChildren.push(ghostMarker);
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
return [
|
return [
|
||||||
assingChildren(currentChilds, currentNode),
|
assingChildren(currentChilds, currentNode),
|
||||||
|
|||||||
Generated
+3
-3
@@ -113,7 +113,7 @@ overrides:
|
|||||||
uuid@<11.1.1: ^11.1.1
|
uuid@<11.1.1: ^11.1.1
|
||||||
|
|
||||||
patchedDependencies:
|
patchedDependencies:
|
||||||
'@react-pdf/layout@5.2.0': 0b6c66a14ff45a9b594fcd6c207fcb72dc9608384451803359d36bc8ec5c1245
|
'@react-pdf/layout@5.2.0': 0409efd0fcb399ac0b7e962b4a7f0ab763c82317001a6637b71216cf2fc480b0
|
||||||
'@react-pdf/textkit': e1e963cedc6a2f322b4309c782bba317d2b49bad73da787321151a89491e5d62
|
'@react-pdf/textkit': e1e963cedc6a2f322b4309c782bba317d2b49bad73da787321151a89491e5d62
|
||||||
fontkit@2.0.4: 90f4c51c676a88b91dcc397d60a677c77b5e6dc8e15ffb3538310965ef5c05a4
|
fontkit@2.0.4: 90f4c51c676a88b91dcc397d60a677c77b5e6dc8e15ffb3538310965ef5c05a4
|
||||||
react-pdf-html@2.1.5: e8456fc885241f35e3b642ad6122015b88f855d717663793f5b3293c19afac9b
|
react-pdf-html@2.1.5: e8456fc885241f35e3b642ad6122015b88f855d717663793f5b3293c19afac9b
|
||||||
@@ -11360,7 +11360,7 @@ snapshots:
|
|||||||
jay-peg: 1.1.1
|
jay-peg: 1.1.1
|
||||||
png-js: 2.0.0
|
png-js: 2.0.0
|
||||||
|
|
||||||
'@react-pdf/layout@5.2.0(patch_hash=0b6c66a14ff45a9b594fcd6c207fcb72dc9608384451803359d36bc8ec5c1245)':
|
'@react-pdf/layout@5.2.0(patch_hash=0409efd0fcb399ac0b7e962b4a7f0ab763c82317001a6637b71216cf2fc480b0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@react-pdf/fns': 3.1.3
|
'@react-pdf/fns': 3.1.3
|
||||||
'@react-pdf/image': 3.1.2
|
'@react-pdf/image': 3.1.2
|
||||||
@@ -11401,7 +11401,7 @@ snapshots:
|
|||||||
'@babel/runtime': 7.29.7
|
'@babel/runtime': 7.29.7
|
||||||
'@react-pdf/fns': 3.1.3
|
'@react-pdf/fns': 3.1.3
|
||||||
'@react-pdf/font': 4.1.2
|
'@react-pdf/font': 4.1.2
|
||||||
'@react-pdf/layout': 5.2.0(patch_hash=0b6c66a14ff45a9b594fcd6c207fcb72dc9608384451803359d36bc8ec5c1245)
|
'@react-pdf/layout': 5.2.0(patch_hash=0409efd0fcb399ac0b7e962b4a7f0ab763c82317001a6637b71216cf2fc480b0)
|
||||||
'@react-pdf/primitives': 4.4.0
|
'@react-pdf/primitives': 4.4.0
|
||||||
'@react-pdf/reconciler': 2.0.0(react@19.2.8)
|
'@react-pdf/reconciler': 2.0.0(react@19.2.8)
|
||||||
'@react-pdf/render': 4.7.0
|
'@react-pdf/render': 4.7.0
|
||||||
|
|||||||
Reference in New Issue
Block a user