<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/assets/site_slatecave/atom_to_html.xslt"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>slatecave.net - Slatians Notebook</title>
    <subtitle>Slatians hideout</subtitle>
    <link rel="self" type="application/atom+xml" href="https://slatecave.net/notebook/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-03-22T00:00:00+00:00</updated>
    <id>https://slatecave.net/notebook/atom.xml</id>
    <entry xml:lang="en">
        <title>Caddy JSON log format</title>
        <published>2026-03-22T00:00:00+00:00</published>
        <updated>2026-03-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/caddy-log-format/"/>
        <id>https://slatecave.net/notebook/caddy-log-format/</id>
        
        <summary type="text">How the default JSON access log format of the Caddy webserver is structured</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/caddy-log-format/">&lt;h2 id=&quot;the-access-log-format&quot;&gt;The Access log Format&lt;&#x2F;h2&gt;
&lt;p&gt;The access logs are written as text files with one independent JSON object per line for each request.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;level&lt;&#x2F;code&gt;: log level, set to &lt;code&gt;info&lt;&#x2F;code&gt; for most requests, sometimes &lt;code&gt;error&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ts&lt;&#x2F;code&gt;: Timestamp of thee request, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;caddyserver.com&#x2F;docs&#x2F;json&#x2F;logging&#x2F;logs&#x2F;encoder&#x2F;json&#x2F;time_format&quot;&gt;format is configurable&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;logger&lt;&#x2F;code&gt;: An identifier for the logger inside caddy that produced the line&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;msg&lt;&#x2F;code&gt;: Always set to &lt;code&gt;handled request&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;request&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;remote_ip&lt;&#x2F;code&gt;: IP that the request came from&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;remote_port&lt;&#x2F;code&gt;: Port number that the request came from (as string)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;client_ip&lt;&#x2F;code&gt;: IP that caddy believes is the actual client&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;proto&lt;&#x2F;code&gt;: HTTP protocol i.e. &lt;code&gt;HTTP&#x2F;1.1&lt;&#x2F;code&gt;, &lt;code&gt;HTTP&#x2F;2.0&lt;&#x2F;code&gt;, &lt;code&gt;HTTP&#x2F;3.0&lt;&#x2F;code&gt;, …&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;method&lt;&#x2F;code&gt;: The http method used for the request i.e. &lt;code&gt;GET&lt;&#x2F;code&gt;, &lt;code&gt;OPTIONS&lt;&#x2F;code&gt;, &lt;code&gt;POST&lt;&#x2F;code&gt;, &lt;code&gt;PUT&lt;&#x2F;code&gt;, &lt;code&gt;DELETE&lt;&#x2F;code&gt;, …&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;host&lt;&#x2F;code&gt;: The host the request was targeted at (i.e. &lt;code&gt;example.org&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;uri&lt;&#x2F;code&gt;: Absolue path and query of the URI that was requested i.e. &lt;code&gt;&#x2F;&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;icon.png&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;search&#x2F;?q=foo&lt;&#x2F;code&gt;, …&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;headers&lt;&#x2F;code&gt;: An object describing the request headers&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;tls&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;resumed&lt;&#x2F;code&gt;: nullable boolean, weather a previous tls connection was resumed&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;version&lt;&#x2F;code&gt;: nullable integer, the legacy version field of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Transport_Layer_Security#TLS_record&quot;&gt;TLS-record&lt;&#x2F;a&gt; (substract &lt;code&gt;768&lt;&#x2F;code&gt; to get the minor version)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cipher_suite&lt;&#x2F;code&gt;: nullable integer, &lt;em&gt;somehow&lt;&#x2F;em&gt; encodes the used TLS cipher suite&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;proto&lt;&#x2F;code&gt;: nullable string, empty, null or &lt;code&gt;http&#x2F;1.1&lt;&#x2F;code&gt; for &lt;code&gt;HTTP&#x2F;1.*&lt;&#x2F;code&gt;, &lt;code&gt;h2&lt;&#x2F;code&gt; for &lt;code&gt;HTTP&#x2F;2.0&lt;&#x2F;code&gt; and &lt;code&gt;h3&lt;&#x2F;code&gt; for &lt;code&gt;HTTP&#x2F;3.0&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;server_name&lt;&#x2F;code&gt; nullable string, the name given via SNI&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bytes_read&lt;&#x2F;code&gt;: integer, How many request body bytes were read&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;user_id&lt;&#x2F;code&gt;: string, usually empty&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;duration&lt;&#x2F;code&gt;: float, How long the request took in seconds&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;size&lt;&#x2F;code&gt;: integer: Reply size in bytes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;status&lt;&#x2F;code&gt;: integer: HTTP status code, status code &lt;code&gt;0&lt;&#x2F;code&gt; means that the connection was closed before a reply could be sent&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;resp_headers&lt;&#x2F;code&gt;: Object describing the response headers&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;headers&quot;&gt;Headers&lt;&#x2F;h3&gt;
&lt;p&gt;Header names are always writte in Kebab-Title-Case i.e. &lt;code&gt;User-Agent&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Header names always map to an array of values as it is possible that each header could be duplicated (sometimes intentional, sometimes not).&lt;&#x2F;p&gt;
&lt;p&gt;Some headers like &lt;code&gt;Authorization&lt;&#x2F;code&gt; always have the placeholder value &lt;code&gt;REDACTED&lt;&#x2F;code&gt;, caddy does this automatically by default.&lt;&#x2F;p&gt;
&lt;p&gt;Example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;headers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;Content-Length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;227&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;User-Agent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;Synapse&#x2F;1.149.1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;Content-Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;application&#x2F;json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-property-name&quot;&gt;Authorization&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;REDACTED&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
    </entry>
    <entry xml:lang="en">
        <title>The SQLite strict Guide</title>
        <published>2026-01-23T00:00:00+00:00</published>
        <updated>2026-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/sqlite-strict-guide/"/>
        <id>https://slatecave.net/notebook/sqlite-strict-guide/</id>
        
        <summary type="text">How to make data validation in SQLite possible, an overview</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/sqlite-strict-guide/">&lt;h2 id=&quot;sqlite-is-permissive-by-default&quot;&gt;SQLite is permissive by default&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite is famous for working with the absolute minimum of data specification. While this may help with prototyping it is really bad at catching mistakes early because a lot of unintended things are permitted.&lt;&#x2F;p&gt;
&lt;p&gt;A table definition can be as simple as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; table&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; notes&lt;&#x2F;span&gt;&lt;span&gt;(id, note);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This creates a table &lt;code&gt;notes&lt;&#x2F;code&gt; with the columns &lt;code&gt;id&lt;&#x2F;code&gt; and &lt;code&gt;note&lt;&#x2F;code&gt;. What is permitted inside these columns? Everything!&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Setting &lt;code&gt;note&lt;&#x2F;code&gt; and &lt;code&gt;id&lt;&#x2F;code&gt; both to &lt;code&gt;NULL&lt;&#x2F;code&gt;? Yes&lt;&#x2F;li&gt;
&lt;li&gt;Having ten notes with the same &lt;code&gt;id&lt;&#x2F;code&gt;? Yes&lt;&#x2F;li&gt;
&lt;li&gt;Mixing numbers, text and BLOB-encoded UUIDs in &lt;code&gt;id&lt;&#x2F;code&gt;? Completely fine&lt;&#x2F;li&gt;
&lt;li&gt;Setting &lt;code&gt;note&lt;&#x2F;code&gt; to 3.1415 (the number)? Why not&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As you can see this simple example allows a huge number of unintended variations of the data, most of these will probably make your program crash if actually encountered and it only gets worse with more complex schemata.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;who-is-this-guide-for&quot;&gt;Who is this Guide for?&lt;&#x2F;h2&gt;
&lt;p&gt;This guide is for everyone who wants their database to loudly complain about incorrect data the moment something tries to write it to catch errors early and save headaches later.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to follow along you can do so by running &lt;code&gt;sqlite3&lt;&#x2F;code&gt; and copying the examples into the resulting SQLite shell.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;primary-keys&quot;&gt;&lt;code&gt;PRIMARY KEY&lt;&#x2F;code&gt;s&lt;&#x2F;h2&gt;
&lt;p&gt;Declare your primary keys as &lt;code&gt;INTEGER PRIMARY KEY NOT NULL&lt;&#x2F;code&gt;, this will make them a super fast alias for the &lt;code&gt;rowid&lt;&#x2F;code&gt; and autofill when you&#x27;re inserting new columns.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Using &lt;code&gt;INT PRIMARY KEY&lt;&#x2F;code&gt; will not work!&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;www.sqlite.org&amp;#x2F;lang_createtable.html#rowid&quot; &gt;
		SQLite &lt;code&gt;CREATE TABLE&lt;&#x2F;code&gt; documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;explicit-null-and-not-null&quot;&gt;Explicit &lt;code&gt;NULL&lt;&#x2F;code&gt; and &lt;code&gt;NOT NULL&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;By default SQLite assumes that any column is nullable and usually you don&#x27;t want that because few things can ruin your day like a &lt;code&gt;NULL&lt;&#x2F;code&gt; in the wrong place.&lt;&#x2F;p&gt;
&lt;p&gt;Always declare &lt;code&gt;NULL&lt;&#x2F;code&gt; or &lt;code&gt;NOT NULL&lt;&#x2F;code&gt; with every column.&lt;&#x2F;p&gt;
&lt;p&gt;This way it is always explicit what the column expects.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strict-tables&quot;&gt;&lt;code&gt;STRICT&lt;&#x2F;code&gt; Tables&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite by default does not do any actual type checking on the columns (except for some special cases). Putting &lt;code&gt;STRICT&lt;&#x2F;code&gt; as the last word of a &lt;code&gt;CREATE TABLE&lt;&#x2F;code&gt; statement changes that and makes SQLite check.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example of a strict table:&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; strict_example&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    foo &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bar &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; strict_example(foo, bar) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Human rights&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; strict_example(foo, bar) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Matter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;NULL&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Automatic type conversion still happens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; strict_example(foo, bar) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;123&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;123&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will not work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; strict_example(foo, bar) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Matter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Antimatter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Runtime error: cannot store TEXT value in INTEGER column strict_example.bar (19)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;In strict tables you can use the following datatypes:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type&lt;&#x2F;th&gt;&lt;th&gt;What to use for&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;INT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Prefer using &lt;code&gt;INTEGER&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;INTEGER&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;A 64 bit signed integer (that is encoded suing a variable length scheme), it can also be used as &lt;code&gt;PRIMARY KEY&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;REAL&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;A number type that can store non integer numbers (64-bit float)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;TEXT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Use for storing well formed Unicode&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;BLOB&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Can store arbitrary binary data&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ANY&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;Can store an arbitrary datatype, similar to using a table without &lt;code&gt;STRICT&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Constraints will be checked when modifying table records and can be explicitly checked using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;pragma.html#pragma_integrity_check&quot;&gt;&lt;code&gt;PRAGMA integrity_check&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;pragma.html#pragma_quick_check&quot;&gt;&lt;code&gt;PRAGMA quick_check&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;sqlite.org&amp;#x2F;stricttables.html&quot; &gt;
		SQLite strict table documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;check-constraints&quot;&gt;&lt;code&gt;CHECK()&lt;&#x2F;code&gt; Constraints&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;CHECK(…)&lt;&#x2F;code&gt; constraints can be used for additional validation of data in the same place as &lt;code&gt;UNIQUE&lt;&#x2F;code&gt;, between the parenthesis there must be an SQL expression that must evaluate to a nonzero value for the check to pass. The check is ran and must pass when rows are added or updated.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example would be &lt;code&gt;CHECK(start_time &amp;lt; end)&lt;&#x2F;code&gt;:&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; check_example&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start_time &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    end_time &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;    CHECK&lt;&#x2F;span&gt;&lt;span&gt;(start_time &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span&gt; end_time)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; check_example(start_time, end_time) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; check_example(start_time, end_time) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;NULL&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will fail because of the check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; check_example(start_time, end_time) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Runtime error: CHECK constraint failed: start_time &amp;lt;= end_time (19)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;Trying to construct a record where the start time is after the end time is not possible on this table. However leaving the &lt;code&gt;end_time&lt;&#x2F;code&gt; &lt;code&gt;NULL&lt;&#x2F;code&gt; will be possible because then &lt;code&gt;start_time &amp;lt;= end_time&lt;&#x2F;code&gt; evaluates to &lt;code&gt;NULL&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Using subqueries inside the &lt;code&gt;CHECK&lt;&#x2F;code&gt; is not possible.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;sqlite.org&amp;#x2F;lang_createtable.html#ckconst&quot; &gt;
		SQLite &lt;code&gt;CHECK&lt;&#x2F;code&gt; constraint documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unique-index&quot;&gt;&lt;code&gt;UNIQUE INDEX&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite supports the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqlite.org&#x2F;lang_createtable.html#uniqueconst&quot;&gt;&lt;code&gt;UNIQUE&lt;&#x2F;code&gt; keyword&lt;&#x2F;a&gt; to make sure the values or combinations of values only occur once, this is a well known SQL feature, another way to enforce the same constraints is using &lt;code&gt;CREATE UNIQUE INDEX&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;UNIQUE INDEX&lt;&#x2F;code&gt; has the additional benefit of not only allowing one to use the columns of a table, but also SQL expressions (SQLite calls this an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqlite.org&#x2F;syntax&#x2F;indexed-column.html&quot;&gt;indexed-column&lt;&#x2F;a&gt;) which can be be used to get creative with SQL constraints.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example of a table that enforces a case insensitive uniqueness constraint on the &lt;code&gt;txt&lt;&#x2F;code&gt; column:&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; unique_example&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    txt &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; UNIQUE INDEX&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; case_insensititve&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;ON&lt;&#x2F;span&gt;&lt;span&gt; unique_example(&lt;&#x2F;span&gt;&lt;span&gt;lower&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;txt));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; unique_example(txt) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Abc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will fail becuase a diffent abc is already present&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; unique_example(txt) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ABC&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Runtime error: UNIQUE constraint failed: index &amp;#39;case_insensititve&amp;#39; (19)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	&lt;figcaption&gt;It works by checking the lower cased text is unique.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;b&gt;Note on the Example:&lt;&#x2F;b&gt; This specific constraint could also be applied with a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqlite.org&#x2F;lang_createtable.html#collateclause&quot;&gt;&lt;code&gt;COLLATE NOCASE&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; in combination with a regular &lt;code&gt;UNIQUE&lt;&#x2F;code&gt; on the column.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;sqlite.org&amp;#x2F;lang_createindex.html#uniqueidx&quot; &gt;
		SQLite unique index documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;combining-unique-and-null&quot;&gt;Combining &lt;code&gt;UNIQUE&lt;&#x2F;code&gt; and &lt;code&gt;NULL&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;SQLite handles combining &lt;code&gt;NULL&lt;&#x2F;code&gt; and &lt;code&gt;UNIQUE&lt;&#x2F;code&gt; by allowing &lt;code&gt;NULL&lt;&#x2F;code&gt; to appear multiple times within a unique column.&lt;&#x2F;p&gt;
&lt;p&gt;This behaviour may be different from a database you are used to as some other databases only allow one &lt;code&gt;NULL&lt;&#x2F;code&gt; per unique column.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;sqlite.org&amp;#x2F;nulls.html&quot; &gt;
		SQLite &lt;code&gt;NULL&lt;&#x2F;code&gt; handling documentation and comparison
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;foreign-keys-and-references&quot;&gt;Foreign Keys and &lt;code&gt;REFERENCES&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Enable foreign key support with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PRAGMA foreign_keys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ON&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add a &lt;code&gt;REFERENCES {parent_table}({parent_column})&lt;&#x2F;code&gt; where &lt;code&gt;{parent_table}&lt;&#x2F;code&gt; and &lt;code&gt;{parent_column}&lt;&#x2F;code&gt; identify the database table and column the ids in the annotated column point to. The &lt;code&gt;REFERENCES&lt;&#x2F;code&gt; must point at columns that are a &lt;code&gt;PRIMARY KEY&lt;&#x2F;code&gt; or have a &lt;code&gt;UNIQUE&lt;&#x2F;code&gt; constraint.&lt;&#x2F;p&gt;
&lt;p&gt;In SQLite the terminology is always that a &lt;i&gt;child table&lt;&#x2F;i&gt; references a &lt;i&gt;parent table&lt;&#x2F;i&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also protects the references from breaking by prohibiting any changes to the fields in the parent table that are referenced by any child tables. See the next section on how to configure this.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example where an item table references entries in a category table:&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PRAGMA foreign_keys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ON&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; example_category&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    c_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; example_category(c_id, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;bar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;baz&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; example_item&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    category &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; REFERENCES&lt;&#x2F;span&gt;&lt;span&gt; example_category(c_id)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will work&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; example_item(category) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; example_item(category) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;NULL&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will fail because there is no category with id 30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; example_item(category) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Runtime error: FOREIGN KEY constraint failed (19)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;sqlite.org&amp;#x2F;foreignkeys.html&quot; &gt;
		SQLite foreign key documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;on-update-and-on-delete&quot;&gt;&lt;code&gt;ON UPDATE&lt;&#x2F;code&gt; and &lt;code&gt;ON DELETE&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;This is an extension of the &lt;code&gt;REFERENCES&lt;&#x2F;code&gt; clause in the previous section. The &lt;code&gt;REFERENCES&lt;&#x2F;code&gt; itself can make sure that no new columns violate the schema while &lt;code&gt;ON UPDATE&lt;&#x2F;code&gt; and &lt;code&gt;ON DELETE&lt;&#x2F;code&gt; make sure, they stay valid when &lt;code&gt;UPDATE&lt;&#x2F;code&gt; and &lt;code&gt;DELETE&lt;&#x2F;code&gt; are used on the referenced (&quot;parent&quot;) rows by deciding how those operations should be handled.&lt;&#x2F;p&gt;




	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;NO ACTION&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		No action is taken when the parent key is modified, this is the same behaviour as without any &lt;code&gt;REFERENCES&lt;&#x2F;code&gt; and allows breaking the reference without any intervention or warning from the database.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;RESTRICT&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		This will cause any operation that would result in changed or broken references to throw the error &quot;FOREIGN KEY constraint failed (19)&quot;. This is the default when a &lt;code&gt;REFERENCES&lt;&#x2F;code&gt; doesn&#x27;t specify any &lt;code&gt;ON UPDATE&lt;&#x2F;code&gt; or &lt;code&gt;ON DELETE&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;SET NULL&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		This will set the reference field to &lt;code&gt;NULL&lt;&#x2F;code&gt; on the operation(s) it is configured for.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;SET DEFAULT&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		This will set the reference field to its &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;lang_createtable.html#the_default_clause&quot;&gt;&lt;code&gt;DEFAULT&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; value on the operation(s) it is configured for.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;CASCADE&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		This will make the references follow what the parent is doing, on an update all referencing fields will be updated too, on a deletion all referencing fields will be deleted too.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example that demonstrates cascading updates and deletes in a setting where log entries reference some kind of program run:&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PRAGMA foreign_keys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ON&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; example_run&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    r_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    name&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; example_run(r_id, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;name&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;blubber&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dragon&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; example_log&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    l_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; PRIMARY KEY&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    run &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;INTEGER&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; REFERENCES&lt;&#x2F;span&gt;&lt;span&gt; example_run(r_id) &lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;ON UPDATE CASCADE&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt; ON DELETE CASCADE&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    message&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; NOT NULL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;) STRICT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; example_log(run, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;message&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;blah&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;blubb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dragon goes &amp;quot;miep&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;dragon receives hug&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Move ids of the run around for demonstration purposes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;UPDATE&lt;&#x2F;span&gt;&lt;span&gt; example_run &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;SET&lt;&#x2F;span&gt;&lt;span&gt; r_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; WHERE&lt;&#x2F;span&gt;&lt;span&gt; r_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; All entries previously associated with run 2 have now been rewritten to run 42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span&gt; run, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; FROM&lt;&#x2F;span&gt;&lt;span&gt; example_log;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 1|blah&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 1|blubb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 1|done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 42|dragon goes &amp;quot;miep&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 42|dragon receives hug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Will delete the run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;DELETE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; FROM&lt;&#x2F;span&gt;&lt;span&gt; example_run &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;WHERE&lt;&#x2F;span&gt;&lt;span&gt; r_id &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; And also the log entries associated with the run:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; This will return no entries where the run is set to 1.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span&gt; run, &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; FROM&lt;&#x2F;span&gt;&lt;span&gt; example_log;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Output:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 42|dragon goes &amp;quot;miep&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; 42|dragon receives hug&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;sqlite.org&amp;#x2F;foreignkeys.html#fk_actions&quot; &gt;
		SQLite &lt;code&gt;ON DELETE&lt;&#x2F;code&gt; and &lt;code&gt;ON UPDATE&lt;&#x2F;code&gt; documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also-triggers&quot;&gt;See also: Triggers&lt;&#x2F;h2&gt;
&lt;p&gt;Triggers can be a way to enforce other constraints on the data model, even spanning multiple tables and producing custom error messages using the &lt;code&gt;RAISE()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;However, getting triggers right would a it&#x27;s own guide and usually one wants &lt;code&gt;INSERT&lt;&#x2F;code&gt; &lt;em&gt;and&lt;&#x2F;em&gt; &lt;code&gt;UPDATE&lt;&#x2F;code&gt; triggers leading to a lot of duplicate code that is difficult to debug.&lt;&#x2F;p&gt;
&lt;p&gt;In a nutshell: Triggers are powerful but difficult, use them only when there is absolutely no other option.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;www.sqlite.org&amp;#x2F;lang_createtrigger.html&quot; &gt;
		SQLite &lt;code&gt;CREATE TRIGGER&lt;&#x2F;code&gt; documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Interesting Resources for building Search Engines</title>
        <published>2025-02-01T00:00:00+00:00</published>
        <updated>2026-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/interesting-search/"/>
        <id>https://slatecave.net/notebook/interesting-search/</id>
        
        <summary type="text">A collection of links to articles and documentation.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/interesting-search/">&lt;h2 id=&quot;how-search-works&quot;&gt;How Search works&lt;&#x2F;h2&gt;
&lt;p&gt;Articles that dive into how a Search Engine works under the hood.&lt;&#x2F;p&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;izihawa.github.io&#x2F;summa&#x2F;blog&#x2F;how-search-engines-work&#x2F;&quot;&gt;How Search Engines Work — Summa Blog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.meilisearch.com&#x2F;blog&#x2F;how-full-text-search-engines-work&quot;&gt;How to […]: inside a full text search engine — meilisearch Blog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;infolab.stanford.edu&#x2F;pub&#x2F;papers&#x2F;google.pdf&quot;&gt;The Anatomy of a Large-Scale Hypertextual Web Search Engine — The original Google Paper (PDF)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;p&gt;&lt;b&gt;Shameless self promotion:&lt;&#x2F;b&gt; Check out the &lt;a href=&quot;&#x2F;topics&#x2F;#search-engines&quot;&gt;Search Engines topic here on slatecave.net&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;datastructures&quot;&gt;Datastructures&lt;&#x2F;h2&gt;
&lt;p&gt;Datastructures useful for building search engines.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fst-finite-state-transducers&quot;&gt;FST — Finite State Transducers&lt;&#x2F;h3&gt;
&lt;p&gt;In a nutshell: FSTs use properties of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Finite-state_machine&quot;&gt;State Machines&lt;&#x2F;a&gt; to store sorted sets of strings, map strings to numbers and run fast prefix queries, but also other queries using automata like regex or even &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Levenshtein_distance&quot;&gt;levenstein distance&lt;&#x2F;a&gt; queries.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;burntsushi.net&amp;#x2F;transducers&amp;#x2F;&quot; &gt;
		Index 1,600,000,000 Keys with Automata and Rust
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;An implementation would be the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BurntSushi&#x2F;fst&quot;&gt;rust fst crate&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;roaring-bitmaps&quot;&gt;Roaring Bitmaps&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;roaringbitmap.org&#x2F;&quot;&gt;Roaring Bitmaps&lt;&#x2F;a&gt; are datastructures, that from the outside can be operated like giant bitmaps, storing very big sets of numbers, but optimise themselves on the inside to use memory as efficient as possible and staying fast.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;arxiv.org&amp;#x2F;pdf&amp;#x2F;1402.6407v4&quot; &gt;
		Better bitmap performance with Roaring bitmaps — Research Paper (PDF)
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;crawling-strategies&quot;&gt;Crawling strategies&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;stract&quot;&gt;Stract&lt;&#x2F;h3&gt;
&lt;p&gt;Stract is mostly Interesting because of its politeness algorithm that in a nutshell is a politeness factor multiplied by a either the response time or a minimum delay, whichever is larger. Capped at a maximum delay of 180s that should be good for the website and the crawler.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; While the algorithm is Interesting the robots.txt &lt;code&gt;Crawl-delay&lt;&#x2F;code&gt; should take priority if present (though that one should also be capped at a friendly value).&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;stract.com&amp;#x2F;webmasters&quot; &gt;
		Stract Crawler — Webmaster Documentation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;server-to-crawler-protocols&quot;&gt;Server to Crawler Protocols&lt;&#x2F;h2&gt;
&lt;p&gt;If are crawling the web and care about admins not making your life difficult one should respect the web servers and their administrators. Respecting these signals also helps gathering higher quality data.&lt;&#x2F;p&gt;
&lt;p&gt;The baseline is implementing and respecting robot.txt, other protocols may provide additional useful metadata depending on your use case.&lt;&#x2F;p&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.robotstxt.org&#x2F;&quot;&gt;robots.txt website&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;community&#x2F;reports&#x2F;tdmrep&#x2F;CG-FINAL-tdmrep-20240202&#x2F;#sec-introduction&quot;&gt;Text Data Mining — TDM Reservation Protocol&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;p&gt;An interesting overview is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;seirdy.one&#x2F;meta&#x2F;scrapers-i-block&#x2F;#how-i-block-bots&quot;&gt;&quot;How I block bots&quot; by Seirdy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;relevancy-and-ranking&quot;&gt;Relevancy and Ranking&lt;&#x2F;h2&gt;
&lt;p&gt;List of algorithms that allow one to sort search results.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bag-of-words-ranking&quot;&gt;Bag of words ranking&lt;&#x2F;h3&gt;
&lt;p&gt;The most straight forward way of measuring how well a document matches a query is word counting. Though simple counters aren&#x27;t very good at this, weighting them relative to statistics of your document corpus makes very good at keyword based search though.&lt;&#x2F;p&gt;
&lt;p&gt;Usually the go to is BM25 as it automatically lightens the impact of common words and rewards completeness over repeating the same words over and over again. It also has a theoretical maximum output, so one can normalise it.&lt;&#x2F;p&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Okapi_BM25&quot;&gt;Okapi BM25 — simple normalised and tuneable term frequency based algorithm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tf%E2%80%93idf&quot;&gt;TF-IDF — term frequency-inverse document frequency&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;h3 id=&quot;pagerank&quot;&gt;PageRank&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;PageRank&quot;&gt;PageRank&lt;&#x2F;a&gt; at its core is for measuring a documents overall relevancy in the context of other documents that can link to each other, not towards a search query.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s famous for being at the core of Google for many years.&lt;&#x2F;p&gt;
&lt;p&gt;The PageRank algorithm is described in the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;infolab.stanford.edu&#x2F;pub&#x2F;papers&#x2F;google.pdf&quot;&gt;original Google Paper from 1998&lt;&#x2F;a&gt; but also has its own dedicated Paper.&lt;&#x2F;p&gt;
&lt;p&gt;In a nutshell: Every page has a score, it distributes that score via its links to other pages (and keeps some for itself for dampening reasons) iterate a few times and the scores now represent how relevant in terms of incoming links a page is.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;http:&amp;#x2F;&amp;#x2F;ilpubs.stanford.edu:8090&amp;#x2F;422&amp;#x2F;1&amp;#x2F;1999-66.pdf&quot; &gt;
		The PageRank Citation Ranking: Bringing Order to the Web
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h3 id=&quot;textrank&quot;&gt;TextRank&lt;&#x2F;h3&gt;
&lt;p&gt;TextRank is a variation of PageRank applied to texts.&lt;&#x2F;p&gt;
&lt;p&gt;It can be used for keyword extraction, simple, automatic summaries, but also for augmenting bag of words algorithms with some smarter weights.&lt;&#x2F;p&gt;
&lt;p&gt;TextRank can also be used to pull in knowledge from a knowledge graph when connecting words and sentences.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;aclanthology.org&amp;#x2F;W04-3252&amp;#x2F;&quot; &gt;
		TextRank: Bringing Order into Text
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;text-processing&quot;&gt;Text Processing&lt;&#x2F;h2&gt;
&lt;p&gt;Text by itself is pretty messy, when building a search engine one probably wants to apply some normalization.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;snowball-stemming&quot;&gt;Snowball Stemming&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Snowball is a small string processing language for creating stemming algorithms for use in Information Retrieval, plus a collection of stemming algorithms implemented using it.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The best thing about Snowball is that it can be compiled to other languages you are more likely to write your search engine in.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;snowballstem.org&amp;#x2F;&quot; &gt;
		Snowball
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Acronyms on the Social Internet</title>
        <published>2024-12-25T00:00:00+00:00</published>
        <updated>2024-12-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/social-acronyms/"/>
        <id>https://slatecave.net/notebook/social-acronyms/</id>
        
        <summary type="text">A little dictionary for random letter collections one might encounter on the Internet.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/social-acronyms/">&lt;p&gt;&lt;q&gt;TIL: This thing is very useful IMHO&lt;&#x2F;q&gt; … what ???&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acronyms&quot;&gt;Acronyms&lt;&#x2F;h2&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		ALT (Text)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Alternative Text
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		ALT-Text is a kind of image description that describes the &lt;em&gt;meaning&lt;&#x2F;em&gt; of or the &lt;em&gt;intention&lt;&#x2F;em&gt; behind an image (but not necessarily every visual detail) so it helps people who can&#x27;t see (slow connection, broken link, blind, …) or understand image for some reason.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		It can also be used as an art-form where the ALT-Text serves its original function &lt;strong&gt;and&lt;&#x2F;strong&gt; is itself worth reading because it is written in a creative way.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		alt (Account)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Alternative&#x2F;Secondary Account
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Some people have multiple Accounts they publish on or openly keep as backups, these may be referred to as alt accounts or &lt;q&gt;alts&lt;&#x2F;q&gt;.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		CW
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Trauma_trigger#Trigger_warnings&quot;&gt;Content Warning&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		DM
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Direct Message
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Message sent with restricted visibility to only a few intended recipients.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		IMO
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		In My Opinion
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		IMHO
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		In My Honest Opinion
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		OH
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Over Heard
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Usually used as a prefix for posts quoting something funny someone overheard.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		The variation &lt;q&gt;Self OH&lt;&#x2F;q&gt; means someone is quoting themselves.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		RFC
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Request For Comments
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Either refers to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;&quot;&gt;IETF&#x2F;IRTF&#x2F;IAB RFC specifications&lt;&#x2F;a&gt;, a project specific RFC system or a standalone document someone wants feedback on.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		TIL
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Today I Learned
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Used as a prefix for posts where someone who just learned about something is sharing that information. Usually because that information is considered useful.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;This list isn&#x27;t complete, it&#x27;ll be expanded as people ask me or I learn about things myself.&lt;&#x2F;p&gt;
&lt;p&gt;Also see the list of Acronyms for content warnings below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tone-indicators&quot;&gt;Tone Indicators&lt;&#x2F;h2&gt;
&lt;p&gt;Tone indicators like &lt;code&gt;&#x2F;s&lt;&#x2F;code&gt; are sometimes appended to the end of a message to signal the intention behind a message (i.e. sarcasm), because on the internet things aren&#x27;t always obvious (evidence: you are reading this article). They always start with a forward slash &lt;code&gt;&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The most important&#x2F;common ones are:&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;&#x2F;s&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		sarcasm
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;&#x2F;j&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		joking
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;&#x2F;hj&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		half joking
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-action-next&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;en.wikipedia.org&amp;#x2F;wiki&amp;#x2F;Tone_indicator&quot; &gt;
		Wikipedia has a more complete list and background information.
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acronyms-for-content-warnings&quot;&gt;Acronyms for Content Warnings&lt;&#x2F;h2&gt;
&lt;p&gt;Content warnings are an important mechanism to let people opt out of content they might find uncomfortable to very stressing. To keep the needed effort low a bunch of acronyms to tag common&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;+&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Positive Content
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Used as a suffix the poster thinks the content behind the warning is on the more positive side of things.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;-&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Negative Content
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Used as a suffix the poster thinks the content behind the warning is on the more negative side of things.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		ph
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Physical Health
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Usually content mentioning injuries or other physical health issues
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		mh
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Mental Health
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Content mentioning mental health issues
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		pol, depol, uspol, …
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Politics
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Usually used as part of &lt;i&gt;Content Warning&lt;&#x2F;i&gt; messages to flag messages mentioning politics, it can be prefixed by a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_ISO_3166_country_codes&quot;&gt;two or three letter country reference&lt;&#x2F;a&gt; to quickly communicate which country is talked about.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Templating Zoo</title>
        <published>2024-07-02T00:00:00+00:00</published>
        <updated>2024-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/templating/"/>
        <id>https://slatecave.net/notebook/templating/</id>
        
        <summary type="text">Stuck with some undocumented templating?</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/templating/">&lt;h2 id=&quot;what-is-templating&quot;&gt;What is Templating?&lt;&#x2F;h2&gt;
&lt;p&gt;Templating in the sense of this articlee is when there is a text with placeholders that get filled in according to some set of rules (the &lt;i&gt;templating language&lt;&#x2F;i&gt;). Using templating is often easier than hardcoding some string assembly logic, it also has the benefit that the template could be read in from a configuration file.&lt;&#x2F;p&gt;
&lt;p&gt;In case you&#x27;ve ended up here because you have some sample templating but no documentation: Keep reading, you&#x27;ll probably find what you&#x27;re searching for. (No gurantees though, there are many templating mechanisms out there)&lt;&#x2F;p&gt;
&lt;p&gt;Since most Templating languages borrow from each other it makes sense to group them into Families.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-printf-likes&quot;&gt;The printf likes&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Printf&quot;&gt;printf()&lt;&#x2F;a&gt; function makes it easy to generate semi-templated text in C and other languages without having to do manual string manipulaion. These templates are sometimes even applicable in reverse like with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scanf&quot;&gt;scanf&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;man3&#x2F;strptime.3&quot;&gt;strptime&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		How to recognize
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The placeholders usually start with a percent sign (&lt;code&gt;%&lt;&#x2F;code&gt;) and end in a single letter that depends on the datatype. Extra information on how exactly to format is between the two.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Special characters may be escapable using &lt;a href=&quot;&#x2F;notebook&#x2F;ascii&#x2F;#escaping-in-scripting-and-programming&quot;&gt;backslash (&lt;code&gt;&#x2F;&lt;&#x2F;code&gt;) escape sequences&lt;&#x2F;a&gt;.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Examples
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;Template that contains a string: %s&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;Formatted number: %.2f&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;Literal percent sign: %%&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Languages
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		printf likes are implemented in many places
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		The fully featured printf is likely to be found around C programs or in scripting languages like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.lua.org&#x2F;manual&#x2F;5.4&#x2F;manual.html#pdf-string.format&quot;&gt;&lt;code&gt;string.format()&lt;&#x2F;code&gt; in lua&lt;&#x2F;a&gt; or the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;printf&quot;&gt;printf shell command&lt;&#x2F;a&gt;.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Documentation
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Printf#Format_specifier&quot;&gt;printf&lt;&#x2F;a&gt; for generic number and string formatting
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;strftime.3&quot;&gt;strftime&lt;&#x2F;a&gt; for formatting timestamps (quite popular across different libraries)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		custom formats like for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;find#printf&quot;&gt;find command&lt;&#x2F;a&gt; also exist, those are usually documented in a manual somewhere
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;&lt;b&gt;Compatibility Warning:&lt;&#x2F;b&gt; printf implementations are not consistent and not all implementations support all features. For example encoding characters as octal (i.e. &lt;code&gt;&#x2F;033&lt;&#x2F;code&gt;) is more widely supported than its hexadecimal cousin (i.e. &lt;code&gt;\x1B&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;python-printf-style&quot;&gt;Python printf-style&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3.12&#x2F;library&#x2F;stdtypes.html#old-string-formatting&quot;&gt;Python has &quot;printf-style String Formatting&quot;&lt;&#x2F;a&gt; using the &lt;code&gt;%&lt;&#x2F;code&gt;-operator. The printf syntax has been extended to allow indexing dictionaries and is usually encoutered as &lt;code&gt;%(key)s&lt;&#x2F;code&gt; where &lt;code&gt;key&lt;&#x2F;code&gt; is the key used to index the dictionary and &lt;code&gt;s&lt;&#x2F;code&gt; is an example of the most common printf type, but all other types work too, if the data allows.&lt;&#x2F;p&gt;
&lt;p&gt;While &lt;strong&gt;this approach is dicouraged&lt;&#x2F;strong&gt; (in favor of pythons new format function) it will be used for quite some time in configuration files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;go-templates&quot;&gt;Go-Templates&lt;&#x2F;h2&gt;
&lt;p&gt;Go-templates are named after ther implementation in the go programming language, the are part of the de-facto standard library. They are best known from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gohugo.io&#x2F;&quot;&gt;Hugo static site generator&lt;&#x2F;a&gt;, though the hugo extension usually aren&#x27;t reimplemented elsewhere. The template packages by themselves are pretty barebones.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		How to recognize
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;strong&gt;All&lt;&#x2F;strong&gt; template syntax happens eclosed between &lt;code&gt;{{&lt;&#x2F;code&gt; and &lt;code&gt;}}&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Placeholders usually start with a dot (&lt;code&gt;.&lt;&#x2F;code&gt;)
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Examples
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;{{.Count}} items are made of {{.Material}}&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;{{23 -}} &amp;lt; {{- 45}}&lt;&#x2F;code&gt; renders to &lt;code&gt;23&amp;lt;45&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;Hello, {{.}}!&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;{{ if and (eq .View &quot;search&quot;) (ne .Data.Site &quot;&quot;) }}…{{ end }}&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Langugage
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Go
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Documentation
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;text&#x2F;template&quot;&gt;text&#x2F;template&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;html&#x2F;template&quot;&gt;html&#x2F;template&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;jinja2-and-friends&quot;&gt;Jinja2 and friends&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jinja.palletsprojects.com&#x2F;en&#x2F;&quot;&gt;Jinja2&lt;&#x2F;a&gt; is a flexible and popular templating engine, that is used almost everywhere, where moere advanced templating is used. It also heavily inspired the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keats.github.io&#x2F;tera&#x2F;&quot;&gt;tera crate for rust&lt;&#x2F;a&gt;, which has almost identical syntax.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		How to recognize
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Variables are enclosed in &lt;code&gt;{{&lt;&#x2F;code&gt; and &lt;code&gt;}}&lt;&#x2F;code&gt;, template logic uses &lt;code&gt;{%&lt;&#x2F;code&gt; and &lt;code&gt;%}&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Templates based on other templates have &lt;code&gt;{% extends &quot;…&quot; %}&lt;&#x2F;code&gt; as their first line.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Variables don&#x27;t start with a dot (&lt;code&gt;.&lt;&#x2F;code&gt;) (that&#x27;&#x27;s a go template thing)
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Examples
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;This morning I need {{ size | default(value=&quot;a huge cup of&quot; }} coffe.&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;{% if thing.is_working %}🥳{% else %}🔧{% endif %}&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Languages
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Python
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Rust
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Documentation
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jinja.palletsprojects.com&#x2F;en&#x2F;&quot;&gt;Jinja2&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;keats.github.io&#x2F;tera&#x2F;docs&#x2F;&quot;&gt;tera&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Where to find
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		In web-related contexts, generating HTML or XML
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Configuration templates, for example in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.ansible.com&#x2F;ansible&#x2F;latest&#x2F;collections&#x2F;ansible&#x2F;builtin&#x2F;template_module.html&quot;&gt;Ansible&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		In other contexts too …
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;xslt&quot;&gt;XSLT&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;XSLT&quot;&gt;XSLT (Extensible Stylesheet Language Transformations)&lt;&#x2F;a&gt; is usually used to convert XML to different XML, but it can also be (ab)used to convert XML to text.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
				
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		How to recognize
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The template is XML and mentions the &lt;code&gt;xsl:&lt;&#x2F;code&gt; namespace (&lt;code&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;XSL&#x2F;Transform&lt;&#x2F;code&gt;) a lot.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Example
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;XSLT#Examples&quot;&gt;Wikipedia Article on XSLT&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Languages
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Java, but not exclusiely
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Where to find
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		In enterprisey apllications from the 90s
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;a href=&quot;&#x2F;blog&#x2F;atom-xslt&#x2F;&quot;&gt;In your web-browser&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Standards Zoo</title>
        <published>2024-06-01T00:00:00+00:00</published>
        <updated>2024-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/standards/"/>
        <id>https://slatecave.net/notebook/standards/</id>
        
        <summary type="text">Bookmarks for public content of widely used ISO-Standards.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/standards/">&lt;h2 id=&quot;why-this-page-exists&quot;&gt;Why this page exists&lt;&#x2F;h2&gt;
&lt;p&gt;Many things in our world interoperate because they are standardised. Most notably the internet which is built on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rfc-editor.org&quot;&gt;freely available Standards published by the Internet Engineering Task Force (IETF) on rfc-editor.org&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However most standardisation organisations charge a premium for the standard documents. Through various legal frameworks and publishing by the organisations in their own interest the important content of those standards is public knowledge.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Useful Previews:&lt;&#x2F;b&gt; ISO has free previews of specifications that only include the informative sections. (Those may already contain the information you need to understand something.&lt;&#x2F;p&gt;
&lt;p&gt;This page aims to collect these in one place, one Section per topic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;timekeeping&quot;&gt;Timekeeping&lt;&#x2F;h2&gt;
&lt;p&gt;For Date and Timestamps there are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;standard&#x2F;70907.html&quot;&gt;ISO 8601-1&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;standard&#x2F;70908.html&quot;&gt;ISO 8601-2&lt;&#x2F;a&gt;. The most important part of those (exact timestamps) is also known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3339&quot;&gt;RFC 3339&lt;&#x2F;a&gt; which got extended by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc9557&quot;&gt;RFC 9557&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ISO_8601&quot;&gt;Wikipedia article on ISO 8601&lt;&#x2F;a&gt; also explains pretty well what the standard specifies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;languages&quot;&gt;Languages&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;language-identification&quot;&gt;Language Identification&lt;&#x2F;h3&gt;
&lt;p&gt;When in need of a list of codes for unambiguous language identification the standard is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;standard&#x2F;74575.html&quot;&gt;ISO 639&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;iso-639-language-code&quot;&gt;ISO 639 Popular standards article&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;One of the official language registries is maintained by the US Library of Congress. A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.loc.gov&#x2F;standards&#x2F;iso639-2&#x2F;&quot;&gt;list for languages titled ISO 639-2&lt;&#x2F;a&gt; and one for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.loc.gov&#x2F;standards&#x2F;iso639-5&#x2F;&quot;&gt;language families titled ISO 639-5&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iso639-3.sil.org&#x2F;&quot;&gt;complete ISO 639-3 language list&lt;&#x2F;a&gt; is officially maintained by SIL International (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sil.org&#x2F;language-technology&#x2F;standards&quot;&gt;SIL also promotes other language related standards&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;language-tagging&quot;&gt;Language Tagging&lt;&#x2F;h3&gt;
&lt;p&gt;For language tagging (i.e. describing a documents language, like the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;html.spec.whatwg.org&#x2F;multipage&#x2F;dom.html#the-lang-and-xml:lang-attributes&quot;&gt;HTML &lt;code&gt;lang&lt;&#x2F;code&gt; attribute&lt;&#x2F;a&gt;) there is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;info&#x2F;bcp47&quot;&gt;BCP 47 collection of standards&lt;&#x2F;a&gt; the corresponding &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;language-subtag-registry&#x2F;language-subtag-registry&quot;&gt;language subtag registry maintained by IANA&lt;&#x2F;a&gt; contains codes and descriptions for languages, language variants, regions, scripts. Most of them are compatible with their ISO counterparts.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The form of language tag with the underscore (i.e. &lt;code&gt;de_DE&lt;&#x2F;code&gt;) &lt;strong&gt;is not&lt;&#x2F;strong&gt; and has never been BCP 47 compliant, write it with a hyphen (i.e. &lt;code&gt;de-DE&lt;&#x2F;code&gt;) instead. The underscore version is used in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9799919799&#x2F;basedefs&#x2F;V1_chap08.html#tag_08_02&quot;&gt;POSIX systems for Localization&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;script-identification&quot;&gt;Script Identification&lt;&#x2F;h3&gt;
&lt;p&gt;For unambiguous script identification &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;standard&#x2F;81905.html&quot;&gt;ISO 15924&lt;&#x2F;a&gt; assigns unambiguous four-letter codes to every script in wide enough use that they are relevant. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.unicode.org&#x2F;iso15924&#x2F;&quot;&gt;ISO 15924 code list&lt;&#x2F;a&gt; is maintained by the Unicode consortium.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;regions-and-countries&quot;&gt;Regions and Countries&lt;&#x2F;h2&gt;
&lt;p&gt;For identifying countries and their subdivision there is ISO 3166 (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;iso-3166-country-codes.html&quot;&gt;ISO 3166 Popular  standards article&lt;&#x2F;a&gt;). The Machine readable lists are a paid service, but there is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;obp&#x2F;ui&#x2F;#iso:pub:PUB500001:en&quot;&gt;human readable list of the ISO 3166-1 codes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There is a useful &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_ISO_3166_country_codes&quot;&gt;List of ISO 3166 country codes on Wikipedia&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;language-subtag-registry&#x2F;language-subtag-registry&quot;&gt;BCP 47 language subtag registry&lt;&#x2F;a&gt; also maps some of the Alpha-2 codes to English country names.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;places-with-transportation-infrastructure&quot;&gt;Places with Transportation Infrastructure&lt;&#x2F;h3&gt;
&lt;p&gt;For places with Transportation Infrastructure there is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unece.org&#x2F;trade&#x2F;uncefact&#x2F;unlocode&quot;&gt;UN&#x2F;LOCODE&lt;&#x2F;a&gt;. It also has a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;service.unece.org&#x2F;trade&#x2F;locode&#x2F;2023-1%20SubdivisionCodes.htm&quot;&gt;list of Countries and their subdivisions&lt;&#x2F;a&gt; and a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;unece.org&#x2F;trade&#x2F;cefact&#x2F;unlocode-code-list-country-and-territory&quot;&gt;list of Countries and places with transportation infrastructure&lt;&#x2F;a&gt; relevant for larger scale trading.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;business&quot;&gt;Business&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;identifying-currencies&quot;&gt;Identifying Currencies&lt;&#x2F;h3&gt;
&lt;p&gt;For unambiguous currency identification &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;standard&#x2F;64758.html&quot;&gt;ISO 4217&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iso.org&#x2F;iso-4217-currency-codes.html&quot;&gt;ISO 4217 Popular standards article&lt;&#x2F;a&gt;) specifies lists of current and historic currencies. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.six-group.com&#x2F;en&#x2F;products-services&#x2F;financial-information&#x2F;data-standards.html&quot;&gt;currency registry&lt;&#x2F;a&gt; is maintained by Six Group Ltd.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Portable Shell-Scripting</title>
        <published>2024-05-17T00:00:00+00:00</published>
        <updated>2024-05-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/portable-shell/"/>
        <id>https://slatecave.net/notebook/portable-shell/</id>
        
        <summary type="text">Knowledge for writing portable shell scripts that work across operating system distributions.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/portable-shell/">&lt;h2 id=&quot;what-makes-your-shellscripts-break&quot;&gt;What makes your shellscripts break?&lt;&#x2F;h2&gt;
&lt;p&gt;Before outlining how shellscripts can be made portable … why do they break?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;This is a &quot;you should consider&quot;, not a &quot;you have to&quot;:&lt;&#x2F;b&gt; Depending on the purpose and intended audience of your script not all of the following may apply.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-my-shell&quot;&gt;Not my Shell&lt;&#x2F;h3&gt;
&lt;p&gt;Not everyone has the same shell installed. Different systems come with different shells installed, mainly either &lt;code&gt;bash&lt;&#x2F;code&gt; or &lt;code&gt;dash&lt;&#x2F;code&gt; (though there are other shells for running scripts you might run across).&lt;&#x2F;p&gt;
&lt;p&gt;While the language those shells use looks the same every shell has some extensions to make live a bit easier. Problem is that using those extensions aren&#x27;t standardised and only work in one specific shell, that might not be installed on your target system.&lt;&#x2F;p&gt;
&lt;p&gt;This problem usually happens with bash extensions, they are also known as &lt;i&gt;bashisms&lt;&#x2F;i&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-my-coreutils&quot;&gt;Not my Coreutils&lt;&#x2F;h3&gt;
&lt;p&gt;The coreutils are those programs everyone uses all the time when writing more advanced shell scripts. Examples are &lt;code&gt;grep&lt;&#x2F;code&gt;, &lt;code&gt;sed&lt;&#x2F;code&gt;, &lt;code&gt;ls&lt;&#x2F;code&gt; and so on.&lt;&#x2F;p&gt;
&lt;p&gt;Well known implementations are the GNU coreutils, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.busybox.net&#x2F;&quot;&gt;busybox&lt;&#x2F;a&gt; or Apples implementation for MacOS.&lt;&#x2F;p&gt;
&lt;p&gt;Like the shells different implementations of those commands have different extensions. Using those extensions will break your script in unexpected ways when running on a different system that has a different set or version of Coreutils installed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on &lt;code&gt;awk&lt;&#x2F;code&gt;:&lt;&#x2F;b&gt; &lt;code&gt;awk&lt;&#x2F;code&gt; usually isn&#x27;t part of the coreutils package, but the problems applies. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;invisible-island.net&#x2F;mawk&#x2F;&quot;&gt;mawk&lt;&#x2F;a&gt; for a less well known, but still popular implementation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-my-environment&quot;&gt;Not my Environment&lt;&#x2F;h3&gt;
&lt;p&gt;When writing scripts it is easy to assume that &lt;code&gt;&#x2F;tmp&lt;&#x2F;code&gt; is where temporary files go, &lt;code&gt;&#x2F;run&#x2F;user&#x2F;$UID&lt;&#x2F;code&gt; houses session files and &lt;code&gt;~&#x2F;.cache&#x2F;&lt;&#x2F;code&gt; is a sensible cache directory … &lt;strong&gt;all of those are wrong&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That is how your systems work, maybe your friends system works like this too, but some people out there use different file system layout for very good reasons (performance, security, etc.).&lt;&#x2F;p&gt;
&lt;p&gt;Those people are very very glad when everything uses standardised environment variables like &lt;code&gt;TMPDIR&lt;&#x2F;code&gt;, &lt;code&gt;XDG_RUNTIME_DIR&lt;&#x2F;code&gt; and &lt;code&gt;XDG_CACHE_HOME&lt;&#x2F;code&gt;. (And you might become such a someone faster than you expect!)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-my-program&quot;&gt;Not my Program&lt;&#x2F;h3&gt;
&lt;p&gt;In rare cases programs have different names on different distributions.&lt;&#x2F;p&gt;
&lt;p&gt;This can&#x27;t be easily avoided by some standardised mechanism and is something one should generally be aware of.&lt;&#x2F;p&gt;
&lt;p&gt;One example is &lt;code&gt;readlink -f&lt;&#x2F;code&gt; to canonicalize filenames, except for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.freebsd.org&#x2F;cgi&#x2F;man.cgi?query=readlink&quot;&gt;FreeBSD readlink&lt;&#x2F;a&gt;, where that option sets a formatting template.&lt;&#x2F;p&gt;
&lt;p&gt;Another Example of this is the Tesseract OCR engine CLI-tool which is called &lt;code&gt;tesseract&lt;&#x2F;code&gt;, except on Void Linux where it is called &lt;code&gt;tesseract-ocr&lt;&#x2F;code&gt; because they already had a different program packaged that is called &lt;code&gt;tesseract&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For other programs that aren&#x27;t part of the directories in &lt;code&gt;PATH&lt;&#x2F;code&gt; one might run into this problem sooner.&lt;&#x2F;p&gt;
&lt;p&gt;When implementing something like this: Use sensible defaults, allow for working around any issues and document how the mechanism works.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;not-my-display-server&quot;&gt;Not my Display Server&lt;&#x2F;h3&gt;
&lt;p&gt;Do you run Xorg, Wayland, only a TTY (over SSH) or something else?How many of your tools rely on that specific display protocol being available?&lt;&#x2F;p&gt;
&lt;p&gt;Make sure you know the limits of your tools and implement appropriate mechanisms to switch tools when necessary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;posix-shell&quot;&gt;POSIX Shell&lt;&#x2F;h2&gt;
&lt;p&gt;POSIX is a great thing, it standardises (amongst other things) shell syntax and command line utilities.&lt;&#x2F;p&gt;
&lt;p&gt;If you only use what POSIX defines in a way it is defined by POSIX your shellscripts will work across a wider range of systems without you having to do any extra work.&lt;&#x2F;p&gt;
&lt;p&gt;The official standard document is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;publications.opengroup.org&#x2F;standards&#x2F;unix&#x2F;t101&quot;&gt;Single UNIX® Specification, Version 4, 2018 Edition&lt;&#x2F;a&gt; published by the Open Group, but that is behind a login.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily Wikipedia has a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_POSIX_commands&quot;&gt;List of POSIX commands&lt;&#x2F;a&gt;, where for almost every listed command the first external link on the command specific page is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9699919799&#x2F;&quot;&gt;official POSIX specification in HTML&lt;&#x2F;a&gt; (no login needed).&lt;&#x2F;p&gt;
&lt;p&gt;Starting a shellscript with &lt;code&gt;#!&#x2F;bin&#x2F;sh&lt;&#x2F;code&gt; usually indicates that it is using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9699919799&#x2F;utilities&#x2F;V3_chap02.html&quot;&gt;POSIX compatible shell syntax&lt;&#x2F;a&gt;. In practice this means you just write normal shell code but watch out to avoid some shell-specific features. (See Linters)&lt;&#x2F;p&gt;
&lt;p&gt;POSIX also specifies some &lt;a href=&quot;&#x2F;notebook&#x2F;env&#x2F;#linux-and-posix&quot;&gt;Environment Variables&lt;&#x2F;a&gt; that can be used to find out the right thing to do, like where to put temporary files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xdg-freedesktop-org&quot;&gt;XDG - freedesktop.org&lt;&#x2F;h2&gt;
&lt;p&gt;If you are interacting with user folders or the desktop try to use the &lt;a href=&quot;&#x2F;notebook&#x2F;env&#x2F;#xdg-freedesktop-org&quot;&gt;Freedesktop specified Environment Variables&lt;&#x2F;a&gt;. Also the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitlab.freedesktop.org&#x2F;xdg&#x2F;xdg-utils&#x2F;&quot;&gt;xdg-utils&lt;&#x2F;a&gt;, while not perfect provide ready to use implementations of commonly needed functionality, most prominent opening files.&lt;&#x2F;p&gt;
&lt;p&gt;Also see my blog-posts on the xdg-utils: &lt;a href=&quot;&#x2F;blog&#x2F;xdg-open-under-the-hood&#x2F;&quot;&gt;&quot;It just opens files&quot; - xdg-open under the hood&lt;&#x2F;a&gt; and &lt;a href=&quot;&#x2F;blog&#x2F;xdg-mime&#x2F;&quot;&gt;xdg-mime: Mapping Files to Applications taken apart&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linters&quot;&gt;Linters&lt;&#x2F;h2&gt;
&lt;p&gt;Linters can help you avoid some not very obvious mistakes and compatibility problems.&lt;&#x2F;p&gt;
&lt;p&gt;For shell scripts the go to linter is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;shellcheck.net&quot;&gt;shellcheck&lt;&#x2F;a&gt; (your favourite Linux distribution probably has it packaged).&lt;&#x2F;p&gt;
&lt;p&gt;If you need to lint an &lt;code&gt;awk&lt;&#x2F;code&gt; script&#x2F;command: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;gawk&quot;&gt;&lt;code&gt;gawk&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; has the &lt;code&gt;--lint&lt;&#x2F;code&gt; and &lt;code&gt;--lint-old&lt;&#x2F;code&gt; options (both will run the command) that make gawk tell you when it stumbles across something you might want to avoid happening. The &lt;code&gt;--lint-old&lt;&#x2F;code&gt; option is also great for catching constructs that only work in &lt;code&gt;gawk&lt;&#x2F;code&gt; but not other implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;declare-your-dependencies&quot;&gt;Declare your Dependencies&lt;&#x2F;h2&gt;
&lt;p&gt;When using non-POSIX tools, try to document what you are using and why.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ATmega328P and the Arduino UNO R3</title>
        <published>2024-03-31T00:00:00+00:00</published>
        <updated>2024-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/atmega328p/"/>
        <id>https://slatecave.net/notebook/atmega328p/</id>
        
        <summary type="text">Pinout of the ATmega328P and how it maps to the Arduino UNO R3.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/atmega328p/">&lt;p&gt;Pinout of the ATmega328P and how it maps to the Arduino UNO R3.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; According to the Datasheet most of this Information also applies to the ATmega328, ATmega168(P)A, ATmega88(P)A and ATmega48(P)A.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pinout-table&quot;&gt;Pinout Table&lt;&#x2F;h2&gt;
&lt;p&gt;The following Table applies to the 28 Pin DIP Packaged ATmega328. The Arduino Pin mapping is based on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.arduino.cc&#x2F;hardware&#x2F;uno-rev3&#x2F;&quot;&gt;Arduino UNO R3&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Pin&lt;&#x2F;th&gt;
		&lt;th&gt;Name&lt;&#x2F;th&gt;
		&lt;th&gt;Ardu&amp;shy;ino Pin&lt;&#x2F;th&gt;
		&lt;th&gt;PWM&lt;&#x2F;th&gt;
		&lt;th&gt;PC&amp;shy;INT&lt;&#x2F;th&gt;
		&lt;th&gt;Bus&lt;&#x2F;th&gt;
		&lt;th&gt;Extra&lt;&#x2F;th&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;1&lt;&#x2F;td&gt;
		&lt;td&gt;PC6&lt;&#x2F;td&gt;
		&lt;td&gt;Reset&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;14&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;Reset&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;2&lt;&#x2F;td&gt;
		&lt;td&gt;PD0&lt;&#x2F;td&gt;
		&lt;td&gt;0&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;16&lt;&#x2F;td&gt;
		&lt;td&gt;Serial RX&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;3&lt;&#x2F;td&gt;
		&lt;td&gt;PD1&lt;&#x2F;td&gt;
		&lt;td&gt;1&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;17&lt;&#x2F;td&gt;
		&lt;td&gt;Serial TX&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;4&lt;&#x2F;td&gt;
		&lt;td&gt;PD2&lt;&#x2F;td&gt;
		&lt;td&gt;2&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;18&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;Ext. Interrupt 0&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;5&lt;&#x2F;td&gt;
		&lt;td&gt;PD3&lt;&#x2F;td&gt;
		&lt;td&gt;3&lt;&#x2F;td&gt;
		&lt;td&gt;OC2B&lt;&#x2F;td&gt;
		&lt;td&gt;19&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;Ext. Interrupt 1&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;6&lt;&#x2F;td&gt;
		&lt;td&gt;PD4&lt;&#x2F;td&gt;
		&lt;td&gt;4&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;20&lt;&#x2F;td&gt;
		&lt;td&gt;Serial XCK&lt;&#x2F;td&gt;
		&lt;td&gt;Timer 0&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;7&lt;&#x2F;td&gt;
		&lt;td&gt;VCC&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;8&lt;&#x2F;td&gt;
		&lt;td&gt;GND&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;9&lt;&#x2F;td&gt;
		&lt;td&gt;PB6&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;6&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;XTAL1, TOSC1&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;10&lt;&#x2F;td&gt;
		&lt;td&gt;PB7&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;7&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;XTAL2, TOSC2&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;11&lt;&#x2F;td&gt;
		&lt;td&gt;PD5&lt;&#x2F;td&gt;
		&lt;td&gt;5&lt;&#x2F;td&gt;
		&lt;td&gt;OC0B&lt;&#x2F;td&gt;
		&lt;td&gt;21&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;Timer 1&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;12&lt;&#x2F;td&gt;
		&lt;td&gt;PD6&lt;&#x2F;td&gt;
		&lt;td&gt;6&lt;&#x2F;td&gt;
		&lt;td&gt;OC0A&lt;&#x2F;td&gt;
		&lt;td&gt;22&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;AIN0&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;13&lt;&#x2F;td&gt;
		&lt;td&gt;PD7&lt;&#x2F;td&gt;
		&lt;td&gt;7&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;23&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;AIN1&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;14&lt;&#x2F;td&gt;
		&lt;td&gt;PB0&lt;&#x2F;td&gt;
		&lt;td&gt;8&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;0&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;CLKO, ICP1&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;15&lt;&#x2F;td&gt;
		&lt;td&gt;PB1&lt;&#x2F;td&gt;
		&lt;td&gt;9&lt;&#x2F;td&gt;
		&lt;td&gt;OC1A&lt;&#x2F;td&gt;
		&lt;td&gt;1&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;16&lt;&#x2F;td&gt;
		&lt;td&gt;PB2&lt;&#x2F;td&gt;
		&lt;td&gt;10&lt;&#x2F;td&gt;
		&lt;td&gt;OC1B&lt;&#x2F;td&gt;
		&lt;td&gt;2&lt;&#x2F;td&gt;
		&lt;td&gt;SPI SS&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;17&lt;&#x2F;td&gt;
		&lt;td&gt;PB3&lt;&#x2F;td&gt;
		&lt;td&gt;11&lt;&#x2F;td&gt;
		&lt;td&gt;OC2A&lt;&#x2F;td&gt;
		&lt;td&gt;3&lt;&#x2F;td&gt;
		&lt;td&gt;SPI MOSI&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;18&lt;&#x2F;td&gt;
		&lt;td&gt;PB4&lt;&#x2F;td&gt;
		&lt;td&gt;12&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;4&lt;&#x2F;td&gt;
		&lt;td&gt;SPI MISO&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;19&lt;&#x2F;td&gt;
		&lt;td&gt;PB5&lt;&#x2F;td&gt;
		&lt;td&gt;13&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;5&lt;&#x2F;td&gt;
		&lt;td&gt;SPI SCK&lt;&#x2F;td&gt;
		&lt;td&gt;Builtin LED (Arduino)&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;20&lt;&#x2F;td&gt;
		&lt;td&gt;AVCC&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;Analog VCC&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;21&lt;&#x2F;td&gt;
		&lt;td&gt;AREF&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;Analog Reference&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;22&lt;&#x2F;td&gt;
		&lt;td&gt;GND&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;23&lt;&#x2F;td&gt;
		&lt;td&gt;PC0&lt;&#x2F;td&gt;
		&lt;td&gt;14 (A0)&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;8&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;ADC0&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;24&lt;&#x2F;td&gt;
		&lt;td&gt;PC1&lt;&#x2F;td&gt;
		&lt;td&gt;15 (A1)&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;9&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;ADC1&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;25&lt;&#x2F;td&gt;
		&lt;td&gt;PC2&lt;&#x2F;td&gt;
		&lt;td&gt;16 (A2)&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;10&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;ADC2&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;26&lt;&#x2F;td&gt;
		&lt;td&gt;PC3&lt;&#x2F;td&gt;
		&lt;td&gt;17 (A3)&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;11&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;ADC3&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;27&lt;&#x2F;td&gt;
		&lt;td&gt;PC4&lt;&#x2F;td&gt;
		&lt;td&gt;18 (A4)&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;12&lt;&#x2F;td&gt;
		&lt;td&gt;I²C SDA&lt;&#x2F;td&gt;
		&lt;td&gt;ADC4&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

	&lt;tr&gt;
		&lt;td&gt;28&lt;&#x2F;td&gt;
		&lt;td&gt;PC5&lt;&#x2F;td&gt;
		&lt;td&gt;19 (A5)&lt;&#x2F;td&gt;
		&lt;td&gt;&lt;&#x2F;td&gt;
		&lt;td&gt;13&lt;&#x2F;td&gt;
		&lt;td&gt;I²C SCL&lt;&#x2F;td&gt;
		&lt;td&gt;ADC5&lt;&#x2F;td&gt;
	&lt;&#x2F;tr&gt;

&lt;&#x2F;table&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		Pin
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Physical Pin on the ATmega328P DIP Package.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Name
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The Pin name in the ATmega328 Datasheet.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Arduino Pin
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The Pin number&#x2F;name assigned by Arduino.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		PWM
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Which oscillator the Pin is connected to. If it is connected to one it supports PWM.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		PCINT
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The Pin Change Interrupt number assigned to the pin.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Bus
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Bus protocol Hardware the pin is connected to.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Extra
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Any extra features the Pin might have or a short explanation.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;&lt;b&gt;Note on SPI Nomenclature:&lt;&#x2F;b&gt; Instead of the old &quot;Master&quot; and &quot;Slave&quot; terminology on SPI you can use &lt;i&gt;Main&lt;&#x2F;i&gt; and &lt;i&gt;Secondary&lt;&#x2F;i&gt; while keeping all the old Acronyms. 😉&lt;&#x2F;p&gt;
&lt;h2 id=&quot;barebones-arduino-uno-r3-compatible&quot;&gt;Barebones Arduino UNO R3 compatible&lt;&#x2F;h2&gt;
&lt;p&gt;Maybe you&#x27;ve built something awesome and now you want to get it off that bulky Arduino board and for some reason the individual parts are cheaper than a tiny Arduino compatible board (they used to be, guess who has a stash of ATmega328P chips).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;needed-parts&quot;&gt;Needed Parts&lt;&#x2F;h3&gt;
&lt;p&gt;To build a barebones Arduino UNO R3 compatible you need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;One ATmega328P&lt;&#x2F;li&gt;
&lt;li&gt;Something to flash the Arduino bootloader&lt;&#x2F;li&gt;
&lt;li&gt;Power circuit:
&lt;ul&gt;
&lt;li&gt;A stable 5V Power supply (I.e. from USB)&lt;&#x2F;li&gt;
&lt;li&gt;Two optional 100nF Capacitors&lt;&#x2F;li&gt;
&lt;li&gt;One optional 10μH Inductor&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Clock Circuit:
&lt;ul&gt;
&lt;li&gt;One 16MHz Crystal&lt;&#x2F;li&gt;
&lt;li&gt;Two 22pf Capacitors&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Reset Circuit
&lt;ul&gt;
&lt;li&gt;One button (open by default)&lt;&#x2F;li&gt;
&lt;li&gt;One 10KΩ (roughly) Resistor&lt;&#x2F;li&gt;
&lt;li&gt;One optional 100nF Capacitor&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;building-the-circuit&quot;&gt;Building the circuit&lt;&#x2F;h3&gt;

	



	


&lt;figure&gt;


&lt;svg original-width=&quot;125mm&quot; original-height=&quot;100mm&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 125 100&quot; xmlns=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg&quot; xmlns:cc=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#&quot; xmlns:dc=&quot;http:&#x2F;&#x2F;purl.org&#x2F;dc&#x2F;elements&#x2F;1.1&#x2F;&quot; xmlns:rdf=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;1999&#x2F;02&#x2F;22-rdf-syntax-ns#&quot;&gt;
	&lt;title&gt;Schematic: Barebones ATmega328P Circuit&lt;&#x2F;title&gt;
	&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot;&gt;
		&lt;path d=&quot;m60 20v75h40v-75h-15a5 5 0 0 1-5 5 5 5 0 0 1-5-5z&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
		&lt;path d=&quot;m35 10-5-5-5 5z&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
		&lt;path d=&quot;m120 10-5-5-5 5z&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;g transform=&quot;translate(1.22e-6 -30)&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&gt;
		&lt;path d=&quot;m20 120h10&quot;&#x2F;&gt;
		&lt;path d=&quot;m22 122h6&quot;&#x2F;&gt;
		&lt;path d=&quot;m24 124h2&quot;&#x2F;&gt;
		&lt;path d=&quot;m25 120v-5&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;g transform=&quot;translate(85 -30)&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&gt;
		&lt;path d=&quot;m20 120h10&quot;&#x2F;&gt;
		&lt;path d=&quot;m22 122h6&quot;&#x2F;&gt;
		&lt;path d=&quot;m24 124h2&quot;&#x2F;&gt;
		&lt;path d=&quot;m25 120v-5&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;g fill=&quot;currentColor&quot; stroke-width=&quot;.265&quot;&gt;
		&lt;path d=&quot;m61.3 56.5h0.369l1.3-2.58v-0.33h-1.86v0.312h1.5v0.0227zm3.49-2.91h-0.369l1.07 2.91h0.364l1.07-2.91h-0.369l-0.864 2.45h-0.0341zm4.79 0.909c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49s0.54 1.49 1.28 1.49c0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16s0.415-1.16 0.943-1.16c0.386 0 0.733 0.216 0.818 0.619zm2.91 0c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49s0.54 1.49 1.28 1.49c0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16s0.415-1.16 0.943-1.16c0.386 0 0.733 0.216 0.818 0.619z&quot; removed-label=&quot;7 VCC&quot;&#x2F;&gt;
		&lt;path d=&quot;m62.1 61.6c0.581 0 0.986-0.339 0.989-0.812-0.0028-0.368-0.249-0.68-0.562-0.739v-0.017c0.273-0.071 0.452-0.338 0.455-0.648-0.0028-0.443-0.375-0.773-0.881-0.773-0.511 0-0.884 0.33-0.881 0.773-0.0028 0.31 0.176 0.577 0.455 0.648v0.017c-0.32 0.0582-0.565 0.371-0.562 0.739-0.0028 0.473 0.402 0.812 0.989 0.812zm0-0.312c-0.399 0-0.645-0.205-0.642-0.517-0.0028-0.328 0.268-0.562 0.642-0.562 0.368 0 0.639 0.234 0.642 0.562-0.0028 0.312-0.249 0.517-0.642 0.517zm0-1.38c-0.318 0-0.543-0.199-0.54-0.5-0.0028-0.295 0.213-0.489 0.54-0.489 0.321 0 0.537 0.193 0.54 0.489-0.0028 0.301-0.227 0.5-0.54 0.5zm4.7-0.347h0.364c-0.108-0.562-0.58-0.949-1.19-0.949-0.746 0-1.27 0.574-1.27 1.49 0 0.92 0.523 1.49 1.3 1.49 0.693 0 1.19-0.462 1.19-1.18v-0.312h-1.11v0.312h0.767c-0.0099 0.523-0.354 0.852-0.847 0.852-0.54 0-0.955-0.409-0.955-1.16s0.415-1.16 0.932-1.16c0.42 0 0.706 0.237 0.83 0.619zm3.29-0.909h-0.347v2.29h-0.0284l-1.59-2.29h-0.341v2.91h0.352v-2.28h0.0284l1.59 2.28h0.341zm1.6 2.91c0.886 0 1.39-0.551 1.39-1.46 0-0.903-0.5-1.45-1.35-1.45h-0.938v2.91zm-0.545-0.312v-2.28h0.562c0.682 0 1.03 0.432 1.03 1.14 0 0.71-0.347 1.15-1.07 1.15z&quot; removed-label=&quot;8 GND&quot;&#x2F;&gt;
		&lt;path d=&quot;m62.2 23.6h-0.352l-0.727 0.483v0.358l0.71-0.472h0.017v2.54h0.352zm2.01 2.91h0.352v-1.14h0.636c0.0256 0 0.0497 0 0.0739-0.0014l0.614 1.14h0.409l-0.658-1.2c0.371-0.126 0.544-0.429 0.544-0.815 0-0.514-0.307-0.892-0.989-0.892h-0.983zm0.352-1.45v-1.14h0.619c0.472 0 0.653 0.23 0.653 0.58 0 0.349-0.182 0.562-0.648 0.562zm3.05 1.5c0.443 0 0.767-0.222 0.869-0.551l-0.324-0.0909c-0.0852 0.227-0.283 0.341-0.545 0.341-0.393 0-0.665-0.254-0.68-0.722h1.58v-0.142c0-0.812-0.483-1.09-0.938-1.09-0.591 0-0.983 0.466-0.983 1.14 0 0.67 0.386 1.12 1.02 1.12zm-0.68-1.31c0.0227-0.339 0.263-0.642 0.646-0.642 0.364 0 0.597 0.273 0.597 0.642zm3.64-0.426c-0.105-0.31-0.341-0.517-0.773-0.517-0.46 0-0.801 0.261-0.801 0.631 0 0.301 0.179 0.503 0.58 0.597l0.364 0.0852c0.22 0.0511 0.324 0.156 0.324 0.307 0 0.188-0.199 0.341-0.511 0.341-0.274 0-0.446-0.118-0.506-0.352l-0.318 0.0796c0.0781 0.371 0.384 0.568 0.83 0.568 0.507 0 0.852-0.277 0.852-0.653 0-0.304-0.19-0.496-0.58-0.591l-0.324-0.0795c-0.259-0.0639-0.375-0.151-0.375-0.318 0-0.188 0.199-0.324 0.466-0.324 0.293 0 0.413 0.162 0.472 0.312zm1.46 1.74c0.443 0 0.767-0.222 0.869-0.551l-0.324-0.0909c-0.0852 0.227-0.283 0.341-0.545 0.341-0.393 0-0.665-0.254-0.68-0.722h1.58v-0.142c0-0.812-0.483-1.09-0.938-1.09-0.591 0-0.983 0.466-0.983 1.14 0 0.67 0.386 1.12 1.02 1.12zm-0.68-1.31c0.0227-0.339 0.263-0.642 0.646-0.642 0.364 0 0.597 0.273 0.597 0.642zm3.04-0.915h-0.466v-0.523h-0.335v0.523h-0.33v0.284h0.33v1.36c0 0.381 0.307 0.562 0.591 0.562 0.125 0 0.205-0.0227 0.25-0.0398l-0.0682-0.301c-0.0284 0.0057-0.0739 0.017-0.148 0.017-0.148 0-0.29-0.0454-0.29-0.33v-1.27h0.466z&quot; removed-label=&quot;1 Reset&quot;&#x2F;&gt;
		&lt;path d=&quot;m62 63.6c-0.591-0.0071-0.972 0.438-0.972 0.972 0 0.562 0.415 0.966 0.915 0.966 0.301 0 0.557-0.148 0.716-0.386h0.0227c0 0.716-0.278 1.12-0.727 1.12-0.307 0-0.494-0.193-0.557-0.46h-0.347c0.0682 0.46 0.415 0.773 0.903 0.773 0.653 0 1.06-0.58 1.06-1.61 0-1.07-0.534-1.37-1.01-1.38zm0 0.312c0.364 0 0.631 0.312 0.631 0.653 0 0.347-0.284 0.659-0.642 0.659-0.358 0-0.619-0.29-0.619-0.653 0-0.364 0.273-0.659 0.631-0.659zm2.91-0.273h-0.415l0.938 1.45-0.938 1.45h0.415l0.75-1.19h0.0227l0.75 1.19h0.415l-0.915-1.45 0.915-1.45h-0.415l-0.75 1.21h-0.0227zm2.24 0.312h0.915v2.6h0.352v-2.6h0.915v-0.312h-2.18zm2.51 2.6 0.293-0.824h1.18l0.293 0.824h0.369l-1.07-2.91h-0.364l-1.07 2.91zm0.403-1.14 0.466-1.31h0.0227l0.466 1.31zm2.18 1.14h1.7v-0.312h-1.35v-2.6h-0.352zm3.04-2.91h-0.352l-0.727 0.483v0.358l0.71-0.472h0.017v2.54h0.352z&quot; removed-label=&quot;9 XTAL1&quot;&#x2F;&gt;
		&lt;path d=&quot;m62.2 68.6h-0.352l-0.727 0.483v0.358l0.71-0.472h0.017v2.54h0.352zm1.78 2.95c0.642 0 1.01-0.544 1.01-1.49 0-0.943-0.375-1.49-1.01-1.49-0.636 0-1.01 0.551-1.01 1.49 0 0.95 0.369 1.49 1.01 1.49zm0-0.312c-0.423 0-0.67-0.425-0.67-1.18 0-0.756 0.25-1.19 0.67-1.19 0.42 0 0.67 0.432 0.67 1.19 0 0.757-0.247 1.18-0.67 1.18zm2.9-2.64h-0.415l0.938 1.45-0.938 1.45h0.415l0.75-1.19h0.0227l0.75 1.19h0.415l-0.915-1.45 0.915-1.45h-0.415l-0.75 1.21h-0.0227zm2.24 0.312h0.915v2.6h0.352v-2.6h0.915v-0.312h-2.18zm2.51 2.6 0.293-0.824h1.18l0.293 0.824h0.369l-1.07-2.91h-0.364l-1.07 2.91zm0.403-1.14 0.466-1.31h0.0227l0.466 1.31zm2.18 1.14h1.7v-0.312h-1.35v-2.6h-0.352zm2.2 0h1.84v-0.312h-1.35v-0.0227l0.653-0.699c0.5-0.536 0.648-0.786 0.648-1.11 0-0.449-0.364-0.807-0.875-0.807-0.51 0-0.898 0.347-0.898 0.858h0.335c0-0.331 0.214-0.551 0.551-0.551 0.315 0 0.557 0.193 0.557 0.5 0 0.268-0.158 0.467-0.494 0.835l-0.96 1.05z&quot; removed-label=&quot;10 XTAL2&quot;&#x2F;&gt;
		&lt;path d=&quot;m82.8 66.5 0.293-0.824h1.18l0.293 0.824h0.369l-1.07-2.91h-0.364l-1.07 2.91zm0.403-1.14 0.466-1.31h0.0227l0.466 1.31zm2.03-1.77h-0.369l1.07 2.91h0.364l1.07-2.91h-0.369l-0.864 2.45h-0.0341zm4.79 0.909c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49s0.54 1.49 1.28 1.49c0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16s0.415-1.16 0.943-1.16c0.386 0 0.733 0.216 0.818 0.619zm2.91 0c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49s0.54 1.49 1.28 1.49c0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16s0.415-1.16 0.943-1.16c0.386 0 0.733 0.216 0.818 0.619zm1.64 2h1.84v-0.312h-1.35v-0.0227l0.653-0.699c0.5-0.536 0.648-0.786 0.648-1.11 0-0.449-0.364-0.807-0.875-0.807-0.51 0-0.898 0.347-0.898 0.858h0.335c0-0.331 0.214-0.551 0.551-0.551 0.315 0 0.557 0.193 0.557 0.5 0 0.268-0.158 0.467-0.494 0.835l-0.96 1.05zm3.37 0.0398c0.642 0 1.01-0.544 1.01-1.49 0-0.943-0.375-1.49-1.01-1.49s-1.01 0.551-1.01 1.49c0 0.95 0.369 1.49 1.01 1.49zm0-0.312c-0.423 0-0.67-0.425-0.67-1.18 0-0.756 0.25-1.19 0.67-1.19 0.42 0 0.67 0.432 0.67 1.19 0 0.757-0.247 1.18-0.67 1.18z&quot; removed-label=&quot;AVCC 20&quot;&#x2F;&gt;
		&lt;path d=&quot;m84.5 61.5 0.293-0.824h1.18l0.293 0.824h0.369l-1.07-2.91h-0.364l-1.07 2.91zm0.403-1.14 0.466-1.31h0.0227l0.466 1.31zm2.18 1.14h0.352v-1.14h0.636c0.0256 0 0.0497 0 0.0739-0.0014l0.614 1.14h0.409l-0.658-1.2c0.371-0.126 0.544-0.429 0.544-0.815 0-0.514-0.307-0.892-0.989-0.892h-0.983zm0.352-1.45v-1.14h0.619c0.472 0 0.653 0.23 0.653 0.58 0 0.349-0.182 0.562-0.648 0.562zm2.2 1.45h1.78v-0.312h-1.43v-0.989h1.31v-0.312h-1.31v-0.983h1.4v-0.312h-1.76zm2.39 0h0.352v-1.3h1.26v-0.312h-1.26v-0.983h1.39v-0.312h-1.74zm3.42 0h1.84v-0.312h-1.35v-0.0227l0.653-0.699c0.5-0.536 0.648-0.786 0.648-1.11 0-0.449-0.364-0.807-0.875-0.807-0.51 0-0.898 0.347-0.898 0.858h0.335c0-0.331 0.214-0.551 0.551-0.551 0.315 0 0.557 0.193 0.557 0.5 0 0.268-0.158 0.467-0.494 0.835l-0.96 1.05zm3.44-2.91h-0.352l-0.727 0.483v0.358l0.71-0.472h0.017v2.54h0.352z&quot; removed-label=&quot;AREF 21&quot;&#x2F;&gt;
		&lt;path d=&quot;m86.7 54.5h0.364c-0.108-0.562-0.58-0.949-1.19-0.949-0.746 0-1.27 0.574-1.27 1.49 0 0.92 0.523 1.49 1.3 1.49 0.693 0 1.19-0.462 1.19-1.18v-0.312h-1.11v0.312h0.767c-0.0099 0.523-0.354 0.852-0.847 0.852-0.54 0-0.955-0.409-0.955-1.16s0.415-1.16 0.932-1.16c0.42 0 0.706 0.237 0.83 0.619zm3.29-0.909h-0.347v2.29h-0.0284l-1.59-2.29h-0.341v2.91h0.352v-2.28h0.0284l1.59 2.28h0.341zm1.6 2.91c0.886 0 1.39-0.551 1.39-1.46 0-0.903-0.5-1.45-1.35-1.45h-0.938v2.91zm-0.545-0.312v-2.28h0.562c0.682 0 1.03 0.432 1.03 1.14 0 0.71-0.347 1.15-1.07 1.15zm3.6 0.312h1.84v-0.312h-1.35v-0.0227l0.653-0.699c0.5-0.536 0.648-0.786 0.648-1.11 0-0.449-0.364-0.807-0.875-0.807-0.51 0-0.898 0.347-0.898 0.858h0.335c0-0.331 0.214-0.551 0.551-0.551 0.315 0 0.557 0.193 0.557 0.5 0 0.268-0.158 0.467-0.494 0.835l-0.96 1.05zm2.42 0h1.84v-0.312h-1.35v-0.0227l0.653-0.699c0.5-0.536 0.648-0.786 0.648-1.11 0-0.449-0.364-0.807-0.875-0.807-0.51 0-0.898 0.347-0.898 0.858h0.335c0-0.331 0.214-0.551 0.551-0.551 0.315 0 0.557 0.193 0.557 0.5 0 0.268-0.158 0.467-0.494 0.835l-0.96 1.05z&quot; removed-label=&quot;GND 22&quot;&#x2F;&gt;
		&lt;path d=&quot;m61.1 31.5h1.84v-0.312h-1.35v-0.0227l0.653-0.699c0.5-0.536 0.648-0.786 0.648-1.11 0-0.449-0.364-0.807-0.875-0.807-0.51 0-0.898 0.347-0.898 0.858h0.335c0-0.331 0.214-0.551 0.551-0.551 0.315 0 0.557 0.193 0.557 0.5 0 0.268-0.158 0.467-0.494 0.835l-0.96 1.05zm3.6 0h0.352v-1.14h0.636c0.0256 0 0.0497 0 0.0739-0.0014l0.614 1.14h0.409l-0.658-1.2c0.371-0.126 0.544-0.429 0.544-0.815 0-0.514-0.307-0.892-0.989-0.892h-0.983zm0.352-1.45v-1.14h0.619c0.472 0 0.653 0.23 0.653 0.58 0 0.349-0.182 0.562-0.648 0.562zm2.37-1.45h-0.415l0.938 1.45-0.938 1.45h0.415l0.75-1.19h0.0227l0.75 1.19h0.415l-0.915-1.45 0.915-1.45h-0.415l-0.75 1.21h-0.0227z&quot; removed-label=&quot;2 RX&quot;&#x2F;&gt;
		&lt;path d=&quot;m62.1 36.6c0.564 0 0.983-0.354 0.983-0.83 0-0.369-0.219-0.638-0.585-0.699v-0.0227c0.294-0.0895 0.477-0.331 0.477-0.659 0-0.412-0.325-0.778-0.864-0.778-0.503 0-0.92 0.31-0.938 0.767h0.341c0.0128-0.29 0.288-0.46 0.591-0.46 0.321 0 0.528 0.195 0.528 0.489 0 0.307-0.24 0.506-0.585 0.506h-0.233v0.312h0.233c0.442 0 0.688 0.224 0.688 0.545 0 0.308-0.268 0.517-0.642 0.517-0.337 0-0.604-0.173-0.625-0.455h-0.358c0.0213 0.457 0.425 0.767 0.989 0.767zm2.58-2.64h0.915v2.6h0.352v-2.6h0.915v-0.312h-2.18zm2.9-0.312h-0.415l0.938 1.45-0.938 1.45h0.415l0.75-1.19h0.0227l0.75 1.19h0.415l-0.915-1.45 0.915-1.45h-0.415l-0.75 1.21h-0.0227z&quot; removed-label=&quot;3 TX&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;ellipse cx=&quot;57.3&quot; cy=&quot;25&quot; rx=&quot;2&quot; ry=&quot;2&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
	&lt;path d=&quot;m67.2 46.5 0.31-0.872h1.24l0.31 0.872h0.391l-1.13-3.08h-0.385l-1.13 3.08zm0.427-1.2 0.493-1.39h0.024l0.493 1.39zm1.78-1.55h0.968v2.75h0.373v-2.75h0.968v-0.331h-2.31zm2.6 2.75h0.355v-1.44c0-0.338 0.247-0.577 0.523-0.577 0.269 0 0.457 0.176 0.457 0.439v1.58h0.361v-1.5c0-0.298 0.186-0.517 0.511-0.517 0.253 0 0.469 0.134 0.469 0.475v1.55h0.355v-1.55c0-0.543-0.292-0.794-0.704-0.794-0.331 0-0.573 0.152-0.692 0.391h-0.024c-0.114-0.247-0.316-0.391-0.619-0.391-0.301 0-0.523 0.144-0.619 0.391h-0.0301v-0.361h-0.343zm4.65 0.0481c0.469 0 0.812-0.235 0.92-0.583l-0.343-0.0962c-0.0902 0.241-0.299 0.361-0.577 0.361-0.416 0-0.704-0.269-0.72-0.764h1.68v-0.15c0-0.86-0.511-1.15-0.992-1.15-0.625 0-1.04 0.493-1.04 1.2s0.409 1.18 1.08 1.18zm-0.72-1.39c0.024-0.359 0.278-0.679 0.684-0.679 0.385 0 0.631 0.289 0.631 0.679zm3.15 2.25c0.553 0 0.998-0.253 0.998-0.848v-2.38h-0.343v0.367h-0.0361c-0.0782-0.12-0.222-0.397-0.673-0.397-0.583 0-0.986 0.463-0.986 1.17 0 0.722 0.421 1.13 0.98 1.13 0.451 0 0.595-0.265 0.673-0.391h0.0301v0.469c0 0.385-0.271 0.559-0.643 0.559-0.419 0-0.567-0.221-0.661-0.349l-0.283 0.198c0.144 0.242 0.428 0.463 0.944 0.463zm-0.012-1.27c-0.445 0-0.673-0.337-0.673-0.818 0-0.469 0.222-0.848 0.673-0.848 0.433 0 0.661 0.349 0.661 0.848 0 0.511-0.235 0.818-0.661 0.818zm2.34 0.409c0.403 0 0.613-0.216 0.686-0.367h0.018v0.313h0.355v-1.52c0-0.734-0.559-0.818-0.854-0.818-0.349 0-0.746 0.12-0.926 0.541l0.337 0.12c0.0782-0.168 0.263-0.349 0.601-0.349 0.326 0 0.487 0.173 0.487 0.469v0.012c0 0.171-0.174 0.156-0.595 0.21-0.428 0.0556-0.896 0.15-0.896 0.679 0 0.451 0.349 0.71 0.788 0.71zm0.0541-0.319c-0.283 0-0.487-0.126-0.487-0.373 0-0.271 0.247-0.355 0.523-0.391 0.15-0.018 0.553-0.0601 0.613-0.132v0.325c0 0.289-0.229 0.571-0.649 0.571zm2.69 0.307c0.597 0 1.04-0.374 1.04-0.878 0-0.391-0.232-0.675-0.619-0.74v-0.024c0.311-0.0947 0.505-0.35 0.505-0.698 0-0.436-0.344-0.824-0.914-0.824-0.532 0-0.974 0.328-0.992 0.812h0.361c0.0135-0.307 0.305-0.487 0.625-0.487 0.34 0 0.559 0.206 0.559 0.517 0 0.325-0.254 0.535-0.619 0.535h-0.247v0.331h0.247c0.468 0 0.728 0.238 0.728 0.577 0 0.326-0.284 0.547-0.679 0.547-0.356 0-0.639-0.183-0.661-0.481h-0.379c0.0226 0.484 0.449 0.812 1.05 0.812zm1.65-0.0421h1.94v-0.331h-1.43v-0.024l0.692-0.74c0.529-0.567 0.686-0.831 0.686-1.17 0-0.475-0.385-0.854-0.926-0.854-0.54 0-0.95 0.367-0.95 0.908h0.355c0-0.35 0.227-0.583 0.583-0.583 0.334 0 0.589 0.204 0.589 0.529 0 0.284-0.167 0.495-0.523 0.884l-1.02 1.11zm3.55 0.0421c0.615 0 1.04-0.359 1.05-0.86-3e-3 -0.389-0.263-0.72-0.595-0.782v-0.018c0.289-0.0752 0.478-0.358 0.481-0.686-3e-3 -0.469-0.397-0.818-0.932-0.818-0.541 0-0.935 0.349-0.932 0.818-3e-3 0.328 0.186 0.61 0.481 0.686v0.018c-0.338 0.0616-0.598 0.392-0.595 0.782-3e-3 0.501 0.425 0.86 1.05 0.86zm0-0.331c-0.422 0-0.683-0.216-0.679-0.547-3e-3 -0.347 0.284-0.595 0.679-0.595 0.389 0 0.676 0.248 0.679 0.595-3e-3 0.331-0.263 0.547-0.679 0.547zm0-1.46c-0.337 0-0.574-0.21-0.571-0.529-3e-3 -0.313 0.225-0.517 0.571-0.517 0.34 0 0.568 0.204 0.571 0.517-3e-3 0.319-0.241 0.529-0.571 0.529zm1.68 1.75h0.373v-1.12h0.673c0.717 0 1.04-0.436 1.04-0.98 0-0.544-0.323-0.974-1.05-0.974h-1.04zm0.373-1.46v-1.29h0.655c0.501 0 0.692 0.274 0.692 0.643s-0.191 0.649-0.686 0.649z&quot; fill=&quot;currentColor&quot; stroke-width=&quot;.265&quot; removed-label=&quot;ATmega328P&quot;&#x2F;&gt;
	&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&gt;
		&lt;path d=&quot;m60 30h-5&quot;&#x2F;&gt;
		&lt;path d=&quot;m60 35h-5&quot;&#x2F;&gt;
		&lt;path d=&quot;m60 55-5-0.0492&quot;&#x2F;&gt;
		&lt;path d=&quot;m60 60h-5&quot;&#x2F;&gt;
		&lt;path d=&quot;m60 65h-5&quot;&#x2F;&gt;
		&lt;path d=&quot;m60 70h-5&quot;&#x2F;&gt;
		&lt;path d=&quot;m100 55h5&quot;&#x2F;&gt;
		&lt;path d=&quot;m100 59.9 5 0.107&quot;&#x2F;&gt;
		&lt;path d=&quot;m100 65h5&quot;&#x2F;&gt;
		&lt;path d=&quot;m36 71h8v3h-8z&quot;&#x2F;&gt;
		&lt;path d=&quot;m35 70h10&quot;&#x2F;&gt;
		&lt;path d=&quot;m45 75h-10&quot;&#x2F;&gt;
		&lt;path d=&quot;m40 70v-5h15&quot;&#x2F;&gt;
		&lt;path d=&quot;m40 75-1e-6 5h10v-10h5&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;path d=&quot;m41.9 66.9h-0.264l-0.545 0.362v0.268l0.533-0.354h0.0128v1.9h0.264zm1.35 2.21c0.441 0.0053 0.729-0.327 0.729-0.733 0-0.422-0.312-0.724-0.686-0.724-0.225 0-0.418 0.11-0.537 0.29h-0.017c0.0011-0.532 0.208-0.839 0.545-0.839 0.23 0 0.369 0.145 0.418 0.341h0.26c-0.0533-0.339-0.311-0.575-0.678-0.575-0.491 0-0.793 0.435-0.793 1.21 0 0.806 0.401 1.03 0.759 1.04zm0-0.234c-0.274 0-0.474-0.233-0.473-0.494 0.0011-0.261 0.211-0.494 0.482-0.494 0.267 0 0.464 0.219 0.464 0.49 0 0.277-0.206 0.499-0.473 0.499zm1.18-1.98v2.18h0.247v-1.66h0.0213l0.682 1.66h0.239l0.682-1.66h0.0213v1.66h0.247v-2.18h-0.315l-0.741 1.81h-0.0256l-0.741-1.81zm2.67 2.18h0.264v-0.976h1.16v0.976h0.264v-2.18h-0.264v0.972h-1.16v-0.972h-0.264zm2.14 0h1.28v-0.234h-0.933v-0.017l0.903-1.18v-0.2h-1.22v0.234h0.899v0.017l-0.929 1.19z&quot; fill=&quot;currentColor&quot; stroke-width=&quot;.5&quot; removed-label=&quot;16MHz&quot;&#x2F;&gt;
	&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot;&gt;
		&lt;g stroke-width=&quot;.5&quot;&gt;
			&lt;path d=&quot;m40 65h-8&quot;&#x2F;&gt;
			&lt;path d=&quot;m32 62v6&quot;&#x2F;&gt;
			&lt;path d=&quot;m30 62v6&quot;&#x2F;&gt;
			&lt;path d=&quot;m30 77v6&quot;&#x2F;&gt;
			&lt;path d=&quot;m32 77v6&quot;&#x2F;&gt;
			&lt;path d=&quot;m40 80h-8&quot;&#x2F;&gt;
			&lt;path d=&quot;m30 80h-5&quot;&#x2F;&gt;
			&lt;path d=&quot;m30 65h-5&quot;&#x2F;&gt;
			&lt;path d=&quot;m55 60h-30v25&quot;&#x2F;&gt;
			&lt;path d=&quot;m105 55h5v30&quot;&#x2F;&gt;
			&lt;path d=&quot;m105 65h3c6e-5 -1.1 0.896-2 2-2 1.1 6.7e-5 2 0.896 2 2h3v-55&quot;&#x2F;&gt;
			&lt;path d=&quot;m55 55-25 1e-6v-45&quot;&#x2F;&gt;
			&lt;path d=&quot;m34 25h-4&quot;&#x2F;&gt;
			&lt;path d=&quot;m46 25 9.25-3e-6&quot;&#x2F;&gt;
		&lt;&#x2F;g&gt;
		&lt;g stroke-width=&quot;.5&quot;&gt;
			&lt;path d=&quot;m13 37c1.1-6.7e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;path d=&quot;m13 32c1.1-6.7e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;path d=&quot;m13 27c1.1-6.7e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;path d=&quot;m13 22c1.1-6.7e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
		&lt;&#x2F;g&gt;
		&lt;g stroke-width=&quot;.5&quot;&gt;
			&lt;path d=&quot;m50 60.1 1.6e-5 -3.12c1.1-6.6e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2v-3&quot;&#x2F;&gt;
			&lt;path d=&quot;m30.1 25-3.12-1.6e-5c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2h-8&quot;&#x2F;&gt;
			&lt;path d=&quot;m55.1 35-3.12-1.6e-5c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2h-16c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2h-1c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2l-8 1.21e-4&quot;&#x2F;&gt;
			&lt;path d=&quot;m55.1 30-3.12-1.6e-5c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2l-16 1.21e-4c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2l-1-6.1e-5c-1.28e-4 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2l-8 1.21e-4&quot;&#x2F;&gt;
		&lt;&#x2F;g&gt;
	&lt;&#x2F;g&gt;
	&lt;g transform=&quot;translate(.5 -29.5)&quot; stroke=&quot;currentColor&quot;&gt;
		&lt;path d=&quot;m47.5 73.5v6&quot; fill=&quot;none&quot; stroke-width=&quot;.463&quot;&#x2F;&gt;
		&lt;g stroke-width=&quot;.5&quot;&gt;
			&lt;path d=&quot;m47.5 76.5h3.25&quot; fill=&quot;none&quot;&#x2F;&gt;
			&lt;ellipse cx=&quot;49.5&quot; cy=&quot;74&quot; rx=&quot;.486&quot; ry=&quot;.5&quot; fill=&quot;currentColor&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;ellipse cx=&quot;49.5&quot; cy=&quot;79&quot; rx=&quot;.5&quot; ry=&quot;.5&quot; fill=&quot;currentColor&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
		&lt;&#x2F;g&gt;
	&lt;&#x2F;g&gt;
	&lt;path d=&quot;m50 25v19&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
	&lt;path d=&quot;m50 40h-18c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2h-1c-6.6e-5 -1.1-0.895-2-2-2-1.1 6.7e-5 -2 0.895-2 2h-3&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
	&lt;path d=&quot;m15.7 45.7h-0.258v-1.5q0-0.129 3e-3 -0.207t9e-3 -0.162q-0.048 0.048-0.087 0.081t-0.099 0.084l-0.228 0.186-0.138-0.177 0.579-0.45h0.219zm2.22-1.07q0 0.345-0.072 0.594-0.072 0.246-0.228 0.378t-0.414 0.132q-0.363 0-0.537-0.291-0.171-0.294-0.171-0.813 0-0.348 0.069-0.594 0.072-0.246 0.228-0.375 0.156-0.132 0.411-0.132 0.36 0 0.537 0.291 0.177 0.288 0.177 0.81zm-1.16 0q0 0.441 0.099 0.66 0.102 0.219 0.345 0.219 0.24 0 0.342-0.216 0.105-0.219 0.105-0.663 0-0.438-0.105-0.657-0.102-0.219-0.342-0.219-0.243 0-0.345 0.219-0.099 0.219-0.099 0.657zm2.87 0q0 0.345-0.072 0.594-0.072 0.246-0.228 0.378t-0.414 0.132q-0.363 0-0.537-0.291-0.171-0.294-0.171-0.813 0-0.348 0.069-0.594 0.072-0.246 0.228-0.375 0.156-0.132 0.411-0.132 0.36 0 0.537 0.291 0.177 0.288 0.177 0.81zm-1.16 0q0 0.441 0.099 0.66 0.102 0.219 0.345 0.219 0.24 0 0.342-0.216 0.105-0.219 0.105-0.663 0-0.438-0.105-0.657-0.102-0.219-0.342-0.219-0.243 0-0.345 0.219-0.099 0.219-0.099 0.657zm2.33-0.564q0.288 0 0.435 0.141 0.147 0.138 0.147 0.45v1.05h-0.261v-1.03q0-0.387-0.36-0.387-0.267 0-0.369 0.15t-0.102 0.432v0.834h-0.264v-1.61h0.213l0.039 0.219h0.015q0.078-0.126 0.216-0.186 0.138-0.063 0.291-0.063zm1.39 1.64h-0.27v-2.14h1.2v0.237h-0.927v0.759h0.87v0.237h-0.87z&quot; fill=&quot;currentColor&quot; stroke-width=&quot;.265&quot; removed-label=&quot;100nF&quot;&#x2F;&gt;
	&lt;path d=&quot;m13 42c1.1-6.7e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
	&lt;g fill=&quot;currentColor&quot; stroke-width=&quot;.265&quot;&gt;
		&lt;path d=&quot;m6.19 14.5h0.364c-0.108-0.562-0.58-0.949-1.19-0.949-0.746 0-1.27 0.574-1.27 1.49 0 0.92 0.523 1.49 1.3 1.49 0.693 0 1.19-0.462 1.19-1.18v-0.312h-1.11v0.312h0.767c-0.00994 0.523-0.354 0.852-0.847 0.852-0.54 0-0.955-0.409-0.955-1.16 0-0.756 0.415-1.16 0.932-1.16 0.42 0 0.706 0.237 0.83 0.619zm3.29-0.909h-0.347v2.29h-0.0284l-1.59-2.29h-0.341v2.91h0.352v-2.28h0.0284l1.59 2.28h0.341zm1.6 2.91c0.886 0 1.39-0.551 1.39-1.46 0-0.903-0.5-1.45-1.35-1.45h-0.938v2.91zm-0.545-0.312v-2.28h0.562c0.682 0 1.03 0.432 1.03 1.14 0 0.71-0.347 1.15-1.07 1.15z&quot; removed-label=&quot;GND&quot;&#x2F;&gt;
		&lt;path d=&quot;m5.96 41.5c0.886 0 1.39-0.551 1.39-1.46 0-0.903-0.5-1.45-1.35-1.45h-0.938v2.91zm-0.545-0.312v-2.28h0.562c0.682 0 1.03 0.432 1.03 1.14 0 0.71-0.347 1.15-1.07 1.15zm2.24-2.28h0.915v2.6h0.352v-2.6h0.915v-0.312h-2.18zm2.73 2.6h0.352v-1.14h0.636c0.0256 0 0.0497 0 0.0739-0.0014l0.614 1.14h0.409l-0.658-1.2c0.371-0.126 0.544-0.429 0.544-0.815 0-0.514-0.307-0.892-0.989-0.892h-0.983zm0.352-1.45v-1.14h0.619c0.472 0 0.653 0.23 0.653 0.58s-0.182 0.562-0.648 0.562z&quot; removed-label=&quot;DTR&quot;&#x2F;&gt;
		&lt;path d=&quot;m7.36 19.4c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49 0 0.92 0.54 1.49 1.28 1.49 0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16 0-0.756 0.415-1.16 0.943-1.16 0.386 0 0.733 0.216 0.818 0.619zm0.409-0.597h0.915v2.6h0.352v-2.6h0.915v-0.312h-2.18zm4.32 0.415h0.341c-0.0156-0.439-0.42-0.767-0.983-0.767-0.557 0-0.994 0.324-0.994 0.812 0 0.392 0.284 0.625 0.739 0.756l0.358 0.102c0.307 0.0852 0.58 0.193 0.58 0.483 0 0.318-0.307 0.528-0.71 0.528-0.347 0-0.653-0.153-0.682-0.483h-0.364c0.0341 0.477 0.42 0.801 1.05 0.801 0.67 0 1.05-0.369 1.05-0.841 0-0.545-0.517-0.722-0.818-0.801l-0.295-0.0796c-0.216-0.0568-0.562-0.17-0.562-0.483 0-0.278 0.256-0.483 0.642-0.483 0.352 0 0.619 0.168 0.653 0.455z&quot; removed-label=&quot;CTS&quot;&#x2F;&gt;
		&lt;path d=&quot;m4.77 23.5h-0.369l1.07 2.91h0.364l1.07-2.91h-0.369l-0.864 2.45h-0.0341zm4.79 0.909c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49 0 0.92 0.54 1.49 1.28 1.49 0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16 0-0.756 0.415-1.16 0.943-1.16 0.386 0 0.733 0.216 0.818 0.619zm2.91 0c-0.108-0.597-0.585-0.949-1.17-0.949-0.744 0-1.28 0.574-1.28 1.49 0 0.92 0.54 1.49 1.28 1.49 0.585 0 1.06-0.352 1.17-0.949h-0.352c-0.0852 0.403-0.432 0.619-0.818 0.619-0.528 0-0.943-0.409-0.943-1.16 0-0.756 0.415-1.16 0.943-1.16 0.386 0 0.733 0.216 0.818 0.619z&quot; removed-label=&quot;VCC&quot;&#x2F;&gt;
		&lt;path d=&quot;m7.64 28.9h0.915v2.6h0.352v-2.6h0.915v-0.312h-2.18zm2.9-0.312h-0.415l0.938 1.45-0.938 1.45h0.415l0.75-1.19h0.0227l0.75 1.19h0.415l-0.915-1.45 0.915-1.45h-0.415l-0.75 1.21h-0.0227z&quot; removed-label=&quot;TX&quot;&#x2F;&gt;
		&lt;path d=&quot;m7.81 36.5h0.352v-1.14h0.636c0.0256 0 0.0497 0 0.0739-0.0014l0.614 1.14h0.409l-0.658-1.2c0.371-0.126 0.544-0.429 0.544-0.815 0-0.514-0.307-0.892-0.989-0.892h-0.983zm0.352-1.45v-1.14h0.619c0.472 0 0.653 0.23 0.653 0.58 0 0.349-0.182 0.562-0.648 0.562zm2.37-1.45h-0.415l0.938 1.45-0.938 1.45h0.415l0.75-1.19h0.0227l0.75 1.19h0.415l-0.915-1.45 0.915-1.45h-0.415l-0.75 1.21h-0.0227z&quot; removed-label=&quot;RX&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;g transform=&quot;translate(-25 -25)&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&gt;
		&lt;path d=&quot;m45 62v6&quot;&#x2F;&gt;
		&lt;path d=&quot;m43 62v6&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;path d=&quot;m18 40-3 2e-6&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
	&lt;path d=&quot;m34 23 12 2e-6v4l-12-2e-6z&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
	&lt;g fill=&quot;currentColor&quot;&gt;
		&lt;g stroke-width=&quot;.265&quot;&gt;
			&lt;path d=&quot;m37.2 26.1h-0.258v-1.5q0-0.129 3e-3 -0.207t9e-3 -0.162q-0.048 0.048-0.087 0.081t-0.099 0.084l-0.228 0.186-0.138-0.177 0.579-0.45h0.219zm2.22-1.07q0 0.345-0.072 0.594-0.072 0.246-0.228 0.378t-0.414 0.132q-0.363 0-0.537-0.291-0.171-0.294-0.171-0.813 0-0.348 0.069-0.594 0.072-0.246 0.228-0.375 0.156-0.132 0.411-0.132 0.36 0 0.537 0.291 0.177 0.288 0.177 0.81zm-1.16 0q0 0.441 0.099 0.66 0.102 0.219 0.345 0.219 0.24 0 0.342-0.216 0.105-0.219 0.105-0.663 0-0.438-0.105-0.657-0.102-0.219-0.342-0.219-0.243 0-0.345 0.219-0.099 0.219-0.099 0.657zm3.16 1.07h-0.318l-0.759-1.02-0.219 0.192v0.831h-0.27v-2.14h0.27v1.06q0.09-0.102 0.183-0.204t0.186-0.204l0.579-0.648h0.315l-0.849 0.933zm0.075 0v-0.237h0.474q-0.111-0.084-0.216-0.21-0.105-0.129-0.174-0.306-0.066-0.177-0.066-0.399 0-0.294 0.114-0.525t0.333-0.363q0.219-0.135 0.534-0.135 0.318 0 0.537 0.132t0.333 0.363 0.114 0.525q0 0.225-0.066 0.402t-0.171 0.306q-0.102 0.126-0.216 0.21h0.471v0.237h-0.804v-0.216q0.186-0.132 0.297-0.27t0.159-0.297q0.048-0.162 0.048-0.36 0-0.228-0.075-0.408t-0.231-0.282q-0.153-0.105-0.396-0.105-0.24 0-0.396 0.105-0.153 0.102-0.228 0.282-0.072 0.18-0.072 0.408 0 0.198 0.048 0.36 0.048 0.159 0.156 0.297 0.111 0.135 0.297 0.27v0.216z&quot; removed-label=&quot;10KΩ&quot;&#x2F;&gt;
			&lt;path d=&quot;m34.1 64.3h-1.42v-0.219l0.561-0.567q0.162-0.162 0.273-0.288t0.168-0.246q0.057-0.123 0.057-0.267 0-0.177-0.105-0.267-0.105-0.093-0.273-0.093-0.156 0-0.276 0.054-0.117 0.054-0.24 0.15l-0.141-0.177q0.126-0.105 0.288-0.177 0.165-0.075 0.369-0.075 0.3 0 0.474 0.153 0.174 0.15 0.174 0.417 0 0.168-0.069 0.315t-0.192 0.291q-0.123 0.141-0.288 0.303l-0.447 0.441v0.012h1.08zm1.72 0h-1.42v-0.219l0.561-0.567q0.162-0.162 0.273-0.288t0.168-0.246q0.057-0.123 0.057-0.267 0-0.177-0.105-0.267-0.105-0.093-0.273-0.093-0.156 0-0.276 0.054-0.117 0.054-0.24 0.15l-0.141-0.177q0.126-0.105 0.288-0.177 0.165-0.075 0.369-0.075 0.3 0 0.474 0.153 0.174 0.15 0.174 0.417 0 0.168-0.069 0.315t-0.192 0.291q-0.123 0.141-0.288 0.303l-0.447 0.441v0.012h1.08zm1.18-1.64q0.297 0 0.477 0.207 0.183 0.207 0.183 0.624 0 0.411-0.183 0.624-0.18 0.213-0.48 0.213-0.186 0-0.309-0.069-0.12-0.072-0.189-0.165h-0.018q6e-3 0.051 0.012 0.129t6e-3 0.135v0.66h-0.264v-2.33h0.216l0.036 0.219h0.012q0.072-0.105 0.189-0.177t0.312-0.072zm-0.048 0.222q-0.246 0-0.348 0.138-0.099 0.138-0.105 0.42v0.051q0 0.297 0.096 0.459 0.099 0.159 0.363 0.159 0.147 0 0.24-0.081 0.096-0.081 0.141-0.219 0.048-0.141 0.048-0.321 0-0.276-0.108-0.441-0.105-0.165-0.327-0.165zm1.87 0.012h-0.405v1.4h-0.264v-1.4h-0.282v-0.123l0.282-0.09v-0.093q0-0.312 0.138-0.447 0.138-0.138 0.384-0.138 0.096 0 0.174 0.018 0.081 0.015 0.138 0.036l-0.069 0.207q-0.048-0.015-0.111-0.03t-0.129-0.015q-0.132 0-0.198 0.09-0.063 0.087-0.063 0.276v0.105h0.405z&quot; removed-label=&quot;22pf&quot;&#x2F;&gt;
			&lt;path d=&quot;m34.1 83.3h-1.42v-0.219l0.561-0.567q0.162-0.162 0.273-0.288t0.168-0.246q0.057-0.123 0.057-0.267 0-0.177-0.105-0.267-0.105-0.093-0.273-0.093-0.156 0-0.276 0.054-0.117 0.054-0.24 0.15l-0.141-0.177q0.126-0.105 0.288-0.177 0.165-0.075 0.369-0.075 0.3 0 0.474 0.153 0.174 0.15 0.174 0.417 0 0.168-0.069 0.315t-0.192 0.291q-0.123 0.141-0.288 0.303l-0.447 0.441v0.012h1.08zm1.72 0h-1.42v-0.219l0.561-0.567q0.162-0.162 0.273-0.288t0.168-0.246q0.057-0.123 0.057-0.267 0-0.177-0.105-0.267-0.105-0.093-0.273-0.093-0.156 0-0.276 0.054-0.117 0.054-0.24 0.15l-0.141-0.177q0.126-0.105 0.288-0.177 0.165-0.075 0.369-0.075 0.3 0 0.474 0.153 0.174 0.15 0.174 0.417 0 0.168-0.069 0.315t-0.192 0.291q-0.123 0.141-0.288 0.303l-0.447 0.441v0.012h1.08zm1.18-1.64q0.297 0 0.477 0.207 0.183 0.207 0.183 0.624 0 0.411-0.183 0.624-0.18 0.213-0.48 0.213-0.186 0-0.309-0.069-0.12-0.072-0.189-0.165h-0.018q6e-3 0.051 0.012 0.129t6e-3 0.135v0.66h-0.264v-2.33h0.216l0.036 0.219h0.012q0.072-0.105 0.189-0.177t0.312-0.072zm-0.048 0.222q-0.246 0-0.348 0.138-0.099 0.138-0.105 0.42v0.051q0 0.297 0.096 0.459 0.099 0.159 0.363 0.159 0.147 0 0.24-0.081 0.096-0.081 0.141-0.219 0.048-0.141 0.048-0.321 0-0.276-0.108-0.441-0.105-0.165-0.327-0.165zm1.87 0.012h-0.405v1.4h-0.264v-1.4h-0.282v-0.123l0.282-0.09v-0.093q0-0.312 0.138-0.447 0.138-0.138 0.384-0.138 0.096 0 0.174 0.018 0.081 0.015 0.138 0.036l-0.069 0.207q-0.048-0.015-0.111-0.03t-0.129-0.015q-0.132 0-0.198 0.09-0.063 0.087-0.063 0.276v0.105h0.405z&quot; removed-label=&quot;22pf&quot;&#x2F;&gt;
			&lt;g removed-label=&quot;Reset
Button&quot;&gt;
				&lt;path d=&quot;m39.1 46h0.264v-0.852h0.477c0.0192 0 0.0373 0 0.0554-0.0011l0.46 0.853h0.307l-0.493-0.901c0.278-0.0948 0.408-0.322 0.408-0.612 0-0.386-0.23-0.669-0.741-0.669h-0.737zm0.264-1.09v-0.857h0.464c0.354 0 0.49 0.173 0.49 0.435s-0.136 0.422-0.486 0.422zm2.29 1.12c0.332 0 0.575-0.166 0.652-0.413l-0.243-0.0682c-0.0639 0.17-0.212 0.256-0.409 0.256-0.295 0-0.499-0.191-0.51-0.541h1.19v-0.107c0-0.609-0.362-0.818-0.703-0.818-0.443 0-0.737 0.349-0.737 0.852s0.29 0.839 0.763 0.839zm-0.51-0.984c0.017-0.255 0.197-0.482 0.485-0.482 0.273 0 0.447 0.205 0.447 0.482zm2.73-0.32c-0.0788-0.232-0.256-0.388-0.58-0.388-0.345 0-0.601 0.196-0.601 0.473 0 0.226 0.134 0.377 0.435 0.447l0.273 0.0639c0.165 0.0384 0.243 0.117 0.243 0.23 0 0.141-0.149 0.256-0.384 0.256-0.206 0-0.335-0.0884-0.379-0.264l-0.239 0.0597c0.0586 0.278 0.288 0.426 0.622 0.426 0.38 0 0.639-0.208 0.639-0.49 0-0.228-0.143-0.372-0.435-0.443l-0.243-0.0597c-0.194-0.0479-0.281-0.113-0.281-0.239 0-0.141 0.149-0.243 0.349-0.243 0.219 0 0.31 0.121 0.354 0.234zm1.1 1.3c0.332 0 0.575-0.166 0.652-0.413l-0.243-0.0682c-0.0639 0.17-0.212 0.256-0.409 0.256-0.295 0-0.499-0.191-0.51-0.541h1.19v-0.107c0-0.609-0.362-0.818-0.703-0.818-0.443 0-0.737 0.349-0.737 0.852s0.29 0.839 0.763 0.839zm-0.51-0.984c0.017-0.255 0.197-0.482 0.485-0.482 0.273 0 0.447 0.205 0.447 0.482zm2.28-0.686h-0.349v-0.392h-0.251v0.392h-0.247v0.213h0.247v1.02c0 0.286 0.23 0.422 0.443 0.422 0.0938 0 0.153-0.017 0.188-0.0298l-0.0511-0.226c-0.0213 0.0043-0.0554 0.0128-0.111 0.0128-0.111 0-0.217-0.0341-0.217-0.247v-0.955h0.349z&quot;&#x2F;&gt;
				&lt;path d=&quot;m37.8 49.8h0.788c0.516 0 0.729-0.251 0.729-0.58 0-0.345-0.239-0.533-0.439-0.545v-0.0213c0.188-0.0511 0.354-0.175 0.354-0.456 0-0.32-0.213-0.58-0.669-0.58h-0.763zm0.264-0.234v-0.759h0.537c0.286 0 0.464 0.192 0.464 0.413 0 0.192-0.132 0.345-0.477 0.345zm0-0.989v-0.724h0.499c0.29 0 0.418 0.153 0.418 0.345 0 0.23-0.188 0.379-0.426 0.379zm2.68 0.554c0 0.307-0.234 0.447-0.422 0.447-0.209 0-0.358-0.153-0.358-0.392v-1.02h-0.251v1.04c0 0.418 0.222 0.618 0.528 0.618 0.247 0 0.409-0.132 0.486-0.298h0.017v0.277h0.251v-1.64h-0.251zm1.42-0.967h-0.349v-0.392h-0.251v0.392h-0.247v0.213h0.247v1.02c0 0.286 0.23 0.422 0.443 0.422 0.0938 0 0.153-0.017 0.188-0.0298l-0.0511-0.226c-0.0213 0.0043-0.0554 0.0128-0.111 0.0128-0.111 0-0.217-0.0341-0.217-0.247v-0.955h0.349zm1.09 0h-0.349v-0.392h-0.251v0.392h-0.247v0.213h0.247v1.02c0 0.286 0.23 0.422 0.443 0.422 0.0938 0 0.153-0.017 0.188-0.0298l-0.0511-0.226c-0.0213 0.0043-0.0554 0.0128-0.111 0.0128-0.111 0-0.217-0.0341-0.217-0.247v-0.955h0.349zm1.03 1.67c0.443 0 0.741-0.337 0.741-0.844 0-0.511-0.298-0.848-0.741-0.848s-0.741 0.337-0.741 0.848c0 0.507 0.298 0.844 0.741 0.844zm0-0.226c-0.337 0-0.49-0.29-0.49-0.618s0.153-0.622 0.49-0.622c0.337 0 0.49 0.294 0.49 0.622s-0.153 0.618-0.49 0.618zm1.38-0.793c0-0.286 0.177-0.447 0.418-0.447 0.233 0 0.375 0.152 0.375 0.409v1.02h0.251v-1.04c0-0.418-0.223-0.618-0.554-0.618-0.247 0-0.401 0.111-0.477 0.277h-0.0213v-0.256h-0.243v1.64h0.251z&quot;&#x2F;&gt;
			&lt;&#x2F;g&gt;
		&lt;&#x2F;g&gt;
		&lt;g stroke=&quot;currentColor&quot; stroke-width=&quot;.5&quot;&gt;
			&lt;circle cx=&quot;50&quot; cy=&quot;25&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;61.8&quot; cy=&quot;21.7&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;50&quot; cy=&quot;40&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;30&quot; cy=&quot;25&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;50&quot; cy=&quot;60&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;25&quot; cy=&quot;65&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;25&quot; cy=&quot;60&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;25&quot; cy=&quot;80&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;40&quot; cy=&quot;80&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
			&lt;circle cx=&quot;40&quot; cy=&quot;65&quot; r=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
		&lt;&#x2F;g&gt;
		&lt;path d=&quot;m36 8.37h0.318v-0.778h0.778v-0.318h-0.778v-0.778h-0.318v0.778h-0.778v0.318h0.778zm2.69 0.551c0.554 0 0.96-0.409 0.96-0.966 0-0.564-0.392-0.977-0.926-0.977-0.196 0-0.386 0.0696-0.506 0.165h-0.017l0.102-0.858h1.22v-0.312h-1.51l-0.176 1.43 0.33 0.0398c0.121-0.0866 0.327-0.149 0.506-0.148 0.371 0.00284 0.642 0.284 0.642 0.665 0 0.374-0.261 0.648-0.619 0.648-0.298 0-0.536-0.192-0.562-0.455h-0.341c0.0213 0.443 0.403 0.767 0.903 0.767zm1.69-2.95h-0.369l1.07 2.91h0.364l1.07-2.91h-0.369l-0.864 2.45h-0.0341z&quot; stroke-width=&quot;.265&quot; removed-label=&quot;+5V&quot;&#x2F;&gt;
		&lt;path d=&quot;m103 8.37h0.318v-0.778h0.778v-0.318h-0.778v-0.778h-0.318v0.778h-0.778v0.318h0.778zm2.69 0.551c0.554 0 0.96-0.409 0.96-0.966 0-0.564-0.392-0.977-0.926-0.977-0.196 0-0.386 0.0696-0.506 0.165h-0.017l0.102-0.858h1.22v-0.312h-1.51l-0.176 1.43 0.33 0.0398c0.121-0.0866 0.327-0.149 0.506-0.148 0.371 0.00284 0.642 0.284 0.642 0.665 0 0.374-0.261 0.648-0.619 0.648-0.298 0-0.536-0.192-0.562-0.455h-0.341c0.0213 0.443 0.403 0.767 0.903 0.767zm1.69-2.95h-0.369l1.07 2.91h0.364l1.07-2.91h-0.369l-0.864 2.45h-0.0341z&quot; stroke-width=&quot;.265&quot; removed-label=&quot;+5V&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot;&gt;
		&lt;path d=&quot;m13 17c1.1-6.7e-5 2-0.895 2-2-6.7e-5 -1.1-0.895-2-2-2&quot; stroke-width=&quot;.5&quot; style=&quot;paint-order:stroke markers fill&quot;&#x2F;&gt;
		&lt;path d=&quot;m15 15h10.1l-0.0912 45&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
		&lt;path d=&quot;m15 20h5&quot; stroke-width=&quot;.5&quot;&#x2F;&gt;
	&lt;&#x2F;g&gt;
	&lt;metadata&gt;
		&lt;rdf:RDF&gt;
			&lt;cc:License rdf:about=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;licenses&#x2F;by-sa&#x2F;4.0&#x2F;&quot;&gt;
				&lt;cc:permits rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#Reproduction&quot;&#x2F;&gt;
				&lt;cc:permits rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#Distribution&quot;&#x2F;&gt;
				&lt;cc:requires rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#Notice&quot;&#x2F;&gt;
				&lt;cc:requires rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#Attribution&quot;&#x2F;&gt;
				&lt;cc:permits rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#DerivativeWorks&quot;&#x2F;&gt;
				&lt;cc:requires rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;ns#ShareAlike&quot;&#x2F;&gt;
			&lt;&#x2F;cc:License&gt;
			&lt;cc:Work rdf:about=&quot;&quot;&gt;
				&lt;cc:license rdf:resource=&quot;http:&#x2F;&#x2F;creativecommons.org&#x2F;licenses&#x2F;by-sa&#x2F;4.0&#x2F;&quot;&#x2F;&gt;
				&lt;dc:title&gt;Schematic: Barebones ATmega328P Circuit&lt;&#x2F;dc:title&gt;
				&lt;dc:creator&gt;
					&lt;cc:Agent&gt;
						&lt;dc:title&gt;Slatian&lt;&#x2F;dc:title&gt;
					&lt;&#x2F;cc:Agent&gt;
				&lt;&#x2F;dc:creator&gt;
				&lt;dc:date&gt;2024-04-06&lt;&#x2F;dc:date&gt;
			&lt;&#x2F;cc:Work&gt;
		&lt;&#x2F;rdf:RDF&gt;
	&lt;&#x2F;metadata&gt;
&lt;&#x2F;svg&gt;


	&lt;figcaption&gt;Schematic of the ATmega328P hooked up to power, an external crystal, and a reset circuit as described below. The Serial interface for programming is illustrated as an FTDI compatible layout.&lt;&#x2F;figcaption&gt;


&lt;&#x2F;figure&gt;


&lt;p&gt;For the power Connect &lt;i&gt;VCC&lt;&#x2F;i&gt; and &lt;i&gt;AVCC&lt;&#x2F;i&gt; to 5V and the two &lt;i&gt;GND&lt;&#x2F;i&gt; to Ground. Leave &lt;i&gt;AREF&lt;&#x2F;i&gt; floating unless you need it.&lt;&#x2F;p&gt;
&lt;p&gt;If you want that extra bit of reliability connect a 100nF Capacitor between &lt;i&gt;VCC&lt;&#x2F;i&gt; and &lt;i&gt;GND&lt;&#x2F;i&gt; and between &lt;i&gt;AVCC&lt;&#x2F;i&gt; and &lt;i&gt;GND&lt;&#x2F;i&gt;. The official UNO has a 10μH inductor between &lt;i&gt;AVCC&lt;&#x2F;i&gt; and the 5V to stabilise it even more.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on AREF:&lt;&#x2F;b&gt; The official Arduino boards connect AREF through 100nF Capacitor to ground. I assume this is to initially pull it to Ground while allowing you to override that setting by simply applying a voltage.&lt;&#x2F;p&gt;
&lt;p&gt;For the Clock connect the 16MHz crystal between &lt;i&gt;XTAL1&lt;&#x2F;i&gt; and &lt;i&gt;XTAL2&lt;&#x2F;i&gt;, and each of &lt;i&gt;XTAL1&lt;&#x2F;i&gt; and &lt;i&gt;XTAL2&lt;&#x2F;i&gt; through a 22pf Capacitor to Ground. Try to no make the circuit paths too long here.&lt;&#x2F;p&gt;
&lt;p&gt;For the Reset Circuit: Connect the &lt;i&gt;Reset&lt;&#x2F;i&gt; pin through a 10KΩ Resistor to 5V, put the button between &lt;i&gt;Reset&lt;&#x2F;i&gt; and Ground.&lt;&#x2F;p&gt;
&lt;p&gt;When using a Serial interface (Make sure it uses 5V logic levels, otherwise you&#x27;ll destroy something), put the 100nF Capacitor between the &lt;i&gt;Ready to Send&lt;&#x2F;i&gt; (&lt;i&gt;RTS&lt;&#x2F;i&gt; or &lt;i&gt;DTR&lt;&#x2F;i&gt;) and the Reset pin, this way the Chip will automatically reset when the Serial line becomes active, which is the exact behaviour you want when programming using the Arduino bootloader.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on perfboard Layout:&lt;&#x2F;b&gt; On a perfboard I usually try to go as compact as possible and have a male header right up to the microcontrollers pins that gives access to GND, Reset, RX and TX (with VCC being part of a male GND, VCC, GND header). The DTR capacitor is on a little adaptor board along with an indicator LED that then plugs into my FTDI breakout. The reset button is near the Reset pin and the pull-up resistor goes below the IC-Socket.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;flashing-the-bootloader&quot;&gt;Flashing the Bootloader&lt;&#x2F;h3&gt;
&lt;p&gt;To flash the Arduino bootloader onto the ATmega328P you have to hook up the SPI interface to a programmer. See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.arduino.cc&#x2F;built-in-examples&#x2F;arduino-isp&#x2F;ArduinoToBreadboard&#x2F;&quot;&gt;official Arduino tutorial&lt;&#x2F;a&gt; for this step or my &lt;a href=&quot;&#x2F;notebook&#x2F;arduino-cli&#x2F;#flashing-a-bootloader-using-arduino-cli&quot;&gt;tutorial for doing the same using &lt;code&gt;arduino-cli&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pwm-and-timer-counters&quot;&gt;PWM and Timer&#x2F;Counters&lt;&#x2F;h2&gt;
&lt;p&gt;The ATmega328P has 3 so called &lt;i&gt;Timer&#x2F;Counter&lt;&#x2F;i&gt; units, called &lt;i&gt;Timer&#x2F;Counter0&lt;&#x2F;i&gt;, &lt;i&gt;Timer&#x2F;Counter1&lt;&#x2F;i&gt; and &lt;i&gt;Timer&#x2F;Counter2&lt;&#x2F;i&gt; each can drive 2 of 6 PWM channels.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll abbreviate them as &lt;i&gt;t&#x2F;c&lt;&#x2F;i&gt; in the following.&lt;&#x2F;p&gt;
&lt;p&gt;Oversimplified they are counters hooked up to a configurable Clock source. Every time the clock ticks the counter increments by one. Each counter has two comperators to trigger actions when the counter has reached a configured point.&lt;&#x2F;p&gt;
&lt;p&gt;The actions that can be triggered may be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Interrupts to the CPU&lt;&#x2F;li&gt;
&lt;li&gt;A PWM Signal that can be output on a pin.&lt;&#x2F;li&gt;
&lt;li&gt;Reset the counter&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;i&gt;t&#x2F;c0&lt;&#x2F;i&gt; and &lt;i&gt;t&#x2F;c2&lt;&#x2F;i&gt; have an 8-bit counter while &lt;i&gt;t&#x2F;c1&lt;&#x2F;i&gt; has a 16-bit counter (it can be put in 8-bit and 12-bit modes too).&lt;&#x2F;p&gt;
&lt;p&gt;The clock source itself is too complicated to explain as there are many options, best explained by the official Datasheet. Usually the system clock is used. Each &lt;i&gt;t&#x2F;c&lt;&#x2F;i&gt; also has a prescaler that can be used to make it run slower than the system by a certain factor.&lt;&#x2F;p&gt;
&lt;p&gt;There are a few modes the counters can be in:&lt;&#x2F;p&gt;




	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		Normal
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Simply counts up and does something when the timer overflows and wraps back to 0
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Clear Timer on Compare Match (CTC)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Counts up, but wraps to 0 and does something when the value in ine of the control registers matches
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Fast PWM
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Counts up, on a first match the PWM signal is turned off, on a second or overflow it is turned back on.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Phase Correct PWM Mode, Timing Diagram
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Counts up and instead of wrapping down again, the PWM signal is toggled at a comparison point.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;For The Phase Correct PWM Mode, the center of the wave always stays in the same place, which is good for driving motors. It also effectively halfes the frequency of the &lt;i&gt;t&#x2F;c&lt;&#x2F;i&gt; in addition to whatever the prescaler does.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pwm-and-arduino&quot;&gt;PWM and Arduino&lt;&#x2F;h3&gt;
&lt;p&gt;The Arduino has 6 PWM capable pins, each connected to one comparator channel of the three timers.&lt;&#x2F;p&gt;
&lt;p&gt;By default all of the &lt;i&gt;t&#x2F;cs&lt;&#x2F;i&gt; are in 8-bit resolution Phase Correct PWM with clock division by 64 in the prescaler, wrapping at the 8-bit overflow (after 256 cycles), which reults in a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.arduino.cc&#x2F;reference&#x2F;en&#x2F;language&#x2F;functions&#x2F;analog-io&#x2F;analogwrite&#x2F;&quot;&gt;PWM frequency of ~490Hz&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The exception here is &lt;i&gt;t&#x2F;c0&lt;&#x2F;i&gt; driving the counter behind the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.arduino.cc&#x2F;reference&#x2F;en&#x2F;language&#x2F;functions&#x2F;time&#x2F;millis&#x2F;&quot;&gt;&lt;code&gt;millis()&lt;&#x2F;code&gt; function&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arduino&#x2F;ArduinoCore-avr&#x2F;blob&#x2F;master&#x2F;cores&#x2F;arduino&#x2F;wiring.c#L65&quot;&gt;code&lt;&#x2F;a&gt;) is in Fast PWM Mode. This is why Arduino Pins 5 and 6 have double the frequency at ~980Hz.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Calculation of how to get from the System frequency to the PWM frequency.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;16MHz &#x2F; 64 &#x2F; 2 &#x2F; 256 = ~488Hz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;h4 id=&quot;tone-generation&quot;&gt;Tone generation&lt;&#x2F;h4&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.arduino.cc&#x2F;reference&#x2F;en&#x2F;language&#x2F;functions&#x2F;advanced-io&#x2F;tone&#x2F;&quot;&gt;&lt;code&gt;tone()&lt;&#x2F;code&gt; function&lt;&#x2F;a&gt; uses &lt;i&gt;t&#x2F;c2&lt;&#x2F;i&gt; which is why it messes up the PWM on Arduino Pins 3 and 11.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arduino&#x2F;ArduinoCore-avr&#x2F;blob&#x2F;63092126a406402022f943ac048fa195ed7e944b&#x2F;cores&#x2F;arduino&#x2F;Tone.cpp#L243&quot;&gt;The underlying code&lt;&#x2F;a&gt; adjusts the clock divider and &lt;i&gt;Compare Registers&lt;&#x2F;i&gt; to select an appropriate one for the desired frequency, and puts the timer into &lt;i&gt;Clear Timer on Compare Match&lt;&#x2F;i&gt; Mode to generate generate an unmodulated square wave.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Assumption:&lt;&#x2F;b&gt; Based on how the code looks it is now capable of using any PWM pin for the tone generating and mess up the the corresponding other PWM pin. I&#x27;ve not bothered to prove or disprove this yet, do your own research.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;avoiding-pwm-flickering&quot;&gt;Avoiding PWM flickering&lt;&#x2F;h4&gt;
&lt;p&gt;When connecting an RGB LED to a combination of &lt;i&gt;t&#x2F;c0&lt;&#x2F;i&gt; and one of the other timers to generate pretty colors you might notice an annoying flicker which comes from you seeing some interference pattern that stems from the different modes.&lt;&#x2F;p&gt;
&lt;p&gt;Since you really shouldn&#x27;t change the configuration of &lt;i&gt;t&#x2F;c0&lt;&#x2F;i&gt; you can put one of the other timers in Fast PWM mode (the LEDs don&#x27;t care).&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example that put&#x27;s &lt;i&gt;t&#x2F;c1&lt;&#x2F;i&gt; into Fast PWM mode given the Arduino default configuration.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Set timer&#x2F;counter 1 from 8-bit phase correct to 8-bit fast&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;bitWrite&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;TCCR1B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; WGM12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-action-next&quot; href=&quot;&amp;#x2F;blog&amp;#x2F;fixing-pwm-flicker&amp;#x2F;&quot; &gt;
		See the blogpost on fixing PWM flicker for an explanation why it flickers.
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;useful-resources&quot;&gt;Useful Resources&lt;&#x2F;h2&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a class=&quot;decoration-action-next&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;en-us&#x2F;product&#x2F;atmega328p#document-table&quot;&gt;ATmega328P Datasheet and Application Notes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-action-next&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microchip.com&#x2F;DS40002061B&quot;&gt;Direct Link to the ATmega328P Datasheet&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-action-next&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.arduino.cc&#x2F;hardware&#x2F;uno-rev3&#x2F;&quot;&gt;Arduino UNO R3 Documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-action-next&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arduino&#x2F;ArduinoCore-avr&#x2F;tree&#x2F;master&quot;&gt;ArduinoCore-avr Source Code&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

</content>
    </entry>
    <entry xml:lang="en">
        <title>XML XPath</title>
        <published>2023-12-22T00:00:00+00:00</published>
        <updated>2023-12-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/xpath/"/>
        <id>https://slatecave.net/notebook/xpath/</id>
        
        <summary type="text">Query elements from XML Documents, on the CLI, in the Browser, everywhere else</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/xpath/">&lt;p&gt;XPath is a way to select tags from an XML Document, it works a bit like a File-path and a bit like a CSS-Selector.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-document&quot;&gt;Example Document&lt;&#x2F;h2&gt;
&lt;p&gt;For the Examples on this page the following XML-Document is assumed.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; encoding&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;UTF-8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;catalog&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;An Overview of Dataformats.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Describes Dataformats&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;JSON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Data Serialization&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;www.json.org&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wikipedia&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;JSON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;XML&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Documents&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;use&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;website&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;www.xml.com&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;link&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; type&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;wikipedia&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; href&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;XML&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;item&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;catalog&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-action-download&quot; href=&quot;.&amp;#x2F;xpath-example.xml&quot;  download&gt;
		Download Example XML
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;querying-nodes&quot;&gt;Querying Nodes&lt;&#x2F;h2&gt;
&lt;p&gt;XPath works like a file-path.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; To address the &lt;code&gt;title&lt;&#x2F;code&gt; tag (&lt;i&gt;node&lt;&#x2F;i&gt; in XPath terminology).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;catalog&#x2F;title&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; If you are inside a context (i.e. one of the &lt;code&gt;item&lt;&#x2F;code&gt; elements) you can also use it like a relative file-path: &lt;code&gt;use&lt;&#x2F;code&gt;, &lt;code&gt;.&#x2F;name&lt;&#x2F;code&gt;, &lt;code&gt;..&#x2F;title&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For wildcards on a single level one can use a &lt;code&gt;*&lt;&#x2F;code&gt; for the tag name.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Same as previous but with a wildcard.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;*&#x2F;title&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;By using &lt;code&gt;&#x2F;&#x2F;&lt;&#x2F;code&gt; one can select all elements matching the following description no matter where in the document they are.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Select &lt;em&gt;all&lt;&#x2F;em&gt; three &lt;code&gt;use&lt;&#x2F;code&gt; tags.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;use&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Using the &lt;code&gt;&#x2F;&#x2F;&lt;&#x2F;code&gt; like &lt;code&gt;&#x2F;catalog&#x2F;&#x2F;use&lt;&#x2F;code&gt; will also work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;querying-attributes&quot;&gt;Querying Attributes&lt;&#x2F;h2&gt;
&lt;p&gt;To get the attribute of a tag use the notation &lt;code&gt;&#x2F;path&#x2F;to&#x2F;tag&#x2F;@attribute&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; To get the &lt;code&gt;href&lt;&#x2F;code&gt; attributes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;link&#x2F;@href&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;dealing-with-multiple-elements-using-predicates&quot;&gt;Dealing with Multiple Elements using Predicates&lt;&#x2F;h2&gt;
&lt;p&gt;When specifying an XPath that yields multiple results maybe one wants not all elements that match a tag.&lt;&#x2F;p&gt;
&lt;p&gt;Writing a number in square brackets will work similar to an array access in a programming language: &lt;code&gt;tag[1]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Select the second &lt;code&gt;item&lt;&#x2F;code&gt; from the catalog:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;catalog&#x2F;item[2]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In place of the Number on can also use expressions like &lt;code&gt;last()&lt;&#x2F;code&gt;, &lt;code&gt;last()-1&lt;&#x2F;code&gt; or &lt;code&gt;position()&amp;gt;1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;One can also compare against attributes here.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Only select the &lt;code&gt;type=&quot;wikipedia&quot;&lt;&#x2F;code&gt; links.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;link[@type=&amp;#39;wikipedia&amp;#39;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note on Quoting:&lt;&#x2F;b&gt; XPath uses single quotes so one can easily use it in XML attributes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Boolean Logic:&lt;&#x2F;b&gt; Boolean logic is implemented with the &lt;code&gt;and&lt;&#x2F;code&gt; and &lt;code&gt;or&lt;&#x2F;code&gt; keywords and the &lt;code&gt;not()&lt;&#x2F;code&gt; function.&lt;&#x2F;p&gt;
&lt;p&gt;These are way more possibilities, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xpath_syntax.asp&quot;&gt;w3schools tutorial has a more complete predicate list&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-node-text&quot;&gt;Getting Node Text&lt;&#x2F;h2&gt;
&lt;p&gt;To get the text inside a node use &lt;code&gt;&#x2F;text()&lt;&#x2F;code&gt; to select it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Get the text from the first items name:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;item[1]&#x2F;name&#x2F;text()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;getting-attribute-text&quot;&gt;Getting Attribute Text&lt;&#x2F;h2&gt;
&lt;p&gt;To get the text from an attribute one can prefix the attribute name with an &lt;code&gt;@&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; To get all URLs from the link elements from the example document.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F;link&#x2F;@href&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; This will select the attribute as a key-value pair in some contexts. To only get the value wrap it like this: &lt;code&gt;concat(&#x27;&#x27;,&#x2F;&#x2F;link&#x2F;@href)&lt;&#x2F;code&gt; (only keeps first element) or &lt;code&gt;string-join(&#x2F;&#x2F;link&#x2F;@href,&#x27; &#x27;)&lt;&#x2F;code&gt; (keeps all elements but requires XPath 2 support).&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example using &lt;code&gt;xquilla&lt;&#x2F;code&gt; to output all link URLs from the example document using newlines as delimiters. The &lt;code&gt;printf&lt;&#x2F;code&gt; is used to convert the &lt;code&gt;\n&lt;&#x2F;code&gt; to a real newline.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string-join(&#x2F;&#x2F;link&#x2F;@href,&amp;#39;\n&amp;#39;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;xqilla&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;dev&#x2F;stdin&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; xpath-example.xml&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;combine-multiple-xpaths&quot;&gt;Combine multiple XPaths&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes the result of one XPath isn&#x27;t enough and you want the combined results of multiple XPaths. (Like a SQL union)&lt;&#x2F;p&gt;
&lt;p&gt;To achieve this you join multiple XPaths using a pipe &lt;code&gt;|&lt;&#x2F;code&gt; character like this: &lt;code&gt; &#x2F;xpath1 | &#x2F;xpath1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xpath-with-namespaces&quot;&gt;XPath with Namespaces&lt;&#x2F;h2&gt;
&lt;p&gt;If some of your Nodes are part of a namespace, i.e. using the &lt;code&gt;&amp;lt;namespace:tag&amp;gt;&lt;&#x2F;code&gt; syntax or the &lt;code&gt;&amp;lt;tag xmlns=&quot;https:&#x2F;&#x2F;example.org&quot;&amp;gt;&lt;&#x2F;code&gt; attribute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; When using the &lt;code&gt;xmlns&lt;&#x2F;code&gt; attribute all children of that node are also in that namespace unless declared otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;When a namespace is used you&#x27;ll notice that your usual queries don&#x27;t work for some strange reason.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Snippet of Atom-Feed serving as an example documents here.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;feed&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;2005&#x2F;Atom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;lang&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;en&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;slatecave.net&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    &amp;lt;!--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Rest of feed &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;feed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;To get the title one may want to try the XPath &lt;code&gt;&#x2F;feed&#x2F;title&lt;&#x2F;code&gt;, but this will fail because of the namespace.&lt;&#x2F;p&gt;
&lt;p&gt;If it is possible to declare the namespace (i.e. in an XSLT-Sheet) then do that and select the element with the namespace prefix, i.e. &lt;code&gt;&#x2F;atom:feed&#x2F;atom:title&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If it is not possible to declare the Namespace you can work around that by using the &lt;code&gt;local-name()&lt;&#x2F;code&gt; function like this: &lt;code&gt;*[local-name()=&#x27;feed&#x27;]&#x2F;*[local-name()=&#x27;title&#x27;]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;useful-links&quot;&gt;Useful Links&lt;&#x2F;h2&gt;
&lt;p&gt;All of the following lead to the w3schools page.&lt;&#x2F;p&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a class=&quot;decoration-destination-text&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xpath_syntax.asp&quot;&gt;XPath Syntax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-destination-text&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xpath_operators.asp&quot;&gt;XPath Operators&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-destination-text&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xsl_functions.asp&quot;&gt;XPath Functions&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-destination-text&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3schools.com&#x2F;xml&#x2F;xpath_intro.asp&quot;&gt;XPath Tutorial&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; There is also the related &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;info&#x2F;rfc9535&quot;&gt;RFC 9535: JSONPath: Query Expressions for JSON&lt;&#x2F;a&gt; that might be interesting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;playing-with-xpath&quot;&gt;Playing with XPath&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;using-xmllint&quot;&gt;Using &lt;code&gt;xmllint&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;xmllint&quot;&gt;&lt;code&gt;xmllint&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; command line utility can do XPath.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;xmllint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;file.xm&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-xpath&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;lt;xpath&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; &lt;code&gt;xmllint&lt;&#x2F;code&gt; and XPath are the &lt;code&gt;jq&lt;&#x2F;code&gt; of XML, if they seem a bit clunky that is because they have been around for a freaking long time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Compatibility:&lt;&#x2F;b&gt; &lt;code&gt;xmllint&lt;&#x2F;code&gt; only works with XPath 1.0, if you get an error stating that a function is unregistred, thats why. It mostly affects functions that somehow involve lists.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-xquilla&quot;&gt;Using &lt;code&gt;xquilla&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;manpages.org&#x2F;xqilla&quot;&gt;&lt;code&gt;xquilla&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; command line tool supports XPath 2.0 and a whole lot of other XML functionality. It usually reads commands from a file and applies it to an XML-Document.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;lt;xpath&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; xquilla&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;dev&#x2F;stdin&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;file.xm&lt;&#x2F;span&gt;&lt;span&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;getting-information-from-html&quot;&gt;Getting information from HTML&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Get the title of the HTML Document.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;slatecave.net&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;xmllint&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-html&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-xpath&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;html&#x2F;head&#x2F;title&#x2F;text()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; Get the social media preview description.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; https:&#x2F;&#x2F;slatecave.net&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;xmllint&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-html&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-xpath&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;string(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&#x2F;html&#x2F;head&#x2F;meta[@property=&amp;#39;og:description&amp;#39;]&#x2F;@content |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&#x2F;html&#x2F;head&#x2F;meta[@property=&amp;#39;og:description&amp;#39;]&#x2F;text()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Explanation:&lt;&#x2F;b&gt; Both examples use &lt;code&gt;-&lt;&#x2F;code&gt; to tell &lt;code&gt;xmllint&lt;&#x2F;code&gt; to read from its standard input (that is the &lt;code&gt;curl&lt;&#x2F;code&gt; output here), enable the HTML parser with the &lt;code&gt;--html&lt;&#x2F;code&gt; option and discard any errors from &lt;code&gt;xmllint&lt;&#x2F;code&gt; using &lt;code&gt;2&amp;gt;&amp;amp;-&lt;&#x2F;code&gt;, which tells the shell to close the standard error.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Getting your Smartcards and Security Tokens working on Linux</title>
        <published>2023-12-03T00:00:00+00:00</published>
        <updated>2023-12-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/get-security-token-working-on-linux/"/>
        <id>https://slatecave.net/notebook/get-security-token-working-on-linux/</id>
        
        <summary type="text">You just bought a popular Security Token to find it not working out of the box on Linux?</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/get-security-token-working-on-linux/">&lt;p&gt;Most Problems I had with Smartcards or Security Tokens just boiled down to missing packages. (&lt;code&gt;pcsclite&lt;&#x2F;code&gt;, &lt;code&gt;ccid&lt;&#x2F;code&gt; and &lt;code&gt;libfido2&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-smartcards-and-security-tokens&quot;&gt;What are Smartcards and Security Tokens?&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Security_token&quot;&gt;Security Tokens&lt;&#x2F;a&gt; are small devices that hold cryptographic keys and implement some number of protocols that make those keys usable without them ever leaving the device.&lt;&#x2F;p&gt;
&lt;p&gt;This behaviour is useful because nobody can steal your key from such a device, even if you plug that Security token into a virus dripping publicly accessible PC (though that doesn&#x27;t mean you should).&lt;&#x2F;p&gt;
&lt;p&gt;Popular security Tokens are: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;YubiKey&quot;&gt;YubiKey&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Nitrokey&quot;&gt;Nitrokey&lt;&#x2F;a&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Tillitis_TKey&quot;&gt;Tillitis TKey&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Solo&quot;&gt;SoloKey&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; I&#x27;m not qualified to to recommend any Security Tokens, these are just the popular ones I know people will search for.&lt;&#x2F;p&gt;
&lt;p&gt;Smartcards are the same technology in card form, examples include modern bank cards, passports and other credit card sized plastic lumps with a chip baked into them.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll use the terms &lt;i&gt;smartcards&lt;&#x2F;i&gt; and &lt;i&gt;security token&lt;&#x2F;i&gt; interchangeably here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-missing-packages&quot;&gt;Install missing Packages&lt;&#x2F;h2&gt;
&lt;p&gt;For some reason the utilities for using Smartcards or  don&#x27;t declare the needed backends as their dependencies, those backends are needed to turn sometime obscure USB or NFC interfaces into APIs that applications can access without worrying about device details.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pcsclite-and-ccid&quot;&gt;&lt;code&gt;pcsclite&lt;&#x2F;code&gt; and &lt;code&gt;ccid&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Middleware to access a smart card using SCard API (PC&#x2F;SC).&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pcsclite.apdu.fr&#x2F;&quot;&gt;pcsclite&lt;&#x2F;a&gt; provides a service that takes PC&#x2F;SC hardware and patches it through to userspace. Usually you need a driver for your Smartcards reader which comes in the &lt;code&gt;ccid&lt;&#x2F;code&gt; (sometimes &lt;code&gt;pcsc-ccid&lt;&#x2F;code&gt;) package. (You may need a more specific driver in some cases)&lt;&#x2F;p&gt;
&lt;p&gt;It is needed for the part of the smartcard that can do actual signing and encryption, and is commonly used with OpenPGP or PKCS#11.&lt;&#x2F;p&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Smartcards&quot;&gt;The ArchWiki on Smartcards&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.debian.org&#x2F;Smartcards&quot;&gt;The Debian Wiki on Smartcards&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;h3 id=&quot;libfido2&quot;&gt;&lt;code&gt;libfido2&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;FIDO2_Project&quot;&gt;FIDO2&lt;&#x2F;a&gt; (the successor to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Universal_2nd_Factor&quot;&gt;Universal 2nd Factor&lt;&#x2F;a&gt;) provides authentication functionality usually used as a second factor to log into websites.&lt;&#x2F;p&gt;
&lt;p&gt;Usually installing the &lt;code&gt;libfido2&lt;&#x2F;code&gt; package solves the problem that your Security Token is not recognised as it also contains all the needed udev tweaks and so on. Maybe a reboot is necessary.&lt;&#x2F;p&gt;
&lt;p&gt;Testing this functionality with your browser can be done using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;demo.yubico.com&#x2F;&quot;&gt;Yubicos demo page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;wiki.archlinux.org&amp;#x2F;title&amp;#x2F;Universal_2nd_Factor&quot; &gt;
		The ArchWiki has more information on Universal 2nd Factor and FIDO
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;YubiKey Note:&lt;&#x2F;b&gt; Installing &lt;code&gt;libfido2&lt;&#x2F;code&gt; also fixed the not very helpful &lt;br&gt;&lt;code&gt;WARNING: No OTP HID backend available. OTP protocols will not function&lt;&#x2F;code&gt; &lt;br&gt;for the YubiKey Manager (&lt;code&gt;ykman&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;interesting-things-to-do-with-a-security-token&quot;&gt;Interesting Things to do with a Security Token&lt;&#x2F;h2&gt;
&lt;p&gt;Now that your token is working why not try some interesting things?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Warning:&lt;&#x2F;b&gt; Interesting also means that things can go wrong. Make sure you don&#x27;t lock yourself out of anything important and use a test system if in doubt.&lt;&#x2F;p&gt;
&lt;p&gt;In case you want to use these devices to log into your Linux user or authenticate &lt;code&gt;sudo&lt;&#x2F;code&gt; with one of these Tokens you want to look into PAM Modules. See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Universal_2nd_Factor#Authentication_for_user_sessions&quot;&gt;ArchWiki on Authentication for User Sessions with FIDO2&lt;&#x2F;a&gt; for more information.&lt;&#x2F;p&gt;
&lt;p&gt;You can also secure you ssh-keys with these tokens. See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;SSH_keys#FIDO&#x2F;U2F&quot;&gt;ArchWiki on ssh with FIDO&#x2F;U2F&lt;&#x2F;a&gt; or the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;media.ccc.de&#x2F;v&#x2F;gpn21-28-noch-besser-leben-mit-ssh#t=2116&quot;&gt;Talk &lt;q lang=&quot;de&quot;&gt;Noch besser leben mit SSH&lt;&#x2F;q&gt; (from 35:18)&lt;&#x2F;a&gt; (at the time of writing no English translation is available) held by leyrer at GPN21.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>SQL Cheatsheet</title>
        <published>2023-11-18T00:00:00+00:00</published>
        <updated>2023-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/sql/"/>
        <id>https://slatecave.net/notebook/sql/</id>
        
        <summary type="text">Some useful reminders for the occasional SQL user.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/sql/">&lt;h2 id=&quot;sql-query-anatomy&quot;&gt;SQL Query Anatomy&lt;&#x2F;h2&gt;
&lt;p&gt;Most databases don&#x27;t like it when the SQL clauses are out of order.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Operator
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SELECT … FROM …&lt;&#x2F;code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;lang_select.html&quot;&gt;SQLite&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;INSERT INTO &amp;lt;table&amp;gt;(…) VALUES (…),…&lt;&#x2F;code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;lang_insert.html&quot;&gt;SQLite&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;UPDATE &amp;lt;table&amp;gt; SET …&lt;&#x2F;code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;lang_update.html&quot;&gt;SQLite&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DELETE FROM …&lt;&#x2F;code&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;lang_delete.html&quot;&gt;SQLite&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;JOIN&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;GROUP BY&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;HAVING&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ORDER BY&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;LIMIT&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;OFFSET&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;null-tricks&quot;&gt;NULL Tricks&lt;&#x2F;h2&gt;
&lt;p&gt;Null in SQL is special as it isn&#x27;t equal (&lt;code&gt;=&lt;&#x2F;code&gt;) to anything, not even itself, which seems wiered when coming from programming languages but makes perfect sense when considering that &lt;code&gt;NULL&lt;&#x2F;code&gt; means &quot;unknown value&quot; wich definitely isn&#x27;t equal to another &quot;unknown value&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;If you want null to behave more like in a programming language use the &lt;code&gt;is&lt;&#x2F;code&gt; keyword, where &lt;code&gt;NULL is NULL&lt;&#x2F;code&gt; evaluates to 1 opposed to &lt;code&gt;NULL = NULL&lt;&#x2F;code&gt; which results in a 0.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; For all other values &lt;code&gt;is&lt;&#x2F;code&gt; acts like &lt;code&gt;=&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To get a default value at the time of a query there is the &lt;code&gt;coalesce()&lt;&#x2F;code&gt; function which takes multiple aruments and returns the first non-null one. (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;lang_corefunc.html#coalesce&quot;&gt;SQLite&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sqlite.org&#x2F;nulls.html&quot;&gt;SQLite has a page with more null quirks, comparing SQLite to other Database engines.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;join-types&quot;&gt;Join Types&lt;&#x2F;h2&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example SQL &lt;code&gt;JOIN&lt;&#x2F;code&gt; statement.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span&gt; …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; bookmark&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INNER JOIN&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; url&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; ON&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; url&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;url_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; bookmark&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;url_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;What all joins have in common is that they glue the tables together and output the entries where the &lt;code&gt;ON&lt;&#x2F;code&gt; condition is true.&lt;&#x2F;p&gt;
&lt;p&gt;They differ in how they treat entries that don&#x27;t make it into the output because they didn&#x27;t find a &quot;partner&quot; using the &lt;code&gt;ON&lt;&#x2F;code&gt; condition.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;inner&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		only returns entries that found a partner.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;left&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		doesn&#x27;t drop columns from the already present columns, leaving the joined columns &lt;code&gt;NULL&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;right&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		additionally outputs all entries from the joined table that didn&#x27;t find a partner, leaving the other columns &lt;code&gt;NULL&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;full&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		like a &lt;code&gt;left&lt;&#x2F;code&gt; and &lt;code&gt;right&lt;&#x2F;code&gt; join, returning all of the entries in both tables, joining the ones that are join-able and filling in where joining isn&#x27;t possible.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h3 id=&quot;join-examples&quot;&gt;Join Examples&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; To keep this example as clean as possible types have been omitted, the SQL is intended to be compatible with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sqlite.org&quot;&gt;sqlite3&lt;&#x2F;a&gt;. Use the command &lt;code&gt;sqlite3 :memory:&lt;&#x2F;code&gt; to get an in memory database to play around with.&lt;&#x2F;p&gt;
&lt;p&gt;Assume we have two tables, called &lt;code&gt;left_t&lt;&#x2F;code&gt; and &lt;code&gt;right_t&lt;&#x2F;code&gt; for illustration purposes, bot with a single column.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; left_t&lt;&#x2F;span&gt;&lt;span&gt;(lc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;CREATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TABLE&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; right_t&lt;&#x2F;span&gt;&lt;span&gt;(rc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; left_t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;both&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INSERT INTO&lt;&#x2F;span&gt;&lt;span&gt; right_t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;VALUES&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;both&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;),(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;right&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we can query them an see the results:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;SELECT&lt;&#x2F;span&gt;&lt;span&gt; lc,rc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;FROM&lt;&#x2F;span&gt;&lt;span&gt; left_t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;INNER JOIN&lt;&#x2F;span&gt;&lt;span&gt; right_t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ON&lt;&#x2F;span&gt;&lt;span&gt; lc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; rc ;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We now performed an inner join of &lt;code&gt;right_t&lt;&#x2F;code&gt; against &lt;code&gt;left_t&lt;&#x2F;code&gt; on the single columns having the same value. The returned record is &lt;code&gt;both|both&lt;&#x2F;code&gt;. Pretty intuitive.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Now we substitute the &lt;code&gt;INNER&lt;&#x2F;code&gt; for a &lt;code&gt;LEFT&lt;&#x2F;code&gt; and the result is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;both|both&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;left|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All rows in &lt;code&gt;left_t&lt;&#x2F;code&gt; table mad it through the join, the hole in the &lt;code&gt;right_t&lt;&#x2F;code&gt; was filled with a (blank) &lt;code&gt;NULL&lt;&#x2F;code&gt; field.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; If the &lt;code&gt;right_t&lt;&#x2F;code&gt; table had more columns all of them would be returned as &lt;code&gt;NULL&lt;&#x2F;code&gt;, independent of any &lt;code&gt;DEFAULT&lt;&#x2F;code&gt; or &lt;code&gt;NOT NULL&lt;&#x2F;code&gt; statements.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Similar results for a &lt;code&gt;RIGHT&lt;&#x2F;code&gt; join:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;both|both&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now all rows from the &lt;code&gt;right_t&lt;&#x2F;code&gt; table made it through and the missing rows in the &lt;code&gt;left_t&lt;&#x2F;code&gt; table was filled with a &lt;code&gt;NULL&lt;&#x2F;code&gt; entry.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;And for the &lt;code&gt;FULL&lt;&#x2F;code&gt; join:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;both|both&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;left|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All rows preserved, the ones that matched got joined that ones without matches had the resulting holes filled with &lt;code&gt;NULL&lt;&#x2F;code&gt; fields.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;database-exploration-commands&quot;&gt;Database Exploration Commands&lt;&#x2F;h2&gt;
&lt;p&gt;You Probably know the problem, a Database you are not familiar with with an engine you don&#x27;t use every day and what were the commands again?&lt;&#x2F;p&gt;
&lt;table&gt;
&lt;caption&gt;Common Tasks and the Corresponding &quot;SQL&quot; Commands.&lt;&#x2F;caption&gt;
&lt;tr&gt;&lt;th&gt;Task&lt;&#x2F;th&gt;&lt;th&gt;MariaDB&lt;&#x2F;th&gt;&lt;th&gt;Postgres&lt;&#x2F;th&gt;&lt;th&gt;SQLite&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Get Help&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;help&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;\h&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;.help&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;List Data&amp;shy;bases&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;show databases&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;\l&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;.databases&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Use a Data&amp;shy;base&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;use &amp;lt;data&amp;shy;base&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;\c &amp;lt;data&amp;shy;base&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;Not available&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;List Tables&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;show tables&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;\dt&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;.tables&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Describe Table&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;describe &amp;lt;table&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;\d &amp;lt;table&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;.schema &amp;lt;table&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Quit Shell&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;exit&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;\q&lt;&#x2F;code&gt;, &lt;code&gt;quit&lt;&#x2F;code&gt;, &lt;code&gt;exit&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;td&gt;&lt;code&gt;.q&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Git Cheatsheet(s)</title>
        <published>2023-11-03T00:00:00+00:00</published>
        <updated>2023-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/git/"/>
        <id>https://slatecave.net/notebook/git/</id>
        
        <summary type="text">Some of my git knowledge and where it came from.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/git/">&lt;h2 id=&quot;setting-up&quot;&gt;Setting Up&lt;&#x2F;h2&gt;
&lt;p&gt;Before starting to use git one should take the few minutes to set it up.&lt;&#x2F;p&gt;
&lt;p&gt;Set up your personal information that will end up on your commits:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-global&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; user.email&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;your-mail@example.or&lt;&#x2F;span&gt;&lt;span&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-global&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; user.name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;lt;Name&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set the default branch name to main instead of master
The reasons I do this are because there was some controversy
around the word &quot;master&quot; in this particular context
and and I quickly realised that &quot;main&quot; is way easier to type.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-global&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; init.defaultBranch&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You could set your editor for git commit messages (and other git features) using:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-global&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; core.editor&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;editor-comman&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you (like me) have one editor you want to use for everything: Set the &lt;a href=&quot;&#x2F;notebook&#x2F;env#linux-and-posix&quot;&gt;&lt;code&gt;EDITOR&lt;&#x2F;code&gt; variable in your &lt;code&gt;~&#x2F;.profile&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and git along with a whole range of other programs will pick up on that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;partial-adding&quot;&gt;Partial Adding&lt;&#x2F;h2&gt;
&lt;p&gt;Situation: You have made changes to one file but they should be in two different commits.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt; [&amp;lt;file&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;git will then chop up the changes into &lt;i&gt;hunks&lt;&#x2F;i&gt; and ask interactively if you want to add&#x2F;stage (&lt;code&gt;y&lt;&#x2F;code&gt;) a change, ignore&#x2F;not stage it (&lt;code&gt;n&lt;&#x2F;code&gt;), further subdivide (&lt;code&gt;s&lt;&#x2F;code&gt;) or even edit (&lt;code&gt;e&lt;&#x2F;code&gt;) it. You can use &lt;code&gt;?&lt;&#x2F;code&gt; to get summary of all options currently available.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;undoing-things&quot;&gt;Undoing Things&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;undo-last-commit&quot;&gt;Undo last Commit&lt;&#x2F;h3&gt;
&lt;p&gt;Situation: You just made a git commit but you committed too much by accident.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; If you just messed up the commit message or need to add changes use &lt;code&gt;git commit --amend&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git reset&lt;&#x2F;code&gt; is your friend here, without any arguments it helps when you &lt;code&gt;git add&lt;&#x2F;code&gt;ed too much, it makes git go into the state it was in at the last commit.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; reset&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; HEAD^1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-scm.com&#x2F;book&#x2F;en&#x2F;v2&#x2F;Git-Tools-Revision-Selection#_ancestry_references&quot;&gt;&lt;code&gt;HEAD^1&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; resets git to the parent commit of the last commit. Effectively acting as if the last commit never happened. (You can still recover it using the revlog)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;git reset&lt;&#x2F;code&gt; will only change your git history, not the files you have currently checked out so when using it as described above you won&#x27;t loose any changes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Warning:&lt;&#x2F;b&gt; &lt;code&gt;git reset --hard&lt;&#x2F;code&gt; is intended to throw changes away and it &lt;em&gt;is&lt;&#x2F;em&gt; possible to loose uncommitted data when using it with the &lt;code&gt;--hard&lt;&#x2F;code&gt; flag enabled.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;restore-file-from-last-commit&quot;&gt;Restore File from last Commit&lt;&#x2F;h3&gt;
&lt;p&gt;Situation: You messed up a file and want to throw away the changes since the last commit.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;git&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; restore&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;filenam&lt;&#x2F;span&gt;&lt;span&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is less destructive than &lt;code&gt;git reset --hard&lt;&#x2F;code&gt; which throws away all your changes in a repository since the last commit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shallow-clone&quot;&gt;Shallow clone&lt;&#x2F;h2&gt;
&lt;p&gt;Situation: You have a very large git repository and limited time and&#x2F;or bandwidth and only need the latest few commits.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git clone --depth 3 &amp;lt;url&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This example will only fetch the last 3 commits of the main upstream branch.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shallow-fetch&quot;&gt;Shallow fetch&lt;&#x2F;h3&gt;
&lt;p&gt;In case you need additional branches:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git fetch --depth 3 origin &amp;lt;branch&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git switch --detach FETCH_HEAD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git switch --create &amp;lt;branch&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that you can use all branches you fetched as usual&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-peoples-git-guides&quot;&gt;Other Peoples Git Guides&lt;&#x2F;h2&gt;
&lt;p&gt;These are guides made by other people that I think are useful.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;drewdevault.com&#x2F;2020&#x2F;04&#x2F;06&#x2F;My-weird-branchless-git-workflow.html&quot;&gt;My unorthodox, branchless git workflow&lt;&#x2F;a&gt; Drew DeVault explains how to make use of the fact that the git history of a repository isn&#x27;t set in stone, I mainly use these tricks to completely avoid a lot of merge conflicts in my personal projects.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git-rebase.io&#x2F;&quot;&gt;Learn to change history with git rebase!&lt;&#x2F;a&gt; is Drew DeVault&#x27;s cheatsheet for altering git history in general and the rebase based workflow in the blogpost liked above.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jvns.ca&#x2F;blog&#x2F;2024&#x2F;02&#x2F;01&#x2F;dealing-with-diverged-git-branches&#x2F;&quot;&gt;Dealing with diverged git branches&lt;&#x2F;a&gt; Julia Evans explains how to deal with the situation that changes happend on both the local and remote git repository. (She explains it better than I do here.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;media.ccc.de&#x2F;v&#x2F;DiVOC-5-ein_kurzer_blick_in_git#t=0&quot;&gt;Ein kurzer Blick in .git&#x2F;&lt;&#x2F;a&gt; is a talk held at DiVOC in 2020 by Florian Hars diving into the &lt;code&gt;.git&lt;&#x2F;code&gt; directory, unfortunately no one has translated it to English yet.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jvns.ca&#x2F;blog&#x2F;2024&#x2F;01&#x2F;26&#x2F;inside-git&#x2F;&quot;&gt;Inside .git&lt;&#x2F;a&gt; is a blogpost by Julia Evans that also dives into the &lt;code&gt;.git&lt;&#x2F;code&gt; directory and explains what is inside.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Environment Variable Zoo</title>
        <published>2023-07-03T00:00:00+00:00</published>
        <updated>2025-10-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/env/"/>
        <id>https://slatecave.net/notebook/env/</id>
        
        <summary type="text">Environment Variables for Linux you might want to know about.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/env/">&lt;p&gt;Environment variables are basically inherited, named arguments to processes with a huge impact on how a Linux or other *nix systems work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reading-and-writing-environment-variables&quot;&gt;Reading and Writing Environment Variables&lt;&#x2F;h2&gt;
&lt;p&gt;These commands here should work in almost all shells inspired by the original sh, if you use something else you probably know why and how to use it.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		Read out a single Variable
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;echo &quot;$SHELL&quot;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;printenv SHELL&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		Dump out all variables
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;export&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;printenv&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		Set one or more variable for a single command
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;TZ=UTC LANG=&quot;de_DE.UTF-8&quot; date&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;env TZ=UTC LANG=&quot;de_DE.UTF-8&quot; date&lt;&#x2F;code&gt; Useful program for simpler shells, environment (un)setting and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chain_loading#Chain_loading_in_Unix&quot;&gt;chain-loading&lt;&#x2F;a&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		Set a variable for the currently running shell
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;export TZ=UTC&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;declare -x TZ=UTC&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h3 id=&quot;persisting-environment-variables&quot;&gt;Persisting Environment Variables&lt;&#x2F;h3&gt;
&lt;p&gt;For permanently setting some environment variables there are a number of options (Options further up usually can override the ones below them).&lt;&#x2F;p&gt;




	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;.bashrc&lt;&#x2F;code&gt;, &lt;code&gt;.zshrc&lt;&#x2F;code&gt;, etc.
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Read whenever you start your favourite shell (as a non-login shell), but don&#x27;t assume it has effects on the whole session, it is not made for that.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		Your Desktop Environment
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Desktops like setting environment variables derived from their settings, sometimes for single programs, sometimes for the whole session.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;.profile&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Read on every login (your login manager is responsible for doing this) and applies to your whole session.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;&#x2F;etc&#x2F;profile.d&#x2F;&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;etc&#x2F;profile&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		System-wide &lt;code&gt;.profile&lt;&#x2F;code&gt; equivalent, remember that you are sharing this one with your packages.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		PAM
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;pam&quot;&gt;PAM&lt;&#x2F;a&gt; also sets environment variables.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;The &lt;code&gt;.bashrc&lt;&#x2F;code&gt; (plus friends) and &lt;code&gt;.profile&lt;&#x2F;code&gt; can be reloaded by running &lt;code&gt;source ~&#x2F;&amp;lt;filename&amp;gt;&lt;&#x2F;code&gt; or &lt;code&gt;. ~&#x2F;.filename&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Non POSIX shells usually have their own &lt;code&gt;.profile&lt;&#x2F;code&gt; equivalent, keep that in mind when changing your login shell. Bash for example uses &lt;code&gt;.bash_profile&lt;&#x2F;code&gt; if it exists.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;spying-on-other-processes&quot;&gt;Spying on other Processes&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes it is useful to know what environment variables a given running process has currently set, if the process belongs to you or you have root rights (use them responsibly) you have access to the file that contains the process environment.&lt;&#x2F;p&gt;
&lt;p&gt;The files path is &lt;code&gt;&#x2F;proc&#x2F;$pid&#x2F;environ&lt;&#x2F;code&gt; (Substitute &lt;code&gt;$pid&lt;&#x2F;code&gt; for the process id), it contains the null separated environment variables.&lt;&#x2F;p&gt;
&lt;p&gt;To get them in a pretty way one can use the command &lt;code&gt;tr &#x27;\0&#x27; &#x27;\n&#x27; &amp;lt; &#x2F;proc&#x2F;$pid&#x2F;environ&lt;&#x2F;code&gt; (pipe it into the tr command which replaces the null separators with newlines).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;htop&lt;&#x2F;code&gt; shows the selected processes environment when pressing &lt;kbd&gt;e&lt;&#x2F;kbd&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; This is the reason why it usually is a bad idea to use environment variables for secrets, they can be read out by any other process running under the same user. When transporting secrets from one program to another use pipes and features of your shell to directly read from and write to them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-documentation&quot;&gt;Finding Documentation&lt;&#x2F;h2&gt;
&lt;p&gt;Outside of the usual online sources: Read the documentation and read the manpages. Most manpages have an &lt;code&gt;ENVIRONMENT&lt;&#x2F;code&gt; section describing which variables the program reads and&#x2F;or sets.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;man.voidlinux.org&amp;#x2F;environ&quot; &gt;
		environ(7) - The manpage about the basics of environment variables.
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linux-and-posix&quot;&gt;Linux and Posix&lt;&#x2F;h2&gt;
&lt;p&gt;You can find a more complete list of the standardised variables in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9799919799&#x2F;basedefs&#x2F;V1_chap08.html&quot;&gt;POSIX (2024, the latest at the time of writing) specification on Environment Variables&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;




	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;HOME&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Contains the path to your home directory, as simple as that. (Don&#x27;t abuse for constructs like &lt;code&gt;$HOME&#x2F;.config&#x2F;whatever&lt;&#x2F;code&gt;, that&#x27;s what the XDG home variables are for.)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;PATH&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Contains a colon separated list of paths to directories that contain binary files for running them as commands. Directories closer to the front can override others counting binaries of the same name further back.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;USER&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Should contain the currently logged in username. (Fun fact: the kernel doesn&#x27;t know your username)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;SHELL&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Contains the path to the shell binary configured for the current user, this is probably how your favourite terminal emulator knows about your favourite shell without configuration. This may or may not be the shell you are currently using.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;TMPDIR&lt;&#x2F;code&gt; or &lt;code&gt;TMP&lt;&#x2F;code&gt; or &lt;code&gt;TEMP&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Almost always one of them contains a path to the preferred temporary directory. Useful for when every user gets their own directory with proper permissions. &lt;code&gt;TMPDIR&lt;&#x2F;code&gt; is the one in the POSIX standard and should be the preferred one.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;LC_*&lt;&#x2F;code&gt;, &lt;code&gt;LANGUAGE&lt;&#x2F;code&gt;, &lt;code&gt;LANG&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These contain locale information and are the reason why language settings work across desktop environments. Unfortunately also the reason why you have to restart applications after changing system preferences. For possible values see &lt;code&gt;&#x2F;etc&#x2F;locale.gen&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;etc&#x2F;locale.conf&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Set &lt;code&gt;LANG&lt;&#x2F;code&gt; to &lt;code&gt;C&lt;&#x2F;code&gt; for &quot;no translation at all&quot; usually that results in some form of English.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Standardized in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9799919799&#x2F;basedefs&#x2F;V1_chap08.html#tag_08_02&quot;&gt;POSIX specification on Internationalization Variables&lt;&#x2F;a&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;TZ&lt;&#x2F;code&gt; and &lt;code&gt;TZDIR&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These describe the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tzset#TZ&quot;&gt;current timezone to use&lt;&#x2F;a&gt; i.e. &lt;code&gt;Europe&#x2F;Berlin&lt;&#x2F;code&gt;. Usually points to a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tzfile&quot;&gt;tzfile&lt;&#x2F;a&gt; in &lt;code&gt;&#x2F;usr&#x2F;share&#x2F;zoneinfo&#x2F;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;PAGER&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		A program that can be run using &lt;code&gt;sh -c&lt;&#x2F;code&gt; that shows a textfile (unually in the current terminal)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;EDITOR&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Like &lt;code&gt;PAGER&lt;&#x2F;code&gt;, but for your favourite text editor.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;BROWSER&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Like &lt;code&gt;PAGER&lt;&#x2F;code&gt;, but for your favourite browser. (Not standardised anywhere, but a well known convention)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;MAILER&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Like &lt;code&gt;PAGER&lt;&#x2F;code&gt;, but for sending E-Mail using a program that is compatible with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pubs.opengroup.org&#x2F;onlinepubs&#x2F;9699919799&#x2F;utilities&#x2F;mailx.html&quot;&gt;&lt;code&gt;mailx&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, originally intended to allow a custom implementation of &lt;code&gt;&#x2F;bin&#x2F;mail&lt;&#x2F;code&gt; on early unixoids. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mastodon.social&#x2F;@inawhilecrocodile&#x2F;115435886425492406&quot;&gt;Thank you to inawhilecrocodile for the reasearch!&lt;&#x2F;a&gt; (It was never standardised)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Contrary to what this page previously stated it does &lt;strong&gt;not&lt;&#x2F;strong&gt; take URLs as argument.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;TERM&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Contains the name of the terminal, together with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;terminfo&quot;&gt;terminfo&lt;&#x2F;a&gt; database the capabilities of the terminal can be found out. When remoting into other machines with a less well known terminal &lt;code&gt;xterm&lt;&#x2F;code&gt; is usually a sane fallback.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;MOTD_SHOWN&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		When set it indicates who has already shown the motd to prevent showing it twice. Convention, probably best known implementation is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;man8&#x2F;pam_motd.8&quot;&gt;pam motd module&lt;&#x2F;a&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;NO_COLOR&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		When set to a non-empty string Software shouldn&#x27;t use ANSI-colors unless &lt;strong&gt;explicity&lt;&#x2F;strong&gt; configured to do so. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;no-color.org&#x2F;&quot;&gt;See no-color.org&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; What is meant by run with &lt;code&gt;sh -c&lt;&#x2F;code&gt; is demonstrated pretty well by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;salsa.debian.org&#x2F;debian&#x2F;sensible-utils&#x2F;-&#x2F;blob&#x2F;b555a8db938946c519db3d6d2a25cbe2a39945d2&#x2F;sensible-editor.in#L24&quot;&gt;debians sensible-utils&lt;&#x2F;a&gt;. In a nutshell you lauch your favorite &lt;code&gt;EDITOR&lt;&#x2F;code&gt; using &lt;code&gt;sh -c &quot;$EDITOR \&quot;\$@\&quot;&quot; EDITOR &amp;lt;filepath-goes-here&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; I&#x27;m trying to move the &lt;code&gt;BROWSER&lt;&#x2F;code&gt; and &lt;code&gt;MAILER&lt;&#x2F;code&gt; variables to the XDG section. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;lists.freedesktop.org&#x2F;archives&#x2F;xdg&#x2F;2023-October&#x2F;014662.html&quot;&gt;See the related discussion on the xdg mailing list.&lt;&#x2F;a&gt; You&#x27;ll have to dig around a bit to find all mails 😞.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xdg-freedesktop-org&quot;&gt;XDG freedesktop.org&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;wiki&#x2F;&quot;&gt;freedesktop.org&lt;&#x2F;a&gt; hosts quite a few specifications ensuring interoperability of free (software) desktop envoirnments, these specifications happen to contain quite a lot of envoirnment variables.&lt;&#x2F;p&gt;
&lt;p&gt;XDG stands for Cross Desktop Group.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;base-directories&quot;&gt;Base Directories&lt;&#x2F;h3&gt;
&lt;p&gt;These are defines in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;wiki&#x2F;Specifications&#x2F;basedir-spec&#x2F;&quot;&gt;Desktop Base Directories Specification&lt;&#x2F;a&gt;, while the below is an overview and you should always read the specification.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; while one can usually guess where those directories are, it is &lt;em&gt;always&lt;&#x2F;em&gt; a good idea to respect the environment variables instead of blindly writing to some guessed default path, People trying to organise their Home folder will thank you.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;XDG_DATA_HOME&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Path where applications can dump their non-configuration and non-cache persistence.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Default: &lt;code&gt;$HOME&#x2F;.local&#x2F;share&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_CONFIG_HOME&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Path for storing configuration files (and &lt;em&gt;nothing&lt;&#x2F;em&gt; else!)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Default: &lt;code&gt;$HOME&#x2F;.config&#x2F;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_DATA_DIRS&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		colon &lt;code&gt;:&lt;&#x2F;code&gt; separated list of fallback directories for &lt;code&gt;XDG_DATA_HOME&lt;&#x2F;code&gt; containing default data files. (similar to how &lt;code&gt;$PATH&lt;&#x2F;code&gt; works)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Default: &lt;code&gt; &#x2F;usr&#x2F;local&#x2F;share&#x2F;:&#x2F;usr&#x2F;share&#x2F;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_CONFIG_DIRS&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		colon &lt;code&gt;:&lt;&#x2F;code&gt; separated list of fallback directories for &lt;code&gt;XDG_CONFIG_HOME&lt;&#x2F;code&gt; containing default configuration files. (similar to how &lt;code&gt;$PATH&lt;&#x2F;code&gt; works). This behaviour is very useful when administrating large desktop systems.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Default: &lt;code&gt;&#x2F;etc&#x2F;xdg&#x2F;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_CACHE_HOME&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Path for storing cache files, may contain files specific to the current architecture details, may need cleaning up when on a shared filesystem.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Also be used for files that better get lost rather than ending up in a backup by accident, &lt;code&gt;keepassxc&lt;&#x2F;code&gt; is an example for that.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Default: &lt;code&gt;$HOME&#x2F;.cache&#x2F;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_RUNTIME_DIR&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		For temporary runtime files like sockets, pipes, etc.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Usually: &lt;code&gt;&#x2F;run&#x2F;user&#x2F;&amp;lt;userid&amp;gt;&#x2F;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h3 id=&quot;user-directories&quot;&gt;User Directories&lt;&#x2F;h3&gt;
&lt;p&gt;There is also the possibility to define User directories, these have the form of &lt;code&gt;XDG_&amp;lt;name&amp;gt;_DIR&lt;&#x2F;code&gt; and are configured using the &lt;code&gt;$XDG_CONFIG_HOME&#x2F;user-dirs.dirs&lt;&#x2F;code&gt; and taken care of by the &lt;code&gt;xdg-user-dirs-update&lt;&#x2F;code&gt; utility&lt;&#x2F;p&gt;
&lt;p&gt;Commonly specified ones are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DESKTOP&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DOWNLOAD&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;TEMPLATES&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;PUBLICSHARE&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DOCUMENTS&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;MUSIC&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;PICTURES&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;VIDEOS&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SCREENSHOTS&lt;&#x2F;code&gt; - Used by some popular screenshot scripts&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;current-desktop&quot;&gt;Current Desktop&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;specifications.freedesktop.org&#x2F;desktop-entry-spec&#x2F;desktop-entry-spec-latest.html#recognized-keys&quot;&gt;Freedesktop &quot;Desktop Entry Specification&quot;&lt;&#x2F;a&gt; specifies a &lt;code&gt;XDG_CURRENT_DESKTOP&lt;&#x2F;code&gt; variable that is set from the &lt;code&gt;DesktopNames&lt;&#x2F;code&gt; value in desktops session file (the ones in &lt;code&gt;&#x2F;usr&#x2F;share&#x2F;xsessions&#x2F;&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;usr&#x2F;share&#x2F;wayland-sessions&#x2F;&lt;&#x2F;code&gt; and whatever &lt;code&gt;XDG_DATA_DIRS&lt;&#x2F;code&gt; points to).&lt;&#x2F;p&gt;
&lt;p&gt;It contains a colon separated list of names for the current desktop, primarily intended for activating or deactivating desktop entries (i.e. you don&#x27;t want the gnome settings cluttering up you KDE menus and vice versa).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;xdg-session&quot;&gt;XDG Session&lt;&#x2F;h3&gt;
&lt;p&gt;These variables are &lt;em&gt;not&lt;&#x2F;em&gt; part of a specification, the best source for them is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;wiki&#x2F;Software&#x2F;systemd&#x2F;writing-display-managers&#x2F;&quot;&gt;guide for &quot;Writing Display Managers&quot; with systemd&lt;&#x2F;a&gt; and the manpage for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;systemd&#x2F;man&#x2F;pam_systemd.html&quot;&gt;&lt;code&gt;pam_systemd&lt;&#x2F;code&gt; module&lt;&#x2F;a&gt;. Some of them happen to be useful.&lt;&#x2F;p&gt;




	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;XDG_SEAT&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		By definition set to &lt;code&gt;seat0&lt;&#x2F;code&gt;, probably reserved for future use in multiseat scenarios.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_SESSION_TYPE&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The best documentation for this one is probably the &lt;code&gt;type&lt;&#x2F;code&gt; argument for the pam_systemd module, roughly it is the display server used for the session. (&lt;code&gt;x11&lt;&#x2F;code&gt;,&lt;code&gt;wayland&lt;&#x2F;code&gt;,&lt;code&gt;mir&lt;&#x2F;code&gt;,&lt;code&gt;tty&lt;&#x2F;code&gt;,&lt;code&gt;unknown&lt;&#x2F;code&gt;)
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_SESSION_CLASS&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		either &lt;code&gt;user&lt;&#x2F;code&gt; or &lt;code&gt;greeter&lt;&#x2F;code&gt; depending on whether the session is primarily logged in or for logging in.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_VTNR&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		set to the number of the TTY the current session runs in.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;code&gt;XDG_SESSION_ID&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Either the &lt;code&gt;&#x2F;proc&#x2F;self&#x2F;sessionid&lt;&#x2F;code&gt; of the auditing session or an &quot;independent counter&quot;.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;graphical-environment&quot;&gt;Graphical Environment&lt;&#x2F;h2&gt;




	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;DISPLAY&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The id of your X-Display, on your laptop it is probably &lt;code&gt;:0&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;WAYLAND_DISPLAY&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The name of your wayland socket file in &lt;code&gt;$XDG_RUNTIME_DIR&#x2F;&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;XCURSOR_SIZE&lt;&#x2F;code&gt;, &lt;code&gt;XCURSOR_THEME&lt;&#x2F;code&gt;, &lt;code&gt;XCURSOR_PATH&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		One way to configure how your cursor looks in most applications. It even works with wayland for when other options are not available. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Cursor_themes&quot;&gt;The Arch Wiki has more information on cursor configuration&lt;&#x2F;a&gt;.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		&lt;code&gt;DBUS_SESSION_BUS_ADDRESS&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Contains information on how to connect to the dbus session bus. Usually set by the &lt;code&gt;dbus-run-session&lt;&#x2F;code&gt; wrapper.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;mozilla&quot;&gt;Mozilla&lt;&#x2F;h2&gt;
&lt;p&gt;These are used for Firefox, Thunderbird and other programs that are built on top of Firefox.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;MOZ_ENABLE_WAYLAND&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		If set it enables wayland support for all mozilla programs (if not already enabled by default) typically set to &lt;code&gt;1&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;java&quot;&gt;Java&lt;&#x2F;h2&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;_JAVA_AWT_WM_NONREPARENTING&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Tells java if you have a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Re-parenting_window_manager&quot;&gt;non-reparenting window manager&lt;&#x2F;a&gt;, usually set to 0 on modern Xorg, to 1 on wayland. If your window stays blank that is an indicator this one is wrong. (Yes the underscore at the start is intentional.)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		Possible Values: &lt;code&gt;0&lt;&#x2F;code&gt;, &lt;code&gt;1&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;More Java environment variables will be added when I run into them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kubernetes&quot;&gt;Kubernetes&lt;&#x2F;h2&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		&lt;code&gt;KUBECONFIG&lt;&#x2F;code&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		The path to a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;docs&#x2F;concepts&#x2F;configuration&#x2F;organize-cluster-access-kubeconfig&#x2F;&quot;&gt;yaml file containing connection information for a Kubernetes cluster&lt;&#x2F;a&gt; that tools like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;docs&#x2F;reference&#x2F;kubectl&#x2F;&quot;&gt;&lt;code&gt;kubectl&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;helm.sh&quot;&gt;&lt;code&gt;helm&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; can use to connect to the cluster.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		k3s generates a &lt;code&gt;&#x2F;etc&#x2F;rancher&#x2F;k3s&#x2F;k3s.yaml&lt;&#x2F;code&gt; file you can point this at.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Fontconfig</title>
        <published>2023-06-20T00:00:00+00:00</published>
        <updated>2024-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/fontconfig/"/>
        <id>https://slatecave.net/notebook/fontconfig/</id>
        
        <summary type="text">Some knowledge that makes your life easier when working with fonts on Linux.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/fontconfig/">&lt;h2 id=&quot;what-is-fontconfig&quot;&gt;What is Fontconfig?&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Fontconfig is a library for configuring and customising font access.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It is built into almost every program that runs on Linux and has a GUI (even in into old java software!) and makes it very easy to make configure fonts and then forget about it.&lt;&#x2F;p&gt;
&lt;p&gt;You can find the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;wiki&#x2F;Software&#x2F;fontconfig&#x2F;&quot;&gt;Fontconfig documentation over on freedesktop.org&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fontconfig-cli-tools&quot;&gt;Fontconfig CLI Tools&lt;&#x2F;h2&gt;
&lt;p&gt;You average Linux distribution ships Fontconfig along with some commands to poke it.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-cache&quot;&gt;fc-cache&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		for rebuilding the Fontconfig cache (after installing a font or changing configuration).&lt;br&gt;Usually used like this: &lt;code&gt;fc-cache -f -v&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-conflist&quot;&gt;fc-conflist&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		gives you a list of configuration files found by Fontconfig.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-match&quot;&gt;fc-match&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		for looking up which exact font a given name resolves to, &lt;em&gt;very&lt;&#x2F;em&gt; useful for debugging.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-query&quot;&gt;fc-query&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		to print out metadata for a font file.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-validate&quot;&gt;fc-validate&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		can give a hint abut missing glyphs in a font file for a given language.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-cat&quot;&gt;fc-cat&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		for having a look at the Fontconfig cache.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-list&quot;&gt;fc-list&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		to list all fonts Fontconfig knows about.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-pattern&quot;&gt;fc-pattern&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		helps you by parsing &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;FcPatternFormat&quot;&gt;Fontconfig patterns&lt;&#x2F;a&gt; , useful for debugging.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;fc-scan&quot;&gt;fc-scan&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		similar to &lt;code&gt;fc-query&lt;&#x2F;code&gt; but has the same output format as &lt;code&gt;fc-pattern&lt;&#x2F;code&gt;.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;font-family-names&quot;&gt;Font (Family) Names&lt;&#x2F;h2&gt;
&lt;p&gt;What one usually calls the fonts name actually is the font family name. This is because of historical reasons from back when a font was a case of lead letters for printing and one needed an extra case full of letters for the bold or italic styles.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;family&lt;&#x2F;code&gt; name is usually what is accepted whenever you have some configuration file and it wants a font name. Usually the postscript name works too. Both can be found out using &lt;code&gt;fc-query&lt;&#x2F;code&gt; on a given font file. &lt;code&gt;fc-list&lt;&#x2F;code&gt; also shows the family name by default.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; &lt;code&gt;fc-query -b&lt;&#x2F;code&gt; omits language and character set information resulting in a more readable output.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Fontconfig also has a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;fontconfig&#x2F;fontconfig-user.html#AEN36&quot;&gt;specific font name&lt;&#x2F;a&gt; that includes the family name, size, style and every other possible font setting.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;system-fonts&quot;&gt;System Fonts&lt;&#x2F;h2&gt;
&lt;p&gt;System fonts using Fontconfig are just configuration aliasing generic names to your favourite font.&lt;&#x2F;p&gt;
&lt;p&gt;The most common are &lt;code&gt;monopace&lt;&#x2F;code&gt;, &lt;code&gt;sans&lt;&#x2F;code&gt; or &lt;code&gt;sans-serif&lt;&#x2F;code&gt; and &lt;code&gt;serif&lt;&#x2F;code&gt;. If your desktop environment has a font preference dialog in the system settings it is changing which font names those aliases point to.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; There is also a convention to alias &lt;code&gt;emoji&lt;&#x2F;code&gt; to your preferred emoji font.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-fonts-that-support-a-codepoint&quot;&gt;Finding Fonts that Support a Codepoint&lt;&#x2F;h2&gt;
&lt;p&gt;To query fonts that support a given character, you need to know its codepoint.&lt;&#x2F;p&gt;
&lt;p&gt;For the following examples I&#x27;ll use the 😃 emoji which has the codepoint &lt;code&gt;U+1f603&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you have a unicode aware &lt;code&gt;printf&lt;&#x2F;code&gt; command (if you don&#x27;t know simply try):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; %x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;😃&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which outputs &lt;code&gt;1f603&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There is also the possibility to use the &lt;code&gt;uni&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;uni&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; identify&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 😃&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It also lists &lt;code&gt;U+1F603&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;







	
		
		
		
		
		
			
			
		
	

	
		
	


	
&lt;div class=&quot;chat-box&quot;&gt;
	&lt;img src=&quot;&amp;#x2F;resources&amp;#x2F;emoji&amp;#x2F;neofox&amp;#x2F;neofox_laptop.png&quot; alt=&quot;Less techy neofox says:&quot; class=&quot;chat-avatar&quot; width=&quot;64&quot; height=&quot;64&quot;&gt;
	&lt;blockquote&gt;
&lt;p&gt;You could also look it up using a search engine, Wikipedia or one of those Emoji lookup sites.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;

&lt;&#x2F;div&gt;



&lt;hr &#x2F;&gt;
&lt;p&gt;You have the codepoint? Great, now you can ask the &lt;code&gt;fc-list&lt;&#x2F;code&gt; command (replace the example &lt;code&gt;1f603&lt;&#x2F;code&gt; with the codepoint you are interested in.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;fc-list&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; :charset=1f603&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should get a list of all fonts on your system that support that codepoint, if that codepoint isn&#x27;t supported by a font on your system the output stays empty.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuration-files&quot;&gt;Configuration Files&lt;&#x2F;h2&gt;
&lt;p&gt;You can find your Fontconfig configuration file in &lt;code&gt;$XDG_CONFIG_DIR&#x2F;fontconfig&lt;&#x2F;code&gt; which in most cases is &lt;code&gt;~&#x2F;.config&#x2F;fontconfig&#x2F;&lt;&#x2F;code&gt;. In there you can either directly edit the &lt;code&gt;fonts.conf&lt;&#x2F;code&gt; file or a file in the &lt;code&gt;conf.d&lt;&#x2F;code&gt; folder.&lt;&#x2F;p&gt;
&lt;p&gt;Global Configuration is in &lt;code&gt;&#x2F;etc&#x2F;fonts&#x2F;&lt;&#x2F;code&gt;. It usually consists of files linked from &lt;code&gt;&#x2F;usr&#x2F;share&#x2F;fontconfig&#x2F;&lt;&#x2F;code&gt; where configuration snippets for common settings are installed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;using-predefined-configuration&quot;&gt;Using Predefined Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;fc-conflist will list all configuration files for fontconfig, the active ones prefixed with &lt;code&gt;+&lt;&#x2F;code&gt; the inactive ones in &lt;code&gt;&#x2F;usr&#x2F;share&#x2F;fontconfig&#x2F;&lt;&#x2F;code&gt; prefixed with a &lt;code&gt;-&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To use the predefined configuration symlink it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ln&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;usr&#x2F;share&#x2F;fontconfig&#x2F;conf.avail&#x2F;70-no-bitmaps.conf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; &#x2F;etc&#x2F;fonts&#x2F;conf.d&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Regenerate the fonconfig cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;fc-cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;fv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.voidlinux.org&#x2F;config&#x2F;graphical-session&#x2F;fonts.html&quot;&gt;Void Linux Documentation on Fonts&lt;&#x2F;a&gt; gives a similar example on linking the &lt;code&gt;70-no-bitmaps.conf&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;etc&#x2F;fonts&#x2F;conf.d&#x2F;&lt;&#x2F;code&gt; to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;void-linux&#x2F;void-packages&#x2F;issues&#x2F;22477&quot;&gt;mitigate the common issue that Firefox picks pixelated bitmap fonts&lt;&#x2F;a&gt; over higher quality ones.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;writing-custom-configuration&quot;&gt;Writing Custom Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;To make a valid Fontconfig configuration file it needs some &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;fontconfig&#x2F;fontconfig-user.html#AEN53&quot;&gt;XML scaffolding&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; version&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;DOCTYPE&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; fontconfig&lt;&#x2F;span&gt;&lt;span&gt; SYSTEM &amp;quot;urn:fontconfig:fonts.dtd&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;fontconfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;	&amp;lt;!--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; actual configuration goes here &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;fontconfig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That scaffold can now be filled with some rules.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; In case you are in need of an example, have a look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;fontconfig&#x2F;fontconfig-user.html#AEN252&quot;&gt;Fontconfig documentation examples&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;slatian&#x2F;dotfiles&#x2F;src&#x2F;branch&#x2F;main&#x2F;.config&#x2F;fontconfig&quot;&gt;my Fontconfig&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Those rule could be disabling fonts without having to uninstall them, useful when one doesn&#x27;t have root access or wants to keep the font files for some reason.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example rule for disabling FontAwesome to prevent it from interfering with other icon-fonts.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;selectfont&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rejectfont&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;pattern&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;			&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;patelt&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;FontAwesome&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;patelt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;pattern&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;		&amp;lt;!--&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; More pattern instances for other fonts can go here &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;--&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;rejectfont&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;selectfont&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;Another application is to configure the system fonts mentioned before using &lt;code&gt;alias&lt;&#x2F;code&gt; rules. For setting the &lt;code&gt;emoji&lt;&#x2F;code&gt; (or any other) font one simply maps the family name &lt;code&gt;emoji&lt;&#x2F;code&gt; to the family name of the preferred font.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example rule for aliasing &lt;code&gt;emoji&lt;&#x2F;code&gt; to &lt;code&gt;Twemoji&lt;&#x2F;code&gt;.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;prefer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Twemoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;prefer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	&lt;figcaption&gt;The same mechanism could be used to alias something like &lt;code&gt;Helvetica&lt;&#x2F;code&gt; to your favourite sans font family.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;The &lt;code&gt;prefer&lt;&#x2F;code&gt; part of the alias also accepts multiple font families, this can be used to apply the &lt;code&gt;emoji&lt;&#x2F;code&gt; alias to system fonts by telling Fontconfig to prefer your favourite monospace, sans or serif font &lt;b&gt;and&lt;&#x2F;b&gt; whatever is aliased to &lt;code&gt;emoji&lt;&#x2F;code&gt; over all other installed fonts.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;monospace&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;prefer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Noto Sans Mono&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;		&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;emoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;family&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;prefer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;alias&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course there are more applications for Fontconfig configurations, but those probably deserve more specific pages.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; I&#x27;m using Twemoji and Noto Sans, not because I like the companies that made them, but because they are under a permissive license are mostly complete, look okay and are one of the very few things those companies are actually doing good for humanity.&lt;&#x2F;p&gt;
&lt;p&gt;There are community made fonts like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rsms.me&#x2F;inter&#x2F;&quot;&gt;Inter&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;openmoji.org&#x2F;&quot;&gt;OpenMoji&lt;&#x2F;a&gt; (plus some more) out there with an impressive coverage and feature set that shouldn&#x27;t go unmentioned here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-fonts&quot;&gt;Installing fonts&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;from-packages&quot;&gt;From packages&lt;&#x2F;h3&gt;
&lt;p&gt;Usually the packages do everything for you and even install some sane Fontconfig rules.&lt;&#x2F;p&gt;
&lt;p&gt;If they don&#x27;t, have a look at the Fontconfig files they install and check if they clash with your own configuration or if the package description, documentation or comment in its Fontconfig file mentions additional required configuration. This is usually the case for emoji fonts to get them as the default font.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;from-files&quot;&gt;From files&lt;&#x2F;h3&gt;
&lt;p&gt;In case you have a modern Linux distribution you can install a font by dropping the ttf or otf file into &lt;code&gt;~&#x2F;.local&#x2F;share&#x2F;fonts&#x2F;&lt;&#x2F;code&gt; or &lt;code&gt;~&#x2F;.fonts&#x2F;&lt;&#x2F;code&gt;, the latter works on older distributions too.&lt;&#x2F;p&gt;
&lt;p&gt;To apply the changes run &lt;code&gt;fc-cache -f -v&lt;&#x2F;code&gt; to rebuild the Fontconfig cache and restart your applications (or log out and back in).&lt;&#x2F;p&gt;
&lt;p&gt;Before restarting applications you could verify that the font was installed using the &lt;code&gt;fc-match&lt;&#x2F;code&gt; and &lt;code&gt;fc-list&lt;&#x2F;code&gt; commands.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;converting-woff2-to-ttf&quot;&gt;Converting woff2 to ttf&lt;&#x2F;h4&gt;
&lt;p&gt;Google (who else 🙄) made a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;woff2&quot;&gt;tool for converting woff2 fonts to ttf and back&lt;&#x2F;a&gt;, the package containing it is simply called &lt;code&gt;woff2&lt;&#x2F;code&gt; in most Linux distributions.&lt;&#x2F;p&gt;
&lt;p&gt;It contains the &lt;code&gt;woff2_decompress&lt;&#x2F;code&gt; command, give it a path to a woff2 font file and it will convert it to ttf. There is also a &lt;code&gt;woff2_compress&lt;&#x2F;code&gt; that works in the other direction.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ANSI Escape Sequences</title>
        <published>2023-05-28T00:00:00+00:00</published>
        <updated>2024-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/ansi-escape-sequences/"/>
        <id>https://slatecave.net/notebook/ansi-escape-sequences/</id>
        
        <summary type="text">The things that make your Terminal colourful</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/ansi-escape-sequences/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ANSI_escape_code&quot;&gt;ANSI Escape sequences&lt;&#x2F;a&gt; are some standardised byte sequences that make most Terminals do some thing other than just printing characters on screen. Like printing colourful characters!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-ansi-escape-sequences&quot;&gt;Using ANSI-Escape Sequences&lt;&#x2F;h2&gt;
&lt;p&gt;ANSI-Escape sequences can be used by writing an ASCII-Escape characters followed by some instructions to your Programs standard output or standard error.&lt;&#x2F;p&gt;
&lt;p&gt;The codes can be produced by any string escaping mechanism. In proper programming and scripting languages the syntax for the escape character in double quoted strings is usually &lt;code&gt;\x1b&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The shell being a bit different you should use either &lt;code&gt;printf&lt;&#x2F;code&gt; or &lt;code&gt;echo -e&lt;&#x2F;code&gt;. While most systems support both the chance of &lt;code&gt;printf&lt;&#x2F;code&gt; being supported is usually higher.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-ansi-escape-sequences-responsibly&quot;&gt;Using ANSI-Escape Sequences Responsibly&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;b&gt;While colors and text effects are pretty:&lt;&#x2F;b&gt; You should consider the cases where they shouldn&#x27;t be enabled and respect user choices.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Disable color output by default when the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;no-color.org&quot;&gt;&lt;code&gt;NO_COLOR&lt;&#x2F;code&gt; environment variable is non-empty&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Disable use of escape codes by default when the output isn&#x27;t a terminal.&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t overuse color, it gets confusing pretty quickly.&lt;&#x2F;li&gt;
&lt;li&gt;Make sure no information gets lost when disabling escape codes.
&lt;ul&gt;
&lt;li&gt;Does using grep on the output work to find information?&lt;&#x2F;li&gt;
&lt;li&gt;Does piping it into &lt;code&gt;espeak-ng&lt;&#x2F;code&gt; give a sensible result?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When writing &lt;q&gt;by default&lt;&#x2F;q&gt; that means unless &lt;strong&gt;explicitly&lt;&#x2F;strong&gt; requested (i.e. through a &lt;code&gt;--color always&lt;&#x2F;code&gt; CLI option).&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;seirdy.one&amp;#x2F;posts&amp;#x2F;2022&amp;#x2F;06&amp;#x2F;10&amp;#x2F;cli-best-practices&amp;#x2F;&quot; &gt;
		Seirdy about &lt;q&gt;Best practices for inclusive CLIs&lt;&#x2F;q&gt;.
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Thank you to Seirdy!&lt;&#x2F;b&gt; Most of the above is a summarized and filtered TL;DR of Seirdys article, you should definitely read it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-text-color-and-effects&quot;&gt;Setting Text Color and Effects&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ll focus on Select Graphic Rendition (SGR) codes here, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ANSI_escape_code#CSIsection&quot;&gt;Wikipedia has a more complete list&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example for the shell which prints out &lt;q&gt;_FOOBAR_&lt;&#x2F;q&gt; in bright (&lt;code&gt;01&lt;&#x2F;code&gt;) red (&lt;code&gt;31&lt;&#x2F;code&gt;). After that, it resets to default settings (&lt;code&gt;00&lt;&#x2F;code&gt;) and prints a newline character (&lt;code&gt;\n&lt;&#x2F;code&gt;)&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\033[01;31m_FOOBAR_\033[00m\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; With %s placeholder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;\033[01;31m%s\033[00m\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;_FOOBAR_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;As you can see in the example, multiple escape-codes can be chained in one sequence by delimiting them with a &lt;code&gt;;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;\033&lt;&#x2F;code&gt; part will turn into an ASCII escape character, the &lt;code&gt;[&lt;&#x2F;code&gt; tells the terminal that this is an ANSI Control Sequence Initiator (CSI) after that can come one or more codes. The sequence is finished by an &lt;code&gt;m&lt;&#x2F;code&gt; to tell the terminal that everything between the &lt;abbr title=&quot;Control Sequence Initiator&quot;&gt;CSI&lt;&#x2F;abbr&gt; and it are &lt;abbr title=&quot;Select Graphic Rendition&quot;&gt;SGR&lt;&#x2F;abbr&gt; codes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on the &lt;code&gt;\033&lt;&#x2F;code&gt; and compatibility:&lt;&#x2F;b&gt; The &lt;code&gt;\033&lt;&#x2F;code&gt; is the octal representation of the Escape ASCII-Character and is the most widely supported one across &lt;code&gt;printf&lt;&#x2F;code&gt; implementations. (The dash printf implementation for example doesn&#x27;t support hexadecimal representation.)&lt;&#x2F;p&gt;
&lt;table&gt;
&lt;caption&gt;Most commonly used codes&lt;&#x2F;caption&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;&#x2F;th&gt;
&lt;th&gt;Code to reverse&lt;&#x2F;th&gt;
&lt;th&gt;Effect&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;00&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Reset all effects&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;3&quot; class=&quot;table-subheading&quot;&gt;Foreground color&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;30-37&lt;&#x2F;td&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;Set the Foreground color&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;90-97&lt;&#x2F;td&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;Set the Foreground color, bright variation&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;3&quot; class=&quot;table-subheading&quot;&gt;Background color&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;40-47&lt;&#x2F;td&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;td&gt;Set the Background color&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;100-107&lt;&#x2F;td&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;td&gt;Set the Background color, bright variation&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;3&quot; class=&quot;table-subheading&quot;&gt;Font effects&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;01&lt;&#x2F;td&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;Bright text (usually bold and brighter color)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;02&lt;&#x2F;td&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;Dim text (usually only effect on color)&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;03&lt;&#x2F;td&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;Italic text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;04&lt;&#x2F;td&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;Underlined text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;05&lt;&#x2F;td&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;Blinking text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;07&lt;&#x2F;td&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;Reverse foreground and background color&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;08&lt;&#x2F;td&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;Concealed&#x2F;Hidden text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;09&lt;&#x2F;td&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;Strikethrough text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The leading zeros are not needed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;colors&quot;&gt;Colors&lt;&#x2F;h3&gt;
&lt;p&gt;You may have noticed that the &lt;code&gt;3x&lt;&#x2F;code&gt;, &lt;code&gt;4x&lt;&#x2F;code&gt;, &lt;code&gt;9x&lt;&#x2F;code&gt;, and &lt;code&gt;10x&lt;&#x2F;code&gt; family of codes all use the last digit in the range from 0 to 7 as a color parameter.&lt;&#x2F;p&gt;
&lt;table&gt;
&lt;caption&gt;Table of colors&lt;&#x2F;caption&gt;
&lt;tr&gt;&lt;th&gt;Code&lt;&#x2F;th&gt;&lt;th&gt;Color&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;Black or Dark Grey&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;Red&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;Green&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Yellow&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;Blue&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;Violet &#x2F; Purple&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;Cyan or Turquoise&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;Light Grey or White&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;Please keep in mind that different people have different color palettes when you want to write reusable scripts.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Shell Null Termination &#x2F; Separation</title>
        <published>2023-05-27T00:00:00+00:00</published>
        <updated>2025-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/shell-null-termination/"/>
        <id>https://slatecave.net/notebook/shell-null-termination/</id>
        
        <summary type="text">What is null termination, why and how to use it in shell pipelines.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/shell-null-termination/">&lt;p&gt;Null or zero termination or separation is when one uses a null byte to separate records, which is different from the newline usually used in shell pipelines.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why&quot;&gt;Why&lt;&#x2F;h2&gt;
&lt;p&gt;Usually operating things by a newline is good enough and easy to debug, but even a little shell pipeline like a &lt;code&gt;ls | sort&lt;&#x2F;code&gt; can blow up when it encounters unexpected data like a filename that contains a newline character.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Fun fact:&lt;&#x2F;b&gt; Most filesystems actually allow you to use all kinds of characters from emoji to non-printables and control characters. Including newlines. One could even put ASCII-art in a filename (I&#x27;ve already done that)!&lt;&#x2F;p&gt;
&lt;p&gt;Using a null character saves you there as it is the only character guaranteed to never occur inside a filename and this becomes more important with other sources of (untrusted) input.&lt;&#x2F;p&gt;
&lt;p&gt;The improved version would be &lt;code&gt;ls --zero | sort -z&lt;&#x2F;code&gt; and a &lt;code&gt;| tr &#x27;\0&#x27; &#x27;\n&#x27;&lt;&#x2F;code&gt; to convert to newlines for the human that still wants the illusion of line separation.&lt;&#x2F;p&gt;
&lt;p&gt;Examples of inputs you shouldn&#x27;t trust:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The human in front of the machine (I know myself)&lt;&#x2F;li&gt;
&lt;li&gt;Your filesystem (because USB sticks, downloads, the human, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Anything that comes in over the network (Not even your own service, not the service you are paying for, …)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;translating-between-worlds&quot;&gt;Translating between Worlds&lt;&#x2F;h2&gt;
&lt;p&gt;To translate between newline separated and the null separated world there is a little utility called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tr.1&quot;&gt;&lt;code&gt;tr&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
		
	
		
			
			
		
	
		
			
		
	
		
			
			
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		null to newline
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;tr &#x27;\0&#x27; &#x27;\n&#x27;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		newline to null
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;tr &#x27;\n&#x27; &#x27;\0&#x27;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		swap newline and null
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;tr &#x27;\n\0&#x27; &#x27;\0\n&#x27;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dt&gt;
		remove potential nulls
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;tr -d &#x27;\0&#x27;&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;Make sure to actually remove the characters you assume to not be in your input!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-a-program-into-null-separation-mode&quot;&gt;Getting a Program into Null-Separation Mode&lt;&#x2F;h2&gt;
&lt;p&gt;Unfortunately there is no &quot;the one way&quot; to make a program use nulls instead of newlines so here is a a hopefully useful table. Please note that some programs only have the option available in the gnu version, but not in i.e. the busybox version.&lt;&#x2F;p&gt;
&lt;p&gt;If a program has some kind of &lt;code&gt;printf&lt;&#x2F;code&gt; option one can use that to make the output null separated.&lt;&#x2F;p&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;&#x2F;th&gt;&lt;th&gt;Version&lt;&#x2F;th&gt;&lt;th&gt;Input Flag(s)&lt;&#x2F;th&gt;&lt;th&gt;Output Flag(s)&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;awk&lt;&#x2F;td&gt;&lt;td&gt;gnu, other modern&lt;&#x2F;td&gt;&lt;td&gt;-v &#x27;RS=\0&#x27;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;cut&lt;&#x2F;td&gt;&lt;td&gt;gnu&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;find&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-print0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;fzf&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;--read0&lt;&#x2F;td&gt;&lt;td&gt;--print0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;grep -r&lt;&#x2F;td&gt;&lt;td&gt;gnu&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-Z&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;grep&lt;&#x2F;td&gt;&lt;td&gt;gnu&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;inotifywait&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;--format &#x27;…%0&#x27; --no-newline&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ls&lt;&#x2F;td&gt;&lt;td&gt;gnu&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;--zero&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;rg&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;-0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;sed&lt;&#x2F;td&gt;&lt;td&gt;gnu&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;sort&lt;&#x2F;td&gt;&lt;td&gt;gnu, busybox&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;tar -T&lt;&#x2F;td&gt;&lt;td&gt;gnu&lt;&#x2F;td&gt;&lt;td&gt;--null&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;uniq&lt;&#x2F;td&gt;&lt;td&gt;gnu, busybox&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;td&gt;-z&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;xargs&lt;&#x2F;td&gt;&lt;td&gt;gnu, busybox&lt;&#x2F;td&gt;&lt;td&gt;-0&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;read&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;IFS=&quot;&quot; read&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The best way to automatically find out if a program supports an option is to &lt;code&gt;grep -q&lt;&#x2F;code&gt; across the output of its &lt;code&gt;--help&lt;&#x2F;code&gt;. Just make sure to choose a specific enough regex to avoid false positives. Trying out is also an option but that usually is a bit more complex.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; &lt;code&gt;read&lt;&#x2F;code&gt; is a shell builtin, which is why you don&#x27;t have to export the &lt;code&gt;IFS&lt;&#x2F;code&gt; (information separator) variable. This also affects other shell builtins like for-loops.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shell-variables-and-null-bytes&quot;&gt;Shell Variables and Null Bytes&lt;&#x2F;h2&gt;
&lt;p&gt;Shells usually drop null-characters when storing them into variables, so don&#x27;t rely on that happening and pipe information directly or, &lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;portable-shell&#x2F;&quot;&gt;if your constraints allow&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;shell&#x2F;#bash-arrays&quot;&gt;use bash arrays&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Because of this limitation for-loops can&#x27;t make use of null separation, use &lt;code&gt;while read&lt;&#x2F;code&gt; (will probably result in a subshell though) and &lt;code&gt;xargs&lt;&#x2F;code&gt; instead.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on &lt;code&gt;IFS&lt;&#x2F;code&gt;:&lt;&#x2F;b&gt; Setting the &lt;code&gt;IFS&lt;&#x2F;code&gt; to a newline by &lt;code&gt;IFS=&quot;&amp;lt;newline&amp;gt;&quot;&lt;&#x2F;code&gt; where &lt;code&gt;&amp;lt;newline&amp;gt;&lt;&#x2F;code&gt; is a literal line break (as in: the closing quote being the first character of the next line) you at least get clean newline separation if a for loop is really needed.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Speech Recognition Frontends</title>
        <published>2023-05-09T00:00:00+00:00</published>
        <updated>2026-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/speech-recognition-frontends/"/>
        <id>https://slatecave.net/notebook/speech-recognition-frontends/</id>
        
        <summary type="text">Projects making use of speech recognition</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/speech-recognition-frontends/">&lt;p&gt;This page intends to give an overview what kind of projects out there are open source (or preferably free software) making use of speech recognition without relying on some well known cloud providers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;The projects listed here fall into 3 broader categories.&lt;&#x2F;p&gt;
&lt;p&gt;Build your own voice something:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#voice2json&quot;&gt;voice2json&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#dragonfly&quot;&gt;Dragonfly&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Voice Input Methods that could replace Mouse and Keyboard:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#easyspeak&quot;&gt;EasySpeak&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#numen&quot;&gt;Numen&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#simon-kde&quot;&gt;Simon&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Voice assistants:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#rhasspy-voice-assistant&quot;&gt;Rhasspy&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;speech-recognition-frontends&#x2F;#mycroft-voice-assistant&quot;&gt;Mycroft&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;voice2json&quot;&gt;voice2json&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;voice2json&lt;&#x2F;code&gt; is a collection of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;voice2json.org&#x2F;commands.html&quot;&gt;command-line tools&lt;&#x2F;a&gt; for offline speech&#x2F;intent recognition on Linux. It is free, open source (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;opensource.org&#x2F;licenses&#x2F;MIT&quot;&gt;MIT&lt;&#x2F;a&gt;), and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;voice2json.org&#x2F;#supported-languages&quot;&gt;supports 18 human languages&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;voice2json.org&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;voice2json.org&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;It can make use of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kaldi-asr.org&#x2F;&quot;&gt;CMU Sphinx&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kaldi-asr.org&#x2F;&quot;&gt;Kaldi&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mozilla&#x2F;DeepSpeech&quot;&gt;Mozilla DeepSpeech&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;julius-speech&#x2F;julius&quot;&gt;Julius&lt;&#x2F;a&gt;, depending on the used language profile.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dragonfly&quot;&gt;Dragonfly&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Dragonfly is a speech recognition framework for Python that makes it convenient to create custom commands to use with speech recognition software.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;dictation-toolbox&amp;#x2F;dragonfly&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;dictation-toolbox&amp;#x2F;dragonfly
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;I learned about this from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;handsfree.dev&quot;&gt;handsfree.dev&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;easyspeak&quot;&gt;EasySpeak&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Voice control for Linux desktops. Fully local, no cloud, Wayland-native.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;ctsdownloads&amp;#x2F;easyspeak&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;ctsdownloads&amp;#x2F;easyspeak
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Tries to be a blend of input method and voice assistant.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;numen&quot;&gt;Numen&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Numen is voice control for computing without a keyboard. It works system-wide on Linux and the speech recognition runs locally.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;numenvoice.org&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;numenvoice.org&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;johngebbie.com&#x2F;&quot;&gt;John Gebbie&lt;&#x2F;a&gt; also has some &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~geb&#x2F;numen#see-also&quot;&gt;related projects linked in the README&lt;&#x2F;a&gt;, he also made &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;handsfree.dev&#x2F;&quot;&gt;handsfree.dev&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simon-kde&quot;&gt;Simon (KDE)&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Simon is an open source speech recognition program that can replace your mouse and keyboard. The system is designed to be as flexible as possible and will work with any language or dialect.&lt;&#x2F;p&gt;
&lt;p&gt;Simon uses the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kde.org&quot;&gt;KDE libraries&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cmusphinx.github.io&#x2F;&quot;&gt;CMU SPHINX&lt;&#x2F;a&gt; and &#x2F; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;julius.osdn.jp&#x2F;en_index.php&quot;&gt;Julius&lt;&#x2F;a&gt; coupled with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;htk.eng.cam.ac.uk&#x2F;&quot;&gt;HTK&lt;&#x2F;a&gt; and runs on Windows and Linux.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;simon.kde.org&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;simon.kde.org&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt;Some links have been replaced with their redirect targets.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rhasspy-voice-assistant&quot;&gt;Rhasspy Voice Assistant&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Rhasspy (ɹˈæspi) is an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rhasspy&quot;&gt;open source&lt;&#x2F;a&gt;, fully offline set of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rhasspy.readthedocs.io&#x2F;en&#x2F;latest&#x2F;#services&quot;&gt;voice assistant services&lt;&#x2F;a&gt; for many human languages […]&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;rhasspy.readthedocs.io&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;rhasspy.readthedocs.io
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mycroft-voice-assistant&quot;&gt;Mycroft Voice Assistant&lt;&#x2F;h2&gt;
&lt;p&gt;Mycroft is an open source voice Assistant that makes use of a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MycroftAI&#x2F;mycroft-precise&quot;&gt;custom wakeword listener&lt;&#x2F;a&gt; and Mozilla &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mozilla&#x2F;DeepSpeech&quot;&gt;DeepSpeech&lt;&#x2F;a&gt; together with some custom components that has no easy-to-find non-marketing short description.&lt;&#x2F;p&gt;
&lt;p&gt;If you are looking for the technical stuff instead of company selling things stuff, you&#x27;ll find it in the Documentation menu of their page.&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;mycroft.ai&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;mycroft.ai&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;feedback&quot;&gt;Feedback&lt;&#x2F;h2&gt;
&lt;p&gt;If some of the information here is outdated, incorrect or you know a project that is not in this list please &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;slatian&#x2F;site-source.slatecave-net&#x2F;issues&quot;&gt;open an issue over on Codeberg&lt;&#x2F;a&gt; or &lt;a href=&quot;&#x2F;about&#x2F;me#contact&quot;&gt;contact me in some other way&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Scanning, OCR and PDF</title>
        <published>2023-04-24T00:00:00+00:00</published>
        <updated>2024-05-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/scanning-ocr-and-pdf/"/>
        <id>https://slatecave.net/notebook/scanning-ocr-and-pdf/</id>
        
        <summary type="text">A cheatsheet for scanning and and OCRing documents on Linux with sane and tesseract</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/scanning-ocr-and-pdf/">&lt;h2 id=&quot;scanning&quot;&gt;Scanning&lt;&#x2F;h2&gt;
&lt;p&gt;Under Linux one can scan an image with the &lt;code&gt;scanimage&lt;&#x2F;code&gt; command provided by the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sane-project.org&#x2F;&quot;&gt;SANE framework&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;A helper function that scans an image from the default scanner to the given path with settings suitable for OCR&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;scan_image_to&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;	printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Scanning Image …\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	scanimage&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Gray&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-format&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; png&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-resolution&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 300&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The &lt;code&gt;--mode&lt;&#x2F;code&gt; and &lt;code&gt;--resolution&lt;&#x2F;code&gt; options are scanner specific and my work different for you. See &lt;code&gt;scanimage --help&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;

	
&lt;&#x2F;figure&gt;
&lt;h3 id=&quot;unpaper&quot;&gt;Unpaper&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;unpaper&#x2F;unpaper&quot;&gt;Unpaper&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;unpaper&quot;&gt;manpage&lt;&#x2F;a&gt;) is a scan post-processing tool which can remove paper and scan artefacts and also do alignment of carelessly scanned pages. Which is great when preparing them for OCR.&lt;&#x2F;p&gt;
&lt;p&gt;Thanks to a friend of mine for mentioning it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ocr-using-tesseract-and-imagemagick&quot;&gt;OCR using Tesseract and imagemagick&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tesseract-ocr&#x2F;tesseract&quot;&gt;Tesseract&lt;&#x2F;a&gt; is both, a library and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tesseract&quot;&gt;command line tool&lt;&#x2F;a&gt; for Optical Character Recognition (OCR). Image in, text in image out.&lt;&#x2F;p&gt;
&lt;p&gt;It best works with greyscale images with low background noise and high contrast. Getting a scan closer to that can be done using unpaper or - for scans of known quality - imagemagick using its builtin contrast filter and the level clipping, which is faster than any fully automatic tool.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;A function that can be used to OCR a given prerotated image that does some preprocessing with imagemagick to improve noise (the -level option) and contrast for scans, the output is the OCR as plaintext to stdout.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Usage: ocr_image &amp;lt;image&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ocr_image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	convert&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;colorspace&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; Gray&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;contrast&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;level&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 20%,100%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;contrast&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;contrast&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	tesseract&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; deu+eng&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-oem&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-psm&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;To explain the most important tesseract options:&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		-l
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		To set the used &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tesseract#LANGUAGES_AND_SCRIPTS&quot;&gt;language or script&lt;&#x2F;a&gt;. Accepts multiple values separated by a &lt;code&gt;+&lt;&#x2F;code&gt;. i.e. &lt;code&gt;-l deu+eng&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		--oem
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		To set the mode of operation, meaning whether or not to use the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Long_short-term_memory&quot;&gt;LSTM&lt;&#x2F;a&gt; based approach or the original tesseract OCR. At the time of writing I had the best results with option 2, enabling both.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		--psm
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		Tells tesseract what &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tesseract#OPTIONS&quot;&gt;kind of layout analysis&lt;&#x2F;a&gt; to run. I prefer to do a separate OSD (Orientation and Script Detection) only run in mode 0 rotating the image and then using the full automatic layout mode 3 without OSD to do the actual OCR.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		--user-words
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		To give tesseract a text file with a list of words that are likely to occur in the document, this helps avoiding the OCR equivalent to a typo. There is also a pattern file (note that these are &lt;b&gt;not&lt;&#x2F;b&gt; regexes!). &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;tesseract#CONFIG_FILES_AND_AUGMENTING_WITH_USER_DATA&quot;&gt;More on word and pattern lists in the tesseract manpage.&lt;&#x2F;a&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;&lt;b&gt;Note for Void-Linux users:&lt;&#x2F;b&gt; The package name and command for calling tesseract is &lt;code&gt;tesseract-ocr&lt;&#x2F;code&gt; on Void.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;This function uses tesseract with the psm 0 mode to correctly orientate a given image file that is assumed to be German or English text. The file is then replaced.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Usage: rotate_scanned_image &amp;lt;image&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;rotate_scanned_image&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Replace or leve out the -l option here if you work with other languages&#x2F;scripts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	PAGE_OSD&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;tesseract&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; deu+eng&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-oem&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-psm&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;amp;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;    #&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;if DEBUG_OSD is set print some debug output.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-logical-expression&quot;&gt;	[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;DEBUG_OSD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-logical-expression&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt; printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;PAGE OSD =====\n%s\n==============\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;PAGE_OSD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;amp;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	APPLY_ROTATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt; printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;%s\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;PAGE_OSD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; awk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&#x2F;^Rotate:&#x2F;{ print $2 }&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;	convert&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;rotate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;APPLY_ROTATION&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:-&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;b&gt;Note on DPI settings:&lt;&#x2F;b&gt; Tesseract assumes the images to be scanned at 300dpi, if you are using a different resolution make sure to tell tesseract using the &lt;code&gt;--dpi&lt;&#x2F;code&gt; option.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pdf-creation-and-manipulation&quot;&gt;PDF creation and manipulation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;creating-a-pdf-from-images&quot;&gt;Creating a PDF from images&lt;&#x2F;h3&gt;
&lt;p&gt;To create a PDF from images without OCR one can use imagemagick.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example that uses the &lt;code&gt;convert&lt;&#x2F;code&gt; command to convert two png files to an pdf with a pagesize of DIN A4.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;convert&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;page&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; a4&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; page_1.png&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; page_2.png&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; document.pdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;Also see the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;imagemagick.org&#x2F;script&#x2F;command-line-options.php#page&quot;&gt;imagemagick documentation on the -page option.&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ocr-using-ocrmypdf&quot;&gt;OCR using OCRmyPDF&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ocrmypdf.readthedocs.io&#x2F;en&#x2F;latest&#x2F;index.html&quot;&gt;OCRmyPDF&lt;&#x2F;a&gt; is a python wrapper for tesseract that makes it pretty painless to run OCR on a PDF and turn PDFs into &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ocrmypdf.readthedocs.io&#x2F;en&#x2F;latest&#x2F;introduction.html#about-pdf-a&quot;&gt;standards compliant PDF&#x2F;A&lt;&#x2F;a&gt; and optimize PDFs to reduce filesize.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example for OCRing a PDF file that contains German and English text as images.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;ocrmypdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; deu+eng&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; input.pdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; output.pdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;b&gt;Package Note:&lt;&#x2F;b&gt; The package is called &lt;code&gt;ocrmypdf&lt;&#x2F;code&gt; for all major Linux distributions (AUR on Arch).&lt;&#x2F;p&gt;
&lt;p&gt;Thank you (again) to the friend who found this tool.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-pdfs-with-ocr-using-tesseract-and-poppler&quot;&gt;Creating PDFs with OCR using tesseract and poppler&lt;&#x2F;h3&gt;
&lt;p&gt;To create PDFs with an OCR overlay one can delegate the image to PDF step to tesseract using its &lt;code&gt;pdf&lt;&#x2F;code&gt; preset and join the resulting documents after the OCR step with the poppler &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;pdfunite&quot;&gt;&lt;code&gt;pdfunite&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; tool.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Tesseract command to generate a PDF with OCR overlay for a single page with the options left out (they are the same as with the plaintext preset)&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tesseract page_n.png page_n [options...] pdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;figure&gt;
	&lt;figcaption&gt;pdfunite command to join multiple PDFs together. Btw. these can be any PDF documents.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pdfunite&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; page_&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;.pdf&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; document.pdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;b&gt;Accessibility Note:&lt;&#x2F;b&gt; These OCR overlays while pretty good are intended for making the documents searchable, they are not a replacement for proper semantic and accessible documents.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;getting-text-out-of-pdf-files&quot;&gt;Getting text out of PDF files&lt;&#x2F;h3&gt;
&lt;p&gt;To get text out of a PDF one can use the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;pdftotext&quot;&gt;&lt;code&gt;pdftotext&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;pdftohtml&quot;&gt;&lt;code&gt;pdftohtml&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; command (which come with poppler).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;pdftotext&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; file.pdf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;packages&quot;&gt;Packages&lt;&#x2F;h2&gt;
&lt;p&gt;To get the commandline utilities on some distributions one should also install the &lt;code&gt;&amp;lt;packagename&amp;gt;-bin&lt;&#x2F;code&gt; package.&lt;&#x2F;p&gt;
&lt;p&gt;Imagemagick is sometimes just called &lt;code&gt;magick&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Tesseract usually comes without the needed data files, these probably come in packages called like &lt;code&gt;tesseract-data-&amp;lt;lang&amp;gt;&lt;&#x2F;code&gt;, if you just want everything there is probably a &lt;code&gt;tesseract-data-all&lt;&#x2F;code&gt; metapackage.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;pdfunite&lt;&#x2F;code&gt; and &lt;code&gt;pdfto*&lt;&#x2F;code&gt; commands are either directly in the &lt;code&gt;poppler&lt;&#x2F;code&gt; package or in &lt;code&gt;poppler-utils&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>IP-Address Ranges</title>
        <published>2023-03-08T00:00:00+00:00</published>
        <updated>2025-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/ip-ranges/"/>
        <id>https://slatecave.net/notebook/ip-ranges/</id>
        
        <summary type="text">Overview of reserved IP-Address ranges for IPv4 and IPv6</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/ip-ranges/">&lt;h2 id=&quot;in-general&quot;&gt;In General&lt;&#x2F;h2&gt;
&lt;p&gt;While IPv4 and IPv6 have different terminology, they share some concepts. Scope and Delivery schemes.&lt;&#x2F;p&gt;
&lt;p&gt;Both IP-Versions share the following delivery schemes:&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		Unicast
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		one to one, the default
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Multicast
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		one to many, v6 had a huge Update there
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Broadcast
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		usually inside the scope of a single network
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;Scope is a bit version dependant, usually you have:&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;max-one-dd&quot;&gt;

	
		&lt;dt&gt;
		Global
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These addresses are globally routable and assigned by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;&quot;&gt;IANA&lt;&#x2F;a&gt; and the local Internet registries.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Private
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These addresses are reserved for private use and you are free to use the in your own network, just be aware, that you can&#x27;t use them on the internet.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Loopback
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These addresses always route back to the sending machine, usually &lt;code&gt;localhost&lt;&#x2F;code&gt; resolves to them.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Link-Local
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These adresses are automatically assigned so that host on the same network can talk to each other.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Documentation
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These addresses are reserved for documentation purposes.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Other reserved
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		These adresses are reserved and have some conditions on when you are supposed to use them.
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h2 id=&quot;ipv6-adress-ranges&quot;&gt;IPv6 Adress Ranges&lt;&#x2F;h2&gt;
&lt;p&gt;By default IPv6 adresses are unassigned global unicast adresses and therefore reserved for future use. The IANA has a complete list with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;iana-ipv6-special-registry&#x2F;iana-ipv6-special-registry.xhtml&quot;&gt;IANA IPv6 Special-Purpose Address Registry&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		Global Unicast (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4291.html#section-2.5.4&quot;&gt;RFC 4291, Section 2.5.4&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;2000::&#x2F;3&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Unique Local (Private) (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4193&quot;&gt;RFC 4193&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;fd00::&#x2F;8&lt;&#x2F;code&gt; (with Random Global ID)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;fc00::&#x2F;8&lt;&#x2F;code&gt; (reserved for future use)
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Loopback (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4291.html#section-2.5.3&quot;&gt;RFC 4291, Section 2.5.3&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;::1&#x2F;128&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Link-Local (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4291.html#section-2.5.6&quot;&gt;RFC 4291, Section 2.5.6&lt;&#x2F;a&gt;
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;fe80::&#x2F;10&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Documentation (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3849.html&quot;&gt;RFC 3849&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;2001:db8::&#x2F;32&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Multicast (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4291.html#section-2.7&quot;&gt;RFC 4291, Section 2.7&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;ff00::&#x2F;8&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		IETF Protocol Assignments (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc6890.html#section-2.1&quot;&gt;RFC 6890&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;2001:0000::&#x2F;23&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		NAT64 Well-Known Prefix (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc6052#section-2&quot;&gt;RFC 6052, Section 2&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;64:ff9b::&#x2F;96&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Site-Local IPv6 Unicast Addresses (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4291.html#section-2.5.7&quot;&gt;RFC 4291, Section 2.5.7&lt;&#x2F;a&gt;) have been deprecated in favour of Unique Local Addresses (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc4193&quot;&gt;RFC 4193&lt;&#x2F;a&gt;) which are pretty similar, but better defined.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ipv4-address-ranges&quot;&gt;IPv4 Address Ranges&lt;&#x2F;h2&gt;
&lt;p&gt;By default IPv4 adresses are adresses that fall in the global unicast category. The IANA has a complete List with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iana.org&#x2F;assignments&#x2F;iana-ipv4-special-registry&#x2F;iana-ipv4-special-registry.xhtml#iana-ipv4-special-registry-1&quot;&gt;IANA IPv4 Special-Purpose Address Registry&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;




	
		
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
			
			
				
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	
		
			
			
		
	
		
	
		
			
		
	
		
			
			
		
	


&lt;dl class=&quot;&quot;&gt;

	
		&lt;dt&gt;
		Private (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc1918.html&quot;&gt;RFC 1918&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;192.168.0.0&#x2F;16&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;172.16.0.0&#x2F;12&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;10.0.0.0&#x2F;8&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Loopback (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc1122.html#page-31&quot;&gt;RFC 1122, Section 3.2.1.3&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;127.0.0.0&#x2F;8&lt;&#x2F;code&gt; Note that this is an entire network.
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;127.0.0.1&lt;&#x2F;code&gt; is usually used.
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Link-Local (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc3927.html&quot;&gt;RFC 2927&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;169.254.0.0&#x2F;16&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Documentation (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc5737.html#section-3&quot;&gt;RFC 5737&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;192.0.2.0&#x2F;24&lt;&#x2F;code&gt; (TEST-NET-1)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;198.51.100.0&#x2F;24&lt;&#x2F;code&gt; (TEST-NET-2)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;203.0.113.0&#x2F;24&lt;&#x2F;code&gt; (TEST-NET-3)
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Shared (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc6598.html&quot;&gt;RFC 6598&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;100.64.0.0&#x2F;10&lt;&#x2F;code&gt; &lt;br&gt;&lt;q&gt;used as Shared Address Space to accommodate the needs of Carrier-Grade NAT (CGN) devices.&lt;&#x2F;q&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Benchmarking (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc2544.html#appendix-C.2.2.1&quot;&gt;RFC 2544&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;198.18.0.0&#x2F;15&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		Multicast
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;240.0.0.0&#x2F;4&lt;&#x2F;code&gt; Multicast &quot;Namespace&quot; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc1112.html#section-4&quot;&gt;RFC 1112&lt;&#x2F;a&gt;)
		&lt;&#x2F;dd&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;192.52.193.0&#x2F;24&lt;&#x2F;code&gt; Automatic Multicast Tunneling (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc7450.html&quot;&gt;RFC 7450&lt;&#x2F;a&gt;)
		&lt;&#x2F;dd&gt;
	

	

	
		&lt;dt&gt;
		IETF Protocol Assignments (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc6890.html#section-2.1&quot;&gt;RFC 6890&lt;&#x2F;a&gt;)
		&lt;&#x2F;dt&gt;
	

	
		&lt;dd&gt;
		&lt;code&gt;192.0.0.0&#x2F;24&lt;&#x2F;code&gt;
		&lt;&#x2F;dd&gt;
	

&lt;&#x2F;dl&gt;
&lt;h3 id=&quot;broadcast&quot;&gt;Broadcast&lt;&#x2F;h3&gt;
&lt;p&gt;Broadcast addresses with IPv4 work by setting the host-part of the address to all ones (in the binary representation) they send to all hosts in the local network.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc919.html&quot;&gt;RFC 919&lt;&#x2F;a&gt; &lt;code&gt;255.255.255.255&lt;&#x2F;code&gt; is defined as &lt;q&gt;broadcast to all of its immediate neighbors&lt;&#x2F;q&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Serial Port Troubleshooting on Linux</title>
        <published>2023-02-14T00:00:00+00:00</published>
        <updated>2023-02-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/serial-not-working/"/>
        <id>https://slatecave.net/notebook/serial-not-working/</id>
        
        <summary type="text">How to find out why your serial Port isn&#x27;t working</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/serial-not-working/">&lt;p&gt;A serial port (i.e. for programming a microcontroller) can have multiple reasons why it is not working. This guide is based on my experience and will try to cover most cases, FAQ style.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hints&quot;&gt;Hints&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;It is always a good idea to try to look up the problem in your distributions wiki&#x2F;documentation first!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can manually connect to a serial port using &lt;code&gt;screen &#x2F;dev&#x2F;tty&amp;lt;name&amp;gt;&lt;&#x2F;code&gt;.
Quit with &lt;kbd&gt;Ctrl+a&lt;&#x2F;kbd&gt; and pressing &lt;kbd&gt;k&lt;&#x2F;kbd&gt; after that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;is-your-serial-device-showing-up&quot;&gt;Is your Serial device showing up?&lt;&#x2F;h2&gt;
&lt;p&gt;Use &lt;code&gt;ls &#x2F;dev&#x2F;tty*&lt;&#x2F;code&gt; to get a list of terminal devices on your Linux machine. If you find a &lt;code&gt;ttyUSBn&lt;&#x2F;code&gt; or a &lt;code&gt;ttyACMn&lt;&#x2F;code&gt; (where &lt;code&gt;n&lt;&#x2F;code&gt; is a number) that appears when you plug your device in and disappears when unplugging (yes that&#x27;s the easiest way) that is your device with hardware and drivers working, skip this section.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Builtin serial ports are sometimes also called &lt;code&gt;&#x2F;dev&#x2F;Sn&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;is-the-hardware-recognised&quot;&gt;Is the Hardware recognised?&lt;&#x2F;h3&gt;
&lt;p&gt;Try running &lt;code&gt;lsusb&lt;&#x2F;code&gt;, it will give you a list of connected USB devices, if your device is not among them you either have a bad cable, a bad microcontroller or (for some micros) the controller is not in programming mode.&lt;&#x2F;p&gt;
&lt;p&gt;If the device shows up in &lt;code&gt;lsusb&lt;&#x2F;code&gt; but there is no serial port, your hardware is working but there is a driver problem. (or the hardware doesn&#x27;t provide a serial port.)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;would-a-reboot-fix-the-problem&quot;&gt;Would a reboot fix the problem?&lt;&#x2F;h3&gt;
&lt;p&gt;This only the case if there has been a system update since the last reboot.&lt;&#x2F;p&gt;
&lt;p&gt;(Depending on your definition of a shortcut: just reboot)&lt;&#x2F;p&gt;
&lt;p&gt;If you are not using a very uncommon setup check if &lt;code&gt;&#x2F;lib&#x2F;modules&lt;&#x2F;code&gt; (the directory kernel modules (drivers) are in) contains a directory called the same as the output of &lt;code&gt;uname -r&lt;&#x2F;code&gt; (the version of the currently running kernel).&lt;&#x2F;p&gt;
&lt;p&gt;If that is not the case your package manager has cleaned up the old modules during an update and you have not rebooted yet (still running the old kernel). The solution in this case is a reboot, then the hardware management will be able to find the modules the kernel needs because the running version matches the version of the modules in the filesystem.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;missing-package-or-driver-error&quot;&gt;Missing Package or Driver Error&lt;&#x2F;h3&gt;
&lt;p&gt;If a reboot did not or would not fix your problem try searching for a driver package (usually the package name contains &lt;code&gt;ftdi&lt;&#x2F;code&gt; for USB to serial adaptors).&lt;&#x2F;p&gt;
&lt;p&gt;If you find the necessary package already installed, running &lt;code&gt;dmesg -w&lt;&#x2F;code&gt; as root and then plugging in the device is also worth a look at this point. &lt;code&gt;dmesg&lt;&#x2F;code&gt; prints logs from your kernel, including potential information and errors from relevant drivers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-you-have-permission-for-accessing-serial-ports&quot;&gt;Do you have permission for accessing serial ports?&lt;&#x2F;h2&gt;
&lt;p&gt;Run &lt;code&gt;ls -l &#x2F;dev&#x2F;tty*&lt;&#x2F;code&gt;, this will tell you who owns the device files, file permissions apply like with regular files.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;An example output line, the file belongs to the &lt;code&gt;root&lt;&#x2F;code&gt; user and the &lt;code&gt;dialout&lt;&#x2F;code&gt; group, both are allowed to read and write.&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw-rw---- 1 root dialout 4, 67  5. Sep 12:25 &#x2F;dev&#x2F;ttyS0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#^  ^ The 2 rw here indicate that owner and group may read from and write to this device.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;By default on many distributions the hardware management comes preconfigured in a way that only permits users in the &lt;code&gt;dialout&lt;&#x2F;code&gt; group to use serial ports. Check if you are a member of that group using the &lt;code&gt;groups&lt;&#x2F;code&gt; command.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The &lt;code&gt;dialout&lt;&#x2F;code&gt; group may have a different name on some distributions if the &lt;code&gt;ls -l&lt;&#x2F;code&gt; didn&#x27;t indicate that the serial port belongs to the &lt;code&gt;dialout&lt;&#x2F;code&gt; group this is the case for you. (look up serial ports in the distributions wiki).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on Arch derived Distributions:&lt;&#x2F;b&gt; On Archlinux and derived distributions the relevant group is called &lt;code&gt;uucp&lt;&#x2F;code&gt; instead of &lt;code&gt;dialout&lt;&#x2F;code&gt;. (UUCP stands for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;UUCP&quot;&gt;Unix-to-Unix Copy&lt;&#x2F;a&gt; which was common to be used over a serial link.)&lt;&#x2F;p&gt;
&lt;p&gt;You can give a user permission by running &lt;code&gt;sudo usermod -a -G dialout &amp;lt;username&amp;gt;&lt;&#x2F;code&gt; and logging out and back in after that.&lt;&#x2F;p&gt;
&lt;p&gt;In case your system looks completely different you may want to investigate &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;man.voidlinux.org&#x2F;udev&quot;&gt;&lt;code&gt;udev&lt;&#x2F;code&gt; and udev rules&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;is-something-else-using-the-port&quot;&gt;Is something else using the port?&lt;&#x2F;h2&gt;
&lt;p&gt;Since a program doesn&#x27;t really know what is on the other side of a serial port some programs simply connect and try to find out. This may interfere with whatever you are trying to do.&lt;&#x2F;p&gt;
&lt;p&gt;One of these programs is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;packages.debian.org&#x2F;bullseye&#x2F;brltty&quot;&gt;brltty&lt;&#x2F;a&gt; which is preconfigured by most big distributions. It tries very hard to make sure plugging a braille display into an USB port will make it immediately available. (which is very good, your little Arduino isn&#x27;t nearly as important!) Unfortunately it has to open every serial device that connects to the system to find out whether it is a braille display or not.&lt;&#x2F;p&gt;
&lt;p&gt;To fix that behaviour either configure the &quot;offending&quot; program or stop (and disable) the service it belongs to if you don&#x27;t need it.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example of how to disable and stop the &lt;code&gt;brltty&lt;&#x2F;code&gt; service on most systemd based distributions. &lt;br&gt;&lt;strong&gt;Do not do this if you rely on a working braille display!&lt;&#x2F;strong&gt;&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; systemctl&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; disable&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-now&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; brltty&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;did-that-fix-it&quot;&gt;Did that fix it?&lt;&#x2F;h2&gt;
&lt;p&gt;If this guide helped you please consider sharing it.&lt;&#x2F;p&gt;
&lt;p&gt;In case you found a mistake  or ended up in a dead end, don&#x27;t hesitate to &lt;a href=&quot;&#x2F;about&#x2F;me#contact&quot;&gt;contact me&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>arduino-cli</title>
        <published>2023-02-13T00:00:00+00:00</published>
        <updated>2023-02-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/arduino-cli/"/>
        <id>https://slatecave.net/notebook/arduino-cli/</id>
        
        <summary type="text">Some arduino-cli common patterns and tricks</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/arduino-cli/">&lt;p&gt;While &lt;code&gt;arduino-cli&lt;&#x2F;code&gt; is an awesome tool, unfortunately most guides skip right past it and assume you use the Arduino IDE, this page is a collection of common patterns for &lt;code&gt;arduino-cli&lt;&#x2F;code&gt;. It assumes that you know a few things about how Arduino works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basics&quot;&gt;Basics&lt;&#x2F;h2&gt;
&lt;p&gt;To create a sketch &lt;code&gt;arduino-cli&lt;&#x2F;code&gt; assumes that your main &lt;code&gt;.ino&lt;&#x2F;code&gt; file has the same name as the directory containing it.&lt;&#x2F;p&gt;
&lt;p&gt;To build and upload use &lt;code&gt;arduino-cli compile --fqbn &amp;lt;fqbn&amp;gt;&lt;&#x2F;code&gt; and &lt;code&gt;arduino-cli upload -p &amp;lt;serial-device&amp;gt; --fqbn &amp;lt;fqbn&amp;gt;&lt;&#x2F;code&gt; in your code directory.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Hint:&lt;&#x2F;b&gt; On Linux your serial devices are called &lt;code&gt;&#x2F;dev&#x2F;ttyUSBn&lt;&#x2F;code&gt; and &lt;code&gt;&#x2F;dev&#x2F;ttyACMn&lt;&#x2F;code&gt; where &lt;code&gt;n&lt;&#x2F;code&gt; is a number.&lt;br&gt; &lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;serial-not-working&#x2F;&quot;&gt;Make sure you have the permissions to access them and nothing else is trying to use those ports.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;You&#x27;ve got an unhelpful error message?&lt;&#x2F;b&gt; Try adding the &lt;code&gt;--log&lt;&#x2F;code&gt; flag, it will cause &lt;code&gt;arduino-cli&lt;&#x2F;code&gt; to print out whatever it is currently doing.&lt;br&gt; This way one can get some context for the error.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fqbn-fully-qualified-board-name&quot;&gt;FQBN? Fully Qualified Board Name!&lt;&#x2F;h2&gt;
&lt;p&gt;The Fully qualified Board name consists of what Arduino calls the &lt;i&gt;Platform ID&lt;&#x2F;i&gt; and a name for the board. You can find it out either by using &lt;code&gt;arduino-cli board search &amp;lt;searchterm&amp;gt;&lt;&#x2F;code&gt;, &lt;code&gt;arduino-cli board listall&lt;&#x2F;code&gt; or by appending the official board name in lowercase to the Platform ID.&lt;&#x2F;p&gt;
&lt;p&gt;Examples include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;arduino:avr:uno&lt;&#x2F;code&gt; (Arduino Uno or another board with an ATMega328P running at 16MHz)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;esp8266:esp8266:generic&lt;&#x2F;code&gt; (A generic esp8266 Module)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;esp32:esp32:esp32&lt;&#x2F;code&gt; (A generic esp32 module)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Please note that the esp boards are not available by default.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compile-and-upload-a-sketch-using-arduino-cli&quot;&gt;Compile and Upload a Sketch using arduino-cli&lt;&#x2F;h2&gt;
&lt;p&gt;I usually create a &lt;code&gt;compile-and-upload.sh&lt;&#x2F;code&gt; script to make development and testing easier.&lt;&#x2F;p&gt;
&lt;figure&gt;
	
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;arduino-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; compile&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-fqbn&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; arduino:avr:uno&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;arduino-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; upload&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-fqbn&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; arduino:avr:uno&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;dev&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;ttyUSB0&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	&lt;figcaption&gt;A simple compile and upload script with a fixed board and an optional argument for the serial port that defaults to &lt;code&gt;&#x2F;dev&#x2F;ttyUSB0&lt;&#x2F;code&gt;&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; When given the &lt;code&gt;-u&lt;&#x2F;code&gt; flag and the options needed for uploading &lt;code&gt;arduino-cli compile --fqbn arduino:avr:uno -u -p &quot;${1:-&#x2F;dev&#x2F;ttyUSB0}&quot;&lt;&#x2F;code&gt; behaves like the above example script.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on shell syntax:&lt;&#x2F;b&gt; The &lt;code&gt;&quot;${1:-&#x2F;dev&#x2F;ttyUSB0}&quot;&lt;&#x2F;code&gt; is read by your shell as replace this with the first argument given to the script or with &lt;code&gt;&#x2F;dev&#x2F;ttyUSB0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adding-more-boards&quot;&gt;Adding more Boards&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;arduino-cli&lt;&#x2F;code&gt; is not just a wrapper for a compiler and whatever you prefer for uploading … it also is a package manager. If you want more boards (or libraries) you can search for and install them.&lt;&#x2F;p&gt;
&lt;p&gt;But if you want to write code for a non-Arduino branded board (i.e. an ESP8266 or ESP32) those packages are not in the Arduino package repositories.&lt;&#x2F;p&gt;
&lt;p&gt;Adding an extra repository can be done by letting &lt;code&gt;arduino-cli&lt;&#x2F;code&gt; do the work …&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;arduino-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; config&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; board_manager.additional_urls&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;url:&#x2F;&#x2F;to&#x2F;index.json&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;… or by manually editing &lt;code&gt;~&#x2F;.arduino15&#x2F;arduino-cli.yaml&lt;&#x2F;code&gt; and adding the URL pinting to the respositories &lt;code&gt;*_index.json&lt;&#x2F;code&gt; file there.&lt;&#x2F;p&gt;
&lt;figure&gt;
	
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;oard_manager&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;  a&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;dditional_urls&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ttps:&#x2F;&#x2F;arduino.esp8266.com&#x2F;stable&#x2F;package_esp8266com_index.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ttps:&#x2F;&#x2F;dl.espressif.com&#x2F;dl&#x2F;package_esp32_index.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ttps:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;espressif&#x2F;arduino-esp32&#x2F;gh-pages&#x2F;package_esp32_dev_index.json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	&lt;figcaption&gt;An excerpt from the configuration file from my laptop with additional URL to the stable esp8266 and esp32 repositories in addition to the development version of the esp32 repository.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Don&#x27;t forget to &lt;code&gt;arduino-cli update&lt;&#x2F;code&gt; and &lt;code&gt;arduino-cli upgrade&lt;&#x2F;code&gt;!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;flashing-a-bootloader-using-arduino-cli&quot;&gt;Flashing a Bootloader using arduino-cli&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;arduino-cli&lt;&#x2F;code&gt; already knows how to flash a new bootloader with the &lt;code&gt;burn-bootloader&lt;&#x2F;code&gt; subcommand, you have to tell it for which board you want the bootloader using &lt;code&gt;--fqbn&lt;&#x2F;code&gt; and which programmer you are using with &lt;code&gt;-P&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; Programmers usually aren&#x27;t quite cheap, but if you have another Arduino (compatible) with UART (serial) and SPI interface you can use that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.arduino.cc&#x2F;built-in-examples&#x2F;arduino-isp&#x2F;ArduinoISP&quot;&gt;Arduino as an &lt;abbr title=&quot;In-circuit Serial Programmer&quot;&gt;ISP&lt;&#x2F;abbr&gt; &lt;&#x2F;a&gt;. (use &lt;code&gt;-P arduinoasisp&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;It may be necessary to provide the port the programmer is on via the &lt;code&gt;-p&lt;&#x2F;code&gt; option. (like with the &lt;code&gt;upload&lt;&#x2F;code&gt; command)&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example using the official AVRISP mkII programmer for AVR chips for an ATMEL 328P in an Arduino Uno like configuration&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;arduino-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; burn-bootloader&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-fqbn&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; arduino:avr:uno&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;P&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; avrispmkii&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;To find out which programmer string you need, go to the &lt;code&gt;ArduinoCore-*&lt;&#x2F;code&gt; repository of your favourite architecture (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arduino&quot;&gt;github.com&#x2F;arduino&lt;&#x2F;a&gt; for the official ones) and open the &lt;code&gt;programmers.txt&lt;&#x2F;code&gt; file (i.e. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arduino&#x2F;ArduinoCore-avr&#x2F;blob&#x2F;master&#x2F;programmers.txt&quot;&gt;ArduinoCore-avr&#x2F;programmers.txt&lt;&#x2F;a&gt;), the keys used there are the needed ids for the &lt;code&gt;-P&lt;&#x2F;code&gt; option.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; An interesting option might be to use an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.arduino.cc&#x2F;built-in-examples&#x2F;arduino-isp&#x2F;ArduinoISP&#x2F;&quot;&gt;Arduino Microcontroller as your programmer&lt;&#x2F;a&gt;, use &lt;code&gt;-P arduinoisp&lt;&#x2F;code&gt; in this case. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arduino&#x2F;arduino-examples&#x2F;blob&#x2F;main&#x2F;examples&#x2F;11.ArduinoISP&#x2F;ArduinoISP&#x2F;ArduinoISP.ino&quot;&gt;The neccessary code is also in a public repository.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-do-i-need-a-bootloader&quot;&gt;Why do I need a Bootloader?&lt;&#x2F;h3&gt;
&lt;p&gt;To be able to seamlessly upload code with just a USB to serial converter like in the example above your microcontroller needs to have the Arduino bootloader installed, a small piece of software that runs when the controller starts (that&#x27;s the reason you need to hook up the reset line when programming) that can be told to write a new program to the controller instead of starting the already existing one.&lt;&#x2F;p&gt;
&lt;p&gt;The boards you can buy online come with a bootloader preinstalled. But maybe you want to build your own Arduino compatible or released the magic smoke and want to just buy the chip itself without a development-board, that is when you want to flash the bootloader yourself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;do-i-need-a-bootloader-to-use-the-arduino-framwork&quot;&gt;Do I need a Bootloader to use the Arduino Framwork?&lt;&#x2F;h3&gt;
&lt;p&gt;No, you can use the programmer of your choice (just use the &lt;code&gt;-P&lt;&#x2F;code&gt; option with the upload command) to flash whatever you coded up directly into the controller at the cost of having to use the programmer every time you upload a new program. (Unless that program is a bootloader 😉)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-sketch-local-libraries&quot;&gt;Using sketch-local Libraries&lt;&#x2F;h2&gt;
&lt;p&gt;To use liberies stored anywhere but the default location (i.e. in a &lt;code&gt;libs&lt;&#x2F;code&gt; folder next to your &lt;code&gt;.ino&lt;&#x2F;code&gt; files) the &lt;code&gt;--library&lt;&#x2F;code&gt; and &lt;code&gt;--libraries&lt;&#x2F;code&gt; can be used. Both accept a comma seperated list of filepaths.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;--library&lt;&#x2F;code&gt; points to individual libraries and &lt;code&gt;--libraries&lt;&#x2F;code&gt; points to folders of libraries.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;figcaption&gt;Example to compile a sketch with a &lt;code&gt;libs&lt;&#x2F;code&gt; folder&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;arduino-cli&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; compile&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-libraries&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; libs&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;-fqbn&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;fqb&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;you-may-also-be-interested-in&quot;&gt;You may also be interested in&lt;&#x2F;h2&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;arduino.github.io&amp;#x2F;arduino-cli&amp;#x2F;latest&amp;#x2F;getting-started&amp;#x2F;&quot; &gt;
		The official arduino-cli documantation
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&#x2F;&#x2F;slatecave.net&#x2F;notebook&#x2F;serial-not-working&#x2F;&quot; &gt;
		Serial Port Troublehooting on Linux
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Resistor Value Table</title>
        <published>2023-01-14T00:00:00+00:00</published>
        <updated>2023-01-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/resistors/"/>
        <id>https://slatecave.net/notebook/resistors/</id>
        
        <summary type="text">For when those Rings don&#x27;t make sense again.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/resistors/">&lt;h2 id=&quot;how-to-read-resistors&quot;&gt;How To Read Resistors&lt;&#x2F;h2&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Color&lt;&#x2F;th&gt;&lt;th&gt;Value&lt;&#x2F;th&gt;&lt;th&gt;Multiplier&lt;&#x2F;th&gt;&lt;th&gt;Tolerance&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row black&quot;&gt;&lt;td&gt;Black&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;1Ω&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row brown&quot;&gt;&lt;td&gt;Brown&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;10Ω&lt;&#x2F;td&gt;&lt;td&gt;± 1%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row red&quot;&gt;&lt;td&gt;Red&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;100Ω&lt;&#x2F;td&gt;&lt;td&gt;± 2%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row orange&quot;&gt;&lt;td&gt;Orange&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;1KΩ&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row yellow&quot;&gt;&lt;td&gt;Yellow&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;10KΩ&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row green&quot;&gt;&lt;td&gt;Green&lt;&#x2F;td&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;100KΩ&lt;&#x2F;td&gt;&lt;td&gt;± 0.5%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row blue&quot;&gt;&lt;td&gt;Blue&lt;&#x2F;td&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;1MΩ&lt;&#x2F;td&gt;&lt;td&gt;± 0.25%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row violet&quot;&gt;&lt;td&gt;Violet&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;10MΩ&lt;&#x2F;td&gt;&lt;td&gt;± 0.10%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row gray&quot;&gt;&lt;td&gt;Gray&lt;&#x2F;td&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;± 0.05%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row white&quot;&gt;&lt;td&gt;White&lt;&#x2F;td&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row gold&quot;&gt;&lt;td&gt;Gold&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;0.1Ω&lt;&#x2F;td&gt;&lt;td&gt;± 5%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr class=&quot;color-row silver&quot;&gt;&lt;td&gt;Silver&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;0.01Ω&lt;&#x2F;td&gt;&lt;td&gt;± 10%&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;Resistors are usually marked with 4 or 5 colored rings to indicate value and tolerance. To read the code in the right direction you have to know that the order is:&lt;&#x2F;p&gt;
&lt;p&gt;1st Ring, 2nd Ring, 3rd Ring (only when you have a 5-Ring code), Multiplier Ring, a larger gap (sometimes not), Tolerance Ring&lt;&#x2F;p&gt;
&lt;p&gt;To decode, read the 1st to 3rd Ring as if they were decimals and then multiply that number with the Multiplier.&lt;&#x2F;p&gt;
&lt;p&gt;For SMD resistors the pattern apparently repeats itself where the last digit on the package is a Multiplier for the other digits, resulting in a value in ohms. Also the form where there is an &lt;code&gt;R&lt;&#x2F;code&gt; in place of the decimal point is common for smaller values.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Podcasts</title>
        <published>2022-11-06T00:00:00+00:00</published>
        <updated>2022-11-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/podcasts/"/>
        <id>https://slatecave.net/notebook/podcasts/</id>
        
        <summary type="text">A list of podcasts I listen to and can recommend</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/podcasts/">&lt;p&gt;Note that these are mostly about IT and (I think) well known podcasts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;english-language-podcasts&quot;&gt;English Language Podcasts&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;foss-and-crafts&quot;&gt;FOSS and Crafts&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;fossandcrafts.org&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;fossandcrafts.org&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;FOSS and Crafts is an interdisciplinary exploration of collaborative creation. […]  We explore such topics as computer programming, craft production, user freedom and agency, especially informed by the principles of the F(L)OSS (Free, Libre, and Open Source Software) and free culture movements.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;postmarketos-podcast&quot;&gt;postmarketOS Podcast&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;cast.postmarketos.org&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;cast.postmarketos.org&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;You just found the corner of the Internet, where postmarketOS team members discuss whatever crazy development details we encounter while cooking up our favorite mobile Linux distribution. Besides news and anecdotes, once in a while we throw in an interview with an exciting guest who brings us their unique view on the wider mobile Linux scene.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;deutschsprachige-podcasts&quot;&gt;Deutschsprachige Podcasts&lt;&#x2F;h2&gt;
&lt;!--LANGUAGE:de--&gt;
&lt;h3 id=&quot;chaosradio&quot;&gt;Chaosradio&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;chaosradio.de&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;chaosradio.de&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Chaosradio ist der Podcast des Chaos Computer Club Berlin (CCCB). In dem (bis zu) zweistündigen Format informieren wir seit 1995 über technische und gesellschaftliche Themen. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chaosradio.de&#x2F;about&quot;&gt;Weiterlesen …&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;c-radar&quot;&gt;C-RadaR&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;www.c-radar.de&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;www.c-radar.de&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Monatliche Radiosendung des Chaos Computer Clubs auf Radio Darmstadt. Jeden 2ten Donnerstag im Monat, 21-23 Uhr. 103,4 MHz UKW &#x2F; DAB+ &#x2F; Stream. Tune In!&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;pentaradio&quot;&gt;Pentaradio&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;www.c3d2.de&amp;#x2F;radio.html&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;www.c3d2.de&amp;#x2F;radio.html
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Magazin für Netzkultur und Politik des Chaos Computer Clubs Dresden C3D2.
jeden vierten Dienstag im Monat 21:30 – 23:00 Uhr
&lt;cite&gt;(Beschreibung: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;coloradio.org&#x2F;?page_id=5199&quot;&gt;coloRadio&lt;&#x2F;a&gt;)&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Webdirectories</title>
        <published>2022-11-03T00:00:00+00:00</published>
        <updated>2025-02-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/webdirectories/"/>
        <id>https://slatecave.net/notebook/webdirectories/</id>
        
        <summary type="text">A collection of link collections I consider worth sharing</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/webdirectories/">&lt;h2 id=&quot;webrings&quot;&gt;Webrings&lt;&#x2F;h2&gt;
&lt;p&gt;Listed roughly in order of preference, it is &lt;em&gt;NOT&lt;&#x2F;em&gt; a ranking. Prefernce in this case means: In therms of how many sites I personally conider interesting. Webrings I found more recently or just don&#x27;t explore as often will naturally rank lower.&lt;&#x2F;p&gt;
&lt;p&gt;In case you are new to webrings: Webrings are sometimes members of other webrings and a few sites are members of a lot of webrings so the below are just some possible entry points.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;geekring&quot;&gt;Geekring&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;geekring.net&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;geekring.net
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;For all those funny, quirky, interesting, personal, strange, offbeat websites that&#x27;s not page 1 on the search engines.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;hotline-webring&quot;&gt;Hotline Webring&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;b&gt;Has no restrictions for joining and may contain objectionable content.&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;hotlinewebring.club&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;hotlinewebring.club&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Geekring with more retro themed websites.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-retronaut-webring&quot;&gt;The retronaut webring&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;b&gt;Has no restrictions for joining and may contain objectionable content.&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;webring.dinhe.net&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;webring.dinhe.net&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;A webring that contains all kinds of sites.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-yesterweb-ring&quot;&gt;The Yesterweb Ring&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;yesterweb.org&amp;#x2F;webring&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;yesterweb.org&amp;#x2F;webring&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This webring is for anyone who is tired of how boring and same-y the internet is today. It&#x27;s for anyone who is sick of seeing websites used purely to drive monetization, informative blogs that ask you to subscribe to see content.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;xxiivv-webring&quot;&gt;XXIIVV Webring&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;webring.xxiivv.com&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;webring.xxiivv.com&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This webring is an attempt to inspire artists &amp;amp; developers to build their websites and share traffic amongst each other. The ring welcomes hand-crafted wikis and portfolios.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;the-512kb-club&quot;&gt;The 512KB Club&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;512kb.club&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;512kb.club&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The 512KB Club is a collection of performance-focused web pages from across the Internet.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;More of a directory but sometimes considered a webring (it&#x27;s missin the ring-part though)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;envs-webring&quot;&gt;envs - webring&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;envs.net&amp;#x2F;ring&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;envs.net&amp;#x2F;ring&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;this webring can be joined by any user on envs.net.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;actual-web-directories&quot;&gt;Actual web directories&lt;&#x2F;h2&gt;
&lt;p&gt;The real phonebooks of the internet!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ooh-directory&quot;&gt;ooh.directory&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;ooh.directory&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;ooh.directory&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A collection of 2,295 blogs about every topic&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The counter in the description is probably outdated by the time you are reding this 😃.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sites-with-lots-of-interesting-links&quot;&gt;Sites with lots of interesting links&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;seirdy-s-home&quot;&gt;Seirdy’s Home&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;seirdy.one&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;seirdy.one&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Not only a source of great links but also great articles containing them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tinygem&quot;&gt;TinyGem&lt;&#x2F;h3&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;tinygem.org&amp;#x2F;&quot; &gt;
		https:&amp;#x2F;&amp;#x2F;tinygem.org&amp;#x2F;
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Have you ever bookmarked a page and worried that you will not find the same stuff next time you are there? Keep the pages on the web saved forever.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;A searchable link aggregator for links people find interesting.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>ASCII Table</title>
        <published>2022-10-16T00:00:00+00:00</published>
        <updated>2024-08-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/ascii/"/>
        <id>https://slatecave.net/notebook/ascii/</id>
        
        <summary type="text">A simple, plain ASCII-Table</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/ascii/">&lt;p&gt;This ASCII-Table is mostly derived from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.unicode.org&#x2F;Public&#x2F;UCD&#x2F;latest&#x2F;&quot;&gt;Unicode 15.0 Documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mostly-printable-characters&quot;&gt;Mostly Printable Characters&lt;&#x2F;h2&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-action-next&quot; href=&quot;#control-characters&quot; &gt;
		Skip to the control characters table
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Codes 0x20 to 0x7E are referred to as the printable characters, 0x7F is a control character. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ASCII#Printable_characters&quot;&gt;Wikipedia has more background information.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;character-tables&quot;&gt;
&lt;table class=&quot;character-table&quot;&gt;
&lt;caption&gt;Numbers and Specials&lt;&#x2F;caption&gt;
&lt;tr&gt;&lt;th&gt;Char&lt;&#x2F;th&gt;&lt;th&gt;Hex&lt;&#x2F;th&gt;&lt;th&gt;Dec&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SPACE&lt;&#x2F;td&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;!&lt;&#x2F;td&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&quot;&lt;&#x2F;td&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;#&lt;&#x2F;td&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;$&lt;&#x2F;td&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;%&lt;&#x2F;td&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;&lt;&#x2F;td&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&#x27;&lt;&#x2F;td&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;(&lt;&#x2F;td&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;)&lt;&#x2F;td&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;*&lt;&#x2F;td&gt;&lt;td&gt;2a&lt;&#x2F;td&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;+&lt;&#x2F;td&gt;&lt;td&gt;2b&lt;&#x2F;td&gt;&lt;td&gt;43&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;,&lt;&#x2F;td&gt;&lt;td&gt;2c&lt;&#x2F;td&gt;&lt;td&gt;44&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;2d&lt;&#x2F;td&gt;&lt;td&gt;45&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;.&lt;&#x2F;td&gt;&lt;td&gt;2e&lt;&#x2F;td&gt;&lt;td&gt;46&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&#x2F;&lt;&#x2F;td&gt;&lt;td&gt;2f&lt;&#x2F;td&gt;&lt;td&gt;47&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;48&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;50&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;51&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;td&gt;52&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;td&gt;53&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;td&gt;54&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;td&gt;55&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;td&gt;56&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;57&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;:&lt;&#x2F;td&gt;&lt;td&gt;3a&lt;&#x2F;td&gt;&lt;td&gt;58&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;;&lt;&#x2F;td&gt;&lt;td&gt;3b&lt;&#x2F;td&gt;&lt;td&gt;59&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;lt;&lt;&#x2F;td&gt;&lt;td&gt;3c&lt;&#x2F;td&gt;&lt;td&gt;60&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;=&lt;&#x2F;td&gt;&lt;td&gt;3d&lt;&#x2F;td&gt;&lt;td&gt;61&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;gt;&lt;&#x2F;td&gt;&lt;td&gt;3e&lt;&#x2F;td&gt;&lt;td&gt;62&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;td&gt;3f&lt;&#x2F;td&gt;&lt;td&gt;63&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;table class=&quot;character-table&quot;&gt;
&lt;caption&gt;Uppercase&lt;&#x2F;caption&gt;
&lt;tr&gt;&lt;th&gt;Char&lt;&#x2F;th&gt;&lt;th&gt;Hex&lt;&#x2F;th&gt;&lt;th&gt;Dec&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;@&lt;&#x2F;td&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;A&lt;&#x2F;td&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;td&gt;65&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;B&lt;&#x2F;td&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;td&gt;66&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;C&lt;&#x2F;td&gt;&lt;td&gt;43&lt;&#x2F;td&gt;&lt;td&gt;67&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;D&lt;&#x2F;td&gt;&lt;td&gt;44&lt;&#x2F;td&gt;&lt;td&gt;68&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;E&lt;&#x2F;td&gt;&lt;td&gt;45&lt;&#x2F;td&gt;&lt;td&gt;69&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;F&lt;&#x2F;td&gt;&lt;td&gt;46&lt;&#x2F;td&gt;&lt;td&gt;70&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;G&lt;&#x2F;td&gt;&lt;td&gt;47&lt;&#x2F;td&gt;&lt;td&gt;71&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;H&lt;&#x2F;td&gt;&lt;td&gt;48&lt;&#x2F;td&gt;&lt;td&gt;72&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;I&lt;&#x2F;td&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;td&gt;73&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;J&lt;&#x2F;td&gt;&lt;td&gt;4a&lt;&#x2F;td&gt;&lt;td&gt;74&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;K&lt;&#x2F;td&gt;&lt;td&gt;4b&lt;&#x2F;td&gt;&lt;td&gt;75&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;L&lt;&#x2F;td&gt;&lt;td&gt;4c&lt;&#x2F;td&gt;&lt;td&gt;76&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;M&lt;&#x2F;td&gt;&lt;td&gt;4d&lt;&#x2F;td&gt;&lt;td&gt;77&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;N&lt;&#x2F;td&gt;&lt;td&gt;4e&lt;&#x2F;td&gt;&lt;td&gt;78&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;O&lt;&#x2F;td&gt;&lt;td&gt;4f&lt;&#x2F;td&gt;&lt;td&gt;79&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;P&lt;&#x2F;td&gt;&lt;td&gt;50&lt;&#x2F;td&gt;&lt;td&gt;80&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Q&lt;&#x2F;td&gt;&lt;td&gt;51&lt;&#x2F;td&gt;&lt;td&gt;81&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;R&lt;&#x2F;td&gt;&lt;td&gt;52&lt;&#x2F;td&gt;&lt;td&gt;82&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;S&lt;&#x2F;td&gt;&lt;td&gt;53&lt;&#x2F;td&gt;&lt;td&gt;83&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;T&lt;&#x2F;td&gt;&lt;td&gt;54&lt;&#x2F;td&gt;&lt;td&gt;84&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;U&lt;&#x2F;td&gt;&lt;td&gt;55&lt;&#x2F;td&gt;&lt;td&gt;85&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;V&lt;&#x2F;td&gt;&lt;td&gt;56&lt;&#x2F;td&gt;&lt;td&gt;86&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;W&lt;&#x2F;td&gt;&lt;td&gt;57&lt;&#x2F;td&gt;&lt;td&gt;87&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;58&lt;&#x2F;td&gt;&lt;td&gt;88&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Y&lt;&#x2F;td&gt;&lt;td&gt;59&lt;&#x2F;td&gt;&lt;td&gt;89&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Z&lt;&#x2F;td&gt;&lt;td&gt;5a&lt;&#x2F;td&gt;&lt;td&gt;90&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;[&lt;&#x2F;td&gt;&lt;td&gt;5b&lt;&#x2F;td&gt;&lt;td&gt;91&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;\&lt;&#x2F;td&gt;&lt;td&gt;5c&lt;&#x2F;td&gt;&lt;td&gt;92&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;]&lt;&#x2F;td&gt;&lt;td&gt;5d&lt;&#x2F;td&gt;&lt;td&gt;93&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;^&lt;&#x2F;td&gt;&lt;td&gt;5e&lt;&#x2F;td&gt;&lt;td&gt;94&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;_&lt;&#x2F;td&gt;&lt;td&gt;5f&lt;&#x2F;td&gt;&lt;td&gt;95&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;table class=&quot;character-table&quot;&gt;
&lt;caption&gt;Lowercase&lt;&#x2F;caption&gt;
&lt;tr&gt;&lt;th&gt;Char&lt;&#x2F;th&gt;&lt;th&gt;Hex&lt;&#x2F;th&gt;&lt;th&gt;Dec&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;#96;&lt;&#x2F;td&gt;&lt;td&gt;60&lt;&#x2F;td&gt;&lt;td&gt;96&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;a&lt;&#x2F;td&gt;&lt;td&gt;61&lt;&#x2F;td&gt;&lt;td&gt;97&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;b&lt;&#x2F;td&gt;&lt;td&gt;62&lt;&#x2F;td&gt;&lt;td&gt;98&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;c&lt;&#x2F;td&gt;&lt;td&gt;63&lt;&#x2F;td&gt;&lt;td&gt;99&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;d&lt;&#x2F;td&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;td&gt;100&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;e&lt;&#x2F;td&gt;&lt;td&gt;65&lt;&#x2F;td&gt;&lt;td&gt;101&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;f&lt;&#x2F;td&gt;&lt;td&gt;66&lt;&#x2F;td&gt;&lt;td&gt;102&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;g&lt;&#x2F;td&gt;&lt;td&gt;67&lt;&#x2F;td&gt;&lt;td&gt;103&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;h&lt;&#x2F;td&gt;&lt;td&gt;68&lt;&#x2F;td&gt;&lt;td&gt;104&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;i&lt;&#x2F;td&gt;&lt;td&gt;69&lt;&#x2F;td&gt;&lt;td&gt;105&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;j&lt;&#x2F;td&gt;&lt;td&gt;6a&lt;&#x2F;td&gt;&lt;td&gt;106&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;k&lt;&#x2F;td&gt;&lt;td&gt;6b&lt;&#x2F;td&gt;&lt;td&gt;107&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;l&lt;&#x2F;td&gt;&lt;td&gt;6c&lt;&#x2F;td&gt;&lt;td&gt;108&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;m&lt;&#x2F;td&gt;&lt;td&gt;6d&lt;&#x2F;td&gt;&lt;td&gt;109&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;n&lt;&#x2F;td&gt;&lt;td&gt;6e&lt;&#x2F;td&gt;&lt;td&gt;110&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;o&lt;&#x2F;td&gt;&lt;td&gt;6f&lt;&#x2F;td&gt;&lt;td&gt;111&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;p&lt;&#x2F;td&gt;&lt;td&gt;70&lt;&#x2F;td&gt;&lt;td&gt;112&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;q&lt;&#x2F;td&gt;&lt;td&gt;71&lt;&#x2F;td&gt;&lt;td&gt;113&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;r&lt;&#x2F;td&gt;&lt;td&gt;72&lt;&#x2F;td&gt;&lt;td&gt;114&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;s&lt;&#x2F;td&gt;&lt;td&gt;73&lt;&#x2F;td&gt;&lt;td&gt;115&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;t&lt;&#x2F;td&gt;&lt;td&gt;74&lt;&#x2F;td&gt;&lt;td&gt;116&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;u&lt;&#x2F;td&gt;&lt;td&gt;75&lt;&#x2F;td&gt;&lt;td&gt;117&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;v&lt;&#x2F;td&gt;&lt;td&gt;76&lt;&#x2F;td&gt;&lt;td&gt;118&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;w&lt;&#x2F;td&gt;&lt;td&gt;77&lt;&#x2F;td&gt;&lt;td&gt;119&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;x&lt;&#x2F;td&gt;&lt;td&gt;78&lt;&#x2F;td&gt;&lt;td&gt;120&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;y&lt;&#x2F;td&gt;&lt;td&gt;79&lt;&#x2F;td&gt;&lt;td&gt;121&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;z&lt;&#x2F;td&gt;&lt;td&gt;7a&lt;&#x2F;td&gt;&lt;td&gt;122&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;{&lt;&#x2F;td&gt;&lt;td&gt;7b&lt;&#x2F;td&gt;&lt;td&gt;123&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;|&lt;&#x2F;td&gt;&lt;td&gt;7c&lt;&#x2F;td&gt;&lt;td&gt;124&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;}&lt;&#x2F;td&gt;&lt;td&gt;7d&lt;&#x2F;td&gt;&lt;td&gt;125&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;~&lt;&#x2F;td&gt;&lt;td&gt;7e&lt;&#x2F;td&gt;&lt;td&gt;126&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DEL&lt;&#x2F;td&gt;&lt;td&gt;7f&lt;&#x2F;td&gt;&lt;td&gt;127&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;b&gt;Note on the &lt;code&gt;DEL&lt;&#x2F;code&gt; code:&lt;&#x2F;b&gt;The DEL being 0x7F, meaning it has all 7 bits set, probably originates from how one &quot;deleted&quot; something from paper tape, by just punching all of the holes one could &quot;erase&quot; the original character. Its meaning is ambigious, but it usually refers to a backspace.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Fun Fact:&lt;&#x2F;b&gt; The lowercase characters in ASCII were an &quot;aftertought&quot; and only added later in 1965, two years after the initial release.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;control-characters&quot;&gt;Control characters&lt;&#x2F;h2&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Char&lt;&#x2F;th&gt;&lt;th&gt;Hex&lt;&#x2F;th&gt;&lt;th&gt;Oct&lt;&#x2F;th&gt;&lt;th&gt;Dec&lt;&#x2F;th&gt;&lt;th&gt;Name&lt;&#x2F;th&gt;&lt;th&gt;C Esc&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;NUL&lt;&#x2F;td&gt;&lt;td&gt;00&lt;&#x2F;td&gt;&lt;td&gt;000&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Null&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SOH&lt;&#x2F;td&gt;&lt;td&gt;01&lt;&#x2F;td&gt;&lt;td&gt;001&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Start Of Heading&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;STX&lt;&#x2F;td&gt;&lt;td&gt;02&lt;&#x2F;td&gt;&lt;td&gt;002&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Start Of Text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ETX&lt;&#x2F;td&gt;&lt;td&gt;03&lt;&#x2F;td&gt;&lt;td&gt;003&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;End Of Text&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;EOT&lt;&#x2F;td&gt;&lt;td&gt;04&lt;&#x2F;td&gt;&lt;td&gt;004&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;End Of Transmission&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ENQ&lt;&#x2F;td&gt;&lt;td&gt;05&lt;&#x2F;td&gt;&lt;td&gt;005&lt;&#x2F;td&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Enquiry&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ACK&lt;&#x2F;td&gt;&lt;td&gt;06&lt;&#x2F;td&gt;&lt;td&gt;006&lt;&#x2F;td&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Acknowledge&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BEL&lt;&#x2F;td&gt;&lt;td&gt;07&lt;&#x2F;td&gt;&lt;td&gt;007&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Bell &#x2F; Alert&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\a&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BS&lt;&#x2F;td&gt;&lt;td&gt;08&lt;&#x2F;td&gt;&lt;td&gt;010&lt;&#x2F;td&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;BAckspace&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;HT&lt;&#x2F;td&gt;&lt;td&gt;09&lt;&#x2F;td&gt;&lt;td&gt;011&lt;&#x2F;td&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;HOrizontal Tab&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\t&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;LF&lt;&#x2F;td&gt;&lt;td&gt;0a&lt;&#x2F;td&gt;&lt;td&gt;012&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Line Feed&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\n&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;VT&lt;&#x2F;td&gt;&lt;td&gt;0b&lt;&#x2F;td&gt;&lt;td&gt;013&lt;&#x2F;td&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Vertical Tab&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\v&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;FF&lt;&#x2F;td&gt;&lt;td&gt;0c&lt;&#x2F;td&gt;&lt;td&gt;014&lt;&#x2F;td&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Form Feed&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\f&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;CR&lt;&#x2F;td&gt;&lt;td&gt;0d&lt;&#x2F;td&gt;&lt;td&gt;015&lt;&#x2F;td&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Carriage Return&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\r&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SO&lt;&#x2F;td&gt;&lt;td&gt;0e&lt;&#x2F;td&gt;&lt;td&gt;016&lt;&#x2F;td&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Shift Out&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SI&lt;&#x2F;td&gt;&lt;td&gt;0f&lt;&#x2F;td&gt;&lt;td&gt;017&lt;&#x2F;td&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Shift In&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DLE&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;020&lt;&#x2F;td&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Data Link Escape&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DC1&lt;&#x2F;td&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;021&lt;&#x2F;td&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Device Control 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DC2&lt;&#x2F;td&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;022&lt;&#x2F;td&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Device Control 2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DC3&lt;&#x2F;td&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;023&lt;&#x2F;td&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Device Control 3&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;DC4&lt;&#x2F;td&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;024&lt;&#x2F;td&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Device Control 4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;NAK&lt;&#x2F;td&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;025&lt;&#x2F;td&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Negative Acknowledge&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SYN&lt;&#x2F;td&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;026&lt;&#x2F;td&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Synchronous Idle&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ETB&lt;&#x2F;td&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;027&lt;&#x2F;td&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;End Of Transmission Block&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;CAN&lt;&#x2F;td&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;030&lt;&#x2F;td&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Cancel&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;EM&lt;&#x2F;td&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;031&lt;&#x2F;td&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;End Of Medium&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;SUB&lt;&#x2F;td&gt;&lt;td&gt;1a&lt;&#x2F;td&gt;&lt;td&gt;032&lt;&#x2F;td&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Substitute&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;ESC&lt;&#x2F;td&gt;&lt;td&gt;1b&lt;&#x2F;td&gt;&lt;td&gt;033&lt;&#x2F;td&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Escape&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;\e&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;FS&lt;&#x2F;td&gt;&lt;td&gt;1c&lt;&#x2F;td&gt;&lt;td&gt;034&lt;&#x2F;td&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;File Seperator&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;GS&lt;&#x2F;td&gt;&lt;td&gt;1d&lt;&#x2F;td&gt;&lt;td&gt;035&lt;&#x2F;td&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Group Seperator&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;RS&lt;&#x2F;td&gt;&lt;td&gt;1e&lt;&#x2F;td&gt;&lt;td&gt;036&lt;&#x2F;td&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Record Seperator&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;US&lt;&#x2F;td&gt;&lt;td&gt;1f&lt;&#x2F;td&gt;&lt;td&gt;037&lt;&#x2F;td&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td class=&quot;name&quot;&gt;Unit Seperator&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; The Names have been titlecased to make them easier to read.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;notation&quot;&gt;Notation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;escaping-in-scripting-and-programming&quot;&gt;Escaping in Scripting and Programming&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes in languages one can&#x27;t use all the characters available in the source file, especially when using control characters. Encoding these as other characters is called &lt;i&gt;escaping&lt;&#x2F;i&gt;. This usually happens with text between double quotes &lt;code&gt;&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There are differences between languages and implementations but the general rules are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Special characters preceeded by a backslash &lt;code&gt;\&lt;&#x2F;code&gt; are taken literally. (i.e. &lt;code&gt;\&quot;&lt;&#x2F;code&gt; or &lt;code&gt;\\&lt;&#x2F;code&gt;) (The exact behaviour varies &lt;em&gt;a lot&lt;&#x2F;em&gt; by language.)&lt;&#x2F;li&gt;
&lt;li&gt;Latin characters preceeded by a backslash to generate control characters (i.e. &lt;code&gt;\n&lt;&#x2F;code&gt;) (The &lt;i&gt;C Esc&lt;&#x2F;i&gt; column)&lt;&#x2F;li&gt;
&lt;li&gt;Hexadecimal value of the character prefixed by &lt;code&gt;\x&lt;&#x2F;code&gt; (i.e. &lt;code&gt;0x1b&lt;&#x2F;code&gt;) (should work almost everywhere)&lt;&#x2F;li&gt;
&lt;li&gt;Octal encoding prefixed by just a backslash (i.e. &lt;code&gt;\033&lt;&#x2F;code&gt;) (&lt;a href=&quot;&#x2F;notebook&#x2F;ansi-escape-sequences&#x2F;#setting-text-color-and-effects&quot;&gt;Use this when using &lt;code&gt;printf&lt;&#x2F;code&gt; on the command line&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;b&gt;Note:&lt;&#x2F;b&gt; &lt;code&gt;C Esc&lt;&#x2F;code&gt; here is short C-Escape as the C language apparantly started this way of excaping characters in strings. It is now used by almost all modern languages and in other contexts. i.e. &lt;code&gt;printf&lt;&#x2F;code&gt;, &lt;code&gt;sed&lt;&#x2F;code&gt;, etc. exact support may vary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;escaping-in-xml-and-html&quot;&gt;Escaping in XML and HTML&lt;&#x2F;h3&gt;
&lt;p&gt;XML and html have their own way of escaping non-printable characters, this involves a sequence sandwiched between an ampersand &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt; and a semicolon &lt;code&gt;;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In general Characters can be escaped using &lt;code&gt;&amp;amp;#&amp;lt;dec&amp;gt;;&lt;&#x2F;code&gt; where &lt;code&gt;&amp;lt;dec&amp;gt;&lt;&#x2F;code&gt; is replaced by the decimal value associted with the character. (i.e, &lt;code&gt;&amp;amp;#38;&lt;&#x2F;code&gt; to encode an ampersand &lt;code&gt;&amp;amp;&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;There are also named escapes to make remembering them easier:&lt;&#x2F;p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Character&lt;&#x2F;th&gt;&lt;th&gt;XML-escape&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;&amp;amp;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;amp;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;lt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;&amp;quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;&amp;amp;quot;&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;table&gt;
&lt;h3 id=&quot;control-and-shift&quot;&gt;Control and Shift&lt;&#x2F;h3&gt;
&lt;p&gt;With the ASCII table control and shift keys an be implemented using simple addition and substraction.&lt;&#x2F;p&gt;
&lt;p&gt;The lowercase character can be obtained by adding 32 (0x20) to the code of the corresponding uppercase character and the control key goes 64 (0x40) in the opposite direction.&lt;&#x2F;p&gt;
&lt;p&gt;With that &lt;kbd&gt;ctrl+c&lt;&#x2F;kbd&gt; maps to code 3 &quot;End of Text&quot;. And &lt;kbd&gt;ctrl+d&lt;&#x2F;kbd&gt; maps to &quot;End of Transmission&quot;. You may know those shortcuts from the terminal, they hopefully make a bit more sense now.&lt;&#x2F;p&gt;
&lt;p&gt;Control characters are sometimes written down&#x2F;printed as the character one gets when adding 64 to the control characters value prefixed by an &lt;code&gt;^&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This maps escape to &lt;code&gt;^]&lt;&#x2F;code&gt; and the nullbyte to &lt;code&gt;^@&lt;&#x2F;code&gt;. (You have probably seen those when opening a binary file in a text editor.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unicode&quot;&gt;Unicode&lt;&#x2F;h2&gt;
&lt;p&gt;Creating a unicode table andkeeping it updated is out of scope here, besides that: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_Unicode_characters&quot;&gt;Wikipedia has a List of Unicode Characters&lt;&#x2F;a&gt; and there are the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.unicode.org&#x2F;charts&#x2F;&quot;&gt;offical Unicode Character Code Charts&lt;&#x2F;a&gt;. (Plus a whole lot of other unicode tables out there.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Notation Hint:&lt;&#x2F;b&gt; Unicode codepoints (that is the number assigned in the unicode standard, not the binary character representation) are written &lt;code&gt;U+&amp;lt;hex&amp;gt;&lt;&#x2F;code&gt; where &lt;code&gt;&amp;lt;hex&amp;gt;&lt;&#x2F;code&gt; is the codepint number in hexadecimal. Example: &lt;code&gt;U+1f603&lt;&#x2F;code&gt; for 😃.&lt;&#x2F;p&gt;
&lt;p&gt;There is also a little commandline tool called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arp242&#x2F;uni&quot;&gt;&lt;code&gt;uni&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, that is pretty good at providing a searchable unicode table.&lt;&#x2F;p&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Shell Snippets</title>
        <published>2022-10-16T00:00:00+00:00</published>
        <updated>2023-05-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Slatian
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://slatecave.net/notebook/shell/"/>
        <id>https://slatecave.net/notebook/shell/</id>
        
        <summary type="text">Some shellcode I catch myself writing over and over again.</summary>
        
        <content type="html" xml:base="https://slatecave.net/notebook/shell/">&lt;p&gt;The snippets on this site are intended for getting copied and being useful so please do that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;argument-parser&quot;&gt;Argument Parser&lt;&#x2F;h2&gt;
&lt;p&gt;A simple argument parser for bash.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Make the script fail when a command fails&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Settings variables go here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;FOO&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;show_help&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;cat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Usage: foo &amp;lt;&amp;lt;options&amp;gt;&amp;gt; &amp;lt;bar&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Blubber blah blah ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-logical-expression&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; -gt&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-logical-expression&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;		-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;			FOO&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;			shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;		-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-regexp&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; show_help&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt; exit&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		*)&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt; printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;Unknown option: %s\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt; exit&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;	esac&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Logic goes here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;FOO&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;set-e-and-shift&quot;&gt;&lt;code&gt;set -e&lt;&#x2F;code&gt; and &lt;code&gt;shift&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;set -e&lt;&#x2F;code&gt; option tells the shell to stop executing a script once a command fails. This is important when using a &lt;code&gt;shift&lt;&#x2F;code&gt; in this kind of while loop where the loop exiting depends on the &lt;code&gt;shift&lt;&#x2F;code&gt; working.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Example:&lt;&#x2F;b&gt; The shift may fail if it is told to move 2 arguments out (&lt;code&gt;shift 2&lt;&#x2F;code&gt;) but there is only one given. In the example above that would be fulfilled when passing &lt;code&gt;--foo&lt;&#x2F;code&gt; as the last argument (a relatively easy to make mistake). If the shift silently failed the argument counter would never reach 0 and the script would be stuck in an endless loop.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hook-helper&quot;&gt;Hook Helper&lt;&#x2F;h2&gt;
&lt;p&gt;This little function calls its argument as an ad-hoc shellscript if it is non-empty, if it returns a nonzero, one should call the default action.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; on fail do default action&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;run_hook&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-logical-expression&quot;&gt;	[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-logical-expression&quot;&gt; ]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; bash&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;figure&gt;
	&lt;figcaption&gt;Example of how this little helper is intended to be used&lt;&#x2F;figcaption&gt;
	&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;export&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; VARIABLE_WHICH_IS_USEFUL_FOR_HOOK&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;something&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;run_hook&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;HOOK_COMMAND&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; default_action&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
	
&lt;&#x2F;figure&gt;
&lt;p&gt;An &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;slatian&#x2F;dotfiles&#x2F;src&#x2F;branch&#x2F;main&#x2F;.local&#x2F;bin&#x2F;filedialog&quot;&gt;example of this being used&lt;&#x2F;a&gt; can be found in my dotfiles with the filedialog. (Fun fact: It was created for this script)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;grep-regex-match-helper&quot;&gt;Grep Regex Match Helper&lt;&#x2F;h2&gt;
&lt;p&gt;This function pipes its first argument into a &lt;code&gt;grep -q&lt;&#x2F;code&gt; command which is given the rest of the arguments.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;matches&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;	TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;	shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;	printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;%s\n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;TEXT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Example usage: &lt;code&gt;matches &quot;$FOO&quot; &quot;^[0-9]$&quot; &amp;amp;&amp;amp; echo &quot;FOO is a number! :)&quot; || FOO=0&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It can also be useful to implement some kind of heuristics based on which patterns occur in a text.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bash-arrays&quot;&gt;Bash Arrays&lt;&#x2F;h2&gt;
&lt;p&gt;Bash has arrays so one doesn&#x27;t have to care about delimiters too much.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;b&gt;Note on compatibility:&lt;&#x2F;b&gt; These arrays only work in bash which isn&#x27;t isntalled everywhere (dash is a popular alternative). Please use &lt;code&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;code&gt; instead of &lt;s&gt;&lt;code&gt;#!&#x2F;bin&#x2F;sh&lt;&#x2F;code&gt;&lt;&#x2F;s&gt; to indicate that your script requires bash to work.&lt;&#x2F;p&gt;
&lt;p&gt;Create an array:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;empty_array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;can go&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt; echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; here&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Appending to an exisiting Array:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;multiple&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;elements&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These can then be accessed with 0 based indices:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; prints out: can go&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To get the number of elements in an array:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An array can expand to multiple arguments:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&amp;gt; %s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Compare with the output of:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;printf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&amp;gt; %s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; foo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bar&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; baz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which is also useful for &lt;code&gt;for&lt;&#x2F;code&gt;-loops:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;for&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin&quot;&gt;	echo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control&quot;&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And to clean up:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; remove element at index 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;uset&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; array[1]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; remove the whole array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name&quot;&gt;uset&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; array&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is more to bash arrays (including associative arrays) …&lt;&#x2F;p&gt;
&lt;p class=&quot;button-paragraph&quot;&gt;
	&lt;a class=&quot;decoration-destination-text&quot; href=&quot;https:&amp;#x2F;&amp;#x2F;www.gnu.org&amp;#x2F;software&amp;#x2F;bash&amp;#x2F;manual&amp;#x2F;html_node&amp;#x2F;Arrays.html&quot; &gt;
		Check out The Bash Reference Manual on Arrays
	&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;&#x2F;h2&gt;

	

&lt;ul class=&quot;link-list&quot;&gt;
&lt;li&gt;&lt;a class=&quot;decoration-action-next&quot; href=&quot;&#x2F;notebook&#x2F;ansi-escape-sequences&quot;&gt;ANSI Escape Sequences&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;decoration-action-next&quot; href=&quot;&#x2F;notebook&#x2F;portable-shell&quot;&gt;Portable Shellscripting&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

</content>
    </entry>
</feed>

