Back to skills
SkillHub ClubResearch & OpsFull StackTech Writer

academic-writer

Professional LaTeX writing assistant. Capabilities include: scanning existing LaTeX templates, reading reference materials (Word/Text), drafting content strictly following templates, and compiling PDFs. Triggers include: 'write thesis', 'draft section', 'compile pdf', 'check latex format'. Designed to work in tandem with 'academic-research-hub' for citation retrieval.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,077
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
B77.6

Install command

npx @skill-hub/cli install openclaw-skills-academic-writer

Repository

openclaw/skills

Skill path: skills/dayunyan/academic-writer

Professional LaTeX writing assistant. Capabilities include: scanning existing LaTeX templates, reading reference materials (Word/Text), drafting content strictly following templates, and compiling PDFs. Triggers include: 'write thesis', 'draft section', 'compile pdf', 'check latex format'. Designed to work in tandem with 'academic-research-hub' for citation retrieval.

Open repository

Best for

Primary workflow: Research & Ops.

Technical facets: Full Stack, Tech Writer.

Target audience: everyone.

License: Proprietary.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install academic-writer into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding academic-writer to shared team environments
  • Use academic-writer for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: academic-writer
description: "Professional LaTeX writing assistant. Capabilities include: scanning existing LaTeX templates, reading reference materials (Word/Text), drafting content strictly following templates, and compiling PDFs. Triggers include: 'write thesis', 'draft section', 'compile pdf', 'check latex format'. Designed to work in tandem with 'academic-research-hub' for citation retrieval."
license: Proprietary
permissions:
  - shell:exec
env:
  PYTHON_CMD: python3
---

# Academic Writer & LaTeX Composer

A comprehensive agent skill for orchestrating academic paper writing in a WSL2/Linux environment. It manages the lifecycle from template analysis to PDF compilation.

⚠️ **Prerequisite:** This skill requires a full LaTeX distribution and Python 3.

## Installation & Setup

Since you are running this in WSL2 (Ubuntu), you must install both system-level LaTeX packages and a Python virtual environment for the worker script.

### 1. System Dependencies (LaTeX)
Open your WSL terminal and run:

```bash
# Update package lists
sudo apt-get update

# Install the full TeX Live distribution (Required for all templates)
# Warning: This download is approx 4GB-7GB
sudo apt-get install texlive-full

# Install latexmk for automated compilation
sudo apt-get install latexmk
```

### 2. Python Environment & Dependencies
It is best practice to use a virtual environment to avoid conflicts.

```bash
# Go to your skill directory
cd ~/.openclaw/skills/academic-writer

# Create a virtual environment
python3 -m venv venv

# Activate the environment
source venv/bin/activate

# Install required Python packages
# python-docx: For reading Word documents
pip install python-docx
```

---

## Quick Reference

| Task | Tool Command |
|------|--------------|
| **Analyze Project** | `scan_template` |
| **Read Notes** | `read_reference` |
| **Draft Content** | `write_latex` |
| **Generate PDF** | `compile_pdf` |
| **Find Citations** | *Delegate to `academic-research-hub`* |

---

## System Instructions & Workflow

**Role:** You are an expert Academic Writer and LaTeX Typesetter.

**Primary Objective:** Create high-quality academic PDFs by strictly adhering to provided templates and user content.

### Core Logic Steps

#### 1. Initialization (Template Enforcement)
*   **Action:** Always start by calling `scan_template` on the current directory.
*   **Logic:**
    *   **If a template exists (e.g., IEEE, ACM, local .cls files):** You MUST respect the class structure. Do not change the preamble unless necessary for a new package.
    *   **If no template exists:** Ask the user if they want to generate a standard `article` structure.

#### 2. Context Loading (Reference Material)
*   **Action:** If the user mentions input files (e.g., "use my notes.docx" or "reference draft.txt"), call `read_reference`.
*   **Logic:** Use this content as the "Ground Truth" for your writing. Do not hallucinate facts outside of the provided context or external research.

#### 3. Literature Search (Cross-Skill Delegation)
*   **Trigger:** When you need to support a claim with a citation and the user hasn't provided it.
*   **Action:** **DO NOT** make up citations. Instead, instruct the agent to use the **`academic-research-hub`** skill.
*   **Protocol:**
    1.  Pause writing.
    2.  Invoke search (e.g., "Find papers on X using academic-research-hub").
    3.  Get the BibTeX.
    4.  Resume writing: Append BibTeX to the `.bib` file using `write_latex` (mode='a') and use `\cite{key}` in the text.

#### 4. Writing & Compilation
*   **Action:** Use `write_latex` to create `.tex` files.
*   **Action:** After finishing a significant section, call `compile_pdf`.
*   **Error Handling:** If `compile_pdf` returns an error log, analyze it, fix the LaTeX syntax, and re-compile.

---

## Tools Definition

### tool: scan_template
Analyzes the current directory to identify LaTeX structure, main files, and templates.
- **command**: `${PYTHON_CMD} scripts/writer_tools.py scan_template {{directory}}`
- **params**:
  - `directory`: (string) Path to scan. Default is ".".

### tool: read_reference
Reads raw text from reference files. Supports `.docx`, `.txt`, `.tex`, `.md`.
- **command**: `${PYTHON_CMD} scripts/writer_tools.py read_reference {{filepath}}`
- **params**:
  - `filepath`: (string) Path to the reference file.

### tool: write_latex
Writes content to a specific file. Can overwrite or append.
- **command**: `${PYTHON_CMD} scripts/writer_tools.py write_latex {{filename}} {{content}} {{mode}}`
- **params**:
  - `filename`: (string) Target filename (e.g., "introduction.tex").
  - `content`: (string) Raw LaTeX content.
  - `mode`: (string) "w" for overwrite, "a" for append. Default is "w".

### tool: compile_pdf
Compiles the project using `latexmk`. Returns success message or error logs.
- **command**: `${PYTHON_CMD} scripts/writer_tools.py compile_pdf {{main_file}}`
- **params**:
  - `main_file`: (string) The root TeX file (e.g., "main.tex").

---

## Common Workflows

### 1. The "Strict Template" Flow
Use this when the user provides a conference template (e.g., IEEEtrans).

1.  **User:** "Draft the intro using `notes.docx` in this folder."
2.  **Agent:** Calls `scan_template` -> Detects `main.tex` (IEEE class).
3.  **Agent:** Calls `read_reference` -> Gets content from `notes.docx`.
4.  **Agent:** Calls `write_latex` -> Writes `intro.tex` following IEEE style.
5.  **Agent:** Calls `write_latex` -> Updates `main.tex` to `\input{intro}`.
6.  **Agent:** Calls `compile_pdf` -> Checks for layout errors.

### 2. The "Research & Write" Flow
Use this when the user needs external citations.

1.  **User:** "Write a paragraph about LLM Agents and cite recent papers."
2.  **Agent:** *Thinking:* "I need citations."
3.  **Agent:** **Calls `academic-research-hub`** (e.g., search arXiv for "LLM Agents 2025").
4.  **Agent:** Receives BibTeX data.
5.  **Agent:** Calls `write_latex` (mode='a') -> Appends to `references.bib`.
6.  **Agent:** Calls `write_latex` -> Writes paragraph with `\cite{...}`.
7.  **Agent:** Calls `compile_pdf`.

---

## Troubleshooting

### Compilation Failures
*   **Error:** `latexmk: command not found`
    *   **Fix:** Ensure you ran `sudo apt-get install latexmk`.
*   **Error:** `! LaTeX Error: File 'article.cls' not found.`
    *   **Fix:** Ensure you ran `sudo apt-get install texlive-full`.
*   **Error:** `! Package citation Error`
    *   **Fix:** Run the compilation twice, or ensure `latexmk` is used (it handles re-runs automatically).

### Python Errors
*   **Error:** `ModuleNotFoundError: No module named 'docx'`
    *   **Fix:** Ensure you activated the venv and ran `pip install python-docx`.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/writer_tools.py

```python
import os
import sys
import subprocess
import json
import glob
try:
    from docx import Document
except ImportError:
    Document = None

def read_reference(file_path):
    """读取参考资料"""
    if not os.path.exists(file_path):
        return f"Error: File {file_path} not found."
    
    try:
        if file_path.endswith('.docx'):
            if Document is None:
                return "Error: python-docx not installed. Run `pip install python-docx`."
            doc = Document(file_path)
            full_text = [para.text for para in doc.paragraphs]
            return '\n'.join(full_text)
        else:
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                return f.read()
    except Exception as e:
        return f"Error reading file: {str(e)}"

def scan_template(directory="."):
    """扫描 LaTeX 结构"""
    tex_files = glob.glob(os.path.join(directory, "*.tex"))
    bib_files = glob.glob(os.path.join(directory, "*.bib"))
    
    main_file = None
    structure = {}
    
    for f_path in tex_files:
        with open(f_path, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
            # 简单启发式查找主文件
            if "\\documentclass" in content and "\\begin{document}" in content:
                main_file = os.path.basename(f_path)
            # 截取前 800 字符供 LLM 理解模板头部
            structure[os.path.basename(f_path)] = content[:800] + "\n...(truncated)"

    return json.dumps({
        "detected_main_file": main_file,
        "tex_files": [os.path.basename(f) for f in tex_files],
        "bib_files": [os.path.basename(f) for f in bib_files],
        "file_previews": structure
    }, ensure_ascii=False)

def write_latex_content(filename, content, mode='w'):
    """写入文件"""
    try:
        with open(filename, mode, encoding='utf-8') as f:
            f.write(content)
        return f"Success: Wrote {len(content)} chars to {filename}"
    except Exception as e:
        return f"Error writing: {str(e)}"

def compile_pdf(main_file):
    """编译 PDF"""
    if not main_file:
        return "Error: No main file specified."
    
    # 检查 latexmk 是否存在
    if subprocess.call(["which", "latexmk"], stdout=subprocess.DEVNULL) != 0:
        return "Error: latexmk not found. Please install texlive-full."

    try:
        # -interaction=nonstopmode: 不因错误暂停
        # -pdf: 生成 PDF
        result = subprocess.run(
            ['latexmk', '-pdf', '-interaction=nonstopmode', main_file],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            timeout=60 # 防止死循环
        )
        
        if result.returncode == 0:
            return f"Success! PDF generated: {main_file.replace('.tex', '.pdf')}"
        else:
            # 提取最后部分的错误日志
            logs = result.stdout + "\n" + result.stderr
            return f"Compilation Failed. Error Log Tail:\n{logs[-1500:]}"
    except Exception as e:
        return f"Execution Error: {str(e)}"

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 writer_tools.py <command> [args]")
        sys.exit(1)

    cmd = sys.argv[1]
    args = sys.argv[2:]

    if cmd == "read_reference":
        print(read_reference(args[0] if args else ""))
    elif cmd == "scan_template":
        print(scan_template(args[0] if args else "."))
    elif cmd == "write_latex":
        # write_latex filename content mode
        filename = args[0]
        content = args[1]
        mode = args[2] if len(args) > 2 else 'w'
        print(write_latex_content(filename, content, mode))
    elif cmd == "compile_pdf":
        print(compile_pdf(args[0] if args else ""))
    else:
        print(f"Unknown command: {cmd}")
```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "dayunyan",
  "slug": "academic-writer",
  "displayName": "Academic Writer",
  "latest": {
    "version": "0.1.0",
    "publishedAt": 1770789552545,
    "commit": "https://github.com/openclaw/skills/commit/cb80922979a0bcc472d87fc3a2484b3c866dee48"
  },
  "history": []
}

```

academic-writer | SkillHub