Metadata-Version: 2.4
Name: kara-templater
Version: 0.1.0
Summary: Python karaoke template engine with native libass text metrics
License-Expression: MIT
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: vendor/LICENSE.libass
License-File: vendor/runtime-licenses/NOTICE.txt
License-File: vendor/runtime-licenses/acl/COPYING
License-File: vendor/runtime-licenses/acl/COPYING.LGPL
License-File: vendor/runtime-licenses/audit-libs/lgpl-2.1.txt
License-File: vendor/runtime-licenses/autoconf/COPYING
License-File: vendor/runtime-licenses/autoconf/COPYING.EXCEPTION
License-File: vendor/runtime-licenses/autoconf/COPYINGv3
License-File: vendor/runtime-licenses/automake/COPYING
License-File: vendor/runtime-licenses/bash/COPYING
License-File: vendor/runtime-licenses/binutils/COPYING
License-File: vendor/runtime-licenses/binutils/COPYING.LIB
License-File: vendor/runtime-licenses/binutils/COPYING3
License-File: vendor/runtime-licenses/binutils/COPYING3.LIB
License-File: vendor/runtime-licenses/brotli/LICENSE
License-File: vendor/runtime-licenses/bzip2-libs/LICENSE
License-File: vendor/runtime-licenses/bzip2/LICENSE
License-File: vendor/runtime-licenses/cairo/COPYING
License-File: vendor/runtime-licenses/cairo/COPYING-LGPL-2.1
License-File: vendor/runtime-licenses/cairo/COPYING-MPL-1.1
License-File: vendor/runtime-licenses/checkpolicy/COPYING
License-File: vendor/runtime-licenses/chkconfig/COPYING
License-File: vendor/runtime-licenses/coreutils-single/COPYING
License-File: vendor/runtime-licenses/cracklib/COPYING.LIB
License-File: vendor/runtime-licenses/crypto-policies/COPYING.LESSER
License-File: vendor/runtime-licenses/cryptsetup-libs/COPYING
License-File: vendor/runtime-licenses/cryptsetup-libs/COPYING.LGPL
License-File: vendor/runtime-licenses/cyrus-sasl-lib/COPYING
License-File: vendor/runtime-licenses/dbus-daemon/COPYING
License-File: vendor/runtime-licenses/dbus-glib/COPYING
License-File: vendor/runtime-licenses/dbus-libs/COPYING
License-File: vendor/runtime-licenses/dbus-tools/COPYING
License-File: vendor/runtime-licenses/device-mapper-libs/COPYING
License-File: vendor/runtime-licenses/device-mapper-libs/COPYING.LIB
License-File: vendor/runtime-licenses/device-mapper/COPYING
License-File: vendor/runtime-licenses/device-mapper/COPYING.LIB
License-File: vendor/runtime-licenses/diffutils/COPYING
License-File: vendor/runtime-licenses/dnf/COPYING
License-File: vendor/runtime-licenses/dnf/PACKAGE-LICENSING
License-File: vendor/runtime-licenses/elfutils-libelf/COPYING-GPLV2
License-File: vendor/runtime-licenses/elfutils-libelf/COPYING-LGPLV3
License-File: vendor/runtime-licenses/elfutils-libs/COPYING-GPLV2
License-File: vendor/runtime-licenses/elfutils-libs/COPYING-LGPLV3
License-File: vendor/runtime-licenses/environment-modules/COPYING.GPLv2
License-File: vendor/runtime-licenses/epel-release/GPL
License-File: vendor/runtime-licenses/expat/COPYING
License-File: vendor/runtime-licenses/file-libs/COPYING
License-File: vendor/runtime-licenses/file/COPYING
License-File: vendor/runtime-licenses/findutils/COPYING
License-File: vendor/runtime-licenses/fontconfig/COPYING
License-File: vendor/runtime-licenses/freetype/FTL.TXT
License-File: vendor/runtime-licenses/freetype/GPLv2.TXT
License-File: vendor/runtime-licenses/freetype/LICENSE.TXT
License-File: vendor/runtime-licenses/fribidi/COPYING
License-File: vendor/runtime-licenses/gawk/COPYING
License-File: vendor/runtime-licenses/gawk/LICENSE.BSD
License-File: vendor/runtime-licenses/gawk/LICENSE.GPLv2
License-File: vendor/runtime-licenses/gawk/LICENSE.LGPLv2
License-File: vendor/runtime-licenses/gcc/COPYING
License-File: vendor/runtime-licenses/gcc/COPYING.LIB
License-File: vendor/runtime-licenses/gcc/COPYING.RUNTIME
License-File: vendor/runtime-licenses/gcc/COPYING3
License-File: vendor/runtime-licenses/gcc/COPYING3.LIB
License-File: vendor/runtime-licenses/gdb/COPYING
License-File: vendor/runtime-licenses/gdb/COPYING.LIB
License-File: vendor/runtime-licenses/gdb/COPYING3
License-File: vendor/runtime-licenses/gdb/COPYING3.LIB
License-File: vendor/runtime-licenses/gdbm-libs/COPYING
License-File: vendor/runtime-licenses/glib2/COPYING
License-File: vendor/runtime-licenses/glibc/COPYING
License-File: vendor/runtime-licenses/glibc/COPYING.LIB
License-File: vendor/runtime-licenses/glibc/LICENSES
License-File: vendor/runtime-licenses/gmp/COPYING
License-File: vendor/runtime-licenses/gmp/COPYING.LESSERv3
License-File: vendor/runtime-licenses/gmp/COPYINGv2
License-File: vendor/runtime-licenses/gmp/COPYINGv3
License-File: vendor/runtime-licenses/gnupg2/COPYING
License-File: vendor/runtime-licenses/gnutls/COPYING
License-File: vendor/runtime-licenses/gnutls/COPYING.LESSER
License-File: vendor/runtime-licenses/gnutls/LICENSE
License-File: vendor/runtime-licenses/gpgme/COPYING
License-File: vendor/runtime-licenses/gpgme/COPYING.LESSER
License-File: vendor/runtime-licenses/gpgme/LICENSES
License-File: vendor/runtime-licenses/graphite2/COPYING
License-File: vendor/runtime-licenses/graphite2/LICENSE
License-File: vendor/runtime-licenses/grep/COPYING
License-File: vendor/runtime-licenses/groff-base/COPYING
License-File: vendor/runtime-licenses/groff-base/FDL
License-File: vendor/runtime-licenses/groff-base/LICENSES
License-File: vendor/runtime-licenses/guile/COPYING
License-File: vendor/runtime-licenses/guile/COPYING.LESSER
License-File: vendor/runtime-licenses/guile/LICENSE
License-File: vendor/runtime-licenses/gzip/COPYING
License-File: vendor/runtime-licenses/gzip/fdl-1.3.txt
License-File: vendor/runtime-licenses/hardlink/gpl-2.0.txt
License-File: vendor/runtime-licenses/harfbuzz/COPYING
License-File: vendor/runtime-licenses/hostname/gpl-2.0.txt
License-File: vendor/runtime-licenses/ima-evm-utils/COPYING
License-File: vendor/runtime-licenses/info/COPYING
License-File: vendor/runtime-licenses/iputils/bsd.txt
License-File: vendor/runtime-licenses/iputils/gpl-2.0.txt
License-File: vendor/runtime-licenses/isl/LICENSE
License-File: vendor/runtime-licenses/json-c/AUTHORS
License-File: vendor/runtime-licenses/json-c/COPYING
License-File: vendor/runtime-licenses/keyutils-libs/LICENCE.LGPL
License-File: vendor/runtime-licenses/kmod-libs/COPYING
License-File: vendor/runtime-licenses/krb5-libs/LICENSE
License-File: vendor/runtime-licenses/less/COPYING
License-File: vendor/runtime-licenses/less/LICENSE
License-File: vendor/runtime-licenses/libarchive/COPYING
License-File: vendor/runtime-licenses/libassuan/COPYING
License-File: vendor/runtime-licenses/libassuan/COPYING.LIB
License-File: vendor/runtime-licenses/libatomic_ops/COPYING
License-File: vendor/runtime-licenses/libatomic_ops/LICENSING.txt
License-File: vendor/runtime-licenses/libbabeltrace/LICENSE
License-File: vendor/runtime-licenses/libbabeltrace/gpl-2.0.txt
License-File: vendor/runtime-licenses/libbabeltrace/mit-license.txt
License-File: vendor/runtime-licenses/libcap-ng/COPYING.LIB
License-File: vendor/runtime-licenses/libcap/License
License-File: vendor/runtime-licenses/libcom_err/NOTICE
License-File: vendor/runtime-licenses/libcomps/COPYING
License-File: vendor/runtime-licenses/libcroco/COPYING
License-File: vendor/runtime-licenses/libcroco/COPYING.LIB
License-File: vendor/runtime-licenses/libcurl/COPYING
License-File: vendor/runtime-licenses/libdb/LICENSE
License-File: vendor/runtime-licenses/libdb/lgpl-2.1.txt
License-File: vendor/runtime-licenses/libdnf/COPYING
License-File: vendor/runtime-licenses/libfdisk/COPYING
License-File: vendor/runtime-licenses/libfdisk/COPYING.LGPLv2.1
License-File: vendor/runtime-licenses/libffi/LICENSE
License-File: vendor/runtime-licenses/libgcc/COPYING
License-File: vendor/runtime-licenses/libgcc/COPYING.LIB
License-File: vendor/runtime-licenses/libgcc/COPYING.RUNTIME
License-File: vendor/runtime-licenses/libgcc/COPYING3
License-File: vendor/runtime-licenses/libgcc/COPYING3.LIB
License-File: vendor/runtime-licenses/libgcrypt/COPYING.LIB
License-File: vendor/runtime-licenses/libgpg-error/COPYING
License-File: vendor/runtime-licenses/libgpg-error/COPYING.LIB
License-File: vendor/runtime-licenses/libicu-devel/LICENSE
License-File: vendor/runtime-licenses/libicu/LICENSE
License-File: vendor/runtime-licenses/libidn2/COPYING
License-File: vendor/runtime-licenses/libidn2/COPYING.LESSERv3
License-File: vendor/runtime-licenses/libidn2/COPYING.unicode
License-File: vendor/runtime-licenses/libidn2/COPYINGv2
License-File: vendor/runtime-licenses/libipt/LICENSE
License-File: vendor/runtime-licenses/libksba/COPYING
License-File: vendor/runtime-licenses/libksba/COPYING.GPLv2
License-File: vendor/runtime-licenses/libksba/COPYING.GPLv3
License-File: vendor/runtime-licenses/libksba/COPYING.LGPLv3
License-File: vendor/runtime-licenses/libmodulemd/COPYING
License-File: vendor/runtime-licenses/libmount/COPYING
License-File: vendor/runtime-licenses/libmount/COPYING.LGPLv2.1
License-File: vendor/runtime-licenses/libmpc/COPYING.LESSER
License-File: vendor/runtime-licenses/libnghttp2/COPYING
License-File: vendor/runtime-licenses/libnsl2/COPYING
License-File: vendor/runtime-licenses/libpciaccess/COPYING
License-File: vendor/runtime-licenses/libpipeline/COPYING
License-File: vendor/runtime-licenses/libpkgconf/COPYING
License-File: vendor/runtime-licenses/libpng/LICENSE
License-File: vendor/runtime-licenses/libpsl/COPYING
License-File: vendor/runtime-licenses/libpwquality/COPYING
License-File: vendor/runtime-licenses/libquadmath/COPYING.LIB.libquadmath
License-File: vendor/runtime-licenses/librepo/COPYING
License-File: vendor/runtime-licenses/libseccomp/LICENSE
License-File: vendor/runtime-licenses/libselinux/LICENSE
License-File: vendor/runtime-licenses/libsemanage/COPYING
License-File: vendor/runtime-licenses/libsepol/COPYING
License-File: vendor/runtime-licenses/libsigsegv/COPYING
License-File: vendor/runtime-licenses/libsmartcols/COPYING
License-File: vendor/runtime-licenses/libsmartcols/COPYING.LGPLv2.1
License-File: vendor/runtime-licenses/libsolv/LICENSE.BSD
License-File: vendor/runtime-licenses/libssh/COPYING
License-File: vendor/runtime-licenses/libtasn1/COPYING
License-File: vendor/runtime-licenses/libtasn1/COPYING.LIB
License-File: vendor/runtime-licenses/libtool-ltdl/COPYING.LIB
License-File: vendor/runtime-licenses/libtool/COPYING
License-File: vendor/runtime-licenses/libunistring/COPYING
License-File: vendor/runtime-licenses/libunistring/COPYING.LIB
License-File: vendor/runtime-licenses/libusbx/COPYING
License-File: vendor/runtime-licenses/libutempter/COPYING
License-File: vendor/runtime-licenses/libuuid/COPYING
License-File: vendor/runtime-licenses/libuuid/COPYING.BSD-3
License-File: vendor/runtime-licenses/libverto/COPYING
License-File: vendor/runtime-licenses/libwayland-client/COPYING
License-File: vendor/runtime-licenses/libwayland-server/COPYING
License-File: vendor/runtime-licenses/libxcrypt/AUTHORS
License-File: vendor/runtime-licenses/libxcrypt/COPYING.LIB
License-File: vendor/runtime-licenses/libxcrypt/LICENSING
License-File: vendor/runtime-licenses/libxkbcommon/LICENSE
License-File: vendor/runtime-licenses/libxml2/Copyright
License-File: vendor/runtime-licenses/libyaml/LICENSE
License-File: vendor/runtime-licenses/libzstd/COPYING
License-File: vendor/runtime-licenses/libzstd/LICENSE
License-File: vendor/runtime-licenses/m4/COPYING
License-File: vendor/runtime-licenses/make/COPYING
License-File: vendor/runtime-licenses/man-db/COPYING
License-File: vendor/runtime-licenses/mpdecimal/LICENSE.txt
License-File: vendor/runtime-licenses/mpfr/COPYING
License-File: vendor/runtime-licenses/mpfr/COPYING.LESSER
License-File: vendor/runtime-licenses/nasm/LICENSE
License-File: vendor/runtime-licenses/ncurses-base/COPYING
License-File: vendor/runtime-licenses/nettle/COPYING.LESSERv3
License-File: vendor/runtime-licenses/nettle/COPYINGv2
License-File: vendor/runtime-licenses/npth/COPYING.LIB
License-File: vendor/runtime-licenses/openldap/COPYRIGHT
License-File: vendor/runtime-licenses/openldap/LICENSE
License-File: vendor/runtime-licenses/openssl-libs/LICENSE
License-File: vendor/runtime-licenses/openssl/LICENSE
License-File: vendor/runtime-licenses/p11-kit/COPYING
License-File: vendor/runtime-licenses/pam/Copyright
License-File: vendor/runtime-licenses/pam/gpl-2.0.txt
License-File: vendor/runtime-licenses/patch/COPYING
License-File: vendor/runtime-licenses/pcre-utf16/COPYING
License-File: vendor/runtime-licenses/pcre-utf16/LICENCE
License-File: vendor/runtime-licenses/pcre-utf32/COPYING
License-File: vendor/runtime-licenses/pcre-utf32/LICENCE
License-File: vendor/runtime-licenses/pcre/COPYING
License-File: vendor/runtime-licenses/pcre/LICENCE
License-File: vendor/runtime-licenses/pcre2/COPYING
License-File: vendor/runtime-licenses/pcre2/LICENCE
License-File: vendor/runtime-licenses/perl-HTTP-Tiny/LICENSE
License-File: vendor/runtime-licenses/perl-IO-Socket-IP/LICENSE
License-File: vendor/runtime-licenses/perl-Net-SSLeay/LICENSE
License-File: vendor/runtime-licenses/perl-Socket/Artistic
License-File: vendor/runtime-licenses/perl-Socket/Copying
License-File: vendor/runtime-licenses/perl-Socket/LICENSE
License-File: vendor/runtime-licenses/perl-Term-ANSIColor/LICENSE
License-File: vendor/runtime-licenses/perl-Term-Cap/LICENSE
License-File: vendor/runtime-licenses/perl-Time-Local/LICENSE
License-File: vendor/runtime-licenses/perl-URI/LICENSE
License-File: vendor/runtime-licenses/perl-Unicode-Normalize/LICENSE
License-File: vendor/runtime-licenses/perl-libnet/Artistic
License-File: vendor/runtime-licenses/perl-libnet/Copying
License-File: vendor/runtime-licenses/perl-libnet/LICENCE
License-File: vendor/runtime-licenses/perl-libs/Artistic
License-File: vendor/runtime-licenses/perl-libs/Copying
License-File: vendor/runtime-licenses/perl-podlators/LICENSE
License-File: vendor/runtime-licenses/pkgconf/COPYING
License-File: vendor/runtime-licenses/platform-python-setuptools/LICENSE
License-File: vendor/runtime-licenses/platform-python/LICENSE
License-File: vendor/runtime-licenses/policycoreutils/COPYING
License-File: vendor/runtime-licenses/popt/COPYING
License-File: vendor/runtime-licenses/procps-ng/COPYING
License-File: vendor/runtime-licenses/procps-ng/COPYING.LIB
License-File: vendor/runtime-licenses/publicsuffix-list-dafsa/COPYING
License-File: vendor/runtime-licenses/python3-dateutil/LICENSE
License-File: vendor/runtime-licenses/python3-dbus/COPYING
License-File: vendor/runtime-licenses/python3-dnf-plugins-core/COPYING
License-File: vendor/runtime-licenses/python3-libs/LICENSE
License-File: vendor/runtime-licenses/python3-pip-wheel/LICENSE.txt
License-File: vendor/runtime-licenses/python3-setools/COPYING
License-File: vendor/runtime-licenses/python3-setools/COPYING.GPL
License-File: vendor/runtime-licenses/python3-setools/COPYING.LGPL
License-File: vendor/runtime-licenses/python3-setuptools-wheel/LICENSE
License-File: vendor/runtime-licenses/python3-six/LICENSE
License-File: vendor/runtime-licenses/python3-systemd/LICENSE.txt
License-File: vendor/runtime-licenses/python3.12-pip-wheel/LICENSE.txt
License-File: vendor/runtime-licenses/readline/COPYING
License-File: vendor/runtime-licenses/readline/USAGE
License-File: vendor/runtime-licenses/rpm/COPYING
License-File: vendor/runtime-licenses/sed/COPYING
License-File: vendor/runtime-licenses/setup/COPYING
License-File: vendor/runtime-licenses/shadow-utils/gpl-2.0.txt
License-File: vendor/runtime-licenses/shadow-utils/shadow-bsd.txt
License-File: vendor/runtime-licenses/systemd/LICENSE.GPL2
License-File: vendor/runtime-licenses/systemd/LICENSE.LGPL2.1
License-File: vendor/runtime-licenses/tar/COPYING
License-File: vendor/runtime-licenses/tpm2-tss/LICENSE
License-File: vendor/runtime-licenses/tzdata/LICENSE
License-File: vendor/runtime-licenses/unzip/COPYING.OLD
License-File: vendor/runtime-licenses/unzip/LICENSE
License-File: vendor/runtime-licenses/util-linux/COPYING.BSD-3
License-File: vendor/runtime-licenses/util-linux/COPYING.GPLv2
License-File: vendor/runtime-licenses/util-linux/COPYING.ISC
License-File: vendor/runtime-licenses/util-linux/COPYING.LGPLv2.1
License-File: vendor/runtime-licenses/util-linux/COPYING.UCB
License-File: vendor/runtime-licenses/valgrind-docs/COPYING.DOCS
License-File: vendor/runtime-licenses/valgrind-gdb/COPYING
License-File: vendor/runtime-licenses/valgrind-scripts/COPYING
License-File: vendor/runtime-licenses/valgrind/COPYING
License-File: vendor/runtime-licenses/which/COPYING
License-File: vendor/runtime-licenses/yasm/Artistic.txt
License-File: vendor/runtime-licenses/yasm/BSD.txt
License-File: vendor/runtime-licenses/yasm/COPYING
License-File: vendor/runtime-licenses/yasm/GNU_GPL-2.0
License-File: vendor/runtime-licenses/yasm/GNU_LGPL-2.0
License-File: vendor/runtime-licenses/zlib/README
Dynamic: license-file

# kara-templater

An ASS karaoke template engine rewritten in Python and C++. It runs without Aegisub or Lua.

The package keeps the karaoke templater's ASS template format, `$variables`, modifiers, and helper functions. **Expressions inside `!…!` and `code` lines use Python.** Lua code in existing templates must be rewritten manually; there is no Lua compatibility interpreter.

## Installation

Requires Python 3.12 or newer. Binary wheels target CPython 3.12–3.14 on Linux x86-64 (glibc 2.28+) and Windows 10+ x64. They include the native library dependencies; no compiler or MSYS2 installation is needed to use a wheel.

```sh
python -m pip install kara-templater
```

Install the fonts specified by your subtitle styles. Missing fonts use system font fallback, and different fonts can change the layout.

### Build from source on Linux

Install a C/C++ toolchain and native dependencies.

Arch Linux:

```sh
sudo pacman -S --needed base-devel python python-pip autoconf automake libtool nasm \
  freetype2 harfbuzz fribidi fontconfig libpng
```

Debian / Ubuntu, with Python 3.12+:

```sh
sudo apt install build-essential python3-dev python3-venv autoconf automake \
  libtool nasm pkg-config libfreetype-dev libharfbuzz-dev libfribidi-dev \
  libfontconfig-dev libpng-dev
```

From the project directory:

```sh
python -m venv .venv
. .venv/bin/activate
python -m pip install .
```

### Build from source on Windows

Use 64-bit Python from [python.org](https://www.python.org/downloads/windows/) and [MSYS2](https://www.msys2.org/). In the MSYS2 **UCRT64** shell, install the native toolchain:

```sh
pacman -Syu
pacman -S --needed patch mingw-w64-ucrt-x86_64-gcc \
  mingw-w64-ucrt-x86_64-pkgconf mingw-w64-ucrt-x86_64-nasm \
  mingw-w64-ucrt-x86_64-freetype mingw-w64-ucrt-x86_64-harfbuzz \
  mingw-w64-ucrt-x86_64-fribidi
```

Restart the shell and complete the update if MSYS2 requests it. Then, in **PowerShell** at the project directory, build and install a wheel. Adjust the MSYS2 path if it is not installed at `C:\msys64`.

```powershell
$env:Path = "C:\msys64\ucrt64\bin;C:\msys64\usr\bin;$env:Path"
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install delvewheel
python tools/collect_licenses.py
python -m pip wheel . --no-deps --wheel-dir dist
python -m delvewheel repair --strip --no-mangle libharfbuzz-0.dll --wheel-dir wheelhouse (Get-ChildItem dist\*.whl).FullName
python -m pip install --no-index --find-links wheelhouse kara-templater
```

The repaired wheel bundles the required DLLs so it can run without MSYS2 on the destination machine. Windows uses the system DirectWrite/GDI font provider.

## Command line

```sh
kara-templater input.ass output.ass
python -m kara_templater input.ass output.ass
```

Try the included example from a source checkout:

```sh
kara-templater examples/karaoke.ass output.ass
```

To correct horizontal coordinates for the video's actual dimensions:

```sh
kara-templater input.ass output.ass --video-size 1920 1080
```

Templates are ASS `Comment` events. Put the template type and modifiers in the **Effect** field. For example:

- Effect: `template syl noblank`
- Text: `!retime("syl")!{\an5\pos($scenter,$smiddle)\fad(50,80)}`

For lyrics such as `{\k50}你{\k50}好`, this generates one positioned effect event per nonblank syllable.

The output preserves templates, turns processed lyrics into comments with Effect `karaoke`, and marks generated events with Effect `fx`. Running the engine again removes old `fx` events and regenerates them.

## Python API

```python
from kara_templater import Document, Style, apply_templates, text_extents

source = Document.load("input.ass")
result = apply_templates(source)
result.save("output.ass")

width, height, descent, external_leading = text_extents(
    Style(fontname="Noto Sans CJK SC", fontsize=48), "你好"
)
```

`apply_templates` returns a new document without modifying its input. `Document.parse(text)` and `result.dumps()` support in-memory use.

## Templates

| Type | Behavior |
| --- | --- |
| `template syl`, or no explicit type | Generate effects per syllable, including the empty syllable at index 0; usually combined with `noblank` |
| `template char` / `template syl char` | Generate effects per Unicode code point, retaining syllable timing |
| `template line` | Concatenate the per-syllable template into one complete effect event |
| `template pre-line` | Prefix a complete event; use the same identifier to merge it with a `line` template |
| `template furi` | Generate effects for furigana |
| `code once / line / syl / furi` | Execute Python statements in that scope; defaults to `once` |

Modifiers include `all`, `repeat N` / `loop N`, `notext`, `keeptags`, `noblank`, `multi`, `fx NAME`, and `fxgroup NAME`. Templates match their own style by default; `all` matches every style. Unknown modifiers, variables, and execution errors report the template event number instead of being silently ignored.

- `\k`, `\K`, `\kf`, `\ko`: syllable duration in centiseconds.
- `\-NAME`: inline effect name, inherited by subsequent syllables.
- `#` / `＃`: continue the preceding syllable; `multi` runs the template separately for each highlight.
- `漢|かん` / `漢｜かん`: separate base text from furigana. A furigana prefix `!` starts a new group; `<` allows spillback to the left. Full-width prefixes are also accepted. A missing furigana style is created as `STYLE-furigana` at half the base font size.

### Variables and execution environment

`$variables` are case-insensitive:

- Line timing and indices: `$lstart`, `$lend`, `$ldur`, `$lmid`, `$li`, `$syln`.
- Syllable timing and indices: `$sstart`, `$send`, `$sdur`, `$skdur`, `$smid`, `$si`.
- Layout: prefix `l` or `s` to `left`, `center`, `right`, `width`, `top`, `middle`, `bottom`, `height`, `x`, or `y`.
- Current-scope aliases: `$start`, `$end`, `$dur`, `$kdur`, `$mid`, `$i`, and unprefixed layout variables.
- Other values: `$layer`, `$style`, `$actor`, `$margin_l`, `$margin_r`, `$margin_v`, `$margin_t`, `$margin_b`.

Expressions and code share Python variables. The environment provides `math`, `random`, `meta`, `styles`, `orgline`, `line`, `syl`, `basesyl`, `j`, `maxj`, `fxgroup`, and `text_extents`. `line` is the current mutable output event; in a code template it is the source lyric event. `syl` is a dictionary with attribute access.

Example Effect and Text pairs:

```text
code once                  → amplitude = 12
code line                  → fxgroup["spark"] = orgline.actor == "solo"
template syl repeat 3      → !retime("syl")!{\an5\pos(!$x + amplitude * j!,$y)}
```

An expression returning `None` produces an empty string. Integral floating-point values are written without a trailing `.0`.

### Helpers

- `retime(mode, addstart=0, addend=0)`: modes are `syl`, `presyl`, `postsyl`, `line`, `preline`, `postline`, `start2syl`, `syl2end`, `sylpct`, and `set` / `abs`. Offsets are milliseconds, except that `sylpct` uses percentages of syllable duration. Timing is based on the current `line`, so consecutive calls use the previously modified times.
- `relayer(layer)`, `restyle(style)`: modify the current output event.
- `maxloop(count)` / `maxloops(count)`, `loopctl(j, count)`: control template loops dynamically.
- `remember(name, value, decorator=None)`, `recall(name, default=None)`, `remember_if(name, value, condition, decorator=None)`: store and retrieve values. The optional decorator is a Python function mapping a name to a memory key.
- `remember_line`, `remember_syl`, `remember_basesyl`: isolate remembered values by source event, current syllable, or base syllable.

## Limitations and safety

- **Only process trusted subtitles.** Python expressions and code have the permissions of the current process. This is not a sandbox. Template iteration and output limits cannot stop arbitrary Python code from looping forever or performing malicious operations.
- The defaults are 10,000 iterations per template loop and 100,000 output events. The Python API accepts `max_iterations` and `max_output_lines` to change these limits.
- Only ASS v4.00+ is supported, not legacy SSA styles. Extra fields, unknown sections, and attachments are preserved, but byte-for-byte formatting is not guaranteed.
- Layout targets single-line karaoke using the base style. It does not simulate automatic wrapping, event collisions, inline style overrides, `\pos` / `\move`, or drawing geometry. `text_extents` supports `\N` hard breaks; syllable layout is not multiline-aware.
- `text_extents` returns logical advance width, font height, and descent, not visible glyph bounds. It preserves edge spaces and measures braces literally. External leading is always `0`. Pixel-identical results across fonts, platforms, or Aegisub's native font interfaces are not guaranteed.
- No GUI, video/audio processing, Automation plugin interface, or other Aegisub features are included.
