kdesc --katoms is Klammertext rendered from ref/, the types in titled groups,
with --katoms full for the regex column. @table :leading L is L lines of the
surrounding text in html as in pdf (default 1), and :rulesep spaces the
horizontal rules. The html table has one style attribute, so :column_width
fractions take effect again. @code and @source_listing render in plain
text; captions are numbered per kind there, and a table needs no blank line
around it. @c takes :nd, and an option-shaped word before a bar inside
literal code is code.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Also: the klammertext argtype (descriptions kept as source), txt table
wrapping and :hpos/:offset, @c between ‹ ›, txt section headings, the
ktext newline-only trim, capitalize(), and the argtype test suite.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Since the previous release: Machine::read_string() (the fs::path/std::string
overload pair split); kdesc -c and -u rendered from the ref/ reflection
klammerset; a fit column's tex width measured in TeX over every entry;
@typeface resolving to the family its css declares (a store directory name
now works in html) and hieroglyphs in @unicode_examples set in their
typeface; the ansi target -- plain text with the type styles a terminal can
show, identical to txt once the escape sequences are stripped -- with the
txt @table carrying :header_style, :style and :hline; @block anchoring,
@table spacing and the Image_quality state variable; and the rewritten
doc/klammertext_for_llm.md.
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)
A run of Unicode code points now needs one pair of carets, not one pair
each: ^9053 53EF 9053^ renders the characters adjacently, and a single
character inside such a run stands for itself. An invalid code point is
an error naming the position that wrote it, rather than an apology
rendered into the finished document; noncharacters are refused alongside
surrogates; and a code point that lands on a Klammertext special is safe
through the re-reads that assemble a document. The character tables now
produce the precomposed form, so a diacritic written as ^a" and one typed
directly are the same text to a search or a copy-paste.
"kdesc -u" describes how to write a Unicode character, with tables of
glyphs beside the codes that produce them. It is new and not yet
complete: it predates the sequence form and the typeface klammer below.
A typeface and a style are no longer both called "font". A typeface is a
family resolved by name; a style code is the one letter naming a type
style. So @document takes :serif_typeface and its siblings, a table takes
:style, captions take :caption_style and :caption_size, the uniform scale
is :text_scale, and the command is "kdesc --typeface". This renames
arguments a document may already use; an old name is a located error
rather than a silent omission.
@typeface sets a passage in another typeface for the length of that
passage:
@typeface Noto Sans Egyptian Hieroglyphs | ^132AA 133CF^ :scale 1.5 @
Writing the klammer is the whole declaration -- the document resolves the
typeface, embeds it in what it produces, and carries its license along.
Two typefaces for scripts no text font covers now ship with Klammertext:
Noto Sans Egyptian Hieroglyphs and Noto Sans Cuneiform. Every typeface in
the distribution now carries its license file.
(from dev 61e598698891)
Typographic transforms (---, quote pairs, ~) no longer touch verbatim
text: @c/@code/@source_listing content and ^'...'^ spans show exactly the
characters written. "^" before any punctuation character quotes it in
every target (the apostrophe excepted: ^' opens a literal span), with the
new :resolve option on @@@target declaring per-target renderings. The
^UUUU^ code-point form accepts 4-6 hex digits, the full Unicode range.
The html output and transform spellings are polyglot (XML-valid), in
preparation for an EPUB target. New suites: transform_test, character_test
(engine), typography_test (SKS).
(from dev 07ce5ea86a0a)
Three changes.
@c now takes its content literally, like @code -- it is the inline form
and @code the block form of the same thing. The named close "c@" is
required, and characters that are special in a target no longer break
the file: @c a_b c@ renders correctly everywhere. The Markdown
converter stops quoting inline code, since nothing needs protecting.
@source_file is renamed @source_listing. Code read from a file is its
own klammer; @code is only for a block written inline (its never-
implemented :filename and :pattern options are removed). The new
:marker P option lists the region between two lines that are exactly
//P, so the source file declares its own extractable regions. A marker
missing or not appearing exactly twice is an error, never a fallback.
Rendering a document that sits in a large directory was paying a
recursive walk of that directory's whole tree on every @eval -- 27
seconds for a document that renders in a third of one. The walk is now
a non-recursive look decided once per directory.
Assembled from dev commit 071b1b183de4.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
If you use a language model to help write Klammertext, give it this file. It is
a dense reference written for a model rather than a person -- not a tutorial,
and it motivates nothing.
Two things make it different from the other documents here.
It tells the model NOT TO GUESS. Its first section maps questions to commands,
because "kdesc" prints the live state of the machine's data structures: what
klammers exist, what arguments each takes, what the argument types accept. The
file says outright that the parameter list kdesc prints is authoritative and
that the file is not, so a model checks rather than infers. "kdiag --process
--check doc.kt" verifies a document without rendering it, and "kdiag --type"
settles how a fragment is being parsed.
Its second section is a table of WRONG ASSUMPTIONS. A model that has not seen
Klammertext pattern-matches it to LaTeX, Markdown or Lisp and produces
confidently wrong syntax, so each row names the likely wrong guess and corrects
it -- braces against the bar separator, bracketed options against ":name value",
"%" against "#", backslash escapes against "^", and @document's body belonging
in its ":text" option rather than in a positional argument.
The rest is the syntax proper: the three "@" tiers, argument forms, a complete
worked document, the klammers most used when authoring, how to define one, and
the behaviour that otherwise costs a debugging session.
The README points at it.
Assembled from dev commit 6c2ff7b8fce3.
mdpdf drives a headless Chromium, and a browser installed as a flatpak --
which is what the Pop!_Shop installs, and so the ordinary case on a Pop!_OS
or System76 machine -- was unusable in two ways, the second of them silent.
It was not found at all. A flatpak puts nothing on PATH and nothing in
/opt, and its wrapper is named com.brave.Browser rather than brave-browser,
so adding the export directory to PATH would not have helped either. The
application ids are now looked for in the flatpak export directories, after
every native browser, so a native one still wins where there is one.
Found, it then rendered in the wrong fonts and reported success. The
@font-face URLs pointed into the font store, which the sandbox cannot read,
and a browser does not report a font it cannot fetch -- it substitutes. The
PDF came out in a default serif and nothing said so. Granting the path
would not have travelled either: sandbox filesystem permissions differ from
one application to the next, so a scheme resting on a path works with one
browser and fails with another on the same machine.
So the document, its fonts and its images are now served to the browser
over the loopback interface instead of being passed as file:// paths. Every
sandbox shares the network namespace -- the DevTools connection already
depends on it -- so this needs no filesystem permission from any sandbox,
present or future. A --keep-html copy is still written with file:// URLs,
so it works when nothing is serving it.
A font that fails to load is now an error rather than a substitution: the
page is asked whether each requested family arrived, and no PDF is written
if one did not. A finished-looking document in the wrong typeface is the
worst failure this program can have.
Separately, a table-of-contents entry no longer carries a bullet. An entry
is a section title, and a marker in front of it reads as a list of things
rather than as a contents; ordinary bulleted lists are unaffected.
(from dev 12929fdff53b)
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)
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)
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)
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>
Sync with klammertext-dev through b90b0e09:
- Argument types end to end: :python_cast values are applied (Python
@eval receives real bools/numbers/lists), argument values are
validated against their argtype patterns with the argtype's
description as the error message, argtypes can declare :default
(overridable per declaration), and parameterized type families are
supported: rest(N) casts a rest argument to an N-dimensional list
(bar-count = dimension).
- Unified indexed_range syntax (selector with parenthesized subsets,
composable mnemonic names) for table lines and spans.
- Table klammer: caption fonts fixed in both targets, :column_width /
:leading / :colsep wired, :colspan and :rowspan render (HTML
attributes; \multicolumn / \multirow), calculated cell values (:calc)
with prefix operators, display-precision semantics, :calc_format and
:decimal period|comma.
- Fonts: closed-world resolution on the Klammertext font store
(infrastructure in mac/font_store; no Google Fonts links or fetch).
Default fonts live in the top-level fnt/; additional fonts install
into KLAMMERTEXT_FONTS directories via kdesc --font (list, samples,
preview, install — classification by font metadata). CSS font family
names are quoted (digit-initial families were silently lost).
- Environment files moved from mac/env/ to the top-level env/; shell
profiles source env/runtime.env. Dead per-host variants removed.
- Container: fnt/ ships in the image; curl removed (no network use).
Bare 'make -C com' now builds -O3 (optimize.env default flip); the install guides drop OPTIMIZE=1 and document DEBUG=1 for an AddressSanitizer build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>