Spaces:
Sleeping
Sleeping
| # 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) | |