Corin1998's picture
Update modules/exporters.py
8f18cb2 verified
# modules/exporters.py
from pathlib import Path
from typing import Optional
from docx import Document
from pptx import Presentation
from pptx.util import Pt
# utils 側で書き込み可能な場所を自動選択
from .utils import ensure_dirs, export_dir
def _resolve_outpath(out_path: Optional[str], default_name: str) -> Path:
ensure_dirs()
base = export_dir()
if out_path:
p = Path(out_path)
if not p.is_absolute():
p = base / p
else:
p = base / default_name
p.parent.mkdir(parents=True, exist_ok=True)
return p
def export_docx(markdown_text: str, out_path: Optional[str] = None) -> str:
"""
非依存最小の DOCX エクスポート(Markdown は簡易に段落分割のみ)
"""
p = _resolve_outpath(out_path, "proposal.docx")
doc = Document()
# シンプルに行単位で追加(見出しの # は太字化のみ)
for line in (markdown_text or "").splitlines():
if line.strip().startswith("#"):
run = doc.add_paragraph().add_run(line.lstrip("# ").strip())
run.bold = True
else:
doc.add_paragraph(line)
doc.save(p)
return str(p)
def export_pptx(markdown_text: str, out_path: Optional[str] = None) -> str:
"""
非依存最小の PPTX エクスポート(1行=1スライド、最初の行はタイトル扱い)
"""
p = _resolve_outpath(out_path, "proposal.pptx")
prs = Presentation()
# 16:9 既定レイアウト(タイトル&本文)を使う
layout = prs.slide_layouts[1]
lines = [ln for ln in (markdown_text or "").splitlines()]
# 1枚目: タイトルスライド
if lines:
slide0 = prs.slides.add_slide(prs.slide_layouts[0]) # タイトル
slide0.shapes.title.text = lines[0].lstrip("# ").strip() or "提案ドラフト"
if len(lines) > 1 and lines[1].strip():
slide0.placeholders[1].text = lines[1].strip()
# 2枚目以降: 残りの行を1行=1スライドで
for ln in lines[2:] if len(lines) > 2 else []:
slide = prs.slides.add_slide(layout)
slide.shapes.title.text = "概要"
tf = slide.placeholders[1].text_frame
tf.clear()
p_para = tf.paragraphs[0]
p_para.text = ln
p_para.font.size = Pt(18)
prs.save(p)
return str(p)