Iota Syntaxis Renderer Specification
Version 1.0 beta1 (2026-05-09)
This document defines the renderer layer of Iota Syntaxis: how parsed text constructs are transformed into host-format markup (Markdown, HTML, LaTeX, plain text).
The Iota Syntaxis Renderer consumes the parser output
defined in SPEC.md §2.1. Renderer conformance
and parser conformance are independent: a tool MAY
implement either, both, or different host-format subsets
of either.
This document is normative. Explanatory material —
motivation, design rationale, additional examples — lives
in RATIONALE\_RENDERER.md, with parallel section
numbering.
The key words MUST, SHOULD, and MAY are used as defined in RFC 2119.
Renderer Overview
The renderer accepts source text, a host format identifier, and configuration (link templates), and returns transformed text with text constructs replaced by host-format equivalents.
Template Substitution
The renderer uses template strings with named
placeholders of the form {field_name}. Each placeholder
is replaced by the corresponding value from the parser’s
extracted fields. Templates support pure string substitution;
no control flow, conditionals, or loops.
A
nullfield substitutes as the empty string.List fields (
tags) substitute as their elements joined by commas.All other fields substitute as their string representation.
Fallback syntax.
A placeholder MAY specify a fallback chain using +a|b+ or +a|b|c+: each alternative is tried in order, and the first non-null, non-empty value is used. This is the only form of logic supported in templates.
Two templates govern each construct’s rendered output:
Target template — produces the link target (URL, href, etc.).
Text template — produces the display text.
The host format’s output pattern combines target and text into the final markup. Output patterns are fixed per host format and not user-configurable:
| Host Format | Labeled (text non-empty) | Unlabeled (text empty) | Metadata |
|---|---|---|---|
| Markdown | [{text}]({target}) |
[{target}]({target}) |
{text} |
| HTML | <a href="{target}">{text}</a> |
<a href="{target}">{target}</a> |
{text} |
| LaTeX | \href{target}{text} |
\url{target} |
{text} |
| Plain text | (see below) | (see below) | {text} |
Pattern selection:
If the construct has no target template (tags, categories, todos), the metadata pattern is used.
Otherwise, the text template is evaluated. If non-empty, the labeled pattern is used; otherwise the unlabeled pattern.
Plain-text host format.
Plain text has no native
link markup, so the labeled and unlabeled patterns above
apply only to URL constructs: ==URL renders as
<{target}> and ==(label)URL renders as
{text} <{target}>. For internal text reference
constructs (ID references, file references, resource
references, and inter-jot resource references), the
plain-text host format leaves the matched source span
unchanged in the rendered output. Annotation suffixes,
specifiers, and the surrounding sigils are preserved
verbatim. Bookmark declarations are removed.
Template Placeholders
The following placeholders are available, by construct type:
| Construct type | Available placeholders |
|---|---|
| Same-space ID reference | {id}, {fragment}, {bookmark}, {bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Cross-space ID reference | {space}, {id}, {fragment}, {bookmark}, {bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Same-space file reference | {filepath}, {fragment}, {bookmark}, {bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Cross-space file reference | {space}, {filepath}, {fragment}, {bookmark}, {bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Standalone resource | {filename}, {fragment}, {bookmark}, {bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Inter-jot resource (same-space, ID) | {id}, {filename}, {resource_fragment}, {resource_bookmark}, {resource_bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Inter-jot resource (cross-space, ID) | {space}, {id}, {filename}, {resource_fragment}, {resource_bookmark}, {resource_bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Inter-jot resource (same-space, file) | {filepath}, {filename}, {resource_fragment}, {resource_bookmark}, {resource_bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| Inter-jot resource (cross-space, file) | {space}, {filepath}, {filename}, {resource_fragment}, {resource_bookmark}, {resource_bookmark_range}, {category}, {tags}, {category_suffix}, {tag_suffixes}, {annotation_suffixes} |
| URL | {url}, {label} ({label} is empty for bare URLs) |
| Bookmark declaration | {name} |
Specifier placeholders.
{fragment}/{resource_fragment}substitute as the original fragment syntax (e.g.,:10-20,:5+10,:42), not the normalized pair. They substitute as the empty string when absent.{bookmark}/{resource_bookmark}substitute as#name(including the#), or empty when absent.{bookmark_range}/{resource_bookmark_range}substitute as the original bookmark range syntax (e.g.,##intro,summary,##,conclusion,##chapter1,), or empty when absent.
Annotation placeholders.
{category}substitutes as the bare category path without the::prefix (e.g.,work::projects), or empty when absent.{tags}substitutes as the tag list joined by commas without..prefixes (e.g.,urgent,draft), or empty when the list is empty.{category_suffix}substitutes as::categoryincluding the::prefix (e.g.,::work::projects), or empty when absent.{tag_suffixes}substitutes as the concatenation of each tag with its..prefix (e.g.,..urgent..draft), or empty when the list is empty.{annotation_suffixes}substitutes as{category_suffix}{tag_suffixes}— the category suffix (if any) followed by the tag suffixes (if any), in canonical order. Empty when neither is present.
Output Escaping
URL labels are the only template input that may contain
arbitrary user-supplied text. Renderers MUST escape
{label} substitutions according to the host format
before emitting markup:
@p2.4cmp10.6cm@
Host Format & Characters that MUST be escaped in {label}
HTML & &, <, >, " (entity-escape)
Markdown & [, ], \ (backslash-escape)
LaTeX & _, |Plain text & (none — labels are emitted verbatim)
All other placeholders ({id}, {space},
{filepath}, {filename}, {fragment},
{bookmark}, {bookmark_range}, {category},
{tags}, the {*_suffix} family, {name}, and
{url}) draw their values from constrained character
sets defined by the grammar in SPEC.md §1.7 and do
not require escaping in any supported host format.
Implementations MUST NOT additionally escape these values.
Template Fallback
The fallback chain +a|b+ (and +a|b|c+, etc.) introduced in §1.1 selects the first non-empty alternative:
An alternative is non-empty if its substitution produces a string of length > 0 after the substitution rules of §1.2 are applied. Lists with no elements,
nullfields, and absent specifiers all substitute as the empty string and are therefore considered empty for fallback purposes.All alternatives in a single chain MUST be valid placeholders for the construct type being rendered. Mixing placeholders that belong to different construct types in one chain is a template configuration error (
SPEC.md§3.6).Alternatives are evaluated left-to-right; the first non-empty result is used and remaining alternatives are not evaluated.
A literal alternative (a string with no
{or}) is always non-empty when it has length > 0 and so MAY be used as a terminating default: +label|url|<no link>+.Fallback chains MUST NOT contain other fallback chains; nested braces are a configuration error.
Renderer Output
The defaults below are normative for conformance. Implementations that support user-configurable templates produce different output when non-default templates are configured.
ID References
Same-space defaults.
Target:
jot://{id}{fragment}{bookmark}{bookmark_range}Text:
--{id}{fragment}{bookmark}{bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | --42 |
[--42](jot://42) |
| Markdown | --42:10-20 |
[--42:10-20](jot://42:10-20) |
| Markdown | --42#intro |
[--42#intro](jot://42#intro) |
| Markdown | --42##intro,summary |
[--42##intro,summary](jot://42##intro,summary) |
| Markdown | --42::work..urgent |
[--42::work..urgent](jot://42) |
| HTML | --42 |
<a href="jot://42">--42</a> |
| LaTeX | --42 |
\href{jot://42}{--42} |
| Plain text | --42 |
--42 (no transformation) |
Annotation suffixes appear in the rendered text by default but not in the link target; they describe the edge from source to target, not a sub-location within the target.
Cross-space defaults.
Target:
jot://{space}/{id}{fragment}{bookmark}{bookmark_range}Text:
--{space}--{id}{fragment}{bookmark}{bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | --work--42 |
[--work--42](jot://work/42) |
| HTML | --work--42 |
<a href="jot://work/42">--work--42</a> |
| LaTeX | --work--42 |
\href{jot://work/42}{--work--42} |
| Plain text | --work--42 |
--work--42 (no transformation) |
File References
Same-space defaults.
Target:
jotf://{filepath}{fragment}{bookmark}{bookmark_range}Text:
//{filepath}{fragment}{bookmark}{bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | //notes.md |
[//notes.md](jotf://notes.md) |
| Markdown | //notes.md:100-120 |
[//notes.md:100-120](jotf://notes.md:100-120) |
| Markdown | //notes.md#conclusion |
[//notes.md#conclusion](jotf://notes.md#conclusion) |
| Markdown | //notes.md##intro,summary |
[//notes.md##intro,summary](jotf://notes.md##intro,summary) |
| HTML | //notes.md |
<a href="jotf://notes.md">//notes.md</a> |
| LaTeX | //notes.md |
\href{jotf://notes.md}{//notes.md} |
| Plain text | //notes.md |
//notes.md (no transformation) |
Cross-space defaults.
Target:
jotf://{space}/{filepath}{fragment}{bookmark}{bookmark_range}Text:
///{space}/{filepath}{fragment}{bookmark}{bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | ///work/notes.md |
[///work/notes.md](jotf://work/notes.md) |
| HTML | ///work/notes.md |
<a href="jotf://work/notes.md">///work/notes.md</a> |
| LaTeX | ///work/notes.md |
\href{jotf://work/notes.md}{///work/notes.md} |
| Plain text | ///work/notes.md |
///work/notes.md (no transformation) |
Resource References
Defaults.
Target:
jotr://{filename}{fragment}{bookmark}{bookmark_range}Text:
;;{filename}{fragment}{bookmark}{bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | ;;report.pdf |
[;;report.pdf](jotr://report.pdf) |
| Markdown | ;;data.csv:1-50 |
[;;data.csv:1-50](jotr://data.csv:1-50) |
| Markdown | ;;report.pdf#chapter1 |
[;;report.pdf#chapter1](jotr://report.pdf#chapter1) |
| Markdown | ;;report.pdf##intro,summary |
[;;report.pdf##intro,summary](jotr://report.pdf##intro,summary) |
| HTML | ;;report.pdf |
<a href="jotr://report.pdf">;;report.pdf</a> |
| LaTeX | ;;report.pdf |
\href{jotr://report.pdf}{;;report.pdf} |
| Plain text | ;;report.pdf |
;;report.pdf (no transformation) |
Tags, Categories, and Todos
Tags, categories, and todos are metadata constructs. Default behavior is to leave them unchanged in the rendered output. Implementations MAY render them with visual formatting (styled badges, links to filtered views), and MAY strip them in a “clean output” mode.
Done todos (??.action…, SPEC.md §1.4.6)
render unchanged by default, just like active todos.
Implementations MAY render them distinctively
(struck-through text, a checked-box glyph, a faded style)
in formatted output; the parser already routes them to
done_todos separately from todos, so the renderer
has the information it needs without reparsing. The optional
completion timestamp on a done todo — exposed as the
completed field on the todo object — is similarly
available for renderers that want to surface it (e.g., as a
trailing date chip), though the default behavior leaves the
original .@<iso-date> text in place in the rendered
output.
URLs
Defaults.
Target:
{url}Text:
{label}
When a label is present, {label} evaluates to the
label and the labeled output pattern is used.
When absent, {label} is empty and the
unlabeled pattern is used.
| Host Format | Input | Pattern | Output |
|---|---|---|---|
| Markdown | ==https://example.com |
Unlabeled | [https://example.com](https://example.com) |
| Markdown | ==(docs)https://example.com |
Labeled | [docs](https://example.com) |
| HTML | ==https://example.com |
Unlabeled | <a href="https://example.com">https://example.com</a> |
| HTML | ==(docs)https://example.com |
Labeled | <a href="https://example.com">docs</a> |
| LaTeX | ==https://example.com |
Unlabeled | \url{https://example.com} |
| LaTeX | ==(docs)https://example.com |
Labeled | \href{https://example.com}{docs} |
| Plain text | ==https://example.com |
Unlabeled | <https://example.com> |
| Plain text | ==(docs)https://example.com |
Labeled | docs <https://example.com> |
The bracketed form ==[label]URL produces identical
output to the parenthesized form.
Bookmarks
Bookmark declarations render as invisible named anchors. The
text template is {name}. Output patterns are fixed per
host format:
| Host Format | Input | Output |
|---|---|---|
| Markdown | !!introduction |
<a id="introduction"></a> |
| HTML | !!introduction |
<span id="introduction"></span> |
| LaTeX | !!introduction |
\hypertarget{introduction}{} |
| Plain text | !!introduction |
(removed — no visible output) |
Inter-Jot Resource References
Same-space ID-based defaults.
Target:
jot://{id}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}Text:
--{id};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | --42;;report.pdf |
[--42;;report.pdf](jot://42/resources/report.pdf) |
| Markdown | --42;;data.csv:1-50 |
[--42;;data.csv:1-50](jot://42/resources/data.csv:1-50) |
| Markdown | --42;;report.pdf#ch1 |
[--42;;report.pdf#ch1](jot://42/resources/report.pdf#ch1) |
| Markdown | --42;;report.pdf##intro,conclusion |
[--42;;report.pdf##intro,conclusion](jot://42/resources/report.pdf##intro,conclusion) |
| HTML | --42;;report.pdf |
<a href="jot://42/resources/report.pdf">--42;;report.pdf</a> |
| LaTeX | --42;;report.pdf |
\href{jot://42/resources/report.pdf}{--42;;report.pdf} |
| Plain text | --42;;report.pdf |
--42;;report.pdf (no transformation) |
Cross-space ID-based defaults.
Target:
jot://{space}/{id}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}Text:
--{space}--{id};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | --work--42;;report.pdf |
[--work--42;;report.pdf](jot://work/42/resources/report.pdf) |
| HTML | --work--42;;report.pdf |
<a href="jot://work/42/resources/report.pdf">--work--42;;report.pdf</a> |
| LaTeX | --work--42;;report.pdf |
\href{jot://work/42/resources/report.pdf}{--work--42;;report.pdf} |
Same-space file-based defaults.
Target:
jotf://{filepath}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}Text:
//{filepath};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | //notes.md;;data.csv |
[//notes.md;;data.csv](jotf://notes.md/resources/data.csv) |
| Markdown | //notes.md;;data.csv:10-20 |
[//notes.md;;data.csv:10-20](jotf://notes.md/resources/data.csv:10-20) |
| HTML | //notes.md;;data.csv |
<a href="jotf://notes.md/resources/data.csv">//notes.md;;data.csv</a> |
| LaTeX | //notes.md;;data.csv |
\href{jotf://notes.md/resources/data.csv}{//notes.md;;data.csv} |
Cross-space file-based defaults.
Target:
jotf://{space}/{filepath}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}Text:
///{space}/{filepath};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes}
| Host Format | Input | Output |
|---|---|---|
| Markdown | ///work/notes.md;;data.csv |
[///work/notes.md;;data.csv](jotf://work/notes.md/resources/data.csv) |
| HTML | ///work/notes.md;;data.csv |
<a href="jotf://work/notes.md/resources/data.csv">///work/notes.md;;data.csv</a> |
| LaTeX | ///work/notes.md;;data.csv |
\href{jotf://work/notes.md/resources/data.csv}{///work/notes.md;;data.csv} |
Link Template Configuration
The default link templates are listed below. Example outputs of these defaults appear in the host-format tables of §2.
| Setting | Default |
|---|---|
ref_target |
jot://{id}{fragment}{bookmark}{bookmark_range} |
ref_text |
--{id}{fragment}{bookmark}{bookmark_range}{annotation_suffixes} |
cross_ref_target |
jot://{space}/{id}{fragment}{bookmark}{bookmark_range} |
cross_ref_text |
--{space}--{id}{fragment}{bookmark}{bookmark_range}{annotation_suffixes} |
file_ref_target |
jotf://{filepath}{fragment}{bookmark}{bookmark_range} |
file_ref_text |
//{filepath}{fragment}{bookmark}{bookmark_range}{annotation_suffixes} |
cross_file_ref_target |
jotf://{space}/{filepath}{fragment}{bookmark}{bookmark_range} |
cross_file_ref_text |
///{space}/{filepath}{fragment}{bookmark}{bookmark_range}{annotation_suffixes} |
resource_target |
jotr://{filename}{fragment}{bookmark}{bookmark_range} |
resource_text |
;;{filename}{fragment}{bookmark}{bookmark_range}{annotation_suffixes} |
inter_jot_ref_target |
jot://{id}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range} |
inter_jot_ref_text |
--{id};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes} |
inter_jot_cross_ref_target |
jot://{space}/{id}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range} |
inter_jot_cross_ref_text |
--{space}--{id};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes} |
inter_jot_file_ref_target |
jotf://{filepath}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range} |
inter_jot_file_ref_text |
//{filepath};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes} |
inter_jot_cross_file_ref_target |
jotf://{space}/{filepath}/resources/{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range} |
inter_jot_cross_file_ref_text |
///{space}/{filepath};;{filename}{resource_fragment}{resource_bookmark}{resource_bookmark_range}{annotation_suffixes} |
url_target |
{url} |
url_text |
{label} |
The jot://, jotf://, jotr:// schemes are
abstract placeholders. Concrete implementations resolve them
to local file paths, web URLs, TUI jump targets, or any other
navigation mechanism appropriate to the host tool.
Implementations MUST support the default templates. Implementations MAY support user-configurable templates using the placeholder vocabulary defined in §1.2.
Renderer Settings
Each link template setting in §3
MAY be overridden by an environment variable named by
uppercasing the setting key and prefixing
JOTR\_:
| Setting key | Env var |
|---|---|
ref_target |
JOTR\_REF\_TARGET |
ref_text |
JOTR\_REF\_TEXT |
cross_ref_target |
JOTR\_CROSS\_REF\_TARGET |
cross_ref_text |
JOTR\_CROSS\_REF\_TEXT |
file_ref_target |
JOTR\_FILE\_REF\_TARGET |
file_ref_text |
JOTR\_FILE\_REF\_TEXT |
cross_file_ref_target |
JOTR\_CROSS\_FILE\_REF\_TARGET |
cross_file_ref_text |
JOTR\_CROSS\_FILE\_REF\_TEXT |
resource_target |
JOTR\_RESOURCE\_TARGET |
resource_text |
JOTR\_RESOURCE\_TEXT |
url_target |
JOTR\_URL\_TARGET |
url_text |
JOTR\_URL\_TEXT |
inter_jot_ref_target |
JOTR\_INTER\_JOT\_REF\_TARGET |
inter_jot_ref_text |
JOTR\_INTER\_JOT\_REF\_TEXT |
inter_jot_cross_ref_target |
JOTR\_INTER\_JOT\_CROSS\_REF\_TARGET |
inter_jot_cross_ref_text |
JOTR\_INTER\_JOT\_CROSS\_REF\_TEXT |
inter_jot_file_ref_target |
JOTR\_INTER\_JOT\_FILE\_REF\_TARGET |
inter_jot_file_ref_text |
JOTR\_INTER\_JOT\_FILE\_REF\_TEXT |
inter_jot_cross_file_ref_target |
JOTR\_INTER\_JOT\_CROSS\allowbreak\_FILE\_REF\_TARGET |
inter_jot_cross_file_ref_text |
JOTR\_INTER\_JOT\_CROSS\allowbreak\_FILE\_REF\_TEXT |
Configuration source priority follows SPEC.md §2.2:
environment variables override the local .jot.toml
override the user-level $HOME/.jot.toml.
Conformance
A tool or library conforms to the Iota Syntaxis Renderer Specification if it:
Accepts source text (or parser output conforming to
SPEC.md§2.1) and produces transformed text per §1 and §2 for at least one host format.Produces output matching the defaults in §3 when no custom templates are configured. Implementations supporting user-configurable templates MUST perform pure string substitution using the placeholder vocabulary in §1.2.
Renders bookmark declarations as invisible anchors per §2.6.
Renders inter-jot resource references per §2.7, including annotation suffixes and specifiers on the resource portion, using the inter-jot templates in §3.
Escapes URL labels per §1.3 for the target host format.
A tool MAY support a subset of host formats (e.g., Markdown only) and still conform, provided the supported subset matches this specification.
A renderer MAY rely on an external parser conforming to
SPEC.md or implement its own; the renderer surface
is defined relative to the parser-output contract in
SPEC.md §2.1, not to a particular implementation.