# figma2pptx Figma 프레임을 **편집 가능한 PowerPoint(.pptx)** 로 변환합니다. 텍스트는 텍스트 상자로, 도형·표선은 실제 도형으로 들어가므로 PPT에서 그대로 수정할 수 있습니다. --- ## 3분 설치 (맥) **1. 터미널에 이 한 줄을 붙여넣으세요** ```bash curl -fsSL https://raw.githubusercontent.com/hoonlamb/figma2pptx/main/setup.sh | bash ``` Git도 관리자 비밀번호도 필요 없습니다. Node가 없으면 설치 폴더 안에 알아서 받습니다. **AI한테 맡겨도 됩니다.** 클로드 코드나 코덱스에 아래를 그대로 붙여넣으세요. ```text https://github.com/hoonlamb/figma2pptx 를 내 맥에 설치해줘. README대로 setup.sh를 실행하고, 끝나면 피그마 토큰 만드는 법을 한 단계씩 알려줘. 권한은 file_content:read 하나만 고르게 해줘. 토큰은 채팅에 붙여넣지 말고 변환기 화면에 직접 넣게 안내해줘. 다 되면 바탕화면 figma2pptx.command를 열어줘. ``` **2. 피그마 토큰 만들기** Figma → Settings → Security → Personal access tokens → Generate new token 권한은 **`file_content:read` 하나만** 체크하세요. `file_comments:read`와 이름이 비슷하니 조심하세요. **3. 바탕화면의 `figma2pptx.command` 더블클릭** 처음 열면 토큰을 물어봅니다. 그다음 피그마에서 섹션이나 프레임을 고르고 링크를 복사해 붙여넣으면 됩니다. ### 알아 둘 것 - **서체:** 피그마에서 쓴 서체가 이 맥에 설치돼 있어야 합니다. 없으면 리포트에 알려 줍니다. - **자동 비교:** Microsoft PowerPoint와 맥 개발 도구(`xcode-select --install`)가 있어야 합니다. 없어도 변환은 됩니다. 처음 비교할 때 PowerPoint 제어를 허용할지 묻습니다. - **토큰:** 내 맥의 `.env`에만 저장되고 api.figma.com 외에는 보내지 않습니다. 변환도 전부 내 맥에서 돌아갑니다. 파일 내용은 피그마 API에서 받습니다. --- ## 사용법 ### 더블클릭 바탕화면의 **figma2pptx.command** 를 더블클릭하세요. 터미널 창이 뜨고 브라우저가 자동으로 열립니다. Figma 링크를 붙여넣고 **변환 시작**을 누르면 됩니다. **끄려면 그 터미널 창을 닫거나 Control+C** 를 누르세요 — 창의 수명이 곧 서버의 수명입니다. ### 터미널을 아예 안 거치고 싶다면 (권장) ```bash cd ~/figma2pptx && bash install.sh --autostart ``` 로그인할 때 서버가 자동으로 뜹니다. 이후로는 **크롬 북마크(`http://127.0.0.1:4785`)만 누르면** 끝입니다. 이 모드에서는 서버를 launchd가 관리하므로 웹 화면의 [프로그램 종료] 버튼이 숨겨집니다. 해제는 `bash install.sh --no-autostart`. ### 터미널 ```bash figma2pptx ``` 인자 없이 치면 위와 똑같이 GUI가 열립니다. 링크를 붙이면 곧바로 변환합니다: ```bash figma2pptx "https://www.figma.com/design/파일키/이름?node-id=1234-5678" -o ~/Desktop ``` | 옵션 | 설명 | |---|---| | `-o, --out` | 저장 폴더 (기본: 현재 폴더) | | `-n, --name` | 파일 이름 (기본: 섹션/페이지 이름) | | `-c, --config` | 설정 JSON 경로 | | `--no-verify` | 변환 후 렌더 비교 생략 (빠름) | **링크는 무엇을 가리켜야 하나요** Figma에서 변환할 **섹션이나 프레임을 선택**한 뒤 링크를 복사하세요. - 섹션을 선택 → 섹션 안의 모든 프레임이 슬라이드가 됩니다 - 프레임 하나를 선택 → 그 프레임만 1장으로 변환됩니다 - `node-id` 없는 링크 → 첫 페이지의 모든 최상위 프레임 프레임은 캔버스에 놓인 순서(위→아래, 왼→오른쪽)대로 슬라이드가 됩니다. --- ## 자동 검수 변환이 끝나면 결과 PPT를 **PowerPoint로 실제 렌더링**해서 Figma 원본 이미지와 페이지별로 비교합니다. 차이가 큰 페이지는 리포트에 ⚠️로 표시됩니다. ### 저장되는 것 기본 저장 위치는 **`~/Desktop/figma2pptx/`** 이고, 변환할 때마다 문서 이름으로 폴더가 하나 생깁니다. 결과물·리포트·검수 이미지가 항상 같은 폴더에 함께 있으므로 데스크탑에 흩어지지 않습니다. ``` ~/Desktop/figma2pptx/ Section 1/ Section 1.pptx ← 결과물 Section 1.report.md ← 성적표 Section 1 검수/ ← ⚠️ 페이지가 있을 때만 생깁니다 figma-003.png 원본 ppt-003.png 변환 결과 diff-003.png 다른 부분(빨간색) ``` **전부 통과하면 검수 폴더는 남지 않습니다.** 11장짜리 문서 하나가 이미지 33장 ≈ 35MB라, 볼 필요 없는 것까지 두면 저장 폴더가 금방 지저분해집니다. 전부 보고 싶으면 `config`에서 `verify.keepImages`를 `"all"`로, 아예 안 남기려면 `"none"`으로 바꾸세요. 폴더 이름에 문서 이름이 들어가고 매번 새로 만들므로, 여러 문서를 같은 폴더에 변환해도 섞이지 않습니다. ### 차이 몇 %가 정상인가요 **0~3%면 정상입니다.** Figma와 PowerPoint는 서로 다른 프로그램이라 글자 외곽선을 미세하게 다르게 그립니다. 디프 이미지에서 배경은 회색이고 글자 테두리만 빨갛다면 잘 된 겁니다. 무언가 밀렸거나 빠졌다면 그보다 훨씬 큰 숫자가 나옵니다. 기준선은 `verify.diffThreshold`(기본 0.04 = 4%)입니다. 리포트(`*.report.md`)에 함께 담기는 것: - 슬라이드·텍스트·도형·이미지 개수 - 설치되지 않은 서체 - **서체 폭 차이** — 아래 설명 - 단색으로 근사한 그라디언트, 생략한 그림자 등 ### 서체 폭 차이 (가장 먼저 볼 항목) 디자인이 A 서체로 폭을 재고 PPT는 B 서체로 조판하면, **글자에 딱 맞춰 그린 것들이 전부 어긋납니다.** 칩이 라벨보다 넓어져 글자가 한쪽으로 쏠리고, 균등하게 잡은 간격이 들쭉날쭉해집니다. 변환할 때마다 CoreText로 **PPT가 실제로 쓸 서체의 글자 폭**을 재서, 디자인이 기록한 폭과 얼마나 다른지 리포트에 남깁니다. ``` ## 서체 폭 차이 - 차이가 난 텍스트 42개 (더 넓게 조판 8개) - 최대 차이 -3.6px - -3.6px Slide 3 «공통사항» ``` **차이가 크면** 원본 피그마에서 그 서체로 다시 조판한 뒤 변환하는 게 가장 깔끔합니다. (예: 디자인은 Noto Sans KR인데 PPT는 Pretendard로 나가는 상황 — `familyMap`으로 이름만 바꾸면 글자 폭까지 따라오지는 않습니다.) 렌더 비교에는 Microsoft PowerPoint(없으면 LibreOffice)가 필요합니다. 둘 다 없으면 비교만 건너뛰고 변환은 정상 진행됩니다. --- ## 설정 `config/default.json`을 복사해 수정한 뒤 `-c` 옵션으로 넘기면 됩니다. ```jsonc { "fonts": { "familyMap": { "Noto Sans KR": "Pretendard" }, // Figma 서체 → PPT 서체 "weights": { "700": { "suffix": "", "bold": true }, // Bold는 굵게 속성으로 "500": { "suffix": " Medium" } // Medium은 "Pretendard Medium"으로 } }, "text": { "padNoWrapPx": 40, // 줄바꿈 없는 텍스트의 여유 폭 "padWrapPx": 6 }, "raster": { "scale": 3 }, // 아이콘·이미지 렌더 배율 "verify": { "diffThreshold": 0.12 } } ``` --- ## 설계 노트 — 어디서 깨지는가 실제 변환에서 부딪힌 문제와 대응입니다. 수정할 때 참고하세요. **1. 그룹(Group) 좌표** Figma에서 프레임은 새 좌표계를 만들지만 **그룹은 만들지 않습니다.** 부모 오프셋을 누적하는 방식으로 짜면 그룹 안의 모든 것이 그룹 위치만큼 밀립니다. 표가 통째로 어긋나는 전형적인 원인입니다. → 모든 노드의 `absoluteBoundingBox`를 쓰고 프레임 원점만 빼서 이 문제를 구조적으로 제거했습니다. **2. 클리핑(clipsContent)** 프레임 밖으로 넘친 자식은 Figma에서 잘려 보이지만 PPT에는 그대로 나옵니다. 카드 밖으로 튀어나온 액센트 바가 대표적입니다. → 클리핑 프레임의 경계와 교차시켜 잘라냅니다. **3. 한 텍스트 안의 혼합 서식** 제목 중 기호 하나만 다른 색인 경우 등. 노드 단위로 색을 읽으면 이 정보가 통째로 날아가 텍스트가 사라지거나 검게 변합니다. → `characterStyleOverrides`를 런으로 분리해 각각의 서식을 살립니다. **4. 줄바꿈 — 상자 폭은 건드리면 안 됩니다** PowerPoint는 같은 서체를 Figma보다 미세하게 넓게 조판합니다. 그대로 두면 한 줄짜리 문장이 두 줄로 깨지며 아래 요소를 덮습니다. → Figma에서 자동 줄바꿈이 아니었던 텍스트(`textAutoResize: WIDTH_AND_HEIGHT`)만 PPT에서 줄바꿈을 끄고 여유 폭을 줍니다. **줄바꿈되는 텍스트에는 절대 여유 폭을 주지 않습니다.** 그 폭이 곧 레이아웃 제약이기 때문입니다 — 어디서 줄이 바뀌는지, 그래서 행이 몇 줄이 되는지, 옆 칸이 어디 놓이는지가 전부 그 폭에서 나옵니다. 1px만 넓혀도 단어 하나가 다음 줄로 넘어가고 표 전체가 밀립니다. 실제로 이걸 어겼을 때: 글자 폭 측정 함수는 텍스트를 **한 줄로 폈을 때**의 폭을 돌려주는데, 이 값을 표 셀에도 적용해서 700px 셀이 3006px 상자를 요구했습니다. 줄바꿈이 사라져 문장이 슬라이드 밖으로 잘려나갔고, 가운데 정렬 셀은 넘친 만큼의 절반이 왼쪽으로 밀려 표 정렬까지 무너졌습니다. → 지금은 텍스트 상자가 슬라이드를 벗어나면 리포트에 경고가 뜹니다. 프레임이 원본을 잘라내므로, 밖으로 나간 상자는 언제나 변환 오류이지 디자인이 아닙니다. **5. 행간·자간** PPT의 배수(multiple) 행간은 1.2배를 한 번 더 곱해 어긋납니다. → Figma의 `lineHeightPx`를 **고정 pt 행간**으로 옮기고, 자간도 px→pt로 환산해 넣습니다. **6. 투명도** 반투명 색은 렌더러마다 결과가 달라집니다. → 실제로 깔린 배경색과 **미리 합성**해 불투명 색으로 넣습니다. **7. 표 셀 테두리** 셀은 방향별로 두께가 다릅니다(왼쪽만, 위만…). 사각형 외곽선으로는 표현할 수 없습니다. → `individualStrokeWeights`를 읽어 **방향별 선 도형**으로 그립니다. **8. 서체 치환 — 가장 많은 사고를 낸 원인** 디자인이 A 서체로 잰 글자 폭이 파일에 박혀 있는데 PPT는 B 서체로 조판하면, 그 폭을 읽어 만든 것이 **전부** 어긋납니다. 실제로 겪은 것: 목차 항목 간격이 45.3~52.1px로 들쭉날쭉해지고, 활성 칩 안의 글자가 2~9px 왼쪽으로 쏠렸습니다(Noto Sans KR ↔ Pretendard는 네 글자에서 3.6px 차이). → 변환할 때마다 CoreText로 **타깃 서체의 실제 폭**을 재서 (a) 줄바꿈 방지 여백을 추측이 아닌 실측으로 잡고, (b) 차이를 리포트에 남깁니다. **9. 세로 위치는 완전히 같지 않습니다** PowerPoint는 고정 행간에서 첫 줄 베이스라인을 피그마보다 아래에 놓습니다. 24px/180% 기준 약 5px. 텍스트만 내려가므로 **옆에 둔 불릿·아이콘이 상대적으로 위로 뜬 것처럼** 보입니다. → 아직 자동 보정하지 않습니다. 글자 옆에 도형을 붙이는 디자인이라면 변환 후 한 번 확인하세요. **10. 벡터·이미지·효과** 아이콘, 그라디언트, 그림자는 네이티브 도형으로 옮길 수 없습니다. → 해당 노드만 Figma에서 3배 해상도 PNG로 렌더링해 심습니다. 자식이 있는 컨테이너는 편집성을 지키려고 단색으로 근사하고, 그 사실을 리포트에 남깁니다. --- ## 자체 테스트 네트워크 없이 엔진만 검증합니다. 위 8가지 함정을 합성 트리로 재현합니다. ```bash node test/selftest.js # 검증만 node test/selftest.js --pptx # 눈으로 볼 샘플 PPT도 생성 ``` --- ## 안 될 때 **더블클릭했는데 아무 창도 안 뜬다 / 크롬에서만 안 열린다** macOS는 `localhost`를 **IPv6(::1)로 먼저** 해석하는데, 서버가 IPv4에만 열려 있으면 크롬은 다른 주소로 재시도하지 않고 그냥 실패합니다. `curl`은 알아서 넘어가기 때문에 "터미널에선 되는데 브라우저에선 안 되는" 상태가 됩니다. → 지금은 서버가 **IPv4·IPv6 양쪽에 모두** 열리고, 브라우저에는 `http://127.0.0.1:4785`를 직접 넘깁니다. 그래도 안 열리면 주소창에 이 주소를 직접 쳐보세요. **`figma2pptx: command not found`** `~/bin`이 PATH에 없거나, PATH를 추가한 뒤 **새 터미널 창을 열지 않은** 경우입니다. `.zshrc`는 새 창에서만 읽힙니다. 그래도 안 되면: ```bash ``` **포트가 이미 사용 중** ```bash PORT=4786 ~/figma2pptx/figma2pptx.command ``` **서버가 살아있는지 확인** ```bash curl -s http://127.0.0.1:4785/status ``` ## 알려진 한계 - **PPT의 "표 개체"가 아닙니다.** 표는 텍스트+선 조합입니다. 재현도를 위한 선택이며, 셀 내용 수정은 자유롭지만 행 추가/삭제 시 선도 함께 옮겨야 합니다. - 회전된 노드, 마스크, 블렌드 모드는 아직 반영하지 않습니다. - 여는 PC에 해당 서체가 설치돼 있어야 합니다.