From 8ae8c3465b8cd1159634f73c05038af25d0d9bf2 Mon Sep 17 00:00:00 2001 From: piglee05022 Date: Mon, 26 May 2025 16:32:21 +0800 Subject: [PATCH 1/3] Create docker-image.yml --- .github/workflows/docker-image.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/docker-image.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..3f53646 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,18 @@ +name: Docker Image CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build the Docker image + run: docker build . --file Dockerfile --tag my-image-name:$(date +%s) From 2fb7c267cc6805152574df55069420a33cbbcdeb Mon Sep 17 00:00:00 2001 From: piglee05022 Date: Tue, 3 Jun 2025 19:20:26 +0800 Subject: [PATCH 2/3] Add legal document generator module --- README.md | 16 ++++++++++ legal_module/__init__.py | 0 legal_module/example.py | 18 +++++++++++ legal_module/filing.py | 66 ++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + 5 files changed, 101 insertions(+) create mode 100644 legal_module/__init__.py create mode 100644 legal_module/example.py create mode 100644 legal_module/filing.py create mode 100644 requirements.txt diff --git a/README.md b/README.md index de432ac..3b15bab 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,19 @@ In addition to the packages specified in the table above, the following packages - `bazelisk` / `bazel` See [Dockerfile](Dockerfile) for the full details of installed packages. + +## Legal document generator module + +This repository includes a simple example module located in `legal_module/` that demonstrates how to generate Traditional Chinese legal filings using the `python-docx` package. The module exposes a `create_filing` function that accepts case information and outputs a formatted Word document. + +Example usage: + +```bash +python3 -m legal_module.example +``` + +This requires the optional dependency **python-docx**. Install it with: + +```bash +pip install python-docx +``` diff --git a/legal_module/__init__.py b/legal_module/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/legal_module/example.py b/legal_module/example.py new file mode 100644 index 0000000..218f9c9 --- /dev/null +++ b/legal_module/example.py @@ -0,0 +1,18 @@ +from .filing import create_filing + +sample_case = { + 'case_number': '臺北地方法院114年度訴字第1234號', + 'parties': '原告:李灃祐 被告:新鑫公司', + 'court': '臺灣臺北地方法院', + 'claims': '請求確認本票債權不存在,並請求返還不當得利新台幣1,000,000元。', + 'facts': '原告與被告簽署車輛分期契約,惟車輛自始未交付,卻遭告提出票據裁定……', + 'laws': ['民法第184條', '票據法第17條', '最高法院111年度台上字第3208號判決'], + 'evidence': [ + {'id': '乙1', 'summary': 'LINE對話紀錄,顯示告知車輛尚未交付'}, + {'id': '乙2', 'summary': '川立公司匯款憑證,顯示資金流向'} + ] +} + +if __name__ == '__main__': + create_filing(sample_case, '法律文書_起訴狀.docx') + print('Document generated: 法律文書_起訴狀.docx') diff --git a/legal_module/filing.py b/legal_module/filing.py new file mode 100644 index 0000000..bf0e7ba --- /dev/null +++ b/legal_module/filing.py @@ -0,0 +1,66 @@ +from typing import Dict + +try: + from docx import Document + from docx.shared import Pt +except ImportError: # pragma: no cover - docx may not be installed + Document = None + Pt = None + +class LegalDocumentGenerator: + """Generate legal filings in Traditional Chinese.""" + + def __init__(self, case_info: Dict[str, any]): + self.case_info = case_info + if Document is None: + raise RuntimeError( + "python-docx is required to generate documents. Please install it via 'pip install python-docx'." + ) + self.doc = Document() + style = self.doc.styles['Normal'] + font = style.font + font.name = '標楷體' + font.size = Pt(16) + + def build(self) -> None: + self.doc.add_heading(self.case_info.get('title', '起訴狀'), level=1) + self._add_basic_info() + self._add_claims() + self._add_facts() + self._add_laws() + self._add_evidence() + + def save(self, filepath: str) -> None: + self.doc.save(filepath) + + # Internal helpers + def _add_basic_info(self) -> None: + self.doc.add_paragraph(f"案號:{self.case_info.get('case_number', '')}") + self.doc.add_paragraph(f"當事人:{self.case_info.get('parties', '')}") + self.doc.add_paragraph(f"法院:{self.case_info.get('court', '')}") + + def _add_claims(self) -> None: + self.doc.add_paragraph("壹、訴之聲明") + self.doc.add_paragraph(self.case_info.get('claims', '')) + + def _add_facts(self) -> None: + self.doc.add_paragraph("貳、事實與理由") + self.doc.add_paragraph(self.case_info.get('facts', '')) + + def _add_laws(self) -> None: + self.doc.add_paragraph("參、法律依據") + for law in self.case_info.get('laws', []): + self.doc.add_paragraph(f"• {law}") + + def _add_evidence(self) -> None: + self.doc.add_paragraph("肆、證據目錄") + for ev in self.case_info.get('evidence', []): + self.doc.add_paragraph(f"【{ev['id']}】{ev['summary']}") + + +def create_filing(case_info: Dict[str, any], output_path: str) -> None: + """Helper function to quickly generate a filing document.""" + generator = LegalDocumentGenerator(case_info) + generator.build() + generator.save(output_path) + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..77894c4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +python-docx From 67b623472b7e0b0bd19030b0f704ad868560035f Mon Sep 17 00:00:00 2001 From: piglee05022 Date: Wed, 4 Jun 2025 19:20:53 +0800 Subject: [PATCH 3/3] Document new filing options --- README.md | 6 ++-- legal_module/example.py | 7 +++-- legal_module/filing.py | 64 ++++++++++++++++++++++++++++++++++++----- requirements.txt | 1 + 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3b15bab..cfd9488 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ See [Dockerfile](Dockerfile) for the full details of installed packages. ## Legal document generator module -This repository includes a simple example module located in `legal_module/` that demonstrates how to generate Traditional Chinese legal filings using the `python-docx` package. The module exposes a `create_filing` function that accepts case information and outputs a formatted Word document. +This repository includes a simple example module located in `legal_module/` that demonstrates how to generate Traditional Chinese legal filings using the `python-docx` package. The module exposes a `create_filing` function that accepts case information and outputs a formatted Word document. When `docx2pdf` is available the file can also be exported to PDF. Generated documents use **2.5 cm margins**, **1.5 line spacing**, and include an optional **附件** section for supporting materials. Example usage: @@ -64,8 +64,8 @@ Example usage: python3 -m legal_module.example ``` -This requires the optional dependency **python-docx**. Install it with: +This requires the optional dependencies **python-docx** and **docx2pdf** for PDF export. Install them with: ```bash -pip install python-docx +pip install python-docx docx2pdf ``` diff --git a/legal_module/example.py b/legal_module/example.py index 218f9c9..2339e53 100644 --- a/legal_module/example.py +++ b/legal_module/example.py @@ -10,9 +10,12 @@ 'evidence': [ {'id': '乙1', 'summary': 'LINE對話紀錄,顯示告知車輛尚未交付'}, {'id': '乙2', 'summary': '川立公司匯款憑證,顯示資金流向'} + ], + 'attachments': [ + {'id': '附件一', 'description': '車輛分期契約影本'}, ] } if __name__ == '__main__': - create_filing(sample_case, '法律文書_起訴狀.docx') - print('Document generated: 法律文書_起訴狀.docx') + create_filing(sample_case, '法律文書_起訴狀.docx', pdf_path='法律文書_起訴狀.pdf') + print('Documents generated: 法律文書_起訴狀.docx, 法律文書_起訴狀.pdf') diff --git a/legal_module/filing.py b/legal_module/filing.py index bf0e7ba..8870b0d 100644 --- a/legal_module/filing.py +++ b/legal_module/filing.py @@ -1,8 +1,10 @@ -from typing import Dict +from typing import Any, Dict, Optional +from pathlib import Path +import tempfile try: from docx import Document - from docx.shared import Pt + from docx.shared import Pt, Cm except ImportError: # pragma: no cover - docx may not be installed Document = None Pt = None @@ -10,17 +12,24 @@ class LegalDocumentGenerator: """Generate legal filings in Traditional Chinese.""" - def __init__(self, case_info: Dict[str, any]): + def __init__(self, case_info: Dict[str, Any]): self.case_info = case_info if Document is None: raise RuntimeError( "python-docx is required to generate documents. Please install it via 'pip install python-docx'." ) self.doc = Document() - style = self.doc.styles['Normal'] + style = self.doc.styles["Normal"] font = style.font - font.name = '標楷體' + font.name = "標楷體" font.size = Pt(16) + style.paragraph_format.line_spacing = Pt(24) # 1.5 line spacing + + for section in self.doc.sections: + section.top_margin = Cm(2.5) + section.bottom_margin = Cm(2.5) + section.left_margin = Cm(2.5) + section.right_margin = Cm(2.5) def build(self) -> None: self.doc.add_heading(self.case_info.get('title', '起訴狀'), level=1) @@ -29,10 +38,25 @@ def build(self) -> None: self._add_facts() self._add_laws() self._add_evidence() + self._add_attachments() def save(self, filepath: str) -> None: self.doc.save(filepath) + def save_pdf(self, filepath: str) -> None: + """Save the generated document as a PDF using docx2pdf if available.""" + try: + from docx2pdf import convert + except ImportError as exc: # pragma: no cover - optional dependency + raise RuntimeError( + "docx2pdf is required for PDF export. Install it via 'pip install docx2pdf'." + ) from exc + + with tempfile.TemporaryDirectory() as tmpdir: + docx_path = Path(tmpdir) / "temp.docx" + self.doc.save(docx_path) + convert(str(docx_path), filepath) + # Internal helpers def _add_basic_info(self) -> None: self.doc.add_paragraph(f"案號:{self.case_info.get('case_number', '')}") @@ -57,10 +81,36 @@ def _add_evidence(self) -> None: for ev in self.case_info.get('evidence', []): self.doc.add_paragraph(f"【{ev['id']}】{ev['summary']}") + def _add_attachments(self) -> None: + attachments = self.case_info.get("attachments") + if not attachments: + return + self.doc.add_paragraph("伍、附件") + for att in attachments: + desc = att.get("description", "") + att_id = att.get("id", "") + self.doc.add_paragraph(f"【{att_id}】{desc}") + + +def create_filing( + case_info: Dict[str, Any], + output_path: str, + pdf_path: Optional[str] = None, +) -> None: + """Helper function to quickly generate a filing document. -def create_filing(case_info: Dict[str, any], output_path: str) -> None: - """Helper function to quickly generate a filing document.""" + Parameters + ---------- + case_info : Dict[str, Any] + Information about the case. + output_path : str + Location to write the DOCX file. + pdf_path : Optional[str] + If provided, also export the document to this PDF path. + """ generator = LegalDocumentGenerator(case_info) generator.build() generator.save(output_path) + if pdf_path: + generator.save_pdf(pdf_path) diff --git a/requirements.txt b/requirements.txt index 77894c4..2e9298f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ python-docx +docx2pdf