<feed xmlns="http://www.w3.org/2005/Atom">
<title>ZEKAR's Blog</title>
<link href="https://zekar.neocities.org/atom.xml" rel="self" />
<link href="https://zekar.neocities.org/" />
<updated>2026-06-10T18:01:11-06:00</updated>
<author>
<name>zekar</name>
</author>
<id>https://zekar.neocities.org/</id>
    <entry>
    <title>Why I built my own static site generator</title>
    <link href="https://zekar.neocities.org/out/posts/ssg.html" />
    <id>https://zekar.neocities.org/out/posts/ssg.html</id>
    <updated>2026-05-24T16:48:45-06:00</updated>
    <content type="html">&lt;h1 id="why-i-built-my-own-static-site-generator"&gt;Why I built my own
static site generator&lt;/h1&gt;
&lt;p&gt;Since the beginning of this website, I’ve always used some kind of
static site generator (SSG). I simply REFUSE to write HTML
&lt;strong&gt;manually.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="2026-05-24-123712.png" /&gt;&lt;/p&gt;
&lt;p&gt;Not only that, but each time I write something I would have to update
the index with the corresponding date and keep track of everything… Such
a pain. That’s why SSG were invented in the first place, I can write a
post in a simple markup format (like markdown), and have it converted
and structured automatically to HTML.&lt;/p&gt;
&lt;h2 id="using-hugo"&gt;Using Hugo&lt;/h2&gt;
&lt;p&gt;Like everyone else, I started out with &lt;a href="https://gohugo.io/"
target="_blank" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;, and I
&lt;strong&gt;really&lt;/strong&gt; hated it. I started out watching Luke Smith’s
tutorials on Hugo (Is it only me that thinks using hugo is completely
out of character for Luke Smith?). After a &lt;a
href="https://codeberg.org/zekar/website-old" target="_blank"
rel="noopener noreferrer"&gt;few&lt;/a&gt; &lt;a
href="https://codeberg.org/zekar/website" target="_blank"
rel="noopener noreferrer"&gt;iterations&lt;/a&gt; I started to think it was
overly complicated… shortcodes? archetypes? it was too muchy. For me,
that felt like the only choice so I stuck with it.&lt;/p&gt;
&lt;p&gt;Honestly, I’d much rather use Hugo than a bloated node framework like
react or vue… or whatever the hell kids nowadays are using. But still,
it’s VERY complex, it has every feature in the world, making it feel
bloated. Which is precisely the OPPOSITE of what good software is.&lt;/p&gt;
&lt;p&gt;Hugo uses Go templates, which I find unnecessarily hard to read. You
need to configure Hugo with a toml file, archetypes, layouts, modules
and a lot of things. Just look at the number of directories in the setup
I mentioned earlier.&lt;/p&gt;
&lt;p&gt;&lt;img src="2026-05-24-124426.png" /&gt;&lt;/p&gt;
&lt;p&gt;What are archetypes? What are layouts? No idea. I could search for
it, but really, I didn’t have the need for that. Features you don’t use
have a name: &lt;strong&gt;bloat&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="using-staw"&gt;Using staw&lt;/h2&gt;
&lt;p&gt;I don’t know why I didn’t search for alternatives earlier. But when I
stumbled upon a site that said was “staw powered” (specifically &lt;a
href="https://sta.li" target="_blank"
rel="noopener noreferrer"&gt;sta.li&lt;/a&gt;) and it piqued my interest. It was
a minimal static site generator written in go by none other than &lt;a
href="https://garbe.ca" target="_blank" rel="noopener noreferrer"&gt;Anselm
R. Garbe&lt;/a&gt;, the mind behind &lt;a href="https://suckless.org"
target="_blank" rel="noopener noreferrer"&gt;suckless.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Don’t get me wrong, I think staw is an amazing piece of software. But
it didn’t exactly generate what I was looking for. I tried to hack on it
for &lt;a href="https://codeberg.org/zekar/staw/commits/branch/master"
target="_blank" rel="noopener noreferrer"&gt;a while&lt;/a&gt; but I wasn’t
completely satisfied with the result. By the end it was almost
unrecognizable (Ship of Theseus ts). I &lt;strong&gt;need&lt;/strong&gt; an RSS/Atom
feed to be happy, and a bit more structure in my site. Also… I don’t
have multiple sites lol.&lt;/p&gt;
&lt;p&gt;The biggest problem I had with staw is that it’s written in Go.
Nothing against Go, just that I’m not particularly prolific in it. So I
always relied on an LLM to help me out to add and remove features.
Undoubtedly, this resulted in a mess of a codebase which made
maintaining it kind of a pain. Also, it had a weird template lol.&lt;/p&gt;
&lt;h2 id="creating-my-own"&gt;Creating my own&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“If you want it done right, you should just do it
yourself”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I thought about making my own static site generator. Why would I?
probably a lot of people had already done this and there is a bajillion
SSG out there. Surely &lt;strong&gt;&lt;em&gt;one&lt;/em&gt;&lt;/strong&gt; does what I want.
That’s right, but the main problem would be that I didn’t write it.
Sounds narcissistic, I know. But if I wrote the actual program, I would
be an &lt;em&gt;expert&lt;/em&gt; on how it works, how to add new features and how
it works internally.&lt;/p&gt;
&lt;p&gt;Take a step back and think for a moment about what does a SSG
&lt;strong&gt;actually&lt;/strong&gt; do; transform text. It transforms from
Markdown into HTML. And there are already several tools that accomplish
this task, notoriously &lt;strong&gt;pandoc.&lt;/strong&gt; I use pandoc for a lot
of things (mostly converting markdown to pdf for school work) so I was
already familiar on how it worked. Pandoc is &lt;em&gt;“a universal document
converter,”&lt;/em&gt; so converting Markdown to HTML would be normal work for
it.&lt;/p&gt;
&lt;p&gt;Pandoc would convert .md files into html. I just need to generate
lists for indexes, generate an rss feed with the html content, structure
the site. Sounds like a job for a &lt;strong&gt;shell script.&lt;/strong&gt;
(Specifically a &lt;a href="../articles/fish-shell.html"&gt;posix-compliant
one&lt;/a&gt;)&lt;/p&gt;
&lt;h3 id="my-requirements-were-simple-enough"&gt;My requirements were simple
enough&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Static pages (makes hosting &lt;em&gt;way&lt;/em&gt; easier)&lt;/li&gt;
&lt;li&gt;Low resource usage (easily accomplished by writing a simple template
and simple styling.)&lt;/li&gt;
&lt;li&gt;Readable in tools like &lt;code&gt;w3m&lt;/code&gt; (Just minimize javascript
lol)&lt;/li&gt;
&lt;li&gt;RSS/Atom feed (EVERYTHING should provide an RSS feed.
Non-negotiable)&lt;/li&gt;
&lt;li&gt;A general &lt;a href="/index.html" target="_blank"
rel="noopener noreferrer"&gt;index&lt;/a&gt; with all pages&lt;/li&gt;
&lt;li&gt;Subdirectories with their own indexes (for article/post
separation)&lt;/li&gt;
&lt;li&gt;Dates (my website went way too long without dates)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of them are self-explanatory, here are some interesting
challenges I solved though.&lt;/p&gt;
&lt;h3 id="feed"&gt;Feed&lt;/h3&gt;
&lt;p&gt;You can find the generated feed at &lt;a href="/atom.xml"
target="_blank" rel="noopener noreferrer"&gt;atom.xml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What I did was just initialize it with some content and then add
every entry for each page. The hardest part was definitely following the
&lt;strong&gt;very strict&lt;/strong&gt; standard for a &lt;strong&gt;valid&lt;/strong&gt; atom
feed.&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;cat&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;lt;EOF&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$FEED&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;feed xmlns=&amp;quot;http://www.w3.org/2005/Atom&amp;quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$SITE_TITLE&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;link href=&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$SITE_URL&lt;/span&gt;&lt;span class="st"&gt;/atom.xml&amp;quot; rel=&amp;quot;self&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;link href=&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$SITE_URL&lt;/span&gt;&lt;span class="st"&gt;/&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;updated&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="fu"&gt;date&lt;/span&gt; &lt;span class="at"&gt;--iso&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;seconds&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/updated&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;author&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="fu"&gt;git&lt;/span&gt; config user.name&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;/author&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$SITE_URL&lt;/span&gt;&lt;span class="st"&gt;/&amp;lt;/id&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-12"&gt;&lt;a href="#cb1-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-13"&gt;&lt;a href="#cb1-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# This gets executed for each page&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-14"&gt;&lt;a href="#cb1-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;append_to_feed()&lt;/span&gt; &lt;span class="kw"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-15"&gt;&lt;a href="#cb1-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;raw_html&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$1&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-16"&gt;&lt;a href="#cb1-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;html_path&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$2&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-17"&gt;&lt;a href="#cb1-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;title&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$3&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-18"&gt;&lt;a href="#cb1-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;date&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$4&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-19"&gt;&lt;a href="#cb1-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-20"&gt;&lt;a href="#cb1-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;#safe_html=$(xml_escape &amp;quot;$raw_html&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-21"&gt;&lt;a href="#cb1-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;title&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;%s\n&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$title&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;sed&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;s/&amp;amp;/\&amp;amp;amp;/g; s/&amp;lt;/\&amp;amp;lt;/g; s/&amp;gt;/\&amp;amp;gt;/g;&amp;#39;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-22"&gt;&lt;a href="#cb1-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;safe_html&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;%s\n&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$raw_html&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;sed&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;s/&amp;amp;/\&amp;amp;amp;/g; s/&amp;lt;/\&amp;amp;lt;/g; s/&amp;gt;/\&amp;amp;gt;/g;&amp;#39;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-23"&gt;&lt;a href="#cb1-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-24"&gt;&lt;a href="#cb1-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="co"&gt;# Append entry to the feed&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-25"&gt;&lt;a href="#cb1-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;cat&lt;/span&gt; &lt;span class="op"&gt;&amp;lt;&amp;lt;EOF&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$FEED&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-26"&gt;&lt;a href="#cb1-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;entry&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-27"&gt;&lt;a href="#cb1-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$title&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-28"&gt;&lt;a href="#cb1-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;link href=&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$SITE_URL&lt;/span&gt;&lt;span class="st"&gt;/&lt;/span&gt;&lt;span class="va"&gt;$html_path&lt;/span&gt;&lt;span class="st"&gt;&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-29"&gt;&lt;a href="#cb1-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;id&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$SITE_URL&lt;/span&gt;&lt;span class="st"&gt;/&lt;/span&gt;&lt;span class="va"&gt;$html_path&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-30"&gt;&lt;a href="#cb1-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;updated&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$date&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/updated&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-31"&gt;&lt;a href="#cb1-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;content type=&amp;quot;html&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$safe_html&lt;/span&gt;&lt;span class="st"&gt;&amp;lt;/content&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-32"&gt;&lt;a href="#cb1-32" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    &amp;lt;/entry&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-33"&gt;&lt;a href="#cb1-33" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-34"&gt;&lt;a href="#cb1-34" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="indexes"&gt;Indexes&lt;/h3&gt;
&lt;p&gt;I spent a lot of time thinking about how to implement the multiple
indexes. My first thought was to, for each index, scan the whole
directory for pages, maybe not the best idea, since I will be scanning
every file TWICE (for the subdir and the main index).&lt;/p&gt;
&lt;p&gt;Then I thought: maybe each subdirectory could maintain its own list
and for the main one merge them all. Well, that’s inefficient since I’ll
need to sort it for each subdir, then sort it again after merging them.
Not ideal. Also, how could I store different lists if I don’t already
know how many list I’ll need? temp files? using &lt;code&gt;eval&lt;/code&gt; for
variable variable names?&lt;/p&gt;
&lt;p&gt;I came up with a realization. I can just, for each file I process,
add it to the global list, then, when rendering the individual indexes
grep for the pattern &lt;code&gt;"href=\"/$dir_name/"&lt;/code&gt;. This is what I
came up with&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;append_to_list()&lt;/span&gt; &lt;span class="kw"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;link_name&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$1&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;title&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$2&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;date&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$3&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;PAGES_LIST&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-7"&gt;&lt;a href="#cb2-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;%s&amp;#39;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$PAGES_LIST&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-8"&gt;&lt;a href="#cb2-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;%s &amp;amp;mdash; &amp;lt;a href=&amp;quot;/%s&amp;quot;&amp;gt;%s&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;\n&amp;#39;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$date&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;${link_name&lt;/span&gt;&lt;span class="op"&gt;%&lt;/span&gt;.md&lt;span class="va"&gt;}&lt;/span&gt;&lt;span class="st"&gt;.html&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$title&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-9"&gt;&lt;a href="#cb2-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-10"&gt;&lt;a href="#cb2-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-11"&gt;&lt;a href="#cb2-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# This newline is important, since subshells don&amp;#39;t parse trailing newlines, I can&amp;#39;t add it inside the subshell.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-12"&gt;&lt;a href="#cb2-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# Technically would work without this, but I like pretty HTML if possible.&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-13"&gt;&lt;a href="#cb2-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="kw"&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-14"&gt;&lt;a href="#cb2-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-15"&gt;&lt;a href="#cb2-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# [...]&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-16"&gt;&lt;a href="#cb2-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-17"&gt;&lt;a href="#cb2-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;for&lt;/span&gt; d &lt;span class="kw"&gt;in&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$INPUT&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;/&lt;span class="pp"&gt;*&lt;/span&gt;/&lt;span class="kw"&gt;;&lt;/span&gt; &lt;span class="cf"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-18"&gt;&lt;a href="#cb2-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;[&lt;/span&gt; &lt;span class="ot"&gt;-d&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$d&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="bu"&gt;]&lt;/span&gt; &lt;span class="kw"&gt;||&lt;/span&gt; &lt;span class="cf"&gt;continue&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-19"&gt;&lt;a href="#cb2-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;dir_name&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="fu"&gt;basename&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$d&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-20"&gt;&lt;a href="#cb2-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;mkdir&lt;/span&gt; &lt;span class="at"&gt;-p&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$OUTPUT&lt;/span&gt;&lt;span class="st"&gt;/&lt;/span&gt;&lt;span class="va"&gt;$dir_name&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-21"&gt;&lt;a href="#cb2-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-22"&gt;&lt;a href="#cb2-22" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;sub_html&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="bu"&gt;[&lt;/span&gt; &lt;span class="ot"&gt;-s&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$d&lt;/span&gt;&lt;span class="st"&gt;/index.md&amp;quot;&lt;/span&gt; &lt;span class="bu"&gt;]&lt;/span&gt; &lt;span class="kw"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="ex"&gt;pandoc&lt;/span&gt; &lt;span class="va"&gt;$PANDOC_FLAGS&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$d&lt;/span&gt;&lt;span class="st"&gt;/index.md&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;||&lt;/span&gt; &lt;span class="bu"&gt;echo&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="ex"&gt;pretty_name&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$dir_name&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt; Index&amp;lt;/h1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-23"&gt;&lt;a href="#cb2-23" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-24"&gt;&lt;a href="#cb2-24" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;sub_list&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;%s\n&amp;#39;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$PAGES_LIST&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;grep&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;href=&lt;/span&gt;&lt;span class="dt"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="st"&gt;/&lt;/span&gt;&lt;span class="va"&gt;$dir_name&lt;/span&gt;&lt;span class="st"&gt;/&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-25"&gt;&lt;a href="#cb2-25" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-26"&gt;&lt;a href="#cb2-26" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="ex"&gt;generate_html&lt;/span&gt; &lt;span class="dt"&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-27"&gt;&lt;a href="#cb2-27" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="bu"&gt;printf&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;%s\n\n%s&amp;#39;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$sub_html&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$sub_list&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-28"&gt;&lt;a href="#cb2-28" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$OUTPUT&lt;/span&gt;&lt;span class="st"&gt;/&lt;/span&gt;&lt;span class="va"&gt;$dir_name&lt;/span&gt;&lt;span class="st"&gt;/index.html&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-29"&gt;&lt;a href="#cb2-29" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="ex"&gt;pretty_name&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$dir_name&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt; Index&amp;quot;&lt;/span&gt; &lt;span class="dt"&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-30"&gt;&lt;a href="#cb2-30" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;        &lt;span class="st"&gt;&amp;quot;&amp;quot;&lt;/span&gt; 1&lt;/span&gt;
&lt;span id="cb2-31"&gt;&lt;a href="#cb2-31" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="the-final-result"&gt;The final result&lt;/h2&gt;
&lt;p&gt;If you wanna take a closer look, &lt;a
href="https://codeberg.org/zekar/zsg.sh" target="_blank"
rel="noopener noreferrer"&gt;here’s the code&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="usage"&gt;Usage&lt;/h3&gt;
&lt;p&gt;You’re EXPECTED to edit the source code, at least for changing the
name and URL of your page. If you’re unfamiliar with shell (you should
learn!), it’s very intuitive to figure out how to change a couple of
variables.&lt;/p&gt;
&lt;p&gt;You can have any number of subdirectories (you can nest them if you
want, but they won’t appear in the navigation bar). In each subdirectory
(and the root), you can add an index.md if you want, it’s not
required.&lt;/p&gt;
&lt;p&gt;You’re EXPECTED to use git. If you’re not (what are you even doing,
man?), the date-generation thingy won’t work (since it uses the date of
commits of a specific file to do it)&lt;/p&gt;
&lt;p&gt;Any non-markdown files will be copied verbatim (images, documents,
stylesheets, etc…)&lt;/p&gt;
&lt;p&gt;A template.html is expected in the same directory as the script, with
standard html boilerplate&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre
class="sourceCode html"&gt;&lt;code class="sourceCode html"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;&amp;lt;!DOCTYPE&lt;/span&gt; html&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;html&lt;/span&gt;&lt;span class="ot"&gt; lang&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;head&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;meta&lt;/span&gt;&lt;span class="ot"&gt; charset&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;meta&lt;/span&gt;&lt;span class="ot"&gt; name&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;viewport&amp;quot;&lt;/span&gt;&lt;span class="ot"&gt; content&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;width=device-width, initial-scale=1&amp;quot;&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;title&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;{{TITLE}}&lt;span class="dt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="kw"&gt;title&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;link&lt;/span&gt;&lt;span class="ot"&gt; href&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;/style.css&amp;quot;&lt;/span&gt;&lt;span class="ot"&gt; rel&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;link&lt;/span&gt;&lt;span class="ot"&gt; href&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;/syntax.css&amp;quot;&lt;/span&gt;&lt;span class="ot"&gt; rel&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="kw"&gt;head&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="dt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kw"&gt;body&lt;/span&gt;&lt;span class="dt"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The script will make sure to close &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; and
&lt;code&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Other than that I think everything is pretty self-explanatory&lt;/p&gt;</content>
    </entry>
    <entry>
    <title>Nix hanging during system rebuild (Solution Included)</title>
    <link href="https://zekar.neocities.org/out/posts/nix-hanging-during-rebuild.html" />
    <id>https://zekar.neocities.org/out/posts/nix-hanging-during-rebuild.html</id>
    <updated>2026-01-18T19:51:53-06:00</updated>
    <content type="html">&lt;h1 id="nix-hanging-during-system-rebuild-solution-included"&gt;Nix hanging
during system rebuild (Solution Included)&lt;/h1&gt;
&lt;p&gt;Just a funny story about me and NixOS. To be clear, if you’re looking
for a solution for your NixOS, I wouldn’t recommend looking for advice
here. The error is so absurd and niche, it’s probably not what you’re
looking for.&lt;/p&gt;
&lt;h1 id="the-error"&gt;The error&lt;/h1&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;$&lt;/span&gt; rb &lt;span class="co"&gt;# alias of sudo nixos-rebuild switch --flake ...&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;building&lt;/span&gt; the system configuration...&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;zsh&lt;/span&gt; nixos on  main &lt;span class="pp"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;$!&lt;/span&gt;&lt;span class="pp"&gt;]&lt;/span&gt;              took 1h44m36s &lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;$&lt;/span&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well… actually, there’s no error message. But thanks to &lt;a
href="https://starship.rs/"&gt;starship’s&lt;/a&gt; &lt;a
href="https://starship.rs/config/#command-duration"&gt;Command Duration&lt;/a&gt;
module, we can see it took almost two hours… and if I haven’t stopped it
manually it’d probably take forever (literally)&lt;/p&gt;
&lt;p&gt;No high CPU usage, no high RAM usage, and no high disk usage. Which
was the common response on the internet about high rebuild times. So… I
didn’t know what to do.&lt;/p&gt;
&lt;p&gt;I rolled back to a previous generation and the problem was “solved.”
The system could rebuild again! Yay!&lt;/p&gt;
&lt;p&gt;But after switching to the new configuration and
&lt;strong&gt;THEN&lt;/strong&gt; rebuilding… yeah, the problem wasn’t solved. I
tried updating, downgrading, and doing all kinds of shenanigans to my
&lt;code&gt;flake.lock&lt;/code&gt;. Maybe it was a bad Nix update (I highly doubt
they’ll ever release a version of Nix which can’t even rebuild its own
system. Probably the most common use of Nix). But no… the problem
persisted.&lt;/p&gt;
&lt;h1 id="the-luckiest-error-message-ever"&gt;The luckiest error message
ever&lt;/h1&gt;
&lt;p&gt;A few days ago, I was messing around with &lt;a
href="https://github.com/altdesktop/playerctl"&gt;playerctl&lt;/a&gt;, I created
some scripts to bind to &lt;a
href="https://github.com/baskerville/sxhkd"&gt;sxhkd&lt;/a&gt;. Yes, not even
music listening is free of the &lt;del&gt;blessing&lt;/del&gt; curse of shell script
automation and hotkey-heavy workflows.&lt;/p&gt;
&lt;p&gt;I wanted to show a notification on every song or status change, so I
made a little test for that.&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;#test&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;playerctl&lt;/span&gt; metadata &lt;span class="at"&gt;--follow&lt;/span&gt; &lt;span class="at"&gt;--format&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;{{status}} {{title}}&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="cf"&gt;while&lt;/span&gt; &lt;span class="bu"&gt;read&lt;/span&gt; &lt;span class="at"&gt;-r&lt;/span&gt; &lt;span class="va"&gt;line&lt;/span&gt;&lt;span class="kw"&gt;;&lt;/span&gt; &lt;span class="cf"&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="ex"&gt;~/.local/bin/music_status.sh&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Can you guess how this script was named? Exactly… &lt;code&gt;test&lt;/code&gt;.
I mean, I was just testing if that worked, so the name made sense in the
moment. If you’re familiar with any Unix-based systems, you might be
facepalming right now, you see where the error lies.&lt;/p&gt;
&lt;p&gt;Ah, the error message, right!&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;/home/zekar/.local/bin/test:&lt;/span&gt; 2: playerctl: not found&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;/home/zekar/.local/bin/test:&lt;/span&gt; 2: playerctl: not found&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;updating&lt;/span&gt; GRUB 2 menu...&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;activating&lt;/span&gt; the configuration...&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;setting&lt;/span&gt; up /etc...&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;reloading&lt;/span&gt; user units for zekar...&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;restarting&lt;/span&gt; sysinit-reactivation.target&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;the&lt;/span&gt; following new units were started: NetworkManager-dispatcher.service&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;Done.&lt;/span&gt; The new configuration is /nix/store/&lt;span class="pp"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;...&lt;/span&gt;&lt;span class="pp"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Luckily, I just recently installed &lt;code&gt;playerctl&lt;/code&gt; and the
generation I rolled back didn’t have it installed so by PURE LUCK I
remembered the &lt;code&gt;test&lt;/code&gt; script I made. (The script and
rebuilding didn’t even happen around the same time, so… I had no idea
they were related!!). If I had &lt;code&gt;playerctl&lt;/code&gt; installed from the
beginning, I wouldn’t have gotten that error message (like at the top of
the post)&lt;/p&gt;
&lt;p&gt;Apparently, somewhere during the Nix evaluation, the
&lt;code&gt;test&lt;/code&gt; binary is called or something like that… Then I asked
myself, “Why is it calling my &lt;code&gt;test&lt;/code&gt; script???”. Finally, it
hit me. THE &lt;code&gt;test&lt;/code&gt; COMMAND EXISTS, I WAS PROBABLY OVERRIDING
IT!&lt;/p&gt;
&lt;p&gt;To be honest, I have no idea how it was able to rebuild if the test
command failed so it probably messed some of its conditional logic near
the end. I could research it more in depth but probably is not worth it
lol.&lt;/p&gt;
&lt;p&gt;I changed my script’s name to something else and the problem went
away.&lt;/p&gt;
&lt;p&gt;Key takeaway: Don’t name your scripts after already existing
programs… I mean, it’s obvious, but when its done by accident you don’t
even notice (especially, because I almost didn’t remember that
&lt;code&gt;test&lt;/code&gt; is the same as &lt;code&gt;[&lt;/code&gt;, and of course, the use
of &lt;code&gt;[&lt;/code&gt; is way more common in scripts and stuff)&lt;/p&gt;</content>
    </entry>
    <entry>
    <title>Setting Up VimWiki with `when`: My Minimalist Agenda Workflow</title>
    <link href="https://zekar.neocities.org/out/posts/vimwiki.html" />
    <id>https://zekar.neocities.org/out/posts/vimwiki.html</id>
    <updated>2025-05-22T01:40:16-06:00</updated>
    <content type="html">&lt;h1
id="setting-up-vimwiki-with-when-my-minimalist-agenda-workflow"&gt;Setting
Up VimWiki with &lt;code&gt;when&lt;/code&gt;: My Minimalist Agenda Workflow&lt;/h1&gt;
&lt;p&gt;I haven’t written a blog post in a while, so… yeah, here we are
again.&lt;/p&gt;
&lt;p&gt;This time, I’m sharing how I’ve set up a minimal personal agenda
system using &lt;a
href="https://github.com/vimwiki/vimwiki"&gt;&lt;code&gt;vimwiki&lt;/code&gt;&lt;/a&gt; and
&lt;a
href="https://www.lightandmatter.com/when/when.html"&gt;&lt;code&gt;when&lt;/code&gt;&lt;/a&gt;,
a lean calendar application that fits the Unix philosophy—&lt;strong&gt;do one
thing, and do it well&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ This isn’t a guide, just me documenting my setup, quirks and all.
Nonetheless, read on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2 id="why-when"&gt;Why &lt;code&gt;when&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;We’ll be using &lt;a
href="https://www.lightandmatter.com/when/when.html"&gt;&lt;code&gt;when&lt;/code&gt;&lt;/a&gt;
instead of something like &lt;a
href="https://calcurse.org/"&gt;&lt;code&gt;calcurse&lt;/code&gt;&lt;/a&gt;. I tried calcurse
for a bit but… Meh, its interface isn’t for me. I wanted something
simpler, something that plays well with &lt;code&gt;vimwiki&lt;/code&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="directory-layout"&gt;Directory Layout&lt;/h2&gt;
&lt;p&gt;Here’s the folder structure for my &lt;code&gt;life/&lt;/code&gt; directory,
which I sync via &lt;a href="https://syncthing.net/"&gt;Syncthing&lt;/a&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;~/Documents/life/&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;├──&lt;/span&gt; diary/&lt;/span&gt;
&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;│&lt;/span&gt;   └── 2025-05-21.md&lt;/span&gt;
&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;├──&lt;/span&gt; calendar/            &lt;span class="co"&gt;# Symlinked from $XDG_CONFIG_HOME/when/&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;│&lt;/span&gt;   ├── overrides.wiki&lt;/span&gt;
&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;│&lt;/span&gt;   └── calendar.wiki&lt;/span&gt;
&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;└──&lt;/span&gt; scripts/&lt;/span&gt;
&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="ex"&gt;└──&lt;/span&gt; agenda.sh        &lt;span class="co"&gt;# Used to insert `when` output into vimwiki&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The goal here is to keep everything related to my notes, schedule,
and life in one tidy place. And of course, sync it across devices
seamlessly.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="declarative-symlinks-with-home-manager"&gt;Declarative Symlinks
with Home Manager&lt;/h2&gt;
&lt;p&gt;Sure, I &lt;em&gt;could&lt;/em&gt; create a symlink manually:&lt;/p&gt;
&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;ln&lt;/span&gt; &lt;span class="at"&gt;-s&lt;/span&gt; ~/Documents/life/calendar ~/.config/when&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But come on—we’re on NixOS. We don’t do &lt;strong&gt;imperative&lt;/strong&gt;
here. Here’s how to make it &lt;em&gt;declarative&lt;/em&gt; with &lt;a
href="https://nix-community.github.io/home-manager/"&gt;&lt;code&gt;home-manager&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb3"&gt;&lt;pre
class="sourceCode nix"&gt;&lt;code class="sourceCode nix"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="va"&gt;home&lt;/span&gt;.&lt;span class="va"&gt;activation&lt;/span&gt;.&lt;span class="va"&gt;symlinkWhen&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; lib&lt;span class="op"&gt;.&lt;/span&gt;hm&lt;span class="op"&gt;.&lt;/span&gt;dag&lt;span class="op"&gt;.&lt;/span&gt;entryAfter &lt;span class="op"&gt;[&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;writeBoundary&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;]&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    target=&amp;quot;$HOME/Documents/life/calendar&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    link=&amp;quot;$HOME/.config/when&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-6"&gt;&lt;a href="#cb3-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    if [ -L &amp;quot;$link&amp;quot; ] || [ -e &amp;quot;$link&amp;quot; ]; then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-7"&gt;&lt;a href="#cb3-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;      rm -rf &amp;quot;$link&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-8"&gt;&lt;a href="#cb3-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    fi&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-9"&gt;&lt;a href="#cb3-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb3-10"&gt;&lt;a href="#cb3-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    ln -s &amp;quot;$target&amp;quot; &amp;quot;$link&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-11"&gt;&lt;a href="#cb3-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;  &amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb3-12"&gt;&lt;a href="#cb3-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="breakdown"&gt;Breakdown&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;home.activation.symlinkWhen&lt;/code&gt;&lt;/strong&gt;: Custom
activation step that runs when you
&lt;code&gt;home-manager switch&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;lib.hm.dag.entryAfter [ "writeBoundary" ]&lt;/code&gt;&lt;/strong&gt;:
Ensures the symlink is created after files are written.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shell logic&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set variables: &lt;code&gt;target="$HOME/Documents/life/calendar"&lt;/code&gt;
&lt;code&gt;link="$HOME/.config/when"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If the link (or file) exists, remove it.&lt;/li&gt;
&lt;li&gt;Create the new symlink.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: After activation,
&lt;code&gt;~/.config/when&lt;/code&gt; is a symlink to your calendar folder.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="when-tools-ignore-their-own-man-pages"&gt;When Tools Ignore Their
Own Man Pages&lt;/h2&gt;
&lt;p&gt;So, according to &lt;code&gt;when&lt;/code&gt;’s man page, config files can live
in several places, following the &lt;a
href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html"&gt;XDG
spec&lt;/a&gt;:&lt;/p&gt;
&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;${WHEN_CONFIG_HOME}&lt;/span&gt;&lt;span class="ex"&gt;/preferences&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;${XDG_CONFIG_HOME}&lt;/span&gt;&lt;span class="ex"&gt;/when/preferences&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;$HOME&lt;/span&gt;&lt;span class="ex"&gt;/.config/when/preferences&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;$HOME&lt;/span&gt;&lt;span class="ex"&gt;/.when/preferences&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great! So I created the file:&lt;/p&gt;
&lt;div class="sourceCode" id="cb5"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb5-1"&gt;&lt;a href="#cb5-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;touch&lt;/span&gt; ~/.config/when/preferences&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then ran:&lt;/p&gt;
&lt;div class="sourceCode" id="cb6"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb6-1"&gt;&lt;a href="#cb6-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;when&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And got this prompt:&lt;/p&gt;
&lt;div class="sourceCode" id="cb7"&gt;&lt;pre
class="sourceCode txt"&gt;&lt;code class="sourceCode default"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;You can now set up your calendar. This involves creating a directory ~/.when...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Wait, what?&lt;/p&gt;
&lt;p&gt;Maybe it’s because the file is empty? So I went ahead and let
&lt;code&gt;when&lt;/code&gt; create its stuff the way it wants to:&lt;/p&gt;
&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;when&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;y&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;nvim&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then moved it manually:&lt;/p&gt;
&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;mv&lt;/span&gt; ~/.when/&lt;span class="pp"&gt;*&lt;/span&gt; ~/.config/when&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Verified contents:&lt;/p&gt;
&lt;div class="sourceCode" id="cb10"&gt;&lt;pre
class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="fu"&gt;ls&lt;/span&gt; ~/.config/when&lt;/span&gt;
&lt;span id="cb10-2"&gt;&lt;a href="#cb10-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# calendar  preferences&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tried again:&lt;/p&gt;
&lt;div class="sourceCode" id="cb11"&gt;&lt;pre
class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;when&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# Still prompts to create ~/.when&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sigh.&lt;/p&gt;
&lt;h3 id="maybe-the-environment-variable"&gt;Maybe the Environment
Variable?&lt;/h3&gt;
&lt;div class="sourceCode" id="cb12"&gt;&lt;pre
class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb12-1"&gt;&lt;a href="#cb12-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="bu"&gt;export&lt;/span&gt; &lt;span class="va"&gt;WHEN_CONFIG_HOME&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$HOME&lt;/span&gt;&lt;span class="st"&gt;/.config/when&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-2"&gt;&lt;a href="#cb12-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;when&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb12-3"&gt;&lt;a href="#cb12-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# Still no luck&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2 id="goodbye-xdg"&gt;Goodbye XDG&lt;/h2&gt;
&lt;p&gt;So yeah, despite what the man page says, &lt;code&gt;when&lt;/code&gt; doesn’t
seem to honor &lt;code&gt;XDG_CONFIG_HOME&lt;/code&gt; or
&lt;code&gt;WHEN_CONFIG_HOME&lt;/code&gt;. Back to messy &lt;code&gt;$HOME&lt;/code&gt; we
go.&lt;/p&gt;
&lt;p&gt;To keep things working, I updated the symlink to point to
&lt;code&gt;~/.when&lt;/code&gt; instead:&lt;/p&gt;
&lt;div class="sourceCode" id="cb13"&gt;&lt;pre
class="sourceCode nix"&gt;&lt;code class="sourceCode nix"&gt;&lt;span id="cb13-1"&gt;&lt;a href="#cb13-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-2"&gt;&lt;a href="#cb13-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;  &lt;span class="va"&gt;home&lt;/span&gt;.&lt;span class="va"&gt;activation&lt;/span&gt;.&lt;span class="va"&gt;symlinkWhen&lt;/span&gt; &lt;span class="op"&gt;=&lt;/span&gt; lib&lt;span class="op"&gt;.&lt;/span&gt;hm&lt;span class="op"&gt;.&lt;/span&gt;dag&lt;span class="op"&gt;.&lt;/span&gt;entryAfter &lt;span class="op"&gt;[&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;writeBoundary&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;]&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-3"&gt;&lt;a href="#cb13-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    target=&amp;quot;$HOME/Documents/life/calendar&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-4"&gt;&lt;a href="#cb13-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    link=&amp;quot;$HOME/.when&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-5"&gt;&lt;a href="#cb13-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-6"&gt;&lt;a href="#cb13-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    if [ -L &amp;quot;$link&amp;quot; ] || [ -e &amp;quot;$link&amp;quot; ]; then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-7"&gt;&lt;a href="#cb13-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;      rm -rf &amp;quot;$link&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-8"&gt;&lt;a href="#cb13-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    fi&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-9"&gt;&lt;a href="#cb13-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb13-10"&gt;&lt;a href="#cb13-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;    ln -s &amp;quot;$target&amp;quot; &amp;quot;$link&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-11"&gt;&lt;a href="#cb13-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="st"&gt;  &amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb13-12"&gt;&lt;a href="#cb13-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Despite the hiccups, I still love &lt;code&gt;when&lt;/code&gt;. It’s minimal,
extensible, and scriptable. I just wish its advertised XDG support
worked. (If you know a fix—please reach out!)&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="a-test-event-does-this-actually-work"&gt;A Test Event: Does This
Actually Work?&lt;/h2&gt;
&lt;p&gt;Time to see if the setup behaves as expected.&lt;/p&gt;
&lt;p&gt;Added this line to &lt;code&gt;calendar&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="calendar"&gt;&lt;code&gt;w=Fri, 12:00 Class with Mr Thompson&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then ran:&lt;/p&gt;
&lt;div class="sourceCode" id="cb15"&gt;&lt;pre
class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb15-1"&gt;&lt;a href="#cb15-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="ex"&gt;when&lt;/span&gt; c m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="calendar"&gt;&lt;code&gt;tomorrow   2025 May 23 12:00 Class with Mr Thompson
Fri        2025 May 30 12:00 Class with Mr Thompson&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Perfect.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="integrating-when-with-vimwiki"&gt;Integrating &lt;code&gt;when&lt;/code&gt;
with VimWiki&lt;/h2&gt;
&lt;p&gt;To display this in my &lt;code&gt;vimwiki&lt;/code&gt;, I’m adding a
&lt;code&gt;== Calendar ==&lt;/code&gt; section in &lt;code&gt;index.wiki&lt;/code&gt;. Then I
use a script to inject the output from &lt;code&gt;when&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here’s the script:&lt;/p&gt;
&lt;div class="sourceCode" id="cb17"&gt;&lt;pre
class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb17-1"&gt;&lt;a href="#cb17-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-2"&gt;&lt;a href="#cb17-2" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-3"&gt;&lt;a href="#cb17-3" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# File to modify&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-4"&gt;&lt;a href="#cb17-4" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;file&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;../index.wiki&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-5"&gt;&lt;a href="#cb17-5" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-6"&gt;&lt;a href="#cb17-6" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# Generate calendar output&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-7"&gt;&lt;a href="#cb17-7" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;custom_text&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="ex"&gt;when&lt;/span&gt; c m&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-8"&gt;&lt;a href="#cb17-8" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-9"&gt;&lt;a href="#cb17-9" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="co"&gt;# Find line number for &amp;#39;== Calendar ==&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-10"&gt;&lt;a href="#cb17-10" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="va"&gt;line_num&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="fu"&gt;grep&lt;/span&gt; &lt;span class="at"&gt;-n&lt;/span&gt; &lt;span class="st"&gt;&amp;#39;== Calendar ==&amp;#39;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;cut&lt;/span&gt; &lt;span class="at"&gt;-d:&lt;/span&gt; &lt;span class="at"&gt;-f1&lt;/span&gt; &lt;span class="kw"&gt;|&lt;/span&gt; &lt;span class="fu"&gt;tail&lt;/span&gt; &lt;span class="at"&gt;-n&lt;/span&gt; 1&lt;span class="va"&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-11"&gt;&lt;a href="#cb17-11" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id="cb17-12"&gt;&lt;a href="#cb17-12" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;if&lt;/span&gt; &lt;span class="bu"&gt;[&lt;/span&gt; &lt;span class="ot"&gt;-n&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$line_num&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="bu"&gt;]&lt;/span&gt;&lt;span class="kw"&gt;;&lt;/span&gt; &lt;span class="cf"&gt;then&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-13"&gt;&lt;a href="#cb17-13" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="va"&gt;tmp_file&lt;/span&gt;&lt;span class="op"&gt;=&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$(&lt;/span&gt;&lt;span class="fu"&gt;mktemp&lt;/span&gt;&lt;span class="va"&gt;)&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-14"&gt;&lt;a href="#cb17-14" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;head&lt;/span&gt; &lt;span class="at"&gt;-n&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$line_num&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$tmp_file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-15"&gt;&lt;a href="#cb17-15" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;echo&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$tmp_file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-16"&gt;&lt;a href="#cb17-16" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;echo&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$custom_text&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$tmp_file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-17"&gt;&lt;a href="#cb17-17" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="fu"&gt;mv&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$tmp_file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;span class="va"&gt;$file&lt;/span&gt;&lt;span class="st"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-18"&gt;&lt;a href="#cb17-18" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-19"&gt;&lt;a href="#cb17-19" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;echo&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;No line containing &amp;#39;== Calendar ==&amp;#39; found.&amp;quot;&lt;/span&gt; &lt;span class="op"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class="dv"&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span id="cb17-20"&gt;&lt;a href="#cb17-20" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;    &lt;span class="bu"&gt;exit&lt;/span&gt; 1&lt;/span&gt;
&lt;span id="cb17-21"&gt;&lt;a href="#cb17-21" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="cf"&gt;fi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After running this, the calendar section in my wiki updates
automatically.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That’s it! My little setup for a VimWiki + &lt;code&gt;when&lt;/code&gt; calendar
integration is complete.&lt;/p&gt;
&lt;p&gt;It’s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal&lt;/li&gt;
&lt;li&gt;Scriptable&lt;/li&gt;
&lt;li&gt;Easy to sync&lt;/li&gt;
&lt;li&gt;Fits into my notes without clutter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ll improve it as I go—and if any big changes come, maybe I’ll write
a follow-up post.&lt;/p&gt;
&lt;p&gt;Btw, being such a simple, useful and &lt;em&gt;underground&lt;/em&gt; tool. I
might as well do a Rust rewrite. Let’s add it to the TODO list on our
VimWiki :::::v&lt;/p&gt;</content>
    </entry>
    <entry>
    <title>Thoughts after installing KISS Linux</title>
    <link href="https://zekar.neocities.org/out/posts/kiss.html" />
    <id>https://zekar.neocities.org/out/posts/kiss.html</id>
    <updated>2026-06-10T18:01:12-06:00</updated>
    <content type="html">&lt;h1 id="thoughts-after-installing-kiss-linux"&gt;Thoughts after installing
KISS Linux&lt;/h1&gt;
&lt;p&gt;I have used NixOS for almost two years. I like that I can safely
reinstall and wipe my disks without worrying I might lose important
configuration since it’s all in a git repo. However, the uncomfortable
truth is that Nix(OS) is extremely complex, both technically and to
use.&lt;/p&gt;
&lt;p&gt;Of course, Nix is &lt;strong&gt;the only real solution&lt;/strong&gt; to a
problem that didn’t need to exist in the first place. (I have planned an
article about dynamic/static linking but it isn’t ready yet). What I
hate the most about NixOS is that you are &lt;strong&gt;absolutely&lt;/strong&gt;
forced to use systemd. &lt;a
href="https://without-systemd.org/wiki/index_php/Main_Page/"
target="_blank" rel="noopener noreferrer"&gt;Systemd is by far the worst
piece of free software on earth&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Well yeah, we’re not talking about bad software, this post is,
surprisingly, very positive.&lt;/p&gt;
&lt;h2 id="whats-kiss-linux"&gt;What’s KISS Linux&lt;/h2&gt;
&lt;p&gt;KISS Linux takes the KISS principle (Keep It Simple Stupid) to its
logical conclusion. It’s a meta-distribution created by the man himself,
Dylan Araps (the guy that created neofetch, and the pure (ba)sh bibles
among other things).&lt;/p&gt;
&lt;p&gt;A distro really isn’t more than a package manager. What is Arch if
not pacman? What is Debian if not apt? What is Fedora if not dnf?
Sometimes just a desktop environment on top of it (Of course, the
desktop environment is most likely KDE or GNOME, not part of the
distribution in and of itself).&lt;/p&gt;
&lt;p&gt;KISS, as well, presents its own way of managing packages, which I
think is as close to perfection as a package manager can be. It has
features that I haven’t seen in other package managers, features that
should be basic. And everything &lt;strong&gt;around 1000 lines of POSIX
shell.&lt;/strong&gt; Absolutely impressive.&lt;/p&gt;
&lt;p&gt;By default you’re given busybox utilities (and init system), the musl
C library, and pretty much nothing else. The installation is similar to
Arch or Gentoo, in the sense you do everything manually, which makes you
understand everything about everything.&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;
&lt;p&gt;I have to admit, it took me a few days to have a working minimal
system. I wanted to do things a little bit differently than I usually
do, so I needed to step outside of my comfort zone.&lt;/p&gt;
&lt;p&gt;Before installing it on my main production machine(s), I wanted to
test it out, not in a VM, but on real hardware. I installed it on a
Thinkpad T410 I had lying around and wasn’t using. Also, I used an
outdated Arch Linux installation media I had as well, because I didn’t
want to flash anything.&lt;/p&gt;
&lt;p&gt;Of course, this isn’t a tutorial, I won’t go through all installation
steps unless I find them particularly interesting. It’s not much
different than installing Arch anyways.&lt;/p&gt;
&lt;h3 id="grub"&gt;Grub&lt;/h3&gt;
&lt;p&gt;During the installation process I stumbled upon a bunch of different
roadblocks, Grub was the first one of them.&lt;/p&gt;
&lt;p&gt;The Thinkpad T410, of course, doesn’t support UEFI. So I’m doing a
traditional BIOS installation. After running &lt;code&gt;grub-install&lt;/code&gt;
and &lt;code&gt;no errors reported&lt;/code&gt; I confidently rebooted my PC, not
expecting it to boot (since I don’t have anything), but at least I
expected to see the grub menu.&lt;/p&gt;
&lt;p&gt;Sadly, this was the least satisfying solution of this whole process.
After several hours of trying different things, manually creating
&lt;code&gt;grub.cfg&lt;/code&gt;, using &lt;code&gt;grub-mkconfig&lt;/code&gt;, everything,
still failed. Even BEFORE it had read the configuration file. To this
day I’m unaware of any &lt;strong&gt;real&lt;/strong&gt; solutions or even what was
the root of the problem. What I ended up doing was running the
&lt;code&gt;grub-install&lt;/code&gt; present in the ARCHISO, not in the chrooted
environment. It worked without problems…&lt;/p&gt;
&lt;h3 id="initramfs"&gt;Initramfs&lt;/h3&gt;
&lt;p&gt;In KISS fashion, I didn’t want to use scripts like
&lt;code&gt;mkinitcpio&lt;/code&gt; or whatever. I wanted the &lt;strong&gt;true&lt;/strong&gt;
experience of making my own initramfs, honestly, this was the part I
enjoyed the most about this installation. Of course, this is not
KISS-specific, but I was already with the “KISS mindset” so I might as
well do it.&lt;/p&gt;
&lt;p&gt;Doing your own initramfs is literally, selecting a directory to work
with, and creating your minimal filesystem. This filesystem should have
installed all the necessary utilities to do whatever it is that you want
to do before booting the system. For me, this includes
&lt;code&gt;busybox&lt;/code&gt; for regular unix utilities, and
&lt;code&gt;cryptsetup&lt;/code&gt; for actually decrypting the disk.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember, if you’re installing busybox in an initramfs, make sure all
symlinks are relative and not absolute. I made a few mistakes that
forced me to start over, and ALWAYS forgot that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In your initramfs you need an &lt;code&gt;init&lt;/code&gt; script, this script
will be the first thing your kernel runs. Use this script to mount
necessary filesystems (&lt;code&gt;proc&lt;/code&gt;, &lt;code&gt;sysfs&lt;/code&gt;,
&lt;code&gt;devtmpfs&lt;/code&gt; &amp;amp; &lt;code&gt;tmpfs&lt;/code&gt;). Without these
filesystems mounted the system can’t function properly.&lt;/p&gt;
&lt;p&gt;What gave me problems here was kernel modules. Since this was only a
installation and there were various things that could go wrong, I was
hesitant to compile my kernel before I had a functional system. So I
lazily copied the &lt;code&gt;vmlinuz&lt;/code&gt; image present in the archiso and
stopped worrying about it. The problem was that it didn’t have the
modules for decrypting the drive builtin, so I needed to
&lt;code&gt;modprobe&lt;/code&gt; them and copy them into the initramfs. With the
correct structure and stuff.&lt;/p&gt;
&lt;p&gt;After that was sorted out, I finally found myself booted into a
minimal kiss linux and I could stop relying on the live ISO (or so I
thought)&lt;/p&gt;
&lt;h3 id="kernel"&gt;Kernel&lt;/h3&gt;
&lt;p&gt;Of course, I needed to compile my own kernel if I wanted to be a
&lt;em&gt;cool kid&lt;/em&gt;, so I did. (And using the arch kernel was a temporary
solution, as I didn’t want to be loading kernel modules manually all the
time, nor did I want to create scripts that do that. Loading kernel
modules is a lot like dynamic linking so I wanted everything (or at
least almost everything) to be built into the kernel itself).&lt;/p&gt;
&lt;p&gt;I thought that running &lt;code&gt;make defconfig&lt;/code&gt; would give me a
starting point of functional configuration that will apply to roughly
all machines. That wasn’t the case, at least for me. The kernel didn’t
boot with the default configuration. It was missing a lot of essential
modules that really should be the defaults. Mostly those about
cryptography.&lt;/p&gt;
&lt;p&gt;I had to load the i915 driver for my integrated gpu to work properly
and tinker with a few related settings to get graphics working. But
eventually I got it. If your graphics aren’t working properly and you
want to boot into your system, try adding &lt;code&gt;nomodeset&lt;/code&gt; as a
kernel parameter in your bootloader, this worked for me while I tried to
get graphics working properly.&lt;/p&gt;
&lt;p&gt;However, after the graphics loaded properly now I had a problem… The
TTY didn’t have proper colors…&lt;/p&gt;
&lt;p&gt;I KNOW IT’S A NITPICK, I WON’T BE USING THE TTY REGULARLY ANYWAYS&lt;/p&gt;
&lt;p&gt;After (again) several hours of trying different configurations,
different kernel modules etc… I finally got it. It wasn’t a kernel
problem, it was a &lt;strong&gt;grub&lt;/strong&gt; problem. What I did was
&lt;code&gt;insmod&lt;/code&gt; video modules (&lt;code&gt;vbe&lt;/code&gt;, &lt;code&gt;vga&lt;/code&gt;,
&lt;code&gt;font&lt;/code&gt;, &lt;code&gt;gfxterm&lt;/code&gt;). Configure
&lt;strong&gt;grub&lt;/strong&gt; to use graphics instead of the fallback VESA video
and in your kernel parameters add &lt;code&gt;vga=current&lt;/code&gt;. Not only
your colors are fixed, but your bootloader looks pretty, as well.&lt;/p&gt;
&lt;h2 id="after-installation"&gt;After installation&lt;/h2&gt;
&lt;p&gt;I’ve been using it, not as my daily driver, but as a “playground”
where I can try certain things once in a while, and it hasn’t been that
hard to do what I want. The upstream repos are &lt;strong&gt;tiny,&lt;/strong&gt;
which encourages you to create your own repo, which I did after a few
hours of installing it.&lt;/p&gt;
&lt;p&gt;The first thing I packaged was &lt;code&gt;zsh&lt;/code&gt;. The
&lt;strong&gt;community&lt;/strong&gt; repo has &lt;code&gt;zsh&lt;/code&gt; packaged but… is it
broken?? For some reason $(command substitution) hangs
&lt;strong&gt;forever.&lt;/strong&gt; So I packaged it myself. I’m not entirely
sure, but my guess is a musl compatibility problem. When I needed to
package something the Alpine repos have been of great use to me, since
they already have patches for making software work on musl.&lt;/p&gt;
&lt;p&gt;I just looked at Alpine’s APKBUILD, downloaded the patches and
translated everything into kiss’ build system, and I had
&lt;code&gt;zsh&lt;/code&gt; working like a charm in no time.&lt;/p&gt;
&lt;p&gt;I packaged a few things after zsh, if upstream provided
statically-linked binaries I just downloaded them and copied them, I
might be a purist about a lot of things, but I’m not a “compile
everything” purist. If upstream provides a perfectly working static
binary, I just save a &lt;strong&gt;lot&lt;/strong&gt; of time by using it, not just
compiling, but in crafting a &lt;code&gt;build&lt;/code&gt; script as well.&lt;/p&gt;
&lt;p&gt;I don’t mind compiling most of my software, but if I can avoid it, I
will. However, if there’s one thing I will DEFINITELY NOT COMPILE, is a
web browser.&lt;/p&gt;
&lt;h3 id="installing-nix-in-kiss"&gt;Installing Nix in Kiss&lt;/h3&gt;
&lt;p&gt;If you want to use proprietary software or bloated software on Kiss
you’re in a tough spot. Most, if not all, proprietary software (and
upstream binaries of free software) are dynamically linked against
glibc, which Kiss Linux doesn’t use. With free software you can get away
with it by recompiling it and linking it against musl (at which point
you might as well statically link it).&lt;/p&gt;
&lt;p&gt;The only other solution would be using an alternative packaging
system/manager. Options are flatpak, appimages and… docker?? (I guess).
Of course, you read the subtitle, what I went with was nix. Honestly
because I’m way more familiar with nix and is the best (but still not
perfect) solution for dependency linked dynamic hell.&lt;/p&gt;
&lt;p&gt;I could package nix as a kiss package; I KNOW it’s (probably)
possible. But honestly, nix being such a massive thing (build users,
daemon, need to load environment variables, creating the /nix/store,
etc…) I really didn’t want to do that. First I thought to lazily copy
the upstream installation script into the &lt;code&gt;build&lt;/code&gt; script, of
course that wasn’t going to work because kiss runs that script in
isolation, so it wouldn’t install anything. I had to do everything
manually. But I didn’t want to lol. Maybe later I’ll actually do it.&lt;/p&gt;
&lt;p&gt;As expected, the installation script provided by nixos.org
&lt;strong&gt;wasn’t portable at all.&lt;/strong&gt; It had a hard dependency on
&lt;code&gt;sudo&lt;/code&gt;, non-standard &lt;code&gt;cp&lt;/code&gt; options. And another
problem that I didn’t know what was causing it. The first fix was
symlinking &lt;code&gt;doas&lt;/code&gt; to &lt;code&gt;sudo&lt;/code&gt;, and thhose parts of
the script worked. Then, I used &lt;code&gt;kiss&lt;/code&gt;’ alternatives system
to temporarily change &lt;code&gt;busybox&lt;/code&gt;’s &lt;code&gt;cp&lt;/code&gt; to gnu’s
&lt;code&gt;cp&lt;/code&gt;. At the end of the script it said something along the
lines of&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember to add this to your profile so the environment variables
work and nix can do its thing&lt;/p&gt;
&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode sh"&gt;&lt;code class="sourceCode bash"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true" tabindex="-1"&gt;&lt;/a&gt;&lt;span class="bu"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Obviously not the exact words but you get the idea)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, just a period. I’m guessing the script was hardcoded to add a
&lt;code&gt;.&lt;/code&gt; and then a path to source required environment variables,
but something went wrong. What went wrong? honestly, no idea.&lt;/p&gt;
&lt;p&gt;Anyways I added the scripts inside
&lt;code&gt;~/.nix-profile/etc/profile.d/*&lt;/code&gt; to my shell profile, and nix
was working flawlessly.&lt;/p&gt;
&lt;p&gt;After installing Nix, I already have everything I should need for a
functional system. If for some reason I can’t do something with regular
kiss, I have Nix to use as a fallback.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Surprisingly, installing Kiss Linux was a really good experience
overall, I got to learn a lot about the system’s internals that I
couldn’t have learned otherwise. Compiling all your software isn’t
&lt;strong&gt;that&lt;/strong&gt; bad, as long as you install mostly minimal
software, (which you should be doing already). I &lt;strong&gt;might&lt;/strong&gt;
switch my production machines to Kiss, but I will have to test it more
days to see if I completely like it.&lt;/p&gt;
&lt;p&gt;Also, I need to figure out a way for remote building of packages, so
I can use my homelab to compile everything instead of choking my poor
thinkpad.&lt;/p&gt;
&lt;p&gt;Making a script for declarative packages and services so I have the
exact same git-managed setup in every machine shouldn’t be that hard.
Once I have that I will happily move all my machines to Kiss. Or perhaps
I will try &lt;strong&gt;&lt;a href="https://github.com/oasislinux/oasis"
target="_blank" rel="noopener noreferrer"&gt;oasis&lt;/a&gt;??&lt;/strong&gt; I don’t
know at this point.&lt;/p&gt;</content>
    </entry>
    <entry>
    <title>The Problem With "Encrypted" Email Providers</title>
    <link href="https://zekar.neocities.org/out/articles/email.html" />
    <id>https://zekar.neocities.org/out/articles/email.html</id>
    <updated>2026-05-31T17:07:09-06:00</updated>
    <content type="html">&lt;h1 id="the-problem-with-encrypted-email-providers"&gt;The Problem With
“Encrypted” Email Providers&lt;/h1&gt;
&lt;p&gt;E-mail, for better or worse is one of the most widely used
communication methods over the internet. Even though it has its &lt;a
href="https://harmful.cat-v.org/software/email/" target="_blank"
rel="noopener noreferrer"&gt;fair share of problems&lt;/a&gt;. It’s way better
than using something like &lt;a
href="https://cadence.moe/blog/2020-06-06-why-you-shouldnt-trust-discord"
target="_blank" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; or &lt;a
href="https://salimvirani.com/facebook/" target="_blank"
rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; or whatever else kids nowadays
are using.&lt;/p&gt;
&lt;h2 id="why-email-is-was-cool"&gt;Why email &lt;del&gt;is&lt;/del&gt; was cool&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Decentralization:&lt;/strong&gt; You don’t go to email.com to
create an account, you use whatever provider you want to use. You have
choice, you can even &lt;a href="https://landchad.net/mail/smtp/"&gt;host your
own&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple:&lt;/strong&gt; By default, email is just plaintext.
Simple, and readable. &lt;a
href="https://web.archive.org/web/20210918021017/https://www.techrepublic.com/blog/it-security/a-practical-example-of-why-html-e-mail-is-a-bad-idea/"
target="_blank" rel="noopener noreferrer"&gt;If you’re sending HTML e-mail,
you’re doing it wrong&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Openness:&lt;/strong&gt; The foundation for email is &lt;em&gt;IMAP&lt;/em&gt;
and &lt;em&gt;SMTP&lt;/em&gt;. You can even use &lt;code&gt;curl&lt;/code&gt; to read email. You
don’t need a web browser. Just need a clients that can understand both
protocols and you’re set.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="why-email-sucks-now"&gt;Why email sucks now&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gmail:&lt;/strong&gt; EVERYONE uses gmail. In terms of setup,
gmail is tremendous hassle, you need to configure extra things to make
your e-mail client actually work like an e-mail client. Thankfully
g-mail &lt;strong&gt;does&lt;/strong&gt; lets you use IMAP &amp;amp; SMTP, but its not
as simple as it should. Naturally, every effort is made to keep you
inside their webapp. Because e-mail is one of the few (the only?)
decentralized technology left in widespread used, the fact that everyone
defaults to Gmail destroys its greatest superpower.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTML:&lt;/strong&gt; HTML mail is stupid (as stated above). It
introduces security risk, results in larger messages, and renders
unreadably by some clients, and more. No normal person sends HTML mail;
it is the exclusive domain of spammers and automated newsletters. &lt;a
href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="why-encrypted-email-providers-are-problematic"&gt;Why “Encrypted”
Email Providers are Problematic&lt;/h2&gt;
&lt;p&gt;When you first start worrying about privacy, you will hear two names
being thrown around constantly: &lt;a href="https://tuta.com/"
target="_blank" rel="noopener noreferrer"&gt;Tuta Mail&lt;/a&gt; &amp;amp; &lt;a
href="https://proton.me/mail" target="_blank"
rel="noopener noreferrer"&gt;Proton Mail&lt;/a&gt; (more obviously exist, but
these are the most common ones). Using this services might give you a
false sense of security since they will only work as advertised if you
use them &lt;strong&gt;correctly.&lt;/strong&gt;&lt;/p&gt;
&lt;h3
id="e2ee-should-be-done-at-the-client-level-not-a-the-provider-level."&gt;E2EE
should be done at the client level, not a the provider level.&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;very&lt;/strong&gt; definition of E2EE is that no plaintext
leaves your device, your messages are &lt;strong&gt;never&lt;/strong&gt; read by the
server, &lt;strong&gt;EVER.&lt;/strong&gt; However, the way this services work is
incompatible with the interoperability of e-mail.&lt;/p&gt;
&lt;p&gt;Imagine you send a E2EE message to a g-mail user; How would they even
read that? They don’t use proton, they can’t decrypt the message. For
standard email to go through, it &lt;em&gt;has&lt;/em&gt; to be send as plaintext
over the wire. &lt;strong&gt;Then what’s the point of encrypting it in the
first place?&lt;/strong&gt; (To clarity: Proton doesn’t actually encrypt
messages to external providers to then decrypt them, that would be dumb)
(You can configure a symmetric passphrase, tho)&lt;/p&gt;
&lt;p&gt;Now imagine two Proton Mail users communicating with each other.
Since both are using the same client, they can understand each other and
the encryption is actually useful. &lt;strong&gt;However, you need to use the
clients provided by the services, you can’t bring your own.&lt;/strong&gt;
Technically is possible to setup a normal client with Proton Mail, but
its a &lt;a href="https://proton.me/support/imap-smtp-and-pop3-setup"
target="_blank" rel="noopener noreferrer"&gt;hassle&lt;/a&gt;. To my
understanding is not possible to do the same with Tuta Mail.&lt;/p&gt;
&lt;p&gt;A big problem with web apps is that you’re trusting the server to
deliver clean JavaScript every time you hit refresh. If a government
forces Proton to server a malicious JS payload to one specific user, the
user most likely won’t even notice its browser is handing over the
decrypted keys. Local clients don’t suffer from this dynamic payload
vulnerability.&lt;/p&gt;
&lt;h3
id="using-these-services-is-better-than-using-any-other-normal-provider."&gt;Using
these services is better than using any other “normal” provider.&lt;/h3&gt;
&lt;p&gt;To be fair, this article isn’t complete hate to this companies. The
fact that people are concerned enough about privacy that this companies
can even exist, is a net positive. If you don’t plan on using a normal
email client there’s no issue with using this services.&lt;/p&gt;
&lt;p&gt;A thing I always like to remind myself, is what’s important, the
reason I started using mainly free software for things. Privacy,
freedom, control. Reducing bloat, customizability, performance,
minimalism, efficiency are just lucky side effects. Yes, I care about
minimal software, following the &lt;a
href="https://suckless.org/philosophy/" target="_blank"
rel="noopener noreferrer"&gt;suckless&lt;/a&gt; &amp;amp; &lt;a
href="https://en.wikipedia.org/wiki/Unix_philosophy" target="_blank"
rel="noopener noreferrer"&gt;unix&lt;/a&gt; philosophies and everything. But the
most important thing of all, is and always will be
&lt;strong&gt;privacy.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="the-self-hosting-trap"&gt;The self-hosting trap&lt;/h2&gt;
&lt;p&gt;Some privacy advocates propose hosting your own email server. While I
find this to be a worthwhile endeavor, it isn’t actually great for
privacy, depending on your threat model.&lt;/p&gt;
&lt;p&gt;Imagine you use your own email server to talk to two different
people. You want to ensure they can’t pin down your exact identity, so
you give them different aliases: &lt;code&gt;foo@zekar.xyz&lt;/code&gt; and
&lt;code&gt;bar@zekar.xyz&lt;/code&gt;. Because that domain name is so unique, it
takes zero effort to figure out that any &lt;code&gt;*@zekar.xyz&lt;/code&gt;
address belongs to the exact same person. Furthermore, if your registrar
doesn’t mask your data, your real name might be tied directly to the
domain registration.&lt;/p&gt;
&lt;p&gt;I only recommend hosting your own mail server &lt;strong&gt;if you want
people to know it’s you,&lt;/strong&gt; and if you have the immense time and
resources required to maintain it. Running a mail server is easily one
of the most demanding services you can self-host due to IP reputation
and spam filtering.&lt;/p&gt;
&lt;h2 id="the-real-solution"&gt;The real solution&lt;/h2&gt;
&lt;p&gt;What I recommend is just using &lt;code&gt;cock.li&lt;/code&gt; or similar
services.&lt;/p&gt;
&lt;p&gt;Simply because they don’t ask for personally identifiable information
at registration. Just a username and a password and nothing else. For
some reason, that’s very hard to find nowadays. Of course, they support
the traditional protocols, IMAP and SMTP (even the old POP!)&lt;/p&gt;
&lt;h3 id="how-can-you-trust-such-a-ridiculous-name"&gt;How can you trust such
a ridiculous name?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;You can’t. Cock.li doesn’t read or scan your e-mail content in any
way, but it’s possible for any e-mail provider to read your e-mail, so
you’ll just have to take our word for it. No “encrypted e-mail” provider
is preventing this: even if they encrypt incoming mail before storing
it, the provider still receives the e-mail in plaintext first, meaning
you’re only protected if you assume no one was reading or copying the
e-mail as it came in.&lt;/p&gt;
&lt;p&gt;Taken from the &lt;a href="https://cock.li" target="_blank"
rel="noopener noreferrer"&gt;cock.li&lt;/a&gt; frontpage&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This ties back to my earlier point. The same trust to place upon
Proton or Tuta to encrypt your emails before they read them, is the same
trust you place upon &lt;strong&gt;cock.li&lt;/strong&gt; to not read them.&lt;/p&gt;
&lt;p&gt;However this trust shouldn’t be necessary.&lt;/p&gt;
&lt;h3 id="the-real-solution-1"&gt;The real solution&lt;/h3&gt;
&lt;p&gt;The only way to ensure your emails are private,
&lt;strong&gt;regardless&lt;/strong&gt; of which provider you use, is to get
yourself a GPG key and encrypt (and sign) your messages locally on your
client.&lt;/p&gt;
&lt;p&gt;If you’re wondering: no, this doesn’t mean you have to copy and paste
encrypted data manually. Most clients handle encryption natively.
Inconvenient? Actually not that much, just keep your key safe, and share
it with everyone you wish.&lt;/p&gt;
&lt;h3 id="the-catch"&gt;The catch&lt;/h3&gt;
&lt;p&gt;The only problem with encrypting your mail is the same problem of
&lt;strong&gt;every&lt;/strong&gt; private communication method. Try to convince
your normie friends to encrypt their mail? Good luck. (Try to convince
them to &lt;strong&gt;even&lt;/strong&gt; use e-mail instead of discord lol)&lt;/p&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;&lt;a href="http://david.woodhou.se/email.html"
target="_blank"
rel="noopener noreferrer"&gt;http://david.woodhou.se/email.html&lt;/a&gt;&lt;a
href="#fnref1" class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>
    </entry>
    <entry>
    <title>My take on perfectionism</title>
    <link href="https://zekar.neocities.org/out/articles/perfection.html" />
    <id>https://zekar.neocities.org/out/articles/perfection.html</id>
    <updated>2025-03-21T17:19:47Z</updated>
    <content type="html">&lt;h1 id="my-take-on-perfectionism"&gt;My take on perfectionism&lt;/h1&gt;
&lt;p&gt;The main reason to build this website is to share my ideas, all of
them, even those I won’t dare to share in person. This one, goes into
the latter group.&lt;/p&gt;
&lt;p&gt;The thing I’ve struggled most in my life is perfection itself, I
always try to be the best version of myself, and the best version of
myself, would be also the perfect version of myself.&lt;/p&gt;
&lt;h2 id="is-perfection-attainable"&gt;Is Perfection Attainable?&lt;/h2&gt;
&lt;p&gt;Perfection is often defined as &lt;em&gt;the state of being complete and
correct in every way.&lt;/em&gt;&lt;a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;. While true perfection
is imposisible for a human to achieve, I believe in striving to be as
close to it as possible.&lt;/p&gt;
&lt;p&gt;But here’s my bold take:&lt;/p&gt;
&lt;h2 id="we-should-all-strive-for-perfection"&gt;We Should All Strive for
Perfection&lt;/h2&gt;
&lt;p&gt;Yes, you read that right. &lt;strong&gt;Everyone should try to be
perfect.&lt;/strong&gt; But before you dismiss this as unrealistic, let me
explain what I mean.&lt;/p&gt;
&lt;p&gt;Perfection isn’t just about excelling in one area; it’s about
balance. I call this &lt;strong&gt;holistic perfection&lt;/strong&gt; as opposed to
&lt;strong&gt;superficial perfection,&lt;/strong&gt; and understanding the
difference is crucial&lt;/p&gt;
&lt;h2 id="holistic-perfection-vs-superficial-perfection"&gt;Holistic
perfection vs superficial perfection&lt;/h2&gt;
&lt;p&gt;Holistic perfection is about striving to improve in
&lt;strong&gt;every&lt;/strong&gt; meaningful area of life, not just one. Many
people chase perfection in a limited sense, and this can be damaging and
frustrating. Let’s look at two hypothetical students to illustrate the
difference.&lt;/p&gt;
&lt;h3 id="the-trap-of-superficial-perfection"&gt;The Trap of Superficial
Perfection&lt;/h3&gt;
&lt;p&gt;Imagine a student who is at the top of their class. They dedicate all
their energy to being academically perfect but neglect their
relationships, emotions, and personal growth. One day, during an
ungraded classroom activity, they make a mistake. Their classmates don’t
react, they never built meaningful connections with them. The student is
devastated. Their self-worth crumbles because their entire identity was
built around being “the best” in school.&lt;/p&gt;
&lt;h3 id="the-power-of-holistic-perfection"&gt;The Power of Holistic
Perfection&lt;/h3&gt;
&lt;p&gt;Now, picture another student, also top of their class, but instead of
fixating solely on academics, they strive for &lt;strong&gt;holistic
perfection&lt;/strong&gt;. They work hard in school, but they also invest in
friendships, emotional resilience, and self-improvement. During the same
classroom activity, they make the same mistake. But instead of feeling
crushed, they shake it off. Why? Because school isn’t their whole world.
They know that understanding the truth of not being perfect is closer to
perfection, than lying to themselves to make them think they are
perfect. They know that striving for perfection also means being
emotionally balanced and adaptable&lt;/p&gt;
&lt;h2 id="possible-criticism-rebuttals"&gt;Possible Criticism &amp;amp;
Rebuttals&lt;/h2&gt;
&lt;p&gt;I get it, saying that &lt;strong&gt;everyone should try to be
perfect&lt;/strong&gt; sounds extreme. You might be thinking:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;“‘Perfect’ people are annoying/irritating/boring.”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“Striving for perfection is exhausting.”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“Failure is natural, why fight it?”&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;“Being perfect in everything is unrealistic.”&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="perfect-people-are-annoying."&gt;Perfect people are annoying.&lt;/h3&gt;
&lt;p&gt;It’s true, people &lt;strong&gt;obsessed&lt;/strong&gt; with perfection can be
irritating. They seek validation and often lack real social skills.&lt;/p&gt;
&lt;p&gt;But someone striving for &lt;strong&gt;holistic perfection&lt;/strong&gt;? They
aim to be perfect in how they communicate, how they treat others, and
how they carry themselves. They don’t need to boast or seek approval.
They remain humble, because humility is closer to true perfection than
arrogance. Someone that’s perfect and not annoying is &lt;em&gt;more
perfect&lt;/em&gt; than someone that’s perfect and annoying.&lt;/p&gt;
&lt;h3 id="striving-for-perfection-is-exhausting."&gt;Striving for perfection
is exhausting.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Superficial perfection is exhausting.&lt;/strong&gt; It demands
constant external validation, making people feel like they must always
prove something.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Holistic perfection, however, is liberating.&lt;/strong&gt; Instead
of obsessing over a single aspect of life, it encourages balance. You’re
trying to be the absolute best at everything; everything, of course,
includes not sacrificing well-being, caring about your mental
health.&lt;/p&gt;
&lt;h3 id="failure-is-natural-why-fight-it"&gt;Failure is natural, why fight
it?&lt;/h3&gt;
&lt;p&gt;Yes, failure is inevitable, and we should try to avoid it as much as
possible. However, someone that confronts failures gracefully is
&lt;em&gt;more perfect&lt;/em&gt; that someone that breaks when confronted to
it.&lt;/p&gt;
&lt;p&gt;Trying to be holistically perfect includes being &lt;em&gt;perfect&lt;/em&gt; in
&lt;em&gt;how you handle failure&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id="being-perfect-in-everyting-is-unrealistic."&gt;Being perfect in
everyting is unrealistic.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Agreed! But that’s not the point.&lt;/strong&gt; The goal is to
&lt;strong&gt;try&lt;/strong&gt; to reach perfection, because, as I said before,
&lt;strong&gt;being&lt;/strong&gt; perfect is impossible. &lt;strong&gt;Trying to be close
to&lt;/strong&gt; perfection is the main idea here.&lt;/p&gt;
&lt;h2 id="my-experience-with-perfectionism."&gt;My experience with
perfectionism.&lt;/h2&gt;
&lt;p&gt;Now, let’s get personal. I have &lt;strong&gt;always&lt;/strong&gt; been a
perfectionist, for as long as I can remember. I don’t know the exact
cause of this, but if has often led to intense stress when I fail to
meet my own unrealistic standards. Whenever I feel frustrated by my
inability to achieve perfection, I remind myself of &lt;strong&gt;holistic
perfection&lt;/strong&gt;, after all, a &lt;strong&gt;truly perfect&lt;/strong&gt; person
wouldn’t become frustrated over their imperfections.&lt;/p&gt;
&lt;p&gt;That’s why I wanted to write this. This thought has been on my mind
for a while, and it has genuinely helped me. I don’t want to sound
arrogant, but deep down, I’ve always felt somewhat superior to others.
Maybe that’s why the usual advice about perfectionism never resonated
with me.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“Everyone makes mistakes.”&lt;/li&gt;
&lt;li&gt;“Yes… everyone but me.”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The concept of holistic perfection helped me reconcile my flaws with
that subconscious sense of superiority. Now I strive to be humble
because, after all, wouldn’t someone truly “perfect” be humble? Thanks
to this shift in mindset, I no longer feel as much pressure from myself,
and I genuinely believe I’ve become a better person.&lt;/p&gt;
&lt;blockquote&gt;

&lt;/blockquote&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li
id="fn1"&gt;&lt;p&gt;https://dictionary.cambridge.org/dictionary/english/perfection&lt;a
href="#fnref1" class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>
    </entry>
    <entry>
    <title>Why you shouldn't use the fish shell</title>
    <link href="https://zekar.neocities.org/out/articles/fish-shell.html" />
    <id>https://zekar.neocities.org/out/articles/fish-shell.html</id>
    <updated>2025-03-20T17:58:26Z</updated>
    <content type="html">&lt;h1 id="why-you-shouldnt-use-the-fish-shell"&gt;Why you shouldn’t use the
fish shell&lt;/h1&gt;
&lt;p&gt;The POSIX standard is a set of rules a UNIX-based operating system
&lt;strong&gt;should&lt;/strong&gt; follow. However, this isn’t always the case.
While it’s perfectly fine to &lt;strong&gt;extend&lt;/strong&gt; the POSIX standard
to add more features and improve functionality –as seen in &lt;a
href="https://www.gnu.org/software/bash/"&gt;bash&lt;/a&gt; and &lt;a
href="https://www.zsh.org/"&gt;zsh&lt;/a&gt;– there’s a third very popular shell
that that has gained significant attention: &lt;em&gt;Fish&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="the-friendly-interactive-shell"&gt;The Friendly Interactive
SHell&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;fish is a smart and user-friendly command line shell for Linux,
macOS, and the rest of the family.[^1]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fish is often marketed as a user-friendly shell, and it does offer
some appealing features for interactive use. However, its design choices
and lack of &lt;em&gt;POSIX&lt;/em&gt; compliance make it a poor choice for
scripting and not a very good one for interactive use.&lt;/p&gt;
&lt;h2 id="fish-vs-posix"&gt;Fish vs POSIX&lt;/h2&gt;
&lt;p&gt;Fish’s lack of POSIX compliance is presented as one of its best
features, however, personally is the most significant drawback. This
means scripts written for Fish may not run correctly on other shells,
and vice versa. This can be a major issue if you need to write portable
scripts that should run on a variety of systems.&lt;/p&gt;
&lt;h2 id="other-shells-vs-posix"&gt;Other shells vs POSIX&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/software/bash"&gt;bash&lt;/a&gt; and &lt;a
href="https://www.zsh.org"&gt;zsh&lt;/a&gt; are not &lt;strong&gt;strictly&lt;/strong&gt;
POSIX-compliant shells because they extend the POSIX standard with
additional functionality that isn’t part of the specification. While
they are largely compatible with POSIX, their extra features can lead to
scripts that don’t work in strictly POSIX-compliant environments. This
is why I always recommend writing scripts in &lt;strong&gt;POSIX-compliant
shell syntax&lt;/strong&gt; whenever possible. Scripts written in
POSIX-compliant shell can run on virtually any UNIX-like system, from
macOS to OpenBSD to Linux (every sane OS—Windows not included!).&lt;/p&gt;
&lt;p&gt;Some people (especially soydev sysadmins) like to write
&lt;code&gt;#!/bin/bash&lt;/code&gt; scripts, this, clearly, is an skill issue, just
write &lt;code&gt;#!/bin/sh&lt;/code&gt; and get good. This is the exact same
problem.&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style="width: 15%" /&gt;
&lt;col style="width: 17%" /&gt;
&lt;col style="width: 35%" /&gt;
&lt;col style="width: 30%" /&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bash&lt;/th&gt;
&lt;th&gt;Zsh&lt;/th&gt;
&lt;th&gt;POSIX&lt;/th&gt;
&lt;th&gt;Fish&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Can run bash and POSIX scripts.&lt;/td&gt;
&lt;td&gt;Can run bash, zsh and POSIX scripts&lt;/td&gt;
&lt;td&gt;Can only run &lt;strong&gt;POSIX-compliant scripts.&lt;/strong&gt; ensuring
maximum portability&lt;/td&gt;
&lt;td&gt;Can only run Fish scripts, it doesn’t even run POSIX scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="why-posix-compliance-matters"&gt;Why POSIX Compliance Matters&lt;/h2&gt;
&lt;p&gt;POSIX compliance ensures that your scripts will work across different
UNIX-like systems without modification. While shells like bash and zsh
offer additional features that can make interactive use more enjoyable,
relying on these extensions for scripting will lead to compatibility
issues. Fish, takes this problem to the extreme by just abandoning POSIX
compliance altogether, making it a poor choice for scripting and a
questionable one for interactive environments (Just use zsh!!).&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If I had to summarize this post in a single phrase, it would be
‘skill issue’. [^1]: https://fishshell.com/&lt;/p&gt;</content>
    </entry>
    <entry>
    <title>The (not-so-problematic) Problem of Evil</title>
    <link href="https://zekar.neocities.org/out/articles/evil.html" />
    <id>https://zekar.neocities.org/out/articles/evil.html</id>
    <updated>2025-07-08T17:18:49-06:00</updated>
    <content type="html">&lt;h1 id="the-not-so-problematic-problem-of-evil"&gt;The (not-so-problematic)
Problem of Evil&lt;/h1&gt;
&lt;h2 id="i.i-the-problem-of-evil"&gt;I.I The problem of Evil&lt;/h2&gt;
&lt;p&gt;One of the most classical arguments against any religion with the
definition of a tri-omni God is &lt;strong&gt;The Problem of Evil.&lt;/strong&gt;
Which states that “If God is all-good and all-powerful, why is there so
much evil?”. This problem is so big and so well-known that the arguments
&lt;strong&gt;against&lt;/strong&gt; this has gained their own name, the so called
&lt;strong&gt;theodicies.&lt;/strong&gt; &lt;a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img
src="https://www.bibleodyssey.org/wp-content/uploads/2022/06/theodicy-ot.jpg" /&gt;&lt;/p&gt;
&lt;h2 id="i.ii-theodicies"&gt;I.II Theodicies&lt;/h2&gt;
&lt;p&gt;A theodicy meaning ‘vindication of God’, from Ancient Greek θεός
theos, “god” and δίκη dikē, “justice”) is an argument with the attempt
to reconcile an all-powerful all-good God’s existence with evil’s
existence.&lt;/p&gt;
&lt;h3 id="free-will"&gt;Free Will&lt;/h3&gt;
&lt;p&gt;God thinks (and if God thinks something it &lt;strong&gt;must&lt;/strong&gt; be
true) that free will is more important than creating perfect loving
creatures that don’t disobey Him at all. If he &lt;em&gt;programmed&lt;/em&gt; us to
just love each others without the free will to &lt;strong&gt;not&lt;/strong&gt; do
it, the love we share wouldn’t be &lt;strong&gt;true&lt;/strong&gt; love, since we
were &lt;strong&gt;forced&lt;/strong&gt; to do so.&lt;/p&gt;
&lt;h3 id="soul-making-theodicy-greater-good-theodicy"&gt;Soul-Making Theodicy
&amp;amp; Greater Good Theodicy&lt;/h3&gt;
&lt;p&gt;I really find these theodicies to be too similar to just put them in
a different category&lt;/p&gt;
&lt;p&gt;Evil and suffering are necessary for moral and spiritual growth. Life
is a soul-making journey where hardships help develop virtues like
courage, compassion and resilience. A painless world would produce
morally immature being. God allows evil to bring about a greater good
that couldn’t happen otherwise.&lt;/p&gt;
&lt;h3 id="punishment-theodicy"&gt;Punishment Theodicy&lt;/h3&gt;
&lt;p&gt;Suffering and evil are divine punishment for sin, caused by the
original sin that we humans, have. God is just, and evil is the result
of human rebellion. All suffering is deserved, either as a consequence
or as discipline.&lt;/p&gt;
&lt;p&gt;All of these theodicies have a million rebuttals and
counter-rebuttals which are outside the scope of this article. However,
they’re here just to demonstrate the importance and weight this problem
has.&lt;/p&gt;
&lt;h2 id="i.iii-the-argument-from-morality"&gt;I.III The Argument from
Morality&lt;/h2&gt;
&lt;p&gt;One of the most popular arguments for the existence of God
(especially in Christian apologetics) is called the &lt;strong&gt;Argument
from Morality&lt;/strong&gt;. It basically claims that &lt;strong&gt;objective
morality can only exist if God exists&lt;/strong&gt;. So if you believe things
like murder, rape, or slavery are &lt;em&gt;really&lt;/em&gt; wrong (not just
personal preference), then, the argument goes, you’re implicitly relying
on God’s existence.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If God does not exist, then objective morality does not
exist. But objective morality does exist. Therefore, God
exists.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="the-core-of-the-argument"&gt;The Core of the Argument:&lt;/h3&gt;
&lt;p&gt;It usually goes something like this:&lt;/p&gt;
&lt;ol type="1"&gt;
&lt;li&gt;If God doesn’t exist, then objective moral values and duties don’t
exist.&lt;/li&gt;
&lt;li&gt;But objective moral values and duties &lt;em&gt;do&lt;/em&gt; exist.&lt;/li&gt;
&lt;li&gt;Therefore, God exists.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The idea is that moral laws require a &lt;strong&gt;moral
lawgiver&lt;/strong&gt;, a transcendent source outside of human opinion.
According to this view, just like physical laws point to a lawmaker,
moral laws must come from God.&lt;/p&gt;
&lt;p&gt;Christian apologists like William Lane Craig lean on this argument
heavily. They claim that atheistic or naturalistic worldviews can’t
account for &lt;em&gt;why&lt;/em&gt; anything is objectively right or wrong. At
best, they say, you get cultural norms, evolutionary instincts, or
personal preferences; not real, binding moral truths.&lt;/p&gt;
&lt;p&gt;The argument dodges the &lt;strong&gt;Euthyphro dilemma&lt;/strong&gt; &lt;a
href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;. Is something good because God
commands it, or does God command it because it’s good? Either morality
comes from the nature of God, or it exists independently of God (which
makes the argument unfeasible). Christian philosophers often resolve
this dilemma by claiming that morality is grounded in God’s unchanging
nature, which is perfectly good. In this view, God neither arbitrarily
invents morality, nor is He subject to it; rather, His nature is the
standard.&lt;/p&gt;
&lt;p&gt;Of course, the first option is what most Christians believe, morality
exists just because God exists.&lt;/p&gt;
&lt;h1 id="ii-the-logical-conclusion"&gt;II The logical conclusion&lt;/h1&gt;
&lt;p&gt;So let’s put the pieces together: Many Christians claim God is the
source of morality. Also, we find pain and suffering in the world and
there are several &lt;strong&gt;theodicies&lt;/strong&gt; to fix this problem,
however the need for these theodicies is itself a sign of the problem’s
weight.&lt;/p&gt;
&lt;p&gt;I speak of The Problem of Evil and theodicies, but this also comes
linked with another problem, which I think its solved by the same
explanation. I’m talking of &lt;strong&gt;disturbing things&lt;/strong&gt; not just
happening, but &lt;strong&gt;endorsed&lt;/strong&gt; by God in the Bible.&lt;/p&gt;
&lt;p&gt;To name a few examples:&lt;/p&gt;
&lt;h3 id="morally-problematic-acts-endorsed-by-god-in-the-bible."&gt;Morally
Problematic Acts Endorsed by God in the Bible.&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;“You may buy male and female slaves from the nations around you… They
will become your property… You can bequeath them to your children as
inherited property.”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Leviticus 25:44-46&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“A man may beat his slave with a rod; as long as the slave doesn’t
die immediately, there’s no punishment.”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Exodus 21:20-21&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Both of these verses don’t just &lt;strong&gt;acknowledge&lt;/strong&gt; the
existence of slavery. They regulate and legitimize it, even the violent
abuse of slaves, without ever condemning the institution. God had the
opportunity (multiple times) to condemn explicitly (if that was His
will), and yet, he didn’t.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Now go and strike Amalek and devote to destruction all that they
have. Do not spare them, but kill both man and woman, child and infant,
ox and sheep, camel and donkey.”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;1 Samuel 15:2-3&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is not a military strike, it’s a divine command to
&lt;strong&gt;exterminate&lt;/strong&gt; an entire population, including
&lt;strong&gt;infants&lt;/strong&gt; and &lt;strong&gt;animals&lt;/strong&gt;. Later, Saul is
punished for &lt;em&gt;not killing enough&lt;/em&gt;. (1 Samuel 15:9-11)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“If a man meets a virgin who is not betrothed, and seizes her and
lies with her… he shall pay the father fifty shekels of silver, and she
shall be his wife.”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Deuteronomy 22:28-29&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The punishment for the rapist is to marry his victim, effectively
binding her to a lifetime with her abuser, with no concern for her
consent or traume.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After David commits adultery with Bathsheba and murders her husband,
God punishes David by killing their child.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2 Samuel 12:13-18&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An innocent child dies &lt;em&gt;for someone else’s sin,&lt;/em&gt; raising
obvious questions about justice and divine fairness.&lt;/p&gt;
&lt;p&gt;Taking all the points discussed previously, we get this
conclusion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;God isn’t just moral; he &lt;em&gt;defines&lt;/em&gt; morality. So if God
commands he death of children, the enslavement of peoples, or eternal
torment; those acts, by definition, are good.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="iii.-but-doesnt-god-give-us-a-moral-compass"&gt;III. But Doesn’t
God Give Us a Moral Compass?&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;“They show that the work of the law is written on their hearts, while
their conscience also bears witness, and their conflicting thoughts
accuse or even excuse them”&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Romans 2:15&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This verse changes everything, God has written the law on our hearts,
most Christians would argue that’s the meaning of this verse. Our moral
intuitions come from God, that’s the “law written on the heart.”&lt;/p&gt;
&lt;p&gt;If that’s true, how can those same intuitions &lt;strong&gt;scream&lt;/strong&gt;
that slavery or genocide is wrong when clearly God, is all for it?&lt;/p&gt;
&lt;p&gt;Who’s wrong? Us or God?&lt;/p&gt;
&lt;p&gt;Well, God can’t be wrong, God can’t lie (Hebrews 6:18) so we
&lt;strong&gt;MUST&lt;/strong&gt; be wrong about some things, these things can
include acts that God endorses in the Bible and we find them
reprehensible.&lt;/p&gt;
&lt;h1 id="iv.-apologists-explaining-the-horrific"&gt;IV. Apologists
Explaining the Horrific&lt;/h1&gt;
&lt;p&gt;Many Christian apologists are aware that some of God’s commands in
the Bible seem deeply immoral to modern readers. Instead of
acknowledging this moral tension, they often try to
&lt;strong&gt;reinterpret&lt;/strong&gt;, &lt;strong&gt;downplay&lt;/strong&gt;, or
&lt;strong&gt;sanitize&lt;/strong&gt; the verses to protect God’s image.&lt;/p&gt;
&lt;h2 id="iv.i-reinterpretation-through-language"&gt;IV.I Reinterpretation
Through Language&lt;/h2&gt;
&lt;p&gt;Apologists argue that we’re misreading the original Hebew or Greek. A
famous example is &lt;strong&gt;&lt;a
href="https://apologeticspress.org/deuteronomy-2228-29-and-rape-5197/"&gt;Deuteronomy
22:28-29&lt;/a&gt;&lt;/strong&gt;, which many take as a law requiring rape victim to
marry her rapist. Apologists claim the Hebrew word translated “seized”
doesn’t necessarily imply force, and therefore, it’s not rape. But even
if that’s true, the passage &lt;strong&gt;still&lt;/strong&gt; mandates forced
lifelong marriage after a premarital sexual encounter, a punishment that
clearly harms the woman more than the man.&lt;/p&gt;
&lt;p&gt;So the “softened” interpretation is morally disturbing, just slightly
less so.&lt;/p&gt;
&lt;h2 id="iv.ii-it-was-a-different-time-defense"&gt;IV.II “It was a Different
Time” Defense&lt;/h2&gt;
&lt;p&gt;This line of reasoning claims that God was simply working within an
ancient cultural norms ;that slavery, genocide, or patriarchy were
&lt;strong&gt;regrettable but necessary&lt;/strong&gt; due to the time period. But
that implies that an all-powerful, all-good Gas somehow
&lt;strong&gt;limited&lt;/strong&gt; by the morality of Iron Age tribes; unable to
command something better or set a moral example.&lt;/p&gt;
&lt;p&gt;If God the moral authority, or is He taking moral cues from Bronze
Age norms?&lt;/p&gt;
&lt;h2 id="iv.iii-greater-good-rationalizations"&gt;IV.III Greater Good
Rationalizations&lt;/h2&gt;
&lt;p&gt;Some claim these morally disturbing actions served a greater divine
purpose we can’t fully understand. But that’s exactly the kind of
reasonins Christians reject when it’s used to excuse real-world evil. If
a dictator kills children for a “greater cause,” we call that evil; not
mysterious goodness.&lt;/p&gt;
&lt;p&gt;If these rationalizations were applied to any other being, Christians
would be horrified. But because it’s God, they twist themselves into
knots trying to justify what they’d never accept from a human.&lt;/p&gt;
&lt;h1 id="v.-the-real-problem-christians-dont-want-to-say-it"&gt;V. The Real
Problem: Christians Don’t Want to Say It&lt;/h1&gt;
&lt;p&gt;This is the core issue. &lt;strong&gt;Most Christians do not want to admit
the full implications of their own theology.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If God defines morality, then &lt;strong&gt;anything He command is, by
definition, good&lt;/strong&gt;; no matter how repugnant it seems to human
conscience. That includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slavery&lt;/li&gt;
&lt;li&gt;Genocide&lt;/li&gt;
&lt;li&gt;Eternal torture&lt;/li&gt;
&lt;li&gt;Killing infants&lt;/li&gt;
&lt;li&gt;Focring marriage after rape&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The consisten Christian response (if take seriously) would be to
say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Even though my conscience is repulsed by this, I submit to God’s
authority, because my moral intuitions are fallible and God’s will is
perfect.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But almost &lt;strong&gt;no one&lt;/strong&gt; actually says that.&lt;/p&gt;
&lt;p&gt;Instead, Christians do everything they can to avoid saying
&lt;strong&gt;what their theology requires.&lt;/strong&gt; They reinterpret, dodge,
or dilute the text to protect their moral instincts. This creates a
bizarre situation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They believe morality comes from God.&lt;/li&gt;
&lt;li&gt;They morally reject some things God does or commands.&lt;/li&gt;
&lt;li&gt;Yet they refuse to admit that either God is wrong or their theology
is flawed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They want to preserve both &lt;strong&gt;God’s moral perfection&lt;/strong&gt;
and their own sense of justice; even when the two clash. That tension is
never resolved. It’s just papered over.&lt;/p&gt;
&lt;h1 id="vi.-conclusion-the-cost-of-consistency"&gt;VI. Conclusion: The Cost
of Consistency&lt;/h1&gt;
&lt;p&gt;Here’s the uncomfortable truth:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You can resolve the Problem of Evil if you’re willing to let
God define morality. But that leads to a horrifying conclusion: anything
God commands (even genocide, slavery, or child killing) is morally
right.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The only alternative is to say that &lt;strong&gt;some things God did or
commanded in the Bible were actually wrong&lt;/strong&gt;; that would mean God
&lt;strong&gt;is not the source of morality,&lt;/strong&gt; and the Argument from
Morality collapses.&lt;/p&gt;
&lt;p&gt;So you’re left with a choice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Submit your moral compass to God, even when it revolts
you.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Or trust your moral compass, and admit that God, as
described in some parts of Scripture, might not be perfectly
good.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can’t think of a rationalization of having it both ways.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You can have a God who defines good and evil. Or you can have
a moral compass you trust. But I’m not sure you can have
both.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;https://en.wikipedia.org/wiki/Theodicy&lt;a href="#fnref1"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn2"&gt;&lt;p&gt;https://www.str.org/w/euthyphro-s-dilemma-1&lt;a
href="#fnref2" class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>
    </entry>
    <entry>
    <title>Beyond Infallibility: A Historical-Critical Examination</title>
    <link href="https://zekar.neocities.org/out/articles/bible.html" />
    <id>https://zekar.neocities.org/out/articles/bible.html</id>
    <updated>2026-06-01T00:51:51-06:00</updated>
    <content type="html">&lt;h1 id="beyond-infallibility-a-historical-critical-examination"&gt;Beyond
Infallibility: A Historical-Critical Examination&lt;/h1&gt;
&lt;h1 id="preamble"&gt;Preamble&lt;/h1&gt;
&lt;p&gt;This is probably the longest and most well-researched article in this
page. This was actually a final project for school, hence the different
tone compared to the rest of the pages here. I’m sincerely proud of my
work and I wanted to share this here. This was the result of what I’m
estimating around a month of daily research and reading.&lt;/p&gt;
&lt;p&gt;Also, this was originally written in markdown to be compiled to latex
to be compiled to PDF and deliver the assignment, of course I can easily
copy everything to my site for it to be compiled to HTML without issues,
thanks pandoc.&lt;/p&gt;
&lt;h1 id="introduction"&gt;Introduction&lt;/h1&gt;
&lt;p&gt;In this paper we will explore the tension between the theological
claim of biblical infallibility and the empirical evidence derived from
the study of ancient manuscripts and historical records. The Bible,
while it remains a profound root of cultural heritage, its status as a
“perfect” historical document is incompatible with rigorous scholarly
scrutiny. This analysis will focus on three primary areas of evidence:
first, we will focus on &lt;strong&gt;textual integrity,&lt;/strong&gt;
demonstrating how the absence of original autographs and the presence of
significant interpolations, such as the Pericope Adulterae (John
7:53–8:11) and the longer ending of Mark (16:9–20), reveal a fluid
transmission history; second, &lt;strong&gt;historical accuracy,&lt;/strong&gt;
exploring conflicts between biblical narratives and external secular
records, exemplified by the incongruity surrounding the Census of
Quirinius and the lack of evidence for the Exodus; and third,
&lt;strong&gt;internal consistency,&lt;/strong&gt; highlighting conflicts in
genealogies, resurrection accounts, and the evolving Christology that
suggest a developmental rather than static theological trajectory.&lt;/p&gt;
&lt;p&gt;Biblical infallibility is the assertion that the Scriptures are
without error in all matters, including history, science, and theology
and it has been a cornerstone of Christian orthodoxy. For many
believers, this doctrine implies that the biblical text, in its original
autographs, represents a divinely preserved and mechanically dictated
record of divine revelation, immune to the corruptions of human
transmission or the limitations of historical context. However, the
applications of modern historical methods, textual criticism, and
archaeology over the last centuries has fundamentally challenged this
premise.&lt;/p&gt;
&lt;h1 id="methodology"&gt;Methodology&lt;/h1&gt;
&lt;p&gt;To rigorously evaluate the claim of biblical infallibility, this
paper employs the historical-critical method, a scholarly framework that
treats biblical texts as human documents produced within specific
historical, cultural, and literary contexts. Unlike traditional dogmatic
approaches that begin with the assumption of divine perfection, this
methodology prioritizes empirical evidence, textual analysis, and
comparative history to reconstruct the origins and development of the
biblical canon. The analysis is structured around three primary pillars
of investigation: Textual Criticism, Historical-Archaeological
Correlation, and Literary-Redaction Criticism.&lt;/p&gt;
&lt;p&gt;It is acknowledged that the historical-critical method cannot prove
or disprove theological truths (e.g., the resurrection as a supernatural
event). Instead, this paper limits its scope to historical and textual
verifiability. The goal is not to dismiss the Bible’s religious value
but to demonstrate that its status as an “infallible” historical record
is incompatible with the empirical evidence of textual variance,
historical discrepancy, and literary development. By adhering to these
rigorous methodologies, the paper aims to provide an objective,
evidence-based assessment of the biblical text’s integrity.&lt;/p&gt;
&lt;h1 id="textual-criticism"&gt;Textual Criticism&lt;/h1&gt;
&lt;p&gt;Textual criticism treats the Bible as a product transmitted through
human agents across centuries rather than a single, immutable artifact.
Manuscripts were copied by scribes working in diverse contexts
(monasteries, scriptoria, and later by professional copyists), each
bringing different training, regional practices, and theological
tendencies to the task. As a result, the surviving manuscript tradition
shows variation at virtually every level: single-letter differences,
word-order shifts, omitted or added phrases, harmonizing adjustments,
and larger interpolations. These variants are not merely clerical noise:
they shape readings and sometimes theological emphases, demonstrating
that the biblical text as we have it is the product of ongoing human
activity, copying, correcting, glossing, and occasionally composing,
rather than a perfectly transmitted original &lt;span class="citation"
data-cites="metzger2005 Epp2015"&gt;(Metzger and Ehrman 2005; Epp and Fee
2015)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In the early Church, most manuscripts were produced by individual
Christians who desired to provide their community with a copy of the
books of the New Testament. Because of this, the demand for more
production often outweighed the accuracy of the copies &lt;span
class="citation" data-cites="metzger2005"&gt;(Metzger and Ehrman
2005)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="the-absence-of-autographs"&gt;The absence of Autographs&lt;/h2&gt;
&lt;p&gt;The Bible is a collection of very old books, books written at a time
when the technology and materials for writing were insufficient compared
to what we have today. The earliest manuscripts we have of the old
testament were written on various materials such as papyrus and animal
skin. These manuscripts were unrelentingly copied manually by scribes
for generations.&lt;/p&gt;
&lt;p&gt;One remarkable example of the destruction of manuscripts is the
collapse of the the Library of Alexandria, which enveloped a great
collection of manuscripts from different cultures. The library met its
demise through conflicts culminating in its destruction, including
potentially original Bible manuscripts. &lt;span class="citation"
data-cites="mia2024"&gt;(Lawrence 2024)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Regarding the scale of variation, modern estimates of textual
variants in the New Testament manuscript tradition vary widely depending
on counting method. Conservative tallies long cited hundreds of
thousands of variants; major recent cataloguing projects place variant
readings well over 400,000 when every orthographic, word-order, and
substantive variant is counted. Even when a large portion of variants
are minor (spelling, word order), a significant number are substantive
with implications for meaning, citation, or theology. &lt;span
class="citation" data-cites="gurry2016"&gt;(Gurry 2016)&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="case-study-1-the-pericope-adulterae-john-753-811"&gt;Case Study 1:
The Pericope Adulterae (John 7:53-8:11)&lt;/h2&gt;
&lt;p&gt;The Pericope Adulterae recounts an episode in which religious leaders
bring a woman accused of adultery before Jesus, intending to test him.
They remind him that the Law of Moses prescribes stoning for such an
offence and ask whether she should be punished. Jesus initially responds
by stooping to write on the ground (or by writing with his finger);
after a moment he replies, “Let anyone among you who is without sin be
the first to throw a stone at her.” Confronted by this challenge, the
accusers depart one by one, beginning with the oldest; when only Jesus
and the woman remain, he tells her that he does not condemn her and
instructs her to “go and sin no more.” The scene powerfully contrasts
judgmental legalism with mercy and calls attention to self-examination
and forgiveness.&lt;/p&gt;
&lt;p&gt;The story of the woman caught in adultery, known as the &lt;em&gt;Pericope
Adulterae,&lt;/em&gt; stands as one of the most famous and well-documented
examples of a later interpolation in the New Testament. While the
narrative of Jesus forgiving a woman and challenging her accusers to
cast the first stone is deeply embedded in Christian tradition and
liturgy, textual evidence overwhelmingly suggests that this passage was
not part of the original Gospel of John. Its inclusion in modern Bibles
is a testament to its theological value rather than its historical
authenticity as a Johannine composition.&lt;/p&gt;
&lt;h3 id="manuscript-evidence"&gt;Manuscript Evidence&lt;/h3&gt;
&lt;p&gt;The strongest case challenging the originality of John 7:53–8:11
centers on its absence from the earliest and most carefully transmitted
Greek witnesses. Two near-contemporary papyri, P66 and P75, both dated
to around the early third century, do not include the episode; these
codices are among the oldest surviving witnesses to John and are
particularly valuable for reconstructing the text as it circulated in
antiquity.&lt;a href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;a href="#fn2" class="footnote-ref"
id="fnref2" role="doc-noteref"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; Equally significant is
the omission of the pericope from two major fourth-century uncial
manuscripts,&lt;a href="#fn3" class="footnote-ref" id="fnref3"
role="doc-noteref"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; Codex Sinaiticus and Codex
Vaticanus, manuscripts that represent authoritative Alexandrian lines of
transmission and are heavily weighted in modern critical editions.&lt;a
href="#fn4" class="footnote-ref" id="fnref4"
role="doc-noteref"&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;&lt;a href="#fn5" class="footnote-ref"
id="fnref5" role="doc-noteref"&gt;&lt;sup&gt;5&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Textual critics have long treated this pattern of absence in early,
high-quality witnesses as decisive evidence against the passage’s
original place in John. According to &lt;span class="citation"
data-cites="metzger2005"&gt;Metzger and Ehrman (2005)&lt;/span&gt;, the
cumulative manuscript and patristic evidence points strongly toward a
non‑Johannine origin. The narrative first appears in later, less uniform
transmission streams; one of the earliest manuscripts that does include
the story within John is the bilingual Codex Bezae, which reflects a
Western textual tradition known for variant and sometimes expanded
readings.&lt;a href="#fn6" class="footnote-ref" id="fnref6"
role="doc-noteref"&gt;&lt;sup&gt;6&lt;/sup&gt;&lt;/a&gt; Taken together, these transmission
facts suggest the episode entered the Johannine corpus at a later stage
in the manuscript tradition rather than forming part of the Gospel’s
original composition.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="./images/2026-04-22-111625.png"
alt="Codex Bezae (c. 400 AD)" /&gt;
&lt;figcaption aria-hidden="true"&gt;Codex Bezae (c. 400 AD)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="stylistic-and-linguistic-anomalies"&gt;Stylistic and Linguistic
Anomalies&lt;/h3&gt;
&lt;p&gt;Scholars who examine style and language beyond the surviving
manuscripts find that the Pericope Adulterae does not sit comfortably
within the rest of John’s Gospel. Its diction and syntactic patterns
stand out from John’s usual manner of expression. Many lexical items and
phrasings present in this episode are either extremely rare or entirely
absent elsewhere in John, yet they occur with relative frequency in the
Synoptic tradition.&lt;a href="#fn7" class="footnote-ref" id="fnref7"
role="doc-noteref"&gt;&lt;sup&gt;7&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="citation" data-cites="wallace2013"&gt;Wallace (2013)&lt;/span&gt;
argues that the passage displays vocabulary, grammatical tendencies, and
thematic motifs more typical of Luke and proposes it could result from
the conflation of two earlier narratives, one traceable to Papias and
the Didaskalia and another attested in Didymus and the so‑called Gospel
of the Hebrews. &lt;span class="citation" data-cites="ehrman2005"&gt;Ehrman
(2005)&lt;/span&gt; observes that the Lukan traits ascribed to the Pericope
Adulterae are concentrated in material related to the first of those
sources.&lt;/p&gt;
&lt;p&gt;The passage’s word choices align unevenly with John’s usual lexicon
and resonate instead with words found in Luke and other non‑Johannine
traditions. Syntactic variance, sentence length, clause linkage, and
rhetorical devices in the episode contrast with Johannine norms,
suggesting either a different authorial hand or layers of redaction. The
textual evidence may reflect the merging of independent anecdotal
strands, a scenario that helps explain why early church writers and
manuscripts vary in including or positioning the episode. Liturgical and
theological shaping. Variation in vocabulary and emphasis could indicate
adaptation for local liturgical use or theological harmonization with
material circulating in communities influenced by Luke and other
second‑generation sources. These converging observations support
treating the Pericope Adulterae as a text with a complex transmission
history rather than as an integral, original Johannine composition.&lt;/p&gt;
&lt;h2 id="case-study-2-the-ending-of-mark-mark-169-20"&gt;Case Study 2: The
ending of Mark (Mark 16:9-20)&lt;/h2&gt;
&lt;p&gt;The Gospel of Mark in its earliest and most reliable Greek witnesses
ends abruptly at 16:8, where the women leave the tomb “for terror and
amazement had seized them, and they said nothing to anyone, for they
were afraid.” This stark termination contrasts with a later tradition
that continues the narrative in verses 9–20. That longer ending is
absent from Codex Sinaiticus and Codex Vaticanus and from several early
versions and patristic citations, while it appears in the majority of
later Byzantine manuscripts and in many liturgical texts. Textual
scholars therefore distinguish between the shorter ending that concludes
at 16:8, the longer ending (16:9–20) present in most later Greek
manuscripts, and an even briefer “shorter ending” attested sporadically.
The cumulative external and internal indicators have led many critical
editors to regard the longer ending as a subsequent addition rather than
the original conclusion of Mark’s Gospel &lt;span class="citation"
data-cites="metzger1987"&gt;Metzger (1987)&lt;/span&gt; &lt;span class="citation"
data-cites="robison2008"&gt;Robison (2008)&lt;/span&gt; &lt;span class="citation"
data-cites="wallace2008"&gt;Wallace (2008)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Internal stylistic evidence supports the judgment that 16:9–20 is
non‑Markan. The vocabulary, grammatical constructions, and rhetorical
pacing of the verses differ from Mark’s characteristic diction, and the
narrative link from verse 8 to verse 9 lacks smooth cohesion. The longer
ending incorporates traditions and motifs that resonate with Luke, John,
and Acts, such as specific resurrection appearances, commissioning
language, and a catalogue of signs following believers. These features
are consistent with a harmonizing editor drawing on other Gospel
traditions to supply a fuller post‑resurrection account for readers
acquainted with the wider narrative corpus &lt;span class="citation"
data-cites="metzger1987"&gt;Metzger (1987)&lt;/span&gt; &lt;span class="citation"
data-cites="black2008"&gt;Black (2008)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Scholars have proposed multiple, not mutually exclusive motivations
for adding the longer ending. Pastoral and liturgical concerns likely
played a role: communities and lectors uneasy with Mark’s suspenseful,
unresolved close may have preferred a more explicit series of
appearances and an apostolic commission to read in worship.
Harmonization and canonical complementation represent another motive,
whereby scribes familiar with the resurrection narratives elsewhere
sought to align Mark’s ending with the broader Gospel tradition.
Doctrinal and apologetic impulses also offer explanation; by appending
signs and commission material the supplement buttressed apostolic
authority and the church’s missionary identity, thereby neutralizing
theological unease generated by an abrupt, enigmatic finale &lt;span
class="citation" data-cites="metzger1987"&gt;Metzger (1987)&lt;/span&gt; &lt;span
class="citation" data-cites="black2008"&gt;Black (2008)&lt;/span&gt; &lt;span
class="citation" data-cites="stein2008"&gt;Stein (2008)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;An additional piece of manuscript evidence relevant to the
transmission history is Codex Bobbiensis. This fifth‑century Latin codex
contains a version of Mark that places the longer ending after verse
16:8 but omits some of the material found in the full longer ending,
reflecting the variety of ways communities treated Mark’s conclusion.
Codex Bobbiensis thus provides an important witness to the mosaic of
early reception attitudes: some communities expanded Mark selectively,
others preserved an abrupt close, and yet others supplied various
shorter or longer supplements. The diversity represented by witnesses
such as Codex Bobbiensis strengthens the view that the extended ending
is a later, composite development arising in multiple textual traditions
rather than a uniform, original Johannine-style conclusion.&lt;/p&gt;
&lt;p&gt;Taken together, manuscript distribution, internal linguistic markers,
and the plausible socioreligious motives for supplementation render the
hypothesis of a later addition historically probable. This conclusion
does not negate the devotional and theological functions the longer
ending served in later Christian practice, but it does prompt careful
distinction between Mark’s earliest attainable form and the accretions
that entered the Gospel as it was transmitted and used across different
early communities.&lt;/p&gt;
&lt;figure&gt;
&lt;img src="./images/2026-04-24-205012.png"
alt="Codex Bobiensis – The last page of the Gospel of Mark." /&gt;
&lt;figcaption aria-hidden="true"&gt;Codex Bobiensis – The last page of the
Gospel of Mark.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="the-role-of-scribes"&gt;The Role of Scribes:&lt;/h2&gt;
&lt;p&gt;Scribes sometimes made deliberate changes to biblical texts to
clarify theology or to correct what they perceived as errors. They
harmonized parallel passages by altering wording to match other Gospels,
smoothed abrupt or awkward transitions, and added explanatory glosses
that later became integrated into the main text. At times they expanded
narratives to supply needed doctrinal affirmations such as explicit
resurrection appearances, apostolic commissioning, or signs validating
authority. Other intentional interventions included correcting perceived
theological problems by changing tense, person, or key terms to avoid
apparent contradiction with creedal convictions, and emending what they
judged to be historical or geographical mistakes to align the text with
received tradition. These kinds of alterations are attested across
diverse manuscript families and are detectable through patterns of
vocabulary, style, and the distribution of variants in early witnesses.
&lt;span class="citation" data-cites="metzger2005"&gt;(Metzger and Ehrman
2005)&lt;/span&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img src="./images/2026-04-24-210417.png" alt="Uncial Sinaitic Codex" /&gt;
&lt;figcaption aria-hidden="true"&gt;Uncial Sinaitic Codex&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h1 id="the-clash-with-history"&gt;The Clash with History&lt;/h1&gt;
&lt;p&gt;The relationship between biblical narratives and external historical
evidence is complex and often contested; while scripture preserves
theological memory and communal identity, archaeological, epigraphic,
and historiographical data sometimes conflict with the literal reading
of those texts. Examining specific cases illustrates how scholars weigh
material remains and nonbiblical records against literary claims, how
those discrepancies inform historical reconstruction, and how
interpretive models distinguish between theological shaping and
potential historical cores within the biblical tradition.&lt;/p&gt;
&lt;h2 id="the-exodus-and-conquest-narratives"&gt;The Exodus and Conquest
Narratives&lt;/h2&gt;
&lt;p&gt;Ancient Israel’s foundational accounts of a mass departure from Egypt
and a subsequent rapid conquest of Canaan are presented with narrative
certainty in the Torah and Joshua, but they run into substantial
challenges when measured against archaeological and demographic data.
The biblical timetable and population figures imply a migration and
sojourn that would have involved on the order of a million to two
million people moving through and temporarily settling the Sinai.&lt;a
href="#fn8" class="footnote-ref" id="fnref8"
role="doc-noteref"&gt;&lt;sup&gt;8&lt;/sup&gt;&lt;/a&gt; Archaeological surveys and
excavations across the Sinai peninsula have not recovered the kinds of
sustained, widespread campsite evidence, refuse concentrations, or
infrastructural remains that such a prolonged, large‑scale migration
would be expected to leave behind. Moreover, material culture trends in
Late Bronze Age Canaan&lt;a href="#fn9" class="footnote-ref" id="fnref9"
role="doc-noteref"&gt;&lt;sup&gt;9&lt;/sup&gt;&lt;/a&gt; show no synchronous, abrupt
demographic displacement compatible with the swift, totalizing military
takeover described in Joshua; instead, regional continuity and complex
patterns of local development and collapse better characterize the
archaeological record &lt;span class="citation"
data-cites="finkelstein2001"&gt;Finkelstein and Silberman (2001)&lt;/span&gt;
&lt;span class="citation" data-cites="garrett2004"&gt;Garrett
(2004)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Textual and interdisciplinary scholarship therefore often treats the
biblical Exodus and conquest accounts as theological‑national origin
narratives rather than straightforward historical reportage. Some
researchers propose models in which smaller migrations, social memory,
and the literary shaping of diverse tribal traditions were later woven
into a cohesive national myth that served theological and identity
functions for emerging Israelite communities. Others suggest that
episodes preserved in the texts may have distant historical
cores—localized expulsions, boundary conflicts, or migrations—that were
later magnified and retold in grand scale. These interpretive frameworks
account for the mismatch between large biblical demographic claims and
the archaeological silence for mass movement in the Sinai and immediate,
wholesale conquest of Canaanite cities &lt;span class="citation"
data-cites="finkelstein2001"&gt;Finkelstein and Silberman (2001)&lt;/span&gt;
&lt;span class="citation" data-cites="miller2009"&gt;Miller and Hayes
(2009)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="the-census-of-quirinius"&gt;The Census of Quirinius&lt;/h2&gt;
&lt;p&gt;The Gospel of Luke reports that Jesus was born during a census under
Quirinius, governor of Syria, a detail that has long posed chronological
difficulty when compared with external Roman sources. Luke’s narrative
places a population registration at the time of Jesus’ birth,
associating it with Quirinius’s administrative action; however, Roman
records and the historian Josephus situate Quirinius’s well‑attested
census in Judea to the year 6 CE, an event that took place decades after
the reign of Herod the Great and the traditional timeframe assigned to
Jesus’ birth. This chronological discrepancy creates tension between
Luke’s chronological markers and independent historical data about Roman
provincial administration and the dating of Herod’s death &lt;span
class="citation" data-cites="meier1991"&gt;Meier (1991)&lt;/span&gt; &lt;span
class="citation" data-cites="ehrman2012"&gt;Ehrman (2012)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Scholars have advanced several strategies to reconcile or explain the
disjunction. Some attempts harmonize the accounts by hypothesizing an
earlier, less well‑attested census or an earlier administrative role for
Quirinius, though documentary evidence for such an action is thin and
contested. Other scholars treat Luke’s reference as theologically
motivated historiography, where Roman administrative terminology is used
anachronistically or loosely to frame a theological message about
imperial involvement in the nativity story. Still other interpreters
propose that Luke conflated memories of separate events or incorporated
a known later event into the nativity narrative for narrative or
theological ends. These approaches underline how careful comparison of
biblical narrative claims with external epigraphic and historiographical
evidence can reveal tensions and invite nuanced readings that separate
theological aims from strict chronological reporting &lt;span
class="citation" data-cites="meier1991"&gt;Meier (1991)&lt;/span&gt; &lt;span
class="citation" data-cites="ehrman2012"&gt;Ehrman (2012)&lt;/span&gt;.&lt;/p&gt;
&lt;h1
id="internal-inconsistencies-contradictions-and-development"&gt;Internal
Inconsistencies: Contradictions and Development&lt;/h1&gt;
&lt;p&gt;The internal fabric of the New Testament contains tensions that
reveal divergent traditions, editorial activity, and theological
development. Examining genealogies, resurrection accounts, and
chronologies exposes concrete contradictions in names, sequences, and
events. Tracing how Christological expression intensifies from the
Synoptics to John demonstrates theological elaboration across
communities and generations. Finally, the literary relationships among
the Synoptics indicate active use, adaptation, and redaction of earlier
sources by later evangelists rather than verbatim reportage.&lt;/p&gt;
&lt;h2 id="contradictory-accounts"&gt;Contradictory Accounts&lt;/h2&gt;
&lt;p&gt;The genealogical presentations in Matthew and Luke differ
substantially in structure, purpose, and content. Matthew traces Jesus’
ancestry from Abraham through David’s son Solomon to Joseph in a royal,
legal line that emphasizes fulfillment of Jewish messianic expectations,
arranging the genealogy in three sets of fourteen generations; Luke, by
contrast, traces a markedly different sequence backward from Jesus to
Adam via David’s son Nathan and names different men as Joseph’s father,
creating an apparent contradiction in the paternal line ascribed to
Jesus. Scholarly solutions range from typological and legal
interpretations such as levirate marriage or royal/legal genealogy to
the conclusion that the evangelists preserved competing traditions with
different theological agendas rather than a single harmonizable
biography &lt;span class="citation"
data-cites="hooker1993 meier1991"&gt;(Hooker 1993; Meier 1991)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The resurrection narratives likewise display significant divergence
in who visited the tomb, what they witnessed there, and the order of
post‑resurrection appearances. Mark’s shorter ending stops at silence
and fear with the women fleeing the tomb; Matthew presents an angelic
appearance, an earthquake, and Jesus’ appearance to the disciples in
Galilee; Luke emphasizes Emmaus&lt;a href="#fn10" class="footnote-ref"
id="fnref10" role="doc-noteref"&gt;&lt;sup&gt;10&lt;/sup&gt;&lt;/a&gt; and Jerusalem
appearances with a different cast of witnesses and a distinctive
portrayal of the risen body; John foregrounds personal encounters such
as Mary Magdalene’s recognition and Thomas’s confession of belief. These
differences include variation in the number and identity of women at the
tomb, the presence or absence of angels, the location of appearances,
and the initial reactions of witnesses. The cumulative pattern suggests
independent narrative streams and theological emphases shaped by
distinct community memories and purposes rather than a single, uniform
eyewitness chronology &lt;span class="citation"
data-cites="brown1994"&gt;Kenny (2004)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Chronological claims also generate internal tension, most notably the
expression “three days and three nights” and the widely attested Friday
crucifixion to resurrection on Sunday. Some first‑century interpreters
understood idiomatic Sabbath counting that allowed part‑day counts to
satisfy the phrase while others note that Jesus’ own sayings and Passion
chronologies differ in Gospel testimony in ways that require
interpretive smoothing. The divergent temporal markers highlight how
gospel authors framed events according to theological typology,
liturgical reckoning, and communal memory, producing narratives that are
not strictly harmonized in chronological detail &lt;span class="citation"
data-cites="wright2003"&gt;(Wright 2003)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="the-development-of-christology"&gt;The Development of
Christology&lt;/h2&gt;
&lt;p&gt;Mark portrays Jesus primarily as the suffering Messiah and Son of
Man, a figure who embodies the paradox of a messianic vocation bound up
with suffering, rejection, and a tendency toward secrecy concerning his
identity and mission. Mark’s emphasis on human suffering, Jesus’ emotive
responses, and the motif often called the “Messianic Secret” give
priority to an ambiguous, ambivalent christological presentation that
yields to confession only gradually within the narrative &lt;span
class="citation" data-cites="hooker1991"&gt;(Hooker 1991)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Matthew and Luke present an expanded christology that incorporates
infancy narratives, prophetic fulfillment formulas, and more overt
claims to Jesus’ lordship. Both evangelists include birth narratives
that signal divine initiative in Jesus’ origins and deploy scriptural
fulfillment to locate Jesus within Israel’s salvation history; their
portrayals of Jesus move toward clearer recognition of divine status and
theological significance while retaining narrative continuity with
Markan material. The emphasis on fulfillment and the inclusion of
infancy material mark a theological intensification relative to Mark
&lt;span class="citation" data-cites="safrai1990 porter1997"&gt;(Safrai 1990;
Porter 1997)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;John advances christology further by opening with a high
christological prologue that identifies Jesus with the preexistent
Logos, employs explicit “I AM” sayings that echo divine self‑designation
in Hebrew scripture, and stages extended discourses that assert unique
ontological claims. The Johannine Jesus functions as both revealer and
revelation, and the language of preexistence and ontological unity with
the Father exemplify a developed theological language that presupposes
reflection beyond the earliest Synoptic strata. The gradient from Mark’s
messianic suffering figure to John’s preexistent Logos indicates
theological evolution within early Christian communities rather than a
static, fully articulated christology from the outset &lt;span
class="citation" data-cites="brown1970 barrett1978"&gt;(Brown 1970; Barrett
1978)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="the-synoptic-problem"&gt;The Synoptic Problem&lt;/h2&gt;
&lt;p&gt;Markan Priority, the dominant solution to the Synoptic Problem, holds
that Mark was written first and that Matthew and Luke used Mark as a
principal source while also drawing on additional material unique to
them. Literary analysis shows extensive verbatim agreement between
Matthew, Luke, and Mark, often with Matthew and Luke improving grammar,
clarifying awkward features, or smoothing theological tensions in Mark’s
narrative; such editorial behavior points to authors who actively
composed and adapted existing texts for their own communities rather
than serving as neutral recorders of independent eyewitness testimony.
The double‑source hypothesis that supplements Mark with a hypothetical
sayings source, Q, for material common to Matthew and Luke but absent in
Mark further underscores the composite and editorial nature of the
canonical Gospels &lt;span class="citation"
data-cites="goodacre2001"&gt;(Goodacre 2001)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The implications of Markan Priority and editorial adaptation are
significant for historical reconstruction. If evangelists worked as
redactors who shaped, arranged, and augmented sources to address
theological and pastoral concerns, then differing portraits of Jesus and
variant event sequences reflect editorial choices and community memory
as much as historical reminiscence. Recognizing the Gospels as
theological narratives fashioned from earlier traditions explains why
internal contradictions and developmental trajectories appear within the
corpus and why scholars must employ careful source criticism, form
criticism, and redaction criticism when attempting to recover historical
foundations beneath the theological layers &lt;span class="citation"
data-cites="rankin2002 hooker1991"&gt;(Rankin 2002; Hooker
1991)&lt;/span&gt;.&lt;/p&gt;
&lt;h1 id="theological-implications"&gt;Theological Implications&lt;/h1&gt;
&lt;h2 id="distinguishing-inerrancy-from-infallibility"&gt;Distinguishing
“Inerrancy” from “Infallibility”&lt;/h2&gt;
&lt;p&gt;Debates about how to preserve doctrinal confidence in scripture often
hinge on redefining terms so that older claims of verbal inerrancy are
narrowed to a claim about spiritual authority rather than literal
historical or scientific accuracy. Some contemporary theologians and
confessional traditions explicitly confine inerrancy to “matters of
faith and morals,” thereby allowing for historical, chronological, and
scientific discrepancies without conceding the Bible’s authority for
doctrine and ethical teaching. This conciliatory move seeks to protect
ecclesial teaching while acknowledging the complex compositional history
and the presence of demonstrable errors and divergent traditions in the
text &lt;span class="citation" data-cites="metzger2005 ehrman2005"&gt;(Metzger
and Ehrman 2005; Ehrman 2005)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;A stronger historical claim is that the evidential record undermines
even a robust form of infallibility when that term is taken to imply
reliable historical reportage. The presence of demonstrable
chronological contradictions, divergent genealogies, conflicting
resurrection sequences, and clear signs of editorial alteration for
theological or liturgical reasons indicates that the texts do not
consistently function as historically infallible chronicles. Treating
the Bible as infallible in spiritual or moral instruction while
acknowledging historical fallibility is a coherent theological stance,
but the empirical evidence motivates scholars to distinguish carefully
between theological authority and empirical historicity &lt;span
class="citation" data-cites="metzger1987"&gt;(Metzger 1987)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="the-human-element"&gt;The Human Element&lt;/h2&gt;
&lt;p&gt;The biblical corpus is the product of multiple human authors and
communities writing across centuries, each bringing particular
perspectives, social locations, rhetorical aims, and theological
agendas. These human dimensions account for variant traditions,
editorial harmonizations, and occasional historical inaccuracies;
recognizing them does not necessitate dismissing the texts’ religious
significance, but it does require that interpreters attend to authorial
intents, redactional processes, and the limits of individual and
communal knowledge in antiquity. As &lt;span class="citation"
data-cites="ehrman2005"&gt;Ehrman (2005)&lt;/span&gt; argued, scribes and authors
sometimes altered texts deliberately to clarify doctrine or to resolve
perceived problems, which demonstrates both the human agency shaping the
text and the theological stakes that motivated interventions.&lt;/p&gt;
&lt;p&gt;Acknowledging the Bible’s human provenance invites methodological
humility and a distinction between confessional readings and
historical‑critical inquiry. It allows theological reflection to draw on
the texts’ moral and spiritual resources while permitting historians and
textual critics to map how beliefs developed, how traditions were
transmitted and adapted, and how communities used scripture to negotiate
identity and doctrine. This dual approach respects religious conviction
without obscuring the evident human processes that produced the
canonical texts &lt;span class="citation"
data-cites="metzger2005 ehrman2005"&gt;(Metzger and Ehrman 2005; Ehrman
2005)&lt;/span&gt;.&lt;/p&gt;
&lt;h1 id="conclusion"&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The evidence surveyed shows that the Bible contains significant
tensions with external historical data, internal contradictions, and
clear signs of theological development and scribal intervention. These
features collectively challenge simple claims of literal inerrancy and
support understanding the corpus as a product of layered composition,
transmission, and communal use.&lt;/p&gt;
&lt;p&gt;Three interlocking pillars ground this assessment. Textual evidence
from manuscript traditions reveals additions, omissions, and deliberate
alterations exemplified by the Pericope Adulterae and the endings of
Mark, which demonstrate how scribes and communities shaped the text over
time. Historical comparison exposes mismatches between narrative claims
and archaeological or historiographical data, as with the
Exodus/conquest traditions and the Quirinius census, underscoring limits
to straightforward historicism. Internal consistency issues, including
divergent genealogies, variant resurrection accounts, and evolving
christological language across the Gospels, indicate theological
development rather than a single, unchanging revelation.&lt;/p&gt;
&lt;p&gt;Approaching the Bible as a complex library of human religious
experience preserves its moral and spiritual resources while
acknowledging the human processes that produced and transmitted these
writings. This perspective honors both the texts’ lived role in faith
communities and the evidential realities revealed by critical
scholarship.&lt;/p&gt;
&lt;p&gt;Scholars, clergy, and readers should engage scripture with
historical‑critical tools alongside theological reflection. Combining
source, form, redaction, and manuscript criticism with archaeological
and historiographical comparison will yield a more accurate and nuanced
understanding of the Bible’s origins, development, and ongoing
significance.&lt;/p&gt;
&lt;h1 id="bibliography"&gt;Bibliography&lt;/h1&gt;
&lt;div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list"&gt;
&lt;div id="ref-barrett1978" class="csl-entry" role="listitem"&gt;
Barrett, C. K. 1978. &lt;em&gt;The Gospel According to St John&lt;/em&gt;. London:
SPCK.
&lt;/div&gt;
&lt;div id="ref-black2008" class="csl-entry" role="listitem"&gt;
Black, David Alan. 2008. &lt;span&gt;“Perspectives on the Ending of Mark: Four
Views.”&lt;/span&gt; In, edited by David Alan Black. Nashville: B &amp;amp; H
Academic.
&lt;/div&gt;
&lt;div id="ref-brown1970" class="csl-entry" role="listitem"&gt;
Brown, Raymond E. 1970. &lt;em&gt;The Gospel According to John (i-XII)&lt;/em&gt;.
Garden City: Doubleday.
&lt;/div&gt;
&lt;div id="ref-brown1994" class="csl-entry" role="listitem"&gt;
———. 1994. &lt;em&gt;The Death of the Messiah, Volume 2&lt;/em&gt;. New York: Anchor
Bible.
&lt;/div&gt;
&lt;div id="ref-ehrman2005" class="csl-entry" role="listitem"&gt;
Ehrman, Bart D. 2005. &lt;em&gt;Misquoting Jesus: The Story Behind Who Changed
the Bible and Why&lt;/em&gt;. San Francisco: HarperSanFrancisco.
&lt;/div&gt;
&lt;div id="ref-ehrman2012" class="csl-entry" role="listitem"&gt;
———. 2012. &lt;em&gt;Did Jesus Exist? The Historical Argument for Jesus of
Nazareth&lt;/em&gt;. New York: HarperOne.
&lt;/div&gt;
&lt;div id="ref-Epp2015" class="csl-entry" role="listitem"&gt;
Epp, Eldon J., and Gordon D. Fee. 2015. &lt;em&gt;Studies in the Theory and
Method of New Testament Textual Criticism&lt;/em&gt;. Eugene, OR: Wipf; Stock.
&lt;/div&gt;
&lt;div id="ref-finkelstein2001" class="csl-entry" role="listitem"&gt;
Finkelstein, Israel, and Neil Asher Silberman. 2001. &lt;em&gt;The Bible
Unearthed: Archaeology’s New Vision of Ancient Israel and the Origin of
Its Sacred Texts&lt;/em&gt;. New York: Free Press.
&lt;/div&gt;
&lt;div id="ref-garrett2004" class="csl-entry" role="listitem"&gt;
Garrett, Stephen. 2004. &lt;em&gt;Unearthing the Bible: Archaeological
Discoveries Relating to the Old Testament&lt;/em&gt;. Cambridge: Cambridge
University Press.
&lt;/div&gt;
&lt;div id="ref-goodacre2001" class="csl-entry" role="listitem"&gt;
Goodacre, Mark. 2001. &lt;em&gt;The Synoptic Problem: A Way Through the
Maze&lt;/em&gt;. London: T&amp;amp;T Clark.
&lt;/div&gt;
&lt;div id="ref-gurry2016" class="csl-entry" role="listitem"&gt;
Gurry, Peter J. 2016. &lt;span&gt;“The Number of Variants in the Greek New
Testament: A Proposed Estimte.”&lt;/span&gt;
&lt;/div&gt;
&lt;div id="ref-hooker1991" class="csl-entry" role="listitem"&gt;
Hooker, Morna D. 1991. &lt;em&gt;Jesus and the Servant&lt;/em&gt;. London: SCM
Press.
&lt;/div&gt;
&lt;div id="ref-hooker1993" class="csl-entry" role="listitem"&gt;
———. 1993. &lt;em&gt;The Gospel According to Saint Mark&lt;/em&gt;. London: Black’s
New Testament Commentaries.
&lt;/div&gt;
&lt;div id="ref-kenny2004" class="csl-entry" role="listitem"&gt;
Kenny, Anthony. 2004. &lt;em&gt;Resurrection: What It Means for Us&lt;/em&gt;. New
Haven: Yale University Press.
&lt;/div&gt;
&lt;div id="ref-mia2024" class="csl-entry" role="listitem"&gt;
Lawrence, Mia. 2024. &lt;span&gt;“Where Are the Original Bible
Manuscripts?”&lt;/span&gt; 2024. &lt;a
href="https://www.freebiblestudyhub.com/archives/4299"&gt;https://www.freebiblestudyhub.com/archives/4299&lt;/a&gt;.
&lt;/div&gt;
&lt;div id="ref-meier1991" class="csl-entry" role="listitem"&gt;
Meier, John P. 1991. &lt;em&gt;A Marginal Jew: Rethinking the Historical
Jesus, Volume 1&lt;/em&gt;. New York: Doubleday.
&lt;/div&gt;
&lt;div id="ref-metzger1987" class="csl-entry" role="listitem"&gt;
Metzger, Bruce M. 1987. &lt;em&gt;A Textual Commentary on the Greek New
Testament&lt;/em&gt;. London: United Bible Societies.
&lt;/div&gt;
&lt;div id="ref-metzger2005" class="csl-entry" role="listitem"&gt;
Metzger, Bruce M., and Bart D. Ehrman. 2005. &lt;em&gt;The Text of the New
Testament: Its Transmission, Corruption, and Restoration&lt;/em&gt;. 4th ed.
New York: Oxford University Press.
&lt;/div&gt;
&lt;div id="ref-miller2009" class="csl-entry" role="listitem"&gt;
Miller, J. Maxwell, and John H. Hayes. 2009. &lt;em&gt;A History of Ancient
Israel and Judah&lt;/em&gt;. Louisville: Westminster John Knox Press.
&lt;/div&gt;
&lt;div id="ref-porter1997" class="csl-entry" role="listitem"&gt;
Porter, Stanley E. 1997. &lt;em&gt;The Literary Function of Possessive
Pronouns in the Gospel of Matthew&lt;/em&gt;. New York: Peter Lang.
&lt;/div&gt;
&lt;div id="ref-rankin2002" class="csl-entry" role="listitem"&gt;
Rankin, H. O. 2002. &lt;em&gt;Redaction Criticism and the Gospels&lt;/em&gt;.
Atlanta: Scholars Press.
&lt;/div&gt;
&lt;div id="ref-robison2008" class="csl-entry" role="listitem"&gt;
Robison, John W. 2008. &lt;em&gt;The Text of Mark: A Study of the
Endings&lt;/em&gt;. Atlanta: Scholars Press.
&lt;/div&gt;
&lt;div id="ref-safrai1990" class="csl-entry" role="listitem"&gt;
Safrai, Shmuel. 1990. &lt;em&gt;The Literature of the Sages, Second Temple and
Apocalyptic Periods&lt;/em&gt;. Grand Rapids: Eerdmans.
&lt;/div&gt;
&lt;div id="ref-stein2008" class="csl-entry" role="listitem"&gt;
Stein, Robert H. 2008. &lt;span&gt;“The Ending of Mark.”&lt;/span&gt; &lt;em&gt;Bulletin
for Biblical Research&lt;/em&gt; 18 (1): 79–100.
&lt;/div&gt;
&lt;div id="ref-wallace2008" class="csl-entry" role="listitem"&gt;
Wallace, Daniel B. 2008. &lt;em&gt;Reexamining the Textual Evidence for the
Ending of Mark&lt;/em&gt;. Fearn: Paternoster Press.
&lt;/div&gt;
&lt;div id="ref-wallace2013" class="csl-entry" role="listitem"&gt;
———. 2013. &lt;span&gt;“Where Is the Story of the Woman Caught in Adultery
Really From?”&lt;/span&gt; 2013. &lt;a
href="https://danielbwallace.com/2013/06/26/where-is-the-story-of-the-woman-caught-in-adultery-really-from/"&gt;https://danielbwallace.com/2013/06/26/where-is-the-story-of-the-woman-caught-in-adultery-really-from/&lt;/a&gt;.
&lt;/div&gt;
&lt;div id="ref-wright2003" class="csl-entry" role="listitem"&gt;
Wright, N. T. 2003. &lt;em&gt;The Resurrection of the Son of God&lt;/em&gt;.
Minneapolis: Fortress Press.
&lt;/div&gt;
&lt;/div&gt;
&lt;section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;Early third-century papyrus manuscript (P66) of the
Gospel of John; a principal early witness for establishing textual
readings in John.&lt;a href="#fnref1" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn2"&gt;&lt;p&gt;Early third-century papyrus (P75) containing substantial
portions of Luke and John; closely aligned with Codex Vaticanus and
important for the Alexandrian text tradition.&lt;a href="#fnref2"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn3"&gt;&lt;p&gt;An uncial codex is a manuscript written in a majuscule,
all-capital script used from the third to eighth centuries; codices
allowed writing on both sides of leaves and facilitated reference to
discrete passages.&lt;a href="#fnref3" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn4"&gt;&lt;p&gt;Fourth-century parchment codex containing most of the
Christian Bible; a principal Alexandrian witness with significant
authority in textual criticism.&lt;a href="#fnref4" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn5"&gt;&lt;p&gt;Fourth-century parchment codex (Vat. gr. 1209); a
foundational Alexandrian witness for both the Septuagint and New
Testament texts.&lt;a href="#fnref5" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn6"&gt;&lt;p&gt;Fifth-century bilingual Greek–Latin codex notable for
its Western text-type readings and for preserving variant traditions of
the Gospels and Acts.&lt;a href="#fnref6" class="footnote-back"
role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn7"&gt;&lt;p&gt;The &lt;strong&gt;Synoptic Gospels&lt;/strong&gt; (Matthew, Mark,
and Luke) are called “synoptic” because they can be viewed together in
parallel and share extensive overlap in content and sequence; their
interrelationships are central to critical study of the Gospels and to
reconstructing early Jesus traditions.&lt;a href="#fnref7"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn8"&gt;&lt;p&gt;The Sinai peninsula is the triangular desert landbridge
between Africa and Asia where the biblical narrative places the
Israelites’ wandering; archaeologically it is challenging terrain for
preservation of ephemeral nomadic campsites.&lt;a href="#fnref8"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn9"&gt;&lt;p&gt;The Late Bronze Age (c. 1550–1200 BCE) is the
archaeological period conventionally associated with the late Egyptian
Empire and the historical horizon often connected to the Exodus and the
early Israelite settlement in Canaan.&lt;a href="#fnref9"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn10"&gt;&lt;p&gt;Emmaus is the village to which Luke narrates two
disciples traveling when they encounter the risen Jesus; it functions as
a key locale in Luke’s resurrection narrative.&lt;a href="#fnref10"
class="footnote-back" role="doc-backlink"&gt;↩︎&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>
    </entry>
</feed>
