S5-5: centralized part-box synthesis (band-y x content-margins)
Add synthesize_part_box() as the single authoritative S5 part-box projection (T3 swap point): content-margin x-extent x part-band y-extent, BOTTOMLEFT coords; label_box retained as a separate anchor. build() attaches box per part. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
@@ -44,6 +44,34 @@ def _furn_kind(it):
|
||||
return "chrome_text"
|
||||
|
||||
|
||||
def synthesize_part_box(part_band, content_x_band):
|
||||
"""Return the one authoritative S5 part-box projection.
|
||||
|
||||
Parts remain boxes in S5, but the box is a projection rather than intrinsic
|
||||
geometry: document content margins provide the x-extent and the part band
|
||||
provides y. The band end is already bounded by the next part in bands.py;
|
||||
the original label box remains a separate anchor for rendering/review.
|
||||
|
||||
Coordinates stay in the first-pass PDF-point BOTTOMLEFT bbox shape.
|
||||
"""
|
||||
if not content_x_band:
|
||||
return None
|
||||
try:
|
||||
x_left = content_x_band["x_left"]
|
||||
x_right = content_x_band["x_right"]
|
||||
y_start = part_band["y_start"]
|
||||
y_end = part_band["y_end"]
|
||||
except KeyError:
|
||||
return None
|
||||
return {
|
||||
"l": round(x_left, 1),
|
||||
"t": round(y_start, 1),
|
||||
"r": round(x_right, 1),
|
||||
"b": round(y_end, 1),
|
||||
"coord_origin": "BOTTOMLEFT",
|
||||
}
|
||||
|
||||
|
||||
def build(structured, bands, furniture, pdf=None, page_roles=None):
|
||||
page_roles = page_roles or {}
|
||||
part_bbox = {p["label"]: p.get("bbox")
|
||||
@@ -124,10 +152,15 @@ def build(structured, bands, furniture, pdf=None, page_roles=None):
|
||||
main = [{"question": m["question"], "y_start": m["y_start"], "y_end": m["y_end"],
|
||||
"is_start": m.get("is_start", True),
|
||||
"source": "auto", "confirmed": False} for m in pb["main"]]
|
||||
part = [{"label": p["label"], "question": p["question"],
|
||||
"y_start": p["y_start"], "y_end": p["y_end"],
|
||||
"label_box": part_bbox.get(p["label"]), # app may render a box instead of lines
|
||||
"source": "auto", "confirmed": False} for p in pb["part"]]
|
||||
part = []
|
||||
for p in pb["part"]:
|
||||
part.append({
|
||||
"label": p["label"], "question": p["question"],
|
||||
"y_start": p["y_start"], "y_end": p["y_end"],
|
||||
"label_box": part_bbox.get(p["label"]), # anchor, not the part extent
|
||||
"box": synthesize_part_box(p, xband),
|
||||
"source": "auto", "confirmed": False,
|
||||
})
|
||||
pr = page_roles.get(pgs) or page_roles.get(pg) or {}
|
||||
pages[pgs] = {
|
||||
"role": pr.get("role", "question"),
|
||||
|
||||
Reference in New Issue
Block a user