commit ed6c1e9522537fc8a8d4ee1b3819d749a524a357 Author: Daniel Fichtinger Date: Wed Jul 2 16:02:49 2025 -0400 initial commit diff --git a/.build.yml b/.build.yml new file mode 100644 index 0000000..eec049e --- /dev/null +++ b/.build.yml @@ -0,0 +1,30 @@ +image: alpine/edge +oauth: pages.sr.ht/PAGES:RW +packages: + - hut + - uv +environment: + site: ficd.ca +tasks: + - build: | + if [ "$GIT_REF" = "refs/heads/main" ]; then + uv run --with 'git+https://git.sr.ht/~ficd/zona' zona build + else + echo "Skipping build: not on main" + fi + + # - package: | + # if [ "$GIT_REF" = "refs/heads/main" ]; then + # cd public + # tar -cvz . > ../public.tar.gz + # else + # echo "Skipping package: not on main" + # fi + + # - upload: | + # if [ "$GIT_REF" = "refs/heads/main" ]; then + # hut pages publish -d "$site" public.tar.gz + # else + # echo "Skipping upload: not on main" + # fi + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a48cf0d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +public diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..61d6850 --- /dev/null +++ b/config.yml @@ -0,0 +1,25 @@ +title: Daniel Fichtinger +base_url: https://ficd.ca +language: en +sitemap: + Home: / + Blog: /blog + Now: /now + Contact: /contact +ignore: +- .git +- .env +- '*/.marksman.toml' +markdown: + image_labels: true + syntax_highlighting: + enabled: true + theme: ashen + wrap: false +theme: + name: default +build: + clean_output_dir: true + include_drafts: false +blog: + dir: blog diff --git a/content/.kakroot b/content/.kakroot new file mode 100644 index 0000000..e69de29 diff --git a/content/.marksman.toml b/content/.marksman.toml new file mode 100644 index 0000000..e69de29 diff --git a/content/.well-known/discord b/content/.well-known/discord new file mode 100644 index 0000000..f052e53 --- /dev/null +++ b/content/.well-known/discord @@ -0,0 +1 @@ +dh=f8548f3bdad262cca03fe75eaa2ef36d3fa4f0a5 diff --git a/content/LICENSE.md b/content/LICENSE.md new file mode 100644 index 0000000..27c5cfe --- /dev/null +++ b/content/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Daniel Fichtinger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/content/about.md b/content/about.md new file mode 100644 index 0000000..6e16d00 --- /dev/null +++ b/content/about.md @@ -0,0 +1,26 @@ +--- +title: About Me +--- + +# About Me + +My name is Daniel, and I am a graduate student researching cybersecurity, +programmer, and Linux enthusiast. I completed a Bachelor's of Computing +(Honours) at Queen's University in 2024, and I'm currently in the Master's of +Science program at the School of Computing. As part of the NSERC CREATE +Cybersecurity program, my work combines programming, cryptography, system +design, and threat modeling to tackle real-world security challenges. + +My research interest is authentication, and I like programming in Go and Python. +I spend my free time writing code, tinkering, and contributing to open-source +projects. Feel free to [contact me](/contact) if you want to see my resume. + +I use Kakoune as my main text editor, and I type in +[Colemak-DH](https://colemakmods.github.io/mod-dh/) on a +[custom layout](https://sr.ht/~ficd/zmk). I run Arch Linux on a desktop PC and +ThinkPad, my preferred terminal is Foot, and I've been enjoying Niri as a window +manager. + +I'm passionate about minimalist technology. This website is part of +[the 1mb club](https://1mb.club/), [JavaScript free](https://jsfree.org/), and +built with [zona](https://sr.ht/~ficd/zona), a tool I wrote myself. diff --git a/content/blog/building-this-site.md b/content/blog/building-this-site.md new file mode 100644 index 0000000..5b83aab --- /dev/null +++ b/content/blog/building-this-site.md @@ -0,0 +1,29 @@ +--- +title: Building This Site +date: 2025-04-10 +--- + +I care about thoughtful design, and forcing your visitors to download dozens of +megabytes of assets and JavaScript dependencies just to read a single article +doesn't feel very thoughtful to me. That's why I've committed to a 1 megabyte +upper limit for every page on this site. There's also no point for there to be +any JavaScript here, so I'd rather not include it, even if some fancy features +may rely on it. + +My goal on this website is simply to share my thoughts. I can't really do that +if I'm distracted by the framework. There should be minimal barriers between +having an idea, and turning it into a blog post. + +I think the simplest and most elegant way to build a personal website, and the +approach I've taken here, is to use a Markdown-based static site generator. +Markdown is _nice_ (although I do have some complaints), and because the +building blocks are so simple, the output should be cleanly viewable even on an +old copy of Internet Explorer. + +Now, I must admit, I _did_ take the unnecessarily complicated route of building +my **own** static site generator. It's probably unnecessary, considering how +many great tools already exist, but what can I say? I like building stuff. + +Now, I have a system where I can update this site with very little effort. All I +need to do is add a new file, write some content in Markdown, and commit it to +the repo. diff --git a/content/blog/email-in-helix.md b/content/blog/email-in-helix.md new file mode 100644 index 0000000..851d39c --- /dev/null +++ b/content/blog/email-in-helix.md @@ -0,0 +1,256 @@ +--- +title: Writing Emails In Helix +date: 2025-05-29 +--- + +This article is all about writing emails in Helix. Obviously, Helix isn't an +email client -- and it's lacking in a plugin system, so you can't really turn it +into one, either. And that's okay! You might be wondering, then, what exactly do +I mean by "writing emails in Helix"? + +An email client needs to do a whole lot more than write text! It needs to +connect to your mail servers, show your messages, display and allow you to +interact with flags/labels, be able to **send** your email, etc. Only an insane +person would try to hamfist this functionality into a text editor (I'm looking +at you, Neovim plugin developers!). + +Helix is **really** good at its _one_ job, and that's **editing text**. It is a +text editor, after all. As it turns out, _writing_ emails is, well, text +editing, which is Helix's forte. So why not take Helix's amazing writing +experience, and apply it to email? If you're willing to take the plunge, you may +be pleasantly surprised at how **joyful** writing email can actually be! + +There are a few different ways to approach composing emails in Helix. This post +covers what worked best for me. That is, using Helix as a composer for the +`aerc` email client. It wasn't straightforward to figure out at first, but +all-in-all, the configuration isn't actually that complicated, so you should be +able to set it up in no time. + + + +- [Aerc Integration](#aerc-integration) +- [Naive Approach](#naive-approach) +- [Helix Workspace](#helix-workspace) +- [Markdown Highlighting](#markdown-highlighting) +- [Spellcheck](#spellcheck) +- [Formatting](#formatting) +- [Conclusion](#conclusion) + + + +## Aerc Integration + +At the end of the day, an email is just a text file. An `.eml` file, to be +exact. So, you _could_ just open up a fresh buffer, manually type in your +headers, and go to town. When you're done, you can figure out _some_ way to +actually send that file (perhaps dragging and dropping it into your mail +client). + +However, that's not really ideal. For starters, emails have a **lot** of +headers, and if you mess any of them up, your message might not get delivered. +You probably want to be able to, at the very least, **reply** to an email and +have its headers be auto-filled. + +Therefore, some level of integration with an actual email client is desirable. +Let the client handle every _other_ aspect of reading and sending email, and +relegate **writing** to Helix. This is the approach I'll be covering. + +## Naive Approach + +The simplest approach should work with zero configuration. `aerc` uses your +`$EDITOR` to compose your emails by default; so you can get started using Helix +right away! However, this is missing two important features: **spellchecking** +and **formatting**. To that end, we have to figure out how to get Helix to load +a custom configuration for emails. + +## Helix Workspace + +As you may know, Helix gives you an option to specify _per-project_ +configuration. This requires creating a `.helix` directory in the root of your +project, and filling it with `config.toml` and `languages.toml` files that +override your default config. _However_, there isn't currently a way to specify +_filetype-specific_ options; this is where we have to get creative. + +I recommend creating a folder inside your `aerc` config called `helix-config`. +Its name doesn't actually matter, so you can call it whatever you want! This +directory will serve as our _workspace_. The basic idea is to have `aerc` open +email files with this directory set as the current working directory — which is +what induces Helix to load the workspace config. + +Inside our new workspace, let's create the `.helix` directory and populate +`config.toml` with our preferences: + +```toml +[editor] +text-width = 74 +[editor.soft-wrap] +enable = true +wrap-at-text-width = true +``` + +The final step is the simplest. First, create a shell script inside +`helix-config`: + +```bash +#!/bin/sh + +cd ~/.config/aerc/helix-config && hx "$@" +``` + +This will serve as our "email entry point". It simply sets the CWD to our new +workspace, then loads Helix normally. Then, you'll need to set the `editor` +option in `aerc.conf`: + +```ini +[compose] +editor=/home/yourUserName/.config/aerc/helix-config/hx.sh +``` + +Unfortunately, you have to provide an absolute path, otherwise `aerc` won't find +the script. + +## Markdown Highlighting + +When writing plain-text emails, I like to use Markdown markup. Consider the +following message: + +``` +Dear John, + +Thanks for sharing! I _seriously_ appreciate your help. + +To proceed, we'll need to do: + +- Thing A +- Thing B +``` + +Even though the recipient will receive this email in un-rendered plain text +format, the _semantics_ are still very clear. Of course, we don't _need_ +highlighting in our editor to write markdown, but it can help make the +experience a bit better. + +All you need to do is create a `.helix/languages.toml` file inside our email +workspace from before: + +```toml +[[language]] +name = "markdown" +file-types = [{ glob = "/tmp/aerc-compose-*.eml" }] +``` + +Take note of the `file-types` entry. Email compose files opened by `aerc` will +always match the `/tmp/aerc-compose-*.eml` pattern. The above snippet ensures +that emails will be treated as Markdown files by Helix. The reason I recommend +putting this in your _workspace_ config and not setting it globally is to avoid +complications if you ever find yourself needing to edit a regular `.eml` file +_outside_ of `aerc`. + +## Spellcheck + +The excellent [harper](https://github.com/Automattic/harper) LSP supports +Markdown out-of-the-box. You can follow the instructions in its documentation to +install and configure it for Helix. Then, you can add it to your workspace +`languages.toml`: + +```toml +language-servers = ["harper-ls"] +``` + +## Formatting + +Many plain-text email clients _don't_ automatically wrap lines for readers. A +soft-wrapped email may look completely fine on your end, but be totally +unreadable for your recipient. Therefore, we need a way to _hard-wrap_ our +emails before sending them. This ended up being a much bigger challenge than I +thought it would. + +My first approach was to use the nifty `wrap` filter that `aerc` ships with by +adding it to `languages.toml`: + +```toml +formatter = { command = "/usr/lib/aerc/filters/wrap", args = ["-w", "74"] } +``` + +This worked _okay_, but it totally broke the markup at times. Crucially, it +doesn't respect code blocks or verbatim sections denoted by backticks. If you're +participating in technical mailing lists, you definitely want these to be +preserved. + +Using a regular Markdown formatter introduced another problem: Markup was +preserved, but not in an email-friendly way. Consider this example: + +``` +How's it going? + +Best, +Daniel +``` + +A standard Markdown formatter ignores single line breaks and produces this +output: + +``` +How's it going? + +Best, Daniel +``` + +It similarly mangles signature blocks: + +``` +-- +Daniel +Programmer +email@address.com +``` + +Becomes: + +``` +-- Daniel Programmer email@address.com +``` + +Eventually, I realized that I'd have to write my **own** formatter. I wrote a +Python script that hard-wraps the input, automatically reflows paragraphs, and +squashes consecutive paragraph breaks — while preserving the following: + +- Any long sequence not broken by spaces. +- Quoted lines (`>` prefixed email quotes). +- Indented lines. +- Markdown lists. +- Markdown code blocks. +- Signature blocks at end of file. +- Sign-offs. + +Sign-offs are preserved by following a simple heuristic. A two-line sequence is +considered to be a signoff if: + +- It starts with 1-5 words ending with a comma, followed by +- 1-5 words that each start with capital letters. + +This covers signoffs like these: + +``` +Best, +Daniel + +Yours truly, +John Alfred Smith +``` + +I provide a number of flags and options, so you can configure the formatter to +your liking. If you want to use it, `format.py` is available in my +[mail-utils](https://git.sr.ht/~ficd/mail-utils) repository on sourcehut. To add +it to your mail workspace just requires changing one line in `languages.toml`: + +```toml +formatter = { command = "/path/to/format.py" } +auto-format = true +``` + +## Conclusion + +Hopefully, this guide was helpful in getting you set up with composing your +emails in Helix. A similar guide for Kakoune is in the works, so check back +soon! diff --git a/content/blog/email-in-kakoune.md b/content/blog/email-in-kakoune.md new file mode 100644 index 0000000..8dfdef5 --- /dev/null +++ b/content/blog/email-in-kakoune.md @@ -0,0 +1,171 @@ +--- +title: Writing Emails In Kakoune +date: 2025-06-01 +--- + +This post will guide you through my setup for using Kakoune as an email composer +inside `aerc`. I'll also explain how to configure Kakoune to act as the _pager_ +for reading `text/plain` emails. If you only care about the final config, feel +free to skip to it [here](#final-configuration). + + + +- [Naive Approach](#naive-approach) +- [Composer Setup](#composer-setup) +- [Reader Setup](#reader-setup) +- [Final Configuration](#final-configuration) + + + +## Naive Approach + +Since `aerc` uses your `$EDITOR` for composition, you don't technically have to +do anything. I prefer setting it explicitly in `aerc.conf`, for good measure: + +```ini +[compose] +editor=kak +``` + +The rest of the magic happens in your `kakrc`. + +## Composer Setup + +Essentially, we want to hook `filetype=mail` and set our buffer configuration +there. I'll share a recommended configuration with some explanation. + +```kak +hook global WinSetOption filetype=mail %~ + set-option window formatcmd '/home/fic/dev/utils/mail-utils/format.py' + set-option window comment_line '>' + try autospell-enable + hook -group mail-auto-format window BufWritePre .* format + hook -once -always window WinSetOption filetype=.* %{ + unset-option window formatcmd + remove-hooks window mail-auto-format + } +~ +``` + +I use a custom formatter to format emails. It automatically hard-wraps lines +while preserving certain markup elements, code blocks, sign-offs, and signature +blocks. For more details, check the formatting section of my post on +[Helix](/blog/email/helix#formatting). + +I find that setting `>` as the `comment_line` token is convenient for working +with quotes in replies. + +The `try autospell-enable` enables my +[kak-autospell](https://git.sr.ht/~ficd/kak-autospell) plugin for the buffer. +Essentially, it provides spellchecking that's continuously refreshed and hidden +in insert mode. + +The remaining commands configure auto-formatting on save. I always prefer having +this on so I never forget to format my message before sending it. + +## Reader Setup + +I find that using Kakoune to **read** emails is helpful because of how easy it +is to copy quotes, open links, etc. Configuring this is a tad hackier, however. +The basic idea is to set Kakoune as the viewer `pager` in `aerc.conf`. + +However, all this does is pipe the email to `kak` through standard input, so we +need to tell the editor to treat it like an email: + +```ini +[viewer] +pager=kak -e 'set buffer filetype mail' +``` + +When you're using Kakoune as a pager, you'll probably want to configure some +things differently. In my case, I like to set the buffer as `readonly`, remove +the `number-lines` and `show-whitespaces` highlighters, disable soft-wrap & my +scrolloff settings, and _not_ set any formatters. + +The `pager` command above sets the filetype, but we need to distinguish between +_composing_ and _reading_ in our Kakoune hook. When Kakoune is opened with input +through standard input, it loads a buffer that's conveniently named `*stdin*`. +Thus, we can check the buffer name before continuing. + +If we're in "reading mode", we define a hidden command called `ismailreader` +which doesn't do anything. Why? If the command is defined, and we try to invoke +it... well, nothing happens! But if it's **not** defined, we get an error +instead. We can combine this with the `try` command to for some simple boolean +logic. + +```kak +evaluate-commands %sh{ + # stdin, we assume it's a pager + if [ "$kak_bufname" = "*stdin*" ]; then + echo 'define-command -hidden ismailreader nop' + fi +} +try %{ + ismailreader + # do reader config here +} catch %{ + # do composer config here +} +``` + +I set the following configuration for "reader mode": + +```kak +set buffer readonly true +try %{ + remove-highlighter window/number-lines + remove-highlighter window/show-whitespaces + # custom commands defined elsewhere in my kakrc + ui-wrap-disable + ui-scrolloff-disable +} +``` + +## Final Configuration + +To recap, you'll want to set this in `aerc.conf`: + +```ini +[viewer] +pager=kak -e 'set buffer filetype mail' + +# ... + +[compose] +editor=kak +``` + +And the following in your `kakrc`: + +```kak +hook global WinSetOption filetype=mail %~ + evaluate-commands %sh{ + # stdin, we assume it's a pager + if [ "$kak_bufname" = "*stdin*" ]; then + echo 'define-command -hidden ismailreader nop' + fi + } + try %{ + # READER MODE setup + ismailreader + set buffer readonly true + try %{ + # remove these highlighters so everything displays properly + remove-highlighter window/number-lines + remove-highlighter window/show-whitespaces + ui-wrap-disable + ui-scrolloff-disable + } + } catch %{ + # WRITER MODE setup + set-option window formatcmd '/home/fic/dev/utils/mail-utils/format.py' + set-option window comment_line '>' + try autospell-enable + hook -group mail-auto-format window BufWritePre .* format + hook -once -always window WinSetOption filetype=.* %{ + unset-option window formatcmd + remove-hooks window mail-auto-format + } + } +~ +``` diff --git a/content/blog/index.md b/content/blog/index.md new file mode 100644 index 0000000..cc9e9d6 --- /dev/null +++ b/content/blog/index.md @@ -0,0 +1,10 @@ +--- +title: Blog Posts +template: post_list +post: false +--- + +Here, you can find my musings on various technology topics. I take a _digital +garden_-like approach, meaning these articles are likely incomplete and may be +changed at any point. + diff --git a/content/blog/mirror-srht-to-github.md b/content/blog/mirror-srht-to-github.md new file mode 100644 index 0000000..439b42b --- /dev/null +++ b/content/blog/mirror-srht-to-github.md @@ -0,0 +1,112 @@ +--- +title: Automatically Mirror Sr.ht To GitHub +date: 2025-05-15 +--- + +For a variety of reasons, I've recently migrated to [sr.ht](https://sr.ht/~ficd) +for Git and project hosting. I prefer the minimal, no-frills interface, and I +really like that you can have multiple repositories, mailing lists, and issue +trackers grouped under the same project. The email-centric workflow is also +appealing to me. + +However, the fact remains that a strong presence on GitHub is very important. If +you're a student hoping to land a programming job, you need to keep those commit +stats up. Many tools, such as [Yazi](https://yazi-rs.github.io/)'s package +manager, only support GitHub repositories. However, I don't _like_ GitHub, +that's the whole reason I switched! + +I finally decided to give automatically mirroring my repositories a shot. While +it was a bit of work to set up, it's worth it in the end. In this post, I'll +guide you through the process. + +## SSH and Sourcehut Secrets + +The first step is to give `builds.sr.ht` push access to your GitHub repositories +via `ssh`. Begin by generating an `ssh` key pair: + +```bash +ssh-keygen -t ed25519 -f ~/.ssh/gh_mirror_id -N "" +``` + +You'll want to add the _public_ key to your GitHub account. Navigate to +**Settings** → **SSH and GPG keys**, click the big green button, and paste the +contents of `gh_mirror_id.pub`. Make sure its key type is "Authentication Key", +and give it a helpful name like `sr.ht builds`. + +Next, you need to upload the _private_ key to Sourcehut. Visit +[builds.sr.ht/secrets](https://builds.sr.ht/secrets), name it something +memorable, and paste `gh_mirror_id` into the big box labeled "Secret". Take care +to tick the **Secret Type** → **SSH Key** menu option before hitting the blue +"Add" button. + +Keep this page open, because you'll need the secret's UUID later. + +## Build Manifest + +The basic idea is as follows: whenever you push to your chosen `sr.ht` +repositories, it should automatically be pushed to GitHub with the `--mirror` +flag. Sourcehut has an automated build system that's up for the task. _(Note: +you need a paid account to use it.)_ + +For any repository you want to mirror, you'll need to add a file called +`.build.yml` to the root. This file will look familiar if you've worked with +GitHub actions before. Then, you set up the environment, import the `ssh` key +from earlier, and add a task for pushing the repository as if you were doing it +from the command line. Finally, make sure you've created an empty GitHub +repository ahead of time — otherwise, the build will fail! + +```yaml +image: alpine/latest +packages: + - git + - openssh +secrets: + - SECRET_UUID_HERE +environment: + # in case the repos have different names + srht_repo: repo-name-on-srht + github_repo: repo-name-on-gh + github: git@github.com:yourusername +tasks: + # ssh-keyscan is required, command fails otherwise! + - mirror: | + ssh-keyscan github.com >> ~/.ssh/known_hosts + cd "$srht_repo" + git remote add github "$github/$github_repo.git" + git push --mirror github +``` + +And that's it! Anytime you push to a branch that has this build manifest in it, +your GitHub mirror is updated. + +## Readme Wrangling + +Since all you're doing is _mirroring_, you can't have a different readme on +GitHub. There's a few things I recommend doing so folks viewing your repository +on GitHub don't get confused. You can mention the mirror in the "About" section, +and include a link to your `sr.ht` repo: + +![](/static/images/gh_about.png) + +I also recommend prominently displaying links to your bug tracker and mailing +list, if applicable to your project. Finally, make sure there's an early link to +the `sr.ht` project page. You could also explicitly mention that the project +lives on sourcehut and is mirrored on GitHub, but this may be overkill. Consider +this example from my Ashen project README: + +`ex_start` + +This monorepository contains official implementations of Ashen across a range of +editors, terminals, tools, and more — each carefully tuned to carry the same +muted warmth. The project lives on [sourcehut](https://sr.ht/~ficd/ashen/) and +is mirrored on [GitHub](https://github.com/ficcdaf/ashen). To report issues or +make requests, visit the [ticket tracker](https://todo.sr.ht/~ficd/ashen) or +contact the [mailing list](https://lists.sr.ht/~ficd/ashen) (_possibly by +carrier pigeon_.) + +`ex_end` + +## Happy Hacking! + +Now, you should be able to comfortably use `sr.ht` to host your projects without +sacrificing the ubiquity of GitHub. Happy hacking! diff --git a/content/blog/on-websites.md b/content/blog/on-websites.md new file mode 100644 index 0000000..6d6233d --- /dev/null +++ b/content/blog/on-websites.md @@ -0,0 +1,74 @@ +--- +title: On Websites (Or The Case For The Personal Web) +date: 2025-05-05 +--- + +## Preamble + +The internet is a [lovecraftian entity](/blog/the-lovecraftian-internet) in its +size and complexity. Much of its gargantuan scope is invisible to us, the _deep +web_, but even the surface web is mostly beyond our comprehension as +individuals. The electric highways are, in no small part, dominated by social +media platforms. The internet is the perfect technology for sharing ourselves +with others, and social media makes this easy. However, it's come at a great +cost -- to our privacy, our money, our freedom, our individuality. + +I'm not here to litigate the complicated issue that is social media's effect on +society. I'm not here to tell you _why_ there's a problem with our digital +platforms. What I will say is that it seems fairly uncontroversial to point out +that social media is an _addiction_ for many of us. I'm sure that you, dear +reader, have also considered "taking a break" or even quitting. Even if we don't +know exactly why, we do seem to agree, as a society, that something is wrong. + +Past this introduction, I'm not here to criticize social media. I'm also not +here to refer you to other platforms like Mastodon and Matrix. I'm here to tell +you that **the internet doesn't have to be this way**. + +## Websites + +Today, we think of websites as _platforms_: storefronts, news, town squares, +encyclopedias. Something maintained by companies and organizations providing a +service. The space for _us_ to share _ourselves_, it seems, is on someone else's +website. What format you can post in, how your profile looks; you're at the +mercy of the service provider. So, why don't we just make our own websites? + +A website is actually remarkably simple. Sure, **web development** isn't; it's +been increasing in complexity and bloat by the year. But a _website_ is _just_ a +document that's hosted at some address. Visitors _download_ the document, and +their browser _renders_ it. That's how you're reading this page, even. + +Websites don't **need** functionality. They don't need fancy graphics and +buttons. They literally **only** need text. Everything else is fluff -- great +fluff, my own site has images and a theme -- but fluff nonetheless. As soon as +you realize this, you'll learn that you don't need to be a developer or tech +wizard to publish a website. And I argue that, as creative individuals, to make +full use of what the web is **really** great at, it's definitely worth +publishing a website. + +## Why Should You Make A Website? + +I think there's something to be said for having a corner of the internet that's +_truly_ your own. When you post on social media, that profile isn't **really** +yours. If it were, how come you can't, say, change the background color? Play +music for your visitors? How come you're limited by _how_ you can post? On +Instagram, you can only post visual media, not really the best way to share your +complex thoughts on something. + +Your website is **yours**. You can post what, when, and how _you_ want to. The +_data_ is yours too. There are so many ways to express your creativity and +personality through this medium. Take a stroll through +[Neocities'](https://neocities.org) public offerings sometime to see what I +mean. + +When you publish to your website, you're not thinking about likes, shares and +friends. You just write, and upload. Whoever reads it, reads it. Unless you've +set up some analytics (which I don't even recommend), you _don't_ know how many +people have read your posts. And I think it's better this way. + +Stepping away from social media to cultivate my own digital garden has allowed +me to perform a more authentic version of myself on the internet. It's great +having one, central place to share myself with the wold. Blog posts, art, +technical projects, my resume, all I need to do now is direct people here. + +So, do yourself a favor and try building a personal website. I think it's one of +the most rewarding ways to participate in the internet. diff --git a/content/blog/rediscovering-email.md b/content/blog/rediscovering-email.md new file mode 100644 index 0000000..fc830ad --- /dev/null +++ b/content/blog/rediscovering-email.md @@ -0,0 +1,235 @@ +--- +title: Rediscovering Email +date: 2025-03-24 +--- + +## Preamble + +"Kids these days" don't really use email anymore. _It's me by the way, I'm +kids._ Sure, we email our professors, we email our resumes to potential +employers, we email when the business is a tad too official for text or +WhatsApp. + +Email isn't just for communication. Think about it: when all you want to do is +talk to someone, are you sending them an email? When's the last time you emailed +a friend or loved one "What's up? How's it going?" + +Email has been relegated, essentially, to administrative tasks. Emails are +something you _have_ to send. They carry an air of officiality. Definitely not +the way to contact your friends. + +Why is that? + +## Web Mail Sucks + +I think our _experience_ of writing email takes a large chunk of the blame. To +be honest, it's pretty dreadful most of the time, thanks in no small part due to +the _God-awful_ interfaces through which we interact with emails. + +Web mail interfaces _suck_. You log into Gmail just to see that every fifth +letter in your inbox is actually an ad. I'm not talking promotional mail, I'm +talking a literal ad, served to you by Google, masquerading as a real message. + +And tell me why Outlook needs to make hundreds of JavaScript requests, and cache +a hundred megabytes of data just to show my inbox? If I'm using my laptop on the +school network, chances are, I'll be sitting there for at least ten seconds +before I can even see whether I've got any new messages. + +Oh, and I don't know about you, but since I spent most of the day using my +computer, I like to do whatever I can to prolong my ability to, like, use my +eyes. A big part of that means using dark mode wherever possible, as God +intended. Which brings me to my next point: dark mode in most web mail clients +isn't great. + +For instance, Proton Mail provides a lovely dark interface for your inbox, just +to burn your retinas off the moment you start composing a message or reading a +new email. This is one area I must be fair to Outlook, however, which provides +one of the nicest dark interfaces I've used. + +![](/static/images/email_1.png) + +For quite a few reasons, including those stated above, and of course wanting to +use my own text editor to write my letters, I finally decided it was time to +figure out a better way to interact with email. And as it turns out, there +really is one! + +## Email In The Terminal? + +If you know me at all, you know I'm a **fiend** for the terminal. If a given +task is even _possible_ to do in a command-line (or TUI) interface, then that's +the way I'll be doing it from now on until my hands my fall off my wrists. Call +it a neurodivergent stubbornness, but it's just the only way I really like to +interact with my computer. + +It also happens that Helix, my text editor of choice, also runs in the terminal. +Anytime I'd have to draft an email longer than a few sentences, I'd start to +feel the withdrawal. Maybe Helix has really spoiled me, but the experience of +manipulating text in this beautiful program is too good to **not** incorporate +into every aspect of my life that involves writing. I'm already writing my +papers and slideshows in Helix (_more on that in a future post_), so why not +email? + +First, I figured out using Thunderbird. Although it has many problems (like, +tell me how there _still_ isn't tray support for Linux?!) using Thunderbird was +otherwise a "solid" experience. Sure, Thunderbird is a GUI app, _but_ I wasted +no time in finding a pipeline for writing emails in my beloved Helix. + +The extension "External Editor Revived" does exactly what it sounds like. Using +it, I was able to open up email files for editing in Helix, then pipe them back +to Thunderbird for review and sending. I was happy with this setup for a while +despite its problems. + +But as it turns out, an even nerdier way was just around the corner... + +## Enter Aerc + +I forget where I first heard about `aerc`, but I'm really glad that I did! It's +a lovely little TUI email client maintained by the good people at Source Hut. It +features a vim-like ex-command setup and controls. The controls are also 100% +remappable, which makes my Colemak brain happy. + +My favorite part, though, is the composing interface. It's really clever: the +top of the screen holds the standard headers you expect to see like From, To, +and the Subject, but the part where you write the body of your letter is +actually a tmux-style embedded terminal running your favorite `$EDITOR`! + +![](/static/images/email_2.png) + +Of course, there were quite a few hiccups in getting Helix to play along; +namely, spellchecking, Markdown syntax highlighting and automatic text-wrap was +a challenge. If you're interested in the details, I'll later be publishing a +tutorial outlining step-by-step how to replicate my Helix-mail setup. + +### Authentication Problems + +If you're going to use an email client, you need to authenticate with your email +provider. For Proton Mail, this was easy enough; the Bridge app interfaces with +your encrypted inbox, and exposes IMAP and SMTP services locally. Outlook, on +the other hand (especially a school/corporate policy) is a **hassle**. + +Without getting too deep into it, it was more than one day of headache before I +managed to get it working. The solution involved finding (and modifying) a +Python script to authenticate and save my initial refresh token, as well as +manage requesting new access tokens when they expire. I also had to gaslight +Microsoft into thinking I was actually using Thunderbird (by pulling the +`client_id` straight from the Mozilla source code). + +## Organizing Email + +My inbox has _always_ been disorganized. Frankly, I don't know a single person +whose inbox isn't. And it's understandable! The tools at our disposal aren't +particularly helpful, and most importantly, **they're not standardized.** For +example, we could create various folders, moving the appropriate emails as we +read them. Some _(emph: some)_ providers let you automate this, but I've found +the filter rules to be a bit lacking. Organizing by folders also inherently +limits your ability to later filter and narrow down your searches. + +Tags are clearly the best way, but again, the implementation depends +per-provider. Worst of all, as with most things these days, non-standard +implementations mean that as soon as you've put all your eggs in the basket, +you're essentially locked in; unless you want to go to the _colossal_ hassle of +re-organizing your inbox playing by _another_ provider's rules. + +## Storing Email Locally + +As it turns out, `aerc` (and other mail clients like it), besides the standard +ability to read mail from an IMAP server, has another trick up its sleeve. That +trick is reading mail from a _local database_. Now, this might not seem like a +big deal. Thunderbird does this too: when you access your inbox via IMAP, +Thunderbird downloads and caches all of your emails. + +What I never knew, and it took messing around with `aerc` to learn about, is +that there exist multiple _standardized_ ways to store emails locally. What this +means is that as long as you synchronize your emails to this local store, you +can access them from **any** client! + +I chose to go with a tool called `mbsync`, which stores mail in the standard +"maildir" format, and keeps it in sync with an IMAP server. The syncing only +happens when you trigger it manually -- although you can easily configure +another program to "listen" for new emails and sync automatically. I decided to +forego this, more on why later. + +## Complex Tagging + +The best part is that once you've got this email database, you can pick from a +host of tools and systems for indexing and organizing it. I went with a tool +called `notmuch`, a program that's very popular among programmers much older and +more bearded than I am. `notmuch` _indexes_ your maildir and basically acts as a +query engine. I found the experience of using it similar to, say, SQL. The basic +premise is that you write queries about your emails. + +```sh +# Here's me searching for emails about GitHub authorization +notmuch search 'from:/@.*github.*/ subject:/auth\w*/' +``` + +You can also apply an arbitrary string to an email as a **tag**. Tags are more +powerful than **flags**, which are IMAP compliant, but limited to only a few +specific roles. `notmuch` allows you to create and use as many different tags as +you want! + +```sh +# Here's me applying the "personal" tag to +notmuch tag +personal -- 'path:personal/**' +``` + +But the real juice is configuring rules that will automatically tag your new +emails. Then, not only can you filter/query your mail by tag, but when you open +your mailbox in `aerc`, you can configure queries as "folders" for easy, +repeated viewing. Nice! + +## The Synchronization Problem + +I spent a lot of time on tagging. Figuring out the rules and automatic filters, +fine-tuning my queries, etc. When I finally had it all figured out, I +encountered the next problem, which (I guess) I could've foreseen: **the +`notmuch` database is local**! And as it turns out, synchronizing its database +between devices (home PC and laptop in my case) is **not** a trivial task. + +I first tried a tool called [muchsync](https://www.muchsync.org/). It's a clever +piece of software, with one big problem: it's designed around one database that +acts as a central server, which _other_ databases replicate. This turned out to +not be particularly reliable for my case, because thanks to the aforementioned +[authentication hacks](#authentication-problems), I can only **reliably** +synchronize my mail if I'm actually at the computer to re-authenticate when +necessary. Trying to wrangle the authentication and GPG-encrypted tokens via +`ssh` was starting to feel like more trouble than it was worth. + +My next idea was to use SyncThing to just keep the entire local database +synchronized, peer-to-peer style. I figured that as long as I only ran `mbsync` +manually (for the external IMAP sync) and only accessed/edited my mail from one +device at a time, I wouldn't have any conflicts. + +That was, apparently, an incorrect assumption. I was basically faced with a +conflict every single time I updated some tags or deleted a few emails. Because +of how `mbsync` is written, it was basically impossible to recover from these +broken database states. After multiple instances of needing to re-download my +entire inbox, I decided it was time to cut my losses, and `notmuch` +`pacman -Rns`'d out of my life almost as quickly as it `-Syu`'d into it. + +## JMAP Is Amazing + +For reasons I'll get into in another post, at this point, I was also completely +fed up with Proton Mail, and on the hunt for a new provider. I'd heard good +things about Fastmail, and after seeing that they implemented a new protocol +called JMAP, I decided to try it out. + +> Note: I was actually so pleased with Fastmail that my free trial went paid +> subscriber in less than a day. Take that, Proton! + +JMAP has **labels**, which are similar enough to `notmuch` tags. But because +they're supported by the protocol itself, they're hosted by the mail server +itself, meaning you can completely sidestep the synchronization hassle. Not only +that, but they're also a first-class citizen in Fastmail's web interface (which +is one of the best I've ever used). + +A **label** is basically analogous to a folder. If an email has a certain label, +it's basically in that folder. If it has multiple, it's like multiple folders +symlink to the same message. What's cool about this system is that you can move +and "copy" your mail around without actually creating redundant copies of +emails. + +With this approach, you don't even need to maintain an archive folder. Any mail +that doesn't have the Inbox label is considered archived. This means you can +archive messages while still retaining their other labels. Very useful for +things like digital receipts and automated messages from `noreply` addresses. diff --git a/content/blog/the-lovecraftian-internet.md b/content/blog/the-lovecraftian-internet.md new file mode 100644 index 0000000..9836f32 --- /dev/null +++ b/content/blog/the-lovecraftian-internet.md @@ -0,0 +1,64 @@ +--- +title: The Lovecraftian Internet +date: 2025-04-05 +--- + +# The Lovecraftian Internet + +The web we know is spun by gluttonous spiders no longer satiated by flies and +roaches. They cast their net wide across the world, like cuckoos they lay their +parasitic eggs inside our lives. They fondle our brains until our DNA is +infested with algorithms, our ribcages become mainframes and our eyes turn into +screens. + +
+A dithered monochrome image of HR Giger's Li II (1976) + +Li +II, H.R. Giger, 1976. + +
+ +No more. + +The spores are already sprouting, recycling the decaying corporate internet into +binary compost. + +The internet is incomprehensively massive. Conservative estimates claim at least +**4.2 billion** indexed webpages.1 _Indexed_, in this context, means +publicly accessible individual webpages that can be found on a search engine +because [web crawlers](https://en.wikipedia.org/wiki/Web_crawler) can reach +them. This is known as the **surface web**. + +The figure doesn't account for the rest of the internet: private resources +hidden behind firewalls, internal webpages and services, e-mail traffic, IoT +devices, direct messages, video game servers, media & file storage, just to name +a few. These are all part of the **deep web**: the portion of the internet that +cannot be indexed by search engines. + +
+A dithered grayscale image of a datacenter + +Leonardo Rizzi, 2010. + +
+ +No one knows the true size of the deep web. It's impossible to even guess. +According to the BBC,2 the "big four" store _at least_ **1.2 million +terabytes** of data. So even before we consider the fairly recent eruption of AI +and the sprawling datasets and models that came with it, that's already +9.6 x 1018 bits of data. That's more ones and zeros +than grains of sand on Earth.3 + +The internet is a +[Lovecraftian](https://www.hplovecraft.com/creation/bestiary.aspx) entity in +scale, tangibility, and perceptibility. Clearly, this web was not spun by an +itsy-bitsy spider. + +--- + +# References + +1. [WorldWideWebSize](https://www.worldwidewebsize.com/) +2. [ScienceFocus Magazine](https://www.sciencefocus.com/future-technology/how-much-data-is-on-the-internet) +3. [NPR](https://www.npr.org/sections/krulwich/2012/09/17/161096233/which-is-greater-the-number-of-sand-grains-on-earth-or-stars-in-the-sky) diff --git a/content/code.md b/content/code.md new file mode 100644 index 0000000..e58e737 --- /dev/null +++ b/content/code.md @@ -0,0 +1,10 @@ +- [sr.ht](https://sr.ht/~ficd) + - My main development platform. Most of my own projects can be found here. +- [GitHub](https://github.com/ficcdaf) + - I mirror some of my projects here, or host clones of GitHub projects I + contribute to. +- [ficd.ca source code](https://git.sr.ht/~ficd/blog) + - Source code of this website. Not very interesting; it's mostly Markdown. +- [site builder source code](https://git.sr.ht/~ficd/zona/tree/dev-stable) + - Source code of `zona`, the tool I developed to build and maintain this + website. diff --git a/content/contact.md b/content/contact.md new file mode 100644 index 0000000..e1418a4 --- /dev/null +++ b/content/contact.md @@ -0,0 +1,8 @@ +## Contact + +- Email + - [daniel@ficd.ca](mailto:daniel@ficd.ca) +- Public Key (for encryption, signing) + - [public key](/public-key.asc) +- IRC + - `ficd` on [Libera](irc://irc.libera.chat) diff --git a/content/header.md b/content/header.md new file mode 100644 index 0000000..6e31836 --- /dev/null +++ b/content/header.md @@ -0,0 +1,5 @@ +- [Home](/) +- [About](/about) +- [Now](/now) +- [Blog](/blog) +- [Code](/code) diff --git a/content/index.md b/content/index.md new file mode 100644 index 0000000..47c6c84 --- /dev/null +++ b/content/index.md @@ -0,0 +1,30 @@ +--- +title: Home +--- + +
+ +

Daniel Fichtinger

+ +
+ +![A [dithered](https://en.wikipedia.org/wiki/Dither#Digital_photography_and_image_processing), monochrome photo of me, 2024.](static/images/dithered_ficd.jpg) + + +Welcome to my website. I like programming, Linux, and cybersecurity. I can +usually be found coding, learning, or petting my cat. + +- [About Me](/about) +- [Now](/now) +- [Blog](/blog) +- [Projects](/projects) +- [Research](/research) +- [Poetry](/poetry) +- [Contact](/contact) + +I'm passionate about less-is-more approaches to software. This website is +static, hosts zero JavaScript, and serves no more than 1 megabyte per page. I'm +also the author of [Ashen](https://sr.ht/~ficd/ashen), a warm, dark, muted color +scheme. It's available for editors, terminals, tools, interfaces, and more: + +![A preview of Ashen for Helix.](static/images/ashen_preview.png) diff --git a/content/now.md b/content/now.md new file mode 100644 index 0000000..d0ab20c --- /dev/null +++ b/content/now.md @@ -0,0 +1,21 @@ +--- +title: Now +--- + +This is my [now](https://nownownow.com/about) page. + +**Updated June 25, 2025**. + +**What I'm up to:** + +- Playing Stellar Blade and watching Jujutsu Kaisen. +- Writing and beginning implementation work on my dissertation. +- Obsessively customizing Kakoune and writing too many plugins for my sanity to + keep up with. +- Rewriting [zona](https://sr.ht/~ficd/zona) in + [Python](https://git.sr.ht/~ficd/zona-py). + - Reached and passed feature-parity with the development branch of the Go + version. + - I just implemented [Ashen](https://sr.ht/~ficd/ashen) syntax highlighting + for code blocks, and I'm almost ready to migrate this website to the new + build system! diff --git a/content/poetry/angels-and-wires.md b/content/poetry/angels-and-wires.md new file mode 100644 index 0000000..19076db --- /dev/null +++ b/content/poetry/angels-and-wires.md @@ -0,0 +1,66 @@ +--- +title: angels and wires +--- + +
+A dithered monochrome image of a mushroom. +Mushrooms, 2024, Daniel. + +
+ +The rain comes\ +And goes\ +From the soils\ +laced with love,\ +A mushroom\ +Grows + +Decay makes more\ +and still death grows,\ +Of my heart\ +The mushroom knows.\ + +A god is here,\ +whispers the forest.\ +Deep among the roots\ +mycelium spirit.\ + +organic wires, genetic protocols\ +Does it have a soul? That thing, with its\ +irregular expressions and\ +writing in tongues\ +and it\ +has veins?\ + +it is inside the screen\ +we created angels and ripped their\ +wings from their backs their\ +halos from their heads their\ +them from their there\ + +metal to me\ +gold to veins and tin to skin\ +there runs a network\ +through forests and cities and\ +gardens and superstores and\ + +its presence weigh heavy\ +over the parking lot in the grass\ +inference of intent\ +To reach inside and solder pins to neurons and\ +copper to cells and fungus to arteries and\ +Take a byte of my heart.\ + +just a bit more, I say\ +Just one or none more day\ +but the thing wont wait\ +Be that as it may.\ + +from my head\ +The mushroom grows\ +The wire says,\ +Decompose.\ +From my head,\ +an interface grows.\ +My heart,\ +the mushroom chose.\ diff --git a/content/poetry/index.md b/content/poetry/index.md new file mode 100644 index 0000000..787ea5a --- /dev/null +++ b/content/poetry/index.md @@ -0,0 +1,5 @@ +--- +title: Poems +--- + +- [angels and wires](/poetry/angels-and-wires) diff --git a/content/projects.md b/content/projects.md new file mode 100644 index 0000000..4e5c7b2 --- /dev/null +++ b/content/projects.md @@ -0,0 +1,179 @@ +--- +title: Projects +--- + +

Projects

+ + + +- [Static Site Builder](#static-site-builder) +- [Libraries](#libraries) + - [Typst](#typst) +- [Utilities](#utilities) + - [System Maintenance](#system-maintenance) + - [Email](#email) + - [Desktop](#desktop) +- [Keyboard](#keyboard) +- [Ashen](#ashen) +- [Plugins](#plugins) + - [Kakoune](#kakoune) + - [Fish](#fish) + - [Helix](#helix) + - [Neovim](#neovim) + + + +I really enjoy programming, especially writing simple utilities to solve common +problems. Here, I list project I've written on my own time. For my academic +work, please see the [research](/research) section. + +## Static Site Builder + +[Zona](https://git.sr.ht/~ficd/zona) + +- Static site builder written in Python and optimized for lightweight blogs + following minimalist design principles. +- Support for templates, declarative metadata, and configuration files. +- Interprets inline image "alt text" as Markdown, rendered as an image tag. +- In active development, plans for many more features. +- Used to build this website. + +## Libraries + +### Typst + +- [typpres](https://git.sr.ht/~ficd/typpres) + - Provides functions to make creating slideshows with + [polylux](https://github.com/polylux-typ/polylux) more convenient. +- [reflib](https://git.sr.ht/~ficd/reflib) + - Provides functions to make typesetting label references more convenient. + +## Utilities + +### System Maintenance + +- [AutoYADM](https://git.sr.ht/~ficd/autoyadm) + - Shell utility to automate managing dot files with [yadm](https://yadm.io/). + - Intelligently auto-tracks newly created children of tracked subdirectories. + - Consists of two Bash scripts; very lightweight. + - Fish port in the works. + - I use this daily to keep my [dotfiles](https://git.sr.ht/~ficd/dotfiles) in + sync. + +### Email + +- [Email Parser](https://github.com/ficcdaf/tree-sitter-mail) + - Forked and maintains a Tree-sitter parser for `mail` files. + - Extended formal grammar definitions, supporting additional syntax elements & + fixing critical bugs. + - Wrote highlight and text object queries implementing `mail` support for + Helix; contributed the feature upstream. + - Currently researching how to leverage the parser to contribute `mail` + support to the Harper grammar checker. +- [Email Formatter](https://git.sr.ht/~ficd/mail-utils) + - Wrote a lightweight email formatter in Python, intended to format outgoing + plaintext emails. + - Wraps paragraphs at specified column width. + - Automatically reflows uneven paragraphs. + - Preserves long words, quoted lines, indented lines, lists, code blocks, and + signature blocks. + - Custom heuristic for preserving two-line signoffs. + +### Desktop + +[Repository](https://git.sr.ht/~ficd/wayland-utils) + +- Screen Recording Utility +- Niri Window Status + - Python server that integrates with Niri to provide a live indicator of + windows open on active workspaces. + - Designed for use with Waybar and similar software. +- Niri Window Picker + - Simple Python script that spawns a fuzzy picker allowing users to fuzzily + select an open window to switch focus to. + +## Keyboard + +- Self-built wireless [corne](https://github.com/foostan/crkbd) keyboard. +- [Colemak-DH](https://colemakmods.github.io/mod-dh/) (non-QWERTY, ergonomic + layout). +- [Custom columnar split layout](https://github.com/ficcdaf/zmk-config) + leveraging overloaded modifiers and layers to maximize efficiency. +- Custom [ANSI layout](https://github.com/ficcdaf/scripts/tree/main/keyd) + intended to make my ThinkPad internal keyboard as ergonomic as possible + without conflicting with external keyboards. + +## Ashen + +[Ashen](https://sr.ht/~ficd/ashen) + +- Original color scheme designed by me. +- Carefully tuned to fill a particular niche. +- Opinionated, clean, muted, and dark. +- Active user base, receives contributions. +- Ported to a wide variety of software, including (but not limited to): + - Helix (text editor). + - Terminal emulators (Most popular emulators covered) + - Firefox + - CLI tools (eza, bat) + - TUI tools (lazygit, yazi) + +![](https://git.sr.ht/~ficd/ashen/blob/HEAD/helix/preview_wide.png) + +## Plugins + +### Kakoune + +- [kak-wrap-nav](https://git.sr.ht/~ficd/kak-wrap-nav) + - Implementation of Vim's `gj/gk` (visual vertical navigation) for Kakoune. + - Contains 1:1 implementation of Kakoune's visual wrapping algorithm in Go + (needed to calculate offsets for visual navigation) + - **Work in progress.** +- [kak-autospell](https://git.sr.ht/~ficd/kak-autospell) + - Automatically refreshes and clears spellchecker highlighting. + - Provides convenience mappings for using built-in spellchecker. +- [kak-ashen](https://git.sr.ht/~ficd/kak-ashen) + - Official implementation of [Ashen](https://sr.ht/~ficd/ashen) for Kakoune. + - Features toggle-able mode-indicating dynamic cursor with optional EOL + variants. + - Additional tree-sitter support, including Helix capture groups. + - `kakoune-lsp` support. +- [kak-title-bar](https://git.sr.ht/~ficd/kak-title-bar) + - Asynchronously renders a bufferlist as the terminal's window title for tight + integration with the window manager. + - Indicates buffer modified states and active buffer. + +### Fish + +- [jrnl.fish](https://git.sr.ht/jrnl.fish) + - Small utility for managing daily journal entries. + - Template support. +- [smartcd.fish](https://git.sr.ht/smartcd.fish) + - Adds contextual smart behavior to the `cd` command. +- Fisher (contribution) + - Added support for sourcehut plugins and fixed a critical issue with unsafe + tilde path expansion. + - [PR](https://github.com/jorgebucaran/fisher/pull/802) + +### Helix + +> Mandatory caveat: Helix does _not_ have a plugin system! However, it _does_ +> allow your to invoke shell commands, making it possible to implement some very +> hacky functionality. + +- [hx-typ-zathura](https://git.sr.ht/~ficd/dotfiles/blob/main/.config/helix/scripts/hx-typ-zathura.fish) + - Easily open a PDF preview of your current Typst file in Zathura. +- [justfile formatter](https://git.sr.ht/~ficd/dotfiles/blob/main/.config/helix/scripts/format_just.fish) + - Workaround for formatting justfiles without any dependencies. + +### Neovim + +- [Academic.nvim](https://github.com/ficcdaf/academic.nvim) + - Neovim plugin. + - Automatically installs and configures an Academic English spelling + dictionary. + - Minimal performance overhead. + +- [Ashen.nvim](https://github.com/ficcdaf/ashen.nvim) + - Implementation of Ashen for Neovim. + - Supports numerous plugin integrations. diff --git a/content/public-key.asc b/content/public-key.asc new file mode 100644 index 0000000..66b8fec --- /dev/null +++ b/content/public-key.asc @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGNBGRyXGgBDADuIm0fB4l1zyqcPiWaRoVaz0JBPCTbFozYj8hqB8PCwYFmn5Zs +UkpoimEHkToC6nmmEHETDNyJ84b637Tkj1ujNPTZy2Gt+pC04A7N1+TNn7R6ZSRZ +KlDxTHF+LsA31BSdsI55BCMZhKVb/ZPmTdQlniNv6G0F+RQTxpjkcjxnfZYsBJVb +9QlDXov4u+LulYxGhLFgPuxrLbPkKgegjpyDtBgvoBQbZDo1Pywd47K+43hUtBlt +eAzUkldQhygCn2pyWuqiSyZcGYvj9XCl4qM1+kklp/kn/gf/M2lvW3HCGTTjry/q +y7lgDhev+orPHvA+EX4cKkLop5X3jX3PDPWQreJXPLO+jSrUTyhomfslpBsz8Kq+ +ufDA/RtPyfznH5sUt3fdY9hqVZdv3dtmFk9DO7NBP1T+jlPXC8kpK8/+zp6NPmVB +8nR7lFglGirVzlqzYXKFq7GrcQitCTBDg22Vo1UrIhFHFbRga6y34w94QxTyGAce +SbDq41lVs3mL35MAEQEAAbQiRGFuaWVsIEZpY2h0aW5nZXIgPGRhbmllbEBmaWNk +LmNhPokB1wQTAQgAQQIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgBYhBJZW +mchi2pIUPN4od9GwlHslQgIUBQJn1k8mBQkHJlm+AAoJENGwlHslQgIU1zwL/3es +5dJ+hVbJMTfyHu2SxEAhgm3QREYBX3fLE8RcmjH9fe0/ccl11Snd+LDNUxJcuec+ +GkuLJFiCo3z1XxjmhjxNxNowATfhkLAjyhY2SRu9qxsDSj+5kbJC5UIyIPpu0SAB +eyIWTpb9Qd2YI8rj0cCgxB0rCto7a0+zYPcpqnZwJX2ecawPjcmfxSDPVKq7aKH5 ++zrdcgdbSgc9ECCQqHJw+X5xXkrOmGIU+o3J2du0+f7EnhMbKpnW+xPov9zhEUiD +Q3IAYaEc3zcHJohqYV3j7UHIrAF9n59p388I/zVal5oBrxiXGDggd9hH/5KAPMQ2 +DwY7QVihzhXzYAtU1ecqUkZjVnOvJfpjX+fl8+Yybhf9harfl7VikBqhfzy45CHg +6JbP64oNYRP4iV5lqovRUCefLtJtWYgP06Q/crI4MAj/i4TtVNqrWow6KBj5K2Fn +1r4bd13eF9Xdkm5Wo2GxNzwzRRm0JfuQHQWrK4yGdjlJ3wDWVoWCKrUblcm2abkB +jQRkclxoAQwAvZbt+0GynjnP/VkogmpMK2jBULVpWuv8qh/Dy0jYZwDQXn1VzF7/ +IhuBM0vGBUhRONvMyN1Cw6rk0J3rGnHs71OVGrO5QIkmtHqRJeGjtelBqbodl4Iq +bN5bTQt70/zl/OXLQtufWZu2+u265jJWKWTM0l41eeTnJZ7RciLaJY2C3rdUjgRA +xQSK56gWdzi3nDyL26vEYoHmR6hZM3A2ka5d8jjQUpwikHIJ3Vz1qWKhtBGL6ZaW +X/K8L1qRH3KDDz911ghsxrEiFYiruzC1eRE0ooqoQwV5DsseBYkEPPdnbRzr7TBJ +VFLNOAjm7/pwpmAevOVKuWUUSyZ57zsEQy9/niy71/G0Avxp4KXojdJJddU7al77 +4Dp8qiXpilI3+mtInXu9WkFDMDNGg64eRVPludhTn/gN6bGHCKp/ZVWH6z1Kt+JO +WNMSuWXZhBHFOacjPM9BuAGwWUGLbZJ28RuGhKIMDC9PfR+GvqU92R1ONvSXRXLq +pfFtzo4agJ2NABEBAAGJAbwEGAEIACYCGwwWIQSWVpnIYtqSFDzeKHfRsJR7JUIC +FAUCZ9ZPUgUJByZZ6gAKCRDRsJR7JUICFN/1C/4meDXPUGAaZ0kbIkiTm5zyPFtp +8RjshM5s+a9ZSSWE5D4KA8xPEBzdlEoQ16Ah8kk9JzQzo8aWCPO2mCmXk5Q3uM4b +P2LcGEB2mVh/nxbXQtDawIhaTsqHD3fuLB4Jcy1AvqXgLmBkv5ZKOSuOmT4cLNut +p6OFJGVmHOs7WYHE31zBLDQ53yX8gYsEzoa19uZtWZA5mhrZ8Eh2sCD7xmCuAxw2 +M8cVfMes3w9+kGBF8Uuonv3uNSsXK/cvwR1TDqIvzO5gxxcobwqqIf37pKn3NeUF +ni+8+TSKLBo89kr1FT6JUFkjWtaeVfSPYo39zEKYv+wcYoYLB/59D2dbdETCuzHP +zpFnFk+hQz3oKCn55puijuSipUEimHr2rfvO5FjBgcnpqakR9SdtckH/OMlOxXsJ +SaCsHjQgLfWtuiMbLQ49beLCHIHNz+7uIOqFhQQOGmdSCS59RvUevLzOiLHGwXSF +fJ5ZxrVn4FFvdKHthktJR/eppHMOndnV6hCQAJc= +=KgyY +-----END PGP PUBLIC KEY BLOCK----- diff --git a/content/research.md b/content/research.md new file mode 100644 index 0000000..a6eeb0d --- /dev/null +++ b/content/research.md @@ -0,0 +1,52 @@ +--- +title: Research +--- + +# Research Work + + + +- [Research Work](#research-work) + - [Peer-To-Peer MFA System](#peer-to-peer-mfa-system) + - [Linux Dependency & Vulnerability Analysis](#linux-dependency-vulnerability-analysis) + - [Ultrasonic Auth: Continuous Acoustic Authentication for Vehicles](#ultrasonic-auth-continuous-acoustic-authentication-for-vehicles) + - [SonicAuth: A Time-Synchronized Voice Authentication Scheme Using Speech Transcription And Speaker Verification](#sonicauth-a-time-synchronized-voice-authentication-scheme-using-speech-transcription-and-speaker-verification) + - [Master's Thesis](#masters-thesis) + + + +I am very passionate about research, which I have conducted during my +undergraduate and ongoing Master's education. My main research interest is +Authentication. + +## Peer-To-Peer MFA System + +- Undergraduate capstone project. +- Topic: P2P MFA system using sound comparison. +- Status: Completed. + +## Linux Dependency & Vulnerability Analysis + +- Research project for "Release Engineering" graduate class. +- Topic: Relationship between package dependencies and vulnerabilities in Linux + Distributions. +- Status: Completed. + +## Ultrasonic Auth: Continuous Acoustic Authentication for Vehicles + +- Research project for "Cyber-Physical System Security" graduate class. +- Topic: A novel authentication scheme leveraging a purpose made codec for + encrypted data transfer over sound. +- Status: Completed. + +## SonicAuth: A Time-Synchronized Voice Authentication Scheme Using Speech Transcription And Speaker Verification + +- Research project for "AI in Cybersecurity" graduate class. +- Topic: A novel voice-powered authentication scheme leveraging AI & applying a + new approach to TOTP. +- Status: Completed. + +## Master's Thesis + +- Topic: Real-time phishing resilient MFA. +- Status: Ongoing. diff --git a/content/resume/base.min.css b/content/resume/base.min.css new file mode 100644 index 0000000..b1891eb --- /dev/null +++ b/content/resume/base.min.css @@ -0,0 +1,5 @@ +/*! + * Base CSS for pdf2htmlEX + * Copyright 2012,2013 Lu Wang + * https://github.com/pdf2htmlEX/pdf2htmlEX/blob/master/share/LICENSE + */#sidebar{position:absolute;top:0;left:0;bottom:0;width:250px;padding:0;margin:0;overflow:auto}#page-container{position:absolute;top:0;left:0;margin:0;padding:0;border:0}@media screen{#sidebar.opened+#page-container{left:250px}#page-container{bottom:0;right:0;overflow:auto}.loading-indicator{display:none}.loading-indicator.active{display:block;position:absolute;width:64px;height:64px;top:50%;left:50%;margin-top:-32px;margin-left:-32px}.loading-indicator img{position:absolute;top:0;left:0;bottom:0;right:0}}@media print{@page{margin:0}html{margin:0}body{margin:0;-webkit-print-color-adjust:exact}#sidebar{display:none}#page-container{width:auto;height:auto;overflow:visible;background-color:transparent}.d{display:none}}.pf{position:relative;background-color:white;overflow:hidden;margin:0;border:0}.pc{position:absolute;border:0;padding:0;margin:0;top:0;left:0;width:100%;height:100%;overflow:hidden;display:block;transform-origin:0 0;-ms-transform-origin:0 0;-webkit-transform-origin:0 0}.pc.opened{display:block}.bf{position:absolute;border:0;margin:0;top:0;bottom:0;width:100%;height:100%;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;user-select:none}.bi{position:absolute;border:0;margin:0;-ms-user-select:none;-moz-user-select:none;-webkit-user-select:none;user-select:none}@media print{.pf{margin:0;box-shadow:none;page-break-after:always;page-break-inside:avoid}@-moz-document url-prefix(){.pf{overflow:visible;border:1px solid #fff}.pc{overflow:visible}}}.c{position:absolute;border:0;padding:0;margin:0;overflow:hidden;display:block}.t{position:absolute;white-space:pre;font-size:1px;transform-origin:0 100%;-ms-transform-origin:0 100%;-webkit-transform-origin:0 100%;unicode-bidi:bidi-override;-moz-font-feature-settings:"liga" 0}.t:after{content:''}.t:before{content:'';display:inline-block}.t span{position:relative;unicode-bidi:bidi-override}._{display:inline-block;color:transparent;z-index:-1}::selection{background:rgba(127,255,255,0.4)}::-moz-selection{background:rgba(127,255,255,0.4)}.pi{display:none}.d{position:absolute;transform-origin:0 100%;-ms-transform-origin:0 100%;-webkit-transform-origin:0 100%}.it{border:0;background-color:rgba(255,255,255,0.0)}.ir:hover{cursor:pointer} \ No newline at end of file diff --git a/content/resume/bg1.png b/content/resume/bg1.png new file mode 100644 index 0000000..c5d417c Binary files /dev/null and b/content/resume/bg1.png differ diff --git a/content/resume/bg2.png b/content/resume/bg2.png new file mode 100644 index 0000000..ca36096 Binary files /dev/null and b/content/resume/bg2.png differ diff --git a/content/resume/f1.woff b/content/resume/f1.woff new file mode 100644 index 0000000..e402500 Binary files /dev/null and b/content/resume/f1.woff differ diff --git a/content/resume/f2.woff b/content/resume/f2.woff new file mode 100644 index 0000000..6a022cf Binary files /dev/null and b/content/resume/f2.woff differ diff --git a/content/resume/f3.woff b/content/resume/f3.woff new file mode 100644 index 0000000..c6b9a9a Binary files /dev/null and b/content/resume/f3.woff differ diff --git a/content/resume/f4.woff b/content/resume/f4.woff new file mode 100644 index 0000000..6f543a0 Binary files /dev/null and b/content/resume/f4.woff differ diff --git a/content/resume/f5.woff b/content/resume/f5.woff new file mode 100644 index 0000000..2239c9a Binary files /dev/null and b/content/resume/f5.woff differ diff --git a/content/resume/fancy.min.css b/content/resume/fancy.min.css new file mode 100644 index 0000000..a1f1e7a --- /dev/null +++ b/content/resume/fancy.min.css @@ -0,0 +1,5 @@ +/*! + * Fancy styles for pdf2htmlEX + * Copyright 2012,2013 Lu Wang + * https://github.com/pdf2htmlEX/pdf2htmlEX/blob/master/share/LICENSE + */@keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes swing{0{transform:rotate(0)}10%{transform:rotate(0)}90%{transform:rotate(720deg)}100%{transform:rotate(720deg)}}@-webkit-keyframes swing{0{-webkit-transform:rotate(0)}10%{-webkit-transform:rotate(0)}90%{-webkit-transform:rotate(720deg)}100%{-webkit-transform:rotate(720deg)}}@media screen{#sidebar{background-color:#2f3236;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0IiBoZWlnaHQ9IjQiPgo8cmVjdCB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjNDAzYzNmIj48L3JlY3Q+CjxwYXRoIGQ9Ik0wIDBMNCA0Wk00IDBMMCA0WiIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2U9IiMxZTI5MmQiPjwvcGF0aD4KPC9zdmc+")}#outline{font-family:Georgia,Times,"Times New Roman",serif;font-size:13px;margin:2em 1em}#outline ul{padding:0}#outline li{list-style-type:none;margin:1em 0}#outline li>ul{margin-left:1em}#outline a,#outline a:visited,#outline a:hover,#outline a:active{line-height:1.2;color:#e8e8e8;text-overflow:ellipsis;white-space:nowrap;text-decoration:none;display:block;overflow:hidden;outline:0}#outline a:hover{color:#0cf}#page-container{background-color:#9e9e9e;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1IiBoZWlnaHQ9IjUiPgo8cmVjdCB3aWR0aD0iNSIgaGVpZ2h0PSI1IiBmaWxsPSIjOWU5ZTllIj48L3JlY3Q+CjxwYXRoIGQ9Ik0wIDVMNSAwWk02IDRMNCA2Wk0tMSAxTDEgLTFaIiBzdHJva2U9IiM4ODgiIHN0cm9rZS13aWR0aD0iMSI+PC9wYXRoPgo8L3N2Zz4=");-webkit-transition:left 500ms;transition:left 500ms}.pf{margin:13px auto;box-shadow:1px 1px 3px 1px #333;border-collapse:separate}.pc.opened{-webkit-animation:fadein 100ms;animation:fadein 100ms}.loading-indicator.active{-webkit-animation:swing 1.5s ease-in-out .01s infinite alternate none;animation:swing 1.5s ease-in-out .01s infinite alternate none}.checked{background:no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3goQDSYgDiGofgAAAslJREFUOMvtlM9LFGEYx7/vvOPM6ywuuyPFihWFBUsdNnA6KLIh+QPx4KWExULdHQ/9A9EfUodYmATDYg/iRewQzklFWxcEBcGgEplDkDtI6sw4PzrIbrOuedBb9MALD7zv+3m+z4/3Bf7bZS2bzQIAcrmcMDExcTeXy10DAFVVAQDksgFUVZ1ljD3yfd+0LOuFpmnvVVW9GHhkZAQcxwkNDQ2FSCQyRMgJxnVdy7KstKZpn7nwha6urqqfTqfPBAJAuVymlNLXoigOhfd5nmeiKL5TVTV+lmIKwAOA7u5u6Lped2BsbOwjY6yf4zgQQkAIAcedaPR9H67r3uYBQFEUFItFtLe332lpaVkUBOHK3t5eRtf1DwAwODiIubk5DA8PM8bYW1EU+wEgCIJqsCAIQAiB7/u253k2BQDDMJBKpa4mEon5eDx+UxAESJL0uK2t7XosFlvSdf0QAEmlUnlRFJ9Waho2Qghc1/U9z3uWz+eX+Wr+lL6SZfleEAQIggA8z6OpqSknimIvYyybSCReMsZ6TislhCAIAti2Dc/zejVNWwCAavN8339j27YbTg0AGGM3WltbP4WhlRWq6Q/btrs1TVsYHx+vNgqKoqBUKn2NRqPFxsbGJzzP05puUlpt0ukyOI6z7zjOwNTU1OLo6CgmJyf/gA3DgKIoWF1d/cIY24/FYgOU0pp0z/Ityzo8Pj5OTk9PbwHA+vp6zWghDC+VSiuRSOQgGo32UErJ38CO42wdHR09LBQK3zKZDDY2NupmFmF4R0cHVlZWlmRZ/iVJUn9FeWWcCCE4ODjYtG27Z2Zm5juAOmgdGAB2d3cBADs7O8uSJN2SZfl+WKlpmpumaT6Yn58vn/fs6XmbhmHMNjc3tzDGFI7jYJrm5vb29sDa2trPC/9aiqJUy5pOp4f6+vqeJ5PJBAB0dnZe/t8NBajx/z37Df5OGX8d13xzAAAAAElFTkSuQmCC)}} \ No newline at end of file diff --git a/content/resume/index.md b/content/resume/index.md new file mode 100644 index 0000000..005652d --- /dev/null +++ b/content/resume/index.md @@ -0,0 +1,8 @@ +--- +title: Resume +--- + +To view a web-friendly version of my resume, [click here](/resume/resume.html). +You can also [download the PDF](/resume/resume.pdf) (~80 KB) if you wish to +print it or attach it to an email. If you think we'd work well together, don't +hesitate to reach out at [daniel@ficd.ca](mailto:daniel@ficd.ca). diff --git a/content/resume/pdf2htmlEX-64x64.png b/content/resume/pdf2htmlEX-64x64.png new file mode 100644 index 0000000..e3276fa Binary files /dev/null and b/content/resume/pdf2htmlEX-64x64.png differ diff --git a/content/resume/resume.css b/content/resume/resume.css new file mode 100644 index 0000000..da134d8 --- /dev/null +++ b/content/resume/resume.css @@ -0,0 +1,347 @@ +.ff0{font-family:sans-serif;visibility:hidden;} +@font-face{font-family:ff1;src:url(f1.woff)format("woff");}.ff1{font-family:ff1;line-height:0.958008;font-style:normal;font-weight:normal;visibility:visible;} +@font-face{font-family:ff2;src:url(f2.woff)format("woff");}.ff2{font-family:ff2;line-height:0.945803;font-style:normal;font-weight:normal;visibility:visible;} +@font-face{font-family:ff3;src:url(f3.woff)format("woff");}.ff3{font-family:ff3;line-height:0.973633;font-style:normal;font-weight:normal;visibility:visible;} +@font-face{font-family:ff4;src:url(f4.woff)format("woff");}.ff4{font-family:ff4;line-height:0.937988;font-style:normal;font-weight:normal;visibility:visible;} +@font-face{font-family:ff5;src:url(f5.woff)format("woff");}.ff5{font-family:ff5;line-height:0.941895;font-style:normal;font-weight:normal;visibility:visible;} +.m0{transform:matrix(0.250000,0.000000,0.000000,0.250000,0,0);-ms-transform:matrix(0.250000,0.000000,0.000000,0.250000,0,0);-webkit-transform:matrix(0.250000,0.000000,0.000000,0.250000,0,0);} +.m1{transform:none;-ms-transform:none;-webkit-transform:none;} +.v0{vertical-align:0.000000px;} +.ls0{letter-spacing:0.000000px;} +.sc_{text-shadow:none;} +.sc0{text-shadow:-0.015em 0 transparent,0 0.015em transparent,0.015em 0 transparent,0 -0.015em transparent;} +@media screen and (-webkit-min-device-pixel-ratio:0){ +.sc_{-webkit-text-stroke:0px transparent;} +.sc0{-webkit-text-stroke:0.015em transparent;text-shadow:none;} +} +.ws0{word-spacing:0.000000px;} +._1{margin-left:-3.164143px;} +._2{margin-left:-1.093743px;} +._3{width:1.035237px;} +._5{width:2.084393px;} +._16{width:3.091310px;} +._c{width:4.094727px;} +._d{width:5.463163px;} +._f{width:6.611395px;} +._10{width:7.789029px;} +._15{width:8.844050px;} +._8{width:11.640759px;} +._11{width:12.695113px;} +._a{width:13.839259px;} +._9{width:14.972071px;} +._4{width:19.999998px;} +._b{width:21.021172px;} +._14{width:40.000012px;} +._0{width:80.000020px;} +._6{width:91.394950px;} +._12{width:324.762547px;} +._e{width:470.641549px;} +._7{width:604.840850px;} +._13{width:695.934487px;} +.fc0{color:rgb(0,0,0);} +.fs5{font-size:32.000000px;} +.fs1{font-size:36.000000px;} +.fs2{font-size:40.000000px;} +.fs4{font-size:48.000000px;} +.fs3{font-size:56.000000px;} +.fs0{font-size:70.000000px;} +.y0{bottom:-0.500000px;} +.y38{bottom:42.201544px;} +.y37{bottom:55.283575px;} +.y36{bottom:68.365606px;} +.y35{bottom:81.447638px;} +.y6a{bottom:85.885720px;} +.y34{bottom:94.529669px;} +.y69{bottom:98.967750px;} +.y68{bottom:112.049780px;} +.y33{bottom:113.111700px;} +.y67{bottom:125.131810px;} +.y32{bottom:131.561920px;} +.y66{bottom:138.213844px;} +.y31{bottom:144.643950px;} +.y65{bottom:151.295875px;} +.y30{bottom:157.725980px;} +.y64{bottom:164.377906px;} +.y2f{bottom:170.808014px;} +.y63{bottom:177.459938px;} +.y2e{bottom:183.890045px;} +.y62{bottom:190.541969px;} +.y2d{bottom:196.972076px;} +.y2c{bottom:210.054108px;} +.y61{bottom:212.624000px;} +.y2b{bottom:223.136139px;} +.y60{bottom:239.654275px;} +.y2a{bottom:241.718170px;} +.y5f{bottom:252.736306px;} +.y29{bottom:260.168360px;} +.y5e{bottom:265.818338px;} +.y28{bottom:273.250394px;} +.y5d{bottom:278.900369px;} +.y27{bottom:286.332425px;} +.y5c{bottom:297.614200px;} +.y26{bottom:299.414456px;} +.y25{bottom:312.496488px;} +.y5b{bottom:316.064426px;} +.y24{bottom:325.578519px;} +.y5a{bottom:329.146458px;} +.y59{bottom:342.228489px;} +.y23{bottom:344.160550px;} +.y58{bottom:362.310520px;} +.y57{bottom:364.360320px;} +.y22{bottom:366.110750px;} +.y56{bottom:382.810515px;} +.y21{bottom:393.141020px;} +.y55{bottom:395.892546px;} +.y54{bottom:408.974578px;} +.y20{bottom:411.723050px;} +.y1e{bottom:411.986720px;} +.y53{bottom:422.056609px;} +.y1f{bottom:424.805080px;} +.y1d{bottom:424.936920px;} +.y52{bottom:442.138640px;} +.y1c{bottom:443.387118px;} +.y51{bottom:444.188450px;} +.y1b{bottom:456.469149px;} +.y50{bottom:462.538630px;} +.y1a{bottom:475.051180px;} +.y18{bottom:475.314850px;} +.y4f{bottom:484.678858px;} +.y19{bottom:488.133200px;} +.y17{bottom:488.265040px;} +.y4e{bottom:497.760889px;} +.y16{bottom:506.715236px;} +.y4d{bottom:517.842920px;} +.y15{bottom:519.797268px;} +.y4c{bottom:519.892730px;} +.y14{bottom:532.879299px;} +.y4b{bottom:538.342926px;} +.y4a{bottom:551.424958px;} +.y13{bottom:551.461330px;} +.y11{bottom:551.725000px;} +.y49{bottom:564.506989px;} +.y12{bottom:564.543360px;} +.y10{bottom:564.675200px;} +.y48{bottom:584.589020px;} +.yf{bottom:586.625400px;} +.y47{bottom:586.638820px;} +.y46{bottom:605.089024px;} +.ye{bottom:613.655670px;} +.y45{bottom:618.171055px;} +.y44{bottom:631.253086px;} +.yd{bottom:632.237700px;} +.yb{bottom:632.501370px;} +.y43{bottom:644.335118px;} +.yc{bottom:645.319730px;} +.ya{bottom:645.451570px;} +.y42{bottom:657.417149px;} +.y9{bottom:663.901760px;} +.y41{bottom:677.499180px;} +.y40{bottom:679.548980px;} +.y8{bottom:682.483800px;} +.y6{bottom:682.747470px;} +.y7{bottom:695.565830px;} +.y5{bottom:695.697660px;} +.y3f{bottom:701.499180px;} +.y4{bottom:717.647860px;} +.y3e{bottom:728.529449px;} +.y3d{bottom:741.611480px;} +.y3{bottom:751.178130px;} +.y3c{bottom:754.693511px;} +.y3b{bottom:767.775543px;} +.y2{bottom:776.678132px;} +.y3a{bottom:780.857574px;} +.y1{bottom:794.601958px;} +.y39{bottom:799.439605px;} +.h3{height:26.490234px;} +.h7{height:28.320312px;} +.h6{height:28.808594px;} +.h4{height:29.433594px;} +.h8{height:34.570312px;} +.h5{height:40.332031px;} +.h2{height:50.415039px;} +.h0{height:841.889800px;} +.h1{height:842.500000px;} +.w0{width:595.275600px;} +.w1{width:596.000000px;} +.x0{left:0.000000px;} +.x4{left:36.000000px;} +.x9{left:44.505859px;} +.x3{left:145.235450px;} +.x2{left:152.884140px;} +.x1{left:228.385480px;} +.x8{left:302.637800px;} +.xa{left:311.143650px;} +.xe{left:373.714070px;} +.xb{left:407.571500px;} +.x7{left:437.849820px;} +.x6{left:484.622280px;} +.x5{left:503.562700px;} +.xc{left:512.888880px;} +.xd{left:514.436740px;} +@media print{ +.v0{vertical-align:0.000000pt;} +.ls0{letter-spacing:0.000000pt;} +.ws0{word-spacing:0.000000pt;} +._1{margin-left:-4.218858pt;} +._2{margin-left:-1.458324pt;} +._3{width:1.380316pt;} +._5{width:2.779191pt;} +._16{width:4.121747pt;} +._c{width:5.459635pt;} +._d{width:7.284217pt;} +._f{width:8.815193pt;} +._10{width:10.385372pt;} +._15{width:11.792067pt;} +._8{width:15.521012pt;} +._11{width:16.926817pt;} +._a{width:18.452345pt;} +._9{width:19.962762pt;} +._4{width:26.666665pt;} +._b{width:28.028229pt;} +._14{width:53.333349pt;} +._0{width:106.666693pt;} +._6{width:121.859933pt;} +._12{width:433.016729pt;} +._e{width:627.522065pt;} +._7{width:806.454467pt;} +._13{width:927.912649pt;} +.fs5{font-size:42.666667pt;} +.fs1{font-size:48.000000pt;} +.fs2{font-size:53.333333pt;} +.fs4{font-size:64.000000pt;} +.fs3{font-size:74.666667pt;} +.fs0{font-size:93.333333pt;} +.y0{bottom:-0.666667pt;} +.y38{bottom:56.268725pt;} +.y37{bottom:73.711433pt;} +.y36{bottom:91.154141pt;} +.y35{bottom:108.596851pt;} +.y6a{bottom:114.514293pt;} +.y34{bottom:126.039558pt;} +.y69{bottom:131.957000pt;} +.y68{bottom:149.399707pt;} +.y33{bottom:150.815600pt;} +.y67{bottom:166.842413pt;} +.y32{bottom:175.415893pt;} +.y66{bottom:184.285125pt;} +.y31{bottom:192.858600pt;} +.y65{bottom:201.727833pt;} +.y30{bottom:210.301307pt;} +.y64{bottom:219.170541pt;} +.y2f{bottom:227.744019pt;} +.y63{bottom:236.613251pt;} +.y2e{bottom:245.186727pt;} +.y62{bottom:254.055958pt;} +.y2d{bottom:262.629435pt;} +.y2c{bottom:280.072144pt;} +.y61{bottom:283.498667pt;} +.y2b{bottom:297.514852pt;} +.y60{bottom:319.539033pt;} +.y2a{bottom:322.290893pt;} +.y5f{bottom:336.981741pt;} +.y29{bottom:346.891147pt;} +.y5e{bottom:354.424451pt;} +.y28{bottom:364.333859pt;} +.y5d{bottom:371.867158pt;} +.y27{bottom:381.776567pt;} +.y5c{bottom:396.818933pt;} +.y26{bottom:399.219275pt;} +.y25{bottom:416.661984pt;} +.y5b{bottom:421.419235pt;} +.y24{bottom:434.104692pt;} +.y5a{bottom:438.861944pt;} +.y59{bottom:456.304652pt;} +.y23{bottom:458.880733pt;} +.y58{bottom:483.080693pt;} +.y57{bottom:485.813760pt;} +.y22{bottom:488.147667pt;} +.y56{bottom:510.414020pt;} +.y21{bottom:524.188027pt;} +.y55{bottom:527.856728pt;} +.y54{bottom:545.299437pt;} +.y20{bottom:548.964067pt;} +.y1e{bottom:549.315627pt;} +.y53{bottom:562.742145pt;} +.y1f{bottom:566.406773pt;} +.y1d{bottom:566.582560pt;} +.y52{bottom:589.518187pt;} +.y1c{bottom:591.182824pt;} +.y51{bottom:592.251267pt;} +.y1b{bottom:608.625532pt;} +.y50{bottom:616.718173pt;} +.y1a{bottom:633.401573pt;} +.y18{bottom:633.753133pt;} +.y4f{bottom:646.238477pt;} +.y19{bottom:650.844267pt;} +.y17{bottom:651.020053pt;} +.y4e{bottom:663.681185pt;} +.y16{bottom:675.620315pt;} +.y4d{bottom:690.457227pt;} +.y15{bottom:693.063024pt;} +.y4c{bottom:693.190307pt;} +.y14{bottom:710.505732pt;} +.y4b{bottom:717.790568pt;} +.y4a{bottom:735.233277pt;} +.y13{bottom:735.281773pt;} +.y11{bottom:735.633333pt;} +.y49{bottom:752.675985pt;} +.y12{bottom:752.724480pt;} +.y10{bottom:752.900267pt;} +.y48{bottom:779.452027pt;} +.yf{bottom:782.167200pt;} +.y47{bottom:782.185093pt;} +.y46{bottom:806.785365pt;} +.ye{bottom:818.207560pt;} +.y45{bottom:824.228073pt;} +.y44{bottom:841.670781pt;} +.yd{bottom:842.983600pt;} +.yb{bottom:843.335160pt;} +.y43{bottom:859.113491pt;} +.yc{bottom:860.426307pt;} +.ya{bottom:860.602093pt;} +.y42{bottom:876.556198pt;} +.y9{bottom:885.202347pt;} +.y41{bottom:903.332240pt;} +.y40{bottom:906.065307pt;} +.y8{bottom:909.978400pt;} +.y6{bottom:910.329960pt;} +.y7{bottom:927.421107pt;} +.y5{bottom:927.596880pt;} +.y3f{bottom:935.332240pt;} +.y4{bottom:956.863813pt;} +.y3e{bottom:971.372599pt;} +.y3d{bottom:988.815307pt;} +.y3{bottom:1001.570840pt;} +.y3c{bottom:1006.258015pt;} +.y3b{bottom:1023.700724pt;} +.y2{bottom:1035.570843pt;} +.y3a{bottom:1041.143432pt;} +.y1{bottom:1059.469277pt;} +.y39{bottom:1065.919473pt;} +.h3{height:35.320312pt;} +.h7{height:37.760417pt;} +.h6{height:38.411458pt;} +.h4{height:39.244792pt;} +.h8{height:46.093750pt;} +.h5{height:53.776042pt;} +.h2{height:67.220052pt;} +.h0{height:1122.519733pt;} +.h1{height:1123.333333pt;} +.w0{width:793.700800pt;} +.w1{width:794.666667pt;} +.x0{left:0.000000pt;} +.x4{left:48.000000pt;} +.x9{left:59.341145pt;} +.x3{left:193.647267pt;} +.x2{left:203.845520pt;} +.x1{left:304.513973pt;} +.x8{left:403.517067pt;} +.xa{left:414.858200pt;} +.xe{left:498.285427pt;} +.xb{left:543.428667pt;} +.x7{left:583.799760pt;} +.x6{left:646.163040pt;} +.x5{left:671.416933pt;} +.xc{left:683.851840pt;} +.xd{left:685.915653pt;} +} diff --git a/content/resume/resume.html b/content/resume/resume.html new file mode 100644 index 0000000..8d3d6df --- /dev/null +++ b/content/resume/resume.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + +
+

Security-Focused Soware DeveloperMSc. ComputingOpen Source Contributor
   


Bachelor in Computing (Honours) — Cybersecurity




Master of Science — Computing — NSERC CREATE Cybersecurity





Teaching Assistant

Various semesters



Dec. 2024 — Jan. 2025
Jan. 2024 — Apr. 2024
Sep. 2020 — Dec. 2020

Soware Developer (Python)







Residence Don


 

Python AI in Cybersecurity — 2025

      

      
     



      



Go Cyberphysical System Security — 2025
      
       




   


        


      


Java, Python, JavaScript Undergraduate Capstone Project — 2024
       



     


       

+
Python Release Engineering — 2025
       






     



 
       

      





      

Go





   

DTS










         




Grammar DSL, Scheme
 
mail
ini









  








     

     

    





       

+
+
+ +
+ + diff --git a/content/resume/resume.outline b/content/resume/resume.outline new file mode 100644 index 0000000..f79a7c7 --- /dev/null +++ b/content/resume/resume.outline @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/content/resume/resume.pdf b/content/resume/resume.pdf new file mode 100644 index 0000000..6763421 Binary files /dev/null and b/content/resume/resume.pdf differ diff --git a/content/static/images/ashen_preview.png b/content/static/images/ashen_preview.png new file mode 100644 index 0000000..cd4fca0 Binary files /dev/null and b/content/static/images/ashen_preview.png differ diff --git a/content/static/images/datacenter2-d.jpg b/content/static/images/datacenter2-d.jpg new file mode 100644 index 0000000..a78eb9b Binary files /dev/null and b/content/static/images/datacenter2-d.jpg differ diff --git a/content/static/images/dithered_ficd.jpg b/content/static/images/dithered_ficd.jpg new file mode 100644 index 0000000..d3c7eba Binary files /dev/null and b/content/static/images/dithered_ficd.jpg differ diff --git a/content/static/images/email_1.png b/content/static/images/email_1.png new file mode 100644 index 0000000..29a44ae Binary files /dev/null and b/content/static/images/email_1.png differ diff --git a/content/static/images/email_2.png b/content/static/images/email_2.png new file mode 100644 index 0000000..ee4c0f9 Binary files /dev/null and b/content/static/images/email_2.png differ diff --git a/content/static/images/favicon.png b/content/static/images/favicon.png new file mode 100644 index 0000000..d92131f Binary files /dev/null and b/content/static/images/favicon.png differ diff --git a/content/static/images/gh_about.png b/content/static/images/gh_about.png new file mode 100644 index 0000000..da2765b Binary files /dev/null and b/content/static/images/gh_about.png differ diff --git a/content/static/images/h_self2.jpg b/content/static/images/h_self2.jpg new file mode 100644 index 0000000..76aa1f5 Binary files /dev/null and b/content/static/images/h_self2.jpg differ diff --git a/content/static/images/hrgiger.png b/content/static/images/hrgiger.png new file mode 100644 index 0000000..baa148c Binary files /dev/null and b/content/static/images/hrgiger.png differ diff --git a/content/static/images/mush.png b/content/static/images/mush.png new file mode 100644 index 0000000..02f5f73 Binary files /dev/null and b/content/static/images/mush.png differ diff --git a/content/static/style.css b/content/static/style.css new file mode 100644 index 0000000..d6d538e --- /dev/null +++ b/content/static/style.css @@ -0,0 +1,236 @@ +:root { + --main-text-color: #b4b4b4; + --main-bg-color: #121212; + --main-link-color: #df6464; + --main-heading-color: #df6464; + --main-bullet-color: #d87c4a; + --main-transparent: rgba(255, 255, 255, 0.15); + --main-small-text-color: rgba(255, 255, 255, 0.45); +} + +body { + line-height: 1.6; + font-size: 18px; + font-family: sans-serif; + background: var(--main-bg-color); + color: var(--main-text-color); + padding-left: calc(100vw - 100%); +} + +/* h1, */ +h2, +h3, +h4, +h5, +h6 { + color: var(--main-heading-color); +} + +h1 { + margin-block-start: 0.67rem; + margin-block-end: 0.67rem; + font-size: 2rem; + font-weight: bold; +} + +article h1:first-of-type { + margin-block-start: 1.67rem; +} + +h2 { + margin-block-start: 0.83rem; + margin-block-end: 0.83rem; + font-size: 1.5rem; + font-weight: bold; +} + +h3 { + margin-block-start: 1rem; + margin-block-end: 1rem; + font-size: 1.17em; + font-weight: bold; +} + +h4 { + margin-block-start: 1.33rem; + margin-block-end: 1.33rem; + font-size: 1rem; + font-weight: bold; +} + +article h1+h4:first-of-type { + margin-block-start: 0rem; +} + +h5 { + margin-block-start: 1.67rem; + margin-block-end: 1.67rem; + font-size: 0.83rem; + font-weight: bold; +} + +h6 { + margin-block-start: 2.33rem; + margin-block-end: 2.33rem; + font-size: 0.67rem; + font-weight: bold; +} + +ul { + list-style-type: disc; + /* or any other list style */ +} + +li::marker { + color: var(--main-bullet-color); + /* Change this to your desired color */ +} + +a { + color: var(--main-link-color); +} + +a:hover { + background: var(--main-transparent); +} + +img { + display: block; + margin-left: auto; + margin-right: auto; + width: auto; + height: auto; +} + +blockquote { + color: var(--main-small-text-color); + border-left: 3px solid var(--main-transparent); + padding: 0 1rem; + margin-left: 0; + margin-right: 0; +} + +hr { + border: none; + height: 1px; + background: var(--main-small-text-color); +} + +code { + background: var(--main-transparent); + border-radius: 0.1875rem; + /* padding: .0625rem .1875rem; */ + /* margin: 0 .1875rem; */ +} + +code, +pre { + white-space: pre; + word-wrap: break-word; + overflow-wrap: break-word; + font-family: 'Fira Code', 'Consolas', 'Courier New', monospace; + font-size: 0.95em; +} + +pre { + background-color: #1d1d1d; + color: #d5d5d5; + padding: 1em; + border-radius: 5px; + line-height: 1.5; + overflow-x: auto; +} + +code { + background-color: #1d1d1d; + color: #d5d5d5; + padding: 0.2em 0.4em; + border-radius: 3px; +} + + +small { + font-size: 0.95rem; + color: var(--main-small-text-color); +} + +small a { + color: inherit; + /* Inherit the color of the surrounding text */ + text-decoration: underline; + /* Optional: Keep the underline to indicate a link */ +} + +.title-container { + display: flex; + justify-content: center; + align-items: center; + text-align: center; +} + +.title-container h1 { + margin: 0; +} + +.image-container { + text-align: center; + margin: 20px 0; + /* Optional: add some spacing around the image container */ +} + +.image-container img { + /* max-width: 308px; */ + max-height: 308px; +} + +.image-container small { + display: block; + /* Ensure the caption is on a new line */ + margin-top: 5px; + /* Optional: adjust spacing between image and caption */ +} + +.image-container small a { + color: inherit; + /* Ensure the link color matches the small text */ + text-decoration: underline; + /* Optional: underline to indicate a link */ +} + +#header ul { + list-style-type: none; + padding-left: 0; +} + +#header li { + display: inline; + font-size: 1.2rem; + margin-right: 1.2rem; +} + +#container { + margin: 2.5rem auto; + width: 90%; + max-width: 60ch; +} + +#postlistdiv ul { + list-style-type: none; + padding-left: 0; +} + +.moreposts { + font-size: 0.95rem; + padding-left: 0.5rem; +} + +#nextprev { + text-align: center; + margin-top: 1.4rem; + font-size: 0.95rem; +} + +#footer { + color: var(--main-small-text-color); +} + diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..87a8392 --- /dev/null +++ b/templates/base.html @@ -0,0 +1,34 @@ + + + + {{ metadata.title }} + + + + + +
+ {% if header %} + + {% endif %} + {% block content %}{% endblock %} + {% if footer %} +
+
+ {{ footer | safe }} +
+ {% endif %} +
+ + + diff --git a/templates/basic.html b/templates/basic.html new file mode 100644 index 0000000..fbedadb --- /dev/null +++ b/templates/basic.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block content %} +{{ content | safe }} +{% endblock %} + diff --git a/templates/footer.md b/templates/footer.md new file mode 100644 index 0000000..f47028c --- /dev/null +++ b/templates/footer.md @@ -0,0 +1,5 @@ +All posted code written by me is licensed under [MIT](/LICENSE), and all other +original written work is licensed under +[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0). This +website is [open source](https://git.sr.ht/~ficd/blog), built with +[zona](https://sr.ht/~ficd/zona), and hosted on [sr.ht](https://sr.ht/). diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 0000000..f058c85 --- /dev/null +++ b/templates/header.html @@ -0,0 +1,5 @@ +
    +{% for name, url in site_map.items() %} +
  • {{ name }}
  • +{% endfor %} +
diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..91b2616 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} + +{% block content %} +

{{ metadata.title }}

+{% if metadata.date %} +
+{% endif %} +
{{ content | safe }}
+{% endblock %} + diff --git a/templates/post_list.html b/templates/post_list.html new file mode 100644 index 0000000..7fcf922 --- /dev/null +++ b/templates/post_list.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block content %} + +

{{ metadata.title }}

+ +
{{ content | safe }}
+ +{% if post_list %} + +{% endif %} +{% endblock %} + +