A character written in the ^...^ mnemonic form -- ^oe^, ^zz^, ^hello^ --
used to kill ktext outright: no message, no output, and an exit status
that looked like a crash because it was one. Only the forms that happen
to spell hexadecimal digits escaped, and they were right by luck rather
than by reading. Any caret form that names no character is now a located
error that quotes what was written.
A klammer may now sit inside square brackets and braces as it already
could inside parentheses, and may be followed by the punctuation that
ends a sentence: [@i word@], {@b word@}, @i word@'s. The rule is a fixed
list of characters, because none of them can occur inside a klammer name
and so none of them is ambiguous next to a delimiter. A letter still
cannot: "x@" is the named closing delimiter, so a letter before "@" has
two readings and no rule can separate them.
The abbreviations an author writes -- the hyphen form @i-word, a klammer
glued to its neighbouring punctuation -- are now recognised as author
conveniences only. They are not applied to @@ definitions or @@@ system
commands, which are written by someone who needs no such shorthand and
whose forms are already whole.
Also fixed, each of them silent: an exported shell function in the
environment broke every @eval in the document; a line break written with
@nl was destroyed when it passed through a klammer that generates a
table, printing as \textbackslash{}newline in the finished PDF; and
"kdesc --coverage" shortened its file column by comparing the spelling of
a path rather than the path, so a klammer set reached by a symbolic link
showed a full path where its neighbours showed a short one.
New in the distribution: ref/, a small klammerset that describes the
Klammermachine's own tables in Klammertext. It currently provides the
character tables -- the diacritics and the extended Latin letters -- as
klammers that render to any target, so the documentation of what can be
written cannot drift from what the machine accepts. It is early, and
will grow.
The Klammertext taxonomy now has a section on targets, describes the
@@@klammerset system command alongside the other three, and states the
precedence of "^" -- what a caret means before a letter, a digit, a
punctuation character, and a quote, in one ordered list.
(from dev 6594c7ff8c1f)
Klammertext editor support
Editing support for Klammertext files (.kt documents and .k klammer
definitions) in four editors, built around one shared implementation.
| Directory | Contents |
|---|---|
shared/ |
The shared editor core (klammertext_edit.py) and the Klammertext language server (klammertext_ls.py). Everything structure-aware — indentation, table alignment, delimiter matching, delimiter diagnostics — implemented once, in dependency-free Python. |
emacs/ |
Emacs major mode. An independent elisp implementation of the same algorithms (Emacs cannot call Python per keystroke), held byte-equal to the shared core by the test suite. |
sublime/ |
Sublime Text package. Syntax file plus thin plugin wrappers that import the shared core directly (Sublime's plugin host is Python). |
vim/ |
Vim plugin. Syntax/ftplugin files plus commands that run the shared core's CLI; with +python3, the core also runs in-process (= operator, live match highlighting). |
vscode/ |
Visual Studio Code extension. TextMate grammar plus a dependency-free extension that spawns the language server and speaks LSP to it. |
The architecture
Klammertext's structural layer — @-run tiers, bar-run dimension,
^-escapes, # removal, literal spans, nesting depth — is independent of
both the Klammermachine and any klammer set, and every editor needs the
same operations on it. Those operations live in
shared/klammertext_edit.py:
- Indentation — 2 spaces per nesting level; bar runs and closing
delimiters sit at their opener's column;
@documentis transparent; verbatim/@eval/removed content is never touched. Explicit-only in every editor: whitespace is content in Klammertext. - Table alignment — pad a
@table's rows so the depth-0|separators line up (rows end with||; cells over 30 characters or spanning lines opt their row out; over 100 columns the command declines; never a space inside a bar run). - Delimiter matching — open ↔ close for klammer applications, literal klammers matched by name with opaque content, everything else by depth.
- Diagnostics — whole-buffer balance check over all three
@-tiers: unclosed openings, extra closes, name and tier mismatches, unclosed literal spans and#[blocks. - A CLI (
indent | align | match | checkover stdin/stdout) for editors that shell out (Vim), and for scripts.
shared/klammertext_ls.py puts a language server in front of the same
core: JSON-RPC over stdio, no dependencies. It serves publishDiagnostics,
document/range formatting (reindentation), documentHighlight and
definition (the matcher), and a klammertext.alignTable command. The
VS Code extension is its first client; any LSP client works — Neovim's
built-in LSP, Emacs eglot, Sublime's LSP package — with a one-line
configuration pointing at python3 klammertext_ls.py.
Syntax highlighting and cursor-latency features stay native in each editor (a tokenizer or a per-keystroke matcher cannot round-trip to Python), so each editor directory carries its own syntax artifact and, where relevant, its own thin glue.
Locating the shared core
The Sublime, Vim, and VS Code integrations find klammertext_edit.py (and
VS Code additionally klammertext_ls.py) in this order: a copy at the
integration's own root (the editing zip vendors one there, so each
unpacked folder is self-contained), ../shared/ relative to the
integration (this repository's layout — using an editor directory straight
from a checkout just works), then $KLAMMERTEXT_HOME/doc/edit/shared/.
Keeping things in sync
klammertext_edit.py is the source of truth for the policy lists
(LITERAL_KLAMMERS, TRANSPARENT_KLAMMERS, CODE_KLAMMERS,
ALIGN_KLAMMERS) and limits (INDENT_OFFSET, CELL_MAX, ROW_MAX).
Two kinds of artifact cannot read it and restate parts of it by hand:
- The Emacs mode — a full independent implementation with its own
defcustoms, checked byte-for-byte against the shared core by
tst/editor_test.sh. - The static syntax files — the literal-klammer set (
@code) appears in the Sublime.sublime-syntax, the Vimsyntax/klammertext.vim, and the VS CodetmLanguage.jsongrammar (and the Emacs defcustom). When you add a literal klammer, change them together; each file's header carries the same SYNC note.
Testing
tst/editor_test.sh (run by dbg/rebuild.sh and make -C tst test)
drives the fixture pairs in tst/editor/ through the shared core's API
and CLI, checks idempotence, checks the Emacs implementation for
byte-equality, runs the language server through a scripted LSP client
(ls_test.py), exercises the VS Code extension against the real server
under a stubbed VS Code API (vscode_ext_test.js), and runs the Vim
plugin's commands headlessly. Emacs, Vim, and Node/VS Code halves skip
gracefully where not installed.