DOCX 생성, 편집 및 분석
.docx는 XML 파일들의 ZIP 아카이브입니다. 작업에 따라 적절한 접근 방식을 선택하세요:
| 작업 | 접근 방식 |
|---|---|
| 새 문서 생성 | docx (npm) 스크립트 작성 — 아래 주의사항 참조 |
| 기존 문서 편집 | unzip → word/document.xml 편집 → zip (docx-js는 기존 파일을 열 수 없음) |
| 내용 읽기 | pandoc -t markdown file.docx |
아래 스크립트 경로는 이 스킬의 디렉터리를 기준으로 합니다.
docx-js로 생성하기 — 주의사항
docx는 사전 설치되어 있습니다. npm install을 먼저 실행하지 말고, 스크립트를 작성하여 바로 require('docx') 하세요. require가 실패하는 경우에만 npm install docx를 실행합니다. 모델은 API를 알고 있습니다. 주의해야 할 함정들은 다음과 같습니다:
- 페이지 크기 기본값은 A4입니다. US Letter를 사용하려면
page: { size: { width: 12240, height: 15840 } }로 설정하세요 (DXA 단위; 1440 = 1인치). - 가로 방향: 세로 방향 치수와
orientation: PageOrientation.LANDSCAPE를 전달하세요. docx-js가 내부적으로 너비와 높이를 바꿉니다. - 표는 이중 너비가 필요합니다: 표에
columnWidths를 설정하고, 모든 셀에width를WidthType.DXA로 설정하세요 (PERCENTAGE는 Google Docs에서 깨집니다). 열 너비의 합은 표 너비와 같아야 합니다. - 표 음영:
ShadingType.CLEAR를 사용하고, 절대SOLID를 사용하지 마세요 (검은색으로 렌더링됩니다). - 목록: 문자 그대로
•를 삽입하지 마세요.LevelFormat.BULLET을 사용한numbering구성을 사용하세요. ImageRun에는type:이 필요합니다 ("png","jpg", ...).PageBreak는Paragraph안에 있어야 합니다.- 절대
\n을 사용하지 마세요 — 별도의Paragraph요소를 사용하세요. - 목차: 제목은 내장
HeadingLevel.*을 사용해야 합니다. 사용자 정의 제목 스타일은outlineLevel이 설정되어야 목차에 나타납니다. - 가로줄로 표를 사용하지 마세요 — 대신 단락 아래쪽 테두리를 사용하세요.
- 점선 안내선 / 같은 줄 오른쪽 정렬:
TextRun내에서 리터럴.이나 공백 패딩 대신PositionalTab(alignment: PositionalTabAlignment.RIGHT,leader: PositionalTabLeader.DOT)을 사용하세요.
출력 확인
.docx를 작성한 후 렌더링하여 확인하세요:
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg # 그런 다음 이미지 읽기
pdftoppm은 페이지 번호를 페이지 수의 너비만큼 0으로 채웁니다 (page-01.jpg…page-12.jpg).
기존 문서 편집
레거시 .doc 파일은 먼저 변환해야 합니다: python scripts/office/soffice.py --headless --convert-to docx file.doc.
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete # 심볼릭 링크 항목 제거 — 외부 출처의 docx는 신뢰할 수 없음
python scripts/merge_runs.py unpacked/ # 조각난 실행(runs)을 병합하여 텍스트를 찾을 수 있게 함
# unpacked/word/document.xml을 제자리에서 편집 — 재포맷하거나 pretty-print하지 마십시오
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx # XSD 검사; --auto-repair는 일반적인 문제 수정
# 변경 내용 추적 중? --author "<변경 내용 추적한 이름>"을 추가하여 모든 편집이 추적되는지 확인
Word는 텍스트를 여러 <w:r> 실행(개정 ID, 맞춤법 검사 표시)으로 나누기 때문에, 문서에서 보이는 구절이 XML에서 연속된 문자열로 존재하지 않는 경우가 많습니다. merge_runs.py는 word/document.xml에서 인접하고 동일한 서식의 실행을 병합하며, 내용이나 렌더링을 변경하지 않습니다. 또한 .docx 파일을 직접 받을 수도 있습니다 (python scripts/merge_runs.py doc.docx -o merged.docx).
변경 내용 추적: 변경 내용을 추적(redlining)할 때 --author "<변경 내용 추적한 이름>" (필요 --original)로 검증하면, 의도치 않게 변경하고도 <w:ins>/<w:del>로 감싸지지 않은 텍스트를 보고합니다. 이는 승인된 보기에서는 보이지 않기 때문에 쉽게 실수할 수 있습니다. 실행을 <w:ins>/<w:del>로 감싸고 w:id, w:author, w:date 속성을 추가하세요. <w:del> 내부의 텍스트 요소는 <w:delText>이며, <w:t>가 아닙니다. 삭제된 단락 표시(<w:pPr><w:rPr><w:del w:id=".." w:author=".." w:date=".."/></w:rPr></w:pPr>)는 "이 단락을 다음 단락과 병합"을 의미합니다. 따라서 단락을 완전히 삭제하는 것은 이 표시와 모든 실행에 대한 <w:del>을 추가하는 것입니다. <w:del/>은 rPr의 다른 자식보다 먼저 와야 합니다. 그 순서는 스키마에 의해 강제됩니다.
모든 변경 내용이 승인된 깨끗한 복사본을 만들려면: python scripts/accept_changes.py in.docx out.docx.
삭제된 단락 표시를 승인하면 해당 단락이 아래 단락과 병합되어야 하므로, 실행이 모두 삭제된 단락은 사라집니다. Word는 이렇게 합니다. 하지만 accept_changes.py와 pandoc --track-changes=accept는 항상 그렇지 않습니다. 둘 다 같은 방식으로 실패합니다 — 삭제된 텍스트는 제거하지만 비워진 단락은 남겨서, 자동 번호가 매겨진 경우 잘못된 빈 글머리 기호로 읽힙니다:
pandoc --track-changes=accept는 단락을 병합하지 않습니다.accept_changes.py(LibreOffice)는 삭제된 단락 뒤에 빈 공백 단락이 오는 경우를 제외하고는 올바르게 병합합니다.
어느 보기에서든 빈 글머리 기호는 해당 보기의 인공물일 뿐, 문서 자체의 결함이 아닙니다. XML에서 단락 삭제를 확인하세요.
주석
주석은 6개의 상호 연결된 파일이 필요합니다. 도우미를 사용하세요 — document.xml도 편집할 때는 디렉터리 모드(unzip/rezip 주기 절약), 그 외에는 .docx 직접 모드를 사용합니다:
# 이미 압축 풀린 디렉터리에 대해 (표시를 배치할 때 선호)
python scripts/comment.py unpacked/ "Fees & expenses cap is too low"
python scripts/comment.py unpacked/ "Agreed" --parent 0
# .docx 파일에 대해 직접
python scripts/comment.py contract.docx "This cap is too low" -o annotated.docx
이 스크립트는 comments.xml, commentsExtended.xml, commentsIds.xml, commentsExtensible.xml, 관계(relationships), 콘텐츠 유형 재정의(content-type overrides)를 작성합니다. 주석 ID는 자동으로 할당됩니다. 그런 다음 word/document.xml에 추가할 <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> 스니펫을 출력하여 주석이 특정 텍스트에 고정되도록 합니다. 이러한 표시를 배치하기 전까지 주석은 존재하지만 보이지 않습니다.
의존성
docx (npm, 사전 설치됨 — require('docx')가 실패하는 경우에만 설치) · pandoc · LibreOffice (soffice) · pdftoppm (Poppler)
이 스킬은 Anthropic에서 만들고 유지 관리합니다. 프론트매터 메타데이터를 제외하고는 수정 없이 여기에 공급되었습니다. 이용 약관은 LICENSE.txt를 참조하세요.