k4o renders Obsidian-flavored Markdown and oliver parses it natively — every extension filter lands as a real document node, not a literal marker. All demos on this page are the pipeline's own output.
highlight wraps in <mark>, strike in <del> — colored highlights take a color name:
$ cat ex.knap
{{ t | highlight }}
{{ s | strike }}
$ dogbed render ex.knap -d ex.json
<p><mark>ship it</mark></p>
<p><del>do not ship it</del></p>
math and math_block emit TeX — inline $…$, display $$…$$. Oliver typesets nothing; the span is yours to hand to MathJax:
$ cat mx.knap
{{ f | math }}
{{ b | math_block }}
$ dogbed render mx.knap -d mx.json
<p><span class="math inline">e = mc^2</span></p>
<div class="math display">x = (-b +- sqrt(b^2 - 4ac)) / 2a
</div>
callout turns a value into an Obsidian callout — > [!type] under the hood, a callout-<type> div on the page. Give each callout its own blank line:
$ cat co.knap
{{ note | callout:"note" }}
{{ warn | callout:"warning" }}
$ dogbed render co.knap -d co.json
<div class="callout callout-note">
<p>the cap counts the shell too</p>
</div>
<div class="callout callout-warning">
<p>the href passes through verbatim</p>
</div>
list:task and list:numbered-task emit checkboxes — the list filter's four modes are bullet, numbered, task, numbered-task. Footnotes ([^n] + definitions) are on the same flag set:
$ cat tk.knap
{{ items | list:task }}
$ dogbed render tk.knap -d tk.json
<ul>
<li><input type="checkbox" disabled="" />done</li>
<li><input type="checkbox" disabled="" />todo</li>
</ul>
The quiet ones: comment writes an invisible %%…%% note into the source (it never reaches the output — the empty first paragraph below is where it was), wikilink emits [[page]] (a link by default — a consumer-side resolver can rewrite the target), and embed emits ![[x]] as a placeholder span until a resolver claims it:
$ cat mt.knap
{{ c | comment }}
{{ w | wikilink }}
{{ e | embed }}
$ dogbed render mt.knap -d mt.json
<p>
<a href="Getting%20Started">Getting Started</a>
<span class="embed" data-embed-target="demo.knap">demo.knap</span></p>
And the undo button: escape_md walks a value back to plain text — inline specials get backslash-escaped before Markdown sees them. For data you don't trust, escape first, format later:
$ cat esc.knap
{{ t | escape_md }}
$ echo '{"t":"a *em* and `code` and [x](http://e.com)"}' | dogbed render esc.knap -d -
<p>a *em* and `code` and [x](http://e.com)</p>
rendered by dogbed — k4o templates it, oliver renders it