mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-09-29 08:14:25 +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 {
|
||||
const doc = await task.promise;
|
||||
const pages: string[][] = [];
|
||||
const positions: { str: string; x: number; y: number }[][] = [];
|
||||
for (let n = 1; n <= doc.numPages; n++) {
|
||||
const page = await doc.getPage(n);
|
||||
const text = await page.getTextContent();
|
||||
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 {
|
||||
marker: pages.findIndex((p) => p.some((s) => s.includes("•") || s.startsWith("1."))),
|
||||
first: pages.findIndex((p) => p.some((s) => s.includes("TARGET"))),
|
||||
last: pages.findIndex((p) => p.some((s) => s.includes("END"))),
|
||||
pages,
|
||||
positions,
|
||||
};
|
||||
} finally {
|
||||
await task.destroy();
|
||||
@@ -256,4 +263,40 @@ describe("list marker pagination (#3344)", () => {
|
||||
.match(/\bSome\b/g),
|
||||
).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
|
||||
index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..8e6117947e87e40dd39f1bf33a1435194cc3f334 100644
|
||||
index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..716ca874d496d40e0709236d4d7fe828a77088a7 100644
|
||||
--- a/lib/index.js
|
||||
+++ b/lib/index.js
|
||||
@@ -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
|
||||
if (currentChildren.length === 0) {
|
||||
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 [currentNode, nextNode] = splitNode(node, height);
|
||||
@@ -99,6 +99,28 @@ index 18c2618f4630b3c1296c8c3cac317b8d7666bbe8..8e6117947e87e40dd39f1bf33a143519
|
||||
+ if (markerIndex < contentIndex) nextChildren.unshift(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 [
|
||||
assingChildren(currentChilds, currentNode),
|
||||
|
||||
Generated
+3
-3
@@ -113,7 +113,7 @@ overrides:
|
||||
uuid@<11.1.1: ^11.1.1
|
||||
|
||||
patchedDependencies:
|
||||
'@react-pdf/layout@5.2.0': 0b6c66a14ff45a9b594fcd6c207fcb72dc9608384451803359d36bc8ec5c1245
|
||||
'@react-pdf/layout@5.2.0': 0409efd0fcb399ac0b7e962b4a7f0ab763c82317001a6637b71216cf2fc480b0
|
||||
'@react-pdf/textkit': e1e963cedc6a2f322b4309c782bba317d2b49bad73da787321151a89491e5d62
|
||||
fontkit@2.0.4: 90f4c51c676a88b91dcc397d60a677c77b5e6dc8e15ffb3538310965ef5c05a4
|
||||
react-pdf-html@2.1.5: e8456fc885241f35e3b642ad6122015b88f855d717663793f5b3293c19afac9b
|
||||
@@ -11360,7 +11360,7 @@ snapshots:
|
||||
jay-peg: 1.1.1
|
||||
png-js: 2.0.0
|
||||
|
||||
'@react-pdf/layout@5.2.0(patch_hash=0b6c66a14ff45a9b594fcd6c207fcb72dc9608384451803359d36bc8ec5c1245)':
|
||||
'@react-pdf/layout@5.2.0(patch_hash=0409efd0fcb399ac0b7e962b4a7f0ab763c82317001a6637b71216cf2fc480b0)':
|
||||
dependencies:
|
||||
'@react-pdf/fns': 3.1.3
|
||||
'@react-pdf/image': 3.1.2
|
||||
@@ -11401,7 +11401,7 @@ snapshots:
|
||||
'@babel/runtime': 7.29.7
|
||||
'@react-pdf/fns': 3.1.3
|
||||
'@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/reconciler': 2.0.0(react@19.2.8)
|
||||
'@react-pdf/render': 4.7.0
|
||||
|
||||
Reference in New Issue
Block a user