A named group of optional parameters, declared once and used by several
klammers, so a writer learns one vocabulary instead of a spelling per
klammer. The "o" target is a pseudo-target beside "k": "k" declares a
klammer's interface and documents it, "o" declares an option interface and
documents it, and neither produces output for any target.
@@caption_args.o :caption :number.bool true :caption_side.side
: Arguments that define a caption for a block element @@
@@code.k :filename @hpos_args :hpos left @ @caption_args :caption_side top @
| text.literal : A source file displayed verbatim @@
A set is used only in the parameter list of a ".k" declaration -- the one
place a klammer's interface is declared once for all of its targets -- and
is resolved as that list is read. Names and types come from the set; a
default may be overridden where it is used. A klammer application in a
parameter list is now a definition-time error.
The SKS gains the sets caption_args and hpos_args (:hpos and :offset), and
@table, @image, @image_grid, @reference and @show gain .k declarations. A
distance is no longer written as a position: :hpos 4em is rejected, and the
same layout is :hpos left :offset 4em. Code listings are numbered by
default, like tables and figures.
New engine sources mac/option_set{,_registry}.{h,cpp}; tst/ ships two more
suites, option_set_test.sh and signature_test.sh (twelve in all).
(from dev 34e536cb0329)
A klammer that reaches itself, directly or through a cycle, expanded
until the C++ stack was exhausted: the process died from SIGSEGV with no
message and no location. The former limit guarded only the top-level
fixed-point iteration, never the descent through klammer application. A
depth guard now raises a recursion error naming the klammer and where it
was applied. The same loop's termination test moves from "the katom list
stopped growing" to "a pass applied no klammer", since a klammer whose
body expands to nothing is a reduction that adds no katoms; exceeding the
round limit is now an error rather than a message followed by rendering a
document with live klammers still in it.
ktext --check locates every klammer application written in a document or
in a klammer body and checks name existence, argument count, option
names, and target coverage without applying anything, reporting all
problems at once. This is possible because Klammertext has no catcodes:
katom structure is fixed when a file is read, so a klammer body has a
determinate shape before it is expanded. The check therefore reaches what
the engine cannot -- the branch of a @cond that is not selected, and
bodies a given render never enters.
@cond's set of truth values is an open language question, so its meaning
is unchanged here; an unrecognized predicate now warns, giving its value
and location.
tst/ gains recursion_test.sh (7 cases) and check_test.sh (19 cases), and
this snapshot's test Makefile is generated from the shipped suite list so
the two cannot drift apart.
(from dev c27e63802406)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The four defaulted parameters in html_util.h stayed by-value while the
definition became const&, leaving the called overload undefined.
Linux's -shared linking hid it (lazy dlopen resolution); it broke the
book-structure HTML path at runtime. Both sides now agree (const&,
defaults kept); combine_files converted consistently as well.
(from dev a910e11431d2)
The @@@klammerset system command formally declares a klammerset — a
named, logically related group of klammer definitions — with an
operative, idempotent declaration (:requires and :files load in order
at the declaration point, relative to the declaring file). A bare
symbol given to ktext -k, kdesc --input, or :requires resolves to
x/x.k on the search path: the document's directory, then
KLAMMERTEXT_KLAMMERSETS, then KLAMMERTEXT_HOME; kdesc --klammerset
lists the available sets. sks/sks.k is the first declared klammerset,
so `-k sks` loads the SKS by name. The engine's lookup classes were
renamed *_set → *_registry to keep the two concepts apart, and the
whole C++ tree now follows standard const-correctness conventions.
tst/ gains klammerset_test.sh (18 cases).
(from dev 64b1abf23e56)
Two development changes since the last snapshot.
perf(build): com/Makefile's recursive $(MAKE) commands inherited no
jobserver, so kdiag, kdesc and ktext linked one after another even though
they are independent links against the already-built library. A clean
rebuild drops from 27.9 s to 23.1 s on an i9-14900KF and from 16.4 s to
13.8 s on an M5 Pro.
fix(list): LaTeX's built-in enumerate and itemize stop at four levels, so
a deeper @ol or @ul failed with "Too deeply nested". sks/list/sty/list.sty
now redefines both through enumitem to allow nine, with explicit per-level
itemize markers, since \renewlist discards the built-in ones.
(from dev 15b822f06ee0)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
klammertext-align.el calls string-trim, string-blank-p, and
string-empty-p without requiring subr-x. Newer Emacs has that library
loaded already; on Emacs 27 -- what Ubuntu 22.04 and Pop!_OS 22.04 ship
-- the symbols are void and table alignment fails with "Symbol's
function definition is void: string-blank-p". The README now states
Emacs 27.1 as the supported floor.
(from dev 43a4ce7dea2a)
Case 5 of the module-resolution suite failed on macOS only, because /var
is a symlink to /private/var there: `mktemp -d` returns an unresolved
path while Python's os.getcwd() reports the resolved one, so the test
compared two spellings of the same directory. Resolving the temp
directory once at creation with `pwd -P` makes every path in the suite
consistent.
(from dev ca9eaa2c867a)
An optional argument has three values: the default (the name is absent),
the argument type's :alone value (the name is written alone), and a
written value.
:alone is declared by the argument type only, never by a klammer's
parameter declaration -- a default is what one klammer means by silence,
but a bare option name must read the same way in every klammer. The bool
type declares :alone true, which is the whole of the convention that a
bare boolean option means true; there is no boolean special case in the
engine. A type whose pattern matches running text cannot declare :alone,
since an option's value runs to the next bar or option name and would
swallow the following text.
kdesc and `ktext -m` now show [default: X] and [alone: Y] per argument
type.
In the Standard Klammer Set: @code :number becomes a bool (it was an
untyped string tested only for truthiness, so a bare :number was a
no-op); decimal_mark declares :alone comma; table_hline and table_vline
declare :alone all. The 35 bools that default false gained the bare form
for free.
Tests: tst/alone_test.sh (21 cases) joins the shipped suite.
(from dev 6024f49c2859)
@date/@datetime gain :lang (German: "16. Juni 1910") over a document-wide
Language state variable, and :number for the numeric form (en 6/16/1910,
de 16.06.1910 per DIN 5008). @eval finds Python modules next to the file
that names them regardless of the cwd, and the new :cwd option runs an
eval in a chosen working directory (@source_file uses it to resolve
against the document). Two new test suites ship in tst/.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Folder copies into ~/.vscode/extensions no longer load in modern VS Code;
make_vsix.sh packages the extension (bash + python3 only) and the README
installs it with `code --install-extension`.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
doc/edit/ now holds a shared Python implementation of the language's
structural layer (klammertext_edit.py) and a dependency-free language
server (klammertext_ls.py), with integrations for Emacs, Sublime Text,
Vim, and Visual Studio Code. The editor test suite in tst/ covers the
core's API and CLI, the language server protocol, the VS Code
extension, headless Vim, and Emacs byte-equality.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Filenames may contain spaces: quote on the command line; filename
lists use a standalone "/" separator; unseparated names that do not
exist are rejoined into names that do (announced); leading ~ expands.
- Without -o, output is written to the input file's directory; -o fully
specifies the output directory and basename.
- "Word not parsed" warnings now appear without -v, only for text that
survives removal, with correct line numbers.
- New tst/filename_test.sh regression suite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tst/ now carries all three engine regression suites (cond, deftype,
escape) and the Makefile runs them. The README gains a Provenance
section: this repository is a curated snapshot of the private
development tree, stamped with the development commit it was assembled
from.
(from dev f6463478da4c)
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>