<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>gsr.dev</title>
    <link>https://gsr.dev/blog</link>
    <description>Blog posts from Gabriel Sanches</description>
    <language>en-us</language>
    <pubDate></pubDate>
    <lastBuildDate>Sat, 04 Apr 2026 00:18:06 UTC</lastBuildDate>
    <generator>https://git.sr.ht/~gbrlsnchs/website</generator>
    <item>
      <title>Using Tree-sitter to highlight code on the web</title>
      <link>https://gsr.dev/blog/tree-sitter-on-the-web</link>
      <description>&lt;p&gt;Whenever I wanted to start blogging, I always wondered how to handle syntax
highlighting in code blocks. The two most common options were probably:&lt;ul&gt;&lt;li&gt;Use a JavaScript library to handle that dynamically&lt;li&gt;Skip syntax highlighting whatsoever&lt;/ul&gt;&lt;p&gt;Neither seemed attractive for a blog post, to be honest. Using JavaScript
could introduce the burden of an external runtime dependency, while having no
syntax highlighting at all could backfire by making code snippets confusing
instead of informative.&lt;p&gt;So with that in mind, my end goal was to have something static, consistent,
complete and which I could customize. And then I asked myself, &lt;em&gt;&amp;ldquo;can&amp;rsquo;t I
use Tree-sitter on the web?&amp;rdquo;&lt;/em&gt;.&lt;h2&gt;Enter Tree-sitter&lt;/h2&gt;&lt;p&gt;The first time I got to know Tree-sitter was when I still used the &lt;a href=https://atom-editor.cc/&gt;Atom code
editor&lt;/a&gt;. If I&amp;rsquo;m not wrong, the Tree-sitter project
was created by the Atom team themselves, possibly making it the first code
editor to use Tree-sitter.&lt;p&gt;Then it later followed me through my &lt;a href=https://neovim.io/&gt;Neovim&lt;/a&gt; era, but
I never really delved into how Tree-sitter worked, I only plugged it in to
my editor in order to get nice syntax highlighting.&lt;p&gt;But what&amp;rsquo;s Tree-sitter after all? Quoting the &lt;a href=https://tree-sitter.github.io/tree-sitter/&gt;Tree-sitter
website&lt;/a&gt;:&lt;blockquote&gt;&lt;p&gt;Tree-sitter is a parser generator tool and an incremental parsing library. It
can build a concrete syntax tree for a source file and efficiently update
the syntax tree as the source file is edited.&lt;/blockquote&gt;&lt;p&gt;So very cool. This means we can inject content out of code blocks into
a Tree-sitter parser and retrieve a syntax tree out of it. Amazing!&lt;p&gt;And, differently from code editors, we just want to highlight static code,
so it should be even easier. But this also means we need to set up a build
step for the blog posts.&lt;h2&gt;Parsing code blocks from Markdown files&lt;/h2&gt;&lt;p&gt;I think it&amp;rsquo;s not uncommon for bloggers to use Markdown in order to write
their posts. And I&amp;rsquo;m no different (nor special). I&amp;rsquo;m using Go with two
libraries to parse my blog posts:&lt;ul&gt;&lt;li&gt;&lt;a href=https://github.com/adrg/frontmatter&gt;https://github.com/adrg/frontmatter&lt;/a&gt; to parse Frontmatter metadata from posts&lt;li&gt;&lt;a href=https://github.com/gomarkdown/markdown&gt;https://github.com/gomarkdown/markdown&lt;/a&gt; to parse the Markdown content itself&lt;/ul&gt;&lt;p&gt;All the Markdown content is injected in a &lt;code&gt;post.html&lt;/code&gt; HTML template during
the build step:&lt;pre&gt;&lt;code class=lang-html&gt;&lt;span class=ts-text&gt;{{define &amp;#34;content&amp;#34;}}&lt;/span&gt;
&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;div&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;post&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=ts-text&gt;...&lt;/span&gt;

  &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;article&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=ts-text&gt;{{.Content}}&lt;/span&gt;
  &lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;article&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=ts-text&gt;...&lt;/span&gt;
&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;div&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=ts-text&gt;{{end}}&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;But, in order to capture code blocks during Markdown parsing, we need to
use a custom renderer so that we can intercept code block nodes, parse them
into a syntax tree and inject meaningful &lt;code&gt;&amp;lt;span&gt;&lt;/code&gt; tags surrounding code we
want to highlight.&lt;p&gt;In order to build the syntax tree, I&amp;rsquo;m using
&lt;a href=https://github.com/tree-sitter/go-tree-sitter&gt;https://github.com/tree-sitter/go-tree-sitter&lt;/a&gt;. It has awesome instructions
on how to use it with existing grammars, so I will skip its setup here. You
can always visit the source code for this website by clicking on the link
at the footer. 🙂&lt;p&gt;With a Tree-sitter parser in hands, we need is to create a &lt;em&gt;Markdown render
hook function&lt;/em&gt;. The signature for that looks like the following:&lt;pre&gt;&lt;code class=lang-go&gt;&lt;span class=ts-func&gt;func&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;w&lt;/span&gt; &lt;span class=ts-package_identifier&gt;io&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-type_identifier&gt;Writer&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;node&lt;/span&gt; &lt;span class=ts-package_identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-type_identifier&gt;Node&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;entering&lt;/span&gt; &lt;span class=ts-type_identifier&gt;bool&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt; &lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-package_identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-type_identifier&gt;WalkStatus&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-type_identifier&gt;bool&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;The two important pieces here are the writer &lt;code&gt;w&lt;/code&gt;, to which we need to write
our own output, and &lt;code&gt;node&lt;/code&gt;, which contains the content of our Markdown code
block. And with them, we are able to extract code blocks like this:&lt;pre&gt;&lt;code class=lang-go&gt;&lt;span class=ts-identifier&gt;code&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;ok&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;node&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-*&gt;*&lt;/span&gt;&lt;span class=ts-package_identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-type_identifier&gt;CodeBlock&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;
&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-!&gt;!&lt;/span&gt;&lt;span class=ts-identifier&gt;ok&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
	&lt;span class=ts-return&gt;return&lt;/span&gt; &lt;span class=ts-identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;GoToNext&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-false&gt;false&lt;/span&gt;
&lt;span class=ts-}&gt;}&lt;/span&gt;

&lt;span class=ts-identifier&gt;lang&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-type_identifier&gt;string&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;code&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;Info&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;Whenever we&amp;rsquo;re not dealing with a code block, we just let the Markdown
parser know that it can apply its own thing to the code block and go to
next. Otherwise, we extract the language in order to let the Tree-sitter
parse know which language it should use:&lt;pre&gt;&lt;code class=lang-go&gt;&lt;span class=ts-var&gt;var&lt;/span&gt; &lt;span class=ts-identifier&gt;tslang&lt;/span&gt; &lt;span class=ts-package_identifier&gt;unsafe&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-type_identifier&gt;Pointer&lt;/span&gt;
&lt;span class=ts-switch&gt;switch&lt;/span&gt; &lt;span class=ts-identifier&gt;lang&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
&lt;span class=ts-case&gt;case&lt;/span&gt; &lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-interpreted_string_literal_content&gt;html&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;
	&lt;span class=ts-identifier&gt;tslang&lt;/span&gt; &lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt; &lt;span class=ts-identifier&gt;tshtml&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Language&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;
&lt;span class=ts-case&gt;case&lt;/span&gt; &lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-interpreted_string_literal_content&gt;css&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;
	&lt;span class=ts-identifier&gt;tslang&lt;/span&gt; &lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt; &lt;span class=ts-identifier&gt;tscss&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Language&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;
&lt;span class=ts-case&gt;case&lt;/span&gt; &lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-interpreted_string_literal_content&gt;yaml&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;
	&lt;span class=ts-identifier&gt;tslang&lt;/span&gt; &lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt; &lt;span class=ts-identifier&gt;tsyaml&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Language&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;
&lt;span class=ts-case&gt;case&lt;/span&gt; &lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-interpreted_string_literal_content&gt;go&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;
	&lt;span class=ts-identifier&gt;tslang&lt;/span&gt; &lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt; &lt;span class=ts-identifier&gt;tsgo&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Language&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;
&lt;span class=ts-default&gt;default&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;
	&lt;span class=ts-return&gt;return&lt;/span&gt; &lt;span class=ts-identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;GoToNext&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-false&gt;false&lt;/span&gt;
&lt;span class=ts-}&gt;}&lt;/span&gt;

&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;err&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;tsParser&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;SetLanguage&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;ts&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;NewLanguage&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;tslang&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt; &lt;span class=ts-identifier&gt;err&lt;/span&gt; &lt;span class=&#34;ts-!=&#34;&gt;!=&lt;/span&gt; &lt;span class=ts-nil&gt;nil&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
	&lt;span class=ts-return&gt;return&lt;/span&gt; &lt;span class=ts-identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;Terminate&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-false&gt;false&lt;/span&gt;
&lt;span class=ts-}&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;After the language is selected for the Tree-sitter parser, we build the tree,
write the opening code block tag, and then proceed to walk over the syntax
tree in order to process its leaves. For that, we use a tree cursor:&lt;pre&gt;&lt;code class=lang-go&gt;&lt;span class=ts-identifier&gt;src&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;code&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;Literal&lt;/span&gt;
&lt;span class=ts-identifier&gt;tree&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;tsParser&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Parse&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;src&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-nil&gt;nil&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;
&lt;span class=ts-defer&gt;defer&lt;/span&gt; &lt;span class=ts-identifier&gt;tree&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Close&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;

&lt;span class=ts-identifier&gt;fmt&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Fprintf&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;w&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-grave&gt;`&lt;/span&gt;&lt;span class=ts-raw_string_literal_content&gt;&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;#34;lang-%s&amp;#34;&amp;gt;&lt;/span&gt;&lt;span class=ts-grave&gt;`&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;lang&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;

&lt;span class=ts-var&gt;var&lt;/span&gt; &lt;span class=ts-identifier&gt;pos&lt;/span&gt; &lt;span class=ts-type_identifier&gt;uint&lt;/span&gt; &lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt; &lt;span class=ts-int_literal&gt;0&lt;/span&gt;
&lt;span class=ts-identifier&gt;cursor&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;tree&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;RootNode&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Walk&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;And with that cursor in hands, we can now loop until there are no more leaves
to visit:&lt;pre&gt;&lt;code class=lang-go&gt;&lt;span class=ts-label_name&gt;loop&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;
	&lt;span class=ts-for&gt;for&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
		&lt;span class=ts-identifier&gt;node&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;cursor&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Node&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;

		&lt;span class=ts-comment&gt;// Checking count for named children helps considering literal values as leaf nodes.&lt;/span&gt;
		&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;node&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;NamedChildCount&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt; &lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=ts-int_literal&gt;0&lt;/span&gt; &lt;span class=ts-&amp;&amp;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=ts-identifier&gt;cursor&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;GotoFirstChild&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
			&lt;span class=ts-continue_statement&gt;continue&lt;/span&gt;
		&lt;span class=ts-}&gt;}&lt;/span&gt;

		&lt;span class=ts-comment&gt;// From here on, it&amp;#39;s a leaf.&lt;/span&gt;
		&lt;span class=ts-identifier&gt;start&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;end&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;node&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;ByteRange&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;

		&lt;span class=ts-comment&gt;// Write what comes before the leaf node.&lt;/span&gt;
		&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;start&lt;/span&gt; &lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=ts-identifier&gt;pos&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
			&lt;span class=ts-identifier&gt;before&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;src&lt;/span&gt;&lt;span class=ts-[&gt;[&lt;/span&gt;&lt;span class=ts-identifier&gt;pos&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;&lt;span class=ts-identifier&gt;start&lt;/span&gt;&lt;span class=ts-]&gt;]&lt;/span&gt;
			&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;_&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;err&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;w&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Write&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-[&gt;[&lt;/span&gt;&lt;span class=ts-]&gt;]&lt;/span&gt;&lt;span class=ts-type_identifier&gt;byte&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;html&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;EscapeString&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;before&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt; &lt;span class=ts-identifier&gt;err&lt;/span&gt; &lt;span class=&#34;ts-!=&#34;&gt;!=&lt;/span&gt; &lt;span class=ts-nil&gt;nil&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
				&lt;span class=ts-return&gt;return&lt;/span&gt; &lt;span class=ts-identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;Terminate&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-false&gt;false&lt;/span&gt;
			&lt;span class=ts-}&gt;}&lt;/span&gt;
		&lt;span class=ts-}&gt;}&lt;/span&gt;

		&lt;span class=ts-comment&gt;// Then write the node itself wrapped by the appropriate HTML tag.&lt;/span&gt;
		&lt;span class=ts-identifier&gt;value&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;html&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;EscapeString&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-type_identifier&gt;string&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;src&lt;/span&gt;&lt;span class=ts-[&gt;[&lt;/span&gt;&lt;span class=ts-identifier&gt;start&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt;&lt;span class=ts-identifier&gt;end&lt;/span&gt;&lt;span class=ts-]&gt;]&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;
		&lt;span class=ts-identifier&gt;kind&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;node&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Kind&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt;
		&lt;span class=ts-comment&gt;// ...&lt;/span&gt;

		&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;_&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;err&lt;/span&gt; &lt;span class=&#34;ts-:=&#34;&gt;:=&lt;/span&gt; &lt;span class=ts-identifier&gt;fmt&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Fprintf&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;w&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-grave&gt;`&lt;/span&gt;&lt;span class=ts-raw_string_literal_content&gt;&amp;lt;span class=&amp;#34;ts-%s&amp;#34;&amp;gt;%s&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class=ts-grave&gt;`&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;kind&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-identifier&gt;value&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt; &lt;span class=ts-identifier&gt;err&lt;/span&gt; &lt;span class=&#34;ts-!=&#34;&gt;!=&lt;/span&gt; &lt;span class=ts-nil&gt;nil&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
			&lt;span class=ts-return&gt;return&lt;/span&gt; &lt;span class=ts-identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;Terminate&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-false&gt;false&lt;/span&gt;
		&lt;span class=ts-}&gt;}&lt;/span&gt;

		&lt;span class=ts-identifier&gt;pos&lt;/span&gt; &lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt; &lt;span class=ts-identifier&gt;end&lt;/span&gt;

		&lt;span class=ts-comment&gt;// Apply the same processing to the leaf&amp;#39;s siblings.&lt;/span&gt;
		&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;cursor&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;GotoNextSibling&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
			&lt;span class=ts-continue_statement&gt;continue&lt;/span&gt;
		&lt;span class=ts-}&gt;}&lt;/span&gt;

		&lt;span class=ts-comment&gt;// If no siblings, go back to parents to find new nodes.&lt;/span&gt;
		&lt;span class=ts-for&gt;for&lt;/span&gt; &lt;span class=ts-identifier&gt;cursor&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;GotoParent&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
			&lt;span class=ts-if&gt;if&lt;/span&gt; &lt;span class=ts-identifier&gt;cursor&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;GotoNextSibling&lt;/span&gt;&lt;span class=ts-argument_list&gt;()&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
				&lt;span class=ts-continue&gt;continue&lt;/span&gt; &lt;span class=ts-label_name&gt;loop&lt;/span&gt;
			&lt;span class=ts-}&gt;}&lt;/span&gt;
		&lt;span class=ts-}&gt;}&lt;/span&gt;

		&lt;span class=ts-break_statement&gt;break&lt;/span&gt;
	&lt;span class=ts-}&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;And finally, we close the code block tag and flag that we will use what we
wrote to &lt;code&gt;w&lt;/code&gt;:&lt;pre&gt;&lt;code class=lang-go&gt;&lt;span class=ts-identifier&gt;fmt&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-function_identifier&gt;Fprint&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-identifier&gt;w&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-interpreted_string_literal_content&gt;&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;

&lt;span class=ts-return&gt;return&lt;/span&gt; &lt;span class=ts-identifier&gt;ast&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-field_identifier&gt;GoToNext&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt; &lt;span class=ts-true&gt;true&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;The result of all this parsing is, for example, this kind of HTML code:&lt;pre&gt;&lt;code class=lang-html&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;pre&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;code&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;lang-go&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-func&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;func&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-(&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;(&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;w&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-package_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;io&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-.&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;.&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-type_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;Writer&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-,&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;,&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;node&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-package_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;ast&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-.&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;.&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-type_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;Node&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-,&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;,&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;entering&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-type_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;bool&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-)&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;)&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-(&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;(&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-package_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;ast&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-.&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;.&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-type_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;WalkStatus&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-,&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;,&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-type_identifier&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;bool&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt; &lt;span class=ts-attribute_name&gt;class&lt;/span&gt;&lt;span class=&#34;ts-=&#34;&gt;=&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=ts-attribute_value&gt;ts-)&lt;/span&gt;&lt;span class=ts-double_quote&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=ts-text&gt;)&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;span&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;code&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;ts-&lt;/&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=ts-tag_name&gt;pre&lt;/span&gt;&lt;span class=&#34;ts-&gt;&#34;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;Which I can then style using simply CSS classes:&lt;pre&gt;&lt;code class=lang-css&gt;&lt;span class=ts-tag_name&gt;code&lt;/span&gt;&lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;lang-go&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-type_identifier&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
    &lt;span class=ts-property_name&gt;font-weight&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-plain_value&gt;bold&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
    &lt;span class=ts-property_name&gt;color&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-function_name&gt;var&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-plain_value&gt;--light-cyan&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
  &lt;span class=ts-}&gt;}&lt;/span&gt;

  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-double_quote&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-interpreted_string_literal_content&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
    &lt;span class=ts-property_name&gt;color&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-function_name&gt;var&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-plain_value&gt;--green&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
  &lt;span class=ts-}&gt;}&lt;/span&gt;

  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-import&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-func&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-if&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-var&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-switch&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-case&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-default&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-return&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-continue_statement&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-break_statement&lt;/span&gt;&lt;span class=ts-,&gt;,&lt;/span&gt;
  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-for&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
    &lt;span class=ts-property_name&gt;font-weight&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-plain_value&gt;bold&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
    &lt;span class=ts-property_name&gt;color&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-function_name&gt;var&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-plain_value&gt;--light-red&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
  &lt;span class=ts-}&gt;}&lt;/span&gt;

  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-nil&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
    &lt;span class=ts-property_name&gt;font-weight&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-plain_value&gt;bold&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
    &lt;span class=ts-property_name&gt;color&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-function_name&gt;var&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-plain_value&gt;--blue&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
  &lt;span class=ts-}&gt;}&lt;/span&gt;

  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-comment&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
    &lt;span class=ts-property_name&gt;font-style&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-plain_value&gt;italic&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
    &lt;span class=ts-property_name&gt;color&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-function_name&gt;var&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-plain_value&gt;--gray&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
  &lt;span class=ts-}&gt;}&lt;/span&gt;

  &lt;span class=ts-dot&gt;.&lt;/span&gt;&lt;span class=ts-identifier&gt;ts-field_identifier&lt;/span&gt; &lt;span class=ts-{&gt;{&lt;/span&gt;
    &lt;span class=ts-property_name&gt;font-weight&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-plain_value&gt;bold&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
    &lt;span class=ts-property_name&gt;color&lt;/span&gt;&lt;span class=ts-:&gt;:&lt;/span&gt; &lt;span class=ts-function_name&gt;var&lt;/span&gt;&lt;span class=ts-(&gt;(&lt;/span&gt;&lt;span class=ts-plain_value&gt;--magenta&lt;/span&gt;&lt;span class=ts-)&gt;)&lt;/span&gt;&lt;span class=ts-;&gt;;&lt;/span&gt;
  &lt;span class=ts-}&gt;}&lt;/span&gt;
&lt;span class=ts-}&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;Of course, there is some work in order to style it properly, specially for
languages not yet being considered by the parser logic, but once things look
good, there&amp;rsquo;s nothing much to change.&lt;p&gt;And finally after all this processing, the website builder spits out multiple
&lt;code&gt;index.html&lt;/code&gt; files in structured directories under a &lt;code&gt;pages&lt;/code&gt; directory,
and the static output is pushed to a different repository that is picked by
&lt;a href=https://docs.codeberg.org/codeberg-pages/&gt;Codeberg Pages&lt;/a&gt;, and after a
few minutes, the website is updated.</description>
      <author>Gabriel Sanches</author>
      <pubDate>Mon, 16 Feb 2026 00:00:00 UTC</pubDate>
      <guid>773acf589723bfeb6972dab5e335a545</guid>
    </item>
  </channel>
</rss>
