janim-stdio-interact 0.1.3
A utility library for interacting with JAnim GUI via standard input/output
Requires Python: >=3.12

# JAnim Stdio Interact

[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://choosealicense.com/licenses/mit/)
[![PyPI Latest Release](https://img.shields.io/pypi/v/janim-stdio-interact.svg?style=flat&logo=pypi)](https://pypi.org/project/janim-stdio-interact/)

<div align="center">

**&gt; English &lt;** | [简体中文](README_zh_CN.md)

</div>

A utility library for interacting with JAnim GUI and managing windows via standard input/output

## Basic Usage

Interact with the JAnim GUI by passing JSON commands via stdio to open and close specific instances.

First, start the `janim-stdio-i` program:

```sh
janim-stdio-i host
```

For example, to compile a code snippet and build the Timeline within it for display in a preview window, send the following to `stdin`:

```json
{"type": "execute", "key": "id1", "source": "from janim.examples import *\nclass A(HelloJAnimExample): pass"}
```

You will see a preview window open displaying the classic `HelloJAnimExample`.

> [!WARNING]
> All commands sent to `stdin` must be on a single line. Multi-line commands will be truncated.

Here, `"key": "id1"` is used for window reuse. If you send an `execute` command with the same `key`, the Timeline in the existing window will be replaced without opening a new window.

```json
{"type": "execute", "key": "id1", "source": "from janim.examples import *\nclass A(RotatingPieExample): ..."}
```

Sending the command above replaces the `HelloJAnimExample` in the original window with `RotatingPieExample`.

> [!NOTE]
> If a code snippet contains multiple Timelines, the first one is used for the initial build.
>
> On subsequent rebuilds (replacements), it attempts to find a Timeline with the same name as the previous one; if not found, it defaults to the first one.

If we use a different `key`, for example:

```json
{"type": "execute", "key": "id2", "source": "from janim.examples import *\nclass A(ArrowPointingExample): ..."}
```

A new window will open. Essentially, one `key` corresponds to one window.

In addition to compiling and building Timelines via `stdin`, information generated by the GUI is returned via `stdout`. See below for details.

## API Reference

### `stdin`

-   `"type": "execute"`

    Required parameters:

    -   `"key"`: Unique identifier for the window.
    -   `"source"`: Source code for compilation.

    Compiles and builds the Timeline to display in the preview window.

    If the window corresponding to `key` already exists, the original Timeline in that window is replaced with the new one.

    Example:

    ```json
    {"type": "execute", "key": "id1", "source": "from janim.examples import *\nclass A(HelloJAnimExample): pass"}
    ```

-   `"type": "close"`

    Required parameters:

    -   `"key"`: Unique identifier for the window.

    Closes the window corresponding to `key`.

    Example:

    ```json
    {"type": "close", "key": "id1"}
    ```

### `stdout`

```json
{"type": "viewer-msg", "key": "...", "from": "...", "janim": { ... }}
```

| Field | Type | Description |
| :--- | :--- | :--- |
| `type` | `string` | Fixed as `"viewer-msg"`, identifying the message category |
| `key` | `string` | Corresponds to the identifier `key` used during creation |
| `from` | `string` | Sender source. Possible values: `"execute"`, `"close"`, `"gui"` |
| `janim` | `object` | The specific event payload, containing the event type and data |

When `"from": "execute"`, it represents the result of the `execute` command sent to `stdin`:

-   When source code compilation fails, the payload is

    ```json
    "janim": {"type": "error", "reason": "compile-failed"}
    ```

-   When the source code contains no usable Timeline, the payload is:

    ```json
    "janim": {"type": "error", "reason": "no-timeline"}
    ```

-   When the Timeline build fails, the payload is:

    ```json
    "janim": {"type": "error", "reason": "build-failed"}
    ```

-   When execution is successful, the payload is:

    ```json
    "janim": {"type": "success"}
    ```

When `"from": "close"`, it represents the result of the `close` command sent to `stdin`:

-   When no preview interface is found for the identifier, the payload is:

    ```json
    "janim": {"type": "error", "reason": "not-found"}
    ```

-   When executed successfully, the payload is:

    ```json
    "janim": {"type": "success"}
    ```

When `"from": "gui"`, it represents information generated by the GUI:

-   When the interface is created, the payload is:

    ```json
    "janim": {"type": "created"}
    ```

-   When the interface content is replaced, the payload is:

    ```json
    "janim": {"type": "rebuilt"}
    ```

-   When the preview progress changes, the payload is:

    ```json
    "janim": {"type": "lineno", "data": <current_line_number>}
    ```

-   When the interface is closed, the payload is:

    ```json
    "janim": {"type": "close_event"}
    ```