The distribution shipped sks/tns/ and the mdpdf command in the previous snapshot without either install guide mentioning them, so the only way to discover the command was to read env/runtime.env. Both source-install guides now describe it: what it is for (Markdown that is not Klammertext, rendered through a headless browser), that runtime.env defines it -- so a shell started before the installation does not have it -- the two things the distribution does not install (the renderer's virtual environment, created by "md_to_pdf.py --setup", and a Chromium-based browser), the MDPDF_* variables that change its defaults, and where the stylesheet is. (from dev d8ea0e973914)
8.8 KiB
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 (env/makefile.env) auto-detects the OS via uname.
1. Toolchain prerequisites
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.
# 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-configand a linkablelibpython. Apple's/usr/bin/python3does not ship a usablepython3-configand Apple discourages linking it — so a package-manager Python (Homebrew or MacPorts) is required. It coexists with Apple's;python3-configresolves to it when the manager'sbinis early onPATH(/opt/homebrew/binfor Homebrew,/opt/local/binfor MacPorts — both set up by their installers). For MacPorts,port select --set python3 python312makespython3andpython3-configresolve. makefile.envgets all Python include/link flags frompython3-configand auto-detects the package-manager prefix (/opt/homebrewor/opt/local, viaMACOS_PREFIX), so either manager works without edits. Override withmake MACOS_PREFIX=...if yours is installed elsewhere.
2. Image support (the @image klammer): OpenImageIO
# 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
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/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:
cd "$KLAMMERTEXT_HOME"
make -C com -j # optimized (-O3) by default; libklammertext.so + sks/*.so + bin/{ktext,kdesc,kdiag}
ktext -s '@eval 1 + 1 @' -d # smoke test — prints 2
(For a debug build with AddressSanitizer, intended for development, prefix
DEBUG=1: DEBUG=1 make -C com -j.)
For a document smoke test, create a small file and render it to HTML:
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:
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:
cat >> "$KLAMMERTEXT_HOME/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):
xelatex --version
ktext hello.kt -t pdf # writes hello.pdf
6. Optional: the mdpdf command (Markdown to PDF)
Klammertext ships a second, independent route in sks/tns/: mdpdf renders
a Markdown file to PDF through a headless browser, bypassing Klammertext
entirely. It is for a document that is not written in Klammertext — one you
have not converted yet, or one whose Markdown is not worth converting.
The command is a shell function that env/runtime.env defines, so if you
source that file (section 3) you already have it — in shells started after
the installation. In a shell that was already running, source it again:
source "$KLAMMERTEXT_HOME/env/runtime.env"
type mdpdf # mdpdf is a shell function
Two things it needs that the distribution does not install:
# 1. The Markdown renderer, in a virtual environment of its own. PEP 668
# forbids installing it into the system Python, so this is not optional
# and not a system package.
python3 "$KLAMMERTEXT_HOME/sks/tns/md_to_pdf.py" --setup
# 2. A Chromium-based browser -- Brave, Chrome or Chromium -- which is the
# renderer. Any one of them will do, and an .app in /Applications is
# found without being told where it is.
brew install --cask chromium
Then:
mdpdf notes.md # writes notes.pdf beside it
mdpdf notes # the .md may be left off
It supplies the fonts, the size matching and the code wrapping, and completes
on *.md at the TAB key. Each default is a variable you may set in
~/.zprofile — MDPDF_SERIF, MDPDF_SANS, MDPDF_MONO, MDPDF_MATCH,
MDPDF_WRAP, and MDPDF_BROWSER for a browser installed somewhere the
command does not look. Any option of the underlying md_to_pdf.py may also
be given on the command line, where it overrides the default:
mdpdf notes.md --paper letter --margin 0.75
The stylesheet it applies is sks/tns/markdown.css; copy it, edit the copy,
and pass --css yourcopy.css to render to your own taste.
7. Updating
To update an existing source installation to the latest version:
cd "$KLAMMERTEXT_HOME"
git pull
make -C com -j # rebuild library, SKS components, and commands (optimized)
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.envselects clang on Darwin automatically. - Do not run gcc-built binaries on macOS. GCC (Homebrew
g++-NNor MacPortsg++-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 examplestd::source_locationreturning a bad pointer, soMachine::Machine()walks intostrlenand SIGSEGVs). Always run the clang-built binary. (gcc-built binaries run fine on Linux.) - Switching compilers requires a full clean —
g++andclang++objects must not be mixed (ABI).make -C com redodoes a full clean rebuild acrossmac,sks, andcom; a partialmake -C mac cleandoes not.