scitex_writer
SciTeX Writer - LaTeX manuscript compilation system with MCP server.
- Four Interfaces:
Python API: import scitex_writer as sw
CLI: scitex-writer <command>
GUI: scitex-writer gui (browser-based editor)
MCP: 38 tools for AI agents
- Modules:
claim: Traceable scientific assertions (stats, figures, citations)
compile: Compile manuscripts to PDF
export: Export manuscript for arXiv submission
migration: Import from / export to external platforms (Overleaf)
project: Clone, info, get_pdf
tables: List, add, remove, csv_to_latex
figures: List, add, remove, convert
bib: List, add, remove, merge
guidelines: IMRAD writing tips
prompts: AI2 Asta integration
gui: Browser-based editor (Django)
- scitex_writer.usage()
Get the usage guide with branding applied.
- Returns:
Formatted usage guide string.
- Return type:
- class scitex_writer.Writer(project_dir, name=None, git_strategy='child', branch=None, tag=None)[source]
Bases:
objectLaTeX manuscript compiler.
- __init__(project_dir, name=None, git_strategy='child', branch=None, tag=None)[source]
Initialize for project directory.
If directory doesn’t exist, creates new project.
- Parameters:
project_dir (Path) – Path to project directory.
name (str, optional) – Project name (used if creating new project).
git_strategy (str, optional) – Git initialization strategy: - ‘child’: Create isolated git in project directory (default) - ‘parent’: Use parent git repository - ‘origin’: Preserve template’s original git history - None or ‘none’: Disable git initialization
branch (str, optional) – Specific branch of template repository to clone. If None, clones the default branch. Mutually exclusive with tag.
tag (str, optional) – Specific tag/release of template repository to clone. If None, clones the default branch. Mutually exclusive with branch.
- _attach_or_create_project(name=None)[source]
Create new project or attach to existing one.
If project directory doesn’t exist, creates it based on git_strategy: - ‘child’: Full template with git initialization - ‘parent’/’None’: Minimal directory structure
- Parameters:
name (str, optional) – Project name (used if creating new project).
- Returns:
Path to the project directory.
- Return type:
Path
- _verify_project_structure()[source]
Verify attached project has expected structure.
Checks: - Required directories exist (01_manuscript, 02_supplementary, 03_revision)
- Raises:
RuntimeError – If structure is invalid.
- Return type:
- compile_manuscript(timeout=300, log_callback=None, progress_callback=None)[source]
Compile manuscript to PDF with optional live callbacks.
Runs scripts/shell/compile_manuscript.sh with configured settings.
- Parameters:
timeout (int, optional) – Maximum compilation time in seconds (default: 300).
log_callback (callable, optional) – Called with each log line: log_callback(“Running pdflatex…”).
progress_callback (callable, optional) – Called with progress: progress_callback(50, “Pass 2/3”).
- Returns:
With success status, PDF path, and errors/warnings.
- Return type:
CompilationResult
Examples
>>> writer = Writer(Path("my_paper")) >>> result = writer.compile_manuscript() >>> if result.success: ... print(f"PDF created: {result.output_pdf}")
- compile_supplementary(timeout=300, log_callback=None, progress_callback=None)[source]
Compile supplementary materials to PDF with optional live callbacks.
Runs scripts/shell/compile_supplementary.sh with configured settings.
- Parameters:
timeout (int, optional) – Maximum compilation time in seconds (default: 300).
log_callback (callable, optional) – Called with each log line.
progress_callback (callable, optional) – Called with progress updates.
- Returns:
With success status, PDF path, and errors/warnings.
- Return type:
CompilationResult
Examples
>>> writer = Writer(Path("my_paper")) >>> result = writer.compile_supplementary() >>> if result.success: ... print(f"PDF created: {result.output_pdf}")
- compile_revision(track_changes=False, timeout=300, log_callback=None, progress_callback=None)[source]
Compile revision document with optional change tracking and live callbacks.
Runs scripts/shell/compile_revision.sh with configured settings.
- Parameters:
track_changes (bool, optional) – Enable change tracking in compiled PDF (default: False).
timeout (int, optional) – Maximum compilation time in seconds (default: 300).
log_callback (callable, optional) – Called with each log line.
progress_callback (callable, optional) – Called with progress updates.
- Returns:
With success status, PDF path, and errors/warnings.
- Return type:
CompilationResult
Examples
>>> writer = Writer(Path("my_paper")) >>> result = writer.compile_revision(track_changes=True) >>> if result.success: ... print(f"Revision PDF: {result.output_pdf}")
- get_section(section_name, doc_type='manuscript')[source]
Get a DocumentSection by name and document type.
- Parameters:
- Returns:
Section object with .read(), .write(), .commit(), .history(), .diff().
- Return type:
DocumentSection
- Raises:
ValueError – If doc_type is unknown or section_name not found.
- read_section(section_name, doc_type='manuscript')[source]
Read a section’s content as string.
- Parameters:
- Returns:
Section content. Empty string if section file is empty or missing.
- Return type:
Examples
>>> writer = Writer(Path("my_paper")) >>> text = writer.read_section("abstract") >>> text = writer.read_section("title", "shared")
- write_section(section_name, content, doc_type='manuscript')[source]
Write content to a section.
- Parameters:
- Returns:
True if write succeeded.
- Return type:
Examples
>>> writer = Writer(Path("my_paper")) >>> writer.write_section("abstract", "New abstract text.") True
- scitex_writer.ensure_workspace(project_dir, git_strategy='child', **kwargs)[source]
Ensure writer workspace exists at {project_dir}/.scitex/writer/.
If the directory already exists, returns the path without modification. If not, clones the full scitex-writer template.
- Parameters:
- Returns:
Path to the writer workspace directory.
- Return type:
- scitex_writer.gui(project_dir, port=5050, host='127.0.0.1', open_browser=True, desktop=False, hot_reload=False)
Launch the Django editor server locally.
Tries scitex_app._standalone.run_standalone first (gets the full workspace shell from scitex-ui). Falls back to a bare runserver bootstrap if scitex-app is not installed.
- Return type:
Submodules
scitex_writer.compile
Compilation functions for LaTeX manuscripts.
Usage:
import scitex_writer as sw
# Compile manuscript
result = sw.compile.manuscript("./my-paper")
# With options
result = sw.compile.manuscript("./my-paper", draft=True, no_figs=True)
# Compile other document types
result = sw.compile.supplementary("./my-paper")
result = sw.compile.revision("./my-paper", track_changes=True)
# Compile raw LaTeX content with color mode support
result = sw.compile.content(
latex_content,
project_dir="./my-paper", # Optional, for .preview/ output
color_mode="dark", # 'light' or 'dark'
)
- scitex_writer.compile.manuscript(project_dir, timeout=300, no_figs=False, no_tables=False, no_diff=False, draft=False, dark_mode=False, quiet=False, verbose=False, engine=None)[source]
Compile manuscript to PDF.
- Parameters:
project_dir (
str) – Path to scitex-writer project directory.timeout (
int) – Compilation timeout in seconds.no_figs (
bool) – Skip figure processing.no_tables (
bool) – Skip table processing.no_diff (
bool) – Skip diff generation.draft (
bool) – Fast single-pass compilation.dark_mode (
bool) – Enable dark mode output.quiet (
bool) – Suppress output.verbose (
bool) – Verbose output.engine (
str|None) – LaTeX engine override (‘tectonic’, ‘latexmk’, ‘3pass’).
- Return type:
- Returns:
Dict with success status, pdf_path, and any errors.
- scitex_writer.compile.supplementary(project_dir, timeout=300, no_figs=False, no_tables=False, no_diff=False, draft=False, quiet=False, engine=None)[source]
Compile supplementary materials to PDF.
- Parameters:
project_dir (
str) – Path to scitex-writer project directory.timeout (
int) – Compilation timeout in seconds.no_figs (
bool) – Skip figure processing.no_tables (
bool) – Skip table processing.no_diff (
bool) – Skip diff generation.draft (
bool) – Fast single-pass compilation.quiet (
bool) – Suppress output.engine (
str|None) – LaTeX engine override (‘tectonic’, ‘latexmk’, ‘3pass’).
- Return type:
- Returns:
Dict with success status, pdf_path, and any errors.
- scitex_writer.compile.revision(project_dir, track_changes=False, timeout=300, no_diff=True, draft=False, quiet=False, engine=None)[source]
Compile revision document to PDF.
- Parameters:
project_dir (
str) – Path to scitex-writer project directory.track_changes (
bool) – Enable change tracking.timeout (
int) – Compilation timeout in seconds.no_diff (
bool) – Skip diff generation.draft (
bool) – Fast single-pass compilation.quiet (
bool) – Suppress output.engine (
str|None) – LaTeX engine override (‘tectonic’, ‘latexmk’, ‘3pass’).
- Return type:
- Returns:
Dict with success status, pdf_path, and any errors.
- scitex_writer.compile.content(latex_content, project_dir=None, color_mode='light', name='content', timeout=60, keep_aux=False)[source]
Compile raw LaTeX content to PDF.
Creates a standalone document from the provided LaTeX content and compiles it to PDF. Supports light/dark color modes for comfortable viewing.
- Parameters:
latex_content (
str) – Raw LaTeX content to compile. Can be: - A complete document (with documentclass) - Document body only (will be wrapped automatically)project_dir (
str|None) – Optional path to scitex-writer project. If provided, PDF is copied to the project’s .preview/ directory.color_mode (
str) – Color theme: ‘light’ (default) or ‘dark’ (Monaco #1E1E1E).name (
str) – Name for the output (used in filename).timeout (
int) – Compilation timeout in seconds.keep_aux (
bool) – Keep auxiliary files (.aux, .log, etc.) after compilation.
- Return type:
- Returns:
Dict with success status, output_pdf path, log, and any errors.
Example:
import scitex_writer as sw # Compile simple content result = sw.compile.content( r"\section{Introduction}\nThis is my introduction.", color_mode="dark", )
scitex_writer.project
Project management functions.
Usage:
import scitex_writer as sw
# Create new project from template
result = sw.project.clone("./my-new-paper")
# Get project info
info = sw.project.info("./my-paper")
# Get path to compiled PDF
pdf = sw.project.get_pdf("./my-paper", "manuscript")
- scitex_writer.project.clone(project_dir, git_strategy='child', branch=None, tag=None)[source]
Create a new writer project from template.
- Parameters:
- Return type:
- Returns:
Dict with success status and project_path.
scitex_writer.bib
Bibliography management functions.
Usage:
import scitex_writer as sw
# List bib files
result = sw.bib.list_files("./my-paper")
# List entries
result = sw.bib.list_entries("./my-paper")
# Add an entry
sw.bib.add("./my-paper", "@article{Smith2024, ...}")
# Merge all bib files
sw.bib.merge("./my-paper")
- scitex_writer.bib.list_entries(project_dir, bibfile=None)[source]
List all BibTeX entries in the project or specific file.
- scitex_writer.bib.get(project_dir, citation_key)[source]
Get a specific BibTeX entry by citation key.
- scitex_writer.bib.add(project_dir, bibtex_entry, bibfile='custom.bib', deduplicate=True)[source]
Add a BibTeX entry to a bibliography file.
scitex_writer.tables
Table management functions.
Usage:
import scitex_writer as sw
# List tables in project
result = sw.tables.list("./my-paper")
# Add a table
sw.tables.add("./my-paper", "results", "col1,col2\n1,2", "Results summary")
# Convert CSV to LaTeX
result = sw.tables.csv_to_latex("data.csv", "table.tex")
- scitex_writer.tables.list(project_dir, doc_type='manuscript')[source]
List all tables in a writer project.
- scitex_writer.tables.add(project_dir, name, csv_content, caption, label=None, doc_type='manuscript')[source]
Add a new table (CSV + caption) to the project.
- Parameters:
- Return type:
- Returns:
Dict with csv_path, caption_path, label.
- scitex_writer.tables.remove(project_dir, name, doc_type='manuscript')[source]
Remove a table (CSV + caption) from the project.
- scitex_writer.tables.archive(project_dir, name, doc_type='manuscript')[source]
Move a table to legacy/ instead of deleting.
Moves CSV and caption files from caption_and_media/ to legacy/, preserving them for potential reuse or supplementary materials.
- scitex_writer.tables.csv_to_latex(csv_path, output_path=None, caption=None, label=None, longtable=False)[source]
Convert CSV file to LaTeX table format.
- Parameters:
- Return type:
- Returns:
Dict with latex_content and output_path.
scitex_writer.figures
Figure management functions.
Usage:
import scitex_writer as sw
# List figures in project
result = sw.figures.list("./my-paper")
# Add a figure
sw.figures.add("./my-paper", "fig01", "./plot.png", "Results plot")
# Convert figure format
sw.figures.convert("input.pdf", "output.png")
- scitex_writer.figures.list(project_dir, extensions=None)[source]
List all figures in a writer project.
- scitex_writer.figures.add(project_dir, name, image_path, caption, label=None, doc_type='manuscript')[source]
Add a figure (copy image + create caption) to the project.
- Parameters:
- Return type:
- Returns:
Dict with image_path, caption_path, label.
- scitex_writer.figures.remove(project_dir, name, doc_type='manuscript')[source]
Remove a figure (image + caption) from the project.
Removes all associated files including those in subdirectories (jpg_for_compilation/, mermaid_originals/).
- scitex_writer.figures.archive(project_dir, name, doc_type='manuscript')[source]
Move a figure to legacy/ instead of deleting.
Moves all associated files (tex, images, mermaid sources) from caption_and_media/ to legacy/, preserving them for potential reuse.
- scitex_writer.figures.convert(input_path, output_path, dpi=300, quality=95)[source]
Convert figure between formats (e.g., PDF to PNG).
scitex_writer.export
Export functions for manuscript packaging and arXiv compliance.
Usage:
import scitex_writer as sw
# Export manuscript as arXiv-ready tarball
result = sw.export.manuscript("./my-paper")
# Clean LaTeX for arXiv compliance
cleaned = sw.export.clean_latex(raw_latex)
# Check compliance
result = sw.export.check_compliance(title, abstract, latex_content)
# Validate file types in a directory
valid, invalid = sw.export.validate_file_types(Path("./my-paper"))
# Suggest arXiv categories from text
suggestions = sw.export.suggest_categories("deep learning neural network")
- scitex_writer.export.manuscript(project_dir, output_dir=None, format='arxiv')[source]
Export manuscript as arXiv-ready tarball.
scitex_writer.guidelines
IMRAD writing guidelines for scientific manuscripts.
Guidelines are templates/tips for writing manuscript sections. Prompts can be built from guidelines + user content.
Usage:
from scitex_writer.guidelines import get, build, list_sections
# Get raw guidelines
tips = get("abstract")
# Build prompt with draft
prompt = build("abstract", draft="My draft text...")
- Custom guidelines via environment variables:
SCITEX_WRITER_GUIDELINE_ABSTRACT=/path/to/custom.md SCITEX_WRITER_GUIDELINE_DIR=/path/to/guidelines/
- scitex_writer.guidelines.get(section)[source]
Get writing guidelines for a manuscript section.
- Parameters:
section (
str) – One of: abstract, introduction, methods, discussion, proofread- Return type:
- Returns:
Guidelines markdown content with PLACEHOLDER marker.
- Raises:
ValueError – If section is not recognized.
FileNotFoundError – If guidelines file not found.
scitex_writer.prompts
Action prompts for scientific manuscript workflows.
Currently provides AI2 Asta prompt generation for finding related papers and potential collaborators.
Usage:
from scitex_writer.prompts import generate_asta
result = generate_asta(project_path, search_type="related")
print(result["prompt"])
For IMRAD writing guidelines, use scitex_writer.guidelines instead.
- scitex_writer.prompts.generate_asta(project_path, search_type='related')
Generate AI2 Asta prompt from manuscript files.
This creates a prompt suitable for Semantic Scholar’s Asta AI to find related papers or potential collaborators.
- Parameters:
- Returns:
success: Whether generation succeeded
prompt: The generated prompt for AI2 Asta
search_type: The search type used
next_steps: List of suggested next steps
error: Error message if failed, None otherwise
- Return type:
Dictionary with
- Environment Variables:
SCITEX_WRITER_PROMPT_ASTA_RELATED: Custom template for related papers SCITEX_WRITER_PROMPT_ASTA_COAUTHORS: Custom template for collaborators
scitex_writer.writer
Writer class for manuscript LaTeX compilation.
Provides object-oriented interface to scitex-writer functionality.
- class scitex_writer.writer.Writer(project_dir, name=None, git_strategy='child', branch=None, tag=None)[source]
Bases:
objectLaTeX manuscript compiler.
- __init__(project_dir, name=None, git_strategy='child', branch=None, tag=None)[source]
Initialize for project directory.
If directory doesn’t exist, creates new project.
- Parameters:
project_dir (Path) – Path to project directory.
name (str, optional) – Project name (used if creating new project).
git_strategy (str, optional) – Git initialization strategy: - ‘child’: Create isolated git in project directory (default) - ‘parent’: Use parent git repository - ‘origin’: Preserve template’s original git history - None or ‘none’: Disable git initialization
branch (str, optional) – Specific branch of template repository to clone. If None, clones the default branch. Mutually exclusive with tag.
tag (str, optional) – Specific tag/release of template repository to clone. If None, clones the default branch. Mutually exclusive with branch.
- _attach_or_create_project(name=None)[source]
Create new project or attach to existing one.
If project directory doesn’t exist, creates it based on git_strategy: - ‘child’: Full template with git initialization - ‘parent’/’None’: Minimal directory structure
- Parameters:
name (str, optional) – Project name (used if creating new project).
- Returns:
Path to the project directory.
- Return type:
Path
- _verify_project_structure()[source]
Verify attached project has expected structure.
Checks: - Required directories exist (01_manuscript, 02_supplementary, 03_revision)
- Raises:
RuntimeError – If structure is invalid.
- Return type:
- compile_manuscript(timeout=300, log_callback=None, progress_callback=None)[source]
Compile manuscript to PDF with optional live callbacks.
Runs scripts/shell/compile_manuscript.sh with configured settings.
- Parameters:
timeout (int, optional) – Maximum compilation time in seconds (default: 300).
log_callback (callable, optional) – Called with each log line: log_callback(“Running pdflatex…”).
progress_callback (callable, optional) – Called with progress: progress_callback(50, “Pass 2/3”).
- Returns:
With success status, PDF path, and errors/warnings.
- Return type:
CompilationResult
Examples
>>> writer = Writer(Path("my_paper")) >>> result = writer.compile_manuscript() >>> if result.success: ... print(f"PDF created: {result.output_pdf}")
- compile_supplementary(timeout=300, log_callback=None, progress_callback=None)[source]
Compile supplementary materials to PDF with optional live callbacks.
Runs scripts/shell/compile_supplementary.sh with configured settings.
- Parameters:
timeout (int, optional) – Maximum compilation time in seconds (default: 300).
log_callback (callable, optional) – Called with each log line.
progress_callback (callable, optional) – Called with progress updates.
- Returns:
With success status, PDF path, and errors/warnings.
- Return type:
CompilationResult
Examples
>>> writer = Writer(Path("my_paper")) >>> result = writer.compile_supplementary() >>> if result.success: ... print(f"PDF created: {result.output_pdf}")
- compile_revision(track_changes=False, timeout=300, log_callback=None, progress_callback=None)[source]
Compile revision document with optional change tracking and live callbacks.
Runs scripts/shell/compile_revision.sh with configured settings.
- Parameters:
track_changes (bool, optional) – Enable change tracking in compiled PDF (default: False).
timeout (int, optional) – Maximum compilation time in seconds (default: 300).
log_callback (callable, optional) – Called with each log line.
progress_callback (callable, optional) – Called with progress updates.
- Returns:
With success status, PDF path, and errors/warnings.
- Return type:
CompilationResult
Examples
>>> writer = Writer(Path("my_paper")) >>> result = writer.compile_revision(track_changes=True) >>> if result.success: ... print(f"Revision PDF: {result.output_pdf}")
- get_section(section_name, doc_type='manuscript')[source]
Get a DocumentSection by name and document type.
- Parameters:
- Returns:
Section object with .read(), .write(), .commit(), .history(), .diff().
- Return type:
DocumentSection
- Raises:
ValueError – If doc_type is unknown or section_name not found.
- read_section(section_name, doc_type='manuscript')[source]
Read a section’s content as string.
- Parameters:
- Returns:
Section content. Empty string if section file is empty or missing.
- Return type:
Examples
>>> writer = Writer(Path("my_paper")) >>> text = writer.read_section("abstract") >>> text = writer.read_section("title", "shared")
- write_section(section_name, content, doc_type='manuscript')[source]
Write content to a section.
- Parameters:
- Returns:
True if write succeeded.
- Return type:
Examples
>>> writer = Writer(Path("my_paper")) >>> writer.write_section("abstract", "New abstract text.") True