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:

str

class scitex.writer.Writer(project_dir, name=None, git_strategy='child', branch=None, tag=None)[source]

Bases: object

LaTeX 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.

compile_manuscript(timeout=300, log_callback=None, progress_callback=None, runner=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}")

runner is the underlying compile implementation; it defaults to scitex_writer._compile.compile_manuscript(). Exposed so callers and tests can supply an alternate implementation without patching module internals.

compile_supplementary(timeout=300, log_callback=None, progress_callback=None, runner=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}")

runner defaults to scitex_writer._compile.compile_supplementary(); exposed for injection without patching module internals.

compile_revision(track_changes=False, timeout=300, log_callback=None, progress_callback=None, runner=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}")

runner defaults to scitex_writer._compile.compile_revision(); exposed for injection without patching module internals.

get_section(section_name, doc_type='manuscript')[source]

Get a DocumentSection by name and document type.

Parameters:
  • section_name (str) – Section name (e.g., ‘abstract’, ‘introduction’, ‘title’).

  • doc_type (str) – Document type: ‘shared’, ‘manuscript’, ‘supplementary’, or ‘revision’.

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:
  • section_name (str) – Section name (e.g., ‘abstract’, ‘introduction’).

  • doc_type (str) – Document type: ‘shared’, ‘manuscript’, ‘supplementary’, or ‘revision’.

Returns:

Section content. Empty string if section file is empty or missing.

Return type:

str

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:
  • section_name (str) – Section name (e.g., ‘abstract’, ‘introduction’).

  • content (str) – Content to write.

  • doc_type (str) – Document type: ‘shared’, ‘manuscript’, ‘supplementary’, or ‘revision’.

Returns:

True if write succeeded.

Return type:

bool

Examples

>>> writer = Writer(Path("my_paper"))
>>> writer.write_section("abstract", "New abstract text.")
True
watch(on_compile=None, runner=None)[source]

Auto-recompile on file changes.

runner defaults to scitex_writer._utils._watch.watch_manuscript(); exposed for injection without patching module internals.

Return type:

None

get_pdf(doc_type='manuscript')[source]

Get output PDF path (Read).

Return type:

Optional[Path]

delete()[source]

Delete project directory (Delete).

Return type:

bool

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:
  • project_dir (str or Path) – Root project directory. Writer workspace will be at {project_dir}/.scitex/writer/ (hidden, dotfile convention).

  • git_strategy (str, optional) – Git initialization strategy (‘child’, ‘parent’, ‘origin’, None).

  • **kwargs – Forwarded to Writer constructor (branch, tag, etc.).

Returns:

Path to the writer workspace directory.

Return type:

pathlib.Path

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:

None