175 lines
5.6 KiB
Markdown
175 lines
5.6 KiB
Markdown
---
|
|
name: markdown-to-doc
|
|
label: Markdown → 문서 변환
|
|
description: Markdown 파일을 서식이 적용된 Word(.docx) 또는 PDF 문서로 변환합니다.
|
|
icon: \uE8A5
|
|
allowed-tools:
|
|
- file_read
|
|
- file_write
|
|
- process
|
|
- format_convert
|
|
- document_assemble
|
|
tabs: cowork
|
|
---
|
|
|
|
Markdown 파일을 전문적인 Word 또는 PDF 문서로 변환하세요.
|
|
## 실행 경로 선택 (Python 가능/불가)
|
|
- 먼저 `process`로 `python --version`을 확인하세요.
|
|
- Python 가능: 기존 python-docx 경로를 사용하세요.
|
|
- Python 불가: `format_convert`를 우선 사용해 Markdown을 docx/pdf로 변환하고, 변환 제한 시 `file_write`로 보정 가이드를 생성하세요.
|
|
|
|
|
|
## 사전 준비
|
|
먼저 필요한 패키지가 설치되어 있는지 확인하고, 없으면 설치하세요:
|
|
```
|
|
process: pip install python-docx markdown
|
|
```
|
|
|
|
## 작업 절차
|
|
|
|
1. **Markdown 파일 확인**: file_read로 변환할 Markdown 파일의 내용과 구조를 파악
|
|
2. **변환 옵션 확인**: 사용자에게 다음 옵션을 확인
|
|
- 출력 형식: Word(.docx) 또는 PDF
|
|
- 폰트: 맑은 고딕 (기본) / 사용자 지정
|
|
- 여백, 페이지 크기 설정
|
|
- 머리글/바닥글 포함 여부
|
|
3. **Python 스크립트 작성**: file_write로 변환 스크립트 생성
|
|
4. **스크립트 실행**: `process`로 Python 스크립트 실행
|
|
5. **결과 확인**: 생성된 문서 파일 경로와 페이지 수를 안내
|
|
|
|
## 스타일 매핑
|
|
|
|
| Markdown | Word 스타일 | 설명 |
|
|
|----------|------------|------|
|
|
| `# 제목` | Heading 1 | 16pt, 굵게 |
|
|
| `## 소제목` | Heading 2 | 14pt, 굵게 |
|
|
| `### 항목` | Heading 3 | 12pt, 굵게 |
|
|
| 본문 텍스트 | Normal | 11pt |
|
|
| `**굵게**` | Bold run | 굵게 |
|
|
| `*기울임*` | Italic run | 기울임 |
|
|
| `` `코드` `` | 코드 스타일 | Consolas, 배경색 |
|
|
| `> 인용` | Quote | 들여쓰기 + 왼쪽 테두리 |
|
|
| `- 목록` | List Bullet | 글머리 기호 |
|
|
| `1. 번호` | List Number | 번호 목록 |
|
|
| 표 | Table Grid | 테두리 표 |
|
|
| `---` | 페이지 구분 | 가로선 → 페이지 나누기 |
|
|
| 코드 블록 | 코드 단락 | Consolas, 회색 배경 |
|
|
|
|
## Python 스크립트 템플릿
|
|
```python
|
|
import re
|
|
from docx import Document
|
|
from docx.shared import Inches, Pt, Cm, RGBColor
|
|
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
from docx.oxml.ns import qn
|
|
import markdown
|
|
|
|
# Markdown 파일 읽기
|
|
with open('input.md', 'r', encoding='utf-8') as f:
|
|
md_content = f.read()
|
|
|
|
doc = Document()
|
|
|
|
# 기본 스타일 설정
|
|
style = doc.styles['Normal']
|
|
font = style.font
|
|
font.name = '맑은 고딕'
|
|
font.size = Pt(11)
|
|
style.element.rPr.rFonts.set(qn('w:eastAsia'), '맑은 고딕')
|
|
|
|
# 여백 설정
|
|
for section in doc.sections:
|
|
section.top_margin = Cm(2.54)
|
|
section.bottom_margin = Cm(2.54)
|
|
section.left_margin = Cm(3.17)
|
|
section.right_margin = Cm(3.17)
|
|
|
|
# Markdown 파싱 및 변환
|
|
lines = md_content.split('\n')
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i]
|
|
|
|
# 제목 (Heading)
|
|
if line.startswith('#'):
|
|
level = len(line) - len(line.lstrip('#'))
|
|
text = line.lstrip('#').strip()
|
|
doc.add_heading(text, level=min(level, 4))
|
|
|
|
# 코드 블록
|
|
elif line.startswith('```'):
|
|
code_lines = []
|
|
i += 1
|
|
while i < len(lines) and not lines[i].startswith('```'):
|
|
code_lines.append(lines[i])
|
|
i += 1
|
|
p = doc.add_paragraph()
|
|
run = p.add_run('\n'.join(code_lines))
|
|
run.font.name = 'Consolas'
|
|
run.font.size = Pt(9)
|
|
|
|
# 인용
|
|
elif line.startswith('>'):
|
|
text = line.lstrip('>').strip()
|
|
p = doc.add_paragraph(text)
|
|
p.paragraph_format.left_indent = Cm(1.27)
|
|
|
|
# 글머리 기호
|
|
elif line.startswith('- ') or line.startswith('* '):
|
|
text = line[2:].strip()
|
|
doc.add_paragraph(text, style='List Bullet')
|
|
|
|
# 번호 목록
|
|
elif re.match(r'^\d+\.\s', line):
|
|
text = re.sub(r'^\d+\.\s', '', line).strip()
|
|
doc.add_paragraph(text, style='List Number')
|
|
|
|
# 가로선 → 페이지 나누기
|
|
elif line.strip() in ('---', '***', '___'):
|
|
doc.add_page_break()
|
|
|
|
# 빈 줄
|
|
elif line.strip() == '':
|
|
pass
|
|
|
|
# 일반 텍스트
|
|
else:
|
|
p = doc.add_paragraph()
|
|
# 굵게, 기울임 처리
|
|
parts = re.split(r'(\*\*.*?\*\*|\*.*?\*|`.*?`)', line)
|
|
for part in parts:
|
|
if part.startswith('**') and part.endswith('**'):
|
|
run = p.add_run(part[2:-2])
|
|
run.bold = True
|
|
elif part.startswith('*') and part.endswith('*'):
|
|
run = p.add_run(part[1:-1])
|
|
run.italic = True
|
|
elif part.startswith('`') and part.endswith('`'):
|
|
run = p.add_run(part[1:-1])
|
|
run.font.name = 'Consolas'
|
|
run.font.size = Pt(10)
|
|
else:
|
|
p.add_run(part)
|
|
|
|
i += 1
|
|
|
|
# 저장
|
|
doc.save('output.docx')
|
|
print(f'변환 완료: output.docx ({len(doc.paragraphs)}개 단락)')
|
|
```
|
|
|
|
## 표 변환
|
|
Markdown 표가 있으면 Word 표로 변환합니다:
|
|
- 헤더 행: 굵게, 배경색 적용
|
|
- 셀 정렬: Markdown의 `:---`, `:---:`, `---:` 구문 반영
|
|
- 테두리: 전체 셀에 얇은 테두리
|
|
|
|
## 규칙
|
|
- 원본 Markdown 파일은 수정하지 않음
|
|
- 인코딩: UTF-8 기본
|
|
- 이미지 링크(``)는 로컬 파일이면 삽입, URL이면 경로만 표시
|
|
- 복잡한 Markdown(수식, 다이어그램)은 지원 범위와 한계를 안내
|
|
- 출력 파일명: 원본 파일명 기준 (.md → .docx)
|
|
|
|
한국어로 안내하세요. 작업 폴더에 Python 스크립트와 결과 파일을 저장하세요.
|