Loading...
No commits yet
Not committed History
Blame
tables.py • 5.6 KB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Timestamp: 2026-01-27
# File: src/scitex_writer/_mcp/tools/tables.py

"""Table MCP tools."""


from typing import Literal, Optional

from fastmcp import FastMCP

from ..handlers import csv_to_latex as _csv_to_latex
from ..handlers import latex_to_csv as _latex_to_csv
from ..utils import resolve_project_path


def register_tools(mcp: FastMCP) -> None:
    """Register table tools."""

    @mcp.tool()
    def writer_csv_to_latex(
        csv_path: str,
        output_path: Optional[str] = None,
        caption: Optional[str] = None,
        label: Optional[str] = None,
        longtable: bool = False,
    ) -> dict:
        """[writer] Convert CSV file to LaTeX table format."""
        return _csv_to_latex(csv_path, output_path, caption, label, longtable)

    @mcp.tool()
    def writer_latex_to_csv(
        latex_path: str,
        output_path: Optional[str] = None,
        table_index: int = 0,
    ) -> dict:
        """[writer] Convert LaTeX table to CSV format."""
        return _latex_to_csv(latex_path, output_path, table_index)

    @mcp.tool()
    def writer_list_tables(
        project_dir: str,
        doc_type: Literal["manuscript", "supplementary", "revision"] = "manuscript",
    ) -> dict:
        """[writer] List all tables in a writer project."""
        try:
            project_path = resolve_project_path(project_dir)
            doc_dirs = {
                "manuscript": project_path / "01_manuscript",
                "supplementary": project_path / "02_supplementary",
                "revision": project_path / "03_revision",
            }
            doc_dir = doc_dirs.get(doc_type)
            if not doc_dir or not doc_dir.exists():
                return {
                    "success": False,
                    "error": f"Document directory not found: {doc_type}",
                }

            table_dir = doc_dir / "contents" / "tables" / "caption_and_media"
            if not table_dir.exists():
                return {"success": True, "tables": [], "count": 0}

            tables = []
            for csv_file in sorted(table_dir.glob("*.csv")):
                caption_file = csv_file.with_suffix(".tex")
                tables.append(
                    {
                        "name": csv_file.stem,
                        "csv_path": str(csv_file),
                        "caption_path": str(caption_file)
                        if caption_file.exists()
                        else None,
                        "has_caption": caption_file.exists(),
                    }
                )

            return {"success": True, "tables": tables, "count": len(tables)}
        except Exception as e:
            return {"success": False, "error": str(e)}

    @mcp.tool()
    def writer_add_table(
        project_dir: str,
        name: str,
        csv_content: str,
        caption: str,
        label: Optional[str] = None,
        doc_type: Literal["manuscript", "supplementary"] = "manuscript",
    ) -> dict:
        """[writer] Add a new table (CSV + caption) to the project."""
        try:
            project_path = resolve_project_path(project_dir)
            doc_dirs = {
                "manuscript": project_path / "01_manuscript",
                "supplementary": project_path / "02_supplementary",
            }
            doc_dir = doc_dirs.get(doc_type)
            if not doc_dir:
                return {"success": False, "error": f"Invalid doc_type: {doc_type}"}

            table_dir = doc_dir / "contents" / "tables" / "caption_and_media"
            table_dir.mkdir(parents=True, exist_ok=True)

            # Write CSV
            csv_path = table_dir / f"{name}.csv"
            csv_path.write_text(csv_content, encoding="utf-8")

            # Write caption
            if label is None:
                label = f"tab:{name.replace(' ', '_')}"
            caption_content = f"\\caption{{{caption}}}\n\\label{{{label}}}\n"
            caption_path = table_dir / f"{name}.tex"
            caption_path.write_text(caption_content, encoding="utf-8")

            return {
                "success": True,
                "csv_path": str(csv_path),
                "caption_path": str(caption_path),
                "label": label,
            }
        except Exception as e:
            return {"success": False, "error": str(e)}

    @mcp.tool()
    def writer_remove_table(
        project_dir: str,
        name: str,
        doc_type: Literal["manuscript", "supplementary"] = "manuscript",
    ) -> dict:
        """[writer] Remove a table (CSV + caption) from the project."""
        try:
            project_path = resolve_project_path(project_dir)
            doc_dirs = {
                "manuscript": project_path / "01_manuscript",
                "supplementary": project_path / "02_supplementary",
            }
            doc_dir = doc_dirs.get(doc_type)
            if not doc_dir:
                return {"success": False, "error": f"Invalid doc_type: {doc_type}"}

            table_dir = doc_dir / "contents" / "tables" / "caption_and_media"
            csv_path = table_dir / f"{name}.csv"
            caption_path = table_dir / f"{name}.tex"

            removed = []
            if csv_path.exists():
                csv_path.unlink()
                removed.append(str(csv_path))
            if caption_path.exists():
                caption_path.unlink()
                removed.append(str(caption_path))

            if not removed:
                return {"success": False, "error": f"Table not found: {name}"}

            return {"success": True, "removed": removed}
        except Exception as e:
            return {"success": False, "error": str(e)}


# EOF