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:
38
doc/install/klammertext.zsh
Normal file
38
doc/install/klammertext.zsh
Normal 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"
|
||||
}
|
||||
133
doc/install/linux_container_install.md
Normal file
133
doc/install/linux_container_install.md
Normal 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
|
||||
```
|
||||
277
doc/install/linux_source_install.md
Normal file
277
doc/install/linux_source_install.md
Normal 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.
|
||||
161
doc/install/macos_container_install.md
Normal file
161
doc/install/macos_container_install.md
Normal 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
|
||||
```
|
||||
171
doc/install/macos_source_install.md
Normal file
171
doc/install/macos_source_install.md
Normal 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.
|
||||
117
doc/install/texlive_additional_packages.sh
Normal file
117
doc/install/texlive_additional_packages.sh
Normal 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"
|
||||
Reference in New Issue
Block a user