diff --git a/docs/reports/Viewclinic_AI_Answer_Readiness_Report_v2_표준캔버스.pdf b/docs/reports/Viewclinic_AI_Answer_Readiness_Report_v2_표준캔버스.pdf new file mode 100644 index 0000000..b15f9d4 Binary files /dev/null and b/docs/reports/Viewclinic_AI_Answer_Readiness_Report_v2_표준캔버스.pdf differ diff --git a/docs/reports/Viewclinic_AI_Answer_Readiness_Report_v2_표준캔버스.pptx b/docs/reports/Viewclinic_AI_Answer_Readiness_Report_v2_표준캔버스.pptx new file mode 100644 index 0000000..9fe9176 Binary files /dev/null and b/docs/reports/Viewclinic_AI_Answer_Readiness_Report_v2_표준캔버스.pptx differ diff --git a/docs/reports/Viewclinic_POC_Proposal_v2_표준캔버스.pdf b/docs/reports/Viewclinic_POC_Proposal_v2_표준캔버스.pdf new file mode 100644 index 0000000..36283ef Binary files /dev/null and b/docs/reports/Viewclinic_POC_Proposal_v2_표준캔버스.pdf differ diff --git a/docs/reports/Viewclinic_POC_Proposal_v2_표준캔버스.pptx b/docs/reports/Viewclinic_POC_Proposal_v2_표준캔버스.pptx new file mode 100644 index 0000000..afe695a Binary files /dev/null and b/docs/reports/Viewclinic_POC_Proposal_v2_표준캔버스.pptx differ diff --git a/scripts/rescale_deck.py b/scripts/rescale_deck.py new file mode 100644 index 0000000..da89c54 --- /dev/null +++ b/scripts/rescale_deck.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +"""PPTX 덱을 균등 배율로 축소/확대한다 (좌표·폰트·선굵기·여백 전부). + +INFINITH 덱(20x11.25in)은 표준 캔버스(13.33x7.5in)의 1.5배라 폰트 pt 숫자가 +1.5배 부풀려져 있다. 2/3로 균등 축소하면 화면 모습은 동일하고 pt는 표준이 된다. +원본은 덮어쓰지 않는다. 반드시 새 파일로 저장한다. + + python3 scripts/rescale_deck.py [배율=0.6667] +""" +import sys +from fractions import Fraction + +from pptx import Presentation + +NS = "{http://schemas.openxmlformats.org/drawingml/2006/main}" + +# EMU 좌표 속성 (요소 태그 → 속성들) +GEOM = { + f"{NS}off": ("x", "y"), + f"{NS}ext": ("cx", "cy"), + f"{NS}chOff": ("x", "y"), + f"{NS}chExt": ("cx", "cy"), +} +# 폰트 크기(1/100pt) 속성을 갖는 요소 +SZ_TAGS = {f"{NS}rPr", f"{NS}defRPr", f"{NS}endParaRPr"} +# 텍스트 프레임 안쪽 여백(EMU) +BODYPR_ATTRS = ("lIns", "tIns", "rIns", "bIns") + + +def scale_int(v, f): + return str(int(round(int(v) * f))) + + +def scale_tree(root, f): + for el in root.iter(): + tag = el.tag + if tag in GEOM: + for a in GEOM[tag]: + if el.get(a) is not None: + el.set(a, scale_int(el.get(a), f)) + elif tag in SZ_TAGS: + if el.get("sz") is not None: + el.set("sz", scale_int(el.get("sz"), f)) + elif tag == f"{NS}ln": + if el.get("w") is not None: + el.set("w", scale_int(el.get("w"), f)) + elif tag == f"{NS}bodyPr": + for a in BODYPR_ATTRS: + if el.get(a) is not None: + el.set(a, scale_int(el.get(a), f)) + elif tag == f"{NS}spcPts": + if el.get("val") is not None: + el.set("val", scale_int(el.get("val"), f)) + + +def main(): + src, dst = sys.argv[1], sys.argv[2] + f = float(sys.argv[3]) if len(sys.argv) > 3 else float(Fraction(2, 3)) + if src == dst: + sys.exit("원본 덮어쓰기 금지. 출력 파일명을 다르게 지정하세요.") + prs = Presentation(src) + prs.slide_width = int(round(prs.slide_width * f)) + prs.slide_height = int(round(prs.slide_height * f)) + for slide in prs.slides: + scale_tree(slide._element, f) + for layout in prs.slide_layouts: + scale_tree(layout._element, f) + for master in prs.slide_masters: + scale_tree(master._element, f) + prs.save(dst) + print(f"저장: {dst} ({prs.slide_width/914400:.3f} x {prs.slide_height/914400:.3f} in, 배율 {f:.4f})") + + +if __name__ == "__main__": + main()