Metadata-Version: 2.4
Name: drawio2tikz
Version: 0.6.0
Summary: Convert diagrams.net/draw.io diagrams to TikZ via SVG.
Keywords: drawio,diagrams.net,svg,tikz,latex
Author: Daiki Okayama
Author-email: Daiki Okayama <lawliet.d.k.m@gmail.com>
License-Expression: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Classifier: Topic :: Multimedia :: Graphics :: Editors :: Vector-Based
Classifier: Topic :: Text Processing :: Markup :: LaTeX
Requires-Dist: defusedxml>=0.7.1
Requires-Dist: fastapi>=0.123
Requires-Dist: idna>=3.15
Requires-Dist: pillow>=12.3.0
Requires-Dist: python-multipart>=0.0.31
Requires-Dist: rich>=15.0
Requires-Dist: starlette>=1.3.1
Requires-Dist: typer>=0.15
Requires-Dist: uvicorn[standard]>=0.38
Requires-Python: >=3.14
Project-URL: Homepage, https://github.com/okayama-daiki/drawio2tikz
Project-URL: Issues, https://github.com/okayama-daiki/drawio2tikz/issues
Description-Content-Type: text/markdown

# drawio2tikz

`drawio2tikz` converts draw.io diagrams to TikZ code for embedding in LaTeX documents.

## Features

- Converts either a single draw.io page or all pages
- Converts multiple draw.io files from the web UI
- Preserves label colors, bold text, font sizes, and simple line breaks
- **Ignores draw.io font family names**, allowing output to use the host LaTeX document font
- Removes draw.io SVG CSS that cannot be represented in TikZ, including `light-dark(...)` from draw.io's dark mode color scheme
- Restores draw.io labels emitted as SVG `foreignObject` elements, which draw.io exports as HTML fragments

## Requirements

- **Python 3.14 or newer**
- **`drawio` CLI** available on `PATH` (install from [diagrams.net](https://diagrams.net) or via Homebrew: `brew install --cask drawio`)

## Installation

### pip / uv

Install from PyPI:

```bash
uv tool install drawio2tikz
```

Or with pip:

```bash
pip install drawio2tikz
```

### Development Setup

Clone the repository and install in development mode:

```bash
git clone https://github.com/okayama-daiki/drawio2tikz.git
cd drawio2tikz
uv sync
uv run drawio2tikz --help
```

## Usage

### Basic Usage

Convert a single page from a draw.io file to TikZ:

```bash
drawio2tikz path/to/figure.drawio -o output_dir
```

This generates `figure.tex` in the output directory.

### Convert All Pages

To convert all pages in a multi-page `.drawio` file:

```bash
drawio2tikz path/to/multipage.drawio --all-pages -o output_dir
```

Each page is saved as `multipage-01.tex`, `multipage-02.tex`, and so on.

### Keep Intermediate SVG

To debug or inspect the intermediate SVG (after sanitization):

```bash
drawio2tikz path/to/figure.drawio -o output_dir --keep-svg --svg-dir output_dir/svg
```

### View Help

```bash
drawio2tikz --help
```

## Web App

Run the FastAPI web UI locally:

```bash
uv sync
uv run drawio2tikz-web
```

Then open <http://localhost:8000>.

The conversion API is available at `POST /api/convert` with multipart form data:

- `file`: one or more `.drawio`, `.drawio.png`, or `.xml` files
- `page_index`: 1-based page index, default `1`
- `all_pages`: convert every page, default `false`
- `keep_svg`: include the sanitized intermediate SVG, default `false`

### Docker

Build and run the web app:

```bash
docker build -t drawio2tikz .
docker run --rm -p 8000:8000 drawio2tikz
```

On Apple Silicon, build the amd64 image because the Dockerfile installs the draw.io Desktop `.deb` package:

```bash
docker build --platform linux/amd64 -t drawio2tikz .
docker run --rm --platform linux/amd64 -p 8000:8000 drawio2tikz
```

### Cloud Run deployment

Pushes to `main` run the full CI suite and then deploy the amd64 container to the
`drawio2tikz` Cloud Run service in `asia-northeast1`. GitHub Actions authenticates with
Workload Identity Federation, so the repository does not store a Google Cloud service-account
key.

The deployment keeps Cloud Run at zero minimum instances, one maximum instance, and one
concurrent request per instance. After Cloud Run imports the image, CI deletes the temporary
Artifact Registry copy; a one-day cleanup policy handles interrupted runs as a fallback.

Cloud Run uses the dedicated `drawio2tikz-runtime` service account. It has no project-level role
and can access only the `drawio2tikz-origin-auth` Secret Manager secret. The GitHub deployer is
restricted to updating the existing Cloud Run service, pushing/deleting transient images in the
single Artifact Registry repository, and acting as that runtime service account. Its Workload
Identity Federation trust is limited to this repository's immutable GitHub ID and the `main`
branch.

The workflow expects these GitHub Actions repository variables:

- `GCP_WORKLOAD_IDENTITY_PROVIDER`
- `GCP_DEPLOY_SERVICE_ACCOUNT`

### Custom domain

The public custom domain is <https://drawio2tikz.daiki.dev>. A small Cloudflare Worker in
`cloudflare/` streams requests to Cloud Run. Cloudflare manages the DNS record and TLS certificate
through a Worker Custom Domain configured once in the Cloudflare dashboard. The domain is
intentionally not declared in `cloudflare/wrangler.jsonc`, so CI cannot modify zone routes.

Cloudflare deployment expects these GitHub Actions repository secrets:

- `CLOUDFLARE_ACCOUNT_ID`
- `CLOUDFLARE_API_TOKEN`
- `ORIGIN_AUTH_TOKEN`

The Cloudflare token needs only `Account / Workers Scripts / Edit` for the selected account; it
needs no zone permission. The origin token is installed as a Cloudflare Worker secret and a Cloud
Run Secret Manager reference. Direct requests to the public `run.app` URL are rejected without
that header.

## Security

The web service limits each upload to 10 MiB, combined uploads to 20 MiB, requests to 10 files,
draw.io documents to 50 pages, decompressed diagram XML to 20 MiB, and draw.io export processes to
120 seconds. XML parsing disables DTD and entity expansion. Browser responses carry a restrictive
content security policy and related security headers.

The generated TikZ intentionally preserves raw TeX entered in draw.io labels. Treat output from
untrusted diagrams as untrusted source code: inspect it before compiling and do not enable TeX
shell escape for untrusted output.

## LaTeX Setup

Add these packages to your LaTeX document preamble:

```tex
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{amsmath}
```

Include the generated TikZ file:

```tex
\input{path/to/figure.tex}
```

For support of arbitrary large font sizes, use a scalable font:

```tex
\usepackage{mlmodern}
```

### Example LaTeX Document

```tex
\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{amsmath}
\usepackage{mlmodern}

\begin{document}

\section{My Diagram}

\begin{figure}
  \centering
  \input{figures/diagram.tex}
  \caption{A diagram created in draw.io}
\end{figure}

\end{document}
```

## Contributing

Contributions are welcome! Please feel free to open issues or submit pull requests on [GitHub](https://github.com/okayama-daiki/drawio2tikz).

## License

MIT
