Spaces:
Runtime error
Runtime error
| from __future__ import annotations | |
| import re | |
| from pathlib import Path | |
| from docx import Document | |
| from docx.enum.text import WD_ALIGN_PARAGRAPH | |
| from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT | |
| from docx.oxml import OxmlElement | |
| from docx.oxml.ns import qn | |
| from docx.shared import Inches, Pt, RGBColor | |
| ROOT = Path(__file__).resolve().parents[1] | |
| SOURCE = ROOT / "docs" / "final_report_draft.md" | |
| OUTPUT = ROOT / "deliverables" / "Turkish_Legal_RAG_Final_Report.docx" | |
| def set_cell_shading(cell, fill: str) -> None: | |
| tc_pr = cell._tc.get_or_add_tcPr() | |
| shd = OxmlElement("w:shd") | |
| shd.set(qn("w:fill"), fill) | |
| tc_pr.append(shd) | |
| def set_cell_margins(cell, top=80, start=120, bottom=80, end=120) -> None: | |
| tc = cell._tc | |
| tc_pr = tc.get_or_add_tcPr() | |
| tc_mar = tc_pr.first_child_found_in("w:tcMar") | |
| if tc_mar is None: | |
| tc_mar = OxmlElement("w:tcMar") | |
| tc_pr.append(tc_mar) | |
| for margin, value in [("top", top), ("start", start), ("bottom", bottom), ("end", end)]: | |
| node = tc_mar.find(qn(f"w:{margin}")) | |
| if node is None: | |
| node = OxmlElement(f"w:{margin}") | |
| tc_mar.append(node) | |
| node.set(qn("w:w"), str(value)) | |
| node.set(qn("w:type"), "dxa") | |
| def style_document(doc: Document) -> None: | |
| section = doc.sections[0] | |
| section.top_margin = Inches(1) | |
| section.bottom_margin = Inches(1) | |
| section.left_margin = Inches(1) | |
| section.right_margin = Inches(1) | |
| styles = doc.styles | |
| normal = styles["Normal"] | |
| normal.font.name = "Calibri" | |
| normal.font.size = Pt(11) | |
| normal.paragraph_format.space_after = Pt(6) | |
| normal.paragraph_format.line_spacing = 1.10 | |
| title = styles["Title"] | |
| title.font.name = "Calibri" | |
| title.font.size = Pt(22) | |
| title.font.bold = True | |
| title.font.color.rgb = RGBColor(11, 37, 69) | |
| title.paragraph_format.space_after = Pt(8) | |
| for style_name, size, color in [ | |
| ("Heading 1", 16, RGBColor(46, 116, 181)), | |
| ("Heading 2", 13, RGBColor(46, 116, 181)), | |
| ("Heading 3", 12, RGBColor(31, 77, 120)), | |
| ]: | |
| style = styles[style_name] | |
| style.font.name = "Calibri" | |
| style.font.size = Pt(size) | |
| style.font.bold = True | |
| style.font.color.rgb = color | |
| style.paragraph_format.space_before = Pt(10) | |
| style.paragraph_format.space_after = Pt(5) | |
| def add_table(doc: Document, rows: list[list[str]]) -> None: | |
| if not rows: | |
| return | |
| table = doc.add_table(rows=len(rows), cols=len(rows[0])) | |
| table.alignment = WD_TABLE_ALIGNMENT.CENTER | |
| table.style = "Table Grid" | |
| for r_idx, row in enumerate(rows): | |
| for c_idx, value in enumerate(row): | |
| cell = table.cell(r_idx, c_idx) | |
| cell.text = value.strip() | |
| cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER | |
| set_cell_margins(cell) | |
| for paragraph in cell.paragraphs: | |
| paragraph.paragraph_format.space_after = Pt(0) | |
| for run in paragraph.runs: | |
| run.font.size = Pt(9) | |
| run.font.name = "Calibri" | |
| if r_idx == 0: | |
| run.font.bold = True | |
| if r_idx == 0: | |
| set_cell_shading(cell, "F2F4F7") | |
| doc.add_paragraph() | |
| def parse_table(lines: list[str], start: int) -> tuple[list[list[str]], int]: | |
| rows = [] | |
| i = start | |
| while i < len(lines) and lines[i].strip().startswith("|"): | |
| raw = lines[i].strip() | |
| parts = [part.strip() for part in raw.strip("|").split("|")] | |
| if not all(re.fullmatch(r":?-{3,}:?", part or "") for part in parts): | |
| rows.append(parts) | |
| i += 1 | |
| return rows, i | |
| def build() -> None: | |
| doc = Document() | |
| style_document(doc) | |
| title = doc.add_paragraph(style="Title") | |
| title.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| title.add_run("Turkish Legal RAG: Base vs Fine-Tuned RAG Evaluation") | |
| meta = doc.add_paragraph() | |
| meta.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| run = meta.add_run("CENG493 Term Project - Final Technical Report") | |
| run.italic = True | |
| run.font.color.rgb = RGBColor(85, 85, 85) | |
| doc.add_paragraph() | |
| lines = SOURCE.read_text(encoding="utf-8").splitlines() | |
| in_code = False | |
| code_buffer: list[str] = [] | |
| i = 0 | |
| while i < len(lines): | |
| line = lines[i].rstrip() | |
| stripped = line.strip() | |
| if stripped.startswith("```"): | |
| if in_code: | |
| para = doc.add_paragraph() | |
| para.style = doc.styles["No Spacing"] | |
| code_run = para.add_run("\n".join(code_buffer)) | |
| code_run.font.name = "Consolas" | |
| code_run.font.size = Pt(9) | |
| code_buffer = [] | |
| in_code = False | |
| else: | |
| in_code = True | |
| i += 1 | |
| continue | |
| if in_code: | |
| code_buffer.append(line) | |
| i += 1 | |
| continue | |
| if not stripped: | |
| i += 1 | |
| continue | |
| if stripped.startswith("|"): | |
| rows, i = parse_table(lines, i) | |
| add_table(doc, rows) | |
| continue | |
| if stripped.startswith("# "): | |
| # The title is already rendered as a cover title. | |
| i += 1 | |
| continue | |
| if stripped.startswith("## "): | |
| doc.add_paragraph(stripped[3:], style="Heading 1") | |
| elif stripped.startswith("### "): | |
| doc.add_paragraph(stripped[4:], style="Heading 2") | |
| elif stripped.startswith("- "): | |
| doc.add_paragraph(stripped[2:], style="List Bullet") | |
| elif re.match(r"^\d+\. ", stripped): | |
| doc.add_paragraph(re.sub(r"^\d+\. ", "", stripped), style="List Number") | |
| else: | |
| doc.add_paragraph(stripped) | |
| i += 1 | |
| footer = doc.sections[0].footer.paragraphs[0] | |
| footer.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| footer.add_run("Turkish Legal RAG - CENG493").font.size = Pt(9) | |
| OUTPUT.parent.mkdir(parents=True, exist_ok=True) | |
| doc.save(OUTPUT) | |
| print(f"Wrote {OUTPUT}") | |
| if __name__ == "__main__": | |
| build() | |