<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>typost demo</title>
  <id>https://typost.sereph.us/</id>
  <updated>2026-02-14T00:00:00Z</updated>
  <link href="https://typost.sereph.us/atom.xml" rel="self"/>
  <link href="https://typost.sereph.us/" rel="alternate"/>
  <generator>typost</generator>
  <entry>
    <title>A tour of Typst and typost</title>
    <link href="https://typost.sereph.us/blog/tour/" rel="alternate"/>
    <id>https://typost.sereph.us/blog/tour/</id>
    <updated>2026-02-14T00:00:00Z</updated>
    <published>2026-02-14T00:00:00Z</published>
    <category term="typst"/>
    <category term="typost"/>
    <category term="features"/>
    <content type="html">&lt;h2&gt;A tour of Typst and typost&lt;/h2&gt;&lt;p&gt;Every block below shows the source, then the actual result.&lt;/p&gt;&lt;hr&gt;&lt;h3&gt;Headings&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt;===&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt;A section&lt;/strong&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;A section&lt;/h4&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt;====&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt;A subsection&lt;/strong&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;A subsection&lt;/h5&gt;&lt;hr&gt;&lt;h3&gt;Emphasis and inline styles&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;strong&gt;bold&lt;/strong&gt;&lt;strong&gt;*&lt;/strong&gt;, &lt;em&gt;_&lt;/em&gt;&lt;em&gt;italic&lt;/em&gt;&lt;em&gt;_&lt;/em&gt;, &lt;span style=&quot;color: #6b6b6f&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;code&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;`&lt;/span&gt;, &lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;strike&lt;/span&gt;[struck], &lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;underline&lt;/span&gt;[underlined],
&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;highlight&lt;/span&gt;[highlighted], &lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;sub&lt;/span&gt;[sub], &lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;super&lt;/span&gt;[super]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;bold&lt;/strong&gt;, &lt;em&gt;italic&lt;/em&gt;, &lt;code&gt;code&lt;/code&gt;, &lt;s&gt;struck&lt;/s&gt;, &lt;span style=&quot;text-decoration: underline&quot;&gt;underlined&lt;/span&gt;, &lt;mark&gt;highlighted&lt;/mark&gt;, &lt;sub&gt;sub&lt;/sub&gt;, &lt;sup&gt;super&lt;/sup&gt;&lt;/p&gt;&lt;hr&gt;&lt;h3&gt;Lists&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #8b41b1&quot;&gt;-&lt;/span&gt; one
&lt;span style=&quot;color: #8b41b1&quot;&gt;-&lt;/span&gt; two
  &lt;span style=&quot;color: #8b41b1&quot;&gt;-&lt;/span&gt; nested

&lt;span style=&quot;color: #8b41b1&quot;&gt;+&lt;/span&gt; first
&lt;span style=&quot;color: #8b41b1&quot;&gt;+&lt;/span&gt; second

&lt;span style=&quot;color: #8b41b1&quot;&gt;/&lt;/span&gt; &lt;strong&gt;term&lt;/strong&gt;: its description&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;one&lt;/li&gt;&lt;li&gt;&lt;p&gt;two&lt;/p&gt;&lt;ul&gt;&lt;li&gt;nested&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;first&lt;/li&gt;&lt;li&gt;second&lt;/li&gt;&lt;/ol&gt;&lt;dl&gt;&lt;dt&gt;term&lt;/dt&gt;&lt;dd&gt;its description&lt;/dd&gt;&lt;/dl&gt;&lt;hr&gt;&lt;h3&gt;Code&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;```&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;rust&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;
&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;fn main() {&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;
&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;    println!(&quot;hello from typost&quot;);&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;
&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;
&lt;span style=&quot;color: #6b6b6f&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #6b6b6f&quot;&gt;```&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color: #d73948&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;color: #4b69c6&quot;&gt;main&lt;/span&gt;() {
    &lt;span style=&quot;color: #16718d&quot;&gt;println!&lt;/span&gt;(&lt;span style=&quot;color: #198810&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #198810&quot;&gt;hello from typost&lt;/span&gt;&lt;span style=&quot;color: #198810&quot;&gt;&quot;&lt;/span&gt;);
}&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;&lt;h3&gt;Math&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;Euler&apos;s identity: &lt;span style=&quot;color: #198810&quot;&gt;$&lt;/span&gt;e&lt;span style=&quot;color: #1d6c76&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color: #1d6c76&quot;&gt;(&lt;/span&gt;i &lt;span style=&quot;color: #8b41b1&quot;&gt;pi&lt;/span&gt;&lt;span style=&quot;color: #1d6c76&quot;&gt;)&lt;/span&gt; + 1 = 0&lt;span style=&quot;color: #198810&quot;&gt;$&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Euler’s identity: &lt;math&gt;&lt;msup&gt;&lt;mi&gt;𝑒&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;𝑖&lt;/mi&gt;&lt;mi&gt;𝜋&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/math&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #198810&quot;&gt;$&lt;/span&gt; &lt;span style=&quot;color: #8b41b1&quot;&gt;integral&lt;/span&gt;&lt;span style=&quot;color: #1d6c76&quot;&gt;_&lt;/span&gt;0&lt;span style=&quot;color: #1d6c76&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color: #8b41b1&quot;&gt;infinity&lt;/span&gt; e&lt;span style=&quot;color: #1d6c76&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color: #1d6c76&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #1d6c76&quot;&gt;-&lt;/span&gt;x&lt;span style=&quot;color: #1d6c76&quot;&gt;^&lt;/span&gt;2&lt;span style=&quot;color: #1d6c76&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #8b41b1&quot;&gt;dif&lt;/span&gt; x = &lt;span style=&quot;color: #4b69c6&quot;&gt;sqrt&lt;/span&gt;(&lt;span style=&quot;color: #8b41b1&quot;&gt;pi&lt;/span&gt;) &lt;span style=&quot;color: #1d6c76&quot;&gt;/&lt;/span&gt; 2 &lt;span style=&quot;color: #198810&quot;&gt;$&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;math display=&quot;block&quot;&gt;&lt;msubsup&gt;&lt;mo lspace=&quot;0em&quot;&gt;∫&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mi&gt;∞&lt;/mi&gt;&lt;/msubsup&gt;&lt;msup&gt;&lt;mi&gt;𝑒&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;𝑥&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mspace width=&quot;0.1667em&quot;/&gt;&lt;mo form=&quot;prefix&quot; lspace=&quot;0em&quot; rspace=&quot;0em&quot;&gt;d&lt;/mo&gt;&lt;mi&gt;𝑥&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;msqrt&gt;&lt;mi&gt;𝜋&lt;/mi&gt;&lt;/msqrt&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mfrac&gt;&lt;/math&gt;&lt;hr&gt;&lt;h3&gt;Tables&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;table&lt;/span&gt;(
  columns: &lt;span style=&quot;color: #b60157&quot;&gt;3&lt;/span&gt;,
  [&lt;strong&gt;*&lt;/strong&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;strong&gt;*&lt;/strong&gt;], [&lt;strong&gt;*&lt;/strong&gt;&lt;strong&gt;Typst&lt;/strong&gt;&lt;strong&gt;*&lt;/strong&gt;], [&lt;strong&gt;*&lt;/strong&gt;&lt;strong&gt;Markdown&lt;/strong&gt;&lt;strong&gt;*&lt;/strong&gt;],
  [Math], [yes], [partial],
  [Functions], [yes], [no],
)&lt;/code&gt;&lt;/pre&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Typst&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Markdown&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Math&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;partial&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Functions&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;hr&gt;&lt;h3&gt;Quotes and footnotes&lt;/h3&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;quote&lt;/span&gt;(block: &lt;span style=&quot;color: #d73948&quot;&gt;true&lt;/span&gt;)[
  Typst is a new markup-based typesetting system that is designed to be as
  powerful as LaTeX while being much easier to learn and use.
]

A footnote&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;footnote&lt;/span&gt;[At the bottom of the page.].&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;Typst is a new markup-based typesetting system that is designed to be as powerful as LaTeX while being much easier to learn and use.&lt;/blockquote&gt;&lt;p&gt;A footnote&lt;sup id=&quot;loc-1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#loc-2&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&lt;hr&gt;&lt;h3&gt;typost extras&lt;/h3&gt;&lt;p&gt;A spoiler hides an inline run until you hover it:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;The butler did it &lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;spoiler&lt;/span&gt;[with the candlestick, in the library].&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The butler did it &lt;span class=&quot;typost-spoiler&quot; tabindex=&quot;0&quot;&gt;with the candlestick, in the library&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;A block spoiler stays blurred until you click it, then stays revealed:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;spoiler&lt;/span&gt;(block: &lt;span style=&quot;color: #d73948&quot;&gt;true&lt;/span&gt;)[
  This block stays blurred behind a &quot;click to reveal&quot; pill until you click it,
  and then it stays revealed.
]&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;typost-spoiler-block&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;typost-spoiler-hint&quot;&gt;click to reveal&lt;/span&gt;&lt;div class=&quot;typost-spoiler-content&quot;&gt;This block stays blurred behind a “click to reveal” pill until you click it, and then it stays revealed.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A region can be encrypted at build time — the plaintext never reaches the page:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;encrypted&lt;/span&gt;(password: &lt;span style=&quot;color: #198810&quot;&gt;&quot;hunter2&quot;&lt;/span&gt;)[
  Only readers who know the password see this.
  The plaintext is not in the page source.
]&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;typost-encrypted&quot;&gt;&lt;div class=&quot;typost-lock&quot;&gt;&lt;style&gt;.typost-lock{max-width:26rem;margin:3rem auto;padding:1.5rem;text-align:center;background:var(--surface,#32302f);border:1px solid var(--surface-2,#3c3836);border-radius:var(--radius,10px);box-shadow:0 12px 32px -24px rgba(0,0,0,.8)}.typost-lock-hint{margin:0 0 1rem;color:var(--fg-dim,#a89984);font-size:.95rem}.typost-lock form{display:flex;flex-direction:column;gap:.6rem}.typost-lock input{width:100%;box-sizing:border-box;padding:.6rem .8rem;background:var(--bg-soft,#282828);color:var(--fg,#d4be98);border:1px solid var(--border,#504945);border-radius:8px;font:inherit;outline:none}.typost-lock input:focus{border-color:var(--accent,#a9b665)}.typost-lock button{padding:.6rem 1.2rem;border:0;border-radius:8px;cursor:pointer;background:var(--accent,#a9b665);color:var(--bg,#1d2021);font:inherit;font-weight:600}.typost-lock button:hover{opacity:.9}.typost-lock-error{margin:.2rem 0 0;color:var(--red,#ea6962);font-size:.9rem}&lt;/style&gt;&lt;form class=&quot;typost-lock-form&quot;&gt;&lt;p class=&quot;typost-lock-hint&quot;&gt;This part is encrypted. Enter the password to read it.&lt;/p&gt;&lt;input type=&quot;password&quot; class=&quot;typost-lock-password&quot; autocomplete=&quot;current-password&quot; placeholder=&quot;Password&quot;&gt;&lt;button type=&quot;submit&quot;&gt;Unlock&lt;/button&gt;&lt;p class=&quot;typost-lock-error&quot; role=&quot;alert&quot; hidden&gt;Wrong password.&lt;/p&gt;&lt;/form&gt;&lt;script type=&quot;application/json&quot; class=&quot;typost-lock-params&quot;&gt;{&quot;salt&quot;:&quot;omR5KS2n6MznwjgiuXdcnw==&quot;,&quot;iv&quot;:&quot;YyCdXsq11Bp5G8he&quot;,&quot;iterations&quot;:600000}&lt;/script&gt;&lt;script type=&quot;text/plain&quot; class=&quot;typost-lock-cipher&quot;&gt;ZXH+AVyrS02bfpgyGiPKva9aO5SC00W+MENio+3IY9iV4G1rrJpLomFEDxoAVomYDGrnv333NBjU8MOn6YWAFEIp6V7NH5C5Pe/wvlH0MLsHQFxHUb/ycwCRBoOz5yQeHL4edj4=&lt;/script&gt;&lt;script&gt;
(function () {
  var lock = document.currentScript.closest(&apos;.typost-lock&apos;);
  if (!lock) return;
  var params = JSON.parse(lock.querySelector(&apos;.typost-lock-params&apos;).textContent);
  var cipherB64 = lock.querySelector(&apos;.typost-lock-cipher&apos;).textContent.trim();
  var form = lock.querySelector(&apos;form&apos;);
  var input = lock.querySelector(&apos;.typost-lock-password&apos;);
  var error = lock.querySelector(&apos;.typost-lock-error&apos;);
  function bytes(b64) {
    return Uint8Array.from(atob(b64), function (c) { return c.charCodeAt(0); });
  }
  if (!window.crypto || !window.crypto.subtle) {
    error.hidden = false;
    error.textContent = &apos;WebCrypto is unavailable; serve this site over http(s).&apos;;
    return;
  }
  form.addEventListener(&apos;submit&apos;, function (event) {
    event.preventDefault();
    error.hidden = true;
    var encoder = new TextEncoder();
    window.crypto.subtle
      .importKey(&apos;raw&apos;, encoder.encode(input.value), &apos;PBKDF2&apos;, false, [&apos;deriveKey&apos;])
      .then(function (material) {
        return window.crypto.subtle.deriveKey(
          { name: &apos;PBKDF2&apos;, salt: bytes(params.salt), iterations: params.iterations, hash: &apos;SHA-256&apos; },
          material,
          { name: &apos;AES-GCM&apos;, length: 256 },
          false,
          [&apos;decrypt&apos;]
        );
      })
      .then(function (key) {
        return window.crypto.subtle.decrypt(
          { name: &apos;AES-GCM&apos;, iv: bytes(params.iv) },
          key,
          bytes(cipherB64)
        );
      })
      .then(function (plain) {
        var holder = document.createElement(&apos;div&apos;);
        holder.innerHTML = new TextDecoder().decode(plain);
        var parent = lock.parentNode;
        while (holder.firstChild) parent.insertBefore(holder.firstChild, lock);
        parent.removeChild(lock);
      })
      .catch(function () {
        error.hidden = false;
        error.textContent = &apos;Wrong password.&apos;;
        input.select();
      });
  });
})();
&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;section role=&quot;doc-endnotes&quot;&gt;&lt;ol style=&quot;list-style-type: none&quot;&gt;&lt;li id=&quot;loc-2&quot;&gt;&lt;sup role=&quot;doc-backlink&quot;&gt;&lt;a href=&quot;#loc-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;At the bottom of the page.&lt;/li&gt;&lt;/ol&gt;&lt;/section&gt;</content>
  </entry>
  <entry>
    <title>The design of typost</title>
    <link href="https://typost.sereph.us/blog/design/" rel="alternate"/>
    <id>https://typost.sereph.us/blog/design/</id>
    <updated>2026-02-10T00:00:00Z</updated>
    <published>2026-02-10T00:00:00Z</published>
    <category term="typost"/>
    <category term="design"/>
    <content type="html">&lt;h2&gt;The design of typost&lt;/h2&gt;&lt;p&gt;typost turns a Typst program into a website. Typst is the authoring &lt;strong&gt;and&lt;/strong&gt; structure language: there is no config DSL, no front-matter format, and no content convention.&lt;/p&gt;&lt;h3&gt;The entry is the site&lt;/h3&gt;&lt;p&gt;The entry file is a Typst program. It declares the site’s metadata and &lt;code&gt;#include&lt;/code&gt;s every page — nothing is discovered from filenames:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #198810&quot;&gt;&quot;lib/typost.typ&quot;&lt;/span&gt;: site

&lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;site&lt;/span&gt;(title: &lt;span style=&quot;color: #198810&quot;&gt;&quot;typost demo&quot;&lt;/span&gt;)

&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color: #198810&quot;&gt;&quot;pages/home.typ&quot;&lt;/span&gt;
&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color: #198810&quot;&gt;&quot;pages/about.typ&quot;&lt;/span&gt;
&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;include&lt;/span&gt; &lt;span style=&quot;color: #198810&quot;&gt;&quot;pages/blog.typ&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;A page is a show rule&lt;/h3&gt;&lt;p&gt;Each page is its own Typst file. It starts with a selectorless show rule that picks a layout; the rest of the file is the body, and named arguments other than &lt;code&gt;route&lt;/code&gt;, &lt;code&gt;layout&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, and &lt;code&gt;tags&lt;/code&gt; become its front matter:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #198810&quot;&gt;&quot;lib/typost.typ&quot;&lt;/span&gt;: page

&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;show&lt;/span&gt;: page.&lt;span style=&quot;color: #4b69c6&quot;&gt;with&lt;/span&gt;(route: &lt;span style=&quot;color: #198810&quot;&gt;&quot;about/index.html&quot;&lt;/span&gt;, title: &lt;span style=&quot;color: #198810&quot;&gt;&quot;About&quot;&lt;/span&gt;)

&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt;=&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;text-decoration: underline&quot;&gt;&lt;strong&gt;About&lt;/strong&gt;&lt;/span&gt;
&lt;span style=&quot;color: #1d6c76&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A layout is called as &lt;code&gt;layout(route, data, content)&lt;/code&gt;, so the theme can render the nav, title, and byline around the body.&lt;/p&gt;&lt;h3&gt;One render, many documents&lt;/h3&gt;&lt;p&gt;typost compiles the entry in Typst’s experimental &lt;strong&gt;bundle&lt;/strong&gt; target: a single compilation emits every document and asset. Because the pages share that bundle, they can query each other. The lists on the &lt;a href=&quot;https://typost.sereph.us/&quot;&gt;home&lt;/a&gt; and &lt;a href=&quot;https://typost.sereph.us/blog/&quot;&gt;blog&lt;/a&gt; pages are not maintained by hand:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;typst&quot;&gt;&lt;span style=&quot;color: #d73948&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #d73948&quot;&gt;context&lt;/span&gt; {
  &lt;span style=&quot;color: #d73948&quot;&gt;for&lt;/span&gt; m &lt;span style=&quot;color: #d73948&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #4b69c6&quot;&gt;query&lt;/span&gt;(metadata).&lt;span style=&quot;color: #4b69c6&quot;&gt;filter&lt;/span&gt;(m &lt;span style=&quot;color: #d73948&quot;&gt;=&gt;&lt;/span&gt; &lt;span style=&quot;color: #74747c&quot;&gt;/* …section == &quot;blog&quot;… */&lt;/span&gt;) [
    &lt;span style=&quot;color: #4b69c6&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #4b69c6&quot;&gt;link&lt;/span&gt;(m.value.typost.data.url, m.value.typost.data.title)
  ]
}&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Plugins and the pipeline&lt;/h3&gt;&lt;p&gt;Everything optional is a plugin. A plugin can contribute Typst modules, mutate the site manifest before render, and rewrite the exported files. They run at fixed stages:&lt;/p&gt;&lt;pre&gt;&lt;code data-lang=&quot;text&quot;&gt;config → typst(plugins) → eval-only → prepare(plugins) → render → post(plugins) → emit&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This demo uses five:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;sitemap&lt;/strong&gt; — writes &lt;code&gt;sitemap.xml&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;feed&lt;/strong&gt; — writes an Atom feed and links it from every page;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;encrypt&lt;/strong&gt; — encrypts a content region at build time;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;taxonomies&lt;/strong&gt; — generates a page per tag/category;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;spoiler&lt;/strong&gt; — hover- and click-to-reveal regions.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Sites and plugins communicate through a &lt;code&gt;metadata((typost: …))&lt;/code&gt; channel that is lifted into the manifest before rendering, so the core stays free of any plugin’s concepts.&lt;/p&gt;&lt;aside class=&quot;callout&quot;&gt;The &lt;a href=&quot;https://typost.sereph.us/blog/tour/&quot;&gt;feature tour&lt;/a&gt; shows the same ideas rendered, with each snippet next to its result.&lt;/aside&gt;</content>
  </entry>
</feed>
