A => .build.yml +13 -0
@@ 1,13 @@
+image: alpine/latest
+packages:
+ - hugo
+oauth: pages.sr.ht/PAGES:RW
+environment:
+ site: mrtn.run
+tasks:
+ - package: |
+ cd $site
+ hugo
+ tar -C public -cvz . > ../site.tar.gz
+ - upload: |
+ acurl -f https://pages.sr.ht/publish/$site -Fcontent=@site.tar.gz
A => .gitignore +2 -0
@@ 1,2 @@
+public/
+.hugo_build.lock
A => archetypes/default.md +6 -0
@@ 1,6 @@
+---
+title: "{{ replace .Name "-" " " | title }}"
+date: {{ .Date }}
+draft: true
+---
+
A => config.toml +6 -0
@@ 1,6 @@
+baseURL = "https://mrtn.run"
+languageCode = "en-us"
+title = "Maarten Vos's Blog"
+
+[permalinks]
+blog = "/:year/:month/:day/:filename"
A => content/blog/Complexity-hunt.md +70 -0
@@ 1,70 @@
+---
+title: "Complexity hunt"
+date: 2022-07-30T17:56:42+02:00
+---
+
+Programming languages are getting too complex for their own good. Not only is it
+difficult to remember every new feature of your programming language, previously
+written code also starts to look unidiomatic. But that's not the worst of it.
+When you start to rely on these new fancy features, you are hiding important
+details of your code. Or, in the following case, introduces a bug you have to
+actively hunt for.
+
+```C#
+public override Stream OnGetStream(GetStreamArgs e)
+{
+ var stream = new MemoryStream();
+
+ using var zip = new ZipArchive(stream, ZipArchiveMode.Create, true);
+
+ stream.Position = 0;
+
+ return stream;
+}
+```
+
+Take the previous code block for example, this is complete valid C# and there
+doesn't appear to be anything wrong with it. It uses the new using syntax
+introduced in C# 8. However, if you were to run this code, you would notice that
+what you get back is an empty archive at best, or an invalid one at worst. Why
+is that you may ask? Well, the answers lays in how the ZipArchive class works.
+The ZipArchive class only writes its data to the underlying stream once it has
+been disposed. You may think, but that's what the using statement does, and you
+would be right. However, the new using syntax comes with a caveat. It brings
+your variable into the scope of the method.
+
+The using statement wraps your code into a try-finally block, where the object is diposed.
+However, this happens at the end of the scope, i.e the method.
+Before that happens, we reset the stream's position so that it can be read, but disposing of our ZipArchive moves the Position ahead for more writing. If you remember how the ZipArchive class works, it only writes its data to the underlying stream
+once its been disposed. What you get is code that looks perfectly fine, but is
+broken because some fancy new syntax doesn't behave how you would expect it
+would (disposing right after the object was last used). I spent my morning at work figuring this out and while it wasn't
+particularly difficult, it took time that I could have spent on more important
+issues.
+
+```C#
+public override Stream OnGetStream(GetStreamArgs e)
+{
+ var stream = new MemoryStream();
+
+ using (var zip = new ZipArchive(stream, ZipArchiveMode.Create, true))
+ {
+ }
+
+ // Or you could do this.
+ //zip.Dispose();
+
+ stream.Position = 0;
+
+ return stream;
+}
+```
+
+As you can see in the code above, the issue is solved easily. You use the old
+syntax, which introduces a new scope and ensures that the object is disposed
+before setting the stream's position to 0, or you dispose it manually. I prefer using the old
+syntax since it introduces that new scope, making the code easier to
+follow since it's clear where the ZipArchive is disposed.
+
+With that, my hunt for complexity comes to an end...... until history repeats
+itself. Happy hunting!
A => content/blog/Status-update-July-2022.md +49 -0
@@ 1,49 @@
+---
+title: "Status update, July 2022"
+date: 2022-07-30T17:20:11+02:00
+---
+
+Hello there! How long has it been, a year? Before I get into what I did for the
+month of July, I wanted to quickly explain what's going on here. I started
+this blog the 8th of May, 2021. I picked a simple theme that I didn't hate and
+wrote 2 blog posts, both unrelated to technology. I'd like to think that I've
+grown in that year and that I'm now ready to write some things that I'm actually
+interested in. With that out of the way, here's what I did this month:
+
+I started working on [shishutsu][1], which is a web application for categorizing your spending habits.
+Okay, it's a web application for categorizing *my* spending habits. I wanted to develop
+something that I need myself, and it's been really fun so far! It's being
+written in Go because go has an excellent built-in http server and great
+templating support. It's also fast and does not require a virtual machine like
+.NET or Java does. I've implemented a couple of things, such as sign-ins and
+importing transaction data[^1], but not the core feature of actually
+categorizing your statements. But, that's because I've been so busy working on
+some other things like-
+
+Badger! Badger is a framework, also written in Go, for easily writing web
+applications that require data manipulation, usually coming from a
+database. You give it your database tables and it handles everything for you. It
+generates pages for your queries, forms for creating or editing data and allows for
+lots of customization on top of that. It features zero javascript and is all
+rendered server-side using Go's html/template package. I wish I could give you a
+snippet showing what is required to get a badger application going, but so much
+has still to be done, and even more is going to change. Showing it in its
+current state would just be dishonest. I will make a blog post when it
+eventually becomes public, so stay tuned for that!
+
+As this status update is coming to a close, there is only one thing left to talk
+about. This blog! I rewrote it from scratch without using an existing theme. You
+may notice though that it isn't entirely unique. I did copy the style from [Drew
+Devault's Blog][2] for a simple reason. I really like the style of it. It's
+simple without too much fuss and is generally easy on the eyes. I did however
+add dark mode, which automatically changes depending on your browser's
+preference. I stole some text that read well,
+such as the footer and comment section on blog posts, hopefully he doesn't mind. I didn't see any reason to change what wasn't broken, and so here we are. I hope you enjoyed reading one of
+hopefully many status updates to come, and with that, until next time!
+
+[1]: https://git.sr.ht/~inferiormartin/shishutsu
+[2]: https://drewdevault.com
+
+[^1]: Sadly, my bank does support have a publicly available API. I have to
+ export CSV files, and while I like CSV, I have to do it via their very slow
+ web interface.
A => layouts/blog/single.html +35 -0
@@ 1,35 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{{ .Title }}</title>
+ <link rel="stylesheet" href="/style.css">
+ </head>
+ <body>
+ <main>
+ <h2>{{ .Title }}</h2>
+ <h3>{{ .Date.Format "January 2, 2006" }} on <a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a></h3>
+ <div id="blog-post">
+ <article>
+ {{ .Content }}
+ </article>
+ </div>
+ </main>
+
+ <section id="comment">
+ <p>Have a comment on one of my posts? Start a discussion in <a
+ href="https://lists.sr.ht/~inferiormartin/public-inbox">my
+ public inbox</a> by sending an email to <a
+ href="mailto:~inferiormartin/public-inbox@lists.sr.ht">~inferiormartin/public-inbox@lists.sr.ht</a>
+ [<a href="https://man.sr.ht/lists.sr.ht/etiquette.md">mailing list
+ etiquette</a>]</p>
+ </section>
+
+ <footer>
+ <span>The content for this site is <a
+ href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.</span>
+ <span>The <a href="https://git.sr.ht/~inferiormartin/mrtn.run">code for this site</a> is <a href="https://opensource.org/licenses/MIT">MIT</a>.</span>
+ </footer>
+ </body>
+</html>
A => layouts/index.html +39 -0
@@ 1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{{ .Title }}</title>
+ <link rel="stylesheet" href="/style.css">
+ </head>
+ <body>
+ <main id="index">
+ <section class="articles">
+ <h1 id="index">{{ .Title }}</h1>
+ {{ range (where .Site.RegularPages "Section" "blog") }}
+ <article id="index">
+ <span>{{ .Date.Format "January 2, 2006" }}</span>
+ <br>
+ <a href="{{ .Permalink }}">{{ .Title }}</a>
+ </article>
+ {{ end }}
+ </section>
+ <aside>
+ <img class="avatar" src="/avatar.jpg">
+ <dl>
+ <dt>email</dt>
+ <dd><a href="mailto:maarten@mrtn.run">maarten@mrtn.run</a></dd>
+ <dt>sourcehut</dt>
+ <dd><a href="https://sr.ht/~inferiormartin">~inferiormartin</a></dd>
+ </dl>
+ </aside>
+ </main>
+ <footer>
+ <span>The content for this site is <a
+ href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA<a/>.</span>
+ <span>The <a href="https://git.sr.ht/~inferiormartin/mrtn.run">code
+ for this site</a> is <a
+ href="https://opensource.org/licenses/MIT">MIT</a>.</span>
+ </footer>
+ </body>
+</html>
A => static/avatar.jpg +0 -0
A => static/style.css +92 -0
@@ 1,92 @@
+* {
+ font-family: sans-serif;
+}
+
+* :not(p) {
+ padding: 0;
+ margin: 0;
+}
+
+h1#index {
+ margin-bottom: 25px;
+}
+
+h3 {
+ margin-bottom: 25px;
+}
+
+#blog-post {
+ padding-left: 100px;
+ padding-right: 100px;
+ text-align: left;
+}
+
+#comment {
+ padding-left: 50px;
+ padding-right: 50px;
+ margin-top: 25px;
+ margin-bottom: 25px;
+}
+
+body {
+ max-width: 920px;
+ margin: 0 auto;
+ padding: 1rem;
+}
+
+main#index {
+ display: flex;
+ justify-content: space-between;
+}
+
+article#index {
+ margin-bottom: 10px;
+}
+
+dl, dd {
+ margin-bottom: 10px;
+}
+
+dl {
+ display: grid;
+ grid-template-columns: max-content auto;
+}
+
+dt {
+ font-weight: bold;
+ margin-right: 20px;
+}
+
+.avatar {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ width: 50%;
+ border-radius: 5%;
+ margin-bottom: 25px;
+
+ height: auto;
+ width: auto;
+ max-width: 150px;
+ max-height: 150px;
+}
+
+footer {
+ text-align: center;
+}
+
+@media (prefers-color-scheme: dark) {
+ body {
+ background: #080808;
+ color: white;
+ }
+
+ a:link {
+ color: #ADD8E6;
+ }
+
+ a:visited {
+ color: #CBC3E3;
+ }
+
+}