A reference for an LLM assistant: doc/klammertext_for_llm.md
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.
This commit is contained in:
12
README.md
12
README.md
@@ -25,6 +25,16 @@ the three commands — `ktext`, `kdesc`, `kdiag` (into `bin/`). See the
|
|||||||
source-install guide for prerequisites (TeX Live for PDF output, Python, and so
|
source-install guide for prerequisites (TeX Live for PDF output, Python, and so
|
||||||
on).
|
on).
|
||||||
|
|
||||||
|
## Working with an AI assistant
|
||||||
|
|
||||||
|
If you use a language model to help write Klammertext, give it
|
||||||
|
[`doc/klammertext_for_llm.md`](doc/klammertext_for_llm.md). It is a dense
|
||||||
|
reference written for a model rather than a person: the syntax, the things a
|
||||||
|
model is most likely to assume wrongly about it (Klammertext is not LaTeX,
|
||||||
|
Markdown, or Lisp, and reads oddly if you expect any of them), and how to ask
|
||||||
|
the `kdesc` and `kdiag` commands for the current state of the machine instead
|
||||||
|
of guessing.
|
||||||
|
|
||||||
## Editor support
|
## Editor support
|
||||||
|
|
||||||
Editing support for Emacs, Sublime Text, Vim, and Visual Studio Code —
|
Editing support for Emacs, Sublime Text, Vim, and Visual Studio Code —
|
||||||
@@ -41,7 +51,7 @@ are regenerated on each release — patches cannot be merged directly.
|
|||||||
Report problems (or send patches) to the author; accepted changes are
|
Report problems (or send patches) to the author; accepted changes are
|
||||||
applied to the development tree and appear in a following snapshot.
|
applied to the development tree and appear in a following snapshot.
|
||||||
|
|
||||||
This snapshot was assembled from development commit `6c8ee6c22fca`.
|
This snapshot was assembled from development commit `6c2ff7b8fce3`.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
236
doc/klammertext_for_llm.md
Normal file
236
doc/klammertext_for_llm.md
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
# Klammertext — reference for an LLM assistant
|
||||||
|
|
||||||
|
For a language model helping someone author Klammertext documents. Dense and
|
||||||
|
example-led on purpose: it is not a tutorial, and it motivates nothing. A person
|
||||||
|
wanting to learn Klammertext should read the other documents in `doc/`.
|
||||||
|
|
||||||
|
**Read §1 and §2 before writing any Klammertext.** §2 exists because a model that
|
||||||
|
has not seen this language will pattern-match it to LaTeX, Markdown, or Lisp and
|
||||||
|
produce confidently wrong syntax.
|
||||||
|
|
||||||
|
The klammers named here are the **Standard Klammer Set**, which is what loads by
|
||||||
|
default. A klammer set is user-extensible, so the authority for what exists in
|
||||||
|
any particular setup is `kdesc`, not this file — see §1.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Do not guess — the machine will tell you
|
||||||
|
|
||||||
|
Klammertext is introspectable. `kdesc` **prints the live state of the machine's
|
||||||
|
data structures in digested form**: what klammers exist, what arguments each
|
||||||
|
takes, what the argument types accept, what targets exist. Query it instead of
|
||||||
|
inferring from examples.
|
||||||
|
|
||||||
|
| ask | command |
|
||||||
|
|---|---|
|
||||||
|
| every klammer, with parameters and description | `kdesc -k` |
|
||||||
|
| klammers whose name or description mentions X | `kdesc -k X` |
|
||||||
|
| the output targets | `kdesc -t` |
|
||||||
|
| argument types and what each accepts | `kdesc --argtypes` |
|
||||||
|
| shared option groups and who uses them | `kdesc --optionsets` |
|
||||||
|
| which targets each klammer can render to | `kdesc --coverage` |
|
||||||
|
| what a user's own file defines | `kdesc -i FILE -k` |
|
||||||
|
| the usage of any command | run it with no arguments |
|
||||||
|
|
||||||
|
`kdesc -k <name>` before using an unfamiliar klammer costs one command and
|
||||||
|
replaces a guess. The parameter list it prints is authoritative; this file is
|
||||||
|
not.
|
||||||
|
|
||||||
|
**Check a document without rendering it:**
|
||||||
|
|
||||||
|
```
|
||||||
|
kdiag --process --check doc.kt
|
||||||
|
```
|
||||||
|
|
||||||
|
reports every klammer application whose name, argument count, option names, or
|
||||||
|
target coverage is wrong — including inside branches this render will not take.
|
||||||
|
It applies nothing, so it is safe and fast. Use it before claiming a document is
|
||||||
|
correct.
|
||||||
|
|
||||||
|
**Inspect how text is being parsed:** `kdiag --type '<text>'` shows the tokens
|
||||||
|
("katoms") and their types. This settles arguments about what a piece of syntax
|
||||||
|
actually means.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. What you will get wrong if you assume
|
||||||
|
|
||||||
|
| assumption | reality |
|
||||||
|
|---|---|
|
||||||
|
| It is a macro language like TeX | No catcodes. Token structure is fixed when a file is read and cannot be changed by anything later. This is why static checking works. |
|
||||||
|
| `\command{arg}` | `@name arg @` — an `@` opens, and a **closing delimiter is required**. |
|
||||||
|
| Arguments are `{a}{b}` | Positional arguments are separated by `|` — `@sup 2 \| 3 @`. |
|
||||||
|
| Options are `[key=value]` | `:name value`, anywhere in the argument list — `@link URL :text Click @`. |
|
||||||
|
| `%` starts a comment | `#` removes the rest of the line. `##` removes the rest of the file. `#[ … ]#` removes a block. |
|
||||||
|
| Whitespace is insignificant | It is content, and it is preserved. Blank lines separate paragraphs. |
|
||||||
|
| `\\` escapes | `^` quotes: `^@ ^\| ^# ^^ ^:` produce those characters literally. |
|
||||||
|
| Text is nested in braces | Text lives between the opening and closing delimiter with no wrapper. |
|
||||||
|
| The document body is the first argument | For `@document` the body goes in the **`:text` option** (or `:files`). A positional body is an error. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Lexical core
|
||||||
|
|
||||||
|
Three prefix tiers, distinguished by how many `@`:
|
||||||
|
|
||||||
|
| written | tier | meaning |
|
||||||
|
|---|---|---|
|
||||||
|
| `@name` | application | use a klammer |
|
||||||
|
| `@@name` | definition | define a klammer |
|
||||||
|
| `@@@name` | system | modify the machine (targets, argument types, state, klammersets) |
|
||||||
|
|
||||||
|
**Closing a klammer.** The close is `@` for the application tier, `@@` for
|
||||||
|
definitions, `@@@` for system commands. A close may be *named* by putting the
|
||||||
|
klammer's name immediately before it: `@i text i@.
|
||||||
|
|
||||||
|
> **When to name the close.** Use a bare `@` by default. Use the named form
|
||||||
|
> `name@` when the klammer's body **contains other klammer calls**. The reason is
|
||||||
|
> diagnostic, not stylistic: if delimiters are unbalanced, a named close lets the
|
||||||
|
> machine say exactly which klammer was left open. With bare closes everywhere it
|
||||||
|
> can only report that the count did not work out. Do not name closes on short,
|
||||||
|
> klammer-free bodies — it is noise.
|
||||||
|
|
||||||
|
```
|
||||||
|
@i just text i@ ← unnecessary; @i just text @ is better
|
||||||
|
@s1 A @c literal c@ heading s1@ ← name it: the body contains a klammer call
|
||||||
|
```
|
||||||
|
|
||||||
|
**Arguments.**
|
||||||
|
|
||||||
|
```
|
||||||
|
@name positional1 | positional2 :option value :flag @
|
||||||
|
```
|
||||||
|
|
||||||
|
- `|` separates positional arguments.
|
||||||
|
- `:name value` is an optional argument; it may appear anywhere in the list.
|
||||||
|
- `:name` written alone takes the argument type's "alone" value — for a boolean
|
||||||
|
that is `true`, so `:number` means `:number true`.
|
||||||
|
- An optional argument that is not written takes its default.
|
||||||
|
|
||||||
|
**Abbreviated form.** `@name-arg1-arg2` is `@name arg1 | arg2 @`, valid only
|
||||||
|
while every argument is letters and digits: `@i-italic`, `@sup-2-3`, `@date@`.
|
||||||
|
|
||||||
|
**Literal klammers** take their content uninterpreted (`@c`, `@code`). Their
|
||||||
|
content is not scanned for `@`, `|`, `#`, or `^`, so the machine cannot find the
|
||||||
|
end by counting — **these must be closed with the named form**:
|
||||||
|
|
||||||
|
```
|
||||||
|
@c ImfStandardAttributes.h c@
|
||||||
|
@code
|
||||||
|
int x = a[0]; // # and @ are safe in here
|
||||||
|
code@
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. A complete document
|
||||||
|
|
||||||
|
```
|
||||||
|
@document
|
||||||
|
:title Normalizing to OpenEXR Standard Attributes
|
||||||
|
:subtitle Predictability and provenance
|
||||||
|
:author Joseph Goldstone
|
||||||
|
:date @date@
|
||||||
|
:point_size 12
|
||||||
|
:text
|
||||||
|
|
||||||
|
@s1 Principles s1@
|
||||||
|
|
||||||
|
Ordinary paragraph text. A blank line starts a new paragraph.
|
||||||
|
Use @i emphasis i@ and @b bold @ inline, and @c literal_text c@ for code.
|
||||||
|
|
||||||
|
@link https://openexr.com/ :text the OpenEXR site link@
|
||||||
|
|
||||||
|
@ul
|
||||||
|
first item
|
||||||
|
| second item
|
||||||
|
| third item
|
||||||
|
ul@
|
||||||
|
|
||||||
|
# A comment: removed, and never reaches the output.
|
||||||
|
|
||||||
|
@image figure_name :width .95w :caption A caption @
|
||||||
|
|
||||||
|
@
|
||||||
|
```
|
||||||
|
|
||||||
|
Render it:
|
||||||
|
|
||||||
|
```
|
||||||
|
ktext doc.kt -t pdf # also: -t html, -t tex, -t txt
|
||||||
|
ktext doc.kt -t html # writes a DIRECTORY doc/ containing index.html
|
||||||
|
ktext -s '@i-x' -t html -d # -d displays instead of writing; -s takes a string
|
||||||
|
```
|
||||||
|
|
||||||
|
Output goes **next to the input file** unless `-o` says otherwise.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Klammers most used when authoring
|
||||||
|
|
||||||
|
Confirm parameters with `kdesc -k <name>` — this list is names and intent only.
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| inline | `@i` italic, `@b` bold, `@t` typewriter, `@u` underline, `@c` inline literal, `@sup`, `@sub` |
|
||||||
|
| structure | `@s1`…`@s7` numbered headings, `@h1`…`@h7` unnumbered, `@part`, `@preface`, `@par` |
|
||||||
|
| blocks | `@code`, `@quote`, `@note`, `@indent`, `@block`, `@center`, `@right`, `@columns` |
|
||||||
|
| lists | `@ul` unordered, `@ol` ordered, `@define` term/definition — items separated by `\|` |
|
||||||
|
| tables | `@table` — cells by `\|`, rows by `\|\|`; `@tbl`, `@rowcolor` |
|
||||||
|
| figures | `@image`, `@image_grid`, `@fig`, `@reference` |
|
||||||
|
| other | `@link`, `@date`, `@datetime`, `@color`, `@font`, `@newpage`, `@vspace`, `@email` |
|
||||||
|
|
||||||
|
Bar depth is the dimension: one `|` separates items, two `||` separates rows.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Defining a klammer (only if asked)
|
||||||
|
|
||||||
|
```
|
||||||
|
@@name.k arg1 | arg2 :opt default : Description of what it does @@
|
||||||
|
@@name.html :: <span>*arg1*</span> @@
|
||||||
|
@@name.tex :: \textbf{*arg1*} @@
|
||||||
|
```
|
||||||
|
|
||||||
|
- `.k` declares the interface and documents it; per-target definitions inherit
|
||||||
|
the parameter list with `::`.
|
||||||
|
- `*arg*` substitutes an argument into the body.
|
||||||
|
- A definition with no target suffix applies to every target.
|
||||||
|
- Separators: `:` create, `::` create inheriting parameters, `:::` override an
|
||||||
|
existing definition, `::::` define a default that a later `:` may replace.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Behaviour worth knowing before you debug something
|
||||||
|
|
||||||
|
- **`@cond` is strict about truth.** True: `true`, `True`, `1`. False: `false`,
|
||||||
|
`False`, `0`, and empty. **Anything else is an error**, not "probably false".
|
||||||
|
- **`@cond` evaluates only the branch it selects.** The branch not taken is not
|
||||||
|
read, not evaluated, not expanded — a `@read` of a missing file in the unused
|
||||||
|
branch is harmless.
|
||||||
|
- **A state variable reaches a `@cond` predicate.** The document behaves like a
|
||||||
|
function body whose arguments are its `@@@state` variables.
|
||||||
|
- **`@eval :shell` and `:haskell`:** the command's standard output becomes
|
||||||
|
document text; its standard error does not (it appears under `-v 1`); a nonzero
|
||||||
|
exit is an error. Append `|| true` if a nonzero exit is expected.
|
||||||
|
- **A definition inside a `@cond` branch does not register** — in either branch.
|
||||||
|
Define outside and select between *applications*.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Diagnostics
|
||||||
|
|
||||||
|
- **`-v 1`** reports every decision the command made that the user could not have
|
||||||
|
read off their own input: which klammerset was loaded and from where, which
|
||||||
|
file a font or a `:files` name resolved to, how the output path was built.
|
||||||
|
Higher levels are an implementation trace.
|
||||||
|
- Logging and errors go to **standard error**; the rendered document goes to
|
||||||
|
standard output, so `ktext doc.kt -d | …` is safe.
|
||||||
|
- An error stops the run and names a file, line, and character. There is no
|
||||||
|
warn-and-continue except in two documented cases.
|
||||||
|
- A bare `ktext`, `kdesc`, or `kdiag` prints its usage and exits successfully.
|
||||||
|
|
||||||
|
**When something is wrong:** run `kdiag --process --check doc.kt` first — it
|
||||||
|
finds name, arity, option and coverage faults without rendering. Then `kdesc -k
|
||||||
|
<klammer>` to check the parameter list against what was written. Then `kdiag
|
||||||
|
--type '<fragment>'` if the question is how something is being parsed.
|
||||||
Reference in New Issue
Block a user