Initial commit: Klammertext source distribution

Curated source subset assembled by klammertext-dev's doc/make_dist.sh: the Klammermachine (mac), the Standard Klammer Set (sks), the commands (com), editor plugins and install guides (doc), a test subset (tst), and lib/bin placeholders. Builds with 'make -C com'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-18 18:48:23 +02:00
commit 2ba7ceee7a
272 changed files with 27634 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
# Klammertext via Apple's `container` — macOS (Apple Silicon) shell wrapper
# -----------------------------------------------------------------------------
# Lets you run Klammertext without typing the full `container run ...` command.
# Install: save this file (e.g. ~/klammertext.zsh) and add to your ~/.zshrc:
#
# source ~/klammertext.zsh
#
# Then open a new terminal and use `ktext`, `kdesc`, `kdiag` like normal
# commands. Requires Apple Silicon + macOS 26 or later, with Apple's
# `container` runtime installed and its service started (`container system
# start`). Install `container` from the signed .pkg at
# https://github.com/apple/container/releases (NOT Homebrew). See
# doc/install/macos_container_install.md for the full guide.
# -----------------------------------------------------------------------------
# The published image is multi-arch; on Apple Silicon `container` pulls the
# native arm64 build, so no --platform / --rosetta is needed.
KLAMMERTEXT_IMAGE="${KLAMMERTEXT_IMAGE:-akopra/klammertext:latest}"
_klammertext_run() {
local cmd="$1"; shift
container run --rm \
-v "$PWD:/work" -w /work \
"$KLAMMERTEXT_IMAGE" "$cmd" "$@"
}
# The three Klammertext commands. Files are read from and written to the
# current directory (mounted into the container as /work).
ktext() { _klammertext_run ktext "$@"; }
kdesc() { _klammertext_run kdesc "$@"; }
kdiag() { _klammertext_run kdiag "$@"; }
# Download or update to the latest published image (delete first so the moving
# `latest` tag is definitely refreshed).
klammertext-update() {
container image delete "$KLAMMERTEXT_IMAGE" 2>/dev/null
container image pull "$KLAMMERTEXT_IMAGE"
}

View File

@@ -0,0 +1,133 @@
# Running Klammertext on Linux with Docker
This guide runs Klammertext on a Linux system (Ubuntu or Pop!_OS — the steps are
identical) using the prebuilt Docker container. You do **not** need to install
TeX Live, Python, or any programming tools — everything, including the TeX Live
system that makes PDFs, is packaged inside a single downloadable image. You
install Docker once, then Klammertext works like a normal command.
The published image is multi-arch, so Docker pulls the build matching your CPU
(`amd64` on Intel/AMD, `arm64` on ARM machines) automatically.
For a source build instead (full `@eval` access, no Docker), see
`linux_source_install.md`.
## Step 1 — Install Docker
```bash
sudo apt-get update
sudo apt-get install docker.io
sudo usermod -aG docker $USER
```
Log out and back in for the group change to take effect (so you can run `docker`
without `sudo`). You only do this once.
## Step 2 — Download Klammertext
```bash
docker pull akopra/klammertext:latest
```
This downloads Klammertext and its built-in TeX Live (a few hundred megabytes).
You won't need to do it again unless you're updating.
## Step 3 — Add the Klammertext commands
Add these aliases to `~/.bashrc` (or `~/.zshrc`) so `ktext`, `kdesc`, and
`kdiag` work as ordinary commands that read and write files in whatever folder
you run them from:
```bash
alias ktext='docker run --rm -u $(id -u):$(id -g) -v "$PWD:/work" -w /work akopra/klammertext ktext'
alias kdesc='docker run --rm -v "$PWD:/work" -w /work akopra/klammertext kdesc'
alias kdiag='docker run --rm -v "$PWD:/work" -w /work akopra/klammertext kdiag'
```
The `-u $(id -u):$(id -g)` on `ktext` makes output files owned by you rather than
root. `kdesc` and `kdiag` only read files, so they don't need it. The
`-v "$PWD:/work"` mounts your current directory into the container as `/work`,
which is required for the commands to see your files.
Reload your shell (open a new terminal, or `source ~/.bashrc`).
## Step 4 — Make your first document
In a folder you want to work in, create a test file:
```bash
cat > hello.kt <<'EOF'
@document
:structure article
:title Hello
:text
@s1 Hello, Klammertext @
This document was produced with no TeX Live installed — just Docker and the
Klammertext image.
@
EOF
```
Produce a web page and a PDF:
```bash
ktext hello.kt -t html # makes hello/index.html
ktext hello.kt -t pdf # makes hello.pdf
```
That's it — you're running Klammertext.
## Updating
To update to the latest published image:
```bash
docker pull akopra/klammertext:latest
```
## Haskell support (`@eval :haskell`)
The standard image does not include Haskell. For `@eval :haskell`, pull the
Haskell image and use it in place of the standard one:
```bash
docker pull akopra/klammertext:haskell
alias ktext='docker run --rm -u $(id -u):$(id -g) -v "$PWD:/work" -w /work akopra/klammertext:haskell ktext'
```
Test:
```bash
ktext -s '@eval :haskell main = putStrLn "hello" @' -d
```
Alternatively, a source install gives all `@eval` modes without a separate image
(see `linux_source_install.md`).
## Klammer set loading
The Standard Klammer Set is loaded by default. To load a different klammer set,
pass `-k PATH` (the klammer set's `.k` file). To run with only the three
primitive klammers (`@read`, `@eval`, `@cond`), use `-k none`.
## If something goes wrong
- **`Cannot connect to the Docker daemon`** — the Docker service isn't running:
`sudo systemctl start docker`, then retry.
- **`permission denied` running `docker`** — your user isn't in the `docker`
group yet: `sudo usermod -aG docker $USER`, then log out and back in.
- **`No such file or directory` for your input** — the file must be in the
directory you run the command from (that's what gets mounted). `cd` into the
folder with your `.kt` files first.
- **Output files owned by root** — add `-u $(id -u):$(id -g)` to the `ktext`
command/alias (as shown in Step 3).
## Freeing disk space
To remove the image (you can re-pull it later):
```bash
docker rmi akopra/klammertext:latest
docker system prune # optional: remove all unused Docker data
```

View File

@@ -0,0 +1,277 @@
# Klammertext source installation on Linux (Ubuntu / Pop!_OS)
This document describes how to build and install Klammertext from source on a
Linux system — Ubuntu or Pop!_OS; the steps are identical — without using the
container. A source installation gives full access to all `@eval` modes,
including `:haskell` and `:shell` commands that depend on locally installed
software.
For the container installation on Linux, see `linux_container_install.md`.
## Prerequisites
The following packages are required to build Klammertext:
```bash
sudo apt-get update
sudo apt-get install g++ make python3-dev
```
The C++ compiler must support C++20. GCC 11 or later is required (Ubuntu 22.04
and later include GCC 12+).
The SKS `@image` klammer requires OpenImageIO Python bindings. These must match
the Python version that ktext is built against (check with
`python3.XX -c "import OpenImageIO"`). For example, if ktext links against
Python 3.12:
```bash
pip3.12 install OpenImageIO
```
Verify:
```bash
g++ --version
```
## Clone the repository
```bash
git clone https://git.andykopra.com/ack/klammertext.git
cd klammertext
```
## Environment variables
Klammertext's runtime environment is provided by a single self-configuring
file. Source it from your shell profile (e.g., `~/.bashrc` or `~/.zshrc`):
```bash
source /path/to/klammertext/mac/env/runtime.env
```
It self-locates `KLAMMERTEXT_HOME` from its own path, adds `bin/` and
`tst/` to `PATH` (plus the newest `~/external/texlive/<year>/bin/<arch>` if a
TeX Live is installed there), sets `LD_LIBRARY_PATH` so `libklammertext.so` is
found, and sets the LSan suppressions. There is no per-host or per-OS variable
to set. For a TeX Live or library in a non-standard location, add it to an
optional, gitignored `mac/env/runtime.env.local` (sourced at the end).
After editing your shell profile, reload it:
```bash
source ~/.bashrc
```
## Configure the build
No build configuration is needed. The single `mac/env/makefile.env` is
cross-platform: it reads `KLAMMERTEXT_HOME` from the environment (set by
`runtime.env` above), auto-detects the platform with `uname`, and auto-detects
Python with `python3-config` — no hardcoded version and no per-host file to
edit. Verify the Python development headers are present:
```bash
python3-config --includes # prints -I.../python3.XX for your Python
```
If `python3-config` is missing, install your distribution's `python3-dev`
(Debian/Ubuntu) or `python3-devel` (Fedora/RHEL) package.
## Build
Build the shared library, the SKS components, and the three commands with a
single command: `make -C com` builds its prerequisites in `mac/` and `sks/`
first, then the commands. `OPTIMIZE=1` selects an optimized `-O3` build (what
you want to install and run); without it you get a slower `-O0` debug build
with AddressSanitizer, intended for development:
```bash
make -C com -j OPTIMIZE=1 # lib/libklammertext.so + sks/*.so + bin/{ktext,kdesc,kdiag}
```
Verify the build:
```bash
ktext -s '@eval 1 + 1 @' -d
```
This should print `2`. For a quick document smoke test, create a small file and
render it to HTML:
```bash
cat > hello.kt <<'EOF'
@document
:structure article
:title Hello
:text
@s1 Hello, Klammertext @
This document was built from source.
@
EOF
ktext hello.kt -t html # writes hello/index.html
```
## TeX Live (for PDF output)
The Standard Klammer Set uses **XeLaTeX** for the `pdf` target. Build a complete
Klammertext TeX Live tree with the bundled script, giving it a destination
directory under `~/external/texlive/<year>` — the location `runtime.env`
auto-detects. The script needs `perl`, `xz-utils`, `fontconfig`, and either
`wget` or `curl`:
```bash
sudo apt-get install perl wget xz-utils fontconfig
bash $KLAMMERTEXT_HOME/doc/install/texlive_additional_packages.sh ~/external/texlive/2026
```
This installs `scheme-small` plus the additional packages the SKS needs and
rebuilds all formats, fetching the binaries for your architecture. It writes a
`KLAMMERTEXT_BUILD_INFO.txt` provenance file (mirror, release, package list,
date) into the tree.
Because the tree lives under `~/external/texlive/2026`, `runtime.env` finds it
automatically — open a new shell (or re-source `runtime.env`) and `xelatex`
will be on `PATH`. No manual `KLAMMERTEXT_TEXLIVE_BIN` is needed.
If you would rather reuse a TeX Live you already have, point `runtime.env` at it
from the gitignored escape hatch instead, and install the SKS's extra packages
into it yourself (the package list is in `doc/install/texlive_additional_packages.sh`):
```bash
cat >> "$KLAMMERTEXT_HOME/mac/env/runtime.env.local" <<'EOF'
export KLAMMERTEXT_TEXLIVE_BIN=/path/to/texlive/bin/x86_64-linux
export PATH="$KLAMMERTEXT_TEXLIVE_BIN:$PATH"
EOF
```
Verify and test (reusing the `hello.kt` from the Build section):
```bash
xelatex --version
ktext hello.kt -t pdf # writes hello.pdf
```
## Optional: Haskell (for @eval :haskell)
The `@eval :haskell` mode requires `runghc`, which is part of the Haskell
toolchain. Alternatively, the `akopra/klammertext:haskell` container image
includes GHC (see `linux_container_install.md`).
The recommended way to install Haskell on Ubuntu is via ghcup:
```bash
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
```
Follow the prompts to install GHC, cabal, and related tools. After
installation, ensure the ghcup bin directory is in your `PATH`:
```bash
export PATH=$HOME/.ghcup/bin:$PATH
```
Verify:
```bash
runghc --version
```
Test in Klammertext:
```bash
ktext -s '@eval :haskell main = putStr "Hello from Haskell" @' -d
```
## Directory layout after build
```
klammertext/
├── bin/ ktext, kdesc, kdiag executables (after build)
├── lib/ libklammertext.so shared library (after build)
├── mac/ Klammermachine C++ source
├── sks/ Standard Klammer Set (.k files and .so modules)
│ ├── document/ document.so
│ ├── kutil/ kutil.o
│ └── target/ html_util.o, latex_util.o
├── com/ command source (ktext, kdesc, kdiag) and Makefile
├── doc/ installation guides (doc/install) and editor support (doc/edit)
└── tst/ test suites
```
## Verifying the installation
Run the following commands to verify that everything works:
```bash
# Basic evaluation (Python)
ktext -s '@eval 1 + 1 @' -d
# Shell evaluation
ktext -s '@eval :shell date @' -d
# Show machine state (SKS is loaded by default)
ktext -s '' -m
# HTML and PDF output (uses the hello.kt from the Build section)
ktext hello.kt -t html
ktext hello.kt -t pdf # requires TeX Live
# Haskell evaluation (requires ghcup)
ktext -s '@eval :haskell main = putStr "42" @' -d
# Run unit tests
make -C $KLAMMERTEXT_HOME/tst test
```
## Updating
To update an existing source installation to the latest version:
```bash
cd $KLAMMERTEXT_HOME
git pull
make -C com -j OPTIMIZE=1 # rebuild library, SKS components, and commands
```
The TeX Live tree only needs rebuilding if the SKS's package requirements
changed (rare); when they do, re-run the script from the TeX Live section
above.
## Troubleshooting
**"libklammertext.so: cannot open shared object file"**
Ensure `LD_LIBRARY_PATH` includes `$KLAMMERTEXT_HOME/lib`:
```bash
export LD_LIBRARY_PATH=$KLAMMERTEXT_HOME/lib:$LD_LIBRARY_PATH
```
**"KLAMMERTEXT_HOME is not set"**
Set the environment variable as described in the Environment variables
section above.
**"python3.XX/Python.h: No such file or directory"**
Install the Python development headers:
```bash
sudo apt-get install python3-dev
```
**"xelatex: command not found" (when using -t pdf)**
Install TeX Live and ensure its bin directory is in `PATH`.
**"@eval :haskell requires runghc"**
Install Haskell via ghcup as described in the Optional: Haskell section.

View File

@@ -0,0 +1,161 @@
# Running Klammertext on a Mac (Apple Silicon)
This guide gets Klammertext running on your Mac in a few minutes. You do
**not** need to install TeX Live, Python, or any programming tools —
everything, including the TeX Live system that makes PDFs, is packaged inside
a single downloadable image. You install Apple's `container` runtime once, and
then Klammertext works like a normal command.
This guide is for **Apple Silicon Macs (M1/M2/M3/M4/M5) running macOS 26 or
later**, which is what Apple's `container` runtime requires. (Support for older
Intel Macs can be provided separately if needed.)
## Step 1 — Install Apple's `container` runtime
`container` is Apple's own tool for running Linux container images natively on
Apple Silicon. It's free.
1. Go to <https://github.com/apple/container/releases> and download the latest
installer package (the `.pkg` file). **Do not** use Homebrew — the Homebrew
`container` formula is a different, unrelated tool.
2. Double-click the downloaded `.pkg` and follow the installer.
3. Open the **Terminal** app (Applications → Utilities → Terminal) and start the
`container` background service (accept the recommended default if prompted):
```sh
container system start
```
You only do this once. You can check the service any time with
`container system status`.
## Step 2 — Download Klammertext
In Terminal, paste this and press Return:
```sh
container image pull akopra/klammertext:latest
```
This downloads Klammertext and its built-in TeX Live. It's a few hundred
megabytes, so it takes a minute the first time. Because the image is multi-arch,
`container` fetches the native Apple Silicon (arm64) build. You won't need to do
this again unless you're updating.
## Step 3 — Add the Klammertext commands
This step makes `ktext` (and its helpers) available as ordinary commands.
1. In Terminal, create the wrapper file by pasting this whole block and
pressing Return:
```sh
cat > ~/klammertext.zsh <<'EOF'
# Klammertext via Apple's `container` runtime (native arm64 image; no Rosetta).
KLAMMERTEXT_IMAGE="${KLAMMERTEXT_IMAGE:-akopra/klammertext:latest}"
_klammertext_run() {
local cmd="$1"; shift
container run --rm \
-v "$PWD:/work" -w /work \
"$KLAMMERTEXT_IMAGE" "$cmd" "$@"
}
ktext() { _klammertext_run ktext "$@"; }
kdesc() { _klammertext_run kdesc "$@"; }
kdiag() { _klammertext_run kdiag "$@"; }
klammertext-update() {
container image delete "$KLAMMERTEXT_IMAGE" 2>/dev/null
container image pull "$KLAMMERTEXT_IMAGE"
}
EOF
```
2. Tell your shell to load it, by pasting this and pressing Return:
```sh
echo 'source ~/klammertext.zsh' >> ~/.zshrc
```
3. **Close Terminal and open a new window** so the change takes effect.
You now have three commands — `ktext`, `kdesc`, `kdiag` — that run Klammertext
inside a container while reading and writing files in whatever folder you're
working in.
## Step 4 — Make your first document
In Terminal, go to a folder you want to work in (for example your Desktop) and
create a test file:
```sh
cd ~/Desktop
cat > hello.kt <<'EOF'
@document
:structure article
:title Hello
:text
@s1 Hello, Klammertext @
This document was produced on macOS with no TeX Live installed —
just Apple's `container` runtime and the Klammertext image.
@
EOF
```
Now produce a web page and a PDF from it:
```sh
ktext hello.kt -t html # makes hello/index.html
ktext hello.kt -t pdf # makes hello.pdf
```
Open the results:
```sh
open hello.pdf
open hello/index.html
```
That's it — you're running Klammertext.
## Good to know
- **Work inside one folder.** Klammertext can only see files in (or below) the
folder you run the command from. Keep a document and the files it uses
together, and run `ktext` from that folder.
- **Runs natively.** On Apple Silicon, `container` runs the native arm64 image
with no Rosetta translation.
- **Fonts.** The default fonts (Crimson Pro, Open Sans, Inconsolata) are built
in, so PDFs work with no internet connection. If you ask for a different font
by name, Klammertext downloads it from Google Fonts the first time, which
needs an internet connection.
- **Updating later.** When a new version is announced, run `klammertext-update`
in Terminal.
- **If you also build Klammertext from source on this Mac.** Most people don't —
the whole point of the container is that you don't need a source build. But if
this machine *also* has a native source build on its `PATH` (so `which ktext`
shows a path like `.../K/com/ktext`), the wrapper's `ktext` function would
shadow that native command. To keep both, give the container wrappers their
own names by using `ktextc` / `kdescc` / `kdiagc` (trailing `c` = container)
in place of `ktext` / `kdesc` / `kdiag` in the Step 3 file. Then plain `ktext`
still runs your source build and `ktextc` runs the container.
- **Quitting.** Klammertext only runs while you're using it; there's nothing
left running afterward. If you want to stop the `container` service entirely,
run `container system stop`; start it again with `container system start` next
time.
## If something goes wrong
- **`command not found: ktext`** — you didn't open a new Terminal window after
Step 3, or the `source` line didn't get added. Re-run the Step 3 commands and
open a fresh Terminal.
- **`container: command not found`** — the `container` runtime isn't installed
(Step 1), or the Terminal window predates the install (open a new one).
- **A command hangs or won't connect** — the `container` service isn't running.
Run `container system start` (check with `container system status`), then try
again.
- **A run aborted and now seems stuck** — `container run --rm` can leave the
container behind after an error. Clear leftovers with:
```sh
for id in $(container list -a -q); do container kill "$id"; container delete "$id"; done
```

View File

@@ -0,0 +1,171 @@
# Klammertext source installation on macOS (Apple Silicon)
Companion to `linux_source_install.md`. Verified on an Apple-Silicon Mac
(arm64, macOS 26 "Tahoe"). Klammertext's core (engine, SKS, HTML/LaTeX,
`@image`) builds and runs natively with Apple Clang; the cross-platform build
environment (`mac/env/makefile.env`) auto-detects the OS via `uname`.
## 1. Toolchain prerequisites
```sh
xcode-select --install # Command Line Tools (clang, headers) — if not already present
```
Then install Python with a linkable `libpython` and `python3-config`, using
whichever package manager you have — **Homebrew** or **MacPorts**. Both work;
only the install prefix differs, and the build auto-detects it.
```sh
# Homebrew (https://brew.sh):
brew install python
brew install gcc # OPTIONAL: a second compiler for a standards check
# MacPorts (https://www.macports.org) — provisional, pending testing on a
# MacPorts system:
sudo port install python312
sudo port select --set python3 python312 # so python3 / python3-config resolve
sudo port install gcc14 # OPTIONAL: a second compiler for a standards check
```
Notes:
- The build embeds Python, which needs `python3-config` and a linkable
`libpython`. Apple's `/usr/bin/python3` does **not** ship a usable
`python3-config` and Apple discourages linking it — so a package-manager
Python (Homebrew or MacPorts) is required. It coexists with Apple's;
`python3-config` resolves to it when the manager's `bin` is early on `PATH`
(`/opt/homebrew/bin` for Homebrew, `/opt/local/bin` for MacPorts — both set up
by their installers). For MacPorts, `port select --set python3 python312`
makes `python3` and `python3-config` resolve.
- `makefile.env` gets all Python include/link flags from `python3-config` and
auto-detects the package-manager prefix (`/opt/homebrew` or `/opt/local`, via
`MACOS_PREFIX`), so either manager works without edits. Override with
`make MACOS_PREFIX=...` if yours is installed elsewhere.
## 2. Image support (the `@image` klammer): OpenImageIO
```sh
# Homebrew:
/opt/homebrew/bin/pip3.<N> install --break-system-packages OpenImageIO
# e.g. pip3.14 — match your Python's version
# MacPorts (matches the python312 installed above):
sudo port install py312-openimageio
```
This provides the OpenImageIO Python bindings the embedded interpreter uses.
With pip, the self-contained PyPI wheel goes into that Python's site-packages;
`--break-system-packages` is needed because the Python is PEP-668 "externally
managed". (Homebrew alternative: `brew install openimageio`, heavier — it pulls
ffmpeg/openexr/etc.)
## 3. Clone and configure the environment
```sh
git clone https://git.andykopra.com/ack/klammertext.git ~/projects/klammertext
# Set up the runtime environment (KLAMMERTEXT_HOME, PATH); add to ~/.zprofile:
echo 'source "$HOME/projects/klammertext/mac/env/runtime.env"' >> ~/.zprofile
```
The single self-configuring `runtime.env` self-locates `KLAMMERTEXT_HOME` from
its own path. On macOS it sets no `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH`
(`libklammertext.so` is found via the binaries' `@loader_path` rpath, and
`document.so` is dlopen'd by absolute path under `$KLAMMERTEXT_HOME`) and no
`LSAN_OPTIONS` (LeakSanitizer is unsupported on macOS).
## 4. Build (Apple Clang)
Clang is the compiler you run on macOS, and it is the **default** here
(`makefile.env` selects clang on Darwin), so no `COMPILER=` flag is needed.
A single `make -C com` builds its prerequisites in `mac/` and `sks/` first,
then the commands:
```sh
cd "$KLAMMERTEXT_HOME"
make -C com -j OPTIMIZE=1 # libklammertext.so + sks/*.so + bin/{ktext,kdesc,kdiag}
ktext -s '@eval 1 + 1 @' -d # smoke test — prints 2
```
For a document smoke test, create a small file and render it to HTML:
```sh
cat > hello.kt <<'EOF'
@document
:structure article
:title Hello
:text
@s1 Hello, Klammertext @
This document was built from source.
@
EOF
ktext hello.kt -t html # writes hello/index.html
```
(A PDF render needs TeX Live — see section 5.)
## 5. PDF target: TeX Live
Build a complete Klammertext TeX Live tree with the bundled script, into
`~/external/texlive/<year>` — the location `runtime.env` auto-detects
(`bin/universal-darwin`). macOS already has `curl`, `perl`, and `tar`, and
`install-tl` self-provides `xz`, so nothing extra is needed:
```sh
bash "$KLAMMERTEXT_HOME/doc/install/texlive_additional_packages.sh" ~/external/texlive/2026
```
This installs `scheme-small` plus the SKS's additional packages and rebuilds all
formats, fetching the `universal-darwin` binaries, and writes a
`KLAMMERTEXT_BUILD_INFO.txt` provenance file into the tree. **This is the same
command used on Linux**, so the TeX Live layout is identical across your
machines. `runtime.env` then finds the tree automatically — open a new shell (or
re-source it) and `xelatex` is on `PATH`; no manual `KLAMMERTEXT_TEXLIVE_BIN` is
needed.
If you already run BasicTeX/MacTeX and prefer to reuse it, point `runtime.env`
at its bin directory from the gitignored escape hatch instead (and install the
SKS's extra packages into it yourself — the list is in the script). Set the
variable **and** prepend it to `PATH`, since `runtime.env.local` is sourced
after the main `PATH` is built:
```sh
cat >> "$KLAMMERTEXT_HOME/mac/env/runtime.env.local" <<'EOF'
export KLAMMERTEXT_TEXLIVE_BIN=/usr/local/texlive/2025basic/bin/universal-darwin
export PATH="$KLAMMERTEXT_TEXLIVE_BIN:$PATH"
EOF
```
Verify and test (reusing `hello.kt` from section 4):
```sh
xelatex --version
ktext hello.kt -t pdf # writes hello.pdf
```
## 6. Updating
To update an existing source installation to the latest version:
```sh
cd "$KLAMMERTEXT_HOME"
git pull
make -C com -j OPTIMIZE=1 # rebuild library, SKS components, and commands
```
Rebuild the TeX Live tree only if the SKS's package requirements changed (rare);
re-run the script from section 5.
## Compiler notes (macOS)
- **Clang is the compiler you run, and the default here.** Apple Clang builds
run correctly; `makefile.env` selects clang on Darwin automatically.
- **Do not run gcc-built binaries on macOS.** GCC (Homebrew `g++-NN` or MacPorts
`g++-mp-NN`) is useful only as an optional compile-time standards check
(`make -C com COMPILER=gcc`); the resulting binaries **crash at runtime** on
macOS because of a gcc/macOS codegen issue (for example `std::source_location`
returning a bad pointer, so `Machine::Machine()` walks into `strlen` and
SIGSEGVs). Always run the clang-built binary. (gcc-built binaries run fine on
Linux.)
- **Switching compilers requires a full clean** — `g++` and `clang++` objects
must not be mixed (ABI). `make -C com redo` does a full clean rebuild across
`mac`, `sks`, and `com`; a partial `make -C mac clean` does not.

View File

@@ -0,0 +1,117 @@
#!/bin/bash
# Build a self-contained TeX Live tree for the Klammertext SKS "tex"/"pdf"
# targets: scheme-small plus the additional packages the SKS requires, with
# all formats rebuilt. This is the single source of truth for constructing a
# Klammertext TeX Live directory — used both by the Docker build (Dockerfile,
# per-arch) and for native installs.
#
# Usage:
# texlive_additional_packages.sh <texdir> [mirror]
#
# <texdir> Destination directory for the TeX Live tree (created by
# install-tl), e.g. /opt/texlive or ~/external/texlive/2026.
# Should not already exist.
# [mirror] A CONCRETE tlnet mirror URL. Must NOT be the mirror.ctan.org
# redirect: it resolves to a different mirror (possibly a different
# TeX Live revision) on each call, which makes tlmgr abort partway
# with "tlmgr itself needs to be updated". Defaults to a pinned
# CTAN mirror. Once the current TeX Live year is frozen (the next
# release ships), point this at the historic tlnet-final snapshot
# for exact reproducibility, e.g.
# https://ftp.math.utah.edu/pub/texlive/historic/2026/tlnet-final
#
# install-tl fetches the binaries for the ARCHITECTURE it runs on, so running
# this under arm64 produces an arm64 tree and under x86_64 an x86_64 tree.
#
# Prerequisites on the host: perl, tar, gzip, xz (xz-utils), and either wget or
# curl (macOS ships curl, not wget). fontconfig is recommended so fmtutil can
# build all formats cleanly.
set -eux
TEXDIR="${1:?usage: $0 <texdir> [mirror]}"
MIRROR="${2:-https://ctan.math.illinois.edu/systems/texlive/tlnet}"
# --- Fetch the installer into a scratch dir --------------------------------
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
cd "$WORK"
# Fetch the installer with whichever downloader is present (macOS has curl, not
# wget; Debian build images have wget).
if command -v wget >/dev/null 2>&1; then
wget -q "$MIRROR/install-tl-unx.tar.gz"
else
curl -fsSL -O "$MIRROR/install-tl-unx.tar.gz"
fi
tar --strip-components=1 -xzf install-tl-unx.tar.gz
# --- Base install: scheme-small into $TEXDIR -------------------------------
cat > texlive.profile <<PROFILE
selected_scheme scheme-small
TEXDIR $TEXDIR
TEXMFLOCAL $TEXDIR/texmf-local
TEXMFSYSCONFIG $TEXDIR/texmf-config
TEXMFSYSVAR $TEXDIR/texmf-var
tlpdbopt_install_docfiles 0
tlpdbopt_install_srcfiles 0
tlpdbopt_autobackup 0
PROFILE
# install-tl's in-line fmtutil can exit 3 before all packages are present;
# that is non-fatal (install-tl continues) and the formats are rebuilt below.
./install-tl --profile=texlive.profile --repository="$MIRROR"
# --- Use the tlmgr from the tree we just built (absolute path), not whatever
# tlmgr may be on PATH. Pin its repo to the same concrete mirror and sync
# it to that repo's revision before installing more packages. -----------
ARCH="$(ls "$TEXDIR/bin")"
TLMGR="$TEXDIR/bin/$ARCH/tlmgr"
"$TLMGR" option repository "$MIRROR"
"$TLMGR" update --self
# --- Additional packages required by the SKS beyond scheme-small -----------
# Single list, used both for the install and for the provenance README below,
# so the two cannot drift apart.
PACKAGES="adjustbox collectbox collection-fontsrecommended enumitem fontaxes \
footmisc inconsolata layouts mdframed multirow needspace opensans pict2e \
textpos titlesec upquote zref"
# shellcheck disable=SC2086 # intentional word splitting into separate args
"$TLMGR" install $PACKAGES
# --- Rebuild every format now that the full package set is installed -------
"$TEXDIR/bin/$ARCH/fmtutil-sys" --all
# --- Provenance: record how this tree was constructed ----------------------
# Written into the tree itself so it is self-documenting when found later.
RELEASE="$(head -n1 "$TEXDIR/release-texlive.txt" 2>/dev/null || echo unknown)"
BUILT="$(date -u '+%Y-%m-%d %H:%M:%S UTC')"
cat > "$TEXDIR/KLAMMERTEXT_BUILD_INFO.txt" <<INFO
Klammertext TeX Live tree
=========================
Built for the Klammertext Standard Klammer Set (SKS) "tex"/"pdf" targets by
doc/install/texlive_additional_packages.sh.
Built: $BUILT
Mirror: $MIRROR
TeX Live: $RELEASE
Architecture: bin/$ARCH
Base scheme: scheme-small
Docfiles/srcfiles omitted; all formats rebuilt with fmtutil-sys --all.
Additional packages installed beyond scheme-small:
$(printf ' %s\n' $PACKAGES)
Reconstruct an equivalent tree with:
texlive_additional_packages.sh <texdir> $MIRROR
Note: the mirror above serves the CURRENT TeX Live release, which receives
package updates within its year, so a rebuild is not guaranteed byte-identical.
For exact reproducibility, rebuild from the frozen historic tlnet-final
snapshot once the release year is no longer current, e.g.
https://ftp.math.utah.edu/pub/texlive/historic/<year>/tlnet-final
INFO
echo "Klammertext TeX Live tree built in $TEXDIR (binaries in bin/$ARCH)"
echo "Provenance written to $TEXDIR/KLAMMERTEXT_BUILD_INFO.txt"